mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Merge pull request #301 from meshtastic/add_weatherkit
Hook up Admin Channel
This commit is contained in:
commit
6533234730
24 changed files with 1124 additions and 537 deletions
|
|
@ -14,8 +14,29 @@ enum DeviceRoles: Int, CaseIterable, Identifiable {
|
|||
case clientMute = 1
|
||||
case router = 2
|
||||
case routerClient = 3
|
||||
case repeater = 4
|
||||
case tracker = 5
|
||||
|
||||
var id: Int { self.rawValue }
|
||||
var name: String {
|
||||
get {
|
||||
switch self {
|
||||
|
||||
case .client:
|
||||
return "Client"
|
||||
case .clientMute:
|
||||
return "Muted Client"
|
||||
case .router:
|
||||
return "Router"
|
||||
case .routerClient:
|
||||
return "Router & Client"
|
||||
case .repeater:
|
||||
return "Repeater"
|
||||
case .tracker:
|
||||
return "Tracker"
|
||||
}
|
||||
}
|
||||
}
|
||||
var description: String {
|
||||
get {
|
||||
switch self {
|
||||
|
|
@ -28,6 +49,10 @@ enum DeviceRoles: Int, CaseIterable, Identifiable {
|
|||
return NSLocalizedString("device.role.router", comment: "Router - Mesh packets will prefer to be routed over this node. This node will not be used by client apps. The wifi/ble radios and the oled screen will be put to sleep.")
|
||||
case .routerClient:
|
||||
return NSLocalizedString("device.role.routerclient", comment: "Router Client - Mesh packets will prefer to be routed over this node. The Router Client can be used as both a Router and an app connected Client.")
|
||||
case .repeater:
|
||||
return "Mesh packets will simply be rebroadcasted over this node. Nodes configured with this role will not originate NodeInfo, Position, Telemetry or any other packet type. They will simply rebroadcast any mesh packets on the same frequency, channel num, spread factor, and coding rate."
|
||||
case .tracker:
|
||||
return "Position Mesh packets will be prioritized higher and sent more frequently by default."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -43,6 +68,10 @@ enum DeviceRoles: Int, CaseIterable, Identifiable {
|
|||
return Config.DeviceConfig.Role.router
|
||||
case .routerClient:
|
||||
return Config.DeviceConfig.Role.routerClient
|
||||
case .repeater:
|
||||
return Config.DeviceConfig.Role.repeater
|
||||
case .tracker:
|
||||
return Config.DeviceConfig.Role.tracker
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ enum RegionCodes : Int, CaseIterable, Identifiable {
|
|||
case `in` = 10
|
||||
case nz865 = 11
|
||||
case th = 12
|
||||
case ua433 = 14
|
||||
case ua868 = 15
|
||||
case lora24 = 13
|
||||
|
||||
var id: Int { self.rawValue }
|
||||
|
|
@ -54,6 +56,10 @@ enum RegionCodes : Int, CaseIterable, Identifiable {
|
|||
return "New Zealand 865mhz"
|
||||
case .th:
|
||||
return "Thailand"
|
||||
case .ua433:
|
||||
return "Ukraine 433mhz"
|
||||
case .ua868:
|
||||
return "Ukraine 868mhz"
|
||||
case .lora24:
|
||||
return "2.4 GHZ"
|
||||
}
|
||||
|
|
@ -90,6 +96,10 @@ enum RegionCodes : Int, CaseIterable, Identifiable {
|
|||
return Config.LoRaConfig.RegionCode.nz865
|
||||
case .th:
|
||||
return Config.LoRaConfig.RegionCode.th
|
||||
case .ua433:
|
||||
return Config.LoRaConfig.RegionCode.ua433
|
||||
case .ua868:
|
||||
return Config.LoRaConfig.RegionCode.ua868
|
||||
case .lora24:
|
||||
return Config.LoRaConfig.RegionCode.lora24
|
||||
}
|
||||
|
|
@ -100,6 +110,7 @@ enum ModemPresets : Int, CaseIterable, Identifiable {
|
|||
|
||||
case LongFast = 0
|
||||
case LongSlow = 1
|
||||
case LongModerate = 7
|
||||
case VLongSlow = 2
|
||||
case MedSlow = 3
|
||||
case MedFast = 4
|
||||
|
|
@ -115,6 +126,8 @@ enum ModemPresets : Int, CaseIterable, Identifiable {
|
|||
return "Long Range - Fast"
|
||||
case .LongSlow:
|
||||
return "Long Range - Slow"
|
||||
case .LongModerate:
|
||||
return "Long Range - Moderate"
|
||||
case .VLongSlow:
|
||||
return "Very Long Range - Slow"
|
||||
case .MedSlow:
|
||||
|
|
@ -136,10 +149,12 @@ enum ModemPresets : Int, CaseIterable, Identifiable {
|
|||
return Config.LoRaConfig.ModemPreset.longFast
|
||||
case .LongSlow:
|
||||
return Config.LoRaConfig.ModemPreset.longSlow
|
||||
case .LongModerate:
|
||||
return Config.LoRaConfig.ModemPreset.longModerate
|
||||
case .VLongSlow:
|
||||
return Config.LoRaConfig.ModemPreset.veryLongSlow
|
||||
return Config.LoRaConfig.ModemPreset.veryLongSlow
|
||||
case .MedSlow:
|
||||
return Config.LoRaConfig.ModemPreset.mediumSlow
|
||||
return Config.LoRaConfig.ModemPreset.mediumSlow
|
||||
case .MedFast:
|
||||
return Config.LoRaConfig.ModemPreset.mediumFast
|
||||
case .ShortSlow:
|
||||
|
|
|
|||
|
|
@ -1419,10 +1419,62 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
let messageDescription = "🛎️ Requested Bluetooth 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 requestDeviceConfig(fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Bool {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.getConfigRequest = AdminMessage.ConfigType.deviceConfig
|
||||
|
||||
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 Device 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 requestDisplayConfig(fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Bool {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.getConfigRequest = AdminMessage.ConfigType.displayConfig
|
||||
|
||||
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 Display Config on admin channel \(adminIndex) for node: \(String(connectedPeripheral.num))"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
@ -1455,6 +1507,214 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
return false
|
||||
}
|
||||
|
||||
public func requestNetworkConfig(fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Bool {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.getConfigRequest = AdminMessage.ConfigType.networkConfig
|
||||
|
||||
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 Network 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 requestPositionConfig(fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Bool {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.getConfigRequest = AdminMessage.ConfigType.positionConfig
|
||||
|
||||
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 Position 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 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()
|
||||
adminPacket.getModuleConfigRequest = AdminMessage.ModuleConfigType.rangetestConfig
|
||||
|
||||
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 Range Test 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 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()
|
||||
adminPacket.getModuleConfigRequest = AdminMessage.ModuleConfigType.telemetryConfig
|
||||
|
||||
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 Telemetry 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 saveExternalNotificationModuleConfig(config: ModuleConfig.ExternalNotificationConfig, fromUser: UserEntity, toUser: UserEntity) -> Int64 {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
|
|
@ -1499,12 +1759,9 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "Saved WiFi Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
|
||||
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,355 +40,34 @@ func localConfig (config: Config, context:NSManagedObjectContext, nodeNum: Int64
|
|||
|
||||
// We don't care about any of the Power settings, config is available for everything else
|
||||
if config.payloadVariant == Config.OneOf_PayloadVariant.bluetooth(config.bluetooth) {
|
||||
upsertBluetoothConfigPacket(config: config, nodeNum: nodeNum, context: context)
|
||||
upsertBluetoothConfigPacket(config: config.bluetooth, nodeNum: nodeNum, context: context)
|
||||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.device(config.device) {
|
||||
upsertDeviceConfigPacket(config: config, nodeNum: nodeNum, context: context)
|
||||
upsertDeviceConfigPacket(config: config.device, nodeNum: nodeNum, context: context)
|
||||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.display(config.display) {
|
||||
upsertDisplayConfigPacket(config: config, nodeNum: nodeNum, context: context)
|
||||
upsertDisplayConfigPacket(config: config.display, nodeNum: nodeNum, context: context)
|
||||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.lora(config.lora) {
|
||||
upsertLoRaConfigPacket(config: config, nodeNum: nodeNum, context: context)
|
||||
upsertLoRaConfigPacket(config: config.lora, nodeNum: nodeNum, context: context)
|
||||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.network(config.network) {
|
||||
upsertNetworkConfigPacket(config: config, nodeNum: nodeNum, context: context)
|
||||
upsertNetworkConfigPacket(config: config.network, nodeNum: nodeNum, context: context)
|
||||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.position(config.position) {
|
||||
upsertPositionConfigPacket(config: config, nodeNum: nodeNum, context: context)
|
||||
upsertPositionConfigPacket(config: config.position, nodeNum: nodeNum, context: context)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -759,8 +438,6 @@ func adminAppPacket (packet: MeshPacket, context: NSManagedObjectContext) {
|
|||
|
||||
if let adminMessage = try? AdminMessage(serializedData: packet.decoded.payload) {
|
||||
|
||||
|
||||
|
||||
if adminMessage.payloadVariant == AdminMessage.OneOf_PayloadVariant.getCannedMessageModuleMessagesResponse(adminMessage.getCannedMessageModuleMessagesResponse) {
|
||||
|
||||
if let cmmc = try? CannedMessageModuleConfig(serializedData: packet.decoded.payload) {
|
||||
|
|
@ -802,25 +479,49 @@ 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) {
|
||||
if let config = try? Config(serializedData: packet.decoded.payload) {
|
||||
|
||||
let config = adminMessage.getConfigResponse
|
||||
|
||||
if config.payloadVariant == Config.OneOf_PayloadVariant.bluetooth(config.bluetooth) {
|
||||
upsertBluetoothConfigPacket(config: config.bluetooth, nodeNum: Int64(packet.from), context: context)
|
||||
|
||||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.device(config.device) {
|
||||
upsertDeviceConfigPacket(config: config.device, nodeNum: Int64(packet.from), context: context)
|
||||
|
||||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.lora(config.lora) {
|
||||
upsertLoRaConfigPacket(config: config.lora, nodeNum: Int64(packet.from), context: context)
|
||||
|
||||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.network(config.network) {
|
||||
upsertNetworkConfigPacket(config: config.network, nodeNum: Int64(packet.from), context: context)
|
||||
|
||||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.position(config.position) {
|
||||
upsertPositionConfigPacket(config: config.position, nodeNum: Int64(packet.from), context: context)
|
||||
|
||||
if config.payloadVariant == Config.OneOf_PayloadVariant.bluetooth(config.bluetooth) {
|
||||
upsertBluetoothConfigPacket(config: config, nodeNum: Int64(packet.from), context: context)
|
||||
|
||||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.device(config.device) {
|
||||
upsertDeviceConfigPacket(config: config, nodeNum: Int64(packet.from), context: context)
|
||||
|
||||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.lora(config.lora) {
|
||||
upsertLoRaConfigPacket(config: config, nodeNum: Int64(packet.from), context: context)
|
||||
|
||||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.network(config.network) {
|
||||
upsertNetworkConfigPacket(config: config, nodeNum: Int64(packet.from), context: context)
|
||||
|
||||
} else if config.payloadVariant == Config.OneOf_PayloadVariant.position(config.position) {
|
||||
upsertPositionConfigPacket(config: config, 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())")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,38 @@
|
|||
|
||||
import CoreData
|
||||
|
||||
public func getNodeInfo(id: Int64, context: NSManagedObjectContext) -> NodeInfoEntity {
|
||||
|
||||
let fetchNodeInfoRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "NodeInfoEntity")
|
||||
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(id))
|
||||
|
||||
do {
|
||||
let fetchNodeInfo = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
|
||||
if fetchNodeInfo.count == 1 {
|
||||
return fetchNodeInfo[0]
|
||||
}
|
||||
} catch {
|
||||
return NodeInfoEntity(context: context)
|
||||
}
|
||||
return NodeInfoEntity(context: context)
|
||||
}
|
||||
|
||||
public func getUser(id: Int64, context: NSManagedObjectContext) -> UserEntity {
|
||||
|
||||
let fetchUserRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "UserEntity")
|
||||
fetchUserRequest.predicate = NSPredicate(format: "num == %lld", Int64(id))
|
||||
|
||||
do {
|
||||
let fetchedUser = try context.fetch(fetchUserRequest) as! [UserEntity]
|
||||
if fetchedUser.count == 1 {
|
||||
return fetchedUser[0]
|
||||
}
|
||||
} catch {
|
||||
return UserEntity(context: context)
|
||||
}
|
||||
return UserEntity(context: context)
|
||||
}
|
||||
|
||||
public func getWaypoint(id: Int64, context: NSManagedObjectContext) -> WaypointEntity {
|
||||
|
||||
let fetchWaypointRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "WaypointEntity")
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -159,7 +159,7 @@ func upsertPositionPacket (packet: MeshPacket, context: NSManagedObjectContext)
|
|||
}
|
||||
}
|
||||
|
||||
func upsertBluetoothConfigPacket(config: Config, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertBluetoothConfigPacket(config: Meshtastic.Config.BluetoothConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.bluetooth.config %@", comment: "Bluetooth config received: %@"), String(nodeNum))
|
||||
MeshLogger.log("📶 \(logString)")
|
||||
|
|
@ -174,14 +174,14 @@ func upsertBluetoothConfigPacket(config: Config, nodeNum: Int64, context: NSMana
|
|||
if !fetchedNode.isEmpty {
|
||||
if fetchedNode[0].bluetoothConfig == nil {
|
||||
let newBluetoothConfig = BluetoothConfigEntity(context: context)
|
||||
newBluetoothConfig.enabled = config.bluetooth.enabled
|
||||
newBluetoothConfig.mode = Int32(config.bluetooth.mode.rawValue)
|
||||
newBluetoothConfig.fixedPin = Int32(config.bluetooth.fixedPin)
|
||||
newBluetoothConfig.enabled = config.enabled
|
||||
newBluetoothConfig.mode = Int32(config.mode.rawValue)
|
||||
newBluetoothConfig.fixedPin = Int32(config.fixedPin)
|
||||
fetchedNode[0].bluetoothConfig = newBluetoothConfig
|
||||
} else {
|
||||
fetchedNode[0].bluetoothConfig?.enabled = config.bluetooth.enabled
|
||||
fetchedNode[0].bluetoothConfig?.mode = Int32(config.bluetooth.mode.rawValue)
|
||||
fetchedNode[0].bluetoothConfig?.fixedPin = Int32(config.bluetooth.fixedPin)
|
||||
fetchedNode[0].bluetoothConfig?.enabled = config.enabled
|
||||
fetchedNode[0].bluetoothConfig?.mode = Int32(config.mode.rawValue)
|
||||
fetchedNode[0].bluetoothConfig?.fixedPin = Int32(config.fixedPin)
|
||||
}
|
||||
do {
|
||||
try context.save()
|
||||
|
|
@ -200,7 +200,7 @@ func upsertBluetoothConfigPacket(config: Config, nodeNum: Int64, context: NSMana
|
|||
}
|
||||
}
|
||||
|
||||
func upsertDeviceConfigPacket(config: Config, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertDeviceConfigPacket(config: Meshtastic.Config.DeviceConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.device.config %@", comment: "Device config received: %@"), String(nodeNum))
|
||||
MeshLogger.log("📟 \(logString)")
|
||||
|
|
@ -214,18 +214,18 @@ func upsertDeviceConfigPacket(config: Config, nodeNum: Int64, context: NSManaged
|
|||
if !fetchedNode.isEmpty {
|
||||
if fetchedNode[0].deviceConfig == nil {
|
||||
let newDeviceConfig = DeviceConfigEntity(context: context)
|
||||
newDeviceConfig.role = Int32(config.device.role.rawValue)
|
||||
newDeviceConfig.serialEnabled = config.device.serialEnabled
|
||||
newDeviceConfig.debugLogEnabled = config.device.debugLogEnabled
|
||||
newDeviceConfig.buttonGpio = Int32(config.device.buttonGpio)
|
||||
newDeviceConfig.buzzerGpio = Int32(config.device.buzzerGpio)
|
||||
newDeviceConfig.role = Int32(config.role.rawValue)
|
||||
newDeviceConfig.serialEnabled = config.serialEnabled
|
||||
newDeviceConfig.debugLogEnabled = config.debugLogEnabled
|
||||
newDeviceConfig.buttonGpio = Int32(config.buttonGpio)
|
||||
newDeviceConfig.buzzerGpio = Int32(config.buzzerGpio)
|
||||
fetchedNode[0].deviceConfig = newDeviceConfig
|
||||
} else {
|
||||
fetchedNode[0].deviceConfig?.role = Int32(config.device.role.rawValue)
|
||||
fetchedNode[0].deviceConfig?.serialEnabled = config.device.serialEnabled
|
||||
fetchedNode[0].deviceConfig?.debugLogEnabled = config.device.debugLogEnabled
|
||||
fetchedNode[0].deviceConfig?.buttonGpio = Int32(config.device.buttonGpio)
|
||||
fetchedNode[0].deviceConfig?.buzzerGpio = Int32(config.device.buzzerGpio)
|
||||
fetchedNode[0].deviceConfig?.role = Int32(config.role.rawValue)
|
||||
fetchedNode[0].deviceConfig?.serialEnabled = config.serialEnabled
|
||||
fetchedNode[0].deviceConfig?.debugLogEnabled = config.debugLogEnabled
|
||||
fetchedNode[0].deviceConfig?.buttonGpio = Int32(config.buttonGpio)
|
||||
fetchedNode[0].deviceConfig?.buzzerGpio = Int32(config.buzzerGpio)
|
||||
}
|
||||
do {
|
||||
try context.save()
|
||||
|
|
@ -242,7 +242,7 @@ func upsertDeviceConfigPacket(config: Config, nodeNum: Int64, context: NSManaged
|
|||
}
|
||||
}
|
||||
|
||||
func upsertDisplayConfigPacket(config: Config, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertDisplayConfigPacket(config: Meshtastic.Config.DisplayConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.display.config %@", comment: "Display config received: %@"), String(nodeNum))
|
||||
MeshLogger.log("🖥️ \(logString)")
|
||||
|
|
@ -260,24 +260,24 @@ func upsertDisplayConfigPacket(config: Config, nodeNum: Int64, context: NSManage
|
|||
if fetchedNode[0].displayConfig == nil {
|
||||
|
||||
let newDisplayConfig = DisplayConfigEntity(context: context)
|
||||
newDisplayConfig.gpsFormat = Int32(config.display.gpsFormat.rawValue)
|
||||
newDisplayConfig.screenOnSeconds = Int32(config.display.screenOnSecs)
|
||||
newDisplayConfig.screenCarouselInterval = Int32(config.display.autoScreenCarouselSecs)
|
||||
newDisplayConfig.compassNorthTop = config.display.compassNorthTop
|
||||
newDisplayConfig.flipScreen = config.display.flipScreen
|
||||
newDisplayConfig.oledType = Int32(config.display.oled.rawValue)
|
||||
newDisplayConfig.displayMode = Int32(config.display.displaymode.rawValue)
|
||||
newDisplayConfig.gpsFormat = Int32(config.gpsFormat.rawValue)
|
||||
newDisplayConfig.screenOnSeconds = Int32(config.screenOnSecs)
|
||||
newDisplayConfig.screenCarouselInterval = Int32(config.autoScreenCarouselSecs)
|
||||
newDisplayConfig.compassNorthTop = config.compassNorthTop
|
||||
newDisplayConfig.flipScreen = config.flipScreen
|
||||
newDisplayConfig.oledType = Int32(config.oled.rawValue)
|
||||
newDisplayConfig.displayMode = Int32(config.displaymode.rawValue)
|
||||
fetchedNode[0].displayConfig = newDisplayConfig
|
||||
|
||||
} else {
|
||||
|
||||
fetchedNode[0].displayConfig?.gpsFormat = Int32(config.display.gpsFormat.rawValue)
|
||||
fetchedNode[0].displayConfig?.screenOnSeconds = Int32(config.display.screenOnSecs)
|
||||
fetchedNode[0].displayConfig?.screenCarouselInterval = Int32(config.display.autoScreenCarouselSecs)
|
||||
fetchedNode[0].displayConfig?.compassNorthTop = config.display.compassNorthTop
|
||||
fetchedNode[0].displayConfig?.flipScreen = config.display.flipScreen
|
||||
fetchedNode[0].displayConfig?.oledType = Int32(config.display.oled.rawValue)
|
||||
fetchedNode[0].displayConfig?.displayMode = Int32(config.display.displaymode.rawValue)
|
||||
fetchedNode[0].displayConfig?.gpsFormat = Int32(config.gpsFormat.rawValue)
|
||||
fetchedNode[0].displayConfig?.screenOnSeconds = Int32(config.screenOnSecs)
|
||||
fetchedNode[0].displayConfig?.screenCarouselInterval = Int32(config.autoScreenCarouselSecs)
|
||||
fetchedNode[0].displayConfig?.compassNorthTop = config.compassNorthTop
|
||||
fetchedNode[0].displayConfig?.flipScreen = config.flipScreen
|
||||
fetchedNode[0].displayConfig?.oledType = Int32(config.oled.rawValue)
|
||||
fetchedNode[0].displayConfig?.displayMode = Int32(config.displaymode.rawValue)
|
||||
}
|
||||
|
||||
do {
|
||||
|
|
@ -304,7 +304,7 @@ func upsertDisplayConfigPacket(config: Config, nodeNum: Int64, context: NSManage
|
|||
}
|
||||
}
|
||||
|
||||
func upsertLoRaConfigPacket(config: Config, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertLoRaConfigPacket(config: Meshtastic.Config.LoRaConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.lora.config %@", comment: "LoRa config received: %@"), String(nodeNum))
|
||||
MeshLogger.log("📻 \(logString)")
|
||||
|
|
@ -320,33 +320,34 @@ func upsertLoRaConfigPacket(config: Config, nodeNum: Int64, context: NSManagedOb
|
|||
if fetchedNode[0].loRaConfig == nil {
|
||||
// No lora config for node, save a new lora config
|
||||
let newLoRaConfig = LoRaConfigEntity(context: context)
|
||||
newLoRaConfig.regionCode = Int32(config.lora.region.rawValue)
|
||||
newLoRaConfig.usePreset = config.lora.usePreset
|
||||
newLoRaConfig.modemPreset = Int32(config.lora.modemPreset.rawValue)
|
||||
newLoRaConfig.bandwidth = Int32(config.lora.bandwidth)
|
||||
newLoRaConfig.spreadFactor = Int32(config.lora.spreadFactor)
|
||||
newLoRaConfig.codingRate = Int32(config.lora.codingRate)
|
||||
newLoRaConfig.frequencyOffset = config.lora.frequencyOffset
|
||||
newLoRaConfig.hopLimit = Int32(config.lora.hopLimit)
|
||||
newLoRaConfig.txPower = Int32(config.lora.txPower)
|
||||
newLoRaConfig.txEnabled = config.lora.txEnabled
|
||||
newLoRaConfig.channelNum = Int32(config.lora.channelNum)
|
||||
newLoRaConfig.regionCode = Int32(config.region.rawValue)
|
||||
newLoRaConfig.usePreset = config.usePreset
|
||||
newLoRaConfig.modemPreset = Int32(config.modemPreset.rawValue)
|
||||
newLoRaConfig.bandwidth = Int32(config.bandwidth)
|
||||
newLoRaConfig.spreadFactor = Int32(config.spreadFactor)
|
||||
newLoRaConfig.codingRate = Int32(config.codingRate)
|
||||
newLoRaConfig.frequencyOffset = config.frequencyOffset
|
||||
newLoRaConfig.hopLimit = Int32(config.hopLimit)
|
||||
newLoRaConfig.txPower = Int32(config.txPower)
|
||||
newLoRaConfig.txEnabled = config.txEnabled
|
||||
newLoRaConfig.channelNum = Int32(config.channelNum)
|
||||
fetchedNode[0].loRaConfig = newLoRaConfig
|
||||
} else {
|
||||
fetchedNode[0].loRaConfig?.regionCode = Int32(config.lora.region.rawValue)
|
||||
fetchedNode[0].loRaConfig?.usePreset = config.lora.usePreset
|
||||
fetchedNode[0].loRaConfig?.modemPreset = Int32(config.lora.modemPreset.rawValue)
|
||||
fetchedNode[0].loRaConfig?.bandwidth = Int32(config.lora.bandwidth)
|
||||
fetchedNode[0].loRaConfig?.spreadFactor = Int32(config.lora.spreadFactor)
|
||||
fetchedNode[0].loRaConfig?.codingRate = Int32(config.lora.codingRate)
|
||||
fetchedNode[0].loRaConfig?.frequencyOffset = config.lora.frequencyOffset
|
||||
fetchedNode[0].loRaConfig?.hopLimit = Int32(config.lora.hopLimit)
|
||||
fetchedNode[0].loRaConfig?.txPower = Int32(config.lora.txPower)
|
||||
fetchedNode[0].loRaConfig?.txEnabled = config.lora.txEnabled
|
||||
fetchedNode[0].loRaConfig?.channelNum = Int32(config.lora.channelNum)
|
||||
fetchedNode[0].loRaConfig?.regionCode = Int32(config.region.rawValue)
|
||||
fetchedNode[0].loRaConfig?.usePreset = config.usePreset
|
||||
fetchedNode[0].loRaConfig?.modemPreset = Int32(config.modemPreset.rawValue)
|
||||
fetchedNode[0].loRaConfig?.bandwidth = Int32(config.bandwidth)
|
||||
fetchedNode[0].loRaConfig?.spreadFactor = Int32(config.spreadFactor)
|
||||
fetchedNode[0].loRaConfig?.codingRate = Int32(config.codingRate)
|
||||
fetchedNode[0].loRaConfig?.frequencyOffset = config.frequencyOffset
|
||||
fetchedNode[0].loRaConfig?.hopLimit = Int32(config.hopLimit)
|
||||
fetchedNode[0].loRaConfig?.txPower = Int32(config.txPower)
|
||||
fetchedNode[0].loRaConfig?.txEnabled = config.txEnabled
|
||||
fetchedNode[0].loRaConfig?.channelNum = Int32(config.channelNum)
|
||||
}
|
||||
do {
|
||||
try context.save()
|
||||
context.refresh(fetchedNode[0], mergeChanges: true)
|
||||
print("💾 Updated LoRa Config for node number: \(String(nodeNum))")
|
||||
} catch {
|
||||
context.rollback()
|
||||
|
|
@ -362,7 +363,7 @@ func upsertLoRaConfigPacket(config: Config, nodeNum: Int64, context: NSManagedOb
|
|||
}
|
||||
}
|
||||
|
||||
func upsertNetworkConfigPacket(config: Config, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertNetworkConfigPacket(config: Meshtastic.Config.NetworkConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.network.config %@", comment: "Network config received: %@"), String(nodeNum))
|
||||
MeshLogger.log("🌐 \(logString)")
|
||||
|
|
@ -377,12 +378,16 @@ func upsertNetworkConfigPacket(config: Config, nodeNum: Int64, context: NSManage
|
|||
if !fetchedNode.isEmpty {
|
||||
if fetchedNode[0].networkConfig == nil {
|
||||
let newNetworkConfig = NetworkConfigEntity(context: context)
|
||||
newNetworkConfig.wifiSsid = config.network.wifiSsid
|
||||
newNetworkConfig.wifiPsk = config.network.wifiPsk
|
||||
newNetworkConfig.wifiEnabled = config.wifiEnabled
|
||||
newNetworkConfig.wifiSsid = config.wifiSsid
|
||||
newNetworkConfig.wifiPsk = config.wifiPsk
|
||||
newNetworkConfig.ethEnabled = config.ethEnabled
|
||||
fetchedNode[0].networkConfig = newNetworkConfig
|
||||
} else {
|
||||
fetchedNode[0].networkConfig?.wifiSsid = config.network.wifiSsid
|
||||
fetchedNode[0].networkConfig?.wifiPsk = config.network.wifiPsk
|
||||
fetchedNode[0].networkConfig?.ethEnabled = config.ethEnabled
|
||||
fetchedNode[0].networkConfig?.wifiEnabled = config.wifiEnabled
|
||||
fetchedNode[0].networkConfig?.wifiSsid = config.wifiSsid
|
||||
fetchedNode[0].networkConfig?.wifiPsk = config.wifiPsk
|
||||
}
|
||||
|
||||
do {
|
||||
|
|
@ -403,7 +408,7 @@ func upsertNetworkConfigPacket(config: Config, nodeNum: Int64, context: NSManage
|
|||
}
|
||||
}
|
||||
|
||||
func upsertPositionConfigPacket(config: Config, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
func upsertPositionConfigPacket(config: Meshtastic.Config.PositionConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.position.config %@", comment: "Positon config received: %@"), String(nodeNum))
|
||||
MeshLogger.log("🗺️ \(logString)")
|
||||
|
|
@ -418,22 +423,22 @@ func upsertPositionConfigPacket(config: Config, nodeNum: Int64, context: NSManag
|
|||
if !fetchedNode.isEmpty {
|
||||
if fetchedNode[0].positionConfig == nil {
|
||||
let newPositionConfig = PositionConfigEntity(context: context)
|
||||
newPositionConfig.smartPositionEnabled = config.position.positionBroadcastSmartEnabled
|
||||
newPositionConfig.deviceGpsEnabled = config.position.gpsEnabled
|
||||
newPositionConfig.fixedPosition = config.position.fixedPosition
|
||||
newPositionConfig.gpsUpdateInterval = Int32(config.position.gpsUpdateInterval)
|
||||
newPositionConfig.gpsAttemptTime = Int32(config.position.gpsAttemptTime)
|
||||
newPositionConfig.positionBroadcastSeconds = Int32(config.position.positionBroadcastSecs)
|
||||
newPositionConfig.positionFlags = Int32(config.position.positionFlags)
|
||||
newPositionConfig.smartPositionEnabled = config.positionBroadcastSmartEnabled
|
||||
newPositionConfig.deviceGpsEnabled = config.gpsEnabled
|
||||
newPositionConfig.fixedPosition = config.fixedPosition
|
||||
newPositionConfig.gpsUpdateInterval = Int32(config.gpsUpdateInterval)
|
||||
newPositionConfig.gpsAttemptTime = Int32(config.gpsAttemptTime)
|
||||
newPositionConfig.positionBroadcastSeconds = Int32(config.positionBroadcastSecs)
|
||||
newPositionConfig.positionFlags = Int32(config.positionFlags)
|
||||
fetchedNode[0].positionConfig = newPositionConfig
|
||||
} else {
|
||||
fetchedNode[0].positionConfig?.smartPositionEnabled = config.position.positionBroadcastSmartEnabled
|
||||
fetchedNode[0].positionConfig?.deviceGpsEnabled = config.position.gpsEnabled
|
||||
fetchedNode[0].positionConfig?.fixedPosition = config.position.fixedPosition
|
||||
fetchedNode[0].positionConfig?.gpsUpdateInterval = Int32(config.position.gpsUpdateInterval)
|
||||
fetchedNode[0].positionConfig?.gpsAttemptTime = Int32(config.position.gpsAttemptTime)
|
||||
fetchedNode[0].positionConfig?.positionBroadcastSeconds = Int32(config.position.positionBroadcastSecs)
|
||||
fetchedNode[0].positionConfig?.positionFlags = Int32(config.position.positionFlags)
|
||||
fetchedNode[0].positionConfig?.smartPositionEnabled = config.positionBroadcastSmartEnabled
|
||||
fetchedNode[0].positionConfig?.deviceGpsEnabled = config.gpsEnabled
|
||||
fetchedNode[0].positionConfig?.fixedPosition = config.fixedPosition
|
||||
fetchedNode[0].positionConfig?.gpsUpdateInterval = Int32(config.gpsUpdateInterval)
|
||||
fetchedNode[0].positionConfig?.gpsAttemptTime = Int32(config.gpsAttemptTime)
|
||||
fetchedNode[0].positionConfig?.positionBroadcastSeconds = Int32(config.positionBroadcastSecs)
|
||||
fetchedNode[0].positionConfig?.positionFlags = Int32(config.positionFlags)
|
||||
}
|
||||
do {
|
||||
try context.save()
|
||||
|
|
@ -451,3 +456,337 @@ func upsertPositionConfigPacket(config: Config, nodeNum: Int64, context: NSManag
|
|||
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)")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -168,6 +168,10 @@ struct Config {
|
|||
/// Defaults to PIN_BUZZER if defined.
|
||||
var buzzerGpio: UInt32 = 0
|
||||
|
||||
///
|
||||
/// Sets the role of node
|
||||
var rebroadcastMode: Config.DeviceConfig.RebroadcastMode = .all
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
///
|
||||
|
|
@ -198,13 +202,13 @@ struct Config {
|
|||
|
||||
///
|
||||
/// Repeater device role
|
||||
/// Mesh packets will simply be rebroadcasted over this node. Nodes under this role node will not originate NodeInfo, Position, Telemetry
|
||||
/// or any other packet type. They will simply rebroadcast any mesh packets on the same frequency, channel num, spread factory, and coding rate.
|
||||
/// Mesh packets will simply be rebroadcasted over this node. Nodes configured with this role will not originate NodeInfo, Position, Telemetry
|
||||
/// or any other packet type. They will simply rebroadcast any mesh packets on the same frequency, channel num, spread factor, and coding rate.
|
||||
case repeater // = 4
|
||||
|
||||
///
|
||||
/// Tracker device role
|
||||
/// Position Mesh packets for will be higher priority and sent more frequently by default.
|
||||
/// Position Mesh packets will be prioritized higher and sent more frequently by default.
|
||||
case tracker // = 5
|
||||
case UNRECOGNIZED(Int)
|
||||
|
||||
|
|
@ -238,6 +242,51 @@ struct Config {
|
|||
|
||||
}
|
||||
|
||||
///
|
||||
/// Defines the device's behavior for how messages are rebroadcast
|
||||
enum RebroadcastMode: SwiftProtobuf.Enum {
|
||||
typealias RawValue = Int
|
||||
|
||||
///
|
||||
/// Default behavior.
|
||||
/// Rebroadcast any observed message, if it was on our private channel or from another mesh with the same lora params.
|
||||
case all // = 0
|
||||
|
||||
///
|
||||
/// Same as behavior as ALL but skips packet decoding and simply rebroadcasts them.
|
||||
/// Only available in Repeater role. Setting this on any other roles will result in ALL behavior.
|
||||
case allSkipDecoding // = 1
|
||||
|
||||
///
|
||||
/// Ignores observed messages from foreign meshes that are open or those which it cannot decrypt.
|
||||
/// Only rebroadcasts message on the nodes local primary / secondary channels.
|
||||
case localOnly // = 2
|
||||
case UNRECOGNIZED(Int)
|
||||
|
||||
init() {
|
||||
self = .all
|
||||
}
|
||||
|
||||
init?(rawValue: Int) {
|
||||
switch rawValue {
|
||||
case 0: self = .all
|
||||
case 1: self = .allSkipDecoding
|
||||
case 2: self = .localOnly
|
||||
default: self = .UNRECOGNIZED(rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
var rawValue: Int {
|
||||
switch self {
|
||||
case .all: return 0
|
||||
case .allSkipDecoding: return 1
|
||||
case .localOnly: return 2
|
||||
case .UNRECOGNIZED(let i): return i
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
init() {}
|
||||
}
|
||||
|
||||
|
|
@ -905,6 +954,14 @@ struct Config {
|
|||
/// If true, sets RX boosted gain mode on SX126X based radios
|
||||
var sx126XRxBoostedGain: Bool = false
|
||||
|
||||
///
|
||||
/// This parameter is for advanced users and licensed HAM radio operators.
|
||||
/// Ignore Channel Calculation and use this frequency instead. The frequency_offset
|
||||
/// will still be applied. This will allow you to use out-of-band frequencies.
|
||||
/// Please respect your local laws and regulations. If you are a HAM, make sure you
|
||||
/// enable HAM mode and turn off encryption.
|
||||
var overrideFrequency: Float = 0
|
||||
|
||||
///
|
||||
/// For testing it is useful sometimes to force a node to never listen to
|
||||
/// particular other nodes (simulating radio out of range). All nodenums listed
|
||||
|
|
@ -1186,6 +1243,15 @@ extension Config.DeviceConfig.Role: CaseIterable {
|
|||
]
|
||||
}
|
||||
|
||||
extension Config.DeviceConfig.RebroadcastMode: CaseIterable {
|
||||
// The compiler won't synthesize support with the UNRECOGNIZED case.
|
||||
static var allCases: [Config.DeviceConfig.RebroadcastMode] = [
|
||||
.all,
|
||||
.allSkipDecoding,
|
||||
.localOnly,
|
||||
]
|
||||
}
|
||||
|
||||
extension Config.PositionConfig.PositionFlags: CaseIterable {
|
||||
// The compiler won't synthesize support with the UNRECOGNIZED case.
|
||||
static var allCases: [Config.PositionConfig.PositionFlags] = [
|
||||
|
|
@ -1303,6 +1369,7 @@ extension Config: @unchecked Sendable {}
|
|||
extension Config.OneOf_PayloadVariant: @unchecked Sendable {}
|
||||
extension Config.DeviceConfig: @unchecked Sendable {}
|
||||
extension Config.DeviceConfig.Role: @unchecked Sendable {}
|
||||
extension Config.DeviceConfig.RebroadcastMode: @unchecked Sendable {}
|
||||
extension Config.PositionConfig: @unchecked Sendable {}
|
||||
extension Config.PositionConfig.PositionFlags: @unchecked Sendable {}
|
||||
extension Config.PowerConfig: @unchecked Sendable {}
|
||||
|
|
@ -1491,6 +1558,7 @@ extension Config.DeviceConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImpl
|
|||
3: .standard(proto: "debug_log_enabled"),
|
||||
4: .standard(proto: "button_gpio"),
|
||||
5: .standard(proto: "buzzer_gpio"),
|
||||
6: .standard(proto: "rebroadcast_mode"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
|
|
@ -1504,6 +1572,7 @@ extension Config.DeviceConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImpl
|
|||
case 3: try { try decoder.decodeSingularBoolField(value: &self.debugLogEnabled) }()
|
||||
case 4: try { try decoder.decodeSingularUInt32Field(value: &self.buttonGpio) }()
|
||||
case 5: try { try decoder.decodeSingularUInt32Field(value: &self.buzzerGpio) }()
|
||||
case 6: try { try decoder.decodeSingularEnumField(value: &self.rebroadcastMode) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
|
@ -1525,6 +1594,9 @@ extension Config.DeviceConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImpl
|
|||
if self.buzzerGpio != 0 {
|
||||
try visitor.visitSingularUInt32Field(value: self.buzzerGpio, fieldNumber: 5)
|
||||
}
|
||||
if self.rebroadcastMode != .all {
|
||||
try visitor.visitSingularEnumField(value: self.rebroadcastMode, fieldNumber: 6)
|
||||
}
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
|
|
@ -1534,6 +1606,7 @@ extension Config.DeviceConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImpl
|
|||
if lhs.debugLogEnabled != rhs.debugLogEnabled {return false}
|
||||
if lhs.buttonGpio != rhs.buttonGpio {return false}
|
||||
if lhs.buzzerGpio != rhs.buzzerGpio {return false}
|
||||
if lhs.rebroadcastMode != rhs.rebroadcastMode {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
|
|
@ -1550,6 +1623,14 @@ extension Config.DeviceConfig.Role: SwiftProtobuf._ProtoNameProviding {
|
|||
]
|
||||
}
|
||||
|
||||
extension Config.DeviceConfig.RebroadcastMode: SwiftProtobuf._ProtoNameProviding {
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
0: .same(proto: "ALL"),
|
||||
1: .same(proto: "ALL_SKIP_DECODING"),
|
||||
2: .same(proto: "LOCAL_ONLY"),
|
||||
]
|
||||
}
|
||||
|
||||
extension Config.PositionConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = Config.protoMessageName + ".PositionConfig"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
|
|
@ -1987,6 +2068,7 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem
|
|||
11: .standard(proto: "channel_num"),
|
||||
12: .standard(proto: "override_duty_cycle"),
|
||||
13: .standard(proto: "sx126x_rx_boosted_gain"),
|
||||
14: .standard(proto: "override_frequency"),
|
||||
103: .standard(proto: "ignore_incoming"),
|
||||
]
|
||||
|
||||
|
|
@ -2009,6 +2091,7 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem
|
|||
case 11: try { try decoder.decodeSingularUInt32Field(value: &self.channelNum) }()
|
||||
case 12: try { try decoder.decodeSingularBoolField(value: &self.overrideDutyCycle) }()
|
||||
case 13: try { try decoder.decodeSingularBoolField(value: &self.sx126XRxBoostedGain) }()
|
||||
case 14: try { try decoder.decodeSingularFloatField(value: &self.overrideFrequency) }()
|
||||
case 103: try { try decoder.decodeRepeatedUInt32Field(value: &self.ignoreIncoming) }()
|
||||
default: break
|
||||
}
|
||||
|
|
@ -2055,6 +2138,9 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem
|
|||
if self.sx126XRxBoostedGain != false {
|
||||
try visitor.visitSingularBoolField(value: self.sx126XRxBoostedGain, fieldNumber: 13)
|
||||
}
|
||||
if self.overrideFrequency != 0 {
|
||||
try visitor.visitSingularFloatField(value: self.overrideFrequency, fieldNumber: 14)
|
||||
}
|
||||
if !self.ignoreIncoming.isEmpty {
|
||||
try visitor.visitPackedUInt32Field(value: self.ignoreIncoming, fieldNumber: 103)
|
||||
}
|
||||
|
|
@ -2075,6 +2161,7 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem
|
|||
if lhs.channelNum != rhs.channelNum {return false}
|
||||
if lhs.overrideDutyCycle != rhs.overrideDutyCycle {return false}
|
||||
if lhs.sx126XRxBoostedGain != rhs.sx126XRxBoostedGain {return false}
|
||||
if lhs.overrideFrequency != rhs.overrideFrequency {return false}
|
||||
if lhs.ignoreIncoming != rhs.ignoreIncoming {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
|
|
|
|||
|
|
@ -220,9 +220,34 @@ struct OEMStore {
|
|||
/// The default device encryption key, 16 or 32 byte
|
||||
var oemAesKey: Data = Data()
|
||||
|
||||
///
|
||||
/// A Preset LocalConfig to apply during factory reset
|
||||
var oemLocalConfig: LocalConfig {
|
||||
get {return _oemLocalConfig ?? LocalConfig()}
|
||||
set {_oemLocalConfig = newValue}
|
||||
}
|
||||
/// Returns true if `oemLocalConfig` has been explicitly set.
|
||||
var hasOemLocalConfig: Bool {return self._oemLocalConfig != nil}
|
||||
/// Clears the value of `oemLocalConfig`. Subsequent reads from it will return its default value.
|
||||
mutating func clearOemLocalConfig() {self._oemLocalConfig = nil}
|
||||
|
||||
///
|
||||
/// A Preset LocalModuleConfig to apply during factory reset
|
||||
var oemLocalModuleConfig: LocalModuleConfig {
|
||||
get {return _oemLocalModuleConfig ?? LocalModuleConfig()}
|
||||
set {_oemLocalModuleConfig = newValue}
|
||||
}
|
||||
/// Returns true if `oemLocalModuleConfig` has been explicitly set.
|
||||
var hasOemLocalModuleConfig: Bool {return self._oemLocalModuleConfig != nil}
|
||||
/// Clears the value of `oemLocalModuleConfig`. Subsequent reads from it will return its default value.
|
||||
mutating func clearOemLocalModuleConfig() {self._oemLocalModuleConfig = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _oemLocalConfig: LocalConfig? = nil
|
||||
fileprivate var _oemLocalModuleConfig: LocalModuleConfig? = nil
|
||||
}
|
||||
|
||||
#if swift(>=5.5) && canImport(_Concurrency)
|
||||
|
|
@ -413,6 +438,8 @@ extension OEMStore: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
|
|||
4: .standard(proto: "oem_font"),
|
||||
5: .standard(proto: "oem_text"),
|
||||
6: .standard(proto: "oem_aes_key"),
|
||||
7: .standard(proto: "oem_local_config"),
|
||||
8: .standard(proto: "oem_local_module_config"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
|
|
@ -427,12 +454,18 @@ extension OEMStore: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
|
|||
case 4: try { try decoder.decodeSingularEnumField(value: &self.oemFont) }()
|
||||
case 5: try { try decoder.decodeSingularStringField(value: &self.oemText) }()
|
||||
case 6: try { try decoder.decodeSingularBytesField(value: &self.oemAesKey) }()
|
||||
case 7: try { try decoder.decodeSingularMessageField(value: &self._oemLocalConfig) }()
|
||||
case 8: try { try decoder.decodeSingularMessageField(value: &self._oemLocalModuleConfig) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
if self.oemIconWidth != 0 {
|
||||
try visitor.visitSingularUInt32Field(value: self.oemIconWidth, fieldNumber: 1)
|
||||
}
|
||||
|
|
@ -451,6 +484,12 @@ extension OEMStore: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
|
|||
if !self.oemAesKey.isEmpty {
|
||||
try visitor.visitSingularBytesField(value: self.oemAesKey, fieldNumber: 6)
|
||||
}
|
||||
try { if let v = self._oemLocalConfig {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 7)
|
||||
} }()
|
||||
try { if let v = self._oemLocalModuleConfig {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 8)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
|
|
@ -461,6 +500,8 @@ extension OEMStore: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
|
|||
if lhs.oemFont != rhs.oemFont {return false}
|
||||
if lhs.oemText != rhs.oemText {return false}
|
||||
if lhs.oemAesKey != rhs.oemAesKey {return false}
|
||||
if lhs._oemLocalConfig != rhs._oemLocalConfig {return false}
|
||||
if lhs._oemLocalModuleConfig != rhs._oemLocalModuleConfig {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ struct Connect: View {
|
|||
if isUnsetRegion {
|
||||
HStack {
|
||||
NavigationLink {
|
||||
LoRaConfig(node: node, connectedNode: node)
|
||||
LoRaConfig(node: node)
|
||||
} label: {
|
||||
Label("set.region", systemImage: "globe.americas.fill")
|
||||
.foregroundColor(.red)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ struct NodeMap: View {
|
|||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
@EnvironmentObject var userSettings: UserSettings
|
||||
@AppStorage("meshMapType") var type: String = "hybrid"
|
||||
|
||||
@AppStorage("meshMapCustomTileServer") var customTileServer: String = "" {
|
||||
didSet {
|
||||
if customTileServer == "" {
|
||||
|
|
@ -39,7 +39,7 @@ struct NodeMap: View {
|
|||
), animation: .easeIn)
|
||||
private var waypoints: FetchedResults<WaypointEntity>
|
||||
|
||||
@State private var mapType: MKMapType = .standard
|
||||
@State private var mapType: MKMapType?
|
||||
@State var waypointCoordinate: CLLocationCoordinate2D = LocationHelper.DefaultLocation
|
||||
@State var editingWaypoint: Int = 0
|
||||
@State private var presentingWaypointForm = false
|
||||
|
|
@ -68,7 +68,9 @@ struct NodeMap: View {
|
|||
editingWaypoint = wpId
|
||||
presentingWaypointForm = true
|
||||
}
|
||||
}, positions: Array(positions), waypoints: Array(waypoints), mapViewType: mapType,
|
||||
}, positions: Array(positions),
|
||||
waypoints: Array(waypoints),
|
||||
mapViewType: mapType ?? MKMapType.standard,
|
||||
centerOnPositionsOnly: false,
|
||||
customMapOverlay: self.customMapOverlay,
|
||||
overlays: self.overlays
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ struct BluetoothConfig: View {
|
|||
@Environment(\.dismiss) private var goBack
|
||||
|
||||
var node: NodeInfoEntity?
|
||||
var connectedNode: NodeInfoEntity?
|
||||
|
||||
@State private var isPresentingSaveConfirm: Bool = false
|
||||
@State var hasChanges = false
|
||||
|
|
@ -80,7 +79,7 @@ struct BluetoothConfig: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
.disabled(bleManager.connectedPeripheral == nil)
|
||||
.disabled(self.bleManager.connectedPeripheral == nil || node?.bluetoothConfig == nil)
|
||||
|
||||
Button {
|
||||
isPresentingSaveConfirm = true
|
||||
|
|
@ -97,14 +96,15 @@ struct BluetoothConfig: 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 bc = Config.BluetoothConfig()
|
||||
bc.enabled = enabled
|
||||
bc.mode = BluetoothModes(rawValue: mode)?.protoEnumValue() ?? Config.BluetoothConfig.PairingMode.randomPin
|
||||
bc.fixedPin = UInt32(fixedPin) ?? 123456
|
||||
let adminMessageId = bleManager.saveBluetoothConfig(config: bc, fromUser: node!.user!, toUser: node!.user!)
|
||||
let adminMessageId = bleManager.saveBluetoothConfig(config: bc, 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
|
||||
|
|
@ -127,15 +127,13 @@ struct BluetoothConfig: View {
|
|||
self.fixedPin = String(node?.bluetoothConfig?.fixedPin ?? 123456)
|
||||
self.hasChanges = false
|
||||
|
||||
// Need to request a LoRaConfig from the remote node before allowing changes
|
||||
if node?.bluetoothConfig == nil {
|
||||
print("empty bluetooth config")
|
||||
|
||||
}
|
||||
|
||||
// Need to request a BluetoothConfig from the remote node before allowing changes
|
||||
if connectedNode != nil && node?.bluetoothConfig == nil {
|
||||
_ = bleManager.requestBluetoothConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
|
||||
if bleManager.connectedPeripheral != nil && node?.loRaConfig == nil {
|
||||
print("empty bluetooth config")
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
if connectedNode.id > 0 {
|
||||
_ = bleManager.requestBluetoothConfig(fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: enabled) { newEnabled in
|
||||
|
|
|
|||
|
|
@ -35,12 +35,14 @@ struct DeviceConfig: View {
|
|||
|
||||
Picker("Device Role", selection: $deviceRole ) {
|
||||
ForEach(DeviceRoles.allCases) { dr in
|
||||
Text(dr.description)
|
||||
Text(dr.name)
|
||||
}
|
||||
}
|
||||
.pickerStyle(DefaultPickerStyle())
|
||||
.padding(.top, 10)
|
||||
.padding(.bottom, 10)
|
||||
Text(DeviceRoles(rawValue: deviceRole)?.description ?? "")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
}
|
||||
|
||||
Section(header: Text("Debug")) {
|
||||
|
|
@ -83,7 +85,7 @@ struct DeviceConfig: View {
|
|||
}
|
||||
|
||||
}
|
||||
.disabled(bleManager.connectedPeripheral == nil)
|
||||
.disabled(self.bleManager.connectedPeripheral == nil || node?.deviceConfig == nil)
|
||||
|
||||
HStack {
|
||||
|
||||
|
|
@ -138,11 +140,9 @@ struct DeviceConfig: View {
|
|||
HStack {
|
||||
|
||||
Button {
|
||||
|
||||
isPresentingSaveConfirm = true
|
||||
|
||||
} label: {
|
||||
|
||||
Label("save", systemImage: "square.and.arrow.down")
|
||||
}
|
||||
.disabled(bleManager.connectedPeripheral == nil || !hasChanges)
|
||||
|
|
@ -156,10 +156,10 @@ struct DeviceConfig: 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 dc = Config.DeviceConfig()
|
||||
dc.role = DeviceRoles(rawValue: deviceRole)!.protoEnumValue()
|
||||
dc.serialEnabled = serialEnabled
|
||||
|
|
@ -167,7 +167,7 @@ struct DeviceConfig: View {
|
|||
dc.buttonGpio = UInt32(buttonGPIO)
|
||||
dc.buzzerGpio = UInt32(buzzerGPIO)
|
||||
|
||||
let adminMessageId = bleManager.saveDeviceConfig(config: dc, fromUser: node!.user!, toUser: node!.user!)
|
||||
let adminMessageId = bleManager.saveDeviceConfig(config: dc, 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
|
||||
|
|
@ -195,6 +195,15 @@ struct DeviceConfig: View {
|
|||
self.buttonGPIO = Int(node?.deviceConfig?.buttonGpio ?? 0)
|
||||
self.buzzerGPIO = Int(node?.deviceConfig?.buzzerGpio ?? 0)
|
||||
self.hasChanges = false
|
||||
|
||||
// Need to request a LoRaConfig from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.deviceConfig == nil {
|
||||
print("empty device config")
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
if connectedNode.id > 0 {
|
||||
_ = bleManager.requestDeviceConfig(fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: deviceRole) { newRole in
|
||||
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ struct DisplayConfig: View {
|
|||
.listRowSeparator(.visible)
|
||||
}
|
||||
}
|
||||
.disabled(bleManager.connectedPeripheral == nil)
|
||||
.disabled(self.bleManager.connectedPeripheral == nil || node?.displayConfig == nil)
|
||||
|
||||
Button {
|
||||
|
||||
|
|
@ -116,9 +116,10 @@ struct DisplayConfig: View {
|
|||
"are.you.sure",
|
||||
isPresented: $isPresentingSaveConfirm
|
||||
) {
|
||||
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 dc = Config.DisplayConfig()
|
||||
dc.gpsFormat = GpsFormats(rawValue: gpsFormat)!.protoEnumValue()
|
||||
dc.screenOnSecs = UInt32(screenOnSeconds)
|
||||
|
|
@ -128,7 +129,7 @@ struct DisplayConfig: View {
|
|||
dc.oled = OledTypes(rawValue: oledType)!.protoEnumValue()
|
||||
dc.displaymode = DisplayModes(rawValue: displayMode)!.protoEnumValue()
|
||||
|
||||
let adminMessageId = bleManager.saveDisplayConfig(config: dc, fromUser: node!.user!, toUser: node!.user!)
|
||||
let adminMessageId = bleManager.saveDisplayConfig(config: dc, fromUser: connectedNode.user!, toUser: node!.user!)
|
||||
if adminMessageId > 0 {
|
||||
|
||||
// Should show a saved successfully alert once I know that to be true
|
||||
|
|
@ -156,6 +157,15 @@ struct DisplayConfig: View {
|
|||
self.oledType = Int(node?.displayConfig?.oledType ?? 0)
|
||||
self.displayMode = Int(node?.displayConfig?.displayMode ?? 0)
|
||||
self.hasChanges = false
|
||||
|
||||
// Need to request a LoRaConfig from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.displayConfig == nil {
|
||||
print("empty display config")
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
if connectedNode.id > 0 {
|
||||
_ = bleManager.requestDisplayConfig(fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: screenOnSeconds) { newScreenSecs in
|
||||
if node != nil && node!.displayConfig != nil {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ struct LoRaConfig: View {
|
|||
@Environment(\.dismiss) private var goBack
|
||||
|
||||
var node: NodeInfoEntity?
|
||||
var connectedNode: NodeInfoEntity?
|
||||
|
||||
@State var isPresentingSaveConfirm = false
|
||||
@State var hasChanges = false
|
||||
|
|
@ -62,7 +61,7 @@ struct LoRaConfig: View {
|
|||
.font(.caption)
|
||||
}
|
||||
}
|
||||
.disabled(self.bleManager.connectedPeripheral == nil)
|
||||
.disabled(self.bleManager.connectedPeripheral == nil || node?.loRaConfig == nil)
|
||||
Button {
|
||||
isPresentingSaveConfirm = true
|
||||
} label: {
|
||||
|
|
@ -81,13 +80,14 @@ struct LoRaConfig: View {
|
|||
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 lc = Config.LoRaConfig()
|
||||
lc.hopLimit = UInt32(hopLimit)
|
||||
lc.region = RegionCodes(rawValue: region)!.protoEnumValue()
|
||||
lc.modemPreset = ModemPresets(rawValue: modemPreset)!.protoEnumValue()
|
||||
lc.usePreset = true
|
||||
lc.txEnabled = true
|
||||
let adminMessageId = bleManager.saveLoRaConfig(config: lc, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: node?.myInfo?.adminIndex ?? 0)
|
||||
let adminMessageId = bleManager.saveLoRaConfig(config: lc, fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: node?.myInfo?.adminIndex ?? 0)
|
||||
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
|
||||
|
|
@ -116,9 +116,12 @@ struct LoRaConfig: View {
|
|||
self.hasChanges = false
|
||||
|
||||
// Need to request a LoRaConfig from the remote node before allowing changes
|
||||
if connectedNode != nil && node?.loRaConfig == nil {
|
||||
if bleManager.connectedPeripheral != nil && node?.loRaConfig == nil {
|
||||
print("empty lora config")
|
||||
_ = bleManager.requestLoRaConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
if connectedNode.id > 0 {
|
||||
_ = bleManager.requestLoRaConfig(fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: region) { newRegion in
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ struct RangeTestConfig: View {
|
|||
.font(.caption)
|
||||
}
|
||||
}
|
||||
.disabled(!(node != nil && node!.myInfo?.hasWifi ?? false))
|
||||
.disabled(self.bleManager.connectedPeripheral == nil || node?.positionConfig == nil || !(node != nil && node!.myInfo?.hasWifi ?? false))
|
||||
Button {
|
||||
isPresentingSaveConfirm = true
|
||||
} label: {
|
||||
|
|
@ -62,14 +62,16 @@ struct RangeTestConfig: 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 rtc = ModuleConfig.RangeTestConfig()
|
||||
rtc.enabled = enabled
|
||||
rtc.save = save
|
||||
rtc.sender = UInt32(sender)
|
||||
let adminMessageId = bleManager.saveRangeTestModuleConfig(config: rtc, fromUser: node!.user!, toUser: node!.user!)
|
||||
let adminMessageId = bleManager.saveRangeTestModuleConfig(config: rtc, 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
|
||||
|
|
@ -92,6 +94,15 @@ struct RangeTestConfig: View {
|
|||
self.save = node?.rangeTestConfig?.save ?? false
|
||||
self.sender = Int(node?.rangeTestConfig?.sender ?? 0)
|
||||
self.hasChanges = false
|
||||
|
||||
// Need to request a RangeTestModule Config from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.rangeTestConfig == nil {
|
||||
print("empty range test module config")
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
if connectedNode.id > 0 {
|
||||
_ = bleManager.requestRangeTestModuleConfig(fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: enabled) { newEnabled in
|
||||
if node != nil && node!.rangeTestConfig != nil {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ struct TelemetryConfig: View {
|
|||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
}
|
||||
}
|
||||
.disabled(bleManager.connectedPeripheral == nil)
|
||||
.disabled(self.bleManager.connectedPeripheral == nil || node?.positionConfig == nil)
|
||||
Button {
|
||||
isPresentingSaveConfirm = true
|
||||
} label: {
|
||||
|
|
@ -77,7 +77,8 @@ struct TelemetryConfig: 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 tc = ModuleConfig.TelemetryConfig()
|
||||
|
|
@ -86,7 +87,7 @@ struct TelemetryConfig: View {
|
|||
tc.environmentMeasurementEnabled = environmentMeasurementEnabled
|
||||
tc.environmentScreenEnabled = environmentScreenEnabled
|
||||
tc.environmentDisplayFahrenheit = environmentDisplayFahrenheit
|
||||
let adminMessageId = bleManager.saveTelemetryModuleConfig(config: tc, fromUser: node!.user!, toUser: node!.user!)
|
||||
let adminMessageId = bleManager.saveTelemetryModuleConfig(config: tc, 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
|
||||
|
|
@ -111,6 +112,15 @@ struct TelemetryConfig: View {
|
|||
self.environmentScreenEnabled = node?.telemetryConfig?.environmentScreenEnabled ?? false
|
||||
self.environmentDisplayFahrenheit = node?.telemetryConfig?.environmentDisplayFahrenheit ?? 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 telemetry module config")
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
if connectedNode.id > 0 {
|
||||
_ = bleManager.requestTelemetryModuleConfig(fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: deviceUpdateInterval) { newDeviceInterval in
|
||||
if node != nil && node!.telemetryConfig != nil {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ struct NetworkConfig: View {
|
|||
@State var ethEnabled = false
|
||||
@State var ethMode = 0
|
||||
|
||||
|
||||
var body: some View {
|
||||
|
||||
VStack {
|
||||
|
|
@ -92,7 +91,7 @@ struct NetworkConfig: View {
|
|||
}
|
||||
}
|
||||
.scrollDismissesKeyboard(.interactively)
|
||||
.disabled(!(node != nil))
|
||||
.disabled(self.bleManager.connectedPeripheral == nil || node?.networkConfig == nil)
|
||||
Button {
|
||||
isPresentingSaveConfirm = true
|
||||
} label: {
|
||||
|
|
@ -108,9 +107,10 @@ struct NetworkConfig: 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 network = Config.NetworkConfig()
|
||||
network.wifiEnabled = self.wifiEnabled
|
||||
network.wifiSsid = self.wifiSsid
|
||||
|
|
@ -118,7 +118,7 @@ struct NetworkConfig: View {
|
|||
network.ethEnabled = self.ethEnabled
|
||||
//network.addressMode = Config.NetworkConfig.AddressMode.dhcp
|
||||
|
||||
let adminMessageId = bleManager.saveNetworkConfig(config: network, fromUser: node!.user!, toUser: node!.user!)
|
||||
let adminMessageId = bleManager.saveNetworkConfig(config: network, 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
|
||||
|
|
@ -143,6 +143,15 @@ struct NetworkConfig: View {
|
|||
self.wifiMode = Int(node?.networkConfig?.wifiMode ?? 0)
|
||||
self.ethEnabled = node?.networkConfig?.ethEnabled ?? false
|
||||
self.hasChanges = false
|
||||
|
||||
// Need to request a NetworkConfig from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.positionConfig == nil {
|
||||
print("empty network config")
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
if connectedNode.id > 0 {
|
||||
_ = bleManager.requestNetworkConfig(fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: wifiEnabled) { newEnabled in
|
||||
if node != nil && node!.networkConfig != nil {
|
||||
|
|
|
|||
|
|
@ -185,14 +185,11 @@ struct PositionConfig: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
.disabled(bleManager.connectedPeripheral == nil)
|
||||
.disabled(self.bleManager.connectedPeripheral == nil || node?.positionConfig == nil)
|
||||
|
||||
Button {
|
||||
|
||||
isPresentingSaveConfirm = true
|
||||
|
||||
} label: {
|
||||
|
||||
Label("save", systemImage: "square.and.arrow.down")
|
||||
}
|
||||
.disabled(bleManager.connectedPeripheral == nil || !hasChanges)
|
||||
|
|
@ -205,14 +202,14 @@ struct PositionConfig: 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) {
|
||||
|
||||
if fixedPosition {
|
||||
_ = bleManager.sendPosition(destNum: bleManager.connectedPeripheral.num, wantResponse: false)
|
||||
}
|
||||
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
var pc = Config.PositionConfig()
|
||||
pc.positionBroadcastSmartEnabled = smartPositionEnabled
|
||||
pc.gpsEnabled = deviceGpsEnabled
|
||||
|
|
@ -232,7 +229,7 @@ struct PositionConfig: View {
|
|||
if includeSpeed { pf.insert(.Speed) }
|
||||
if includeHeading { pf.insert(.Heading) }
|
||||
pc.positionFlags = UInt32(pf.rawValue)
|
||||
let adminMessageId = bleManager.savePositionConfig(config: pc, fromUser: node!.user!, toUser: node!.user!)
|
||||
let adminMessageId = bleManager.savePositionConfig(config: pc, 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
|
||||
|
|
@ -278,6 +275,14 @@ struct PositionConfig: View {
|
|||
|
||||
self.hasChanges = false
|
||||
|
||||
// Need to request a PositionConfig from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.positionConfig == nil {
|
||||
print("empty position config")
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
if connectedNode.id > 0 {
|
||||
_ = bleManager.requestPositionConfig(fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: deviceGpsEnabled) { newDeviceGps in
|
||||
if node != nil && node!.positionConfig != nil {
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ struct Settings: View {
|
|||
.disabled(selectedNode > 0 && selectedNode != connectedNodeNum)
|
||||
|
||||
NavigationLink {
|
||||
UserConfig(node: nodes.first(where: { $0.num == selectedNode }), connectedNode: nodes.first(where: { $0.num == connectedNodeNum }))
|
||||
UserConfig(node: nodes.first(where: { $0.num == selectedNode }))
|
||||
} label: {
|
||||
|
||||
Image(systemName: "person.crop.rectangle.fill")
|
||||
|
|
@ -116,14 +116,13 @@ struct Settings: View {
|
|||
.tag(SettingsSidebar.userConfig)
|
||||
|
||||
NavigationLink() {
|
||||
LoRaConfig(node: nodes.first(where: { $0.num == selectedNode }), connectedNode: nodes.first(where: { $0.num == connectedNodeNum }))
|
||||
LoRaConfig(node: nodes.first(where: { $0.num == selectedNode }))
|
||||
} label: {
|
||||
Image(systemName: "dot.radiowaves.left.and.right")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
Text("lora")
|
||||
}
|
||||
.tag(SettingsSidebar.loraConfig)
|
||||
.disabled(selectedNode > 0 && selectedNode != connectedNodeNum)
|
||||
|
||||
NavigationLink() {
|
||||
Channels(node: nodes.first(where: { $0.num == connectedNodeNum }))
|
||||
|
|
@ -136,14 +135,13 @@ struct Settings: View {
|
|||
.disabled(selectedNode > 0 && selectedNode != connectedNodeNum)
|
||||
|
||||
NavigationLink() {
|
||||
BluetoothConfig(node: nodes.first(where: { $0.num == selectedNode }), connectedNode: nodes.first(where: { $0.num == connectedNodeNum }))
|
||||
BluetoothConfig(node: nodes.first(where: { $0.num == selectedNode }))
|
||||
} label: {
|
||||
Image(systemName: "antenna.radiowaves.left.and.right")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
Text("bluetooth")
|
||||
}
|
||||
.tag(SettingsSidebar.bluetoothConfig)
|
||||
.disabled(selectedNode > 0 && selectedNode != connectedNodeNum)
|
||||
|
||||
NavigationLink {
|
||||
DeviceConfig(node: nodes.first(where: { $0.num == selectedNode }))
|
||||
|
|
@ -153,7 +151,6 @@ struct Settings: View {
|
|||
Text("device")
|
||||
}
|
||||
.tag(SettingsSidebar.deviceConfig)
|
||||
.disabled(selectedNode > 0 && selectedNode != connectedNodeNum)
|
||||
|
||||
NavigationLink {
|
||||
DisplayConfig(node: nodes.first(where: { $0.num == selectedNode }))
|
||||
|
|
@ -163,7 +160,6 @@ struct Settings: View {
|
|||
Text("display")
|
||||
}
|
||||
.tag(SettingsSidebar.displayConfig)
|
||||
.disabled(selectedNode > 0 && selectedNode != connectedNodeNum)
|
||||
|
||||
NavigationLink {
|
||||
NetworkConfig(node: nodes.first(where: { $0.num == selectedNode }))
|
||||
|
|
@ -174,7 +170,6 @@ struct Settings: View {
|
|||
Text("network")
|
||||
}
|
||||
.tag(SettingsSidebar.networkConfig)
|
||||
.disabled(selectedNode > 0 && selectedNode != connectedNodeNum)
|
||||
|
||||
NavigationLink {
|
||||
PositionConfig(node: nodes.first(where: { $0.num == selectedNode }))
|
||||
|
|
@ -185,7 +180,6 @@ struct Settings: View {
|
|||
Text("position")
|
||||
}
|
||||
.tag(SettingsSidebar.positionConfig)
|
||||
.disabled(selectedNode > 0 && selectedNode != connectedNodeNum)
|
||||
|
||||
}
|
||||
Section("module.configuration") {
|
||||
|
|
@ -200,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 }))
|
||||
|
|
@ -210,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 }))
|
||||
|
|
@ -220,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 }))
|
||||
|
|
@ -230,7 +221,6 @@ struct Settings: View {
|
|||
Text("range.test")
|
||||
}
|
||||
.tag(SettingsSidebar.rangeTestConfig)
|
||||
.disabled(selectedNode > 0 && selectedNode != connectedNodeNum)
|
||||
|
||||
NavigationLink {
|
||||
SerialConfig(node: nodes.first(where: { $0.num == selectedNode }))
|
||||
|
|
@ -240,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 }))
|
||||
|
|
@ -250,7 +239,6 @@ struct Settings: View {
|
|||
Text("telemetry")
|
||||
}
|
||||
.tag(SettingsSidebar.telemetryConfig)
|
||||
.disabled(selectedNode > 0 && selectedNode != connectedNodeNum)
|
||||
}
|
||||
Section(header: Text("logging")) {
|
||||
NavigationLink {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ struct UserConfig: View {
|
|||
@Environment(\.dismiss) private var goBack
|
||||
|
||||
var node: NodeInfoEntity?
|
||||
var connectedNode: NodeInfoEntity?
|
||||
|
||||
@State private var isPresentingFactoryResetConfirm: Bool = false
|
||||
@State private var isPresentingSaveConfirm: Bool = false
|
||||
|
|
@ -86,10 +85,13 @@ struct UserConfig: View {
|
|||
titleVisibility: .visible
|
||||
) {
|
||||
Button("Save User Config to \(node?.user?.longName ?? "Unknown")?") {
|
||||
|
||||
let connectedUser = getUser(id: bleManager.connectedPeripheral.num, context: context)
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
var u = User()
|
||||
u.shortName = shortName
|
||||
u.longName = longName
|
||||
let adminMessageId = bleManager.saveUser(config: u, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
|
||||
let adminMessageId = bleManager.saveUser(config: u, fromUser: connectedUser, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
|
||||
if adminMessageId > 0 {
|
||||
hasChanges = false
|
||||
goBack()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue