From bdc36610e6762babaea8d5af4d6c38307194121c Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sat, 2 Jul 2022 11:28:25 -0700 Subject: [PATCH] Canned Message --- Meshtastic/Helpers/MeshPackets.swift | 190 ++++++++++++++++++ .../contents | 26 ++- .../Config/Module/CannedMessagesConfig.swift | 12 +- .../Settings/Config/Module/SerialConfig.swift | 105 +++++++++- Meshtastic/Views/Settings/Settings.swift | 2 +- 5 files changed, 320 insertions(+), 15 deletions(-) diff --git a/Meshtastic/Helpers/MeshPackets.swift b/Meshtastic/Helpers/MeshPackets.swift index 39e08310..4dff1875 100644 --- a/Meshtastic/Helpers/MeshPackets.swift +++ b/Meshtastic/Helpers/MeshPackets.swift @@ -331,6 +331,107 @@ func localConfig (config: Config, meshlogging: Bool, context:NSManagedObjectCont func moduleConfig (config: ModuleConfig, meshlogging: Bool, context:NSManagedObjectContext, nodeNum: Int64, nodeLongName: String) { // We don't care about any of the WiFi related MQTT settings + if config.payloadVariant == ModuleConfig.OneOf_PayloadVariant.cannedMessage(config.cannedMessage) { + + var isDefault = false + + if (try! config.serial.jsonString()) == "{}" { + + isDefault = true + print("🥫 Default Canned Message Module config") + } + + let fetchNodeInfoRequest: NSFetchRequest = NSFetchRequest.init(entityName: "NodeInfoEntity") + fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum)) + + do { + + let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity] + // Found a node, save Device Config + if !fetchedNode.isEmpty { + + if fetchedNode[0].cannedMessageConfig == nil { + + let newCannedMessageConfig = CannedMessageConfigEntity(context: context) + + if isDefault { + + newCannedMessageConfig.enabled = false + newCannedMessageConfig.sendBell = false + newCannedMessageConfig.rotary1Enabled = false + newCannedMessageConfig.updown1Enabled = false + newCannedMessageConfig.inputbrokerPinA = 0 + newCannedMessageConfig.inputbrokerPinB = 0 + newCannedMessageConfig.inputbrokerPinPress = 0 + newCannedMessageConfig.inputbrokerEventCw = 0 + newCannedMessageConfig.inputbrokerEventCcw = 0 + newCannedMessageConfig.inputbrokerEventPress = 0 + + } else { + + newCannedMessageConfig.enabled = config.cannedMessage.enabled + newCannedMessageConfig.sendBell = config.cannedMessage.sendBell + newCannedMessageConfig.rotary1Enabled = config.cannedMessage.rotary1Enabled + newCannedMessageConfig.updown1Enabled = config.cannedMessage.updown1Enabled + newCannedMessageConfig.inputbrokerPinA = Int32(config.cannedMessage.inputbrokerPinA) + newCannedMessageConfig.inputbrokerPinB = Int32(config.cannedMessage.inputbrokerPinB) + newCannedMessageConfig.inputbrokerPinPress = Int32(config.cannedMessage.inputbrokerPinPress) + newCannedMessageConfig.inputbrokerEventCw = Int32(config.cannedMessage.inputbrokerEventCw.rawValue) + newCannedMessageConfig.inputbrokerEventCcw = Int32(config.cannedMessage.inputbrokerEventCcw.rawValue) + newCannedMessageConfig.inputbrokerEventPress = Int32(config.cannedMessage.inputbrokerEventPress.rawValue) + } + + fetchedNode[0].cannedMessageConfig = newCannedMessageConfig + + } else { + + if isDefault { + + fetchedNode[0].cannedMessageConfig?.enabled = false + fetchedNode[0].cannedMessageConfig?.sendBell = false + fetchedNode[0].cannedMessageConfig?.rotary1Enabled = false + fetchedNode[0].cannedMessageConfig?.updown1Enabled = false + fetchedNode[0].cannedMessageConfig?.inputbrokerPinA = 0 + fetchedNode[0].cannedMessageConfig?.inputbrokerPinB = 0 + fetchedNode[0].cannedMessageConfig?.inputbrokerPinPress = 0 + fetchedNode[0].cannedMessageConfig?.inputbrokerEventCw = 0 + fetchedNode[0].cannedMessageConfig?.inputbrokerEventCcw = 0 + fetchedNode[0].cannedMessageConfig?.inputbrokerEventPress = 0 + + } else { + + fetchedNode[0].cannedMessageConfig?.enabled = config.cannedMessage.enabled + fetchedNode[0].cannedMessageConfig?.sendBell = config.cannedMessage.sendBell + fetchedNode[0].cannedMessageConfig?.rotary1Enabled = config.cannedMessage.rotary1Enabled + fetchedNode[0].cannedMessageConfig?.updown1Enabled = config.cannedMessage.updown1Enabled + fetchedNode[0].cannedMessageConfig?.inputbrokerPinA = Int32(config.cannedMessage.inputbrokerPinA) + fetchedNode[0].cannedMessageConfig?.inputbrokerPinB = Int32(config.cannedMessage.inputbrokerPinB) + fetchedNode[0].cannedMessageConfig?.inputbrokerPinPress = Int32(config.cannedMessage.inputbrokerPinPress) + fetchedNode[0].cannedMessageConfig?.inputbrokerEventCw = Int32(config.cannedMessage.inputbrokerEventCw.rawValue) + fetchedNode[0].cannedMessageConfig?.inputbrokerEventCcw = Int32(config.cannedMessage.inputbrokerEventCcw.rawValue) + fetchedNode[0].cannedMessageConfig?.inputbrokerEventPress = Int32(config.cannedMessage.inputbrokerEventPress.rawValue) + } + } + + do { + + try context.save() + if meshlogging { MeshLogger.log("💾 Updated Canned Message Module Config for node number: \(String(nodeNum))") } + + } catch { + + context.rollback() + + let nsError = error as NSError + print("💥 Error Updating Core Data CannedMessageConfigEntity: \(nsError)") + } + } + + } catch { + + } + } + if config.payloadVariant == ModuleConfig.OneOf_PayloadVariant.rangeTest(config.rangeTest) { var isDefault = false @@ -403,6 +504,95 @@ func moduleConfig (config: ModuleConfig, meshlogging: Bool, context:NSManagedObj } } + + if config.payloadVariant == ModuleConfig.OneOf_PayloadVariant.serial(config.serial) { + + var isDefault = false + + if (try! config.serial.jsonString()) == "{}" { + + isDefault = true + print("🤖 Default Serial Module config") + } + + let fetchNodeInfoRequest: NSFetchRequest = NSFetchRequest.init(entityName: "NodeInfoEntity") + fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum)) + + do { + + let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity] + // Found a node, save Device Config + if !fetchedNode.isEmpty { + + if fetchedNode[0].serialConfig == nil { + + let newSerialConfig = SerialConfigEntity(context: context) + + if isDefault { + + newSerialConfig.enabled = false + newSerialConfig.echo = false + newSerialConfig.rxd = 0 + newSerialConfig.txd = 0 + newSerialConfig.baudRate = 0 + newSerialConfig.timeout = 0 + newSerialConfig.mode = 0 + + } else { + + newSerialConfig.enabled = config.serial.enabled + newSerialConfig.echo = config.serial.echo + newSerialConfig.rxd = Int32(config.serial.rxd) + newSerialConfig.txd = Int32(config.serial.txd) + newSerialConfig.baudRate = Int32(config.serial.baud.rawValue) + newSerialConfig.timeout = Int32(config.serial.timeout) + newSerialConfig.mode = Int32(config.serial.mode.rawValue) + } + + fetchedNode[0].serialConfig = newSerialConfig + + } else { + + if isDefault { + + fetchedNode[0].serialConfig?.enabled = false + fetchedNode[0].serialConfig?.echo = false + fetchedNode[0].serialConfig?.rxd = 0 + fetchedNode[0].serialConfig?.txd = 0 + fetchedNode[0].serialConfig?.baudRate = 0 + fetchedNode[0].serialConfig?.timeout = 0 + fetchedNode[0].serialConfig?.mode = 0 + + } else { + + fetchedNode[0].serialConfig?.enabled = config.serial.enabled + fetchedNode[0].serialConfig?.echo = config.serial.echo + fetchedNode[0].serialConfig?.rxd = Int32(config.serial.rxd) + fetchedNode[0].serialConfig?.txd = Int32(config.serial.txd) + fetchedNode[0].serialConfig?.baudRate = Int32(config.serial.baud.rawValue) + fetchedNode[0].serialConfig?.timeout = Int32(config.serial.timeout) + fetchedNode[0].serialConfig?.mode = Int32(config.serial.mode.rawValue) + } + } + + do { + + try context.save() + if meshlogging { MeshLogger.log("💾 Updated Serial Module Config for node number: \(String(nodeNum))") } + + } catch { + + context.rollback() + + let nsError = error as NSError + print("💥 Error Updating Core Data SerialConfigEntity: \(nsError)") + } + } + + } catch { + + } + } } func myInfoPacket (myInfo: MyNodeInfo, meshLogging: Bool, context: NSManagedObjectContext) -> MyInfoEntity? { diff --git a/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents index aef25e6d..786d7b7e 100644 --- a/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents +++ b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents @@ -1,7 +1,10 @@ - + + + + @@ -9,7 +12,7 @@ - + @@ -79,7 +82,7 @@ - + @@ -87,6 +90,7 @@ + @@ -120,6 +124,17 @@ + + + + + + + + + + + @@ -149,17 +164,18 @@ - + - + + \ No newline at end of file diff --git a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift index 3353eaa0..914cbd1d 100644 --- a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift @@ -307,12 +307,12 @@ struct CannedMessagesConfig: View { if self.initialLoad{ self.bleManager.context = context - self.enabled = node.cannedMessagesConfig?.enabled ?? false - self.rotary1Enabled = node.cannedMessagesConfig?.rotary1Enabled ?? false - self.updown1Enabled = node.cannedMessagesConfig?.updown1Enabled ?? false - self.inputbrokerPinA = Int(node.cannedMessagesConfig?.inputbrokerPinA ?? 0) - self.inputbrokerPinB = Int(node.cannedMessagesConfig?.inputbrokerPinB ?? 0) - self.inputbrokerPinPress = Int(node.cannedMessagesConfig?.inputbrokerPinPress ?? 0) + self.enabled = node.cannedMessageConfig?.enabled ?? 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.hasChanges = false self.initialLoad = false } diff --git a/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift b/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift index 1ef21a60..16c59540 100644 --- a/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift @@ -65,6 +65,45 @@ enum SerialBaudRates: Int, CaseIterable, Identifiable { } } } + + func protoEnumValue() -> ModuleConfig.SerialConfig.Serial_Baud { + + switch self { + + case .baudDefault: + return ModuleConfig.SerialConfig.Serial_Baud.baudDefault + case .baud110: + return ModuleConfig.SerialConfig.Serial_Baud.baud110 + case .baud300: + return ModuleConfig.SerialConfig.Serial_Baud.baud300 + case .baud600: + return ModuleConfig.SerialConfig.Serial_Baud.baud600 + case .baud1200: + return ModuleConfig.SerialConfig.Serial_Baud.baud1200 + case .baud2400: + return ModuleConfig.SerialConfig.Serial_Baud.baud2400 + case .baud4800: + return ModuleConfig.SerialConfig.Serial_Baud.baud4800 + case .baud9600: + return ModuleConfig.SerialConfig.Serial_Baud.baud9600 + case .baud19200: + return ModuleConfig.SerialConfig.Serial_Baud.baud19200 + case .baud38400: + return ModuleConfig.SerialConfig.Serial_Baud.baud38400 + case .baud57600: + return ModuleConfig.SerialConfig.Serial_Baud.baud57600 + case .baud115200: + return ModuleConfig.SerialConfig.Serial_Baud.baud115200 + case .baud230400: + return ModuleConfig.SerialConfig.Serial_Baud.baud230400 + case .baud460800: + return ModuleConfig.SerialConfig.Serial_Baud.baud460800 + case .baud576000: + return ModuleConfig.SerialConfig.Serial_Baud.baud576000 + case .baud921600: + return ModuleConfig.SerialConfig.Serial_Baud.baud921600 + } + } } enum SerialModeTypes: Int, CaseIterable, Identifiable { @@ -86,6 +125,18 @@ enum SerialModeTypes: Int, CaseIterable, Identifiable { } } } + func protoEnumValue() -> ModuleConfig.SerialConfig.Serial_Mode { + + switch self { + + case .modeDefault: + return ModuleConfig.SerialConfig.Serial_Mode.modeDefault + case .modeSimple: + return ModuleConfig.SerialConfig.Serial_Mode.modeSimple + case .modeProto: + return ModuleConfig.SerialConfig.Serial_Mode.modeProto + } + } } enum SerialTimeoutIntervals: Int, CaseIterable, Identifiable { @@ -127,6 +178,8 @@ struct SerialConfig: View { @Environment(\.managedObjectContext) var context @EnvironmentObject var bleManager: BLEManager + var node: NodeInfoEntity + @State private var isPresentingSaveConfirm: Bool = false @State var initialLoad: Bool = true @State var hasChanges = false @@ -242,8 +295,12 @@ struct SerialConfig: View { var sc = ModuleConfig.SerialConfig() sc.enabled = enabled - //sc.save = save - //sc.sender = sender ? 1 : 0 + sc.echo = echo + sc.rxd = UInt32(rxd) + sc.txd = UInt32(txd) + sc.baud = SerialBaudRates(rawValue: baudRate)!.protoEnumValue() + sc.timeout = UInt32(timeout) + sc.mode = SerialModeTypes(rawValue: mode)!.protoEnumValue() if bleManager.saveSerialModuleConfig(config: sc, destNum: bleManager.connectedPeripheral.num, wantResponse: false) { @@ -266,7 +323,49 @@ struct SerialConfig: View { }) .onAppear { - self.bleManager.context = context + if self.initialLoad{ + + 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 + self.initialLoad = false + } + } + .onChange(of: enabled) { newEnabled in + + if newEnabled != node.serialConfig!.enabled { hasChanges = true } + } + .onChange(of: echo) { newEcho in + + if newEcho != node.serialConfig!.echo { hasChanges = true } + } + .onChange(of: rxd) { newRxd in + + if newRxd != node.serialConfig!.rxd { hasChanges = true } + } + .onChange(of: txd) { newTxd in + + if newTxd != node.serialConfig!.txd { hasChanges = true } + } + .onChange(of: baudRate) { newBaud in + + if newBaud != node.serialConfig!.baudRate { hasChanges = true } + } + .onChange(of: timeout) { newTimeout in + + if newTimeout != node.serialConfig!.timeout { hasChanges = true } + } + .onChange(of: mode) { newMode in + + if newMode != node.serialConfig!.mode { hasChanges = true } } .navigationViewStyle(StackNavigationViewStyle()) } diff --git a/Meshtastic/Views/Settings/Settings.swift b/Meshtastic/Views/Settings/Settings.swift index a89df691..359a76d0 100644 --- a/Meshtastic/Views/Settings/Settings.swift +++ b/Meshtastic/Views/Settings/Settings.swift @@ -151,7 +151,7 @@ struct Settings: View { // nodes.first(where: { $0.num == connectedNodeNum })!.rangeTestConfig != nil) NavigationLink { - SerialConfig() + SerialConfig(node: nodes.first(where: { $0.num == connectedNodeNum }) ?? NodeInfoEntity()) } label: { Image(systemName: "terminal")