Remote Admin for Module Config

This commit is contained in:
Garth Vander Houwen 2023-02-01 09:19:45 -08:00
parent f89f5eddd0
commit 57dbc7b71f
8 changed files with 544 additions and 368 deletions

View file

@ -1559,6 +1559,58 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
return false
}
public func requestCannedMessagesModuleConfig(fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Bool {
var adminPacket = AdminMessage()
adminPacket.getModuleConfigRequest = AdminMessage.ModuleConfigType.cannedmsgConfig
var meshPacket: MeshPacket = MeshPacket()
meshPacket.to = UInt32(toUser.num)
meshPacket.from = UInt32(fromUser.num)
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
meshPacket.priority = MeshPacket.Priority.reliable
meshPacket.channel = UInt32(adminIndex)
var dataMessage = DataMessage()
dataMessage.payload = try! adminPacket.serializedData()
dataMessage.portnum = PortNum.adminApp
dataMessage.wantResponse = true
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Requested Canned Messages Module Config on admin channel \(adminIndex) for node: \(String(connectedPeripheral.num))"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
return true
}
return false
}
public func requestExternalNotificationModuleConfig(fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Bool {
var adminPacket = AdminMessage()
adminPacket.getModuleConfigRequest = AdminMessage.ModuleConfigType.extnotifConfig
var meshPacket: MeshPacket = MeshPacket()
meshPacket.to = UInt32(toUser.num)
meshPacket.from = UInt32(fromUser.num)
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
meshPacket.priority = MeshPacket.Priority.reliable
meshPacket.channel = UInt32(adminIndex)
var dataMessage = DataMessage()
dataMessage.payload = try! adminPacket.serializedData()
dataMessage.portnum = PortNum.adminApp
dataMessage.wantResponse = true
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Requested External Notificaiton Module Config on admin channel \(adminIndex) for node: \(String(connectedPeripheral.num))"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
return true
}
return false
}
public func requestRangeTestModuleConfig(fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Bool {
var adminPacket = AdminMessage()
@ -1585,6 +1637,58 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
return false
}
public func requestMqttModuleConfig(fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Bool {
var adminPacket = AdminMessage()
adminPacket.getModuleConfigRequest = AdminMessage.ModuleConfigType.mqttConfig
var meshPacket: MeshPacket = MeshPacket()
meshPacket.to = UInt32(toUser.num)
meshPacket.from = UInt32(fromUser.num)
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
meshPacket.priority = MeshPacket.Priority.reliable
meshPacket.channel = UInt32(adminIndex)
var dataMessage = DataMessage()
dataMessage.payload = try! adminPacket.serializedData()
dataMessage.portnum = PortNum.adminApp
dataMessage.wantResponse = true
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Requested MQTT Module Config on admin channel \(adminIndex) for node: \(String(connectedPeripheral.num))"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
return true
}
return false
}
public func requestSerialModuleConfig(fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Bool {
var adminPacket = AdminMessage()
adminPacket.getModuleConfigRequest = AdminMessage.ModuleConfigType.serialConfig
var meshPacket: MeshPacket = MeshPacket()
meshPacket.to = UInt32(toUser.num)
meshPacket.from = UInt32(fromUser.num)
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
meshPacket.priority = MeshPacket.Priority.reliable
meshPacket.channel = UInt32(adminIndex)
var dataMessage = DataMessage()
dataMessage.payload = try! adminPacket.serializedData()
dataMessage.portnum = PortNum.adminApp
dataMessage.wantResponse = true
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Requested Serial Module Config on admin channel \(adminIndex) for node: \(String(connectedPeripheral.num))"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
return true
}
return false
}
public func requestTelemetryModuleConfig(fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Bool {
var adminPacket = AdminMessage()

View file

@ -57,338 +57,17 @@ func localConfig (config: Config, context:NSManagedObjectContext, nodeNum: Int64
func moduleConfig (config: ModuleConfig, context:NSManagedObjectContext, nodeNum: Int64, nodeLongName: String) {
if config.payloadVariant == ModuleConfig.OneOf_PayloadVariant.cannedMessage(config.cannedMessage) {
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.cannedmessage.config %@", comment: "Canned Message module config received: %@"), String(nodeNum))
MeshLogger.log("🥫 \(logString)")
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)
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 {
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()
print("💾 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)")
}
} else {
print("💥 No Nodes found in local database matching node number \(nodeNum) unable to save Canned Message Module Config")
}
} catch {
let nsError = error as NSError
print("💥 Fetching node for core data CannedMessageConfigEntity failed: \(nsError)")
}
}
if config.payloadVariant == ModuleConfig.OneOf_PayloadVariant.externalNotification(config.externalNotification) {
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.externalnotification.config %@", comment: "External Notifiation module config received: %@"), String(nodeNum))
MeshLogger.log("📣 \(logString)")
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)
newExternalNotificationConfig.enabled = config.externalNotification.enabled
newExternalNotificationConfig.usePWM = config.externalNotification.usePwm
newExternalNotificationConfig.alertBell = config.externalNotification.alertBell
newExternalNotificationConfig.alertBellBuzzer = config.externalNotification.alertBellBuzzer
newExternalNotificationConfig.alertBellVibra = config.externalNotification.alertBellVibra
newExternalNotificationConfig.alertMessage = config.externalNotification.alertMessage
newExternalNotificationConfig.alertMessageBuzzer = config.externalNotification.alertMessageBuzzer
newExternalNotificationConfig.alertMessageVibra = config.externalNotification.alertMessageVibra
newExternalNotificationConfig.active = config.externalNotification.active
newExternalNotificationConfig.output = Int32(config.externalNotification.output)
newExternalNotificationConfig.outputBuzzer = Int32(config.externalNotification.outputBuzzer)
newExternalNotificationConfig.outputVibra = Int32(config.externalNotification.outputVibra)
newExternalNotificationConfig.outputMilliseconds = Int32(config.externalNotification.outputMs)
newExternalNotificationConfig.nagTimeout = Int32(config.externalNotification.nagTimeout)
fetchedNode[0].externalNotificationConfig = newExternalNotificationConfig
} else {
fetchedNode[0].externalNotificationConfig?.enabled = config.externalNotification.enabled
fetchedNode[0].externalNotificationConfig?.usePWM = config.externalNotification.usePwm
fetchedNode[0].externalNotificationConfig?.alertBell = config.externalNotification.alertBell
fetchedNode[0].externalNotificationConfig?.alertBellBuzzer = config.externalNotification.alertBellBuzzer
fetchedNode[0].externalNotificationConfig?.alertBellVibra = config.externalNotification.alertBellVibra
fetchedNode[0].externalNotificationConfig?.alertMessage = config.externalNotification.alertMessage
fetchedNode[0].externalNotificationConfig?.alertMessageBuzzer = config.externalNotification.alertMessageBuzzer
fetchedNode[0].externalNotificationConfig?.alertMessageVibra = config.externalNotification.alertMessageVibra
fetchedNode[0].externalNotificationConfig?.active = config.externalNotification.active
fetchedNode[0].externalNotificationConfig?.output = Int32(config.externalNotification.output)
fetchedNode[0].externalNotificationConfig?.outputBuzzer = Int32(config.externalNotification.outputBuzzer)
fetchedNode[0].externalNotificationConfig?.outputVibra = Int32(config.externalNotification.outputVibra)
fetchedNode[0].externalNotificationConfig?.outputMilliseconds = Int32(config.externalNotification.outputMs)
fetchedNode[0].externalNotificationConfig?.nagTimeout = Int32(config.externalNotification.nagTimeout)
}
do {
try context.save()
print("💾 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)")
}
} else {
print("💥 No Nodes found in local database matching node number \(nodeNum) unable to save External Notifiation Module Config")
}
} catch {
let nsError = error as NSError
print("💥 Fetching node for core data ExternalNotificationConfigEntity failed: \(nsError)")
}
}
if config.payloadVariant == ModuleConfig.OneOf_PayloadVariant.mqtt(config.mqtt) {
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.mqtt.config %@", comment: "MQTT module config received: %@"), String(nodeNum))
MeshLogger.log("🌉 \(logString)")
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 MQTT Config
if !fetchedNode.isEmpty {
if fetchedNode[0].mqttConfig == nil {
let newMQTTConfig = MQTTConfigEntity(context: context)
newMQTTConfig.enabled = config.mqtt.enabled
newMQTTConfig.address = config.mqtt.address
newMQTTConfig.address = config.mqtt.username
newMQTTConfig.password = config.mqtt.password
newMQTTConfig.encryptionEnabled = config.mqtt.encryptionEnabled
newMQTTConfig.jsonEnabled = config.mqtt.jsonEnabled
fetchedNode[0].mqttConfig = newMQTTConfig
} else {
fetchedNode[0].mqttConfig?.enabled = config.mqtt.enabled
fetchedNode[0].mqttConfig?.address = config.mqtt.address
fetchedNode[0].mqttConfig?.address = config.mqtt.username
fetchedNode[0].mqttConfig?.password = config.mqtt.password
fetchedNode[0].mqttConfig?.encryptionEnabled = config.mqtt.encryptionEnabled
fetchedNode[0].mqttConfig?.jsonEnabled = config.mqtt.jsonEnabled
}
do {
try context.save()
print("💾 Updated MQTT Config for node number: \(String(nodeNum))")
} catch {
context.rollback()
let nsError = error as NSError
print("💥 Error Updating Core Data MQTTConfigEntity: \(nsError)")
}
} else {
print("💥 No Nodes found in local database matching node number \(nodeNum) unable to save MQTT Module Config")
}
} catch {
let nsError = error as NSError
print("💥 Fetching node for core data MQTTConfigEntity failed: \(nsError)")
}
}
if config.payloadVariant == ModuleConfig.OneOf_PayloadVariant.rangeTest(config.rangeTest) {
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.rangetest.config %@", comment: "Range Test module config received: %@"), String(nodeNum))
MeshLogger.log("⛰️ \(logString)")
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].rangeTestConfig == nil {
let newRangeTestConfig = RangeTestConfigEntity(context: context)
newRangeTestConfig.sender = Int32(config.rangeTest.sender)
newRangeTestConfig.enabled = config.rangeTest.enabled
newRangeTestConfig.save = config.rangeTest.save
fetchedNode[0].rangeTestConfig = newRangeTestConfig
} else {
fetchedNode[0].rangeTestConfig?.sender = Int32(config.rangeTest.sender)
fetchedNode[0].rangeTestConfig?.enabled = config.rangeTest.enabled
fetchedNode[0].rangeTestConfig?.save = config.rangeTest.save
}
do {
try context.save()
print("💾 Updated Range Test Config for node number: \(String(nodeNum))")
} catch {
context.rollback()
let nsError = error as NSError
print("💥 Error Updating Core Data RangeTestConfigEntity: \(nsError)")
}
} else {
print("💥 No Nodes found in local database matching node number \(nodeNum) unable to save Range Test Module Config")
}
} catch {
let nsError = error as NSError
print("💥 Fetching node for core data RangeTestConfigEntity failed: \(nsError)")
}
}
if config.payloadVariant == ModuleConfig.OneOf_PayloadVariant.serial(config.serial) {
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.serial.config %@", comment: "Serial module config received: %@"), String(nodeNum))
MeshLogger.log("🤖 \(logString)")
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)
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 {
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()
print("💾 Updated Serial Module Config for node number: \(String(nodeNum))")
} catch {
context.rollback()
let nsError = error as NSError
print("💥 Error Updating Core Data SerialConfigEntity: \(nsError)")
}
} else {
print("💥 No Nodes found in local database matching node number \(nodeNum) unable to save Serial Module Config")
}
} catch {
let nsError = error as NSError
print("💥 Fetching node for core data SerialConfigEntity failed: \(nsError)")
}
}
if config.payloadVariant == ModuleConfig.OneOf_PayloadVariant.telemetry(config.telemetry) {
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.telemetry.config %@", comment: "Telemetry module config received: %@"), String(nodeNum))
MeshLogger.log("📈 \(logString)")
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)
newTelemetryConfig.deviceUpdateInterval = Int32(config.telemetry.deviceUpdateInterval)
newTelemetryConfig.environmentUpdateInterval = Int32(config.telemetry.environmentUpdateInterval)
newTelemetryConfig.environmentMeasurementEnabled = config.telemetry.environmentMeasurementEnabled
newTelemetryConfig.environmentScreenEnabled = config.telemetry.environmentScreenEnabled
newTelemetryConfig.environmentDisplayFahrenheit = config.telemetry.environmentDisplayFahrenheit
fetchedNode[0].telemetryConfig = newTelemetryConfig
} 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?.environmentScreenEnabled = config.telemetry.environmentScreenEnabled
fetchedNode[0].telemetryConfig?.environmentDisplayFahrenheit = config.telemetry.environmentDisplayFahrenheit
}
do {
try context.save()
print("💾 Updated Telemetry Module Config for node number: \(String(nodeNum))")
} catch {
context.rollback()
let nsError = error as NSError
print("💥 Error Updating Core Data TelemetryConfigEntity: \(nsError)")
}
} else {
print("💥 No Nodes found in local database matching node number \(nodeNum) unable to save Telemetry Module Config")
}
} catch {
let nsError = error as NSError
print("💥 Fetching node for core data TelemetryConfigEntity failed: \(nsError)")
}
upsertCannedMessagesModuleConfigPacket(config: config.cannedMessage, nodeNum: nodeNum, context: context)
} else if config.payloadVariant == ModuleConfig.OneOf_PayloadVariant.externalNotification(config.externalNotification) {
upsertExternalNotificationModuleConfigPacket(config: config.externalNotification, nodeNum: nodeNum, context: context)
} else if config.payloadVariant == ModuleConfig.OneOf_PayloadVariant.mqtt(config.mqtt) {
upsertMqttModuleConfigPacket(config: config.mqtt, nodeNum: nodeNum, context: context)
} else if config.payloadVariant == ModuleConfig.OneOf_PayloadVariant.rangeTest(config.rangeTest) {
upsertRangeTestModuleConfigPacket(config: config.rangeTest, nodeNum: nodeNum, context: context)
} else if config.payloadVariant == ModuleConfig.OneOf_PayloadVariant.serial(config.serial) {
upsertSerialModuleConfigPacket(config: config.serial, nodeNum: nodeNum, context: context)
} else if config.payloadVariant == ModuleConfig.OneOf_PayloadVariant.telemetry(config.telemetry) {
upsertTelemetryModuleConfigPacket(config: config.telemetry, nodeNum: nodeNum, context: context)
}
}
@ -800,9 +479,9 @@ func adminAppPacket (packet: MeshPacket, context: NSManagedObjectContext) {
deviceMetadataPacket(metadata: adminMessage.getDeviceMetadataResponse, fromNum: Int64(packet.from), context: context)
} else if adminMessage.payloadVariant == AdminMessage.OneOf_PayloadVariant.getConfigResponse(adminMessage.getConfigResponse) {
let config = adminMessage.getConfigResponse
if config.payloadVariant == Config.OneOf_PayloadVariant.bluetooth(config.bluetooth) {
upsertBluetoothConfigPacket(config: config.bluetooth, nodeNum: Int64(packet.from), context: context)
@ -817,8 +496,32 @@ func adminAppPacket (packet: MeshPacket, context: NSManagedObjectContext) {
} else if config.payloadVariant == Config.OneOf_PayloadVariant.position(config.position) {
upsertPositionConfigPacket(config: config.position, nodeNum: Int64(packet.from), context: context)
}
} else if adminMessage.payloadVariant == AdminMessage.OneOf_PayloadVariant.getModuleConfigResponse(adminMessage.getModuleConfigResponse) {
let moduleConfig = adminMessage.getModuleConfigResponse
if moduleConfig.payloadVariant == ModuleConfig.OneOf_PayloadVariant.cannedMessage(moduleConfig.cannedMessage) {
upsertCannedMessagesModuleConfigPacket(config: moduleConfig.cannedMessage, nodeNum: Int64(packet.from), context: context)
} else if moduleConfig.payloadVariant == ModuleConfig.OneOf_PayloadVariant.externalNotification(moduleConfig.externalNotification) {
upsertExternalNotificationModuleConfigPacket(config: moduleConfig.externalNotification, nodeNum: Int64(packet.from), context: context)
} else if moduleConfig.payloadVariant == ModuleConfig.OneOf_PayloadVariant.mqtt(moduleConfig.mqtt) {
upsertMqttModuleConfigPacket(config: moduleConfig.mqtt, nodeNum: Int64(packet.from), context: context)
} else if moduleConfig.payloadVariant == ModuleConfig.OneOf_PayloadVariant.rangeTest(moduleConfig.rangeTest) {
upsertRangeTestModuleConfigPacket(config: moduleConfig.rangeTest, nodeNum: Int64(packet.from), context: context)
} else if moduleConfig.payloadVariant == ModuleConfig.OneOf_PayloadVariant.serial(moduleConfig.serial) {
upsertSerialModuleConfigPacket(config: moduleConfig.serial, nodeNum: Int64(packet.from), context: context)
} else if moduleConfig.payloadVariant == ModuleConfig.OneOf_PayloadVariant.telemetry(moduleConfig.telemetry) {
upsertTelemetryModuleConfigPacket(config: moduleConfig.telemetry, nodeNum: Int64(packet.from), context: context)
}
} else {
MeshLogger.log("🕸️ MESH PACKET received for Admin App \(try! packet.decoded.jsonString())")
}

View file

@ -7,14 +7,14 @@
import CoreData
public func clearPositions(destNum: Int64, context: NSManagedObjectContext) -> Bool {
let fetchNodeInfoRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "NodeInfoEntity")
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(destNum))
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
let newPostions = [PositionEntity]()
fetchedNode[0].positions? = NSOrderedSet(array: newPostions)
@ -26,7 +26,7 @@ public func clearPositions(destNum: Int64, context: NSManagedObjectContext) -> B
context.rollback()
return false
}
} catch {
print("💥 Fetch NodeInfoEntity Error")
return false
@ -37,11 +37,11 @@ public func clearTelemetry(destNum: Int64, metricsType: Int32, context: NSManage
let fetchNodeInfoRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "NodeInfoEntity")
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(destNum))
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
let emptyTelemetry = [TelemetryEntity]()
fetchedNode[0].telemetries? = NSOrderedSet(array: emptyTelemetry)
@ -53,7 +53,7 @@ public func clearTelemetry(destNum: Int64, metricsType: Int32, context: NSManage
context.rollback()
return false
}
} catch {
print("💥 Fetch NodeInfoEntity Error")
return false
@ -63,9 +63,9 @@ public func clearTelemetry(destNum: Int64, metricsType: Int32, context: NSManage
public func deleteChannelMessages(channel: ChannelEntity, context: NSManagedObjectContext) {
do {
let objects = channel.allPrivateMessages
for object in objects {
context.delete(object)
}
for object in objects {
context.delete(object)
}
try context.save()
} catch let error as NSError {
print("Error: \(error.localizedDescription)")
@ -73,12 +73,12 @@ public func deleteChannelMessages(channel: ChannelEntity, context: NSManagedObje
}
public func deleteUserMessages(user: UserEntity, context: NSManagedObjectContext) {
do {
let objects = user.messageList
for object in objects {
context.delete(object)
}
for object in objects {
context.delete(object)
}
try context.save()
} catch let error as NSError {
print("Error: \(error.localizedDescription)")
@ -92,11 +92,11 @@ public func clearCoreDataDatabase(context: NSManagedObjectContext) {
let entity = persistenceController.managedObjectModel.entities[i]
let query = NSFetchRequest<NSFetchRequestResult>(entityName: entity.name!)
let deleteRequest = NSBatchDeleteRequest(fetchRequest: query)
do {
try context.executeAndMergeChanges(using: deleteRequest)
} catch let error as NSError {
print(error)
print(error)
}
}
}
@ -112,7 +112,7 @@ func upsertPositionPacket (packet: MeshPacket, context: NSManagedObjectContext)
do {
if let positionMessage = try? Position(serializedData: packet.decoded.payload) {
// Don't save empty position packets
if positionMessage.longitudeI > 0 || positionMessage.latitudeI > 0 && (positionMessage.latitudeI != 373346000 && positionMessage.longitudeI != -1220090000)
{
@ -456,3 +456,337 @@ func upsertPositionConfigPacket(config: Meshtastic.Config.PositionConfig, nodeNu
print("💥 Fetching node for core data PositionConfigEntity failed: \(nsError)")
}
}
func upsertCannedMessagesModuleConfigPacket(config: Meshtastic.ModuleConfig.CannedMessageConfig, nodeNum: Int64, context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.cannedmessage.config %@", comment: "Canned Message module config received: %@"), String(nodeNum))
MeshLogger.log("🥫 \(logString)")
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)
newCannedMessageConfig.enabled = config.enabled
newCannedMessageConfig.sendBell = config.sendBell
newCannedMessageConfig.rotary1Enabled = config.rotary1Enabled
newCannedMessageConfig.updown1Enabled = config.updown1Enabled
newCannedMessageConfig.inputbrokerPinA = Int32(config.inputbrokerPinA)
newCannedMessageConfig.inputbrokerPinB = Int32(config.inputbrokerPinB)
newCannedMessageConfig.inputbrokerPinPress = Int32(config.inputbrokerPinPress)
newCannedMessageConfig.inputbrokerEventCw = Int32(config.inputbrokerEventCw.rawValue)
newCannedMessageConfig.inputbrokerEventCcw = Int32(config.inputbrokerEventCcw.rawValue)
newCannedMessageConfig.inputbrokerEventPress = Int32(config.inputbrokerEventPress.rawValue)
fetchedNode[0].cannedMessageConfig = newCannedMessageConfig
} else {
fetchedNode[0].cannedMessageConfig?.enabled = config.enabled
fetchedNode[0].cannedMessageConfig?.sendBell = config.sendBell
fetchedNode[0].cannedMessageConfig?.rotary1Enabled = config.rotary1Enabled
fetchedNode[0].cannedMessageConfig?.updown1Enabled = config.updown1Enabled
fetchedNode[0].cannedMessageConfig?.inputbrokerPinA = Int32(config.inputbrokerPinA)
fetchedNode[0].cannedMessageConfig?.inputbrokerPinB = Int32(config.inputbrokerPinB)
fetchedNode[0].cannedMessageConfig?.inputbrokerPinPress = Int32(config.inputbrokerPinPress)
fetchedNode[0].cannedMessageConfig?.inputbrokerEventCw = Int32(config.inputbrokerEventCw.rawValue)
fetchedNode[0].cannedMessageConfig?.inputbrokerEventCcw = Int32(config.inputbrokerEventCcw.rawValue)
fetchedNode[0].cannedMessageConfig?.inputbrokerEventPress = Int32(config.inputbrokerEventPress.rawValue)
}
do {
try context.save()
print("💾 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)")
}
} else {
print("💥 No Nodes found in local database matching node number \(nodeNum) unable to save Canned Message Module Config")
}
} catch {
let nsError = error as NSError
print("💥 Fetching node for core data CannedMessageConfigEntity failed: \(nsError)")
}
}
func upsertExternalNotificationModuleConfigPacket(config: Meshtastic.ModuleConfig.ExternalNotificationConfig, nodeNum: Int64, context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.externalnotification.config %@", comment: "External Notifiation module config received: %@"), String(nodeNum))
MeshLogger.log("📣 \(logString)")
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)
newExternalNotificationConfig.enabled = config.enabled
newExternalNotificationConfig.usePWM = config.usePwm
newExternalNotificationConfig.alertBell = config.alertBell
newExternalNotificationConfig.alertBellBuzzer = config.alertBellBuzzer
newExternalNotificationConfig.alertBellVibra = config.alertBellVibra
newExternalNotificationConfig.alertMessage = config.alertMessage
newExternalNotificationConfig.alertMessageBuzzer = config.alertMessageBuzzer
newExternalNotificationConfig.alertMessageVibra = config.alertMessageVibra
newExternalNotificationConfig.active = config.active
newExternalNotificationConfig.output = Int32(config.output)
newExternalNotificationConfig.outputBuzzer = Int32(config.outputBuzzer)
newExternalNotificationConfig.outputVibra = Int32(config.outputVibra)
newExternalNotificationConfig.outputMilliseconds = Int32(config.outputMs)
newExternalNotificationConfig.nagTimeout = Int32(config.nagTimeout)
fetchedNode[0].externalNotificationConfig = newExternalNotificationConfig
} else {
fetchedNode[0].externalNotificationConfig?.enabled = config.enabled
fetchedNode[0].externalNotificationConfig?.usePWM = config.usePwm
fetchedNode[0].externalNotificationConfig?.alertBell = config.alertBell
fetchedNode[0].externalNotificationConfig?.alertBellBuzzer = config.alertBellBuzzer
fetchedNode[0].externalNotificationConfig?.alertBellVibra = config.alertBellVibra
fetchedNode[0].externalNotificationConfig?.alertMessage = config.alertMessage
fetchedNode[0].externalNotificationConfig?.alertMessageBuzzer = config.alertMessageBuzzer
fetchedNode[0].externalNotificationConfig?.alertMessageVibra = config.alertMessageVibra
fetchedNode[0].externalNotificationConfig?.active = config.active
fetchedNode[0].externalNotificationConfig?.output = Int32(config.output)
fetchedNode[0].externalNotificationConfig?.outputBuzzer = Int32(config.outputBuzzer)
fetchedNode[0].externalNotificationConfig?.outputVibra = Int32(config.outputVibra)
fetchedNode[0].externalNotificationConfig?.outputMilliseconds = Int32(config.outputMs)
fetchedNode[0].externalNotificationConfig?.nagTimeout = Int32(config.nagTimeout)
}
do {
try context.save()
print("💾 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)")
}
} else {
print("💥 No Nodes found in local database matching node number \(nodeNum) unable to save External Notifiation Module Config")
}
} catch {
let nsError = error as NSError
print("💥 Fetching node for core data ExternalNotificationConfigEntity failed: \(nsError)")
}
}
func upsertMqttModuleConfigPacket(config: Meshtastic.ModuleConfig.MQTTConfig, nodeNum: Int64, context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.mqtt.config %@", comment: "MQTT module config received: %@"), String(nodeNum))
MeshLogger.log("🌉 \(logString)")
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 MQTT Config
if !fetchedNode.isEmpty {
if fetchedNode[0].mqttConfig == nil {
let newMQTTConfig = MQTTConfigEntity(context: context)
newMQTTConfig.enabled = config.enabled
newMQTTConfig.address = config.address
newMQTTConfig.address = config.username
newMQTTConfig.password = config.password
newMQTTConfig.encryptionEnabled = config.encryptionEnabled
newMQTTConfig.jsonEnabled = config.jsonEnabled
fetchedNode[0].mqttConfig = newMQTTConfig
} else {
fetchedNode[0].mqttConfig?.enabled = config.enabled
fetchedNode[0].mqttConfig?.address = config.address
fetchedNode[0].mqttConfig?.address = config.username
fetchedNode[0].mqttConfig?.password = config.password
fetchedNode[0].mqttConfig?.encryptionEnabled = config.encryptionEnabled
fetchedNode[0].mqttConfig?.jsonEnabled = config.jsonEnabled
}
do {
try context.save()
print("💾 Updated MQTT Config for node number: \(String(nodeNum))")
} catch {
context.rollback()
let nsError = error as NSError
print("💥 Error Updating Core Data MQTTConfigEntity: \(nsError)")
}
} else {
print("💥 No Nodes found in local database matching node number \(nodeNum) unable to save MQTT Module Config")
}
} catch {
let nsError = error as NSError
print("💥 Fetching node for core data MQTTConfigEntity failed: \(nsError)")
}
}
func upsertRangeTestModuleConfigPacket(config: Meshtastic.ModuleConfig.RangeTestConfig, nodeNum: Int64, context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.rangetest.config %@", comment: "Range Test module config received: %@"), String(nodeNum))
MeshLogger.log("⛰️ \(logString)")
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].rangeTestConfig == nil {
let newRangeTestConfig = RangeTestConfigEntity(context: context)
newRangeTestConfig.sender = Int32(config.sender)
newRangeTestConfig.enabled = config.enabled
newRangeTestConfig.save = config.save
fetchedNode[0].rangeTestConfig = newRangeTestConfig
} else {
fetchedNode[0].rangeTestConfig?.sender = Int32(config.sender)
fetchedNode[0].rangeTestConfig?.enabled = config.enabled
fetchedNode[0].rangeTestConfig?.save = config.save
}
do {
try context.save()
print("💾 Updated Range Test Config for node number: \(String(nodeNum))")
} catch {
context.rollback()
let nsError = error as NSError
print("💥 Error Updating Core Data RangeTestConfigEntity: \(nsError)")
}
} else {
print("💥 No Nodes found in local database matching node number \(nodeNum) unable to save Range Test Module Config")
}
} catch {
let nsError = error as NSError
print("💥 Fetching node for core data RangeTestConfigEntity failed: \(nsError)")
}
}
func upsertSerialModuleConfigPacket(config: Meshtastic.ModuleConfig.SerialConfig, nodeNum: Int64, context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.serial.config %@", comment: "Serial module config received: %@"), String(nodeNum))
MeshLogger.log("🤖 \(logString)")
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)
newSerialConfig.enabled = config.enabled
newSerialConfig.echo = config.echo
newSerialConfig.rxd = Int32(config.rxd)
newSerialConfig.txd = Int32(config.txd)
newSerialConfig.baudRate = Int32(config.baud.rawValue)
newSerialConfig.timeout = Int32(config.timeout)
newSerialConfig.mode = Int32(config.mode.rawValue)
fetchedNode[0].serialConfig = newSerialConfig
} else {
fetchedNode[0].serialConfig?.enabled = config.enabled
fetchedNode[0].serialConfig?.echo = config.echo
fetchedNode[0].serialConfig?.rxd = Int32(config.rxd)
fetchedNode[0].serialConfig?.txd = Int32(config.txd)
fetchedNode[0].serialConfig?.baudRate = Int32(config.baud.rawValue)
fetchedNode[0].serialConfig?.timeout = Int32(config.timeout)
fetchedNode[0].serialConfig?.mode = Int32(config.mode.rawValue)
}
do {
try context.save()
print("💾 Updated Serial Module Config for node number: \(String(nodeNum))")
} catch {
context.rollback()
let nsError = error as NSError
print("💥 Error Updating Core Data SerialConfigEntity: \(nsError)")
}
} else {
print("💥 No Nodes found in local database matching node number \(nodeNum) unable to save Serial Module Config")
}
} catch {
let nsError = error as NSError
print("💥 Fetching node for core data SerialConfigEntity failed: \(nsError)")
}
}
func upsertTelemetryModuleConfigPacket(config: Meshtastic.ModuleConfig.TelemetryConfig, nodeNum: Int64, context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.telemetry.config %@", comment: "Telemetry module config received: %@"), String(nodeNum))
MeshLogger.log("📈 \(logString)")
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)
newTelemetryConfig.deviceUpdateInterval = Int32(config.deviceUpdateInterval)
newTelemetryConfig.environmentUpdateInterval = Int32(config.environmentUpdateInterval)
newTelemetryConfig.environmentMeasurementEnabled = config.environmentMeasurementEnabled
newTelemetryConfig.environmentScreenEnabled = config.environmentScreenEnabled
newTelemetryConfig.environmentDisplayFahrenheit = config.environmentDisplayFahrenheit
fetchedNode[0].telemetryConfig = newTelemetryConfig
} else {
fetchedNode[0].telemetryConfig?.deviceUpdateInterval = Int32(config.deviceUpdateInterval)
fetchedNode[0].telemetryConfig?.environmentUpdateInterval = Int32(config.environmentUpdateInterval)
fetchedNode[0].telemetryConfig?.environmentMeasurementEnabled = config.environmentMeasurementEnabled
fetchedNode[0].telemetryConfig?.environmentScreenEnabled = config.environmentScreenEnabled
fetchedNode[0].telemetryConfig?.environmentDisplayFahrenheit = config.environmentDisplayFahrenheit
}
do {
try context.save()
print("💾 Updated Telemetry Module Config for node number: \(String(nodeNum))")
} catch {
context.rollback()
let nsError = error as NSError
print("💥 Error Updating Core Data TelemetryConfigEntity: \(nsError)")
}
} else {
print("💥 No Nodes found in local database matching node number \(nodeNum) unable to save Telemetry Module Config")
}
} catch {
let nsError = error as NSError
print("💥 Fetching node for core data TelemetryConfigEntity failed: \(nsError)")
}
}

View file

@ -200,7 +200,7 @@ struct CannedMessagesConfig: View {
.disabled(configPreset > 0)
}
.scrollDismissesKeyboard(.immediately)
.disabled(bleManager.connectedPeripheral == nil)
.disabled(self.bleManager.connectedPeripheral == nil || node?.cannedMessageConfig == nil)
Button {
isPresentingSaveConfirm = true
@ -287,6 +287,15 @@ struct CannedMessagesConfig: View {
self.messages = node?.cannedMessageConfig?.messages ?? ""
self.hasChanges = false
self.hasMessagesChanges = false
// Need to request a CannedMessagesModuleConfig from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.cannedMessageConfig == nil {
print("empty canned messages module config")
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
if connectedNode.id > 0 {
_ = bleManager.requestCannedMessagesModuleConfig(fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
}
.onChange(of: configPreset) { newPreset in

View file

@ -138,7 +138,7 @@ struct ExternalNotificationConfig: View {
}
}
}
.disabled(bleManager.connectedPeripheral == nil)
.disabled(self.bleManager.connectedPeripheral == nil || node?.externalNotificationConfig == nil)
Button {
isPresentingSaveConfirm = true
} label: {
@ -154,7 +154,8 @@ struct ExternalNotificationConfig: View {
isPresented: $isPresentingSaveConfirm,
titleVisibility: .visible
) {
let nodeName = bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : NSLocalizedString("unknown", comment: "Unknown")
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
let nodeName = node?.user?.longName ?? NSLocalizedString("unknown", comment: "Unknown")
let buttonText = String.localizedStringWithFormat(NSLocalizedString("save.config %@", comment: "Save Config for %@"), nodeName)
Button(buttonText) {
var enc = ModuleConfig.ExternalNotificationConfig()
@ -171,7 +172,7 @@ struct ExternalNotificationConfig: View {
enc.outputVibra = UInt32(outputVibra)
enc.outputMs = UInt32(outputMilliseconds)
enc.usePwm = usePWM
let adminMessageId = bleManager.saveExternalNotificationModuleConfig(config: enc, fromUser: node!.user!, toUser: node!.user!)
let adminMessageId = bleManager.saveExternalNotificationModuleConfig(config: enc, fromUser: connectedNode.user!, toUser: node!.user!)
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
@ -205,6 +206,15 @@ struct ExternalNotificationConfig: View {
self.nagTimeout = Int(node?.externalNotificationConfig?.nagTimeout ?? 0)
self.usePWM = node?.externalNotificationConfig?.usePWM ?? false
self.hasChanges = false
// Need to request a TelemetryModuleConfig from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.externalNotificationConfig == nil {
print("empty external notification module config")
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
if connectedNode.id > 0 {
_ = bleManager.requestExternalNotificationModuleConfig(fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
}
.onChange(of: enabled) { newEnabled in
if node != nil && node!.externalNotificationConfig != nil {

View file

@ -126,7 +126,7 @@ struct MQTTConfig: View {
.font(.callout)
}
.scrollDismissesKeyboard(.interactively)
.disabled(!(node != nil))
.disabled(self.bleManager.connectedPeripheral == nil || node?.mqttConfig == nil)
Button {
isPresentingSaveConfirm = true
@ -143,7 +143,8 @@ struct MQTTConfig: View {
isPresented: $isPresentingSaveConfirm,
titleVisibility: .visible
) {
let nodeName = bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : NSLocalizedString("unknown", comment: "Unknown")
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
let nodeName = node?.user?.longName ?? NSLocalizedString("unknown", comment: "Unknown")
let buttonText = String.localizedStringWithFormat(NSLocalizedString("save.config %@", comment: "Save Config for %@"), nodeName)
Button(buttonText) {
var mqtt = ModuleConfig.MQTTConfig()
@ -153,7 +154,7 @@ struct MQTTConfig: View {
mqtt.password = self.password
mqtt.encryptionEnabled = self.encryptionEnabled
mqtt.jsonEnabled = self.jsonEnabled
let adminMessageId = bleManager.saveMQTTConfig(config: mqtt, fromUser: node!.user!, toUser: node!.user!)
let adminMessageId = bleManager.saveMQTTConfig(config: mqtt, fromUser: connectedNode.user!, toUser: node!.user!)
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
@ -179,6 +180,15 @@ struct MQTTConfig: View {
self.encryptionEnabled = (node?.mqttConfig?.encryptionEnabled ?? false)
self.jsonEnabled = (node?.mqttConfig?.jsonEnabled ?? false)
self.hasChanges = false
// Need to request a TelemetryModuleConfig from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.telemetryConfig == nil {
print("empty mqtt module config")
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
if connectedNode.id > 0 {
_ = bleManager.requestMqttModuleConfig(fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
}
.onChange(of: enabled) { newEnabled in
if node != nil && node?.mqttConfig != nil {

View file

@ -97,7 +97,7 @@ struct SerialConfig: View {
.font(.caption)
}
}
.disabled(node == nil)
.disabled(self.bleManager.connectedPeripheral == nil || node?.serialConfig == nil)
Button {
@ -118,9 +118,10 @@ struct SerialConfig: View {
isPresented: $isPresentingSaveConfirm,
titleVisibility: .visible
) {
let nodeName = bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : NSLocalizedString("unknown", comment: "Unknown")
let nodeName = node?.user?.longName ?? NSLocalizedString("unknown", comment: "Unknown")
let buttonText = String.localizedStringWithFormat(NSLocalizedString("save.config %@", comment: "Save Config for %@"), nodeName)
Button(buttonText) {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
var sc = ModuleConfig.SerialConfig()
sc.enabled = enabled
sc.echo = echo
@ -130,7 +131,7 @@ struct SerialConfig: View {
sc.timeout = UInt32(timeout)
sc.mode = SerialModeTypes(rawValue: mode)!.protoEnumValue()
let adminMessageId = bleManager.saveSerialModuleConfig(config: sc, fromUser: node!.user!, toUser: node!.user!)
let adminMessageId = bleManager.saveSerialModuleConfig(config: sc, fromUser: connectedNode.user!, toUser: node!.user!)
if adminMessageId > 0 {
// Should show a saved successfully alert once I know that to be true
@ -160,6 +161,15 @@ struct SerialConfig: View {
self.timeout = Int(node?.serialConfig?.timeout ?? 0)
self.mode = Int(node?.serialConfig?.mode ?? 0)
self.hasChanges = false
// Need to request a SerialModuleConfig from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.serialConfig == nil {
print("empty serial module config")
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
if connectedNode.id > 0 {
_ = bleManager.requestSerialModuleConfig(fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
}
}
.onChange(of: enabled) { newEnabled in

View file

@ -194,7 +194,6 @@ struct Settings: View {
Text("canned.messages")
}
.tag(SettingsSidebar.cannedMessagesConfig)
.disabled(selectedNode > 0 && selectedNode != connectedNodeNum)
NavigationLink {
ExternalNotificationConfig(node: nodes.first(where: { $0.num == selectedNode }))
@ -204,7 +203,6 @@ struct Settings: View {
Text("external.notification")
}
.tag(SettingsSidebar.externalNotificationConfig)
.disabled(selectedNode > 0 && selectedNode != connectedNodeNum)
NavigationLink {
MQTTConfig(node: nodes.first(where: { $0.num == selectedNode }))
@ -214,7 +212,6 @@ struct Settings: View {
Text("mqtt")
}
.tag(SettingsSidebar.mqttConfig)
.disabled(selectedNode > 0 && selectedNode != connectedNodeNum)
NavigationLink {
RangeTestConfig(node: nodes.first(where: { $0.num == selectedNode }))
@ -233,7 +230,6 @@ struct Settings: View {
Text("serial")
}
.tag(SettingsSidebar.serialConfig)
.disabled(selectedNode > 0 && selectedNode != connectedNodeNum)
NavigationLink {
TelemetryConfig(node: nodes.first(where: { $0.num == selectedNode }))