mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Merge pull request #110 from meshtastic/feature/module_settings
Module Configuration
This commit is contained in:
commit
5f0e08d587
21 changed files with 1068 additions and 155 deletions
|
|
@ -839,7 +839,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.3.22;
|
||||
MARKETING_VERSION = 1.3.23;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
|
@ -871,7 +871,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.3.22;
|
||||
MARKETING_VERSION = 1.3.23;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
|
|
|||
|
|
@ -54,6 +54,20 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
let TORADIO_UUID = CBUUID(string: "0xF75C76D2-129E-4DAD-A1DD-7866124401E7")
|
||||
let FROMRADIO_UUID = CBUUID(string: "0x8BA2BCC2-EE02-4A55-A531-C525C5E454D5")
|
||||
let FROMNUM_UUID = CBUUID(string: "0xED9DA18C-A800-4F66-A670-AA7547E34453")
|
||||
|
||||
// Meshtastic DFU details
|
||||
let DFUSERVICE_UUID = CBUUID(string : "cb0b9a0b-a84c-4c0d-bdbb-442e3144ee30")
|
||||
let DFUSIZE_UUID = CBUUID(string: "e74dd9c0-a301-4a6f-95a1-f0e1dbea8e1e")
|
||||
let DFUDATA_UUID = CBUUID(string: "e272ebac-d463-4b98-bc84-5cc1a39ee517")
|
||||
let DFUCRC32_UUID = CBUUID(string: "4826129c-c22a-43a3-b066-ce8f0d5bacc6")
|
||||
let DFURESULT_UUID = CBUUID(string: "5e134862-7411-4424-ac4a-210937432c77")
|
||||
let DFUREGION_UUID = CBUUID(string: "5e134862-7411-4424-ac4a-210937432c67")
|
||||
|
||||
var DFUSIZE_characteristic: CBCharacteristic?
|
||||
var DFUDATA_characteristic: CBCharacteristic?
|
||||
var DFUCRC32_characteristic: CBCharacteristic?
|
||||
var DFURESULT_characteristic: CBCharacteristic?
|
||||
var DFUREGION_characteristic: CBCharacteristic?
|
||||
|
||||
private var meshLoggingEnabled: Bool = true
|
||||
let meshLog = documentsFolder.appendingPathComponent("meshlog.txt")
|
||||
|
|
@ -217,7 +231,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
connectedPeripheral.peripheral.delegate = self
|
||||
|
||||
// Discover Services
|
||||
peripheral.discoverServices([meshtasticServiceCBUUID])
|
||||
peripheral.discoverServices([meshtasticServiceCBUUID, DFUSERVICE_UUID])
|
||||
if meshLoggingEnabled { MeshLogger.log("✅ BLE Connected: \(peripheral.name ?? "Unknown")") }
|
||||
|
||||
}
|
||||
|
|
@ -296,7 +310,14 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
if meshLoggingEnabled { MeshLogger.log("✅ BLE Service for Meshtastic discovered by \(peripheral.name ?? "Unknown")") }
|
||||
//peripheral.discoverCharacteristics(nil, for: service)
|
||||
peripheral.discoverCharacteristics([TORADIO_UUID, FROMRADIO_UUID, FROMNUM_UUID], for: service)
|
||||
}
|
||||
|
||||
} else if (service.uuid == DFUSERVICE_UUID) {
|
||||
|
||||
print("✅ Meshtastic DFU service discovered OK")
|
||||
if meshLoggingEnabled { MeshLogger.log("✅ BLE Service for Meshtastic DFU discovered by \(peripheral.name ?? "Unknown")") }
|
||||
peripheral.discoverCharacteristics([DFUDATA_UUID, DFUSIZE_UUID, DFUREGION_UUID, DFURESULT_UUID, DFUCRC32_UUID], for: service)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -340,6 +361,36 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
if meshLoggingEnabled { MeshLogger.log("✅ BLE did discover FROMNUM (Notify) characteristic for Meshtastic by \(peripheral.name ?? "Unknown")") }
|
||||
FROMNUM_characteristic = characteristic
|
||||
peripheral.setNotifyValue(true, for: characteristic)
|
||||
|
||||
case DFUSIZE_UUID:
|
||||
|
||||
print("✅ DFU Size characteristic OK")
|
||||
if meshLoggingEnabled { MeshLogger.log("✅ BLE did discover DFU Size characteristic for Meshtastic DFU by \(peripheral.name ?? "Unknown")") }
|
||||
DFUSIZE_characteristic = characteristic
|
||||
|
||||
case DFUDATA_UUID:
|
||||
|
||||
print("✅ DFU Data characteristic OK")
|
||||
if meshLoggingEnabled { MeshLogger.log("✅ BLE did discover DFU Data characteristic for Meshtastic DFU by \(peripheral.name ?? "Unknown")") }
|
||||
DFUDATA_characteristic = characteristic
|
||||
|
||||
case DFUCRC32_UUID:
|
||||
|
||||
print("✅ DFU CRC32 characteristic OK")
|
||||
if meshLoggingEnabled { MeshLogger.log("✅ BLE did discover DFU CRC32 characteristic for Meshtastic DFU by \(peripheral.name ?? "Unknown")") }
|
||||
DFUCRC32_characteristic = characteristic
|
||||
|
||||
case DFURESULT_UUID:
|
||||
|
||||
print("✅ DFU Result characteristic OK")
|
||||
if meshLoggingEnabled { MeshLogger.log("✅ BLE did discover DFU Result characteristic for Meshtastic DFU by \(peripheral.name ?? "Unknown")") }
|
||||
DFURESULT_characteristic = characteristic
|
||||
|
||||
case DFUREGION_UUID:
|
||||
|
||||
print("✅ DFU Region characteristic OK")
|
||||
if meshLoggingEnabled { MeshLogger.log("✅ BLE did discover DFU Region characteristic for Meshtastic DFU by \(peripheral.name ?? "Unknown")") }
|
||||
DFUREGION_characteristic = characteristic
|
||||
|
||||
default:
|
||||
break
|
||||
|
|
@ -405,60 +456,65 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
// Handle Any local only packets we get over BLE
|
||||
case .unknownApp:
|
||||
|
||||
if decodedInfo.myInfo.myNodeNum != 0 {
|
||||
var nowKnown = false
|
||||
|
||||
// MyInfo
|
||||
if decodedInfo.myInfo.isInitialized && decodedInfo.myInfo.myNodeNum > 0 {
|
||||
|
||||
let myInfo = myInfoPacket(myInfo: decodedInfo.myInfo, meshLogging: meshLoggingEnabled, context: context!)
|
||||
nowKnown = true
|
||||
let myInfo = myInfoPacket(myInfo: decodedInfo.myInfo, meshLogging: meshLoggingEnabled, context: context!)
|
||||
|
||||
if myInfo != nil {
|
||||
|
||||
if myInfo != nil {
|
||||
|
||||
self.connectedPeripheral.bitrate = myInfo!.bitrate
|
||||
self.connectedPeripheral.num = myInfo!.myNodeNum
|
||||
lastConnnectionVersion = myInfo?.firmwareVersion ?? myInfo!.firmwareVersion ?? "Unknown"
|
||||
self.connectedPeripheral.firmwareVersion = myInfo!.firmwareVersion ?? "Unknown"
|
||||
self.connectedPeripheral.name = myInfo!.bleName ?? "Unknown"
|
||||
|
||||
}
|
||||
|
||||
} else if decodedInfo.nodeInfo.num != 0 {
|
||||
self.connectedPeripheral.bitrate = myInfo!.bitrate
|
||||
self.connectedPeripheral.num = myInfo!.myNodeNum
|
||||
lastConnnectionVersion = myInfo?.firmwareVersion ?? myInfo!.firmwareVersion ?? "Unknown"
|
||||
self.connectedPeripheral.firmwareVersion = myInfo!.firmwareVersion ?? "Unknown"
|
||||
self.connectedPeripheral.name = myInfo!.bleName ?? "Unknown"
|
||||
self.connectedPeripheral.longName = myInfo!.bleName ?? "Unknown"
|
||||
|
||||
let nodeInfo = nodeInfoPacket(nodeInfo: decodedInfo.nodeInfo, meshLogging: meshLoggingEnabled, context: context!)
|
||||
}
|
||||
}
|
||||
// NodeInfo
|
||||
if decodedInfo.nodeInfo.num != 0 {
|
||||
|
||||
nowKnown = true
|
||||
let nodeInfo = nodeInfoPacket(nodeInfo: decodedInfo.nodeInfo, meshLogging: meshLoggingEnabled, context: context!)
|
||||
|
||||
if nodeInfo != nil {
|
||||
|
||||
if nodeInfo != nil {
|
||||
|
||||
self.connectedPeripheral.channelUtilization = decodedInfo.nodeInfo.deviceMetrics.channelUtilization
|
||||
self.connectedPeripheral.airTime = decodedInfo.nodeInfo.deviceMetrics.airUtilTx
|
||||
self.connectedPeripheral.channelUtilization = decodedInfo.nodeInfo.deviceMetrics.channelUtilization
|
||||
self.connectedPeripheral.airTime = decodedInfo.nodeInfo.deviceMetrics.airUtilTx
|
||||
|
||||
if self.connectedPeripheral != nil && self.connectedPeripheral.num == nodeInfo!.num {
|
||||
if self.connectedPeripheral != nil && self.connectedPeripheral.num == nodeInfo!.num {
|
||||
|
||||
if nodeInfo!.user != nil {
|
||||
|
||||
connectedPeripheral.name = nodeInfo!.user!.longName ?? "Unknown"
|
||||
connectedPeripheral.shortName = nodeInfo!.user!.shortName ?? "?????"
|
||||
connectedPeripheral.longName = nodeInfo!.user!.longName ?? "Unknown"
|
||||
}
|
||||
if nodeInfo!.user != nil {
|
||||
|
||||
connectedPeripheral.shortName = nodeInfo!.user!.shortName ?? "????"
|
||||
connectedPeripheral.longName = nodeInfo!.user!.longName ?? "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
} else if decodedInfo.config.isInitialized {
|
||||
|
||||
localConfig(config: decodedInfo.config, meshlogging: meshLoggingEnabled, context: context!, nodeNum: self.connectedPeripheral.num, nodeLongName: self.connectedPeripheral.longName)
|
||||
|
||||
} else if decodedInfo.moduleConfig.isInitialized {
|
||||
|
||||
moduleConfig(config: decodedInfo.moduleConfig, meshlogging: meshLoggingEnabled, context: context!, nodeNum: self.connectedPeripheral.num, nodeLongName: self.connectedPeripheral.longName)
|
||||
|
||||
} else {
|
||||
|
||||
if decodedInfo.configCompleteID == 0 {
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("ℹ️ MESH PACKET received for App UNHANDLED \(try! decodedInfo.packet.jsonString())") }
|
||||
} else {
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("ℹ️ MESH PACKET received for Unknown App UNHANDLED \(try! decodedInfo.packet.jsonString())") }
|
||||
}
|
||||
|
||||
print(decodedInfo.moduleConfig.isInitialized)
|
||||
}
|
||||
}
|
||||
// Config
|
||||
if decodedInfo.config.isInitialized {
|
||||
|
||||
nowKnown = true
|
||||
localConfig(config: decodedInfo.config, meshlogging: meshLoggingEnabled, context: context!, nodeNum: self.connectedPeripheral.num, nodeLongName: self.connectedPeripheral.longName)
|
||||
|
||||
}
|
||||
// Module Config
|
||||
if decodedInfo.moduleConfig.isInitialized {
|
||||
|
||||
nowKnown = true
|
||||
moduleConfig(config: decodedInfo.moduleConfig, meshlogging: meshLoggingEnabled, context: context!, nodeNum: self.connectedPeripheral.num, nodeLongName: self.connectedPeripheral.longName)
|
||||
}
|
||||
// Log any other unknownApp calls
|
||||
if !nowKnown {
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("ℹ️ MESH PACKET received for Unknown App UNHANDLED \(try! decodedInfo.packet.jsonString())") }
|
||||
}
|
||||
|
||||
case .textMessageApp:
|
||||
textMessageAppPacket(packet: decodedInfo.packet, connectedNode: (self.connectedPeripheral != nil ? connectedPeripheral.num : 0), meshLogging: meshLoggingEnabled, context: context!)
|
||||
case .remoteHardwareApp:
|
||||
|
|
@ -607,6 +663,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
newMessage.direction = "IN"
|
||||
newMessage.toUser = fetchedUsers.first(where: { $0.num == toUserNum })
|
||||
newMessage.isEmoji = isEmoji
|
||||
newMessage.admin = false
|
||||
|
||||
if replyID > 0 {
|
||||
|
||||
|
|
@ -793,6 +850,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
@ -834,7 +892,9 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
return false
|
||||
}
|
||||
|
||||
public func saveUser(config: User, destNum: Int64, wantResponse: Bool) -> Bool {
|
||||
public func saveUser(config: User, entity: UserEntity, wantResponse: Bool) -> Int64 {
|
||||
|
||||
var newMessageId: Int64 = 0
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setOwner = config
|
||||
|
|
@ -860,13 +920,35 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
let binaryData: Data = try! toRadio.serializedData()
|
||||
|
||||
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
|
||||
|
||||
let newMessage = MessageEntity(context: context!)
|
||||
newMessage.messageId = Int64(UInt32.random(in: UInt32(UInt8.max)..<UInt32.max))
|
||||
newMessageId = newMessage.messageId
|
||||
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
newMessage.receivedACK = false
|
||||
newMessage.direction = "OUT"
|
||||
newMessage.admin = true
|
||||
newMessage.fromUser = entity
|
||||
newMessage.toUser = entity
|
||||
newMessage.messagePayload = try! dataMessage.jsonString()
|
||||
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
|
||||
return true
|
||||
do {
|
||||
|
||||
try context!.save()
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new Admin Message for node number: \(String(entity.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 false
|
||||
return newMessageId
|
||||
}
|
||||
|
||||
public func sendFactoryReset(destNum: Int64, wantResponse: Bool) -> Bool {
|
||||
|
|
@ -1047,20 +1129,19 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
return false
|
||||
}
|
||||
|
||||
public func getChannelSet (destNum: Int64, wantResponse: Bool) -> Bool {
|
||||
public func saveCannedMessageModuleConfig(config: ModuleConfig.CannedMessageConfig, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 {
|
||||
|
||||
var newMessageId: Int64 = 0
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.getChannelRequest = 1
|
||||
|
||||
|
||||
adminPacket.setModuleConfig.cannedMessage = config
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(connectedPeripheral.num)
|
||||
meshPacket.from = 0 //UInt32(connectedPeripheral.num)
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = 0 //UInt32(fromUser.num)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = wantResponse
|
||||
meshPacket.hopLimit = 0
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
|
|
@ -1075,27 +1156,108 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
let binaryData: Data = try! toRadio.serializedData()
|
||||
|
||||
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
|
||||
|
||||
let newMessage = MessageEntity(context: context!)
|
||||
newMessage.messageId = Int64(UInt32.random(in: UInt32(UInt8.max)..<UInt32.max))
|
||||
newMessageId = newMessage.messageId
|
||||
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
newMessage.receivedACK = false
|
||||
newMessage.direction = "OUT"
|
||||
newMessage.admin = true
|
||||
newMessage.fromUser = fromUser
|
||||
newMessage.toUser = toUser
|
||||
newMessage.messagePayload = try! dataMessage.jsonString()
|
||||
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
|
||||
return true
|
||||
do {
|
||||
|
||||
try context!.save()
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new Canned Message 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 false
|
||||
return newMessageId
|
||||
}
|
||||
|
||||
public func saveRangeTestModuleConfig(config: ModuleConfig.RangeTestConfig, destNum: Int64, wantResponse: Bool) -> Bool {
|
||||
public func saveExternalNotificationModuleConfig(config: ModuleConfig.ExternalNotificationConfig, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 {
|
||||
|
||||
var newMessageId: Int64 = 0
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setModuleConfig.externalNotification = config
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = 0 //UInt32(fromUser.num)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = wantResponse
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
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(UInt32.random(in: UInt32(UInt8.max)..<UInt32.max))
|
||||
newMessageId = newMessage.messageId
|
||||
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
newMessage.receivedACK = false
|
||||
newMessage.direction = "OUT"
|
||||
newMessage.admin = true
|
||||
newMessage.fromUser = fromUser
|
||||
newMessage.toUser = toUser
|
||||
newMessage.messagePayload = try! dataMessage.jsonString()
|
||||
|
||||
do {
|
||||
|
||||
try context!.save()
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new Canned Message 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
|
||||
|
||||
}
|
||||
|
||||
public func saveRangeTestModuleConfig(config: ModuleConfig.RangeTestConfig, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 {
|
||||
|
||||
var newMessageId: Int64 = 0
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setModuleConfig.rangeTest = config
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(connectedPeripheral.num)
|
||||
meshPacket.from = 0 //UInt32(connectedPeripheral.num)
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = 0 //UInt32(fromUser.num)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = wantResponse
|
||||
meshPacket.hopLimit = 0
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
|
|
@ -1110,16 +1272,41 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
let binaryData: Data = try! toRadio.serializedData()
|
||||
|
||||
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
|
||||
|
||||
let newMessage = MessageEntity(context: context!)
|
||||
newMessage.messageId = Int64(UInt32.random(in: UInt32(UInt8.max)..<UInt32.max))
|
||||
newMessageId = newMessage.messageId
|
||||
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
newMessage.receivedACK = false
|
||||
newMessage.direction = "OUT"
|
||||
newMessage.admin = true
|
||||
newMessage.fromUser = fromUser
|
||||
newMessage.toUser = toUser
|
||||
newMessage.messagePayload = try! dataMessage.jsonString()
|
||||
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
|
||||
return true
|
||||
do {
|
||||
|
||||
try context!.save()
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new Range Test 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 false
|
||||
return newMessageId
|
||||
|
||||
}
|
||||
|
||||
public func saveSerialModuleConfig(config: ModuleConfig.SerialConfig, destNum: Int64, wantResponse: Bool) -> Bool {
|
||||
public func saveSerialModuleConfig(config: ModuleConfig.SerialConfig, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 {
|
||||
|
||||
var newMessageId: Int64 = 0
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setModuleConfig.serial = config
|
||||
|
|
@ -1145,12 +1332,93 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
let binaryData: Data = try! toRadio.serializedData()
|
||||
|
||||
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
|
||||
|
||||
let newMessage = MessageEntity(context: context!)
|
||||
newMessage.messageId = Int64(UInt32.random(in: UInt32(UInt8.max)..<UInt32.max))
|
||||
newMessageId = newMessage.messageId
|
||||
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
newMessage.receivedACK = false
|
||||
newMessage.direction = "OUT"
|
||||
newMessage.admin = true
|
||||
newMessage.fromUser = fromUser
|
||||
newMessage.toUser = toUser
|
||||
newMessage.messagePayload = try! dataMessage.jsonString()
|
||||
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
|
||||
return true
|
||||
do {
|
||||
|
||||
try context!.save()
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new 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 false
|
||||
return newMessageId
|
||||
}
|
||||
|
||||
public func saveTelemetryModuleConfig(config: ModuleConfig.TelemetryConfig, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 {
|
||||
|
||||
var newMessageId: Int64 = 0
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setModuleConfig.telemetry = config
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(toUser.num)
|
||||
meshPacket.from = 0 //UInt32(fromUser.num)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = wantResponse
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
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(UInt32.random(in: UInt32(UInt8.max)..<UInt32.max))
|
||||
newMessageId = newMessage.messageId
|
||||
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
|
||||
newMessage.receivedACK = false
|
||||
newMessage.direction = "OUT"
|
||||
newMessage.admin = true
|
||||
newMessage.fromUser = fromUser
|
||||
newMessage.toUser = toUser
|
||||
newMessage.messagePayload = try! dataMessage.jsonString()
|
||||
|
||||
do {
|
||||
|
||||
try context!.save()
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new Canned Message 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
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -331,6 +331,194 @@ 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.cannedMessage.jsonString()) == "{}" {
|
||||
|
||||
isDefault = true
|
||||
print("🥫 Default Canned Message Module config")
|
||||
}
|
||||
|
||||
let fetchNodeInfoRequest: NSFetchRequest<NSFetchRequestResult> = 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 Canned Message 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.externalNotification(config.externalNotification) {
|
||||
|
||||
var isDefault = false
|
||||
|
||||
if (try! config.externalNotification.jsonString()) == "{}" {
|
||||
|
||||
isDefault = true
|
||||
print("🚨 Default External Notifiation Module config")
|
||||
}
|
||||
|
||||
let fetchNodeInfoRequest: NSFetchRequest<NSFetchRequestResult> = 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 External Notificaitone Config
|
||||
if !fetchedNode.isEmpty {
|
||||
|
||||
if fetchedNode[0].externalNotificationConfig == nil {
|
||||
|
||||
let newExternalNotificationConfig = ExternalNotificationConfigEntity(context: context)
|
||||
|
||||
if isDefault {
|
||||
|
||||
|
||||
newExternalNotificationConfig.enabled = false
|
||||
newExternalNotificationConfig.alertBell = false
|
||||
newExternalNotificationConfig.alertMessage = false
|
||||
newExternalNotificationConfig.active = false
|
||||
newExternalNotificationConfig.output = 0
|
||||
newExternalNotificationConfig.outputMilliseconds = 0
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
newExternalNotificationConfig.enabled = config.externalNotification.enabled
|
||||
newExternalNotificationConfig.alertBell = config.externalNotification.alertBell
|
||||
newExternalNotificationConfig.alertMessage = config.externalNotification.alertMessage
|
||||
newExternalNotificationConfig.active = config.externalNotification.active
|
||||
newExternalNotificationConfig.output = Int32(config.externalNotification.output)
|
||||
newExternalNotificationConfig.outputMilliseconds = Int32(config.externalNotification.outputMs)
|
||||
}
|
||||
|
||||
fetchedNode[0].externalNotificationConfig = newExternalNotificationConfig
|
||||
|
||||
} else {
|
||||
|
||||
if isDefault {
|
||||
|
||||
fetchedNode[0].externalNotificationConfig?.enabled = false
|
||||
fetchedNode[0].externalNotificationConfig?.alertBell = false
|
||||
fetchedNode[0].externalNotificationConfig?.alertMessage = false
|
||||
fetchedNode[0].externalNotificationConfig?.active = false
|
||||
fetchedNode[0].externalNotificationConfig?.output = 0
|
||||
fetchedNode[0].externalNotificationConfig?.outputMilliseconds = 0
|
||||
|
||||
} else {
|
||||
|
||||
fetchedNode[0].externalNotificationConfig?.enabled = config.externalNotification.enabled
|
||||
fetchedNode[0].externalNotificationConfig?.alertBell = config.externalNotification.alertBell
|
||||
fetchedNode[0].externalNotificationConfig?.alertMessage = config.externalNotification.alertMessage
|
||||
fetchedNode[0].externalNotificationConfig?.active = config.externalNotification.active
|
||||
fetchedNode[0].externalNotificationConfig?.output = Int32(config.externalNotification.output)
|
||||
fetchedNode[0].externalNotificationConfig?.outputMilliseconds = Int32(config.externalNotification.outputMs)
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
|
||||
try context.save()
|
||||
if meshlogging { MeshLogger.log("💾 Updated External Notification Module Config for node number: \(String(nodeNum))") }
|
||||
|
||||
} catch {
|
||||
|
||||
context.rollback()
|
||||
|
||||
let nsError = error as NSError
|
||||
print("💥 Error Updating Core Data ExternalNotificationConfigEntity: \(nsError)")
|
||||
}
|
||||
}
|
||||
|
||||
} catch {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if config.payloadVariant == ModuleConfig.OneOf_PayloadVariant.rangeTest(config.rangeTest) {
|
||||
|
||||
var isDefault = false
|
||||
|
|
@ -363,7 +551,7 @@ func moduleConfig (config: ModuleConfig, meshlogging: Bool, context:NSManagedObj
|
|||
} else {
|
||||
|
||||
newRangeTestConfig.sender = Int32(config.rangeTest.sender)
|
||||
newRangeTestConfig.enabled = !config.rangeTest.enabled
|
||||
newRangeTestConfig.enabled = config.rangeTest.enabled
|
||||
newRangeTestConfig.save = config.rangeTest.save
|
||||
}
|
||||
|
||||
|
|
@ -378,9 +566,9 @@ func moduleConfig (config: ModuleConfig, meshlogging: Bool, context:NSManagedObj
|
|||
fetchedNode[0].rangeTestConfig?.save = false
|
||||
|
||||
} else {
|
||||
// Client default protobuf value of 0
|
||||
|
||||
fetchedNode[0].rangeTestConfig?.sender = Int32(config.rangeTest.sender)
|
||||
fetchedNode[0].rangeTestConfig?.enabled = !config.rangeTest.enabled
|
||||
fetchedNode[0].rangeTestConfig?.enabled = config.rangeTest.enabled
|
||||
fetchedNode[0].rangeTestConfig?.save = config.rangeTest.save
|
||||
}
|
||||
}
|
||||
|
|
@ -403,6 +591,190 @@ 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<NSFetchRequestResult> = 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 {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if config.payloadVariant == ModuleConfig.OneOf_PayloadVariant.telemetry(config.telemetry) {
|
||||
|
||||
var isDefault = false
|
||||
|
||||
if (try! config.telemetry.jsonString()) == "{}" {
|
||||
|
||||
isDefault = true
|
||||
print("📈 Default Telemetry Module config")
|
||||
}
|
||||
|
||||
let fetchNodeInfoRequest: NSFetchRequest<NSFetchRequestResult> = 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 Telemetry Config
|
||||
if !fetchedNode.isEmpty {
|
||||
|
||||
if fetchedNode[0].telemetryConfig == nil {
|
||||
|
||||
let newTelemetryConfig = TelemetryConfigEntity(context: context)
|
||||
|
||||
if isDefault {
|
||||
|
||||
newTelemetryConfig.deviceUpdateInterval = 0
|
||||
newTelemetryConfig.environmentUpdateInterval = 0
|
||||
newTelemetryConfig.environmentMeasurementEnabled = false
|
||||
newTelemetryConfig.environmentSensorType = 0
|
||||
newTelemetryConfig.environmentScreenEnabled = false
|
||||
newTelemetryConfig.environmentDisplayFahrenheit = false
|
||||
newTelemetryConfig.environmentRecoveryInterval = 0
|
||||
newTelemetryConfig.environmentReadErrorCountThreshold = 0
|
||||
|
||||
} else {
|
||||
|
||||
newTelemetryConfig.deviceUpdateInterval = Int32(config.telemetry.deviceUpdateInterval)
|
||||
newTelemetryConfig.environmentUpdateInterval = Int32(config.telemetry.environmentUpdateInterval)
|
||||
newTelemetryConfig.environmentMeasurementEnabled = config.telemetry.environmentMeasurementEnabled
|
||||
newTelemetryConfig.environmentSensorType = Int32(config.telemetry.environmentSensorType.rawValue)
|
||||
newTelemetryConfig.environmentScreenEnabled = config.telemetry.environmentScreenEnabled
|
||||
newTelemetryConfig.environmentDisplayFahrenheit = config.telemetry.environmentDisplayFahrenheit
|
||||
newTelemetryConfig.environmentRecoveryInterval = Int32(config.telemetry.environmentRecoveryInterval)
|
||||
newTelemetryConfig.environmentReadErrorCountThreshold = Int32(config.telemetry.environmentReadErrorCountThreshold)
|
||||
|
||||
}
|
||||
|
||||
fetchedNode[0].telemetryConfig = newTelemetryConfig
|
||||
|
||||
} else {
|
||||
|
||||
if isDefault {
|
||||
|
||||
fetchedNode[0].telemetryConfig?.deviceUpdateInterval = 0
|
||||
fetchedNode[0].telemetryConfig?.environmentUpdateInterval = 0
|
||||
fetchedNode[0].telemetryConfig?.environmentMeasurementEnabled = false
|
||||
fetchedNode[0].telemetryConfig?.environmentSensorType = 0
|
||||
fetchedNode[0].telemetryConfig?.environmentScreenEnabled = false
|
||||
fetchedNode[0].telemetryConfig?.environmentDisplayFahrenheit = false
|
||||
fetchedNode[0].telemetryConfig?.environmentRecoveryInterval = 0
|
||||
fetchedNode[0].telemetryConfig?.environmentReadErrorCountThreshold = 0
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
fetchedNode[0].telemetryConfig?.deviceUpdateInterval = Int32(config.telemetry.deviceUpdateInterval)
|
||||
fetchedNode[0].telemetryConfig?.environmentUpdateInterval = Int32(config.telemetry.environmentUpdateInterval)
|
||||
fetchedNode[0].telemetryConfig?.environmentMeasurementEnabled = config.telemetry.environmentMeasurementEnabled
|
||||
fetchedNode[0].telemetryConfig?.environmentSensorType = Int32(config.telemetry.environmentSensorType.rawValue)
|
||||
fetchedNode[0].telemetryConfig?.environmentScreenEnabled = config.telemetry.environmentScreenEnabled
|
||||
fetchedNode[0].telemetryConfig?.environmentDisplayFahrenheit = config.telemetry.environmentDisplayFahrenheit
|
||||
fetchedNode[0].telemetryConfig?.environmentRecoveryInterval = Int32(config.telemetry.environmentRecoveryInterval)
|
||||
fetchedNode[0].telemetryConfig?.environmentReadErrorCountThreshold = Int32(config.telemetry.environmentReadErrorCountThreshold)
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
|
||||
try context.save()
|
||||
if meshlogging { MeshLogger.log("💾 Updated Telemetry Module Config for node number: \(String(nodeNum))") }
|
||||
|
||||
} catch {
|
||||
|
||||
context.rollback()
|
||||
|
||||
let nsError = error as NSError
|
||||
print("💥 Error Updating Core Data TelemetryConfigEntity: \(nsError)")
|
||||
}
|
||||
}
|
||||
|
||||
} catch {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func myInfoPacket (myInfo: MyNodeInfo, meshLogging: Bool, context: NSManagedObjectContext) -> MyInfoEntity? {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="20086" systemVersion="21F79" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<entity name="CannedMessageConfig" representedClassName="CannedMessageConfig" syncable="YES" codeGenerationType="class">
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="19574" systemVersion="21F79" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<entity name="CannedMessageConfigEntity" representedClassName="CannedMessageConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="enabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="inputbrokerEventCcw" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="inputbrokerEventCw" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="inputbrokerEventPress" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="inputbrokerPinA" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="inputbrokerPinB" optional="YES" attributeType="Integer 32" usesScalarValueType="YES"/>
|
||||
<attribute name="inputbrokerPinPress" optional="YES" attributeType="Integer 32" usesScalarValueType="YES"/>
|
||||
|
|
@ -9,7 +12,7 @@
|
|||
<attribute name="rotary1Enabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="sendBell" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="updown1Enabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<relationship name="cannedMessagesConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="cannedMessagesConfig" inverseEntity="NodeInfoEntity"/>
|
||||
<relationship name="cannedMessagesConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="cannedMessageConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="DeviceConfigEntity" representedClassName="DeviceConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="debugLogEnabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
|
|
@ -25,6 +28,16 @@
|
|||
<attribute name="screenOnSeconds" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="displayConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="displayConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="ExternalNotificationConfigEntity" representedClassName="ExternalNotificationConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="active" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="alertBell" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="alertMessage" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="enabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="num" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="output" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="outputMilliseconds" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="externalNotificationConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="externalNotificationConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="LoRaConfigEntity" representedClassName="LoRaConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="hopLimit" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="modemPreset" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
|
|
@ -35,6 +48,7 @@
|
|||
<entity name="MessageEntity" representedClassName="MessageEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="ackSNR" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="ackTimestamp" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="admin" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="direction" attributeType="String"/>
|
||||
<attribute name="isEmoji" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="messageId" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
|
|
@ -78,15 +92,18 @@
|
|||
<attribute name="lastHeard" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="num" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="snr" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<relationship name="cannedMessagesConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="CannedMessageConfig" inverseName="cannedMessagesConfigNode" inverseEntity="CannedMessageConfig"/>
|
||||
<relationship name="cannedMessageConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="CannedMessageConfigEntity" inverseName="cannedMessagesConfigNode" inverseEntity="CannedMessageConfigEntity"/>
|
||||
<relationship name="deviceConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="DeviceConfigEntity" inverseName="deviceConfigNode" inverseEntity="DeviceConfigEntity"/>
|
||||
<relationship name="displayConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="DisplayConfigEntity" inverseName="displayConfigNode" inverseEntity="DisplayConfigEntity"/>
|
||||
<relationship name="externalNotificationConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="ExternalNotificationConfigEntity" inverseName="externalNotificationConfigNode" inverseEntity="ExternalNotificationConfigEntity"/>
|
||||
<relationship name="loRaConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="LoRaConfigEntity" inverseName="loRaConfigNode" inverseEntity="LoRaConfigEntity"/>
|
||||
<relationship name="myInfo" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="MyInfoEntity" inverseName="myInfoNode" inverseEntity="MyInfoEntity"/>
|
||||
<relationship name="positionConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="PositionConfigEntity" inverseName="positionConfigNode" inverseEntity="PositionConfigEntity"/>
|
||||
<relationship name="positions" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="PositionEntity" inverseName="nodePosition" inverseEntity="PositionEntity"/>
|
||||
<relationship name="rangeTestConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="RangeTestConfigEntity" inverseName="rangeTestConfigNode" inverseEntity="RangeTestConfigEntity"/>
|
||||
<relationship name="serialConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="SerialConfigEntity" inverseName="serialConfigNode" inverseEntity="SerialConfigEntity"/>
|
||||
<relationship name="telemetries" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="TelemetryEntity" inverseName="nodeTelemetry" inverseEntity="TelemetryEntity"/>
|
||||
<relationship name="telemetryConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="TelemetryConfigEntity" inverseName="telemetryConfigNode" inverseEntity="TelemetryConfigEntity"/>
|
||||
<relationship name="user" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="UserEntity" inverseName="userNode" inverseEntity="UserEntity"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
|
|
@ -119,6 +136,29 @@
|
|||
<attribute name="sender" optional="YES" attributeType="Integer 32" usesScalarValueType="YES"/>
|
||||
<relationship name="rangeTestConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="rangeTestConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="SerialConfigEntity" representedClassName="SerialConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="baudRate" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="echo" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="enabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="mode" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="num" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="rxd" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="timeout" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="txd" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="serialConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="serialConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="TelemetryConfigEntity" representedClassName="TelemetryConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="deviceUpdateInterval" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="environmentDisplayFahrenheit" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="environmentMeasurementEnabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="environmentReadErrorCountThreshold" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="environmentRecoveryInterval" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="environmentScreenEnabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="environmentSensorType" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="environmentUpdateInterval" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="num" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="telemetryConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="telemetryConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="TelemetryEntity" representedClassName="TelemetryEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="airUtilTx" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="barometricPressure" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
|
|
@ -144,21 +184,24 @@
|
|||
<relationship name="sentMessages" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="MessageEntity" inverseName="fromUser" inverseEntity="MessageEntity"/>
|
||||
<relationship name="userNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="user" inverseEntity="NodeInfoEntity"/>
|
||||
<fetchedProperty name="allMessages" optional="YES">
|
||||
<fetchRequest name="fetchedPropertyFetchRequest" entity="MessageEntity" predicateString="((toUser.num == $FETCH_SOURCE.num) OR (fromUser.num == $FETCH_SOURCE.num)) AND isEmoji == false"/>
|
||||
<fetchRequest name="fetchedPropertyFetchRequest" entity="MessageEntity" predicateString="((toUser.num == $FETCH_SOURCE.num) OR (fromUser.num == $FETCH_SOURCE.num)) AND isEmoji == false AND admin = false"/>
|
||||
</fetchedProperty>
|
||||
</entity>
|
||||
<elements>
|
||||
<element name="CannedMessageConfigEntity" positionX="45" positionY="144" width="128" height="209"/>
|
||||
<element name="DeviceConfigEntity" positionX="45" positionY="144" width="128" height="104"/>
|
||||
<element name="DisplayConfigEntity" positionX="54" positionY="153" width="128" height="104"/>
|
||||
<element name="LoRaConfigEntity" positionX="45" positionY="144" width="128" height="104"/>
|
||||
<element name="MessageEntity" positionX="-36" positionY="63" width="128" height="215"/>
|
||||
<element name="MessageEntity" positionX="-36" positionY="63" width="128" height="230"/>
|
||||
<element name="MyInfoEntity" positionX="-18" positionY="81" width="128" height="209"/>
|
||||
<element name="NodeInfoEntity" positionX="-63" positionY="-18" width="128" height="254"/>
|
||||
<element name="NodeInfoEntity" positionX="-63" positionY="-18" width="128" height="299"/>
|
||||
<element name="PositionConfigEntity" positionX="63" positionY="162" width="128" height="149"/>
|
||||
<element name="PositionEntity" positionX="-54" positionY="54" width="128" height="119"/>
|
||||
<element name="RangeTestConfigEntity" positionX="72" positionY="171" width="128" height="104"/>
|
||||
<element name="TelemetryEntity" positionX="160" positionY="192" width="128" height="194"/>
|
||||
<element name="UserEntity" positionX="0" positionY="144" width="128" height="200"/>
|
||||
<element name="CannedMessageConfig" positionX="45" positionY="144" width="128" height="164"/>
|
||||
<element name="SerialConfigEntity" positionX="54" positionY="153" width="128" height="164"/>
|
||||
<element name="ExternalNotificationConfigEntity" positionX="63" positionY="162" width="128" height="149"/>
|
||||
<element name="TelemetryConfigEntity" positionX="72" positionY="171" width="128" height="179"/>
|
||||
</elements>
|
||||
</model>
|
||||
|
|
@ -68,7 +68,7 @@ struct Connect: View {
|
|||
|
||||
if bleManager.connectedPeripheral != nil {
|
||||
|
||||
Text(bleManager.connectedPeripheral.name).font(.title2)
|
||||
Text(bleManager.connectedPeripheral.longName).font(.title2)
|
||||
|
||||
}
|
||||
Text("BLE Name: ").font(.caption)+Text(bleManager.connectedPeripheral.peripheral.name ?? "Unknown")
|
||||
|
|
@ -265,7 +265,7 @@ struct Connect: View {
|
|||
bluetoothOn: self.bleManager.isSwitchedOn,
|
||||
deviceConnected: self.bleManager.connectedPeripheral != nil,
|
||||
name: (bleManager.connectedPeripheral != nil) ? self.bleManager.connectedPeripheral.shortName :
|
||||
"?????")
|
||||
"????")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -464,7 +464,7 @@ struct UserMessageList: View {
|
|||
ConnectedDevice(
|
||||
bluetoothOn: bleManager.isSwitchedOn,
|
||||
deviceConnected: bleManager.connectedPeripheral != nil,
|
||||
name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????")
|
||||
name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ struct NodeDetail: View {
|
|||
ConnectedDevice(
|
||||
bluetoothOn: bleManager.isSwitchedOn,
|
||||
deviceConnected: bleManager.connectedPeripheral != nil,
|
||||
name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????")
|
||||
name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
|
||||
}
|
||||
)
|
||||
.onAppear(perform: {
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ struct NodeMap: View {
|
|||
bluetoothOn: bleManager.isSwitchedOn,
|
||||
deviceConnected: bleManager.connectedPeripheral != nil,
|
||||
name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName :
|
||||
"?????")
|
||||
"????")
|
||||
})
|
||||
.onAppear(perform: {
|
||||
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ struct AppSettings: View {
|
|||
|
||||
ZStack {
|
||||
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????")
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
|
||||
})
|
||||
.onAppear {
|
||||
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ struct DeviceConfig: View {
|
|||
|
||||
ZStack {
|
||||
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????")
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
|
||||
})
|
||||
.onAppear {
|
||||
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ struct DisplayConfig: View {
|
|||
|
||||
ZStack {
|
||||
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????")
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
|
||||
})
|
||||
.onAppear {
|
||||
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ struct LoRaConfig: View {
|
|||
|
||||
ZStack {
|
||||
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????")
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
|
||||
})
|
||||
.onAppear {
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,28 @@ enum InputEventChars: Int, CaseIterable, Identifiable {
|
|||
}
|
||||
}
|
||||
}
|
||||
func protoEnumValue() -> ModuleConfig.CannedMessageConfig.InputEventChar {
|
||||
|
||||
switch self {
|
||||
|
||||
case .keyNone:
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.keyNone
|
||||
case .keyUp:
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.keyUp
|
||||
case .keyDown:
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.keyDown
|
||||
case .keyLeft:
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.keyLeft
|
||||
case .keyRight:
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.keyRight
|
||||
case .keySelect:
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.keySelect
|
||||
case .keyBack:
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.keyBack
|
||||
case .keyCancel:
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.keyCancel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct CannedMessagesConfig: View {
|
||||
|
|
@ -282,16 +304,18 @@ struct CannedMessagesConfig: View {
|
|||
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 bleManager.saveRangeTestModuleConfig(config: rtc, destNum: bleManager.connectedPeripheral.num, wantResponse: false) {
|
||||
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
|
||||
|
||||
//} else {
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -300,19 +324,20 @@ struct CannedMessagesConfig: View {
|
|||
|
||||
ZStack {
|
||||
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????")
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
|
||||
})
|
||||
.onAppear {
|
||||
|
||||
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.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.hasChanges = false
|
||||
self.initialLoad = false
|
||||
}
|
||||
|
|
@ -336,17 +361,35 @@ struct CannedMessagesConfig: View {
|
|||
}
|
||||
.onChange(of: enabled) { newEnabled in
|
||||
|
||||
//if newEnabled != node.cannedMessagesConfig!.enabled {
|
||||
|
||||
hasChanges = true
|
||||
//}
|
||||
if newEnabled != node.cannedMessageConfig!.enabled { hasChanges = true }
|
||||
}
|
||||
.onChange(of: sendBell) { newBell in
|
||||
|
||||
//if newBell != node.rangeTestConfig!.save {
|
||||
|
||||
hasChanges = true
|
||||
//}
|
||||
if newBell != node.cannedMessageConfig!.sendBell { hasChanges = true }
|
||||
}
|
||||
.onChange(of: inputbrokerPinA) { newPinA in
|
||||
|
||||
if newPinA != node.cannedMessageConfig!.inputbrokerPinA { hasChanges = true }
|
||||
}
|
||||
.onChange(of: inputbrokerPinB) { newPinB in
|
||||
|
||||
if newPinB != node.cannedMessageConfig!.inputbrokerPinB { hasChanges = true }
|
||||
}
|
||||
.onChange(of: inputbrokerPinPress) { newPinPress in
|
||||
|
||||
if newPinPress != node.cannedMessageConfig!.inputbrokerPinPress { hasChanges = true }
|
||||
}
|
||||
.onChange(of: inputbrokerEventCw) { newKeyA in
|
||||
|
||||
if newKeyA != node.cannedMessageConfig!.inputbrokerEventCw { hasChanges = true }
|
||||
}
|
||||
.onChange(of: inputbrokerEventCcw) { newKeyB in
|
||||
|
||||
if newKeyB != node.cannedMessageConfig!.inputbrokerEventCcw { hasChanges = true }
|
||||
}
|
||||
.onChange(of: inputbrokerEventPress) { newKeyPress in
|
||||
|
||||
if newKeyPress != node.cannedMessageConfig!.inputbrokerEventPress { hasChanges = true }
|
||||
}
|
||||
.navigationViewStyle(StackNavigationViewStyle())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,9 +63,6 @@ struct ExternalNotificationConfig: View {
|
|||
@State var active = false
|
||||
@State var output = 0
|
||||
@State var outputMilliseconds = 0
|
||||
|
||||
|
||||
|
||||
|
||||
var body: some View {
|
||||
|
||||
|
|
@ -161,15 +158,17 @@ struct ExternalNotificationConfig: View {
|
|||
enc.output = UInt32(output)
|
||||
enc.outputMs = UInt32(outputMilliseconds)
|
||||
|
||||
//if bleManager.saveRangeTestModuleConfig(config: rtc, destNum: bleManager.connectedPeripheral.num, wantResponse: false) {
|
||||
let adminMessageId = bleManager.saveExternalNotificationModuleConfig(config: enc, 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
|
||||
|
||||
//} else {
|
||||
} else {
|
||||
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -178,11 +177,48 @@ struct ExternalNotificationConfig: View {
|
|||
|
||||
ZStack {
|
||||
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????")
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
|
||||
})
|
||||
.onAppear {
|
||||
|
||||
self.bleManager.context = context
|
||||
if self.initialLoad{
|
||||
|
||||
self.bleManager.context = context
|
||||
|
||||
self.enabled = node.externalNotificationConfig?.enabled ?? false
|
||||
self.alertBell = node.externalNotificationConfig?.alertBell ?? false
|
||||
self.alertMessage = node.externalNotificationConfig?.alertMessage ?? false
|
||||
self.active = node.externalNotificationConfig?.active ?? false
|
||||
self.output = Int(node.externalNotificationConfig?.output ?? 0)
|
||||
self.outputMilliseconds = Int(node.externalNotificationConfig?.outputMilliseconds ?? 0)
|
||||
|
||||
self.hasChanges = false
|
||||
self.initialLoad = false
|
||||
}
|
||||
}
|
||||
.onChange(of: enabled) { newEnabled in
|
||||
|
||||
if newEnabled != node.externalNotificationConfig!.enabled { hasChanges = true }
|
||||
}
|
||||
.onChange(of: alertBell) { newAlertBell in
|
||||
|
||||
if newAlertBell != node.externalNotificationConfig!.alertBell { hasChanges = true }
|
||||
}
|
||||
.onChange(of: alertMessage) { newAlertMessage in
|
||||
|
||||
if newAlertMessage != node.externalNotificationConfig!.alertMessage { hasChanges = true }
|
||||
}
|
||||
.onChange(of: active) { newActuve in
|
||||
|
||||
if newActuve != node.externalNotificationConfig!.active { hasChanges = true }
|
||||
}
|
||||
.onChange(of: output) { newOutput in
|
||||
|
||||
if newOutput != node.externalNotificationConfig!.output { hasChanges = true }
|
||||
}
|
||||
.onChange(of: outputMilliseconds) { newOutputMs in
|
||||
|
||||
if newOutputMs != node.externalNotificationConfig!.outputMilliseconds { hasChanges = true }
|
||||
}
|
||||
.navigationViewStyle(StackNavigationViewStyle())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,15 +113,17 @@ struct RangeTestConfig: View {
|
|||
rtc.save = save
|
||||
rtc.sender = UInt32(sender)
|
||||
|
||||
//if bleManager.saveRangeTestModuleConfig(config: rtc, destNum: bleManager.connectedPeripheral.num, wantResponse: false) {
|
||||
let adminMessageId = bleManager.saveRangeTestModuleConfig(config: rtc, 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
|
||||
|
||||
//} else {
|
||||
} else {
|
||||
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -130,7 +132,7 @@ struct RangeTestConfig: View {
|
|||
|
||||
ZStack {
|
||||
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????")
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
|
||||
})
|
||||
.onAppear {
|
||||
|
||||
|
|
@ -146,21 +148,24 @@ struct RangeTestConfig: View {
|
|||
}
|
||||
.onChange(of: enabled) { newEnabled in
|
||||
|
||||
//if newEnabled != node.rangeTestConfig!.enabled {
|
||||
if newEnabled != node.rangeTestConfig!.enabled {
|
||||
|
||||
hasChanges = true
|
||||
//}
|
||||
}
|
||||
}
|
||||
.onChange(of: save) { newSave in
|
||||
|
||||
//if newSave != node.rangeTestConfig!.save {
|
||||
if newSave != node.rangeTestConfig!.save {
|
||||
|
||||
hasChanges = true
|
||||
//}
|
||||
}
|
||||
}
|
||||
.onChange(of: sender) { newSender in
|
||||
|
||||
hasChanges = true
|
||||
if newSender != node.rangeTestConfig!.sender {
|
||||
|
||||
hasChanges = true
|
||||
}
|
||||
}
|
||||
.navigationViewStyle(StackNavigationViewStyle())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -238,14 +291,20 @@ struct SerialConfig: View {
|
|||
"Are you sure?",
|
||||
isPresented: $isPresentingSaveConfirm
|
||||
) {
|
||||
Button("Save Range Test Module Config to \(bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : "Unknown")?") {
|
||||
Button("Save Serial Module Config to \(bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : "Unknown")?") {
|
||||
|
||||
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) {
|
||||
let adminMessageId = bleManager.saveSerialModuleConfig(config: sc, 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
|
||||
|
|
@ -262,11 +321,53 @@ struct SerialConfig: View {
|
|||
|
||||
ZStack {
|
||||
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????")
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
|
||||
})
|
||||
.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())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -187,7 +187,6 @@ struct TelemetryConfig: View {
|
|||
|
||||
@State var deviceUpdateInterval = 0
|
||||
@State var environmentUpdateInterval = 0
|
||||
|
||||
@State var environmentMeasurementEnabled = false
|
||||
@State var environmentSensorType = 0
|
||||
@State var environmentScreenEnabled = false
|
||||
|
|
@ -303,6 +302,8 @@ struct TelemetryConfig: View {
|
|||
Button("Save Telemetry Module Config to \(bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : "Unknown")?") {
|
||||
|
||||
var tc = ModuleConfig.TelemetryConfig()
|
||||
tc.deviceUpdateInterval = UInt32(deviceUpdateInterval)
|
||||
tc.environmentUpdateInterval = UInt32(environmentUpdateInterval)
|
||||
tc.environmentMeasurementEnabled = environmentMeasurementEnabled
|
||||
tc.environmentSensorType = SensorTypes(rawValue: environmentSensorType)!.protoEnumValue()
|
||||
tc.environmentScreenEnabled = environmentScreenEnabled
|
||||
|
|
@ -327,11 +328,58 @@ struct TelemetryConfig: View {
|
|||
|
||||
ZStack {
|
||||
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????")
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
|
||||
})
|
||||
.onAppear {
|
||||
|
||||
self.bleManager.context = context
|
||||
if self.initialLoad{
|
||||
|
||||
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.environmentSensorType = Int(node.telemetryConfig?.environmentSensorType ?? 0)
|
||||
self.environmentScreenEnabled = node.telemetryConfig?.environmentScreenEnabled ?? false
|
||||
self.environmentDisplayFahrenheit = node.telemetryConfig?.environmentDisplayFahrenheit ?? false
|
||||
self.environmentRecoveryInterval = Int(node.telemetryConfig?.environmentRecoveryInterval ?? 0)
|
||||
self.environmentReadErrorCountThreshold = Int(node.telemetryConfig?.environmentReadErrorCountThreshold ?? 0)
|
||||
|
||||
self.hasChanges = false
|
||||
self.initialLoad = false
|
||||
}
|
||||
}
|
||||
.onChange(of: deviceUpdateInterval) { newDeviceInterval in
|
||||
|
||||
if newDeviceInterval != node.telemetryConfig!.deviceUpdateInterval { hasChanges = true }
|
||||
}
|
||||
.onChange(of: environmentUpdateInterval) { newEnvInterval in
|
||||
|
||||
if newEnvInterval != node.telemetryConfig!.environmentUpdateInterval { hasChanges = true }
|
||||
}
|
||||
.onChange(of: environmentMeasurementEnabled) { newEnvEnabled in
|
||||
|
||||
if newEnvEnabled != node.telemetryConfig!.environmentMeasurementEnabled { hasChanges = true }
|
||||
}
|
||||
.onChange(of: environmentSensorType) { newEnvSensorType in
|
||||
|
||||
if newEnvSensorType != node.telemetryConfig!.environmentSensorType { hasChanges = true }
|
||||
}
|
||||
.onChange(of: environmentScreenEnabled) { newEnvScreenEnabled in
|
||||
|
||||
if newEnvScreenEnabled != node.telemetryConfig!.environmentScreenEnabled { hasChanges = true }
|
||||
}
|
||||
.onChange(of: environmentDisplayFahrenheit) { newEnvDisplayF in
|
||||
|
||||
if newEnvDisplayF != node.telemetryConfig!.environmentDisplayFahrenheit { hasChanges = true }
|
||||
}
|
||||
.onChange(of: environmentRecoveryInterval) { newEnvRecoveryInterval in
|
||||
|
||||
if newEnvRecoveryInterval != node.telemetryConfig!.environmentRecoveryInterval { hasChanges = true }
|
||||
}
|
||||
.onChange(of: environmentReadErrorCountThreshold) { newEnvReadErrorCountThreshold in
|
||||
|
||||
if newEnvReadErrorCountThreshold != node.telemetryConfig!.environmentReadErrorCountThreshold { hasChanges = true }
|
||||
}
|
||||
.navigationViewStyle(StackNavigationViewStyle())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ struct PositionConfig: View {
|
|||
|
||||
ZStack {
|
||||
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????")
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
|
||||
})
|
||||
.onAppear {
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ struct ShareChannel: View {
|
|||
|
||||
ZStack {
|
||||
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????")
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
|
||||
})
|
||||
.onAppear {
|
||||
|
||||
|
|
|
|||
|
|
@ -112,14 +112,11 @@ struct UserConfig: View {
|
|||
u.shortName = shortName
|
||||
u.longName = longName
|
||||
|
||||
if bleManager.saveUser(config: u, destNum: bleManager.connectedPeripheral.num, wantResponse: false) {
|
||||
let adminMessageId = bleManager.saveUser(config: u, entity: 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
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -132,7 +129,7 @@ struct UserConfig: View {
|
|||
|
||||
ZStack {
|
||||
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?????")
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
|
||||
})
|
||||
.onAppear {
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue