From 068e73f646f6849bd0507c003ce0c06588ce21d4 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Fri, 17 Jun 2022 07:46:02 -0700 Subject: [PATCH 01/11] Update core data model and protobufs --- Meshtastic Apple.xcodeproj/project.pbxproj | 4 +- MeshtasticApple/Helpers/BLEManager.swift | 10 +- .../Meshtastic.xcdatamodeld/.xccurrentversion | 2 +- .../contents | 6 - .../contents | 111 ++++++++++++++++++ MeshtasticApple/Protobufs/mesh.pb.swift | 12 +- MeshtasticApple/Views/Settings/Settings.swift | 2 + 7 files changed, 130 insertions(+), 17 deletions(-) create mode 100644 MeshtasticApple/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents diff --git a/Meshtastic Apple.xcodeproj/project.pbxproj b/Meshtastic Apple.xcodeproj/project.pbxproj index 2d2a36f9..5a0f433e 100644 --- a/Meshtastic Apple.xcodeproj/project.pbxproj +++ b/Meshtastic Apple.xcodeproj/project.pbxproj @@ -117,6 +117,7 @@ DD4DED8F27AD2975004BA27E /* cannedmessages.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = cannedmessages.pb.swift; sourceTree = ""; }; DD5394FD276BA0EF00AD86B1 /* PositionEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionEntityExtension.swift; sourceTree = ""; }; DD539501276DAA6A00AD86B1 /* MapLocation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapLocation.swift; sourceTree = ""; }; + DD619373285CC7D600E59241 /* MeshtasticDataModel v 4.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MeshtasticDataModel v 4.xcdatamodel"; sourceTree = ""; }; DD6B85A728009258000ACD6B /* ShareChannel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareChannel.swift; sourceTree = ""; }; DD8169F8271F1A6100F4AB02 /* MeshLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshLogger.swift; sourceTree = ""; }; DD8169FA271F1F3A00F4AB02 /* MeshLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshLog.swift; sourceTree = ""; }; @@ -1013,11 +1014,12 @@ DD9D8F2D2764403B00080993 /* Meshtastic.xcdatamodeld */ = { isa = XCVersionGroup; children = ( + DD619373285CC7D600E59241 /* MeshtasticDataModel v 4.xcdatamodel */, DDB2CC6F27F3F0AC009C5FCC /* MeshtasticDataModel v 3.xcdatamodel */, DD45C77427BD4EF80011784F /* MeshtasticDataModel v2.xcdatamodel */, DD9D8F2E2764403B00080993 /* CoreDataSample.xcdatamodel */, ); - currentVersion = DDB2CC6F27F3F0AC009C5FCC /* MeshtasticDataModel v 3.xcdatamodel */; + currentVersion = DD619373285CC7D600E59241 /* MeshtasticDataModel v 4.xcdatamodel */; name = Meshtastic.xcdatamodeld; path = MeshtasticApple/Meshtastic.xcdatamodeld; sourceTree = ""; diff --git a/MeshtasticApple/Helpers/BLEManager.swift b/MeshtasticApple/Helpers/BLEManager.swift index 1d897de1..46dbca57 100644 --- a/MeshtasticApple/Helpers/BLEManager.swift +++ b/MeshtasticApple/Helpers/BLEManager.swift @@ -429,13 +429,17 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph } } - } else if decodedInfo.config.version == 13 { + } else if decodedInfo.config.isInitialized { - localConfig(config: decodedInfo.config, meshlogging: meshLoggingEnabled, context: context!, nodeLongName: self.connectedPeripheral.longName) + //localConfig(config: decodedInfo.config, meshlogging: meshLoggingEnabled, context: context!, nodeLongName: self.connectedPeripheral.longName) + if meshLoggingEnabled { MeshLogger.log("ℹ️ MESH PACKET received for Unknown App UNHANDLED \(try! decodedInfo.config.jsonString())") } } else { - if meshLoggingEnabled { MeshLogger.log("ℹ️ MESH PACKET received for Unknown App UNHANDLED \(try! decodedInfo.packet.jsonString())") } + if decodedInfo.configCompleteID == 0 { + + if meshLoggingEnabled { MeshLogger.log("ℹ️ MESH PACKET received for Unknown App UNHANDLED \(try! decodedInfo.packet.jsonString())") } + } } case .textMessageApp: textMessageAppPacket(packet: decodedInfo.packet, connectedNode: (self.connectedPeripheral != nil ? connectedPeripheral.num : 0), meshLogging: meshLoggingEnabled, context: context!) diff --git a/MeshtasticApple/Meshtastic.xcdatamodeld/.xccurrentversion b/MeshtasticApple/Meshtastic.xcdatamodeld/.xccurrentversion index 0ef73013..5d3a865e 100644 --- a/MeshtasticApple/Meshtastic.xcdatamodeld/.xccurrentversion +++ b/MeshtasticApple/Meshtastic.xcdatamodeld/.xccurrentversion @@ -3,6 +3,6 @@ _XCCurrentVersionName - MeshtasticDataModel v 3.xcdatamodel + MeshtasticDataModel v 4.xcdatamodel diff --git a/MeshtasticApple/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents b/MeshtasticApple/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents index 7d5d50e1..2be97c35 100644 --- a/MeshtasticApple/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents +++ b/MeshtasticApple/Meshtastic.xcdatamodeld/MeshtasticDataModel v 3.xcdatamodel/contents @@ -1,10 +1,5 @@ - - - - - @@ -104,6 +99,5 @@ - \ No newline at end of file diff --git a/MeshtasticApple/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents b/MeshtasticApple/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents new file mode 100644 index 00000000..71115514 --- /dev/null +++ b/MeshtasticApple/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MeshtasticApple/Protobufs/mesh.pb.swift b/MeshtasticApple/Protobufs/mesh.pb.swift index 0d2fc06a..b1f4484d 100644 --- a/MeshtasticApple/Protobufs/mesh.pb.swift +++ b/MeshtasticApple/Protobufs/mesh.pb.swift @@ -1810,11 +1810,11 @@ struct FromRadio { } /// - /// Include the entire config (was: RadioConfig radio) - var config: LocalConfig { + /// Include a part of the config (was: RadioConfig radio) + var config: Config { get { if case .config(let v)? = _storage._payloadVariant {return v} - return LocalConfig() + return Config() } set {_uniqueStorage()._payloadVariant = .config(newValue)} } @@ -1872,8 +1872,8 @@ struct FromRadio { /// starts over with the first node in our DB case nodeInfo(NodeInfo) /// - /// Include the entire config (was: RadioConfig radio) - case config(LocalConfig) + /// Include a part of the config (was: RadioConfig radio) + case config(Config) /// /// Set to send debug console output over our protobuf stream case logRecord(LogRecord) @@ -3356,7 +3356,7 @@ extension FromRadio: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation } }() case 6: try { - var v: LocalConfig? + var v: Config? var hadOneofValue = false if let current = _storage._payloadVariant { hadOneofValue = true diff --git a/MeshtasticApple/Views/Settings/Settings.swift b/MeshtasticApple/Views/Settings/Settings.swift index 4e8db7ea..a436150f 100644 --- a/MeshtasticApple/Views/Settings/Settings.swift +++ b/MeshtasticApple/Views/Settings/Settings.swift @@ -13,6 +13,8 @@ struct Settings: View { @EnvironmentObject var bleManager: BLEManager @EnvironmentObject var userSettings: UserSettings +// var connectednode: NodeInfoEntity + var body: some View { NavigationView { List { From a58337ff1585d4780bc773d033fafa99108eca0c Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Fri, 17 Jun 2022 18:20:30 -0700 Subject: [PATCH 02/11] Update connected device indicators to show up to 5 character short name --- MeshtasticApple/Views/Bluetooth/Connect.swift | 4 ++-- MeshtasticApple/Views/Messages/UserMessageList.swift | 2 +- MeshtasticApple/Views/Nodes/NodeDetail.swift | 2 +- MeshtasticApple/Views/Nodes/NodeMap.swift | 4 ++-- MeshtasticApple/Views/Settings/AppSettings.swift | 2 +- MeshtasticApple/Views/Settings/DeviceConfig.swift | 2 +- MeshtasticApple/Views/Settings/DisplayConfig.swift | 2 +- MeshtasticApple/Views/Settings/LoRaConfig.swift | 2 +- MeshtasticApple/Views/Settings/PositionConfig.swift | 2 +- MeshtasticApple/Views/Settings/RangeTestConfig.swift | 2 +- MeshtasticApple/Views/Settings/ShareChannel.swift | 2 +- MeshtasticApple/Views/Settings/TelemetryConfig.swift | 2 +- 12 files changed, 14 insertions(+), 14 deletions(-) diff --git a/MeshtasticApple/Views/Bluetooth/Connect.swift b/MeshtasticApple/Views/Bluetooth/Connect.swift index 98578eea..ec6743a3 100644 --- a/MeshtasticApple/Views/Bluetooth/Connect.swift +++ b/MeshtasticApple/Views/Bluetooth/Connect.swift @@ -265,8 +265,8 @@ struct Connect: View { ConnectedDevice( bluetoothOn: self.bleManager.isSwitchedOn, deviceConnected: self.bleManager.connectedPeripheral != nil, - name: (bleManager.connectedPeripheral != nil) ? self.bleManager.connectedPeripheral.lastFourCode : - "????") + name: (bleManager.connectedPeripheral != nil) ? self.bleManager.connectedPeripheral.shortName : + "?????") } ) } diff --git a/MeshtasticApple/Views/Messages/UserMessageList.swift b/MeshtasticApple/Views/Messages/UserMessageList.swift index d70a18ec..c6dfd2d1 100644 --- a/MeshtasticApple/Views/Messages/UserMessageList.swift +++ b/MeshtasticApple/Views/Messages/UserMessageList.swift @@ -457,7 +457,7 @@ struct UserMessageList: View { ConnectedDevice( bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, - name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.lastFourCode : "????") + name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????") } } } diff --git a/MeshtasticApple/Views/Nodes/NodeDetail.swift b/MeshtasticApple/Views/Nodes/NodeDetail.swift index 5d7a3699..6369b514 100644 --- a/MeshtasticApple/Views/Nodes/NodeDetail.swift +++ b/MeshtasticApple/Views/Nodes/NodeDetail.swift @@ -352,7 +352,7 @@ struct NodeDetail: View { ConnectedDevice( bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, - name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.lastFourCode : "????") + name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????") } ) .onAppear(perform: { diff --git a/MeshtasticApple/Views/Nodes/NodeMap.swift b/MeshtasticApple/Views/Nodes/NodeMap.swift index 0aa4516d..061852db 100644 --- a/MeshtasticApple/Views/Nodes/NodeMap.swift +++ b/MeshtasticApple/Views/Nodes/NodeMap.swift @@ -125,8 +125,8 @@ struct NodeMap: View { ConnectedDevice( bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, - name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.lastFourCode : - "????") + name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : + "?????") }) .onAppear(perform: { diff --git a/MeshtasticApple/Views/Settings/AppSettings.swift b/MeshtasticApple/Views/Settings/AppSettings.swift index e5c14e1a..6e6aa954 100644 --- a/MeshtasticApple/Views/Settings/AppSettings.swift +++ b/MeshtasticApple/Views/Settings/AppSettings.swift @@ -176,7 +176,7 @@ struct AppSettings: View { ZStack { - ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.lastFourCode : "????") + ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????") }) .onAppear { diff --git a/MeshtasticApple/Views/Settings/DeviceConfig.swift b/MeshtasticApple/Views/Settings/DeviceConfig.swift index ae734c68..148c42bb 100644 --- a/MeshtasticApple/Views/Settings/DeviceConfig.swift +++ b/MeshtasticApple/Views/Settings/DeviceConfig.swift @@ -79,7 +79,7 @@ struct DeviceConfig: View { ZStack { - ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.lastFourCode : "????") + ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????") }) .onAppear { diff --git a/MeshtasticApple/Views/Settings/DisplayConfig.swift b/MeshtasticApple/Views/Settings/DisplayConfig.swift index 35e4ce92..d7c9936f 100644 --- a/MeshtasticApple/Views/Settings/DisplayConfig.swift +++ b/MeshtasticApple/Views/Settings/DisplayConfig.swift @@ -163,7 +163,7 @@ struct DisplayConfig: View { ZStack { - ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.lastFourCode : "????") + ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????") }) .onAppear { diff --git a/MeshtasticApple/Views/Settings/LoRaConfig.swift b/MeshtasticApple/Views/Settings/LoRaConfig.swift index f17e66d9..a2e706a8 100644 --- a/MeshtasticApple/Views/Settings/LoRaConfig.swift +++ b/MeshtasticApple/Views/Settings/LoRaConfig.swift @@ -149,7 +149,7 @@ struct LoRaConfig: View { ZStack { - ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.lastFourCode : "????") + ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????") }) .onAppear { diff --git a/MeshtasticApple/Views/Settings/PositionConfig.swift b/MeshtasticApple/Views/Settings/PositionConfig.swift index 43cf0af4..ffb675e4 100644 --- a/MeshtasticApple/Views/Settings/PositionConfig.swift +++ b/MeshtasticApple/Views/Settings/PositionConfig.swift @@ -239,7 +239,7 @@ struct PositionConfig: View { ZStack { - ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.lastFourCode : "????") + ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????") }) .onAppear { diff --git a/MeshtasticApple/Views/Settings/RangeTestConfig.swift b/MeshtasticApple/Views/Settings/RangeTestConfig.swift index 0723954e..ef86378a 100644 --- a/MeshtasticApple/Views/Settings/RangeTestConfig.swift +++ b/MeshtasticApple/Views/Settings/RangeTestConfig.swift @@ -55,7 +55,7 @@ struct RangeTestConfig: View { ZStack { - ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.lastFourCode : "????") + ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????") }) .onAppear { diff --git a/MeshtasticApple/Views/Settings/ShareChannel.swift b/MeshtasticApple/Views/Settings/ShareChannel.swift index 7b41486b..3a7b2bfe 100644 --- a/MeshtasticApple/Views/Settings/ShareChannel.swift +++ b/MeshtasticApple/Views/Settings/ShareChannel.swift @@ -81,7 +81,7 @@ struct ShareChannel: View { ZStack { - ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.lastFourCode : "????") + ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????") }) .onAppear { diff --git a/MeshtasticApple/Views/Settings/TelemetryConfig.swift b/MeshtasticApple/Views/Settings/TelemetryConfig.swift index aa22679f..78eb78a6 100644 --- a/MeshtasticApple/Views/Settings/TelemetryConfig.swift +++ b/MeshtasticApple/Views/Settings/TelemetryConfig.swift @@ -26,7 +26,7 @@ struct TelemetryConfig: View { ZStack { - ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.lastFourCode : "????") + ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????") }) .onAppear { From 698a2bd1bf0f924acf65030e896ca2137b89ed89 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Fri, 17 Jun 2022 21:47:41 -0700 Subject: [PATCH 03/11] Update protos, fix in region enum issue --- MeshtasticApple/Protobufs/config.pb.swift | 11 ----------- MeshtasticApple/Views/Settings/LoRaConfig.swift | 6 ++++-- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/MeshtasticApple/Protobufs/config.pb.swift b/MeshtasticApple/Protobufs/config.pb.swift index f4ab0e9d..d446dc4a 100644 --- a/MeshtasticApple/Protobufs/config.pb.swift +++ b/MeshtasticApple/Protobufs/config.pb.swift @@ -392,11 +392,6 @@ struct Config { /// CLI Only Option var isPowerSaving: Bool = false - /// - /// Circumvents the logic block for determining whether the device is powered or not. - /// Useful for devices with finicky ADC issues on the battery sense pins. - var isAlwaysPowered: Bool = false - /// /// If non-zero, the device will fully power off this many seconds after external power is removed. var onBatteryShutdownAfterSecs: UInt32 = 0 @@ -1350,7 +1345,6 @@ extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImple static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 1: .standard(proto: "charge_current"), 2: .standard(proto: "is_power_saving"), - 3: .standard(proto: "is_always_powered"), 4: .standard(proto: "on_battery_shutdown_after_secs"), 6: .standard(proto: "adc_multiplier_override"), 7: .standard(proto: "wait_bluetooth_secs"), @@ -1368,7 +1362,6 @@ extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImple switch fieldNumber { case 1: try { try decoder.decodeSingularEnumField(value: &self.chargeCurrent) }() case 2: try { try decoder.decodeSingularBoolField(value: &self.isPowerSaving) }() - case 3: try { try decoder.decodeSingularBoolField(value: &self.isAlwaysPowered) }() case 4: try { try decoder.decodeSingularUInt32Field(value: &self.onBatteryShutdownAfterSecs) }() case 6: try { try decoder.decodeSingularFloatField(value: &self.adcMultiplierOverride) }() case 7: try { try decoder.decodeSingularUInt32Field(value: &self.waitBluetoothSecs) }() @@ -1388,9 +1381,6 @@ extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImple if self.isPowerSaving != false { try visitor.visitSingularBoolField(value: self.isPowerSaving, fieldNumber: 2) } - if self.isAlwaysPowered != false { - try visitor.visitSingularBoolField(value: self.isAlwaysPowered, fieldNumber: 3) - } if self.onBatteryShutdownAfterSecs != 0 { try visitor.visitSingularUInt32Field(value: self.onBatteryShutdownAfterSecs, fieldNumber: 4) } @@ -1418,7 +1408,6 @@ extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImple static func ==(lhs: Config.PowerConfig, rhs: Config.PowerConfig) -> Bool { if lhs.chargeCurrent != rhs.chargeCurrent {return false} if lhs.isPowerSaving != rhs.isPowerSaving {return false} - if lhs.isAlwaysPowered != rhs.isAlwaysPowered {return false} if lhs.onBatteryShutdownAfterSecs != rhs.onBatteryShutdownAfterSecs {return false} if lhs.adcMultiplierOverride != rhs.adcMultiplierOverride {return false} if lhs.waitBluetoothSecs != rhs.waitBluetoothSecs {return false} diff --git a/MeshtasticApple/Views/Settings/LoRaConfig.swift b/MeshtasticApple/Views/Settings/LoRaConfig.swift index a2e706a8..0217b08c 100644 --- a/MeshtasticApple/Views/Settings/LoRaConfig.swift +++ b/MeshtasticApple/Views/Settings/LoRaConfig.swift @@ -19,7 +19,7 @@ enum RegionCodes : Int, CaseIterable, Identifiable { case kr = 7 case tw = 8 case ru = 9 - //case in = 10 + case `in` = 10 case nz865 case th @@ -47,10 +47,12 @@ enum RegionCodes : Int, CaseIterable, Identifiable { return "Taiwan" case .ru: return "Russia" + case .in: + return "India" case .nz865: return "New Zealand 865mhz" case .th: - return "TH" + return "Thailand" } } } From 64fa08789b5a340c63550002c676e28b4c8c1f72 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Fri, 17 Jun 2022 22:05:42 -0700 Subject: [PATCH 04/11] Fix node detail selected node on mac --- MeshtasticApple/Views/Nodes/NodeList.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MeshtasticApple/Views/Nodes/NodeList.swift b/MeshtasticApple/Views/Nodes/NodeList.swift index 0a3d2916..f1a7762e 100644 --- a/MeshtasticApple/Views/Nodes/NodeList.swift +++ b/MeshtasticApple/Views/Nodes/NodeList.swift @@ -105,7 +105,8 @@ struct NodeList: View { self.bleManager.context = context self.bleManager.userSettings = userSettings - if UIDevice.current.userInterfaceIdiom == .pad { + if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac { + if nodes.count > 0 { selection = "0" } From 52d27aa09aa6bfb60c84df113fc0dd6068e64ae3 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sat, 18 Jun 2022 00:08:01 -0700 Subject: [PATCH 05/11] Clean up connected peripheral to be larger and show the short name after we get a node info --- MeshtasticApple/Helpers/BLEManager.swift | 56 ++++++++++--- .../Views/Helpers/ConnectedDevice.swift | 4 +- .../Views/Settings/DeviceConfig.swift | 80 +++++++++++++------ 3 files changed, 103 insertions(+), 37 deletions(-) diff --git a/MeshtasticApple/Helpers/BLEManager.swift b/MeshtasticApple/Helpers/BLEManager.swift index 46dbca57..00488f53 100644 --- a/MeshtasticApple/Helpers/BLEManager.swift +++ b/MeshtasticApple/Helpers/BLEManager.swift @@ -179,7 +179,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph peripheralName = name } - let newPeripheral = Peripheral(id: peripheral.identifier.uuidString, num: 0, name: peripheralName, shortName: String(peripheralName.suffix(3)), longName: peripheralName, lastFourCode: last4Code, firmwareVersion: "Unknown", rssi: RSSI.intValue, bitrate: nil, channelUtilization: nil, airTime: nil, lastUpdate: Date(), subscribed: false, peripheral: peripheral) + let newPeripheral = Peripheral(id: peripheral.identifier.uuidString, num: 0, name: peripheralName, shortName: last4Code, longName: peripheralName, lastFourCode: last4Code, firmwareVersion: "Unknown", rssi: RSSI.intValue, bitrate: nil, channelUtilization: nil, airTime: nil, lastUpdate: Date(), subscribed: false, peripheral: peripheral) let peripheralIndex = peripherals.firstIndex(where: { $0.id == newPeripheral.id }) if peripheralIndex != nil && newPeripheral.peripheral.state != CBPeripheralState.connected { @@ -409,6 +409,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph lastConnnectionVersion = myInfo?.firmwareVersion ?? myInfo!.firmwareVersion ?? "Unknown" self.connectedPeripheral.firmwareVersion = myInfo!.firmwareVersion ?? "Unknown" self.connectedPeripheral.name = myInfo!.bleName ?? "Unknown" + } } else if decodedInfo.nodeInfo.num != 0 { @@ -425,6 +426,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph if nodeInfo!.user != nil { connectedPeripheral.name = nodeInfo!.user!.longName ?? "Unknown" + connectedPeripheral.shortName = nodeInfo!.user!.shortName ?? "?????" } } } @@ -432,7 +434,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph } else if decodedInfo.config.isInitialized { //localConfig(config: decodedInfo.config, meshlogging: meshLoggingEnabled, context: context!, nodeLongName: self.connectedPeripheral.longName) - if meshLoggingEnabled { MeshLogger.log("ℹ️ MESH PACKET received for Unknown App UNHANDLED \(try! decodedInfo.config.jsonString())") } + if meshLoggingEnabled { MeshLogger.log("ℹ️ MESH PACKET received for Unknown App decodedInfo.config.isInitialized \(try! decodedInfo.packet.jsonString())") } } else { @@ -809,26 +811,60 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph return false } - public func getConfig(destNum: Int64, wantResponse: Bool) -> Bool { + public func sendFactoryReset(destNum: Int64, wantResponse: Bool) -> Bool { + + var deviceConfig = Config.DeviceConfig() + deviceConfig.factoryReset = true var adminPacket = AdminMessage() - adminPacket.getConfigRequest = AdminMessage.ConfigType.deviceConfig - - adminPacket.variant = AdminMessage.OneOf_Variant.getConfigRequest(AdminMessage.ConfigType.loraConfig) - + adminPacket.setConfig.device = deviceConfig var meshPacket: MeshPacket = MeshPacket() meshPacket.to = UInt32(connectedPeripheral.num) - meshPacket.from = UInt32(connectedPeripheral.num) + meshPacket.from = 0 //UInt32(connectedPeripheral.num) meshPacket.id = UInt32.random(in: UInt32(UInt8.max).. Bool { + + var adminPacket = AdminMessage() + adminPacket.setConfig.lora = config + + var meshPacket: MeshPacket = MeshPacket() + meshPacket.to = UInt32(connectedPeripheral.num) + meshPacket.from = 0 //UInt32(connectedPeripheral.num) + meshPacket.id = UInt32.random(in: UInt32(UInt8.max).. Date: Mon, 20 Jun 2022 00:13:04 -0700 Subject: [PATCH 06/11] Save Lora config values --- .../Views/Settings/DeviceConfig.swift | 114 +++++++++--------- .../Views/Settings/LoRaConfig.swift | 97 ++++++++++++++- 2 files changed, 149 insertions(+), 62 deletions(-) diff --git a/MeshtasticApple/Views/Settings/DeviceConfig.swift b/MeshtasticApple/Views/Settings/DeviceConfig.swift index bff27d04..90fbe166 100644 --- a/MeshtasticApple/Views/Settings/DeviceConfig.swift +++ b/MeshtasticApple/Views/Settings/DeviceConfig.swift @@ -44,78 +44,74 @@ struct DeviceConfig: View { @State private var isPresentingFactoryResetConfirm: Bool = false var body: some View { - - ZStack { - VStack { + VStack { - Form { + Form { + + Section(header: Text("Options")) { - - Section(header: Text("Options")) { - - Picker("Device Role", selection: $deviceRole ) { - ForEach(DeviceRoles.allCases) { dr in - Text(dr.description) - } + Picker("Device Role", selection: $deviceRole ) { + ForEach(DeviceRoles.allCases) { dr in + Text(dr.description) } - .pickerStyle(InlinePickerStyle()) - .padding(.top, 10) - .padding(.bottom, 10) - } - - Section(header: Text("Debug")) { - - Toggle(isOn: $serialEnabled) { - - Label("Serial Console", systemImage: "terminal") - } - .toggleStyle(SwitchToggleStyle(tint: .accentColor)) - - Toggle(isOn: $debugLogEnabled) { - - Label("Debug Log", systemImage: "ant.fill") - } - .toggleStyle(SwitchToggleStyle(tint: .accentColor)) } + .pickerStyle(InlinePickerStyle()) + .padding(.top, 10) + .padding(.bottom, 10) } - Button("Factory Reset", role: .destructive) { + Section(header: Text("Debug")) { - isPresentingFactoryResetConfirm = true - } - .disabled(bleManager.connectedPeripheral == nil) - .buttonStyle(.bordered) - .buttonBorderShape(.capsule) - .controlSize(.large) - .padding() - .confirmationDialog( - "Are you sure?", - isPresented: $isPresentingFactoryResetConfirm - ) { - Button("Erase all device settings?", role: .destructive) { - - if !bleManager.sendFactoryReset(destNum: bleManager.connectedPeripheral.num, wantResponse: false) { - - print("Factory Reset Failed") - } + Toggle(isOn: $serialEnabled) { + + Label("Serial Console", systemImage: "terminal") } + .toggleStyle(SwitchToggleStyle(tint: .accentColor)) + + Toggle(isOn: $debugLogEnabled) { + + Label("Debug Log", systemImage: "ant.fill") + } + .toggleStyle(SwitchToggleStyle(tint: .accentColor)) } - Spacer() } - .navigationTitle("Device Config") - .navigationBarItems(trailing: - - ZStack { - - ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????") - }) - .onAppear { - - self.bleManager.context = context + Button("Factory Reset", role: .destructive) { + + isPresentingFactoryResetConfirm = true } - .navigationViewStyle(StackNavigationViewStyle()) + .disabled(bleManager.connectedPeripheral == nil) + .buttonStyle(.bordered) + .buttonBorderShape(.capsule) + .controlSize(.large) + .padding() + .confirmationDialog( + "Are you sure?", + isPresented: $isPresentingFactoryResetConfirm + ) { + Button("Erase all device settings?", role: .destructive) { + + if !bleManager.sendFactoryReset(destNum: bleManager.connectedPeripheral.num, wantResponse: false) { + + print("Factory Reset Failed") + } + } + } + Spacer() } + + .navigationTitle("Device Config") + .navigationBarItems(trailing: + + ZStack { + + ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????") + }) + .onAppear { + + self.bleManager.context = context + } + .navigationViewStyle(StackNavigationViewStyle()) } } diff --git a/MeshtasticApple/Views/Settings/LoRaConfig.swift b/MeshtasticApple/Views/Settings/LoRaConfig.swift index 0217b08c..f4c2abe1 100644 --- a/MeshtasticApple/Views/Settings/LoRaConfig.swift +++ b/MeshtasticApple/Views/Settings/LoRaConfig.swift @@ -56,6 +56,39 @@ enum RegionCodes : Int, CaseIterable, Identifiable { } } } + + func protoEnumValue() -> Config.LoRaConfig.RegionCode { + + switch self { + + case .unset: + return Config.LoRaConfig.RegionCode.unset + case .us: + return Config.LoRaConfig.RegionCode.us + case .eu433: + return Config.LoRaConfig.RegionCode.eu433 + case .eu868: + return Config.LoRaConfig.RegionCode.eu868 + case .cn: + return Config.LoRaConfig.RegionCode.cn + case .jp: + return Config.LoRaConfig.RegionCode.jp + case .anz: + return Config.LoRaConfig.RegionCode.anz + case .kr: + return Config.LoRaConfig.RegionCode.kr + case .tw: + return Config.LoRaConfig.RegionCode.tw + case .ru: + return Config.LoRaConfig.RegionCode.ru + case .in: + return Config.LoRaConfig.RegionCode.in + case .nz865: + return Config.LoRaConfig.RegionCode.nz865 + case .th: + return Config.LoRaConfig.RegionCode.th + } + } } enum ModemPresets : Int, CaseIterable, Identifiable { @@ -90,6 +123,27 @@ enum ModemPresets : Int, CaseIterable, Identifiable { } } } + func protoEnumValue() -> Config.LoRaConfig.ModemPreset { + + switch self { + + case .LongFast: + return Config.LoRaConfig.ModemPreset.longFast + case .LongSlow: + return Config.LoRaConfig.ModemPreset.longSlow + case .VLongSlow: + return Config.LoRaConfig.ModemPreset.vlongSlow + case .MidSlow: + return Config.LoRaConfig.ModemPreset.midSlow + case .MidFast: + return Config.LoRaConfig.ModemPreset.midFast + case .ShortSlow: + return Config.LoRaConfig.ModemPreset.shortSlow + case .ShortFast: + return Config.LoRaConfig.ModemPreset.shortFast + + } + } } struct LoRaConfig: View { @@ -98,8 +152,9 @@ struct LoRaConfig: View { @EnvironmentObject var bleManager: BLEManager @State var region = 1 - @State var modemPreset = 0 - @State var numberOfHops = 0 + @State var modemPreset = 0 + @State var hopLimit = 0 + @State var hasChanges = false var body: some View { @@ -133,7 +188,7 @@ struct LoRaConfig: View { } Section(header: Text("Mesh Options")) { - Picker("Number of hops", selection: $numberOfHops) { + Picker("Number of hops", selection: $hopLimit) { ForEach(0..<8) { if $0 == 0 { Text("Default") @@ -145,6 +200,29 @@ struct LoRaConfig: View { .pickerStyle(DefaultPickerStyle()) } } + + Button { + + var lc = Config.LoRaConfig() + lc.hopLimit = UInt32(hopLimit) + lc.region = RegionCodes(rawValue: region)!.protoEnumValue() + lc.modemPreset = ModemPresets(rawValue: modemPreset)!.protoEnumValue() + + if bleManager.saveLoRaConfig(config: lc, destNum: bleManager.connectedPeripheral.num, wantResponse: false) { + + } else { + + } + + } label: { + Label("Save", systemImage: "square.and.arrow.down") + } + .disabled(bleManager.connectedPeripheral == nil || !hasChanges) + .buttonStyle(.bordered) + .buttonBorderShape(.capsule) + .controlSize(.large) + .padding() + } .navigationTitle("LoRa Config") .navigationBarItems(trailing: @@ -157,6 +235,19 @@ struct LoRaConfig: View { self.bleManager.context = context } + .onChange(of: region) { newRegion in + + hasChanges = true + } + .onChange(of: modemPreset) { newModemPreset in + + hasChanges = true + } + .onChange(of: hopLimit) { newHopLimit in + + hasChanges = true + } + .navigationViewStyle(StackNavigationViewStyle()) } } From 18630efa586cc88f6780a001ae1fe5527c7ddcf2 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Mon, 20 Jun 2022 12:51:55 -0700 Subject: [PATCH 07/11] Update Protobufs, finish LoRaConfig UI --- MeshtasticApple/Helpers/BLEManager.swift | 5 +- MeshtasticApple/Helpers/MeshPackets.swift | 37 +++- MeshtasticApple/Protobufs/config.pb.swift | 200 ++++++------------ .../Views/Settings/DeviceConfig.swift | 2 +- .../Views/Settings/LoRaConfig.swift | 106 +++++++--- .../Views/Settings/PositionConfig.swift | 40 +++- 6 files changed, 202 insertions(+), 188 deletions(-) diff --git a/MeshtasticApple/Helpers/BLEManager.swift b/MeshtasticApple/Helpers/BLEManager.swift index 00488f53..a4bc4254 100644 --- a/MeshtasticApple/Helpers/BLEManager.swift +++ b/MeshtasticApple/Helpers/BLEManager.swift @@ -433,8 +433,9 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph } else if decodedInfo.config.isInitialized { - //localConfig(config: decodedInfo.config, meshlogging: meshLoggingEnabled, context: context!, nodeLongName: self.connectedPeripheral.longName) - if meshLoggingEnabled { MeshLogger.log("ℹ️ MESH PACKET received for Unknown App decodedInfo.config.isInitialized \(try! decodedInfo.packet.jsonString())") } + localConfig(config: decodedInfo.config, meshlogging: meshLoggingEnabled, context: context!, nodeLongName: self.connectedPeripheral.longName) + if meshLoggingEnabled { MeshLogger.log("ℹ️ MESH PACKET received for Unknown App decodedInfo.config.isInitialized \(try! decodedInfo.config.jsonString())") } + } else { diff --git a/MeshtasticApple/Helpers/MeshPackets.swift b/MeshtasticApple/Helpers/MeshPackets.swift index 8a8b3304..68976fb2 100644 --- a/MeshtasticApple/Helpers/MeshPackets.swift +++ b/MeshtasticApple/Helpers/MeshPackets.swift @@ -9,11 +9,11 @@ import Foundation import CoreData import SwiftUI -func localConfig (config: LocalConfig, meshlogging: Bool, context:NSManagedObjectContext, nodeLongName: String) { +func localConfig (config: Config, meshlogging: Bool, context:NSManagedObjectContext, nodeLongName: String) { // We don't care about any of the Power settings // We don't want to manage wifi from the phone app and disconnect our device - if meshlogging { MeshLogger.log("⚙️ Local Config version \(config.version) received for \(nodeLongName)") } + //if meshlogging { MeshLogger.log("⚙️ Local Config version \(config.version) received for \(nodeLongName)") } if (try! config.device.jsonString()) == "{}" { @@ -24,6 +24,26 @@ func localConfig (config: LocalConfig, meshlogging: Bool, context:NSManagedObjec print("📟 Has Device config") } + if (try! config.position.jsonString()) == "{}" { + + print("📍 Default Position config") + + } else { + + print("📍 Has Position config") + } + + if (try! config.power.jsonString() == "{\"lsSecs\":300}") { + + print("📍 Default Power config") + print(try! config.power.jsonString()) + + } else { + + print("📍 Has Power config") + print(try! config.power.jsonString()) + } + if (try! config.display.jsonString()) == "{}" { print("🖥️ Default Display config") @@ -33,6 +53,10 @@ func localConfig (config: LocalConfig, meshlogging: Bool, context:NSManagedObjec print("🖥️ Has Display config") } + + + + if (try! config.lora.jsonString()) == "{}" { print("📡 Default LoRa config") @@ -41,15 +65,6 @@ func localConfig (config: LocalConfig, meshlogging: Bool, context:NSManagedObjec print("📡 Has LoRa config") } - - if (try! config.position.jsonString()) == "{}" { - - print("📍 Default Position config") - - } else { - - print("📍 Has Position config") - } } func myInfoPacket (myInfo: MyNodeInfo, meshLogging: Bool, context: NSManagedObjectContext) -> MyInfoEntity? { diff --git a/MeshtasticApple/Protobufs/config.pb.swift b/MeshtasticApple/Protobufs/config.pb.swift index d446dc4a..b93e2a68 100644 --- a/MeshtasticApple/Protobufs/config.pb.swift +++ b/MeshtasticApple/Protobufs/config.pb.swift @@ -26,11 +26,9 @@ struct Config { // methods supported on all messages. /// - /// TODO: REPLACE + /// Payload Variant var payloadVariant: Config.OneOf_PayloadVariant? = nil - /// - /// TODO: REPLACE var device: Config.DeviceConfig { get { if case .device(let v)? = payloadVariant {return v} @@ -39,8 +37,6 @@ struct Config { set {payloadVariant = .device(newValue)} } - /// - /// TODO: REPLACE var position: Config.PositionConfig { get { if case .position(let v)? = payloadVariant {return v} @@ -49,8 +45,6 @@ struct Config { set {payloadVariant = .position(newValue)} } - /// - /// TODO: REPLACE var power: Config.PowerConfig { get { if case .power(let v)? = payloadVariant {return v} @@ -59,8 +53,6 @@ struct Config { set {payloadVariant = .power(newValue)} } - /// - /// TODO: REPLACE var wifi: Config.WiFiConfig { get { if case .wifi(let v)? = payloadVariant {return v} @@ -69,8 +61,6 @@ struct Config { set {payloadVariant = .wifi(newValue)} } - /// - /// TODO: REPLACE var display: Config.DisplayConfig { get { if case .display(let v)? = payloadVariant {return v} @@ -79,8 +69,6 @@ struct Config { set {payloadVariant = .display(newValue)} } - /// - /// TODO: REPLACE var lora: Config.LoRaConfig { get { if case .lora(let v)? = payloadVariant {return v} @@ -92,25 +80,13 @@ struct Config { var unknownFields = SwiftProtobuf.UnknownStorage() /// - /// TODO: REPLACE + /// Payload Variant enum OneOf_PayloadVariant: Equatable { - /// - /// TODO: REPLACE case device(Config.DeviceConfig) - /// - /// TODO: REPLACE case position(Config.PositionConfig) - /// - /// TODO: REPLACE case power(Config.PowerConfig) - /// - /// TODO: REPLACE case wifi(Config.WiFiConfig) - /// - /// TODO: REPLACE case display(Config.DisplayConfig) - /// - /// TODO: REPLACE case lora(Config.LoRaConfig) #if !swift(>=4.1) @@ -166,7 +142,6 @@ struct Config { /// /// This setting is never saved to disk, but if set, all device settings will be returned to factory defaults. - /// (Region, serial number etc... will be preserved) var factoryReset: Bool = false /// @@ -182,7 +157,6 @@ struct Config { /// /// Defines the device's role on the Mesh network - /// unset - 0 enum Role: SwiftProtobuf.Enum { typealias RawValue = Int @@ -191,24 +165,19 @@ struct Config { case client // = 0 /// - /// ClientMute device role - /// This is like the client but packets will not hop over this node. Would be - /// useful if you want to save power by not contributing to the mesh. + /// Client Mute device role + /// Same as a client except packets will not hop over this node, does not contribute to routing packets for mesh. case clientMute // = 1 /// /// Router device role. - /// Uses an agressive algirithem for the flood networking so packets will - /// prefer to be routed over this node. Also assume that this will be - /// unattended and so will turn off the wifi/ble radio as well as the oled screen. + /// Mesh packets will prefer to be routed over this node. This node will not be used by client apps. + /// The wifi/ble radios and the oled screen will be put to sleep. case router // = 2 /// - /// RouterClient device role - /// Uses an agressive algirithem for the flood networking so packets will - /// prefer to be routed over this node. Similiar power management as a regular - /// client, so the RouterClient can be used as both a Router and a Client. Useful - /// as a well placed base station that you could also use to send messages. + /// Router Client device role + /// Mesh packets will prefer to be routed over this node. The Router Client can be used as both a Router and an app connected Client. case routerClient // = 3 case UNRECOGNIZED(Int) @@ -331,6 +300,18 @@ struct Config { /// /// Include positional timestamp (from GPS solution) case posTimestamp // = 128 + + /// + /// Include positional heading + /// Intended for use with vehicle not walking speeds + /// walking speeds are likely to be error prone like the compass + case posHeading // = 256 + + /// + /// Include positional speed + /// Intended for use with vehicle not walking speeds + /// walking speeds are likely to be error prone like the compass + case posSpeed // = 512 case UNRECOGNIZED(Int) init() { @@ -348,6 +329,8 @@ struct Config { case 32: self = .posSatinview case 64: self = .posSeqNos case 128: self = .posTimestamp + case 256: self = .posHeading + case 512: self = .posSpeed default: self = .UNRECOGNIZED(rawValue) } } @@ -363,6 +346,8 @@ struct Config { case .posSatinview: return 32 case .posSeqNos: return 64 case .posTimestamp: return 128 + case .posHeading: return 256 + case .posSpeed: return 512 case .UNRECOGNIZED(let i): return i } } @@ -389,7 +374,7 @@ struct Config { /// If set, we are powered from a low-current source (i.e. solar), so even if it looks like we have power flowing in /// we should try to minimize power consumption as much as possible. /// YOU DO NOT NEED TO SET THIS IF YOU'VE set is_router (it is implied in that case). - /// CLI Only Option + /// Advanced Option var isPowerSaving: Bool = false /// @@ -399,11 +384,13 @@ struct Config { /// /// Ratio of voltage divider for battery pin eg. 3.20 (R1=100k, R2=220k) /// Overrides the ADC_MULTIPLIER defined in variant for battery voltage calculation. + /// Should be set to floating point value between 2 and 4 + /// Fixes issues on Heltec v2 var adcMultiplierOverride: Float = 0 /// /// Wait Bluetooth Seconds - /// The number of seconds for to wait before turning of BLE in No Bluetooth states\ + /// The number of seconds for to wait before turning off BLE in No Bluetooth states /// 0 for default of 1 minute var waitBluetoothSecs: UInt32 = 0 @@ -425,7 +412,7 @@ struct Config { /// Light Sleep Seconds /// In light sleep the CPU is suspended, LoRa radio is on, BLE is off an GPS is on /// ESP32 Only - /// 0 for default of 3600 + /// 0 for default of 300 var lsSecs: UInt32 = 0 /// @@ -441,73 +428,22 @@ struct Config { /// **TBEAM 1.1 Only** enum ChargeCurrent: SwiftProtobuf.Enum { typealias RawValue = Int - - /// - /// TODO: REPLACE case maunset // = 0 - - /// - /// TODO: REPLACE case ma100 // = 1 - - /// - /// TODO: REPLACE case ma190 // = 2 - - /// - /// TODO: REPLACE case ma280 // = 3 - - /// - /// TODO: REPLACE case ma360 // = 4 - - /// - /// TODO: REPLACE case ma450 // = 5 - - /// - /// TODO: REPLACE case ma550 // = 6 - - /// - /// TODO: REPLACE case ma630 // = 7 - - /// - /// TODO: REPLACE case ma700 // = 8 - - /// - /// TODO: REPLACE case ma780 // = 9 - - /// - /// TODO: REPLACE case ma880 // = 10 - - /// - /// TODO: REPLACE case ma960 // = 11 - - /// - /// TODO: REPLACE case ma1000 // = 12 - - /// - /// TODO: REPLACE case ma1080 // = 13 - - /// - /// TODO: REPLACE case ma1160 // = 14 - - /// - /// TODO: REPLACE case ma1240 // = 15 - - /// - /// TODO: REPLACE case ma1320 // = 16 case UNRECOGNIZED(Int) @@ -567,7 +503,7 @@ struct Config { } /// - /// TODO: REPLACE + /// WiFi Config struct WiFiConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for @@ -604,13 +540,12 @@ struct Config { // methods supported on all messages. /// - /// Power management state machine option. - /// See [power management](/docs/software/other/power) for details. - /// 0 for default of one minute + /// Number of seconds the screen stays on after pressing the user button or receiving a message + /// 0 for default of one minute MAXUINT for always on var screenOnSecs: UInt32 = 0 /// - /// How the GPS coordinates are displayed on the OLED screen. + /// How the GPS coordinates are formatted on the OLED screen. var gpsFormat: Config.DisplayConfig.GpsCoordinateFormat = .gpsFormatDec /// @@ -636,24 +571,24 @@ struct Config { case gpsFormatDms // = 1 /// - /// GPS coordinates are displayed in Universal Transverse Mercator format: + /// Universal Transverse Mercator format: /// ZZB EEEEEE NNNNNNN, where Z is zone, B is band, E is easting, N is northing case gpsFormatUtm // = 2 /// - /// GPS coordinates are displayed in Military Grid Reference System format: + /// Military Grid Reference System format: /// ZZB CD EEEEE NNNNN, where Z is zone, B is band, C is the east 100k square, D is the north 100k square, /// E is easting, N is northing case gpsFormatMgrs // = 3 /// - /// GPS coordinates are displayed in Open Location Code (aka Plus Codes). + /// Open Location Code (aka Plus Codes). case gpsFormatOlc // = 4 /// - /// GPS coordinates are displayed in Ordnance Survey Grid Reference (the National Grid System of the UK). - /// Format: AB EEEEE NNNNN, where A is the east 100k square, B is the north 100k square, E is the easting, - /// N is the northing + /// Ordnance Survey Grid Reference (the National Grid System of the UK). + /// Format: AB EEEEE NNNNN, where A is the east 100k square, B is the north 100k square, + /// E is the easting, N is the northing case gpsFormatOsgr // = 5 case UNRECOGNIZED(Int) @@ -691,7 +626,7 @@ struct Config { } /// - /// TODO: REPLACE + /// Lora Config struct LoRaConfig { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for @@ -705,7 +640,6 @@ struct Config { var txPower: Int32 = 0 /// - /// Note: This is the 'old' mechanism for specifying channel parameters. /// Either modem_config or bandwidth/spreading/coding will be specified - NOT BOTH. /// As a heuristic: If bandwidth is specified, do not use modem_config. /// Because protobufs take ZERO space when the value is zero this works out nicely. @@ -736,11 +670,12 @@ struct Config { var frequencyOffset: Float = 0 /// - /// The region code for my radio (US, CN, EU433, etc...) + /// The region code for the radio (US, CN, EU433, etc...) var region: Config.LoRaConfig.RegionCode = .unset /// /// Overrides HOPS_RELIABLE and sets the maximum number of hops. This can't be greater than 7. + /// 0 for default of 3 var hopLimit: UInt32 = 0 /// @@ -756,66 +691,59 @@ struct Config { var unknownFields = SwiftProtobuf.UnknownStorage() - /// - /// The frequency/regulatory region the user has selected. - /// Note: In 1.0 builds (which must still be supported by the android app for a - /// long time) this field will be unpopulated. - /// If firmware is ever upgraded from an old 1.0ish build, the old - /// MyNodeInfo.region string will be used to set UserPreferences.region and the - /// old value will be no longer set. enum RegionCode: SwiftProtobuf.Enum { typealias RawValue = Int /// - /// TODO: REPLACE + /// Region is not set case unset // = 0 /// - /// TODO: REPLACE + /// United States case us // = 1 /// - /// TODO: REPLACE + /// European Union 433mhz case eu433 // = 2 /// - /// TODO: REPLACE + /// European Union 433mhz case eu868 // = 3 /// - /// TODO: REPLACE + /// China case cn // = 4 /// - /// TODO: REPLACE + /// Japan case jp // = 5 /// - /// TODO: REPLACE + /// Australia / New Zealand case anz // = 6 /// - /// TODO: REPLACE + /// Korea case kr // = 7 /// - /// TODO: REPLACE + /// Taiwan case tw // = 8 /// - /// TODO: REPLACE + /// Russia case ru // = 9 /// - /// TODO: REPLACE + /// India case `in` // = 10 /// - /// TODO: REPLACE + /// New Zealand 865mhz case nz865 // = 11 /// - /// TODO: REPLACE + /// Thailand case th // = 12 case UNRECOGNIZED(Int) @@ -870,31 +798,31 @@ struct Config { typealias RawValue = Int /// - /// TODO: REPLACE + /// Long Range - Fast case longFast // = 0 /// - /// TODO: REPLACE + /// Long Range - Slow case longSlow // = 1 /// - /// TODO: REPLACE + /// Very Long Range - Slow case vlongSlow // = 2 /// - /// TODO: REPLACE + /// Medium Range - Slow case midSlow // = 3 /// - /// TODO: REPLACE + /// Medium Range - Fast case midFast // = 4 /// - /// TODO: REPLACE + /// Short Range - Slow case shortSlow // = 5 /// - /// TODO: REPLACE + /// Short Range - Fast case shortFast // = 6 case UNRECOGNIZED(Int) @@ -960,6 +888,8 @@ extension Config.PositionConfig.PositionFlags: CaseIterable { .posSatinview, .posSeqNos, .posTimestamp, + .posHeading, + .posSpeed, ] } @@ -1337,6 +1267,8 @@ extension Config.PositionConfig.PositionFlags: SwiftProtobuf._ProtoNameProviding 32: .same(proto: "POS_SATINVIEW"), 64: .same(proto: "POS_SEQ_NOS"), 128: .same(proto: "POS_TIMESTAMP"), + 256: .same(proto: "POS_HEADING"), + 512: .same(proto: "POS_SPEED"), ] } diff --git a/MeshtasticApple/Views/Settings/DeviceConfig.swift b/MeshtasticApple/Views/Settings/DeviceConfig.swift index 90fbe166..75099874 100644 --- a/MeshtasticApple/Views/Settings/DeviceConfig.swift +++ b/MeshtasticApple/Views/Settings/DeviceConfig.swift @@ -22,7 +22,7 @@ enum DeviceRoles: Int, CaseIterable, Identifiable { case .client: return "Client (default)" case .clientMute: - return "Client Mute - Packets will not hop over this node, does not contribute to routing packets for mesh." + return "Client Mute - Same as a client except packets will not hop over this node, does not contribute to routing packets for mesh." case .router: return "Router - Mesh packets will prefer to be routed over this node. This node will not be used by client apps. The wifi/ble radios and the oled screen will be put to sleep." case .routerClient: diff --git a/MeshtasticApple/Views/Settings/LoRaConfig.swift b/MeshtasticApple/Views/Settings/LoRaConfig.swift index f4c2abe1..17078884 100644 --- a/MeshtasticApple/Views/Settings/LoRaConfig.swift +++ b/MeshtasticApple/Views/Settings/LoRaConfig.swift @@ -28,7 +28,7 @@ enum RegionCodes : Int, CaseIterable, Identifiable { get { switch self { case .unset: - return "UNSET - Please set a Region" + return "Please set a region" case .us: return "United States" case .eu433: @@ -107,19 +107,19 @@ enum ModemPresets : Int, CaseIterable, Identifiable { switch self { case .LongFast: - return "Long Fast" + return "Long Range - Fast" case .LongSlow: - return "Long Slow" + return "Long Range - Slow" case .VLongSlow: - return "Very Long Slow" + return "Very Long Range - Slow" case .MidSlow: - return "Mid Slow" + return "Medium Range - Slow" case .MidFast: - return "Mid Fast" + return "Medium Range - Fast" case .ShortSlow: - return "Short Slow" + return "Short Range - Slow" case .ShortFast: - return "Short Fast" + return "Short Range - Fast" } } } @@ -146,12 +146,48 @@ enum ModemPresets : Int, CaseIterable, Identifiable { } } +enum HopValues : Int, CaseIterable, Identifiable { + + case oneHop = 1 + case twoHops = 2 + case threeHops = 0 + case fourHops = 4 + case fiveHops = 5 + case sixHops = 6 + case sevenHops = 7 + + var id: Int { self.rawValue } + var description: String { + get { + switch self { + + case .oneHop: + return "One Hop" + case .twoHops: + return "Two Hops" + case .threeHops: + return "Three Hops" + case .fourHops: + return "Four Hops" + case .fiveHops: + return "Five Hops" + case .sixHops: + return "Six Hops" + case .sevenHops: + return "Seven Hops" + } + } + } +} + struct LoRaConfig: View { @Environment(\.managedObjectContext) var context @EnvironmentObject var bleManager: BLEManager - @State var region = 1 + @State private var isPresentingSaveConfirm: Bool = false + + @State var region = 0 @State var modemPreset = 0 @State var hopLimit = 0 @State var hasChanges = false @@ -169,10 +205,9 @@ struct LoRaConfig: View { } } .pickerStyle(DefaultPickerStyle()) - Text("The region where you will be using your Meshtastic LoRa radios.") + Text("The region where you will be using your radios.") .font(.caption) .listRowSeparator(.visible) - .listRowSeparator(.visible) } Section(header: Text("Modem")) { Picker("Presets", selection: $region ) { @@ -181,38 +216,27 @@ struct LoRaConfig: View { } } .pickerStyle(DefaultPickerStyle()) - Text("Available modem presets.") + Text("Available modem presets, default is Long Fast.") .font(.caption) .listRowSeparator(.visible) - .listRowSeparator(.visible) } Section(header: Text("Mesh Options")) { Picker("Number of hops", selection: $hopLimit) { - ForEach(0..<8) { - if $0 == 0 { - Text("Default") - } else { - Text("\($0) Hops") - } + ForEach(HopValues.allCases) { hop in + Text(hop.description) } } .pickerStyle(DefaultPickerStyle()) + Text("Sets the maximum number of hops, default is 3.") + .font(.caption) + .listRowSeparator(.visible) } } Button { - var lc = Config.LoRaConfig() - lc.hopLimit = UInt32(hopLimit) - lc.region = RegionCodes(rawValue: region)!.protoEnumValue() - lc.modemPreset = ModemPresets(rawValue: modemPreset)!.protoEnumValue() - - if bleManager.saveLoRaConfig(config: lc, destNum: bleManager.connectedPeripheral.num, wantResponse: false) { - - } else { - - } + isPresentingSaveConfirm = true } label: { Label("Save", systemImage: "square.and.arrow.down") @@ -222,6 +246,28 @@ struct LoRaConfig: View { .buttonBorderShape(.capsule) .controlSize(.large) .padding() + .confirmationDialog( + "Are you sure?", + isPresented: $isPresentingSaveConfirm + ) { + Button("Save LoRa Config to device?") { + + var lc = Config.LoRaConfig() + lc.hopLimit = UInt32(hopLimit) + lc.region = RegionCodes(rawValue: region)!.protoEnumValue() + lc.modemPreset = ModemPresets(rawValue: modemPreset)!.protoEnumValue() + + if bleManager.saveLoRaConfig(config: lc, destNum: bleManager.connectedPeripheral.num, wantResponse: false) { + + // Should show a saved successfully alert once I know that to be true + // for now just disable the button after a successful save + hasChanges = false + + } else { + + } + } + } } .navigationTitle("LoRa Config") @@ -235,7 +281,7 @@ struct LoRaConfig: View { self.bleManager.context = context } - .onChange(of: region) { newRegion in + .onChange(of: region) { newModemPreset in hasChanges = true } diff --git a/MeshtasticApple/Views/Settings/PositionConfig.swift b/MeshtasticApple/Views/Settings/PositionConfig.swift index ffb675e4..05c27867 100644 --- a/MeshtasticApple/Views/Settings/PositionConfig.swift +++ b/MeshtasticApple/Views/Settings/PositionConfig.swift @@ -118,8 +118,14 @@ struct PositionConfig: View { @State var gpsAttemptTime = 0 @State var positionBroadcastSeconds = 0 - @State var includeAltitude = false - @State var includeSatInView = false + @State var includePosAltitude = false + @State var includePosSatsinview = false + @State var includePosSeqNos = false + @State var includePosTimestamp = false + @State var includePosSpeed = false + @State var includePosHeading = false + + var body: some View { @@ -203,30 +209,44 @@ struct PositionConfig: View { .font(.caption) .listRowSeparator(.visible) - Toggle(isOn: $includeAltitude) { + Toggle(isOn: $includePosAltitude) { - Label("Include Altitude", systemImage: "arrow.up") + Label("Altitude", systemImage: "arrow.up") } .toggleStyle(DefaultToggleStyle()) .listRowSeparator(.visible) - Toggle(isOn: $includeSatInView) { + Toggle(isOn: $includePosSatsinview) { - Label("Include number of satellites in view", systemImage: "skew") + Label("Number of satellites", systemImage: "skew") } .toggleStyle(DefaultToggleStyle()) .listRowSeparator(.visible) - Toggle(isOn: $includeSatInView) { //64 + Toggle(isOn: $includePosSeqNos) { //64 - Label("Include a sequence number incremented per packet", systemImage: "number") + Label("Sequence number", systemImage: "number") } .toggleStyle(DefaultToggleStyle()) .listRowSeparator(.visible) - Toggle(isOn: $includeSatInView) { //128 + Toggle(isOn: $includePosTimestamp) { //128 - Label("Include positional timestamp", systemImage: "clock") + Label("Timestamp", systemImage: "clock") + } + .toggleStyle(DefaultToggleStyle()) + .listRowSeparator(.visible) + + Toggle(isOn: $includePosHeading) { //128 + + Label("Vehicle heading", systemImage: "location.circle") + } + .toggleStyle(DefaultToggleStyle()) + .listRowSeparator(.visible) + + Toggle(isOn: $includePosSpeed) { //128 + + Label("Vehicle speed", systemImage: "speedometer") } .toggleStyle(DefaultToggleStyle()) .listRowSeparator(.visible) From e842de9086ffc91a16a80225e3bd8312016f0456 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Mon, 20 Jun 2022 12:56:40 -0700 Subject: [PATCH 08/11] Check for nil connectedPeripheral --- MeshtasticApple/Views/Settings/LoRaConfig.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MeshtasticApple/Views/Settings/LoRaConfig.swift b/MeshtasticApple/Views/Settings/LoRaConfig.swift index 17078884..9fb5afa6 100644 --- a/MeshtasticApple/Views/Settings/LoRaConfig.swift +++ b/MeshtasticApple/Views/Settings/LoRaConfig.swift @@ -250,7 +250,7 @@ struct LoRaConfig: View { "Are you sure?", isPresented: $isPresentingSaveConfirm ) { - Button("Save LoRa Config to device?") { + Button("Save LoRa Config to \(bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : "Unknown")?") { var lc = Config.LoRaConfig() lc.hopLimit = UInt32(hopLimit) From cc8b90607514d82301a4e6193506baa87e5fbcf0 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Mon, 20 Jun 2022 22:26:35 -0700 Subject: [PATCH 09/11] Save LoRa Config --- MeshtasticApple/Helpers/BLEManager.swift | 5 +- MeshtasticApple/Helpers/MeshPackets.swift | 155 +++++++++++++----- .../contents | 7 +- .../Views/Settings/LoRaConfig.swift | 15 +- MeshtasticApple/Views/Settings/Settings.swift | 18 +- 5 files changed, 146 insertions(+), 54 deletions(-) diff --git a/MeshtasticApple/Helpers/BLEManager.swift b/MeshtasticApple/Helpers/BLEManager.swift index a4bc4254..d442b3a0 100644 --- a/MeshtasticApple/Helpers/BLEManager.swift +++ b/MeshtasticApple/Helpers/BLEManager.swift @@ -427,15 +427,14 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph connectedPeripheral.name = nodeInfo!.user!.longName ?? "Unknown" connectedPeripheral.shortName = nodeInfo!.user!.shortName ?? "?????" + connectedPeripheral.longName = nodeInfo!.user!.longName ?? "Unknown" } } } } else if decodedInfo.config.isInitialized { - localConfig(config: decodedInfo.config, meshlogging: meshLoggingEnabled, context: context!, nodeLongName: self.connectedPeripheral.longName) - if meshLoggingEnabled { MeshLogger.log("ℹ️ MESH PACKET received for Unknown App decodedInfo.config.isInitialized \(try! decodedInfo.config.jsonString())") } - + localConfig(config: decodedInfo.config, meshlogging: meshLoggingEnabled, context: context!, nodeNum: self.connectedPeripheral.num, nodeLongName: self.connectedPeripheral.longName) } else { diff --git a/MeshtasticApple/Helpers/MeshPackets.swift b/MeshtasticApple/Helpers/MeshPackets.swift index 68976fb2..bb8a0861 100644 --- a/MeshtasticApple/Helpers/MeshPackets.swift +++ b/MeshtasticApple/Helpers/MeshPackets.swift @@ -9,61 +9,130 @@ import Foundation import CoreData import SwiftUI -func localConfig (config: Config, meshlogging: Bool, context:NSManagedObjectContext, nodeLongName: String) { +func localConfig (config: Config, meshlogging: Bool, context:NSManagedObjectContext, nodeNum: Int64, nodeLongName: String) { // We don't care about any of the Power settings // We don't want to manage wifi from the phone app and disconnect our device //if meshlogging { MeshLogger.log("⚙️ Local Config version \(config.version) received for \(nodeLongName)") } - if (try! config.device.jsonString()) == "{}" { +// if (try! config.device.jsonString()) == "{}" { +// +// print("📟 Default Device config") +// +// } else { +// +// print("📟 Has Device config") +// } +// +// if (try! config.position.jsonString()) == "{}" { +// +// print("📍 Default Position config") +// +// } else { +// +// print("📍 Has Position config") +// } +// +// if (try! config.power.jsonString() == "{\"lsSecs\":300}") { +// +// print("📍 Default Power config") +// print(try! config.power.jsonString()) +// +// } else { +// +// print("📍 Has Power config") +// print(try! config.power.jsonString()) +// } +// +// if (try! config.display.jsonString()) == "{}" { +// +// print("🖥️ Default Display config") +// +// } else { +// +// print("🖥️ Has Display config") +// } - print("📟 Default Device config") + if config.payloadVariant == Config.OneOf_PayloadVariant.lora(config.lora) { - } else { + var isDefault = false - print("📟 Has Device config") - } - - if (try! config.position.jsonString()) == "{}" { + if (try! config.lora.jsonString()) == "{}" { + + isDefault = true + } - print("📍 Default Position config") + let fetchNodeInfoRequest: NSFetchRequest = NSFetchRequest.init(entityName: "NodeInfoEntity") + fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum)) - } else { - - print("📍 Has Position config") - } - - if (try! config.power.jsonString() == "{\"lsSecs\":300}") { - - print("📍 Default Power config") - print(try! config.power.jsonString()) - - } else { - - print("📍 Has Power config") - print(try! config.power.jsonString()) - } - - if (try! config.display.jsonString()) == "{}" { - - print("🖥️ Default Display config") - - } else { - - print("🖥️ Has Display config") - } - + do { - + let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity] + // Found a node, save LoRa Config + if !fetchedNode.isEmpty { + + if fetchedNode[0].loRaConfig == nil { + + let newLoRaConfig = LoRaConfigEntity(context: context) + + if isDefault { + + // UNSET default protobuf value of 0 + newLoRaConfig.regionCode = 0 + // LongFast default protobuf value of 0 + newLoRaConfig.modemPreset = 0 + // 3 Hops default protobuf value of 0 + newLoRaConfig.hopLimit = 0 + } else { + + // UNSET default protobuf value of 0 + newLoRaConfig.regionCode = Int32(config.lora.region.rawValue) + // LongFast default protobuf value of 0 + newLoRaConfig.modemPreset = Int32(config.lora.modemPreset.rawValue) + // 3 Hops default protobuf value of 0 + newLoRaConfig.hopLimit = Int32(config.lora.hopLimit) + } + + fetchedNode[0].loRaConfig = newLoRaConfig + + } else { + + if isDefault { + + // UNSET default protobuf value of 0 + fetchedNode[0].loRaConfig?.regionCode = 0 + // LongFast default protobuf value of 0 + fetchedNode[0].loRaConfig?.modemPreset = 0 + // 3 Hops default protobuf value of 0 + fetchedNode[0].loRaConfig?.hopLimit = 0 + + } else { + // UNSET default protobuf value of 0 + fetchedNode[0].loRaConfig?.regionCode = Int32(config.lora.region.rawValue) + // LongFast default protobuf value of 0 + fetchedNode[0].loRaConfig?.modemPreset = Int32(config.lora.modemPreset.rawValue) + // 3 Hops default protobuf value of 0 + fetchedNode[0].loRaConfig?.hopLimit = Int32(config.lora.hopLimit) + } + } + + do { - - if (try! config.lora.jsonString()) == "{}" { - - print("📡 Default LoRa config") - - } else { - - print("📡 Has LoRa config") + try context.save() + if meshlogging { MeshLogger.log("💾 Updated LoRaConfig for node number: \(String(nodeNum))") } + + } catch { + + context.rollback() + + let nsError = error as NSError + print("💥 Error Updating Core Data MyInfoEntity: \(nsError)") + } + } + + } catch { + + } } } diff --git a/MeshtasticApple/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents b/MeshtasticApple/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents index 71115514..3039ae3b 100644 --- a/MeshtasticApple/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents +++ b/MeshtasticApple/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents @@ -1,10 +1,11 @@ + - + @@ -52,7 +53,7 @@ - + @@ -100,7 +101,7 @@ - + diff --git a/MeshtasticApple/Views/Settings/LoRaConfig.swift b/MeshtasticApple/Views/Settings/LoRaConfig.swift index 9fb5afa6..b10823c9 100644 --- a/MeshtasticApple/Views/Settings/LoRaConfig.swift +++ b/MeshtasticApple/Views/Settings/LoRaConfig.swift @@ -185,8 +185,10 @@ struct LoRaConfig: View { @Environment(\.managedObjectContext) var context @EnvironmentObject var bleManager: BLEManager - @State private var isPresentingSaveConfirm: Bool = false + var node: NodeInfoEntity + @State private var isPresentingSaveConfirm: Bool = false + @State var loadCount = 0 @State var region = 0 @State var modemPreset = 0 @State var hopLimit = 0 @@ -210,7 +212,7 @@ struct LoRaConfig: View { .listRowSeparator(.visible) } Section(header: Text("Modem")) { - Picker("Presets", selection: $region ) { + Picker("Presets", selection: $modemPreset ) { ForEach(ModemPresets.allCases) { m in Text(m.description) } @@ -280,6 +282,15 @@ struct LoRaConfig: View { .onAppear { self.bleManager.context = context + if loadCount == 0 { + + print("got hops \(node.loRaConfig?.hopLimit ?? 0)") + self.hopLimit = Int(node.loRaConfig?.hopLimit ?? 0) + self.region = Int(node.loRaConfig?.regionCode ?? 0) + self.modemPreset = Int(node.loRaConfig?.modemPreset ?? 0) + self.hasChanges = false + } + loadCount+=1 } .onChange(of: region) { newModemPreset in diff --git a/MeshtasticApple/Views/Settings/Settings.swift b/MeshtasticApple/Views/Settings/Settings.swift index a436150f..882efb64 100644 --- a/MeshtasticApple/Views/Settings/Settings.swift +++ b/MeshtasticApple/Views/Settings/Settings.swift @@ -13,7 +13,13 @@ struct Settings: View { @EnvironmentObject var bleManager: BLEManager @EnvironmentObject var userSettings: UserSettings -// var connectednode: NodeInfoEntity + + + @FetchRequest( + sortDescriptors: [NSSortDescriptor(key: "lastHeard", ascending: false)], + animation: .default) + + private var nodes: FetchedResults var body: some View { NavigationView { @@ -55,8 +61,12 @@ struct Settings: View { .symbolRenderingMode(.hierarchical) Text("Display (Device Screen)") } - NavigationLink { - LoRaConfig() + + let connectedNodeNum = bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.num : 0 + + NavigationLink() { + + LoRaConfig(node: nodes.first(where: { $0.num == connectedNodeNum }) ?? NodeInfoEntity()) } label: { Image(systemName: "dot.radiowaves.left.and.right") @@ -64,6 +74,8 @@ struct Settings: View { Text("LoRa") } + .disabled(bleManager.connectedPeripheral == nil) + NavigationLink { PositionConfig() } label: { From b93ec723f12b98d4588445e06400f63757bc5510 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Mon, 20 Jun 2022 22:48:38 -0700 Subject: [PATCH 10/11] Mostly complete lora config --- MeshtasticApple/Views/Settings/LoRaConfig.swift | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/MeshtasticApple/Views/Settings/LoRaConfig.swift b/MeshtasticApple/Views/Settings/LoRaConfig.swift index b10823c9..19e16043 100644 --- a/MeshtasticApple/Views/Settings/LoRaConfig.swift +++ b/MeshtasticApple/Views/Settings/LoRaConfig.swift @@ -188,7 +188,6 @@ struct LoRaConfig: View { var node: NodeInfoEntity @State private var isPresentingSaveConfirm: Bool = false - @State var loadCount = 0 @State var region = 0 @State var modemPreset = 0 @State var hopLimit = 0 @@ -282,17 +281,19 @@ struct LoRaConfig: View { .onAppear { self.bleManager.context = context - if loadCount == 0 { - + } + .task { + do { print("got hops \(node.loRaConfig?.hopLimit ?? 0)") self.hopLimit = Int(node.loRaConfig?.hopLimit ?? 0) self.region = Int(node.loRaConfig?.regionCode ?? 0) self.modemPreset = Int(node.loRaConfig?.modemPreset ?? 0) self.hasChanges = false + } catch { + print("Failed to load node data") } - loadCount+=1 } - .onChange(of: region) { newModemPreset in + .onChange(of: region) { newRegion in hasChanges = true } From 06fdd14c2d888e6a0be41eefe14257b96d589557 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Mon, 20 Jun 2022 22:52:28 -0700 Subject: [PATCH 11/11] Bump version and warnings nobody reads --- Meshtastic Apple.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Meshtastic Apple.xcodeproj/project.pbxproj b/Meshtastic Apple.xcodeproj/project.pbxproj index 5a0f433e..edbac879 100644 --- a/Meshtastic Apple.xcodeproj/project.pbxproj +++ b/Meshtastic Apple.xcodeproj/project.pbxproj @@ -810,7 +810,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.3.19; + MARKETING_VERSION = 1.3.20; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -841,7 +841,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.3.19; + MARKETING_VERSION = 1.3.20; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES;