From 003b6dbf18bf43ec4d12f6529080976278e3b76d Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sun, 25 Feb 2024 15:32:01 -0800 Subject: [PATCH] Handle pax packet --- Meshtastic.xcodeproj/project.pbxproj | 4 ++ Meshtastic/Helpers/BLEManager.swift | 2 +- Meshtastic/Helpers/MeshPackets.swift | 37 +++++++++++++++++++ .../contents | 4 +- Meshtastic/Views/Nodes/PaxCounterLog.swift | 8 ++++ .../Settings/Config/Module/RtttlConfig.swift | 8 ++-- en.lproj/Localizable.strings | 4 ++ 7 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 Meshtastic/Views/Nodes/PaxCounterLog.swift diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index d310645d..d7a7997a 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -35,6 +35,7 @@ DD0F791B28713C8A00A6FDAD /* AdminMessageList.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD0F791A28713C8A00A6FDAD /* AdminMessageList.swift */; }; DD13AA492AB73BF400BA0C98 /* PositionPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD13AA482AB73BF400BA0C98 /* PositionPopover.swift */; }; DD15E4F32B8BA56E00654F61 /* PaxCounterConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD15E4F22B8BA56E00654F61 /* PaxCounterConfig.swift */; }; + DD15E4F52B8BFC8E00654F61 /* PaxCounterLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD15E4F42B8BFC8E00654F61 /* PaxCounterLog.swift */; }; DD1925B728CDA5A400720036 /* CannedMessagesConfigEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1925B628CDA5A400720036 /* CannedMessagesConfigEnums.swift */; }; DD1925B928CDA93900720036 /* SerialConfigEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1925B828CDA93900720036 /* SerialConfigEnums.swift */; }; DD1933762B0835D500771CD5 /* PositionAltitudeChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1933752B0835D500771CD5 /* PositionAltitudeChart.swift */; }; @@ -272,6 +273,7 @@ DD13AA482AB73BF400BA0C98 /* PositionPopover.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionPopover.swift; sourceTree = ""; }; DD14E72C2A80738F006E39BC /* MeshtasticDataModelV15.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV15.xcdatamodel; sourceTree = ""; }; DD15E4F22B8BA56E00654F61 /* PaxCounterConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaxCounterConfig.swift; sourceTree = ""; }; + DD15E4F42B8BFC8E00654F61 /* PaxCounterLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaxCounterLog.swift; sourceTree = ""; }; DD1925B628CDA5A400720036 /* CannedMessagesConfigEnums.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CannedMessagesConfigEnums.swift; sourceTree = ""; }; DD1925B828CDA93900720036 /* SerialConfigEnums.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SerialConfigEnums.swift; sourceTree = ""; }; DD1933752B0835D500771CD5 /* PositionAltitudeChart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionAltitudeChart.swift; sourceTree = ""; }; @@ -580,6 +582,7 @@ DD73FD1028750779000852D6 /* PositionLog.swift */, DD4F23CC28779A3C001D37CB /* EnvironmentMetricsLog.swift */, 6DEDA5592A957B8E00321D2E /* DetectionSensorLog.swift */, + DD15E4F42B8BFC8E00654F61 /* PaxCounterLog.swift */, DDE5B4032B2279A700FCDD05 /* TraceRouteLog.swift */, ); path = Nodes; @@ -1341,6 +1344,7 @@ DDB6CCFB2AAF805100945AF6 /* NodeMapSwiftUI.swift in Sources */, DD73FD1128750779000852D6 /* PositionLog.swift in Sources */, DD5E5206298EE33B00D21B61 /* localonly.pb.swift in Sources */, + DD15E4F52B8BFC8E00654F61 /* PaxCounterLog.swift in Sources */, DD3CC6C028E7A60700FA9159 /* MessagingEnums.swift in Sources */, DD97E96628EFD9820056DDA4 /* MeshtasticLogo.swift in Sources */, DD5E523A298EFA5300D21B61 /* TelemetryWeather.swift in Sources */, diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index d6d2d36a..efb6394b 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -699,7 +699,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate // MeshLogger.log("πŸ•ΈοΈ MESH PACKET received for Neighbor Info App UNHANDLED \(neighborInfo)") } case .paxcounterApp: - MeshLogger.log("πŸ•ΈοΈ MESH PACKET received for PAX Counter App UNHANDLED \((try? decodedInfo.packet.jsonString()) ?? "JSON Decode Failure")") + paxCounterPacket(packet: decodedInfo.packet, context: context!) case .UNRECOGNIZED: MeshLogger.log("πŸ•ΈοΈ MESH PACKET received for Other App UNHANDLED \(try! decodedInfo.packet.jsonString())") case .max: diff --git a/Meshtastic/Helpers/MeshPackets.swift b/Meshtastic/Helpers/MeshPackets.swift index 6734a49b..341ab69f 100644 --- a/Meshtastic/Helpers/MeshPackets.swift +++ b/Meshtastic/Helpers/MeshPackets.swift @@ -545,6 +545,43 @@ func adminResponseAck (packet: MeshPacket, context: NSManagedObjectContext) { print("Failed to fetch admin message by requestID") } } +func paxCounterPacket (packet: MeshPacket, context: NSManagedObjectContext) { + + let logString = String.localizedStringWithFormat("mesh.log.paxcounter %@".localized, String(packet.from)) + MeshLogger.log("πŸ§‘β€πŸ€β€πŸ§‘ \(logString)") + + let fetchNodeInfoRequest: NSFetchRequest = NSFetchRequest.init(entityName: "NodeInfoEntity") + fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(packet.from)) + + do { + let fetchedNode = try context.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity] + + if let paxMessage = try? Paxcount(serializedData: packet.decoded.payload) { + + let newPax = PaxCounterEntity(context: context) + newPax.ble = Int32(truncatingIfNeeded: paxMessage.ble) + newPax.wifi = Int32(truncatingIfNeeded: paxMessage.wifi) + newPax.uptime = Int32(truncatingIfNeeded: paxMessage.uptime) + newPax.time = Date() + + if (fetchedNode?.count ?? 0 > 0) { + guard let mutablePax = fetchedNode?[0].pax!.mutableCopy() as? NSMutableOrderedSet else { + return + } + mutablePax.add(newPax) + do { + try context.save() + } catch { + print("Failed to save pax") + } + } else { + // Node Info Not Found + } + } + } catch { + + } +} func routingPacket (packet: MeshPacket, connectedNodeNum: Int64, context: NSManagedObjectContext) { diff --git a/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModelV 28.xcdatamodel/contents b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModelV 28.xcdatamodel/contents index 8448125f..d3da3c8d 100644 --- a/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModelV 28.xcdatamodel/contents +++ b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModelV 28.xcdatamodel/contents @@ -251,7 +251,7 @@ - + @@ -275,7 +275,7 @@ - + diff --git a/Meshtastic/Views/Nodes/PaxCounterLog.swift b/Meshtastic/Views/Nodes/PaxCounterLog.swift new file mode 100644 index 00000000..8075a8b1 --- /dev/null +++ b/Meshtastic/Views/Nodes/PaxCounterLog.swift @@ -0,0 +1,8 @@ +// +// PaxCounterLog.swift +// Meshtastic +// +// Created by Garth Vander Houwen on 2/25/24. +// + +import Foundation diff --git a/Meshtastic/Views/Settings/Config/Module/RtttlConfig.swift b/Meshtastic/Views/Settings/Config/Module/RtttlConfig.swift index 920533a0..78dd2b7e 100644 --- a/Meshtastic/Views/Settings/Config/Module/RtttlConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/RtttlConfig.swift @@ -21,12 +21,12 @@ struct RtttlConfig: View { var body: some View { VStack { Form { - ConfigHeader(title: "RTTTL Ringtone", config: \.rtttlConfig, node: node, onAppear: setRtttLConfigValue) + ConfigHeader(title: "ringtone", config: \.rtttlConfig, node: node, onAppear: setRtttLConfigValue) Section(header: Text("options")) { HStack { Label("ringtone", systemImage: "music.quarternote.3") - TextField("Ringtone Transfer Language", text: $ringtone, axis: .vertical) + TextField("config.ringtone.label", text: $ringtone, axis: .vertical) .foregroundColor(.gray) .autocapitalization(.none) .disableAutocorrection(true) @@ -47,7 +47,7 @@ struct RtttlConfig: View { } .keyboardType(.default) .listRowSeparator(.hidden) - Text("Ringtone Transfer Language(RTTTL) Ringtone String used by supported buzzers in external notifications.") + Text("config.ringtone.description") .foregroundColor(.gray) .font(.callout) } @@ -66,7 +66,7 @@ struct RtttlConfig: View { } } } - .navigationTitle("ringtone.config") + .navigationTitle("config.ringtone.title") .navigationBarItems(trailing: ZStack { ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?") diff --git a/en.lproj/Localizable.strings b/en.lproj/Localizable.strings index b4f5fb74..520fbee3 100644 --- a/en.lproj/Localizable.strings +++ b/en.lproj/Localizable.strings @@ -64,6 +64,10 @@ "config.power.shutdown.on.power.loss"="Shutdown on Power Loss"; "config.power.shutdown.after.secs"="After"; "config.power.wait.bluetooth.secs"="Bluetooth Off After"; +"config.ringtone"="RTTTL Ringtone"; +"config.ringtone.title"="Ringtone Config"; +"config.ringtone.label"="Ringtone Transfer Language"; +"config.ringtone.description"="Ringtone Transfer Language(RTTTL) Ringtone String used by supported buzzers in external notifications."; "config.module.paxcounter.settings"="PAX Counter"; "config.module.paxcounter.title"="PAX Counter Config"; "config.module.paxcounter.enabled.description"="When enabled the PAX Counter module counts the number of people passing by using WiFi and Bluetooth. Both WiFI and Bluetooth must be enabled for PAX counter to work.";