From c0586f71e3a543a92e6167cf775ac5ea60c15349 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Thu, 16 Mar 2023 17:46:44 -0700 Subject: [PATCH 01/13] Don't disconnect after oat reboot message Sort BLE devices alphabetically by name --- Meshtastic/Views/Bluetooth/Connect.swift | 2 +- Meshtastic/Views/Settings/Firmware.swift | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Meshtastic/Views/Bluetooth/Connect.swift b/Meshtastic/Views/Bluetooth/Connect.swift index 6fd4844c..32b25c29 100644 --- a/Meshtastic/Views/Bluetooth/Connect.swift +++ b/Meshtastic/Views/Bluetooth/Connect.swift @@ -160,7 +160,7 @@ struct Connect: View { if !self.bleManager.isConnected { Section(header: Text("available.radios").font(.title)) { - ForEach(bleManager.peripherals.filter({ $0.peripheral.state == CBPeripheralState.disconnected }).sorted(by: { $0.name > $1.name })) { peripheral in + ForEach(bleManager.peripherals.filter({ $0.peripheral.state == CBPeripheralState.disconnected }).sorted(by: { $0.name < $1.name })) { peripheral in HStack { if userSettings.preferredPeripheralId == peripheral.peripheral.identifier.uuidString { Image(systemName: "star.fill") diff --git a/Meshtastic/Views/Settings/Firmware.swift b/Meshtastic/Views/Settings/Firmware.swift index fa9965c4..54b692ce 100644 --- a/Meshtastic/Views/Settings/Firmware.swift +++ b/Meshtastic/Views/Settings/Firmware.swift @@ -78,9 +78,7 @@ struct Firmware: View { if connectedNode != nil { if !bleManager.sendRebootOta(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode!.myInfo!.adminIndex) { print("Reboot Failed") - } else { - bleManager.disconnectPeripheral(reconnect: false) - } + } } } label: { Label("Send Reboot OTA", systemImage: "square.and.arrow.down") From b492989658ffa99eb40e3e7ca60e0ae08680ee4b Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Fri, 17 Mar 2023 08:32:04 -0700 Subject: [PATCH 02/13] Remove underscores from HardwareModels enum --- Meshtastic/Enums/HardwareModels.swift | 170 +++++++++++------------ Meshtastic/Views/Settings/Firmware.swift | 4 + 2 files changed, 89 insertions(+), 85 deletions(-) diff --git a/Meshtastic/Enums/HardwareModels.swift b/Meshtastic/Enums/HardwareModels.swift index de6e9331..b857fd1f 100644 --- a/Meshtastic/Enums/HardwareModels.swift +++ b/Meshtastic/Enums/HardwareModels.swift @@ -10,27 +10,27 @@ import Foundation enum HardwareModels: String, CaseIterable, Identifiable { case UNSET - case TLORA_V2 - case TLORA_V1 - case TLORA_V2_1_1P6 + case TLORAV2 + case TLORAV1 + case TLORAV211P6 case TBEAM - case HELTEC_V2_0 - case TBEAM_V0P7 - case T_ECHO - case TLORA_V1_1P3 + case HELTECV20 + case TBEAMV0P7 + case TECHO + case TLORAV11P3 case RAK4631 - case HELTEC_V2_1 - case HELTEC_V1 - case LILYGO_TBEAM_S3_CORE + case HELTECV21 + case HELTECV1 + case LILYGOTBEAMS3CORE case RAK11200 - case NANO_G1 - case TLORA_V2_1_1P8 - case TLORA_T3_S3 - case NANO_G1_EXPLORER - case STATION_G1 + case NANOG1 + case TLORAV211P8 + case TLORAT3S3 + case NANOG1EXPLORER + case STATIONG1 case M5STACK - case HELTEC_V3 - case HELTEC_WSL_V3 + case HELTECV3 + case HELTECWSLV3 var id: String { self.rawValue } var description: String { @@ -38,47 +38,47 @@ enum HardwareModels: String, CaseIterable, Identifiable { case .UNSET: return NSLocalizedString("unset", comment: "UNSET") - case .TLORA_V2: + case .TLORAV2: return "TLoRa V2" - case .TLORA_V1: + case .TLORAV1: return "TLoRa V1" - case .TLORA_V2_1_1P6: + case .TLORAV211P6: return "TLoRa V2.1.1.6" case .TBEAM: return "TBeam" - case .HELTEC_V2_0: + case .HELTECV20: return "HELTEC V2.0" - case .TBEAM_V0P7: + case .TBEAMV0P7: return "TBeam 0.7" - case .T_ECHO: + case .TECHO: return "TEcho" - case .TLORA_V1_1P3: + case .TLORAV11P3: return "TLORA V1.1.3" case .RAK4631: return "RAK 4631 NRF" - case .HELTEC_V2_1: + case .HELTECV21: return "HELTEC V2.1" - case .HELTEC_V1: + case .HELTECV1: return "HELTEC V1" - case .LILYGO_TBEAM_S3_CORE: + case .LILYGOTBEAMS3CORE: return "TBEAM S3" case .RAK11200: return "RAK 11200 ESP32" - case .NANO_G1: + case .NANOG1: return "Nano G1" - case .TLORA_V2_1_1P8: + case .TLORAV211P8: return "TLoRa V2.1.1.8" - case .TLORA_T3_S3: + case .TLORAT3S3: return "TLoRa T3 S3" - case .NANO_G1_EXPLORER: + case .NANOG1EXPLORER: return "Nano G1 Explorer" - case .STATION_G1: + case .STATIONG1: return "Station G1" case .M5STACK: return "M5 Stack" - case .HELTEC_V3: + case .HELTECV3: return "Heltec V3" - case .HELTEC_WSL_V3: + case .HELTECWSLV3: return "Heltec wireless stick lite V3" } @@ -88,47 +88,47 @@ enum HardwareModels: String, CaseIterable, Identifiable { case .UNSET: return [] - case .TLORA_V2: + case .TLORAV2: return ["firmware-tlora-v2-"] - case .TLORA_V1: + case .TLORAV1: return ["firmware-tlora-v1-"] - case .TLORA_V2_1_1P6: + case .TLORAV211P6: return ["firmware-tlora-v2-1-1.6-"] case .TBEAM: return ["firmware-tbeam-"] - case .HELTEC_V2_0: + case .HELTECV20: return ["firmware-heltec-v2.0-"] - case .TBEAM_V0P7: + case .TBEAMV0P7: return ["firmware-tbeam0.7-"] - case .T_ECHO: + case .TECHO: return ["firmware-t-echo-"] - case .TLORA_V1_1P3: + case .TLORAV11P3: return ["firmware-tlora_v1_3-"] case .RAK4631: return ["firmware-rak4631-", "firmware-rak4631_eink-"] - case .HELTEC_V2_1: + case .HELTECV21: return ["firmware-heltec-v2.1-"] - case .HELTEC_V1: + case .HELTECV1: return ["firmware-heltec-v1-"] - case .LILYGO_TBEAM_S3_CORE: + case .LILYGOTBEAMS3CORE: return ["firmware-tbeam-s3-core-"] case .RAK11200: return ["firmware-rak11200-"] - case .NANO_G1: + case .NANOG1: return ["firmware-nano-g1-"] - case .TLORA_V2_1_1P8: + case .TLORAV211P8: return ["firmware-tlora-v2-1-1.8-"] - case .TLORA_T3_S3: + case .TLORAT3S3: return ["firmware-tlora-t3s3-v1-"] - case .NANO_G1_EXPLORER: + case .NANOG1EXPLORER: return ["firmware-nano-g1-explorer-"] - case .STATION_G1: + case .STATIONG1: return ["firmware-station-g1-"] case .M5STACK: return ["firmware-m5stack-core-", "firmware-m5stack-coreink-"] - case .HELTEC_V3: + case .HELTECV3: return ["firmware-heltec-v3-"] - case .HELTEC_WSL_V3: + case .HELTECWSLV3: return ["firmware-heltec-wsl-v3-"] } @@ -139,47 +139,47 @@ enum HardwareModels: String, CaseIterable, Identifiable { case .UNSET: return HardwarePlatforms.NONE - case .TLORA_V2: + case .TLORAV2: return HardwarePlatforms.ESP32 - case .TLORA_V1: + case .TLORAV1: return HardwarePlatforms.ESP32 - case .TLORA_V2_1_1P6: + case .TLORAV211P6: return HardwarePlatforms.ESP32 case .TBEAM: return HardwarePlatforms.ESP32 - case .HELTEC_V2_0: + case .HELTECV20: return HardwarePlatforms.ESP32 - case .TBEAM_V0P7: + case .TBEAMV0P7: return HardwarePlatforms.ESP32 - case .T_ECHO: + case .TECHO: return HardwarePlatforms.NRF52 - case .TLORA_V1_1P3: + case .TLORAV11P3: return HardwarePlatforms.ESP32 case .RAK4631: return HardwarePlatforms.NRF52 - case .HELTEC_V2_1: + case .HELTECV21: return HardwarePlatforms.ESP32 - case .HELTEC_V1: + case .HELTECV1: return HardwarePlatforms.ESP32 - case .LILYGO_TBEAM_S3_CORE: + case .LILYGOTBEAMS3CORE: return HardwarePlatforms.ESP32 case .RAK11200: return HardwarePlatforms.ESP32 - case .NANO_G1: + case .NANOG1: return HardwarePlatforms.ESP32 - case .TLORA_V2_1_1P8: + case .TLORAV211P8: return HardwarePlatforms.ESP32 - case .TLORA_T3_S3: + case .TLORAT3S3: return HardwarePlatforms.ESP32 - case .NANO_G1_EXPLORER: + case .NANOG1EXPLORER: return HardwarePlatforms.ESP32 - case .STATION_G1: + case .STATIONG1: return HardwarePlatforms.ESP32 case .M5STACK: return HardwarePlatforms.ESP32 - case .HELTEC_V3: + case .HELTECV3: return HardwarePlatforms.ESP32 - case .HELTEC_WSL_V3: + case .HELTECWSLV3: return HardwarePlatforms.ESP32 } } @@ -189,47 +189,47 @@ enum HardwareModels: String, CaseIterable, Identifiable { case .UNSET: return HardwareModel.unset - case .TLORA_V2: + case .TLORAV2: return HardwareModel.tloraV2 - case .TLORA_V1: + case .TLORAV1: return HardwareModel.tloraV1 - case .TLORA_V2_1_1P6: + case .TLORAV211P6: return HardwareModel.tloraV211P6 case .TBEAM: return HardwareModel.tbeam - case .HELTEC_V2_0: + case .HELTECV20: return HardwareModel.heltecV20 - case .TBEAM_V0P7: + case .TBEAMV0P7: return HardwareModel.tbeamV0P7 - case .T_ECHO: + case .TECHO: return HardwareModel.tEcho - case .TLORA_V1_1P3: + case .TLORAV11P3: return HardwareModel.tloraV11P3 case .RAK4631: return HardwareModel.rak4631 - case .HELTEC_V2_1: + case .HELTECV21: return HardwareModel.heltecV21 - case .HELTEC_V1: + case .HELTECV1: return HardwareModel.heltecV1 - case .LILYGO_TBEAM_S3_CORE: + case .LILYGOTBEAMS3CORE: return HardwareModel.lilygoTbeamS3Core case .RAK11200: return HardwareModel.rak11200 - case .NANO_G1: + case .NANOG1: return HardwareModel.nanoG1 - case .TLORA_V2_1_1P8: + case .TLORAV211P8: return HardwareModel.tloraV211P8 - case .TLORA_T3_S3: + case .TLORAT3S3: return HardwareModel.tloraT3S3 - case .NANO_G1_EXPLORER: + case .NANOG1EXPLORER: return HardwareModel.nanoG1Explorer - case .STATION_G1: + case .STATIONG1: return HardwareModel.stationG1 case .M5STACK: return HardwareModel.m5Stack - case .HELTEC_V3: + case .HELTECV3: return HardwareModel.heltecV3 - case .HELTEC_WSL_V3: + case .HELTECWSLV3: return HardwareModel.heltecWslV3 } } diff --git a/Meshtastic/Views/Settings/Firmware.swift b/Meshtastic/Views/Settings/Firmware.swift index 54b692ce..6d7a7a64 100644 --- a/Meshtastic/Views/Settings/Firmware.swift +++ b/Meshtastic/Views/Settings/Firmware.swift @@ -93,6 +93,10 @@ struct Firmware: View { } else { Text("OTA Updates are not supported on your platform.") .font(.title3) + Text(node?.user?.hwModel ?? "UNSET") + .font(.title3) + Text(hwModel.platform().description) + .font(.title3) } }.padding() From 7ed7c38ff9749ddb0bbaec4caafb847079b92136 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Fri, 17 Mar 2023 08:32:47 -0700 Subject: [PATCH 03/13] Bump version --- Meshtastic.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index b007418b..7c131f75 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -1188,7 +1188,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.1.0; + MARKETING_VERSION = 2.1.2; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -1222,7 +1222,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.1.0; + MARKETING_VERSION = 2.1.2; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; From 398bf8c88e9f5cbcb3d73c766985d1ac22f55c42 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Fri, 17 Mar 2023 23:30:01 -0700 Subject: [PATCH 04/13] Clean up platform enum --- Meshtastic/Enums/HardwareModels.swift | 64 ++++++++++++------------ Meshtastic/Views/Settings/Firmware.swift | 4 +- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/Meshtastic/Enums/HardwareModels.swift b/Meshtastic/Enums/HardwareModels.swift index b857fd1f..59cbc30c 100644 --- a/Meshtastic/Enums/HardwareModels.swift +++ b/Meshtastic/Enums/HardwareModels.swift @@ -138,49 +138,49 @@ enum HardwareModels: String, CaseIterable, Identifiable { switch self { case .UNSET: - return HardwarePlatforms.NONE + return HardwarePlatforms.none case .TLORAV2: - return HardwarePlatforms.ESP32 + return HardwarePlatforms.esp32 case .TLORAV1: - return HardwarePlatforms.ESP32 + return HardwarePlatforms.esp32 case .TLORAV211P6: - return HardwarePlatforms.ESP32 + return HardwarePlatforms.esp32 case .TBEAM: - return HardwarePlatforms.ESP32 + return HardwarePlatforms.esp32 case .HELTECV20: - return HardwarePlatforms.ESP32 + return HardwarePlatforms.esp32 case .TBEAMV0P7: - return HardwarePlatforms.ESP32 + return HardwarePlatforms.esp32 case .TECHO: - return HardwarePlatforms.NRF52 + return HardwarePlatforms.nrf52 case .TLORAV11P3: - return HardwarePlatforms.ESP32 + return HardwarePlatforms.esp32 case .RAK4631: - return HardwarePlatforms.NRF52 + return HardwarePlatforms.nrf52 case .HELTECV21: - return HardwarePlatforms.ESP32 + return HardwarePlatforms.esp32 case .HELTECV1: - return HardwarePlatforms.ESP32 + return HardwarePlatforms.esp32 case .LILYGOTBEAMS3CORE: - return HardwarePlatforms.ESP32 + return HardwarePlatforms.esp32 case .RAK11200: - return HardwarePlatforms.ESP32 + return HardwarePlatforms.esp32 case .NANOG1: - return HardwarePlatforms.ESP32 + return HardwarePlatforms.esp32 case .TLORAV211P8: - return HardwarePlatforms.ESP32 + return HardwarePlatforms.esp32 case .TLORAT3S3: - return HardwarePlatforms.ESP32 + return HardwarePlatforms.esp32 case .NANOG1EXPLORER: - return HardwarePlatforms.ESP32 + return HardwarePlatforms.esp32 case .STATIONG1: - return HardwarePlatforms.ESP32 + return HardwarePlatforms.esp32 case .M5STACK: - return HardwarePlatforms.ESP32 + return HardwarePlatforms.esp32 case .HELTECV3: - return HardwarePlatforms.ESP32 + return HardwarePlatforms.esp32 case .HELTECWSLV3: - return HardwarePlatforms.ESP32 + return HardwarePlatforms.esp32 } } func protoEnumValue() -> HardwareModel { @@ -238,24 +238,24 @@ enum HardwareModels: String, CaseIterable, Identifiable { enum HardwarePlatforms: String, CaseIterable, Identifiable { - case NONE - case ESP32 - case NRF52 - case STM32 - case PIPICO + case none + case esp32 + case nrf52 + case stm32 + case piPico var id: String { self.rawValue } var description: String { switch self { - case .NONE: + case .none: return "None" - case .ESP32: + case .esp32: return "Expressif ESP 32" - case .NRF52: + case .nrf52: return "Nordic NRF52" - case .STM32: + case .stm32: return "ARM STM 32" - case .PIPICO: + case .piPico: return "Raspberrry Pi Pico" } } diff --git a/Meshtastic/Views/Settings/Firmware.swift b/Meshtastic/Views/Settings/Firmware.swift index 6d7a7a64..4ccc253e 100644 --- a/Meshtastic/Views/Settings/Firmware.swift +++ b/Meshtastic/Views/Settings/Firmware.swift @@ -44,7 +44,7 @@ struct Firmware: View { } .padding(.bottom) - if hwModel.platform() == HardwarePlatforms.NRF52 { + if hwModel.platform() == HardwarePlatforms.nrf52 { VStack(alignment: .leading) { if hwModel == HardwareModels.RAK4631 { Text("nRF OTA Device Firmware Update App") @@ -60,7 +60,7 @@ struct Firmware: View { .font(.callout) } } - } else if hwModel.platform() == HardwarePlatforms.ESP32 { + } else if hwModel.platform() == HardwarePlatforms.esp32 { VStack(alignment: .leading) { Text("ESP32 Device Firmware Update") .font(.title3) From 9e37057fdc2232bc02ac8706a2883ec1a518297f Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sat, 18 Mar 2023 17:26:13 -0700 Subject: [PATCH 05/13] Save nag timeout --- .../Settings/Config/Module/ExternalNotificationConfig.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift b/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift index 2074bf0f..5c2c3527 100644 --- a/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift @@ -190,6 +190,7 @@ struct ExternalNotificationConfig: View { enc.alertMessageVibra = alertMessageVibra enc.active = active enc.output = UInt32(output) + enc.nagTimeout = UInt32(nagTimeout) enc.outputBuzzer = UInt32(outputBuzzer) enc.outputVibra = UInt32(outputVibra) enc.outputMs = UInt32(outputMilliseconds) From 6b7fb1a6933ce5e6ba51e5a6d50cbbb75426b449 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sun, 19 Mar 2023 08:31:16 -0700 Subject: [PATCH 06/13] Fix Display, MQTT and Network admin metadata calls --- Meshtastic/Helpers/MeshPackets.swift | 3 +++ Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift | 2 +- Meshtastic/Views/Settings/Config/NetworkConfig.swift | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Meshtastic/Helpers/MeshPackets.swift b/Meshtastic/Helpers/MeshPackets.swift index 81f0caa4..d329dceb 100644 --- a/Meshtastic/Helpers/MeshPackets.swift +++ b/Meshtastic/Helpers/MeshPackets.swift @@ -449,6 +449,9 @@ func adminAppPacket (packet: MeshPacket, context: NSManagedObjectContext) { } else if config.payloadVariant == Config.OneOf_PayloadVariant.device(config.device) { upsertDeviceConfigPacket(config: config.device, nodeNum: Int64(packet.from), context: context) + } else if config.payloadVariant == Config.OneOf_PayloadVariant.display(config.display) { + upsertDisplayConfigPacket(config: config.display, nodeNum: Int64(packet.from), context: context) + } else if config.payloadVariant == Config.OneOf_PayloadVariant.lora(config.lora) { upsertLoRaConfigPacket(config: config.lora, nodeNum: Int64(packet.from), context: context) diff --git a/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift b/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift index f264907e..7389c152 100644 --- a/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift @@ -207,7 +207,7 @@ struct MQTTConfig: View { self.hasChanges = false // Need to request a TelemetryModuleConfig from the remote node before allowing changes - if bleManager.connectedPeripheral != nil && node?.telemetryConfig == nil { + if bleManager.connectedPeripheral != nil && node?.mqttConfig == nil { print("empty mqtt module config") let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context) if node != nil && connectedNode != nil { diff --git a/Meshtastic/Views/Settings/Config/NetworkConfig.swift b/Meshtastic/Views/Settings/Config/NetworkConfig.swift index 4c74afea..95521a6d 100644 --- a/Meshtastic/Views/Settings/Config/NetworkConfig.swift +++ b/Meshtastic/Views/Settings/Config/NetworkConfig.swift @@ -169,7 +169,7 @@ struct NetworkConfig: View { self.hasChanges = false // Need to request a NetworkConfig from the remote node before allowing changes - if bleManager.connectedPeripheral != nil && node?.positionConfig == nil { + if bleManager.connectedPeripheral != nil && node?.networkConfig == nil { print("empty network config") let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context) if node != nil && connectedNode != nil { From db6500445ff1129321de59e46498300266a95952 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sun, 19 Mar 2023 09:40:57 -0700 Subject: [PATCH 07/13] Fix firmware view crash --- Meshtastic/Views/Settings/Firmware.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Meshtastic/Views/Settings/Firmware.swift b/Meshtastic/Views/Settings/Firmware.swift index 4ccc253e..e2876280 100644 --- a/Meshtastic/Views/Settings/Firmware.swift +++ b/Meshtastic/Views/Settings/Firmware.swift @@ -74,7 +74,7 @@ struct Firmware: View { HStack(alignment: .center) { Spacer() Button { - let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context) + let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral?.num ?? 0, context: context) if connectedNode != nil { if !bleManager.sendRebootOta(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode!.myInfo!.adminIndex) { print("Reboot Failed") From f805796af9d0ba3b34c2ffb992775404ebb54616 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sun, 19 Mar 2023 11:28:01 -0700 Subject: [PATCH 08/13] Breadcrumb lines for today for node details --- .../Views/Map/Custom/MapViewSwiftUI.swift | 93 +++++++++++-------- Meshtastic/Views/Nodes/NodeDetail.swift | 2 +- Meshtastic/Views/Nodes/NodeMap.swift | 1 + 3 files changed, 58 insertions(+), 38 deletions(-) diff --git a/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift b/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift index 46a6d070..f208339d 100644 --- a/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift +++ b/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift @@ -21,7 +21,7 @@ struct MapViewSwiftUI: UIViewRepresentable { let mapViewType: MKMapType let userTrackingMode: MKUserTrackingMode let centeringMode: CenteringMode - + let showBreadcrumbLines: Bool let centerOnPositionsOnly: Bool @AppStorage("meshMapRecentering") private var recenter: Bool = false @@ -120,6 +120,16 @@ struct MapViewSwiftUI: UIViewRepresentable { DispatchQueue.main.async { self.presentCustomMapOverlayHash = self.customMapOverlay self.loadedLastUpdatedLocalMapFile = self.lastUpdatedLocalMapFile + + if showBreadcrumbLines { + let nodePositions = positions.filter { $0.time! > Calendar.current.startOfDay(for: Date()) } + let lineCoords = nodePositions.map ({ + (position) -> CLLocationCoordinate2D in + return position.nodeCoordinate! + }) + let polyline = MKPolyline(coordinates: lineCoords, count: nodePositions.count) + mapView.addOverlay(polyline) + } } } @@ -334,45 +344,54 @@ struct MapViewSwiftUI: UIViewRepresentable { public func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { - if let index = self.overlays.firstIndex(where: { overlay_ in overlay_.shape.hash == overlay.hash }) { +// if let index = self.overlays.firstIndex(where: { overlay_ in overlay_.shape.hash == overlay.hash }) { - let unwrappedOverlay = self.overlays[index] - if let circleOverlay = unwrappedOverlay.shape as? MKCircle { - let renderer = MKCircleRenderer(circle: circleOverlay) - renderer.fillColor = unwrappedOverlay.fillColor - renderer.strokeColor = unwrappedOverlay.strokeColor - renderer.lineWidth = unwrappedOverlay.lineWidth - return renderer - } else if let polygonOverlay = unwrappedOverlay.shape as? MKPolygon { - let renderer = MKPolygonRenderer(polygon: polygonOverlay) - renderer.fillColor = unwrappedOverlay.fillColor - renderer.strokeColor = unwrappedOverlay.strokeColor - renderer.lineWidth = unwrappedOverlay.lineWidth - return renderer - } else if let multiPolygonOverlay = unwrappedOverlay.shape as? MKMultiPolygon { - let renderer = MKMultiPolygonRenderer(multiPolygon: multiPolygonOverlay) - renderer.fillColor = unwrappedOverlay.fillColor - renderer.strokeColor = unwrappedOverlay.strokeColor - renderer.lineWidth = unwrappedOverlay.lineWidth - return renderer - } else if let polyLineOverlay = unwrappedOverlay.shape as? MKPolyline { - let renderer = MKPolylineRenderer(polyline: polyLineOverlay) - renderer.fillColor = unwrappedOverlay.fillColor - renderer.strokeColor = unwrappedOverlay.strokeColor - renderer.lineWidth = unwrappedOverlay.lineWidth - return renderer - } else if let multiPolylineOverlay = unwrappedOverlay.shape as? MKMultiPolyline { - let renderer = MKMultiPolylineRenderer(multiPolyline: multiPolylineOverlay) - renderer.fillColor = unwrappedOverlay.fillColor - renderer.strokeColor = unwrappedOverlay.strokeColor - renderer.lineWidth = unwrappedOverlay.lineWidth - return renderer - } else { - return MKOverlayRenderer() - } - } else if let tileOverlay = overlay as? MKTileOverlay { +// let unwrappedOverlay = self.overlays[index] +// if let circleOverlay = unwrappedOverlay.shape as? MKCircle { +// let renderer = MKCircleRenderer(circle: circleOverlay) +// renderer.fillColor = unwrappedOverlay.fillColor +// renderer.strokeColor = unwrappedOverlay.strokeColor +// renderer.lineWidth = unwrappedOverlay.lineWidth +// return renderer +// } else +// if let polygonOverlay = unwrappedOverlay.shape as? MKPolygon { +// let renderer = MKPolygonRenderer(polygon: polygonOverlay) +// renderer.fillColor = unwrappedOverlay.fillColor +// renderer.strokeColor = unwrappedOverlay.strokeColor +// renderer.lineWidth = unwrappedOverlay.lineWidth +// return renderer +// } else if let multiPolygonOverlay = unwrappedOverlay.shape as? MKMultiPolygon { +// let renderer = MKMultiPolygonRenderer(multiPolygon: multiPolygonOverlay) +// renderer.fillColor = unwrappedOverlay.fillColor +// renderer.strokeColor = unwrappedOverlay.strokeColor +// renderer.lineWidth = unwrappedOverlay.lineWidth +// return renderer +// } else if let polyLineOverlay = unwrappedOverlay.shape as? MKPolyline { +// let renderer = MKPolylineRenderer(polyline: polyLineOverlay) +// renderer.fillColor = unwrappedOverlay.fillColor +// renderer.strokeColor = unwrappedOverlay.strokeColor +// renderer.lineWidth = unwrappedOverlay.lineWidth +// return renderer +// } else if let multiPolylineOverlay = unwrappedOverlay.shape as? MKMultiPolyline { +// let renderer = MKMultiPolylineRenderer(multiPolyline: multiPolylineOverlay) +// renderer.fillColor = unwrappedOverlay.fillColor +// renderer.strokeColor = unwrappedOverlay.strokeColor +// renderer.lineWidth = unwrappedOverlay.lineWidth +// return renderer +// } +// else { +// return MKOverlayRenderer() +// } +// } else + if let tileOverlay = overlay as? MKTileOverlay { return MKTileOverlayRenderer(tileOverlay: tileOverlay) } else { + if let routePolyline = overlay as? MKPolyline { + let renderer = MKPolylineRenderer(polyline: routePolyline) + renderer.strokeColor = UIColor.systemBlue + renderer.lineWidth = 5 + return renderer + } return MKOverlayRenderer() } } diff --git a/Meshtastic/Views/Nodes/NodeDetail.swift b/Meshtastic/Views/Nodes/NodeDetail.swift index d914ec74..c5cafe02 100644 --- a/Meshtastic/Views/Nodes/NodeDetail.swift +++ b/Meshtastic/Views/Nodes/NodeDetail.swift @@ -71,10 +71,10 @@ struct NodeDetail: View { mapViewType: mapType, userTrackingMode: MKUserTrackingMode.none, centeringMode: .allPositions, + showBreadcrumbLines: true, centerOnPositionsOnly: true, customMapOverlay: self.customMapOverlay, overlays: self.overlays - ) VStack(alignment: .leading) { Spacer() diff --git a/Meshtastic/Views/Nodes/NodeMap.swift b/Meshtastic/Views/Nodes/NodeMap.swift index 3a9d3de5..7dbad566 100644 --- a/Meshtastic/Views/Nodes/NodeMap.swift +++ b/Meshtastic/Views/Nodes/NodeMap.swift @@ -84,6 +84,7 @@ struct NodeMap: View { mapViewType: mapType, userTrackingMode: userTrackingMode, centeringMode: mapCenteringMode, + showBreadcrumbLines: false, centerOnPositionsOnly: false, customMapOverlay: self.customMapOverlay, overlays: self.overlays From 9957b35d331b3e65e4e96e6e461549d12fd74617 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sun, 19 Mar 2023 11:30:47 -0700 Subject: [PATCH 09/13] Tidy up node filtering logic --- Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift b/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift index f208339d..e672b276 100644 --- a/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift +++ b/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift @@ -122,7 +122,7 @@ struct MapViewSwiftUI: UIViewRepresentable { self.loadedLastUpdatedLocalMapFile = self.lastUpdatedLocalMapFile if showBreadcrumbLines { - let nodePositions = positions.filter { $0.time! > Calendar.current.startOfDay(for: Date()) } + let nodePositions = positions.filter { $0.time! >= Calendar.current.startOfDay(for: Date()) } let lineCoords = nodePositions.map ({ (position) -> CLLocationCoordinate2D in return position.nodeCoordinate! From 4457b463ee20e57082fedd43353d34baf63f95c3 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sun, 19 Mar 2023 16:12:45 -0700 Subject: [PATCH 10/13] Fix double weather loading --- Meshtastic/Views/Nodes/NodeDetail.swift | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/Meshtastic/Views/Nodes/NodeDetail.swift b/Meshtastic/Views/Nodes/NodeDetail.swift index c5cafe02..7f2d8a32 100644 --- a/Meshtastic/Views/Nodes/NodeDetail.swift +++ b/Meshtastic/Views/Nodes/NodeDetail.swift @@ -486,29 +486,6 @@ struct NodeDetail: View { mapType = .hybridFlyover } } - .task(id: node.num) { - do { - - if node.positions?.count ?? 0 > 0 { - - let mostRecent = node.positions?.lastObject as? PositionEntity - - let weather = try await WeatherService.shared.weather(for: mostRecent?.nodeLocation ?? CLLocation(latitude: LocationHelper.currentLocation.latitude, longitude: LocationHelper.currentLocation.longitude)) - condition = weather.currentWeather.condition - temperature = weather.currentWeather.temperature - humidity = Int(weather.currentWeather.humidity * 100) - symbolName = weather.currentWeather.symbolName - - let attribution = try await WeatherService.shared.attribution - attributionLink = attribution.legalPageURL - attributionLogo = colorScheme == .light ? attribution.combinedMarkLightURL : attribution.combinedMarkDarkURL - } - } catch { - print("Could not gather weather information...", error.localizedDescription) - condition = .clear - symbolName = "cloud.fill" - } - } } } } From 4822b07f5b3d7ef6efdb85efc2faa6e11ceb2f1c Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sun, 19 Mar 2023 16:39:09 -0700 Subject: [PATCH 11/13] Update line color on node details --- .../Views/Map/Custom/MapViewSwiftUI.swift | 49 ++----------------- 1 file changed, 5 insertions(+), 44 deletions(-) diff --git a/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift b/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift index e672b276..7ce5e4d6 100644 --- a/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift +++ b/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift @@ -344,53 +344,14 @@ struct MapViewSwiftUI: UIViewRepresentable { public func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { -// if let index = self.overlays.firstIndex(where: { overlay_ in overlay_.shape.hash == overlay.hash }) { - -// let unwrappedOverlay = self.overlays[index] -// if let circleOverlay = unwrappedOverlay.shape as? MKCircle { -// let renderer = MKCircleRenderer(circle: circleOverlay) -// renderer.fillColor = unwrappedOverlay.fillColor -// renderer.strokeColor = unwrappedOverlay.strokeColor -// renderer.lineWidth = unwrappedOverlay.lineWidth -// return renderer -// } else -// if let polygonOverlay = unwrappedOverlay.shape as? MKPolygon { -// let renderer = MKPolygonRenderer(polygon: polygonOverlay) -// renderer.fillColor = unwrappedOverlay.fillColor -// renderer.strokeColor = unwrappedOverlay.strokeColor -// renderer.lineWidth = unwrappedOverlay.lineWidth -// return renderer -// } else if let multiPolygonOverlay = unwrappedOverlay.shape as? MKMultiPolygon { -// let renderer = MKMultiPolygonRenderer(multiPolygon: multiPolygonOverlay) -// renderer.fillColor = unwrappedOverlay.fillColor -// renderer.strokeColor = unwrappedOverlay.strokeColor -// renderer.lineWidth = unwrappedOverlay.lineWidth -// return renderer -// } else if let polyLineOverlay = unwrappedOverlay.shape as? MKPolyline { -// let renderer = MKPolylineRenderer(polyline: polyLineOverlay) -// renderer.fillColor = unwrappedOverlay.fillColor -// renderer.strokeColor = unwrappedOverlay.strokeColor -// renderer.lineWidth = unwrappedOverlay.lineWidth -// return renderer -// } else if let multiPolylineOverlay = unwrappedOverlay.shape as? MKMultiPolyline { -// let renderer = MKMultiPolylineRenderer(multiPolyline: multiPolylineOverlay) -// renderer.fillColor = unwrappedOverlay.fillColor -// renderer.strokeColor = unwrappedOverlay.strokeColor -// renderer.lineWidth = unwrappedOverlay.lineWidth -// return renderer -// } -// else { -// return MKOverlayRenderer() -// } -// } else - if let tileOverlay = overlay as? MKTileOverlay { + if let tileOverlay = overlay as? MKTileOverlay { return MKTileOverlayRenderer(tileOverlay: tileOverlay) } else { if let routePolyline = overlay as? MKPolyline { - let renderer = MKPolylineRenderer(polyline: routePolyline) - renderer.strokeColor = UIColor.systemBlue - renderer.lineWidth = 5 - return renderer + let renderer = MKPolylineRenderer(polyline: routePolyline) + renderer.strokeColor = UIColor.systemIndigo + renderer.lineWidth = 5 + return renderer } return MKOverlayRenderer() } From 9059ceba55f0e12c53503301c7d4457a24cd509a Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sun, 19 Mar 2023 18:37:23 -0700 Subject: [PATCH 12/13] Fix real time loading of all remote admin view --- .../Views/Map/Custom/MapViewSwiftUI.swift | 1 + .../Settings/Config/BluetoothConfig.swift | 14 ++- .../Views/Settings/Config/DeviceConfig.swift | 102 +++++++++--------- .../Views/Settings/Config/DisplayConfig.swift | 23 ++-- .../Views/Settings/Config/LoRaConfig.swift | 34 +++--- .../Config/Module/CannedMessagesConfig.swift | 32 +++--- .../Module/ExternalNotificationConfig.swift | 36 ++++--- .../Settings/Config/Module/MQTTConfig.swift | 21 ++-- .../Config/Module/RangeTestConfig.swift | 14 ++- .../Settings/Config/Module/SerialConfig.swift | 23 ++-- .../Config/Module/TelemetryConfig.swift | 18 ++-- .../Views/Settings/Config/NetworkConfig.swift | 19 ++-- .../Settings/Config/PositionConfig.swift | 51 +++++---- 13 files changed, 232 insertions(+), 156 deletions(-) diff --git a/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift b/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift index 7ce5e4d6..32bed165 100644 --- a/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift +++ b/Meshtastic/Views/Map/Custom/MapViewSwiftUI.swift @@ -348,6 +348,7 @@ struct MapViewSwiftUI: UIViewRepresentable { return MKTileOverlayRenderer(tileOverlay: tileOverlay) } else { if let routePolyline = overlay as? MKPolyline { + let renderer = MKPolylineRenderer(polyline: routePolyline) renderer.strokeColor = UIColor.systemIndigo renderer.lineWidth = 5 diff --git a/Meshtastic/Views/Settings/Config/BluetoothConfig.swift b/Meshtastic/Views/Settings/Config/BluetoothConfig.swift index 3ec63ef3..3dc03f42 100644 --- a/Meshtastic/Views/Settings/Config/BluetoothConfig.swift +++ b/Meshtastic/Views/Settings/Config/BluetoothConfig.swift @@ -40,6 +40,9 @@ struct BluetoothConfig: View { } else { Text("Remote administration for: \(node?.user?.longName ?? "Unknown")") .font(.title3) + .onAppear { + setBluetoothValues() + } } } else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 { Text("Configuration for: \(node?.user?.longName ?? "Unknown")") @@ -135,10 +138,7 @@ struct BluetoothConfig: View { }) .onAppear { self.bleManager.context = context - self.enabled = node?.bluetoothConfig?.enabled ?? true - self.mode = Int(node?.bluetoothConfig?.mode ?? 0) - self.fixedPin = String(node?.bluetoothConfig?.fixedPin ?? 123456) - self.hasChanges = false + setBluetoothValues() // Need to request a BluetoothConfig from the remote node before allowing changes if bleManager.connectedPeripheral != nil && node?.bluetoothConfig == nil { print("empty bluetooth config") @@ -164,4 +164,10 @@ struct BluetoothConfig: View { } } } + func setBluetoothValues() { + self.enabled = node?.bluetoothConfig?.enabled ?? true + self.mode = Int(node?.bluetoothConfig?.mode ?? 0) + self.fixedPin = String(node?.bluetoothConfig?.fixedPin ?? 123456) + self.hasChanges = false + } } diff --git a/Meshtastic/Views/Settings/Config/DeviceConfig.swift b/Meshtastic/Views/Settings/Config/DeviceConfig.swift index 1210cc99..468e770d 100644 --- a/Meshtastic/Views/Settings/Config/DeviceConfig.swift +++ b/Meshtastic/Views/Settings/Config/DeviceConfig.swift @@ -7,35 +7,35 @@ import SwiftUI struct DeviceConfig: View { - + @Environment(\.managedObjectContext) var context @EnvironmentObject var bleManager: BLEManager @Environment(\.dismiss) private var goBack - + var node: NodeInfoEntity? - + @State private var isPresentingNodeDBResetConfirm = false @State private var isPresentingFactoryResetConfirm = false @State private var isPresentingSaveConfirm = false @State var hasChanges = false - + @State var deviceRole = 0 @State var buzzerGPIO = 0 @State var buttonGPIO = 0 @State var serialEnabled = true @State var debugLogEnabled = false @State var rebroadcastMode = 0 - + var body: some View { - + VStack { - + Form { if node != nil && node?.metadata == nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 { Text("There has been no response to a request for device metadata over the admin channel for this node.") .font(.callout) .foregroundColor(.orange) - + } else if node != nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 { // Let users know what is going on if they are using remote admin and don't have the config yet if node?.deviceConfig == nil { @@ -45,6 +45,9 @@ struct DeviceConfig: View { } else { Text("Remote administration for: \(node?.user?.longName ?? "Unknown")") .font(.title3) + .onAppear { + setDeviceValues() + } } } else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 { Text("Configuration for: \(node?.user?.longName ?? "Unknown")") @@ -55,7 +58,7 @@ struct DeviceConfig: View { .foregroundColor(.orange) } Section(header: Text("options")) { - + Picker("Device Role", selection: $deviceRole ) { ForEach(DeviceRoles.allCases) { dr in Text(dr.name) @@ -66,7 +69,7 @@ struct DeviceConfig: View { Text(DeviceRoles(rawValue: deviceRole)?.description ?? "") .foregroundColor(.gray) .font(.caption) - + Picker("Rebroadcast Mode", selection: $rebroadcastMode ) { ForEach(RebroadcastModes.allCases) { rm in Text(rm.name) @@ -78,24 +81,24 @@ struct DeviceConfig: View { .foregroundColor(.gray) .font(.caption) } - + 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)) } - + Section(header: Text("GPIO")) { - + Picker("Button GPIO", selection: $buttonGPIO) { ForEach(0..<40) { if $0 == 0 { @@ -117,14 +120,14 @@ struct DeviceConfig: View { } .pickerStyle(DefaultPickerStyle()) } - + } .disabled(self.bleManager.connectedPeripheral == nil || node?.deviceConfig == nil) - + // Only show these buttons for the BLE connected node if bleManager.connectedPeripheral != nil && node?.num ?? -1 == bleManager.connectedPeripheral.num { HStack { - + Button("Reset NodeDB", role: .destructive) { isPresentingNodeDBResetConfirm = true } @@ -139,7 +142,7 @@ struct DeviceConfig: View { titleVisibility: .visible ) { Button("Erase all device and app data?", role: .destructive) { - + if bleManager.sendNodeDBReset(fromUser: node!.user!, toUser: node!.user!) { bleManager.disconnectPeripheral() clearCoreDataDatabase(context: context) @@ -162,23 +165,23 @@ struct DeviceConfig: View { titleVisibility: .visible ) { Button("Factory reset your device and app? ", role: .destructive) { - + if bleManager.sendFactoryReset(fromUser: node!.user!, toUser: node!.user!) { bleManager.disconnectPeripheral() clearCoreDataDatabase(context: context) } else { print("Factory Reset Failed") - + } } } } } HStack { - + Button { isPresentingSaveConfirm = true - + } label: { Label("save", systemImage: "square.and.arrow.down") } @@ -188,7 +191,7 @@ struct DeviceConfig: View { .controlSize(.large) .padding() .confirmationDialog( - + "are.you.sure", isPresented: $isPresentingSaveConfirm, titleVisibility: .visible @@ -204,7 +207,7 @@ struct DeviceConfig: View { dc.debugLogEnabled = debugLogEnabled dc.buttonGpio = UInt32(buttonGPIO) dc.buzzerGpio = UInt32(buzzerGPIO) - + let adminMessageId = bleManager.saveDeviceConfig(config: dc, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0) if adminMessageId > 0 { // Should show a saved successfully alert once I know that to be true @@ -215,26 +218,21 @@ struct DeviceConfig: View { } } } - message: { - Text("config.save.confirm") - } + message: { + Text("config.save.confirm") + } } Spacer() } .navigationTitle("device.config") .navigationBarItems(trailing: - ZStack { + ZStack { ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????") }) .onAppear { self.bleManager.context = context - self.deviceRole = Int(node?.deviceConfig?.role ?? 0) - self.serialEnabled = (node?.deviceConfig?.serialEnabled ?? true) - self.debugLogEnabled = node?.deviceConfig?.debugLogEnabled ?? false - self.buttonGPIO = Int(node?.deviceConfig?.buttonGpio ?? 0) - self.buzzerGPIO = Int(node?.deviceConfig?.buzzerGpio ?? 0) - self.hasChanges = false - + setDeviceValues() + // Need to request a LoRaConfig from the remote node before allowing changes if bleManager.connectedPeripheral != nil && node?.deviceConfig == nil { print("empty device config") @@ -245,39 +243,47 @@ struct DeviceConfig: View { } } .onChange(of: deviceRole) { newRole in - + if node != nil && node!.deviceConfig != nil { - + if newRole != node!.deviceConfig!.role { hasChanges = true } } } .onChange(of: serialEnabled) { newSerial in - + if node != nil && node!.deviceConfig != nil { - + if newSerial != node!.deviceConfig!.serialEnabled { hasChanges = true } } } .onChange(of: debugLogEnabled) { newDebugLog in - + if node != nil && node!.deviceConfig != nil { - + if newDebugLog != node!.deviceConfig!.debugLogEnabled { hasChanges = true } } } .onChange(of: buttonGPIO) { newButtonGPIO in - + if node != nil && node!.deviceConfig != nil { - + if newButtonGPIO != node!.deviceConfig!.buttonGpio { hasChanges = true } } } .onChange(of: buzzerGPIO) { newBuzzerGPIO in - + if node != nil && node!.deviceConfig != nil { - + if newBuzzerGPIO != node!.deviceConfig!.buttonGpio { hasChanges = true } } } } + func setDeviceValues() { + self.deviceRole = Int(node?.deviceConfig?.role ?? 0) + self.serialEnabled = (node?.deviceConfig?.serialEnabled ?? true) + self.debugLogEnabled = node?.deviceConfig?.debugLogEnabled ?? false + self.buttonGPIO = Int(node?.deviceConfig?.buttonGpio ?? 0) + self.buzzerGPIO = Int(node?.deviceConfig?.buzzerGpio ?? 0) + self.hasChanges = false + } } diff --git a/Meshtastic/Views/Settings/Config/DisplayConfig.swift b/Meshtastic/Views/Settings/Config/DisplayConfig.swift index e45fe011..8a595a11 100644 --- a/Meshtastic/Views/Settings/Config/DisplayConfig.swift +++ b/Meshtastic/Views/Settings/Config/DisplayConfig.swift @@ -43,6 +43,9 @@ struct DisplayConfig: View { } else { Text("Remote administration for: \(node?.user?.longName ?? "Unknown")") .font(.title3) + .onAppear { + setDisplayValues() + } } } else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 { Text("Configuration for: \(node?.user?.longName ?? "Unknown")") @@ -173,14 +176,7 @@ struct DisplayConfig: View { }) .onAppear { self.bleManager.context = context - self.gpsFormat = Int(node?.displayConfig?.gpsFormat ?? 0) - self.screenOnSeconds = Int(node?.displayConfig?.screenOnSeconds ?? 0) - self.screenCarouselInterval = Int(node?.displayConfig?.screenCarouselInterval ?? 0) - self.compassNorthTop = node?.displayConfig?.compassNorthTop ?? false - self.flipScreen = node?.displayConfig?.flipScreen ?? false - self.oledType = Int(node?.displayConfig?.oledType ?? 0) - self.displayMode = Int(node?.displayConfig?.displayMode ?? 0) - self.hasChanges = false + setDisplayValues() // Need to request a LoRaConfig from the remote node before allowing changes if bleManager.connectedPeripheral != nil && node?.displayConfig == nil { @@ -227,4 +223,15 @@ struct DisplayConfig: View { } } } + func setDisplayValues() { + + self.gpsFormat = Int(node?.displayConfig?.gpsFormat ?? 0) + self.screenOnSeconds = Int(node?.displayConfig?.screenOnSeconds ?? 0) + self.screenCarouselInterval = Int(node?.displayConfig?.screenCarouselInterval ?? 0) + self.compassNorthTop = node?.displayConfig?.compassNorthTop ?? false + self.flipScreen = node?.displayConfig?.flipScreen ?? false + self.oledType = Int(node?.displayConfig?.oledType ?? 0) + self.displayMode = Int(node?.displayConfig?.displayMode ?? 0) + self.hasChanges = false + } } diff --git a/Meshtastic/Views/Settings/Config/LoRaConfig.swift b/Meshtastic/Views/Settings/Config/LoRaConfig.swift index 751fb1ee..3eb061da 100644 --- a/Meshtastic/Views/Settings/Config/LoRaConfig.swift +++ b/Meshtastic/Views/Settings/Config/LoRaConfig.swift @@ -30,7 +30,7 @@ struct LoRaConfig: View { @State var isPresentingSaveConfirm = false @State var hasChanges = false - @State var region = 0 + @State var region: Int = 0 @State var modemPreset = 0 @State var hopLimit = 0 @State var txPower = 0 @@ -57,9 +57,13 @@ struct LoRaConfig: View { Text("LoRa config data was requested over the admin channel but no response has been returned from the remote node. You can check the status of admin message requests in the admin message log.") .font(.callout) .foregroundColor(.orange) + } else { Text("Remote administration for: \(node?.user?.longName ?? "Unknown")") .font(.title3) + .onAppear { + setLoRaValues() + } } } else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 { Text("Configuration for: \(node?.user?.longName ?? "Unknown")") @@ -228,19 +232,7 @@ struct LoRaConfig: View { .onAppear { self.bleManager.context = context - self.hopLimit = Int(node?.loRaConfig?.hopLimit ?? 3) - self.region = Int(node?.loRaConfig?.regionCode ?? 0) - self.usePreset = node?.loRaConfig?.usePreset ?? true - self.modemPreset = Int(node?.loRaConfig?.modemPreset ?? 0) - self.txEnabled = node?.loRaConfig?.txEnabled ?? true - self.txPower = Int(node?.loRaConfig?.txPower ?? 0) - self.channelNum = Int(node?.loRaConfig?.channelNum ?? 0) - self.bandwidth = Int(node?.loRaConfig?.bandwidth ?? 0) - self.codingRate = Int(node?.loRaConfig?.codingRate ?? 0) - self.spreadFactor = Int(node?.loRaConfig?.spreadFactor ?? 0) - self.rxBoostedGain = node?.loRaConfig?.sx126xRxBoostedGain ?? false - print(rxBoostedGain) - self.hasChanges = false + setLoRaValues() // Need to request a LoRaConfig from the remote node before allowing changes if bleManager.connectedPeripheral != nil && node?.loRaConfig == nil { @@ -297,4 +289,18 @@ struct LoRaConfig: View { } } } + func setLoRaValues() { + self.hopLimit = Int(node?.loRaConfig?.hopLimit ?? 3) + self.region = Int(node?.loRaConfig?.regionCode ?? 0) + self.usePreset = node?.loRaConfig?.usePreset ?? true + self.modemPreset = Int(node?.loRaConfig?.modemPreset ?? 0) + self.txEnabled = node?.loRaConfig?.txEnabled ?? true + self.txPower = Int(node?.loRaConfig?.txPower ?? 0) + self.channelNum = Int(node?.loRaConfig?.channelNum ?? 0) + self.bandwidth = Int(node?.loRaConfig?.bandwidth ?? 0) + self.codingRate = Int(node?.loRaConfig?.codingRate ?? 0) + self.spreadFactor = Int(node?.loRaConfig?.spreadFactor ?? 0) + self.rxBoostedGain = node?.loRaConfig?.sx126xRxBoostedGain ?? false + self.hasChanges = false + } } diff --git a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift index 386683c8..38debac0 100644 --- a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift @@ -53,6 +53,9 @@ struct CannedMessagesConfig: View { } else { Text("Remote administration for: \(node?.user?.longName ?? "Unknown")") .font(.title3) + .onAppear { + setCannedMessagesValues() + } } } else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 { Text("Configuration for: \(node?.user?.longName ?? "Unknown")") @@ -263,19 +266,7 @@ struct CannedMessagesConfig: View { }) .onAppear { self.bleManager.context = context - self.enabled = node?.cannedMessageConfig?.enabled ?? false - self.sendBell = node?.cannedMessageConfig?.sendBell ?? false - self.rotary1Enabled = node?.cannedMessageConfig?.rotary1Enabled ?? false - self.updown1Enabled = node?.cannedMessageConfig?.updown1Enabled ?? false - self.inputbrokerPinA = Int(node?.cannedMessageConfig?.inputbrokerPinA ?? 0) - self.inputbrokerPinB = Int(node?.cannedMessageConfig?.inputbrokerPinB ?? 0) - self.inputbrokerPinPress = Int(node?.cannedMessageConfig?.inputbrokerPinPress ?? 0) - self.inputbrokerEventCw = Int(node?.cannedMessageConfig?.inputbrokerEventCw ?? 0) - self.inputbrokerEventCcw = Int(node?.cannedMessageConfig?.inputbrokerEventCcw ?? 0) - self.inputbrokerEventPress = Int(node?.cannedMessageConfig?.inputbrokerEventPress ?? 0) - self.messages = node?.cannedMessageConfig?.messages ?? "" - self.hasChanges = false - self.hasMessagesChanges = false + setCannedMessagesValues() // Need to request a CannedMessagesModuleConfig from the remote node before allowing changes if bleManager.connectedPeripheral != nil && node?.cannedMessageConfig == nil { @@ -367,4 +358,19 @@ struct CannedMessagesConfig: View { } } } + func setCannedMessagesValues() { + self.enabled = node?.cannedMessageConfig?.enabled ?? false + self.sendBell = node?.cannedMessageConfig?.sendBell ?? false + self.rotary1Enabled = node?.cannedMessageConfig?.rotary1Enabled ?? false + self.updown1Enabled = node?.cannedMessageConfig?.updown1Enabled ?? false + self.inputbrokerPinA = Int(node?.cannedMessageConfig?.inputbrokerPinA ?? 0) + self.inputbrokerPinB = Int(node?.cannedMessageConfig?.inputbrokerPinB ?? 0) + self.inputbrokerPinPress = Int(node?.cannedMessageConfig?.inputbrokerPinPress ?? 0) + self.inputbrokerEventCw = Int(node?.cannedMessageConfig?.inputbrokerEventCw ?? 0) + self.inputbrokerEventCcw = Int(node?.cannedMessageConfig?.inputbrokerEventCcw ?? 0) + self.inputbrokerEventPress = Int(node?.cannedMessageConfig?.inputbrokerEventPress ?? 0) + self.messages = node?.cannedMessageConfig?.messages ?? "" + self.hasChanges = false + self.hasMessagesChanges = false + } } diff --git a/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift b/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift index 5c2c3527..2765b46d 100644 --- a/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift @@ -48,6 +48,9 @@ struct ExternalNotificationConfig: View { } else { Text("Remote administration for: \(node?.user?.longName ?? "Unknown")") .font(.title3) + .onAppear { + setExternalNotificationValues() + } } } else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 { Text("Configuration for: \(node?.user?.longName ?? "Unknown")") @@ -215,21 +218,7 @@ struct ExternalNotificationConfig: View { }) .onAppear { self.bleManager.context = context - self.enabled = node?.externalNotificationConfig?.enabled ?? false - self.alertBell = node?.externalNotificationConfig?.alertBell ?? false - self.alertBellBuzzer = node?.externalNotificationConfig?.alertBellBuzzer ?? false - self.alertBellVibra = node?.externalNotificationConfig?.alertBellVibra ?? false - self.alertMessage = node?.externalNotificationConfig?.alertMessage ?? false - self.alertMessageBuzzer = node?.externalNotificationConfig?.alertMessageBuzzer ?? false - self.alertMessageVibra = node?.externalNotificationConfig?.alertMessageVibra ?? false - self.active = node?.externalNotificationConfig?.active ?? false - self.output = Int(node?.externalNotificationConfig?.output ?? 0) - self.outputBuzzer = Int(node?.externalNotificationConfig?.outputBuzzer ?? 0) - self.outputVibra = Int(node?.externalNotificationConfig?.outputVibra ?? 0) - self.outputMilliseconds = Int(node?.externalNotificationConfig?.outputMilliseconds ?? 0) - self.nagTimeout = Int(node?.externalNotificationConfig?.nagTimeout ?? 0) - self.usePWM = node?.externalNotificationConfig?.usePWM ?? false - self.hasChanges = false + setExternalNotificationValues() // Need to request a TelemetryModuleConfig from the remote node before allowing changes if bleManager.connectedPeripheral != nil && node?.externalNotificationConfig == nil { @@ -311,4 +300,21 @@ struct ExternalNotificationConfig: View { } } } + func setExternalNotificationValues() { + self.enabled = node?.externalNotificationConfig?.enabled ?? false + self.alertBell = node?.externalNotificationConfig?.alertBell ?? false + self.alertBellBuzzer = node?.externalNotificationConfig?.alertBellBuzzer ?? false + self.alertBellVibra = node?.externalNotificationConfig?.alertBellVibra ?? false + self.alertMessage = node?.externalNotificationConfig?.alertMessage ?? false + self.alertMessageBuzzer = node?.externalNotificationConfig?.alertMessageBuzzer ?? false + self.alertMessageVibra = node?.externalNotificationConfig?.alertMessageVibra ?? false + self.active = node?.externalNotificationConfig?.active ?? false + self.output = Int(node?.externalNotificationConfig?.output ?? 0) + self.outputBuzzer = Int(node?.externalNotificationConfig?.outputBuzzer ?? 0) + self.outputVibra = Int(node?.externalNotificationConfig?.outputVibra ?? 0) + self.outputMilliseconds = Int(node?.externalNotificationConfig?.outputMilliseconds ?? 0) + self.nagTimeout = Int(node?.externalNotificationConfig?.nagTimeout ?? 0) + self.usePWM = node?.externalNotificationConfig?.usePWM ?? false + self.hasChanges = false + } } diff --git a/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift b/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift index 7389c152..33a57063 100644 --- a/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift @@ -38,6 +38,9 @@ struct MQTTConfig: View { } else { Text("Remote administration for: \(node?.user?.longName ?? "Unknown")") .font(.title3) + .onAppear { + setMqttValues() + } } } else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 { Text("Configuration for: \(node?.user?.longName ?? "Unknown")") @@ -198,13 +201,7 @@ struct MQTTConfig: View { }) .onAppear { self.bleManager.context = context - self.enabled = (node?.mqttConfig?.enabled ?? false) - self.address = node?.mqttConfig?.address ?? "" - self.username = node?.mqttConfig?.username ?? "" - self.password = node?.mqttConfig?.password ?? "" - self.encryptionEnabled = (node?.mqttConfig?.encryptionEnabled ?? false) - self.jsonEnabled = (node?.mqttConfig?.jsonEnabled ?? false) - self.hasChanges = false + setMqttValues() // Need to request a TelemetryModuleConfig from the remote node before allowing changes if bleManager.connectedPeripheral != nil && node?.mqttConfig == nil { @@ -231,4 +228,14 @@ struct MQTTConfig: View { } } } + + func setMqttValues() { + self.enabled = (node?.mqttConfig?.enabled ?? false) + self.address = node?.mqttConfig?.address ?? "" + self.username = node?.mqttConfig?.username ?? "" + self.password = node?.mqttConfig?.password ?? "" + self.encryptionEnabled = (node?.mqttConfig?.encryptionEnabled ?? false) + self.jsonEnabled = (node?.mqttConfig?.jsonEnabled ?? false) + self.hasChanges = false + } } diff --git a/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift b/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift index 9d6ed6de..44d03ee9 100644 --- a/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/RangeTestConfig.swift @@ -37,6 +37,9 @@ struct RangeTestConfig: View { } else { Text("Remote administration for: \(node?.user?.longName ?? "Unknown")") .font(.title3) + .onAppear { + setRangeTestValues() + } } } else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 { Text("Configuration for: \(node?.user?.longName ?? "Unknown")") @@ -115,10 +118,7 @@ struct RangeTestConfig: View { }) .onAppear { self.bleManager.context = context - self.enabled = node?.rangeTestConfig?.enabled ?? false - self.save = node?.rangeTestConfig?.save ?? false - self.sender = Int(node?.rangeTestConfig?.sender ?? 0) - self.hasChanges = false + setRangeTestValues() // Need to request a RangeTestModule Config from the remote node before allowing changes if bleManager.connectedPeripheral != nil && node?.rangeTestConfig == nil { @@ -146,4 +146,10 @@ struct RangeTestConfig: View { } } } + func setRangeTestValues() { + self.enabled = node?.rangeTestConfig?.enabled ?? false + self.save = node?.rangeTestConfig?.save ?? false + self.sender = Int(node?.rangeTestConfig?.sender ?? 0) + self.hasChanges = false + } } diff --git a/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift b/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift index c5d1e900..6f5cc238 100644 --- a/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift @@ -44,6 +44,9 @@ struct SerialConfig: View { } else { Text("Remote administration for: \(node?.user?.longName ?? "Unknown")") .font(.title3) + .onAppear { + setSerialValues() + } } } else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 { Text("Configuration for: \(node?.user?.longName ?? "Unknown")") @@ -177,15 +180,7 @@ struct SerialConfig: View { .onAppear { self.bleManager.context = context - self.enabled = node?.serialConfig?.enabled ?? false - self.echo = node?.serialConfig?.echo ?? false - self.rxd = Int(node?.serialConfig?.rxd ?? 0) - self.txd = Int(node?.serialConfig?.txd ?? 0) - self.baudRate = Int(node?.serialConfig?.baudRate ?? 0) - self.timeout = Int(node?.serialConfig?.timeout ?? 0) - self.mode = Int(node?.serialConfig?.mode ?? 0) - self.hasChanges = false - + setSerialValues() // Need to request a SerialModuleConfig from the remote node before allowing changes if bleManager.connectedPeripheral != nil && node?.serialConfig == nil { print("empty serial module config") @@ -247,4 +242,14 @@ struct SerialConfig: View { } } } + func setSerialValues() { + self.enabled = node?.serialConfig?.enabled ?? false + self.echo = node?.serialConfig?.echo ?? false + self.rxd = Int(node?.serialConfig?.rxd ?? 0) + self.txd = Int(node?.serialConfig?.txd ?? 0) + self.baudRate = Int(node?.serialConfig?.baudRate ?? 0) + self.timeout = Int(node?.serialConfig?.timeout ?? 0) + self.mode = Int(node?.serialConfig?.mode ?? 0) + self.hasChanges = false + } } diff --git a/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift b/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift index 3d5910b7..93c67b89 100644 --- a/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift @@ -40,6 +40,9 @@ struct TelemetryConfig: View { } else { Text("Remote administration for: \(node?.user?.longName ?? "Unknown")") .font(.title3) + .onAppear { + setTelemetryValues() + } } } else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 { Text("Configuration for: \(node?.user?.longName ?? "Unknown")") @@ -131,12 +134,7 @@ struct TelemetryConfig: View { }) .onAppear { self.bleManager.context = context - self.deviceUpdateInterval = Int(node?.telemetryConfig?.deviceUpdateInterval ?? 0) - self.environmentUpdateInterval = Int(node?.telemetryConfig?.environmentUpdateInterval ?? 0) - self.environmentMeasurementEnabled = node?.telemetryConfig?.environmentMeasurementEnabled ?? false - self.environmentScreenEnabled = node?.telemetryConfig?.environmentScreenEnabled ?? false - self.environmentDisplayFahrenheit = node?.telemetryConfig?.environmentDisplayFahrenheit ?? false - self.hasChanges = false + setTelemetryValues() // Need to request a TelemetryModuleConfig from the remote node before allowing changes if bleManager.connectedPeripheral != nil && node?.telemetryConfig == nil { @@ -174,4 +172,12 @@ struct TelemetryConfig: View { } } } + func setTelemetryValues() { + self.deviceUpdateInterval = Int(node?.telemetryConfig?.deviceUpdateInterval ?? 0) + self.environmentUpdateInterval = Int(node?.telemetryConfig?.environmentUpdateInterval ?? 0) + self.environmentMeasurementEnabled = node?.telemetryConfig?.environmentMeasurementEnabled ?? false + self.environmentScreenEnabled = node?.telemetryConfig?.environmentScreenEnabled ?? false + self.environmentDisplayFahrenheit = node?.telemetryConfig?.environmentDisplayFahrenheit ?? false + self.hasChanges = false + } } diff --git a/Meshtastic/Views/Settings/Config/NetworkConfig.swift b/Meshtastic/Views/Settings/Config/NetworkConfig.swift index 95521a6d..21c48653 100644 --- a/Meshtastic/Views/Settings/Config/NetworkConfig.swift +++ b/Meshtastic/Views/Settings/Config/NetworkConfig.swift @@ -43,6 +43,9 @@ struct NetworkConfig: View { } else { Text("Remote administration for: \(node?.user?.longName ?? "Unknown")") .font(.title3) + .onAppear { + setNetworkValues() + } } } else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 { Text("Configuration for: \(node?.user?.longName ?? "Unknown")") @@ -161,12 +164,7 @@ struct NetworkConfig: View { }) .onAppear { self.bleManager.context = context - self.wifiEnabled = node?.networkConfig?.wifiEnabled ?? false - self.wifiSsid = node?.networkConfig?.wifiSsid ?? "" - self.wifiPsk = node?.networkConfig?.wifiPsk ?? "" - self.wifiMode = Int(node?.networkConfig?.wifiMode ?? 0) - self.ethEnabled = node?.networkConfig?.ethEnabled ?? false - self.hasChanges = false + setNetworkValues() // Need to request a NetworkConfig from the remote node before allowing changes if bleManager.connectedPeripheral != nil && node?.networkConfig == nil { @@ -203,4 +201,13 @@ struct NetworkConfig: View { } } } + + func setNetworkValues() { + self.wifiEnabled = node?.networkConfig?.wifiEnabled ?? false + self.wifiSsid = node?.networkConfig?.wifiSsid ?? "" + self.wifiPsk = node?.networkConfig?.wifiPsk ?? "" + self.wifiMode = Int(node?.networkConfig?.wifiMode ?? 0) + self.ethEnabled = node?.networkConfig?.ethEnabled ?? false + self.hasChanges = false + } } diff --git a/Meshtastic/Views/Settings/Config/PositionConfig.swift b/Meshtastic/Views/Settings/Config/PositionConfig.swift index b275f77d..25a91a69 100644 --- a/Meshtastic/Views/Settings/Config/PositionConfig.swift +++ b/Meshtastic/Views/Settings/Config/PositionConfig.swift @@ -86,6 +86,9 @@ struct PositionConfig: View { } else { Text("Remote administration for: \(node?.user?.longName ?? "Unknown")") .font(.title3) + .onAppear { + setPositionValues() + } } } else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 { Text("Configuration for: \(node?.user?.longName ?? "Unknown")") @@ -277,28 +280,7 @@ struct PositionConfig: View { .onAppear { self.bleManager.context = context - self.smartPositionEnabled = node?.positionConfig?.smartPositionEnabled ?? true - self.deviceGpsEnabled = node?.positionConfig?.deviceGpsEnabled ?? true - self.fixedPosition = node?.positionConfig?.fixedPosition ?? false - self.gpsUpdateInterval = Int(node?.positionConfig?.gpsUpdateInterval ?? 30) - self.gpsAttemptTime = Int(node?.positionConfig?.gpsAttemptTime ?? 30) - self.positionBroadcastSeconds = Int(node?.positionConfig?.positionBroadcastSeconds ?? 900) - self.positionFlags = Int(node?.positionConfig?.positionFlags ?? 3) - - let pf = PositionFlags(rawValue: self.positionFlags) - - if pf.contains(.Altitude) { self.includeAltitude = true } else { self.includeAltitude = false } - if pf.contains(.AltitudeMsl) { self.includeAltitudeMsl = true } else { self.includeAltitudeMsl = false } - if pf.contains(.GeoidalSeparation) { self.includeGeoidalSeparation = true } else { self.includeGeoidalSeparation = false } - if pf.contains(.Dop) { self.includeDop = true } else { self.includeDop = false } - if pf.contains(.Hvdop) { self.includeHvdop = true } else { self.includeHvdop = false } - if pf.contains(.Satsinview) { self.includeSatsinview = true } else { self.includeSatsinview = false } - if pf.contains(.SeqNo) { self.includeSeqNo = true } else { self.includeSeqNo = false } - if pf.contains(.Timestamp) { self.includeTimestamp = true } else { self.includeTimestamp = false } - if pf.contains(.Speed) { self.includeSpeed = true } else { self.includeSpeed = false } - if pf.contains(.Heading) { self.includeHeading = true } else { self.includeHeading = false } - - self.hasChanges = false + setPositionValues() // Need to request a PositionConfig from the remote node before allowing changes if bleManager.connectedPeripheral != nil && node?.positionConfig == nil { @@ -395,4 +377,29 @@ struct PositionConfig: View { if existingValue != hvdopFlag { hasChanges = true } } } + + func setPositionValues() { + + self.smartPositionEnabled = node?.positionConfig?.smartPositionEnabled ?? true + self.deviceGpsEnabled = node?.positionConfig?.deviceGpsEnabled ?? true + self.fixedPosition = node?.positionConfig?.fixedPosition ?? false + self.gpsUpdateInterval = Int(node?.positionConfig?.gpsUpdateInterval ?? 30) + self.gpsAttemptTime = Int(node?.positionConfig?.gpsAttemptTime ?? 30) + self.positionBroadcastSeconds = Int(node?.positionConfig?.positionBroadcastSeconds ?? 900) + self.positionFlags = Int(node?.positionConfig?.positionFlags ?? 3) + + let pf = PositionFlags(rawValue: self.positionFlags) + if pf.contains(.Altitude) { self.includeAltitude = true } else { self.includeAltitude = false } + if pf.contains(.AltitudeMsl) { self.includeAltitudeMsl = true } else { self.includeAltitudeMsl = false } + if pf.contains(.GeoidalSeparation) { self.includeGeoidalSeparation = true } else { self.includeGeoidalSeparation = false } + if pf.contains(.Dop) { self.includeDop = true } else { self.includeDop = false } + if pf.contains(.Hvdop) { self.includeHvdop = true } else { self.includeHvdop = false } + if pf.contains(.Satsinview) { self.includeSatsinview = true } else { self.includeSatsinview = false } + if pf.contains(.SeqNo) { self.includeSeqNo = true } else { self.includeSeqNo = false } + if pf.contains(.Timestamp) { self.includeTimestamp = true } else { self.includeTimestamp = false } + if pf.contains(.Speed) { self.includeSpeed = true } else { self.includeSpeed = false } + if pf.contains(.Heading) { self.includeHeading = true } else { self.includeHeading = false } + + self.hasChanges = false + } } From a991087bc2f57c1068752249dd0494b2c7ee25fb Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sun, 19 Mar 2023 18:44:10 -0700 Subject: [PATCH 13/13] Turn off phone breadcrumb lines --- Meshtastic/Views/Nodes/NodeDetail.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Meshtastic/Views/Nodes/NodeDetail.swift b/Meshtastic/Views/Nodes/NodeDetail.swift index 7f2d8a32..bb24243d 100644 --- a/Meshtastic/Views/Nodes/NodeDetail.swift +++ b/Meshtastic/Views/Nodes/NodeDetail.swift @@ -71,7 +71,7 @@ struct NodeDetail: View { mapViewType: mapType, userTrackingMode: MKUserTrackingMode.none, centeringMode: .allPositions, - showBreadcrumbLines: true, + showBreadcrumbLines: false, centerOnPositionsOnly: true, customMapOverlay: self.customMapOverlay, overlays: self.overlays