From 9e8288b273b0e49dd1b55bd079d17664ee318f0e Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sat, 9 Jul 2022 06:42:30 -0700 Subject: [PATCH] Clean up methods to save admin messages --- Meshtastic/Helpers/BLEManager.swift | 219 ++++-------------- .../contents | 2 +- Meshtastic/Persistence/Persistence.swift | 2 +- .../Config/Module/CannedMessagesConfig.swift | 89 ++++--- .../Config/Module/TelemetryConfig.swift | 42 +++- 5 files changed, 135 insertions(+), 219 deletions(-) diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index 0de3b4cc..dc23c7c0 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -1318,9 +1318,8 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph public func saveCannedMessageModuleMessages(messages: String, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 { - var newMessageId: Int64 = 0 - var adminPacket = AdminMessage() + adminPacket.setCannedMessageModulePart1 = messages var meshPacket: MeshPacket = MeshPacket() @@ -1335,48 +1334,19 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - - var toRadio: ToRadio! - toRadio = ToRadio() - toRadio.packet = meshPacket - - let binaryData: Data = try! toRadio.serializedData() - if connectedPeripheral!.peripheral.state == CBPeripheralState.connected { - - let newMessage = MessageEntity(context: context!) - newMessage.messageId = Int64(meshPacket.id) - newMessageId = newMessage.messageId - newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970) - newMessage.receivedACK = false - newMessage.admin = true - newMessage.adminDescription = "Saved Canned Message Module Messages for \(toUser.longName ?? "Unknown")" - newMessage.fromUser = fromUser - newMessage.toUser = toUser - newMessage.messagePayload = messages + let messageDescription = "Saved Canned Message Module Messages for \(toUser.longName ?? "Unknown")" + + if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) { - do { - - try context!.save() - - if meshLoggingEnabled { MeshLogger.log("💾 Saved Canned Message Module Messages Admin Message for node: \(String(toUser.num))") } - connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse) - - } catch { - - context!.rollback() - - let nsError = error as NSError - print("💥 Error Inserting New Core Data MessageEntity: \(nsError)") - } + return Int64(meshPacket.id) } - return newMessageId + + return 0 } public func saveExternalNotificationModuleConfig(config: ModuleConfig.ExternalNotificationConfig, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 { - - var newMessageId: Int64 = 0 - + var adminPacket = AdminMessage() adminPacket.setModuleConfig.externalNotification = config @@ -1393,47 +1363,18 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph meshPacket.decoded = dataMessage - var toRadio: ToRadio! - toRadio = ToRadio() - toRadio.packet = meshPacket - - let binaryData: Data = try! toRadio.serializedData() + let messageDescription = "Saved External Notification Module Config for \(toUser.longName ?? "Unknown")" - if connectedPeripheral!.peripheral.state == CBPeripheralState.connected { - - let newMessage = MessageEntity(context: context!) - newMessage.messageId = Int64(meshPacket.id) - newMessageId = newMessage.messageId - newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970) - newMessage.receivedACK = false - newMessage.admin = true - newMessage.adminDescription = "Saved External Notification Module Config for \(toUser.longName ?? "Unknown")" - newMessage.fromUser = fromUser - newMessage.toUser = toUser - newMessage.messagePayload = try! config.jsonString() + if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) { - do { - - try context!.save() - - if meshLoggingEnabled { MeshLogger.log("💾 Saved External Notification Module Config Admin Message for node: \(String(toUser.num))") } - connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse) - - } catch { - - context!.rollback() - - let nsError = error as NSError - print("💥 Error Inserting New Core Data MessageEntity: \(nsError)") - } + return Int64(meshPacket.id) } - return newMessageId + + return 0 } public func saveRangeTestModuleConfig(config: ModuleConfig.RangeTestConfig, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 { - var newMessageId: Int64 = 0 - var adminPacket = AdminMessage() adminPacket.setModuleConfig.rangeTest = config @@ -1450,47 +1391,18 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph meshPacket.decoded = dataMessage - var toRadio: ToRadio! - toRadio = ToRadio() - toRadio.packet = meshPacket - - let binaryData: Data = try! toRadio.serializedData() + let messageDescription = "Saved Range Test Module Config for \(toUser.longName ?? "Unknown")" - if connectedPeripheral!.peripheral.state == CBPeripheralState.connected { - - let newMessage = MessageEntity(context: context!) - newMessage.messageId = Int64(meshPacket.id) - newMessageId = newMessage.messageId - newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970) - newMessage.receivedACK = false - newMessage.admin = true - newMessage.adminDescription = "Saved Range Test Module Config for \(toUser.longName ?? "Unknown")" - newMessage.fromUser = fromUser - newMessage.toUser = toUser - newMessage.messagePayload = try! config.jsonString() + if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) { - do { - - try context!.save() - - if meshLoggingEnabled { MeshLogger.log("💾 Saved a new Range Test Module Config Admin Message for node: \(String(toUser.num))") } - connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse) - - } catch { - - context!.rollback() - - let nsError = error as NSError - print("💥 Error Inserting New Core Data MessageEntity: \(nsError)") - } + return Int64(meshPacket.id) } - return newMessageId + + return 0 } public func saveSerialModuleConfig(config: ModuleConfig.SerialConfig, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 { - var newMessageId: Int64 = 0 - var adminPacket = AdminMessage() adminPacket.setModuleConfig.serial = config @@ -1508,47 +1420,18 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph meshPacket.decoded = dataMessage - var toRadio: ToRadio! - toRadio = ToRadio() - toRadio.packet = meshPacket - - let binaryData: Data = try! toRadio.serializedData() + let messageDescription = "Saved Serial Module Config for \(toUser.longName ?? "Unknown")" - if connectedPeripheral!.peripheral.state == CBPeripheralState.connected { - - let newMessage = MessageEntity(context: context!) - newMessage.messageId = Int64(meshPacket.id) - newMessageId = newMessage.messageId - newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970) - newMessage.receivedACK = false - newMessage.admin = true - newMessage.adminDescription = "Saved Serial Module Config for \(toUser.longName ?? "Unknown")" - newMessage.fromUser = fromUser - newMessage.toUser = toUser - newMessage.messagePayload = try! config.jsonString() + if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) { - do { - - try context!.save() - - if meshLoggingEnabled { MeshLogger.log("💾 Saved Serial Module Config Admin Message for node: \(String(toUser.num))") } - connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse) - - } catch { - - context!.rollback() - - let nsError = error as NSError - print("💥 Error Inserting New Core Data MessageEntity: \(nsError)") - } + return Int64(meshPacket.id) } - return newMessageId + + return 0 } public func saveTelemetryModuleConfig(config: ModuleConfig.TelemetryConfig, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 { - - var newMessageId: Int64 = 0 - + var adminPacket = AdminMessage() adminPacket.setModuleConfig.telemetry = config @@ -1565,6 +1448,19 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph meshPacket.decoded = dataMessage + let messageDescription = "Saved Telemetry Module Config for \(toUser.longName ?? "Unknown")" + + if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) { + + return Int64(meshPacket.id) + } + + return 0 + } + + // Send an admin message to a radio, save a message to core data for logging + private func sendAdminMessageToRadio(meshPacket: MeshPacket, adminDescription: String, fromUser: UserEntity, toUser: UserEntity) -> Bool { + var toRadio: ToRadio! toRadio = ToRadio() toRadio.packet = meshPacket @@ -1575,40 +1471,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph let newMessage = MessageEntity(context: context!) newMessage.messageId = Int64(meshPacket.id) - newMessageId = newMessage.messageId - newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970) - newMessage.receivedACK = false - newMessage.admin = true - newMessage.adminDescription = "Saved Telemetry Module Config for \(toUser.longName ?? "Unknown")" - newMessage.fromUser = fromUser - newMessage.toUser = toUser - newMessage.messagePayload = try! config.jsonString() - - do { - - try context!.save() - - if meshLoggingEnabled { MeshLogger.log("💾 Saved Telemetry Module Config Admin Message for node number: \(String(toUser.num))") } - connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse) - - } catch { - - context!.rollback() - - let nsError = error as NSError - print("💥 Error Inserting New Core Data MessageEntity: \(nsError)") - } - } - return newMessageId - } - - // Send an admin message to a radio, save a message to core data for logging - private func sendAdminMessageToRadio(adminDescription: String, messageId: Int64, fromUser: UserEntity, toUser: UserEntity, binaryData: Data) { - - if connectedPeripheral!.peripheral.state == CBPeripheralState.connected { - - let newMessage = MessageEntity(context: context!) - newMessage.messageId = Int64(messageId) newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970) newMessage.receivedACK = false newMessage.admin = true @@ -1618,10 +1480,13 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph do { + connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse) + try context!.save() if meshLoggingEnabled { MeshLogger.log("💾 \(adminDescription)") } - connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse) + + return true } catch { @@ -1630,6 +1495,8 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph let nsError = error as NSError print("💥 Error inserting new core data MessageEntity: \(nsError)") } + } + return false } } diff --git a/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents index 4945a75d..d8b141ee 100644 --- a/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents +++ b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents @@ -52,7 +52,7 @@ - + diff --git a/Meshtastic/Persistence/Persistence.swift b/Meshtastic/Persistence/Persistence.swift index c37af6e4..8a317e9c 100644 --- a/Meshtastic/Persistence/Persistence.swift +++ b/Meshtastic/Persistence/Persistence.swift @@ -34,7 +34,7 @@ class PersistenceController { init(inMemory: Bool = false) { container = NSPersistentContainer(name: "Meshtastic") - //self.clearDatabase() + self.clearDatabase() if inMemory { container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null") diff --git a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift index d6c19f29..af0e07b7 100644 --- a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift @@ -105,6 +105,7 @@ struct CannedMessagesConfig: View { @State private var isPresentingSaveConfirm: Bool = false @State var initialLoad: Bool = true @State var hasChanges = false + @State var hasMessagesChanges = false @State var configPreset = 0 @State var enabled = false @@ -278,7 +279,7 @@ struct CannedMessagesConfig: View { Label("Save", systemImage: "square.and.arrow.down") } - .disabled(bleManager.connectedPeripheral == nil || !hasChanges) + .disabled(bleManager.connectedPeripheral == nil || (!hasChanges && !hasMessagesChanges)) .buttonStyle(.bordered) .buttonBorderShape(.capsule) .controlSize(.large) @@ -290,40 +291,54 @@ struct CannedMessagesConfig: View { ) { Button("Save Canned Messages Module Config to \(bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : "Unknown")?") { - var cmc = ModuleConfig.CannedMessageConfig() - cmc.enabled = enabled - cmc.sendBell = sendBell - cmc.rotary1Enabled = rotary1Enabled - cmc.updown1Enabled = updown1Enabled - if rotary1Enabled { - - /// Input event origin accepted by the canned messages - /// Can be e.g. "rotEnc1", "upDownEnc1", "cardkb", "faceskb" 623or keyword "_any" - cmc.allowInputSource = "rotEnc1" - - } else if updown1Enabled { - - cmc.allowInputSource = "upDownEnc1" - - } else { - - cmc.allowInputSource = "_any" - } - cmc.inputbrokerPinA = UInt32(inputbrokerPinA) - cmc.inputbrokerPinB = UInt32(inputbrokerPinB) - cmc.inputbrokerPinPress = UInt32(inputbrokerPinPress) - cmc.inputbrokerEventCw = InputEventChars(rawValue: inputbrokerEventCw)!.protoEnumValue() - cmc.inputbrokerEventCcw = InputEventChars(rawValue: inputbrokerEventCcw)!.protoEnumValue() - cmc.inputbrokerEventPress = InputEventChars(rawValue: inputbrokerEventPress)!.protoEnumValue() + if hasChanges { - let adminMessageId = bleManager.saveCannedMessageModuleConfig(config: cmc, fromUser: node!.user!, toUser: node!.user!, wantResponse: true) + var cmc = ModuleConfig.CannedMessageConfig() + cmc.enabled = enabled + cmc.sendBell = sendBell + cmc.rotary1Enabled = rotary1Enabled + cmc.updown1Enabled = updown1Enabled + if rotary1Enabled { + + /// Input event origin accepted by the canned messages + /// Can be e.g. "rotEnc1", "upDownEnc1", "cardkb", "faceskb" 623or keyword "_any" + cmc.allowInputSource = "rotEnc1" + + } else if updown1Enabled { + + cmc.allowInputSource = "upDownEnc1" + + } else { + + cmc.allowInputSource = "_any" + } + cmc.inputbrokerPinA = UInt32(inputbrokerPinA) + cmc.inputbrokerPinB = UInt32(inputbrokerPinB) + cmc.inputbrokerPinPress = UInt32(inputbrokerPinPress) + cmc.inputbrokerEventCw = InputEventChars(rawValue: inputbrokerEventCw)!.protoEnumValue() + cmc.inputbrokerEventCcw = InputEventChars(rawValue: inputbrokerEventCcw)!.protoEnumValue() + cmc.inputbrokerEventPress = InputEventChars(rawValue: inputbrokerEventPress)!.protoEnumValue() + + let adminMessageId = bleManager.saveCannedMessageModuleConfig(config: cmc, fromUser: node!.user!, toUser: node!.user!, wantResponse: true) + + if adminMessageId > 0 { + // 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 + } + } + + if hasMessagesChanges { + + let adminMessageId = bleManager.saveCannedMessageModuleMessages(messages: messagesPart1, fromUser: node!.user!, toUser: node!.user!, wantResponse: true) + + if adminMessageId > 0 { + // Should show a saved successfully alert once I know that to be true + // for now just disable the button after a successful save + hasMessagesChanges = false + } - if adminMessageId > 0 { - // 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 } - } } @@ -363,6 +378,12 @@ struct CannedMessagesConfig: View { // TBeam Three Button 1.3" OLED Screen updown1Enabled = true rotary1Enabled = false + inputbrokerPinA = 25 + inputbrokerPinB = 39 + inputbrokerPinPress = 36 + inputbrokerEventCw = InputEventChars.keyUp.rawValue + inputbrokerEventCcw = InputEventChars.keyDown.rawValue + inputbrokerEventPress = InputEventChars.keySelect.rawValue } hasChanges = true @@ -410,6 +431,10 @@ struct CannedMessagesConfig: View { if newKeyPress != node!.cannedMessageConfig!.inputbrokerEventPress { hasChanges = true } } + .onChange(of: messagesPart1) { newMessagesChanges in + + hasMessagesChanges = true + } .navigationViewStyle(StackNavigationViewStyle()) } } diff --git a/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift b/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift index 188f6d22..492b433b 100644 --- a/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift @@ -289,7 +289,7 @@ struct TelemetryConfig: View { Label("Save", systemImage: "square.and.arrow.down") } - .disabled(bleManager.connectedPeripheral == nil || !hasChanges) + .disabled(bleManager.connectedPeripheral == nil || !hasChanges || node!.telemetryConfig == nil) .buttonStyle(.bordered) .buttonBorderShape(.capsule) .controlSize(.large) @@ -353,35 +353,59 @@ struct TelemetryConfig: View { } .onChange(of: deviceUpdateInterval) { newDeviceInterval in - if newDeviceInterval != node!.telemetryConfig!.deviceUpdateInterval { hasChanges = true } + if node!.telemetryConfig != nil { + + if newDeviceInterval != node!.telemetryConfig!.deviceUpdateInterval { hasChanges = true } + } } .onChange(of: environmentUpdateInterval) { newEnvInterval in - if newEnvInterval != node!.telemetryConfig!.environmentUpdateInterval { hasChanges = true } + if node!.telemetryConfig != nil { + + if newEnvInterval != node!.telemetryConfig!.environmentUpdateInterval { hasChanges = true } + } } .onChange(of: environmentMeasurementEnabled) { newEnvEnabled in - if newEnvEnabled != node!.telemetryConfig!.environmentMeasurementEnabled { hasChanges = true } + if node!.telemetryConfig != nil { + + if newEnvEnabled != node!.telemetryConfig!.environmentMeasurementEnabled { hasChanges = true } + } } .onChange(of: environmentSensorType) { newEnvSensorType in - if newEnvSensorType != node!.telemetryConfig!.environmentSensorType { hasChanges = true } + if node!.telemetryConfig != nil { + + if newEnvSensorType != node!.telemetryConfig!.environmentSensorType { hasChanges = true } + } } .onChange(of: environmentScreenEnabled) { newEnvScreenEnabled in - if newEnvScreenEnabled != node!.telemetryConfig!.environmentScreenEnabled { hasChanges = true } + if node!.telemetryConfig != nil { + + if newEnvScreenEnabled != node!.telemetryConfig!.environmentScreenEnabled { hasChanges = true } + } } .onChange(of: environmentDisplayFahrenheit) { newEnvDisplayF in - if newEnvDisplayF != node!.telemetryConfig!.environmentDisplayFahrenheit { hasChanges = true } + if node!.telemetryConfig != nil { + + if newEnvDisplayF != node!.telemetryConfig!.environmentDisplayFahrenheit { hasChanges = true } + } } .onChange(of: environmentRecoveryInterval) { newEnvRecoveryInterval in - if newEnvRecoveryInterval != node!.telemetryConfig!.environmentRecoveryInterval { hasChanges = true } + if node!.telemetryConfig != nil { + + if newEnvRecoveryInterval != node!.telemetryConfig!.environmentRecoveryInterval { hasChanges = true } + } } .onChange(of: environmentReadErrorCountThreshold) { newEnvReadErrorCountThreshold in - if newEnvReadErrorCountThreshold != node!.telemetryConfig!.environmentReadErrorCountThreshold { hasChanges = true } + if node!.telemetryConfig != nil { + + if newEnvReadErrorCountThreshold != node!.telemetryConfig!.environmentReadErrorCountThreshold { hasChanges = true } + } } .navigationViewStyle(StackNavigationViewStyle()) }