Merge pull request #332 from meshtastic/2.1.0_Working_Changes

2.1.0 working changes
This commit is contained in:
Garth Vander Houwen 2023-03-15 17:00:49 -07:00 committed by GitHub
commit b747634d4e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
50 changed files with 1369 additions and 446 deletions

View file

@ -18,6 +18,7 @@
DD2553572855B02500E55709 /* LoRaConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD2553562855B02500E55709 /* LoRaConfig.swift */; };
DD2553592855B52700E55709 /* PositionConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD2553582855B52700E55709 /* PositionConfig.swift */; };
DD2AD8A8296D2DF9001FF0E7 /* MapViewSwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD2AD8A7296D2DF9001FF0E7 /* MapViewSwiftUI.swift */; };
DD2DC2C029BCD8AB003B383C /* HardwareModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD2DC2BF29BCD8AB003B383C /* HardwareModels.swift */; };
DD2E65262767A01F00E45FC5 /* NodeDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD2E65252767A01F00E45FC5 /* NodeDetail.swift */; };
DD3501892852FC3B000FC853 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD3501882852FC3B000FC853 /* Settings.swift */; };
DD35018B2852FC79000FC853 /* UserSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD35018A2852FC79000FC853 /* UserSettings.swift */; };
@ -110,6 +111,7 @@
DDCDC6CB29481FCC004C1DDA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DDCDC6CD29481FCC004C1DDA /* Localizable.strings */; };
DDCE4E2C2869F92900BE9F8F /* UserConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCE4E2B2869F92900BE9F8F /* UserConfig.swift */; };
DDD3BBD5292D763200D609B3 /* MeshtasticTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD3BBD4292D763200D609B3 /* MeshtasticTests.swift */; };
DDD6EEAF29BC024700383354 /* Firmware.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD6EEAE29BC024700383354 /* Firmware.swift */; };
DDD94A502845C8F5004A87A0 /* DateTimeText.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD94A4F2845C8F5004A87A0 /* DateTimeText.swift */; };
DDD9E4E4284B208E003777C5 /* UserEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD9E4E3284B208E003777C5 /* UserEntityExtension.swift */; };
DDDE59F529AF163D00490C6C /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD41A61C29AE7E8E003C5A37 /* WidgetKit.framework */; };
@ -177,6 +179,7 @@
DD2553562855B02500E55709 /* LoRaConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoRaConfig.swift; sourceTree = "<group>"; };
DD2553582855B52700E55709 /* PositionConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionConfig.swift; sourceTree = "<group>"; };
DD2AD8A7296D2DF9001FF0E7 /* MapViewSwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewSwiftUI.swift; sourceTree = "<group>"; };
DD2DC2BF29BCD8AB003B383C /* HardwareModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HardwareModels.swift; sourceTree = "<group>"; };
DD2E65252767A01F00E45FC5 /* NodeDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeDetail.swift; sourceTree = "<group>"; };
DD3501882852FC3B000FC853 /* Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = "<group>"; };
DD35018A2852FC79000FC853 /* UserSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSettings.swift; sourceTree = "<group>"; };
@ -284,6 +287,7 @@
DDCDC6CE294821AD004C1DDA /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = "<group>"; };
DDCE4E2B2869F92900BE9F8F /* UserConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserConfig.swift; sourceTree = "<group>"; };
DDD3BBD4292D763200D609B3 /* MeshtasticTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MeshtasticTests.swift; sourceTree = "<group>"; };
DDD6EEAE29BC024700383354 /* Firmware.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Firmware.swift; sourceTree = "<group>"; };
DDD94A4F2845C8F5004A87A0 /* DateTimeText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateTimeText.swift; sourceTree = "<group>"; };
DDD9E4E3284B208E003777C5 /* UserEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserEntityExtension.swift; sourceTree = "<group>"; };
DDDD527729B5B83F0045BC3C /* MeshtasticDataModelV9.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV9.xcdatamodel; sourceTree = "<group>"; };
@ -385,6 +389,7 @@
DD0F791A28713C8A00A6FDAD /* AdminMessageList.swift */,
DD4A911D2708C65400501B7E /* AppSettings.swift */,
DDA0B6B1294CDC55001356EC /* Channels.swift */,
DDD6EEAE29BC024700383354 /* Firmware.swift */,
DD8169FA271F1F3A00F4AB02 /* MeshLog.swift */,
DD86D40B287F401000BAEB7A /* SaveChannelQRCode.swift */,
DD3501882852FC3B000FC853 /* Settings.swift */,
@ -483,6 +488,7 @@
DD1925B828CDA93900720036 /* SerialConfigEnums.swift */,
DD994B68295F88B60013760A /* IntervalEnums.swift */,
DD5E5239298EFA5300D21B61 /* TelemetryWeather.swift */,
DD2DC2BF29BCD8AB003B383C /* HardwareModels.swift */,
);
path = Enums;
sourceTree = "<group>";
@ -891,6 +897,7 @@
DD769E0328D18BF1001A3F05 /* DeviceMetricsLog.swift in Sources */,
DDAF8C5326EB1DF10058C060 /* BLEManager.swift in Sources */,
DDC4D568275499A500A4208E /* Persistence.swift in Sources */,
DDD6EEAF29BC024700383354 /* Firmware.swift in Sources */,
DD90860E26F69BAE00DC5189 /* NodeMap.swift in Sources */,
DD964FBD296E6B01007C176F /* EmojiOnlyTextField.swift in Sources */,
DD8169FF272476C700F4AB02 /* LogDocument.swift in Sources */,
@ -926,6 +933,7 @@
DD47E3D626F17ED900029299 /* CircleText.swift in Sources */,
DDC2E18F26CE25FE0042C5E4 /* ContentView.swift in Sources */,
DD2553572855B02500E55709 /* LoRaConfig.swift in Sources */,
DD2DC2C029BCD8AB003B383C /* HardwareModels.swift in Sources */,
DDB6ABD928B0A4BA00384BA1 /* BluetoothModes.swift in Sources */,
DDD9E4E4284B208E003777C5 /* UserEntityExtension.swift in Sources */,
DD2553592855B52700E55709 /* PositionConfig.swift in Sources */,
@ -1180,7 +1188,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 2.0.22;
MARKETING_VERSION = 2.1.0;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTS_MACCATALYST = YES;
@ -1214,7 +1222,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 2.0.22;
MARKETING_VERSION = 2.1.0;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTS_MACCATALYST = YES;

View file

@ -0,0 +1,262 @@
//
// HardwareModels.swift
// Meshtastic
//
// Copyright(c) Garth Vander Houwen 3/11/23.
//
import Foundation
enum HardwareModels: String, CaseIterable, Identifiable {
case UNSET
case TLORA_V2
case TLORA_V1
case TLORA_V2_1_1P6
case TBEAM
case HELTEC_V2_0
case TBEAM_V0P7
case T_ECHO
case TLORA_V1_1P3
case RAK4631
case HELTEC_V2_1
case HELTEC_V1
case LILYGO_TBEAM_S3_CORE
case RAK11200
case NANO_G1
case TLORA_V2_1_1P8
case TLORA_T3_S3
case NANO_G1_EXPLORER
case STATION_G1
case M5STACK
case HELTEC_V3
case HELTEC_WSL_V3
var id: String { self.rawValue }
var description: String {
switch self {
case .UNSET:
return NSLocalizedString("unset", comment: "UNSET")
case .TLORA_V2:
return "TLoRa V2"
case .TLORA_V1:
return "TLoRa V1"
case .TLORA_V2_1_1P6:
return "TLoRa V2.1.1.6"
case .TBEAM:
return "TBeam"
case .HELTEC_V2_0:
return "HELTEC V2.0"
case .TBEAM_V0P7:
return "TBeam 0.7"
case .T_ECHO:
return "TEcho"
case .TLORA_V1_1P3:
return "TLORA V1.1.3"
case .RAK4631:
return "RAK 4631 NRF"
case .HELTEC_V2_1:
return "HELTEC V2.1"
case .HELTEC_V1:
return "HELTEC V1"
case .LILYGO_TBEAM_S3_CORE:
return "TBEAM S3"
case .RAK11200:
return "RAK 11200 ESP32"
case .NANO_G1:
return "Nano G1"
case .TLORA_V2_1_1P8:
return "TLoRa V2.1.1.8"
case .TLORA_T3_S3:
return "TLoRa T3 S3"
case .NANO_G1_EXPLORER:
return "Nano G1 Explorer"
case .STATION_G1:
return "Station G1"
case .M5STACK:
return "M5 Stack"
case .HELTEC_V3:
return "Heltec V3"
case .HELTEC_WSL_V3:
return "Heltec wireless stick lite V3"
}
}
var firmwareStrings: [String] {
switch self {
case .UNSET:
return []
case .TLORA_V2:
return ["firmware-tlora-v2-"]
case .TLORA_V1:
return ["firmware-tlora-v1-"]
case .TLORA_V2_1_1P6:
return ["firmware-tlora-v2-1-1.6-"]
case .TBEAM:
return ["firmware-tbeam-"]
case .HELTEC_V2_0:
return ["firmware-heltec-v2.0-"]
case .TBEAM_V0P7:
return ["firmware-tbeam0.7-"]
case .T_ECHO:
return ["firmware-t-echo-"]
case .TLORA_V1_1P3:
return ["firmware-tlora_v1_3-"]
case .RAK4631:
return ["firmware-rak4631-", "firmware-rak4631_eink-"]
case .HELTEC_V2_1:
return ["firmware-heltec-v2.1-"]
case .HELTEC_V1:
return ["firmware-heltec-v1-"]
case .LILYGO_TBEAM_S3_CORE:
return ["firmware-tbeam-s3-core-"]
case .RAK11200:
return ["firmware-rak11200-"]
case .NANO_G1:
return ["firmware-nano-g1-"]
case .TLORA_V2_1_1P8:
return ["firmware-tlora-v2-1-1.8-"]
case .TLORA_T3_S3:
return ["firmware-tlora-t3s3-v1-"]
case .NANO_G1_EXPLORER:
return ["firmware-nano-g1-explorer-"]
case .STATION_G1:
return ["firmware-station-g1-"]
case .M5STACK:
return ["firmware-m5stack-core-", "firmware-m5stack-coreink-"]
case .HELTEC_V3:
return ["firmware-heltec-v3-"]
case .HELTEC_WSL_V3:
return ["firmware-heltec-wsl-v3-"]
}
}
func platform() -> HardwarePlatforms {
switch self {
case .UNSET:
return HardwarePlatforms.NONE
case .TLORA_V2:
return HardwarePlatforms.ESP32
case .TLORA_V1:
return HardwarePlatforms.ESP32
case .TLORA_V2_1_1P6:
return HardwarePlatforms.ESP32
case .TBEAM:
return HardwarePlatforms.ESP32
case .HELTEC_V2_0:
return HardwarePlatforms.ESP32
case .TBEAM_V0P7:
return HardwarePlatforms.ESP32
case .T_ECHO:
return HardwarePlatforms.NRF52
case .TLORA_V1_1P3:
return HardwarePlatforms.ESP32
case .RAK4631:
return HardwarePlatforms.NRF52
case .HELTEC_V2_1:
return HardwarePlatforms.ESP32
case .HELTEC_V1:
return HardwarePlatforms.ESP32
case .LILYGO_TBEAM_S3_CORE:
return HardwarePlatforms.ESP32
case .RAK11200:
return HardwarePlatforms.ESP32
case .NANO_G1:
return HardwarePlatforms.ESP32
case .TLORA_V2_1_1P8:
return HardwarePlatforms.ESP32
case .TLORA_T3_S3:
return HardwarePlatforms.ESP32
case .NANO_G1_EXPLORER:
return HardwarePlatforms.ESP32
case .STATION_G1:
return HardwarePlatforms.ESP32
case .M5STACK:
return HardwarePlatforms.ESP32
case .HELTEC_V3:
return HardwarePlatforms.ESP32
case .HELTEC_WSL_V3:
return HardwarePlatforms.ESP32
}
}
func protoEnumValue() -> HardwareModel {
switch self {
case .UNSET:
return HardwareModel.unset
case .TLORA_V2:
return HardwareModel.tloraV2
case .TLORA_V1:
return HardwareModel.tloraV1
case .TLORA_V2_1_1P6:
return HardwareModel.tloraV211P6
case .TBEAM:
return HardwareModel.tbeam
case .HELTEC_V2_0:
return HardwareModel.heltecV20
case .TBEAM_V0P7:
return HardwareModel.tbeamV0P7
case .T_ECHO:
return HardwareModel.tEcho
case .TLORA_V1_1P3:
return HardwareModel.tloraV11P3
case .RAK4631:
return HardwareModel.rak4631
case .HELTEC_V2_1:
return HardwareModel.heltecV21
case .HELTEC_V1:
return HardwareModel.heltecV1
case .LILYGO_TBEAM_S3_CORE:
return HardwareModel.lilygoTbeamS3Core
case .RAK11200:
return HardwareModel.rak11200
case .NANO_G1:
return HardwareModel.nanoG1
case .TLORA_V2_1_1P8:
return HardwareModel.tloraV211P8
case .TLORA_T3_S3:
return HardwareModel.tloraT3S3
case .NANO_G1_EXPLORER:
return HardwareModel.nanoG1Explorer
case .STATION_G1:
return HardwareModel.stationG1
case .M5STACK:
return HardwareModel.m5Stack
case .HELTEC_V3:
return HardwareModel.heltecV3
case .HELTEC_WSL_V3:
return HardwareModel.heltecWslV3
}
}
}
enum HardwarePlatforms: String, CaseIterable, Identifiable {
case NONE
case ESP32
case NRF52
case STM32
case PIPICO
var id: String { self.rawValue }
var description: String {
switch self {
case .NONE:
return "None"
case .ESP32:
return "Expressif ESP 32"
case .NRF52:
return "Nordic NRF52"
case .STM32:
return "ARM STM 32"
case .PIPICO:
return "Raspberrry Pi Pico"
}
}
}

View file

@ -92,6 +92,7 @@ enum UpdateIntervals: Int, CaseIterable, Identifiable {
case fifteenSeconds = 15
case thirtySeconds = 30
case oneMinute = 60
case twoMinutes = 120
case fiveMinutes = 300
case tenMinutes = 600
case fifteenMinutes = 900
@ -121,6 +122,8 @@ enum UpdateIntervals: Int, CaseIterable, Identifiable {
return NSLocalizedString("interval.thirty.seconds", comment: "Thirty Seconds")
case .oneMinute:
return NSLocalizedString("interval.one.minute", comment: "One Minute")
case .twoMinutes:
return NSLocalizedString("interval.two.minutes", comment: "Two Minutes")
case .fiveMinutes:
return NSLocalizedString("interval.five.minutes", comment: "Five Minutes")
case .tenMinutes:

View file

@ -158,12 +158,6 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
isConnected = true
if userSettings?.preferredPeripheralId.count ?? 0 < 1 {
userSettings?.preferredPeripheralId = peripheral.identifier.uuidString
// preferredPeripheral = true
} else if userSettings!.preferredPeripheralId == peripheral.identifier.uuidString {
// preferredPeripheral = true
} else {
// preferredPeripheral = false
print("Trying to connect a non prefered peripheral")
}
UserDefaults.standard.synchronize()
// Invalidate and reset connection timer count
@ -426,7 +420,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
} else {
let version = decodedInfo.myInfo.firmwareVersion[...(lastDotIndex ?? String.Index(utf16Offset: 6, in: decodedInfo.myInfo.firmwareVersion))]
nowKnown = true
connectedVersion = String(version)
connectedVersion = String(version.dropLast())
}
let supportedVersion = connectedVersion == "0.0.0" || self.minimumVersion.compare(connectedVersion, options: .numeric) == .orderedAscending || minimumVersion.compare(connectedVersion, options: .numeric) == .orderedSame
@ -446,6 +440,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
connectedPeripheral.longName = myInfo?.bleName ?? NSLocalizedString("unknown", comment: "Unknown")
}
}
tryClearExistingChannels()
}
// NodeInfo
if decodedInfo.nodeInfo.num > 0 && !invalidVersion {
@ -502,7 +497,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
case .waypointApp:
waypointPacket(packet: decodedInfo.packet, context: context!)
case .nodeinfoApp:
if !invalidVersion { nodeInfoAppPacket(packet: decodedInfo.packet, context: context!) }
if !invalidVersion { upsertNodeInfoPacket(packet: decodedInfo.packet, context: context!) }
case .routingApp:
if !invalidVersion { routingPacket(packet: decodedInfo.packet, connectedNodeNum: self.connectedPeripheral.num, context: context!) }
case .adminApp:
@ -873,6 +868,27 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
return false
}
public func sendRebootOta(fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Bool {
var adminPacket = AdminMessage()
adminPacket.rebootOtaSeconds = 5
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.wantAck = true
meshPacket.channel = UInt32(adminIndex)
var dataMessage = DataMessage()
dataMessage.payload = try! adminPacket.serializedData()
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
let messageDescription = "🚀 Sent Reboot OTA Admin Message to: \(toUser.longName ?? NSLocalizedString("unknown", comment: "")) from: \(fromUser.longName ?? NSLocalizedString("unknown", comment: ""))"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
return true
}
return false
}
public func sendFactoryReset(fromUser: UserEntity, toUser: UserEntity) -> Bool {
var adminPacket = AdminMessage()
adminPacket.factoryReset = 5
@ -982,25 +998,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
let fetchMyInfoRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "MyInfoEntity")
fetchMyInfoRequest.predicate = NSPredicate(format: "myNodeNum == %lld", Int64(connectedPeripheral.num))
do {
guard let fetchedMyInfo = try context!.fetch(fetchMyInfoRequest) as? [MyInfoEntity] else {
return false
}
if fetchedMyInfo.count == 1 {
guard let mutableChannels = fetchedMyInfo[0].channels!.mutableCopy() as? NSMutableOrderedSet else {
return false
}
mutableChannels.removeAllObjects()
fetchedMyInfo[0].channels = mutableChannels
do {
try context!.save()
} catch {
print("Failed to clear existing channels from local app database")
}
}
} catch {
print("Failed to find a node MyInfo to save these channels to")
}
tryClearExistingChannels()
let decodedString = base64UrlString.base64urlToBase64()
if let decodedData = Data(base64Encoded: decodedString) {
do {
@ -1129,7 +1127,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
let messageDescription = "🛟 Saved Bluetooth Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
upsertBluetoothConfigPacket(config: config, nodeNum: fromUser.num, context: context!)
upsertBluetoothConfigPacket(config: config, nodeNum: toUser.num, context: context!)
return Int64(meshPacket.id)
}
@ -1154,7 +1152,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Device Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
upsertDeviceConfigPacket(config: config, nodeNum: fromUser.num, context: context!)
upsertDeviceConfigPacket(config: config, nodeNum: toUser.num, context: context!)
return Int64(meshPacket.id)
}
return 0
@ -1172,14 +1170,13 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
meshPacket.priority = MeshPacket.Priority.reliable
meshPacket.wantAck = true
meshPacket.hopLimit = 0
var dataMessage = DataMessage()
dataMessage.payload = try! adminPacket.serializedData()
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Display Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
upsertDisplayConfigPacket(config: config, nodeNum: fromUser.num, context: context!)
upsertDisplayConfigPacket(config: config, nodeNum: toUser.num, context: context!)
return Int64(meshPacket.id)
}
return 0
@ -1191,11 +1188,11 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
adminPacket.setConfig.lora = config
var meshPacket: MeshPacket = MeshPacket()
meshPacket.to = UInt32(toUser.num)
meshPacket.from = UInt32(fromUser.num)
meshPacket.from = UInt32(fromUser.num)
meshPacket.channel = UInt32(adminIndex)
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
meshPacket.priority = MeshPacket.Priority.reliable
meshPacket.wantAck = true
meshPacket.channel = UInt32(adminIndex)
var dataMessage = DataMessage()
dataMessage.payload = try! adminPacket.serializedData()
dataMessage.portnum = PortNum.adminApp
@ -1203,7 +1200,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
let messageDescription = "🛟 Saved LoRa Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
upsertLoRaConfigPacket(config: config, nodeNum: fromUser.num, context: context!)
upsertLoRaConfigPacket(config: config, nodeNum: toUser.num, context: context!)
return Int64(meshPacket.id)
}
@ -1222,8 +1219,6 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
meshPacket.priority = MeshPacket.Priority.reliable
meshPacket.wantAck = true
meshPacket.hopLimit = 0
var dataMessage = DataMessage()
dataMessage.payload = try! adminPacket.serializedData()
dataMessage.portnum = PortNum.adminApp
@ -1233,7 +1228,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
let messageDescription = "🛟 Saved Position Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
upsertPositionConfigPacket(config: config, nodeNum: fromUser.num, context: context!)
upsertPositionConfigPacket(config: config, nodeNum: toUser.num, context: context!)
return Int64(meshPacket.id)
}
@ -1252,8 +1247,6 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
meshPacket.priority = MeshPacket.Priority.reliable
meshPacket.wantAck = true
meshPacket.hopLimit = 0
var dataMessage = DataMessage()
dataMessage.payload = try! adminPacket.serializedData()
dataMessage.portnum = PortNum.adminApp
@ -1263,7 +1256,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
let messageDescription = "🛟 Saved Network Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
upsertNetworkConfigPacket(config: config, nodeNum: fromUser.num, context: context!)
upsertNetworkConfigPacket(config: config, nodeNum: toUser.num, context: context!)
return Int64(meshPacket.id)
}
@ -1282,17 +1275,15 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
meshPacket.priority = MeshPacket.Priority.reliable
meshPacket.wantAck = true
var dataMessage = DataMessage()
dataMessage.payload = try! adminPacket.serializedData()
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Canned Message Module Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
upsertCannedMessagesModuleConfigPacket(config: config, nodeNum: fromUser.num, context: context!)
upsertCannedMessagesModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
return Int64(meshPacket.id)
}
@ -1311,12 +1302,10 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
meshPacket.priority = MeshPacket.Priority.reliable
meshPacket.wantAck = true
var dataMessage = DataMessage()
dataMessage.payload = try! adminPacket.serializedData()
dataMessage.portnum = PortNum.adminApp
dataMessage.wantResponse = true
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Canned Message Module Messages for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
@ -1349,7 +1338,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
let messageDescription = "Saved External Notification Module Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
upsertExternalNotificationModuleConfigPacket(config: config, nodeNum: fromUser.num, context: context!)
upsertExternalNotificationModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
return Int64(meshPacket.id)
}
return 0
@ -1367,7 +1356,6 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
meshPacket.channel = UInt32(adminIndex)
meshPacket.priority = MeshPacket.Priority.reliable
meshPacket.wantAck = true
meshPacket.hopLimit = 0
var dataMessage = DataMessage()
dataMessage.payload = try! adminPacket.serializedData()
@ -1377,7 +1365,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
let messageDescription = "Saved WiFi Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
upsertMqttModuleConfigPacket(config: config, nodeNum: fromUser.num, context: context!)
upsertMqttModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
return Int64(meshPacket.id)
}
return 0
@ -1395,17 +1383,15 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
meshPacket.channel = UInt32(adminIndex)
meshPacket.priority = MeshPacket.Priority.reliable
meshPacket.wantAck = true
var dataMessage = DataMessage()
dataMessage.payload = try! adminPacket.serializedData()
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
let messageDescription = "Saved Range Test Module Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
upsertRangeTestModuleConfigPacket(config: config, nodeNum: fromUser.num, context: context!)
upsertRangeTestModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
return Int64(meshPacket.id)
}
@ -1424,7 +1410,6 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
meshPacket.channel = UInt32(adminIndex)
meshPacket.priority = MeshPacket.Priority.reliable
meshPacket.wantAck = true
meshPacket.hopLimit = 0
var dataMessage = DataMessage()
dataMessage.payload = try! adminPacket.serializedData()
@ -1433,7 +1418,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
let messageDescription = "Saved Serial Module Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
upsertSerialModuleConfigPacket(config: config, nodeNum: fromUser.num, context: context!)
upsertSerialModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
return Int64(meshPacket.id)
}
return 0
@ -1459,7 +1444,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
let messageDescription = "Saved Telemetry Module Config for \(toUser.longName ?? NSLocalizedString("unknown", comment: "Unknown"))"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
upsertTelemetryModuleConfigPacket(config: config, nodeNum: fromUser.num, context: context!)
upsertTelemetryModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
return Int64(meshPacket.id)
}
return 0
@ -1891,6 +1876,28 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
}
return false
}
public func tryClearExistingChannels() {
// Before we get started delete the existing channels from the myNodeInfo
let fetchMyInfoRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "MyInfoEntity")
fetchMyInfoRequest.predicate = NSPredicate(format: "myNodeNum == %lld", Int64(connectedPeripheral.num))
do {
let fetchedMyInfo = try context?.fetch(fetchMyInfoRequest) as? [MyInfoEntity] ?? []
if fetchedMyInfo.count == 1 {
let mutableChannels = fetchedMyInfo[0].channels?.mutableCopy() as? NSMutableOrderedSet
mutableChannels?.removeAllObjects()
fetchedMyInfo[0].channels = mutableChannels
do {
try context!.save()
} catch {
print("Failed to clear existing channels from local app database")
}
}
} catch {
print("Failed to find a node MyInfo to save these channels to")
}
}
}
// MARK: - CB Central Manager implmentation

View file

@ -13,13 +13,11 @@ import ActivityKit
#endif
func generateMessageMarkdown (message: String) -> String {
let types: NSTextCheckingResult.CheckingType = [.address, .link, .phoneNumber]
let detector = try! NSDataDetector(types: types.rawValue)
let matches = detector.matches(in: message, options: [], range: NSRange(location: 0, length: message.utf16.count))
var messageWithMarkdown = message
if matches.count > 0 {
for match in matches {
guard let range = Range(match.range, in: message) else { continue }
if match.resultType == .address {
@ -40,7 +38,6 @@ func generateMessageMarkdown (message: String) -> String {
}
func localConfig (config: Config, context: NSManagedObjectContext, nodeNum: Int64, nodeLongName: String) {
// 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.bluetooth, nodeNum: nodeNum, context: context)
@ -342,7 +339,9 @@ func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObje
newTelemetry.voltage = nodeInfo.deviceMetrics.voltage
newTelemetry.channelUtilization = nodeInfo.deviceMetrics.channelUtilization
newTelemetry.airUtilTx = nodeInfo.deviceMetrics.airUtilTx
let mutableTelemetries = fetchedNode[0].telemetries!.mutableCopy() as! NSMutableOrderedSet
guard let mutableTelemetries = fetchedNode[0].telemetries!.mutableCopy() as? NSMutableOrderedSet else {
return nil
}
fetchedNode[0].telemetries = mutableTelemetries.copy() as? NSOrderedSet
}
@ -356,7 +355,9 @@ func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObje
position.altitude = nodeInfo.position.altitude
position.satsInView = Int32(nodeInfo.position.satsInView)
position.time = Date(timeIntervalSince1970: TimeInterval(Int64(nodeInfo.position.time)))
let mutablePositions = fetchedNode[0].positions!.mutableCopy() as! NSMutableOrderedSet
guard let mutablePositions = fetchedNode[0].positions!.mutableCopy() as? NSMutableOrderedSet else {
return nil
}
fetchedNode[0].positions = mutablePositions.copy() as? NSOrderedSet
}
@ -392,63 +393,6 @@ func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObje
return nil
}
func nodeInfoAppPacket (packet: MeshPacket, context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.nodeinfo.received %@", comment: "Node info received for: %@"), String(packet.from))
MeshLogger.log("📟 \(logString)")
guard packet.from > 0 else { return }
let fetchNodeInfoAppRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "NodeInfoEntity")
fetchNodeInfoAppRequest.predicate = NSPredicate(format: "num == %lld", Int64(packet.from))
do {
let fetchedNode = try context.fetch(fetchNodeInfoAppRequest) as? [NodeInfoEntity] ?? []
if fetchedNode.count == 1 {
fetchedNode[0].id = Int64(packet.from)
fetchedNode[0].num = Int64(packet.from)
fetchedNode[0].lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(packet.rxTime)))
fetchedNode[0].snr = packet.rxSnr
fetchedNode[0].channel = Int32(packet.channel)
if let nodeInfoMessage = try? NodeInfo(serializedData: packet.decoded.payload) {
if nodeInfoMessage.hasDeviceMetrics {
let telemetry = TelemetryEntity(context: context)
telemetry.batteryLevel = Int32(nodeInfoMessage.deviceMetrics.batteryLevel)
telemetry.voltage = nodeInfoMessage.deviceMetrics.voltage
telemetry.channelUtilization = nodeInfoMessage.deviceMetrics.channelUtilization
telemetry.airUtilTx = nodeInfoMessage.deviceMetrics.airUtilTx
var newTelemetries = [TelemetryEntity]()
newTelemetries.append(telemetry)
fetchedNode[0].telemetries? = NSOrderedSet(array: newTelemetries)
}
if nodeInfoMessage.hasUser {
fetchedNode[0].user!.userId = nodeInfoMessage.user.id
fetchedNode[0].user!.num = Int64(nodeInfoMessage.num)
fetchedNode[0].user!.longName = nodeInfoMessage.user.longName
fetchedNode[0].user!.shortName = nodeInfoMessage.user.shortName
fetchedNode[0].user!.macaddr = nodeInfoMessage.user.macaddr
fetchedNode[0].user!.hwModel = String(describing: nodeInfoMessage.user.hwModel).uppercased()
}
}
do {
try context.save()
print("💾 Updated NodeInfo from Node Info App Packet For: \(fetchedNode[0].num)")
} catch {
context.rollback()
let nsError = error as NSError
print("💥 Error Saving NodeInfoEntity from NODEINFO_APP \(nsError)")
}
} else {
// New node info not from device but potentially from another network
}
} catch {
print("💥 Error Fetching NodeInfoEntity for NODEINFO_APP")
}
}
func adminAppPacket (packet: MeshPacket, context: NSManagedObjectContext) {
if let adminMessage = try? AdminMessage(serializedData: packet.decoded.payload) {
@ -617,7 +561,7 @@ func routingPacket (packet: MeshPacket, connectedNodeNum: Int64, context: NSMana
let fetchedMyInfo = try context.fetch(fetchMyInfoRequest) as? [MyInfoEntity]
if fetchedMyInfo?.count ?? 0 > 0 {
for ch in fetchedMyInfo![0].channels!.array as! [ChannelEntity] {
for ch in fetchedMyInfo![0].channels!.array as? [ChannelEntity] ?? [] {
if ch.index == packet.channel {
ch.objectWillChange.send()
@ -685,7 +629,9 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage
telemetry.metricsType = 1
}
telemetry.time = Date(timeIntervalSince1970: TimeInterval(Int64(telemetryMessage.time)))
let mutableTelemetries = fetchedNode[0].telemetries!.mutableCopy() as! NSMutableOrderedSet
guard let mutableTelemetries = fetchedNode[0].telemetries!.mutableCopy() as? NSMutableOrderedSet else {
return
}
mutableTelemetries.add(telemetry)
fetchedNode[0].lastHeard = telemetry.time
fetchedNode[0].telemetries = mutableTelemetries.copy() as? NSOrderedSet
@ -716,7 +662,7 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage
}
}
// Update our live activity if there is one running, not available on mac iOS >= 16.2
#if !targetEnvironment(macCatalyst)
#if !targetEnvironment(macCatalyst)
if #available(iOS 16.2, *) {
let oneMinuteLater = Calendar.current.date(byAdding: .minute, value: (Int(1) ), to: Date())!
@ -734,7 +680,7 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage
}
}
}
#endif
#endif
}
} catch {
context.rollback()

View file

@ -97,6 +97,79 @@ public func clearCoreDataDatabase(context: NSManagedObjectContext) {
}
}
func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.nodeinfo.received %@", comment: "Node info received for: %@"), String(packet.from))
MeshLogger.log("📟 \(logString)")
guard packet.from > 0 else { return }
let fetchNodeInfoAppRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "NodeInfoEntity")
fetchNodeInfoAppRequest.predicate = NSPredicate(format: "num == %lld", Int64(packet.from))
do {
let fetchedNode = try context.fetch(fetchNodeInfoAppRequest) as? [NodeInfoEntity] ?? []
if fetchedNode.count == 0 {
// Not Found Insert
let newNode = NodeInfoEntity(context: context)
newNode.id = Int64(packet.from)
newNode.num = Int64(packet.from)
newNode.lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(packet.rxTime)))
newNode.snr = packet.rxSnr
newNode.channel = Int32(packet.channel)
if let newUserMessage = try? User(serializedData: packet.decoded.payload) {
let newUser = UserEntity(context: context)
newUser.userId = newUserMessage.id
newUser.num = Int64(packet.from)
newUser.longName = newUserMessage.longName
newUser.shortName = newUserMessage.shortName
newUser.macaddr = newUserMessage.macaddr
newUser.hwModel = String(describing: newUserMessage.hwModel).uppercased()
newNode.user = newUser
}
} else {
// Update an existing node
fetchedNode[0].id = Int64(packet.from)
fetchedNode[0].num = Int64(packet.from)
fetchedNode[0].lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(packet.rxTime)))
fetchedNode[0].snr = packet.rxSnr
fetchedNode[0].channel = Int32(packet.channel)
if let nodeInfoMessage = try? NodeInfo(serializedData: packet.decoded.payload) {
if nodeInfoMessage.hasDeviceMetrics {
let telemetry = TelemetryEntity(context: context)
telemetry.batteryLevel = Int32(nodeInfoMessage.deviceMetrics.batteryLevel)
telemetry.voltage = nodeInfoMessage.deviceMetrics.voltage
telemetry.channelUtilization = nodeInfoMessage.deviceMetrics.channelUtilization
telemetry.airUtilTx = nodeInfoMessage.deviceMetrics.airUtilTx
var newTelemetries = [TelemetryEntity]()
newTelemetries.append(telemetry)
fetchedNode[0].telemetries? = NSOrderedSet(array: newTelemetries)
}
if nodeInfoMessage.hasUser {
fetchedNode[0].user!.userId = nodeInfoMessage.user.id
fetchedNode[0].user!.num = Int64(nodeInfoMessage.num)
fetchedNode[0].user!.longName = nodeInfoMessage.user.longName
fetchedNode[0].user!.shortName = nodeInfoMessage.user.shortName
fetchedNode[0].user!.macaddr = nodeInfoMessage.user.macaddr
fetchedNode[0].user!.hwModel = String(describing: nodeInfoMessage.user.hwModel).uppercased()
}
}
do {
try context.save()
print("💾 Updated NodeInfo from Node Info App Packet For: \(fetchedNode[0].num)")
} catch {
context.rollback()
let nsError = error as NSError
print("💥 Error Saving NodeInfoEntity from NODEINFO_APP \(nsError)")
}
}
} catch {
print("💥 Error Fetching NodeInfoEntity for NODEINFO_APP")
}
}
func upsertPositionPacket (packet: MeshPacket, context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat(NSLocalizedString("mesh.log.position.received %@", comment: "Position Packet received from node: %@"), String(packet.from))
@ -119,7 +192,7 @@ func upsertPositionPacket (packet: MeshPacket, context: NSManagedObjectContext)
// Unset the current latest position for this node
let fetchCurrentLatestPositionsRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "PositionEntity")
fetchCurrentLatestPositionsRequest.predicate = NSPredicate(format: "nodePosition.num == %lld && latest = true", Int64(packet.from))
guard let fetchedPositions = try context.fetch(fetchCurrentLatestPositionsRequest) as? [PositionEntity] else {
return
}
@ -164,8 +237,13 @@ func upsertPositionPacket (packet: MeshPacket, context: NSManagedObjectContext)
}
}
} else {
print("💥 Empty POSITION_APP Packet")
print((try? packet.jsonString()) ?? "JSON Decode Failure")
if (try? NodeInfo(serializedData: packet.decoded.payload)) != nil {
upsertNodeInfoPacket(packet: packet, context: context)
} else {
print("💥 Empty POSITION_APP Packet")
print((try? packet.jsonString()) ?? "JSON Decode Failure")
}
}
}
} catch {
@ -355,6 +433,7 @@ func upsertLoRaConfigPacket(config: Meshtastic.Config.LoRaConfig, nodeNum: Int64
newLoRaConfig.txPower = Int32(config.txPower)
newLoRaConfig.txEnabled = config.txEnabled
newLoRaConfig.channelNum = Int32(config.channelNum)
newLoRaConfig.sx126xRxBoostedGain = config.sx126XRxBoostedGain
fetchedNode[0].loRaConfig = newLoRaConfig
} else {
fetchedNode[0].loRaConfig?.regionCode = Int32(config.region.rawValue)
@ -370,6 +449,7 @@ func upsertLoRaConfigPacket(config: Meshtastic.Config.LoRaConfig, nodeNum: Int64
fetchedNode[0].loRaConfig?.txPower = Int32(config.txPower)
fetchedNode[0].loRaConfig?.txEnabled = config.txEnabled
fetchedNode[0].loRaConfig?.channelNum = Int32(config.channelNum)
fetchedNode[0].loRaConfig?.sx126xRxBoostedGain = config.sx126XRxBoostedGain
}
do {
try context.save()

View file

@ -15,7 +15,7 @@ import SwiftProtobuf
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
typealias Version = _2
}
@ -31,7 +31,7 @@ struct AdminMessage {
///
/// TODO: REPLACE
var payloadVariant: AdminMessage.OneOf_PayloadVariant?
var payloadVariant: AdminMessage.OneOf_PayloadVariant? = nil
///
/// Send the specified channel in the response to this message
@ -301,7 +301,7 @@ struct AdminMessage {
}
///
/// This message is only supported for the simulator porduino build.
/// This message is only supported for the simulator Portduino build.
/// If received the simulator will exit successfully.
var exitSimulator: Bool {
get {
@ -442,7 +442,7 @@ struct AdminMessage {
/// Only Implemented for ESP32 Devices. This needs to be issued to send a new main firmware via bluetooth.
case rebootOtaSeconds(Int32)
///
/// This message is only supported for the simulator porduino build.
/// This message is only supported for the simulator Portduino build.
/// If received the simulator will exit successfully.
case exitSimulator(Bool)
///
@ -752,7 +752,7 @@ extension AdminMessage.ConfigType: CaseIterable {
.networkConfig,
.displayConfig,
.loraConfig,
.bluetoothConfig
.bluetoothConfig,
]
}
@ -767,7 +767,7 @@ extension AdminMessage.ModuleConfigType: CaseIterable {
.telemetryConfig,
.cannedmsgConfig,
.audioConfig,
.remotehardwareConfig
.remotehardwareConfig,
]
}
@ -813,7 +813,7 @@ extension HamParameters: @unchecked Sendable {}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
private let _protobuf_package = "meshtastic"
fileprivate let _protobuf_package = "meshtastic"
extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".AdminMessage"
@ -848,7 +848,7 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
97: .standard(proto: "reboot_seconds"),
98: .standard(proto: "shutdown_seconds"),
99: .standard(proto: "factory_reset"),
100: .standard(proto: "nodedb_reset")
100: .standard(proto: "nodedb_reset"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -1315,7 +1315,7 @@ extension AdminMessage.ConfigType: SwiftProtobuf._ProtoNameProviding {
3: .same(proto: "NETWORK_CONFIG"),
4: .same(proto: "DISPLAY_CONFIG"),
5: .same(proto: "LORA_CONFIG"),
6: .same(proto: "BLUETOOTH_CONFIG")
6: .same(proto: "BLUETOOTH_CONFIG"),
]
}
@ -1329,7 +1329,7 @@ extension AdminMessage.ModuleConfigType: SwiftProtobuf._ProtoNameProviding {
5: .same(proto: "TELEMETRY_CONFIG"),
6: .same(proto: "CANNEDMSG_CONFIG"),
7: .same(proto: "AUDIO_CONFIG"),
8: .same(proto: "REMOTEHARDWARE_CONFIG")
8: .same(proto: "REMOTEHARDWARE_CONFIG"),
]
}
@ -1339,7 +1339,7 @@ extension HamParameters: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa
1: .standard(proto: "call_sign"),
2: .standard(proto: "tx_power"),
3: .same(proto: "frequency"),
4: .standard(proto: "short_name")
4: .standard(proto: "short_name"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {

View file

@ -15,7 +15,7 @@ import SwiftProtobuf
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
typealias Version = _2
}
@ -50,7 +50,7 @@ struct ChannelSet {
init() {}
fileprivate var _loraConfig: Config.LoRaConfig?
fileprivate var _loraConfig: Config.LoRaConfig? = nil
}
#if swift(>=5.5) && canImport(_Concurrency)
@ -59,13 +59,13 @@ extension ChannelSet: @unchecked Sendable {}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
private let _protobuf_package = "meshtastic"
fileprivate let _protobuf_package = "meshtastic"
extension ChannelSet: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".ChannelSet"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "settings"),
2: .standard(proto: "lora_config")
2: .standard(proto: "lora_config"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {

View file

@ -15,7 +15,7 @@ import SwiftProtobuf
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
typealias Version = _2
}
@ -42,12 +42,12 @@ extension CannedMessageModuleConfig: @unchecked Sendable {}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
private let _protobuf_package = "meshtastic"
fileprivate let _protobuf_package = "meshtastic"
extension CannedMessageModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".CannedMessageModuleConfig"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "messages")
1: .same(proto: "messages"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {

View file

@ -15,7 +15,7 @@ import SwiftProtobuf
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
typealias Version = _2
}
@ -183,7 +183,7 @@ struct Channel {
init() {}
fileprivate var _settings: ChannelSettings?
fileprivate var _settings: ChannelSettings? = nil
}
#if swift(>=4.2)
@ -193,7 +193,7 @@ extension Channel.Role: CaseIterable {
static var allCases: [Channel.Role] = [
.disabled,
.primary,
.secondary
.secondary,
]
}
@ -207,7 +207,7 @@ extension Channel.Role: @unchecked Sendable {}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
private let _protobuf_package = "meshtastic"
fileprivate let _protobuf_package = "meshtastic"
extension ChannelSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".ChannelSettings"
@ -217,7 +217,7 @@ extension ChannelSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen
3: .same(proto: "name"),
4: .same(proto: "id"),
5: .standard(proto: "uplink_enabled"),
6: .standard(proto: "downlink_enabled")
6: .standard(proto: "downlink_enabled"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -276,7 +276,7 @@ extension Channel: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "index"),
2: .same(proto: "settings"),
3: .same(proto: "role")
3: .same(proto: "role"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -323,6 +323,6 @@ extension Channel.Role: SwiftProtobuf._ProtoNameProviding {
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
0: .same(proto: "DISABLED"),
1: .same(proto: "PRIMARY"),
2: .same(proto: "SECONDARY")
2: .same(proto: "SECONDARY"),
]
}

View file

@ -15,7 +15,7 @@ import SwiftProtobuf
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
typealias Version = _2
}
@ -27,7 +27,7 @@ struct Config {
///
/// Payload Variant
var payloadVariant: Config.OneOf_PayloadVariant?
var payloadVariant: Config.OneOf_PayloadVariant? = nil
var device: Config.DeviceConfig {
get {
@ -632,7 +632,7 @@ struct Config {
init() {}
fileprivate var _ipv4Config: Config.NetworkConfig.IpV4Config?
fileprivate var _ipv4Config: Config.NetworkConfig.IpV4Config? = nil
}
///
@ -891,7 +891,7 @@ struct Config {
// methods supported on all messages.
///
/// When enabled, the `modem_preset` fields will be adheared to, else the `bandwidth`/`spread_factor`/`coding_rate`
/// When enabled, the `modem_preset` fields will be adhered to, else the `bandwidth`/`spread_factor`/`coding_rate`
/// will be taked from their respective manually defined fields
var usePreset: Bool = false
@ -940,14 +940,14 @@ struct Config {
var txEnabled: Bool = false
///
/// If zero then, use default max legal continuous power (ie. something that won't
/// If zero, then use default max legal continuous power (ie. something that won't
/// burn out the radio hardware)
/// In most cases you should use zero here.
/// Units are in dBm.
var txPower: Int32 = 0
///
/// This is controlling the actual hardware frequency the radio is transmitting on.
/// This controls the actual hardware frequency the radio transmits on.
/// Most users should never need to be exposed to this field/concept.
/// A channel number between 1 and NUM_CHANNELS (whatever the max is in the current region).
/// If ZERO then the rule is "use the old channel name hash based
@ -977,7 +977,7 @@ struct Config {
///
/// 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
/// in ignore_incoming will have packets they send droped on receive (by router.cpp)
/// in ignore_incoming will have packets they send dropped on receive (by router.cpp)
var ignoreIncoming: [UInt32] = []
var unknownFields = SwiftProtobuf.UnknownStorage()
@ -998,7 +998,7 @@ struct Config {
case eu433 // = 2
///
/// European Union 433mhz
/// European Union 868mhz
case eu868 // = 3
///
@ -1190,7 +1190,7 @@ struct Config {
var mode: Config.BluetoothConfig.PairingMode = .randomPin
///
/// Specified pin for PairingMode.FixedPin
/// Specified PIN for PairingMode.FixedPin
var fixedPin: UInt32 = 0
var unknownFields = SwiftProtobuf.UnknownStorage()
@ -1199,15 +1199,15 @@ struct Config {
typealias RawValue = Int
///
/// Device generates a random pin that will be shown on the screen of the device for pairing
/// Device generates a random PIN that will be shown on the screen of the device for pairing
case randomPin // = 0
///
/// Device requires a specified fixed pin for pairing
/// Device requires a specified fixed PIN for pairing
case fixedPin // = 1
///
/// Device requires no pin for pairing
/// Device requires no PIN for pairing
case noPin // = 2
case UNRECOGNIZED(Int)
@ -1252,7 +1252,7 @@ extension Config.DeviceConfig.Role: CaseIterable {
.routerClient,
.repeater,
.tracker,
.sensor
.sensor,
]
}
@ -1261,7 +1261,7 @@ extension Config.DeviceConfig.RebroadcastMode: CaseIterable {
static var allCases: [Config.DeviceConfig.RebroadcastMode] = [
.all,
.allSkipDecoding,
.localOnly
.localOnly,
]
}
@ -1278,7 +1278,7 @@ extension Config.PositionConfig.PositionFlags: CaseIterable {
.seqNo,
.timestamp,
.heading,
.speed
.speed,
]
}
@ -1286,7 +1286,7 @@ extension Config.NetworkConfig.AddressMode: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
static var allCases: [Config.NetworkConfig.AddressMode] = [
.dhcp,
.static
.static,
]
}
@ -1298,7 +1298,7 @@ extension Config.DisplayConfig.GpsCoordinateFormat: CaseIterable {
.utm,
.mgrs,
.olc,
.osgr
.osgr,
]
}
@ -1306,7 +1306,7 @@ extension Config.DisplayConfig.DisplayUnits: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
static var allCases: [Config.DisplayConfig.DisplayUnits] = [
.metric,
.imperial
.imperial,
]
}
@ -1316,7 +1316,7 @@ extension Config.DisplayConfig.OledType: CaseIterable {
.oledAuto,
.oledSsd1306,
.oledSh1106,
.oledSh1107
.oledSh1107,
]
}
@ -1326,7 +1326,7 @@ extension Config.DisplayConfig.DisplayMode: CaseIterable {
.default,
.twocolor,
.inverted,
.color
.color,
]
}
@ -1348,7 +1348,7 @@ extension Config.LoRaConfig.RegionCode: CaseIterable {
.th,
.lora24,
.ua433,
.ua868
.ua868,
]
}
@ -1362,7 +1362,7 @@ extension Config.LoRaConfig.ModemPreset: CaseIterable {
.mediumFast,
.shortSlow,
.shortFast,
.longModerate
.longModerate,
]
}
@ -1371,7 +1371,7 @@ extension Config.BluetoothConfig.PairingMode: CaseIterable {
static var allCases: [Config.BluetoothConfig.PairingMode] = [
.randomPin,
.fixedPin,
.noPin
.noPin,
]
}
@ -1403,7 +1403,7 @@ extension Config.BluetoothConfig.PairingMode: @unchecked Sendable {}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
private let _protobuf_package = "meshtastic"
fileprivate let _protobuf_package = "meshtastic"
extension Config: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".Config"
@ -1414,7 +1414,7 @@ extension Config: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBas
4: .same(proto: "network"),
5: .same(proto: "display"),
6: .same(proto: "lora"),
7: .same(proto: "bluetooth")
7: .same(proto: "bluetooth"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -1574,7 +1574,7 @@ extension Config.DeviceConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImpl
4: .standard(proto: "button_gpio"),
5: .standard(proto: "buzzer_gpio"),
6: .standard(proto: "rebroadcast_mode"),
7: .standard(proto: "node_info_broadcast_secs")
7: .standard(proto: "node_info_broadcast_secs"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -1641,7 +1641,7 @@ extension Config.DeviceConfig.Role: SwiftProtobuf._ProtoNameProviding {
3: .same(proto: "ROUTER_CLIENT"),
4: .same(proto: "REPEATER"),
5: .same(proto: "TRACKER"),
6: .same(proto: "SENSOR")
6: .same(proto: "SENSOR"),
]
}
@ -1649,7 +1649,7 @@ 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")
2: .same(proto: "LOCAL_ONLY"),
]
}
@ -1664,7 +1664,7 @@ extension Config.PositionConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageIm
6: .standard(proto: "gps_attempt_time"),
7: .standard(proto: "position_flags"),
8: .standard(proto: "rx_gpio"),
9: .standard(proto: "tx_gpio")
9: .standard(proto: "tx_gpio"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -1745,7 +1745,7 @@ extension Config.PositionConfig.PositionFlags: SwiftProtobuf._ProtoNameProviding
64: .same(proto: "SEQ_NO"),
128: .same(proto: "TIMESTAMP"),
256: .same(proto: "HEADING"),
512: .same(proto: "SPEED")
512: .same(proto: "SPEED"),
]
}
@ -1759,7 +1759,7 @@ extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImple
5: .standard(proto: "mesh_sds_timeout_secs"),
6: .standard(proto: "sds_secs"),
7: .standard(proto: "ls_secs"),
8: .standard(proto: "min_wake_secs")
8: .standard(proto: "min_wake_secs"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -1833,7 +1833,7 @@ extension Config.NetworkConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImp
6: .standard(proto: "eth_enabled"),
7: .standard(proto: "address_mode"),
8: .standard(proto: "ipv4_config"),
9: .standard(proto: "rsyslog_server")
9: .standard(proto: "rsyslog_server"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -1904,7 +1904,7 @@ extension Config.NetworkConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImp
extension Config.NetworkConfig.AddressMode: SwiftProtobuf._ProtoNameProviding {
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
0: .same(proto: "DHCP"),
1: .same(proto: "STATIC")
1: .same(proto: "STATIC"),
]
}
@ -1914,7 +1914,7 @@ extension Config.NetworkConfig.IpV4Config: SwiftProtobuf.Message, SwiftProtobuf.
1: .same(proto: "ip"),
2: .same(proto: "gateway"),
3: .same(proto: "subnet"),
4: .same(proto: "dns")
4: .same(proto: "dns"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -1969,7 +1969,7 @@ extension Config.DisplayConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImp
6: .same(proto: "units"),
7: .same(proto: "oled"),
8: .same(proto: "displaymode"),
9: .standard(proto: "heading_bold")
9: .standard(proto: "heading_bold"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -2045,14 +2045,14 @@ extension Config.DisplayConfig.GpsCoordinateFormat: SwiftProtobuf._ProtoNameProv
2: .same(proto: "UTM"),
3: .same(proto: "MGRS"),
4: .same(proto: "OLC"),
5: .same(proto: "OSGR")
5: .same(proto: "OSGR"),
]
}
extension Config.DisplayConfig.DisplayUnits: SwiftProtobuf._ProtoNameProviding {
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
0: .same(proto: "METRIC"),
1: .same(proto: "IMPERIAL")
1: .same(proto: "IMPERIAL"),
]
}
@ -2061,7 +2061,7 @@ extension Config.DisplayConfig.OledType: SwiftProtobuf._ProtoNameProviding {
0: .same(proto: "OLED_AUTO"),
1: .same(proto: "OLED_SSD1306"),
2: .same(proto: "OLED_SH1106"),
3: .same(proto: "OLED_SH1107")
3: .same(proto: "OLED_SH1107"),
]
}
@ -2070,7 +2070,7 @@ extension Config.DisplayConfig.DisplayMode: SwiftProtobuf._ProtoNameProviding {
0: .same(proto: "DEFAULT"),
1: .same(proto: "TWOCOLOR"),
2: .same(proto: "INVERTED"),
3: .same(proto: "COLOR")
3: .same(proto: "COLOR"),
]
}
@ -2091,7 +2091,7 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem
12: .standard(proto: "override_duty_cycle"),
13: .standard(proto: "sx126x_rx_boosted_gain"),
14: .standard(proto: "override_frequency"),
103: .standard(proto: "ignore_incoming")
103: .standard(proto: "ignore_incoming"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -2207,7 +2207,7 @@ extension Config.LoRaConfig.RegionCode: SwiftProtobuf._ProtoNameProviding {
12: .same(proto: "TH"),
13: .same(proto: "LORA_24"),
14: .same(proto: "UA_433"),
15: .same(proto: "UA_868")
15: .same(proto: "UA_868"),
]
}
@ -2220,7 +2220,7 @@ extension Config.LoRaConfig.ModemPreset: SwiftProtobuf._ProtoNameProviding {
4: .same(proto: "MEDIUM_FAST"),
5: .same(proto: "SHORT_SLOW"),
6: .same(proto: "SHORT_FAST"),
7: .same(proto: "LONG_MODERATE")
7: .same(proto: "LONG_MODERATE"),
]
}
@ -2229,7 +2229,7 @@ extension Config.BluetoothConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageI
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "enabled"),
2: .same(proto: "mode"),
3: .standard(proto: "fixed_pin")
3: .standard(proto: "fixed_pin"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -2272,6 +2272,6 @@ extension Config.BluetoothConfig.PairingMode: SwiftProtobuf._ProtoNameProviding
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
0: .same(proto: "RANDOM_PIN"),
1: .same(proto: "FIXED_PIN"),
2: .same(proto: "NO_PIN")
2: .same(proto: "NO_PIN"),
]
}

View file

@ -15,7 +15,7 @@ import SwiftProtobuf
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
typealias Version = _2
}
@ -73,10 +73,10 @@ struct DeviceConnectionStatus {
init() {}
fileprivate var _wifi: WifiConnectionStatus?
fileprivate var _ethernet: EthernetConnectionStatus?
fileprivate var _bluetooth: BluetoothConnectionStatus?
fileprivate var _serial: SerialConnectionStatus?
fileprivate var _wifi: WifiConnectionStatus? = nil
fileprivate var _ethernet: EthernetConnectionStatus? = nil
fileprivate var _bluetooth: BluetoothConnectionStatus? = nil
fileprivate var _serial: SerialConnectionStatus? = nil
}
///
@ -98,18 +98,18 @@ struct WifiConnectionStatus {
mutating func clearStatus() {self._status = nil}
///
/// WiFi access point ssid
/// WiFi access point SSID
var ssid: String = String()
///
/// Rssi of wireless connection
/// RSSI of wireless connection
var rssi: Int32 = 0
var unknownFields = SwiftProtobuf.UnknownStorage()
init() {}
fileprivate var _status: NetworkConnectionStatus?
fileprivate var _status: NetworkConnectionStatus? = nil
}
///
@ -134,7 +134,7 @@ struct EthernetConnectionStatus {
init() {}
fileprivate var _status: NetworkConnectionStatus?
fileprivate var _status: NetworkConnectionStatus? = nil
}
///
@ -173,11 +173,11 @@ struct BluetoothConnectionStatus {
// methods supported on all messages.
///
/// The pairing pin for bluetooth
/// The pairing PIN for bluetooth
var pin: UInt32 = 0
///
/// Rssi of bluetooth connection
/// RSSI of bluetooth connection
var rssi: Int32 = 0
///
@ -197,7 +197,7 @@ struct SerialConnectionStatus {
// methods supported on all messages.
///
/// The serial baud rate
/// Serial baud rate
var baud: UInt32 = 0
///
@ -220,7 +220,7 @@ extension SerialConnectionStatus: @unchecked Sendable {}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
private let _protobuf_package = "meshtastic"
fileprivate let _protobuf_package = "meshtastic"
extension DeviceConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".DeviceConnectionStatus"
@ -228,7 +228,7 @@ extension DeviceConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageI
1: .same(proto: "wifi"),
2: .same(proto: "ethernet"),
3: .same(proto: "bluetooth"),
4: .same(proto: "serial")
4: .same(proto: "serial"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -281,7 +281,7 @@ extension WifiConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImp
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "status"),
2: .same(proto: "ssid"),
3: .same(proto: "rssi")
3: .same(proto: "rssi"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -327,7 +327,7 @@ extension WifiConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImp
extension EthernetConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".EthernetConnectionStatus"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "status")
1: .same(proto: "status"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -366,7 +366,7 @@ extension NetworkConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._Message
1: .standard(proto: "ip_address"),
2: .standard(proto: "is_connected"),
3: .standard(proto: "is_mqtt_connected"),
4: .standard(proto: "is_syslog_connected")
4: .standard(proto: "is_syslog_connected"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -415,7 +415,7 @@ extension BluetoothConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._Messa
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "pin"),
2: .same(proto: "rssi"),
3: .standard(proto: "is_connected")
3: .standard(proto: "is_connected"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -458,7 +458,7 @@ extension SerialConnectionStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageI
static let protoMessageName: String = _protobuf_package + ".SerialConnectionStatus"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "baud"),
2: .standard(proto: "is_connected")
2: .standard(proto: "is_connected"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {

View file

@ -15,7 +15,7 @@ import SwiftProtobuf
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
typealias Version = _2
}
@ -69,7 +69,7 @@ extension ScreenFonts: CaseIterable {
static var allCases: [ScreenFonts] = [
.fontSmall,
.fontMedium,
.fontLarge
.fontLarge,
]
}
@ -153,7 +153,7 @@ struct DeviceState {
}
///
/// Some GPSes seem to have bogus settings from the factory, so we always do one factory reset.
/// Some GPS receivers seem to have bogus settings from the factory, so we always do one factory reset.
var didGpsReset: Bool {
get {return _storage._didGpsReset}
set {_uniqueStorage()._didGpsReset = newValue}
@ -190,7 +190,7 @@ struct ChannelFile {
///
/// This can be used for customizing the firmware distribution. If populated,
/// show a secondary bootup screen with cuatom logo and text for 2.5 seconds.
/// show a secondary bootup screen with custom logo and text for 2.5 seconds.
struct OEMStore {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
@ -205,7 +205,7 @@ struct OEMStore {
var oemIconHeight: UInt32 = 0
///
/// The Logo in xbm bytechar format
/// The Logo in XBM bytechar format
var oemIconBits: Data = Data()
///
@ -246,8 +246,8 @@ struct OEMStore {
init() {}
fileprivate var _oemLocalConfig: LocalConfig?
fileprivate var _oemLocalModuleConfig: LocalModuleConfig?
fileprivate var _oemLocalConfig: LocalConfig? = nil
fileprivate var _oemLocalModuleConfig: LocalModuleConfig? = nil
}
#if swift(>=5.5) && canImport(_Concurrency)
@ -259,13 +259,13 @@ extension OEMStore: @unchecked Sendable {}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
private let _protobuf_package = "meshtastic"
fileprivate let _protobuf_package = "meshtastic"
extension ScreenFonts: SwiftProtobuf._ProtoNameProviding {
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
0: .same(proto: "FONT_SMALL"),
1: .same(proto: "FONT_MEDIUM"),
2: .same(proto: "FONT_LARGE")
2: .same(proto: "FONT_LARGE"),
]
}
@ -279,16 +279,16 @@ extension DeviceState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
8: .same(proto: "version"),
7: .standard(proto: "rx_text_message"),
9: .standard(proto: "no_save"),
11: .standard(proto: "did_gps_reset")
11: .standard(proto: "did_gps_reset"),
]
fileprivate class _StorageClass {
var _myNode: MyNodeInfo?
var _owner: User?
var _myNode: MyNodeInfo? = nil
var _owner: User? = nil
var _nodeDb: [NodeInfo] = []
var _receiveQueue: [MeshPacket] = []
var _version: UInt32 = 0
var _rxTextMessage: MeshPacket?
var _rxTextMessage: MeshPacket? = nil
var _noSave: Bool = false
var _didGpsReset: Bool = false
@ -397,7 +397,7 @@ extension ChannelFile: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
static let protoMessageName: String = _protobuf_package + ".ChannelFile"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "channels"),
2: .same(proto: "version")
2: .same(proto: "version"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -441,7 +441,7 @@ extension OEMStore: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
5: .standard(proto: "oem_text"),
6: .standard(proto: "oem_aes_key"),
7: .standard(proto: "oem_local_config"),
8: .standard(proto: "oem_local_module_config")
8: .standard(proto: "oem_local_module_config"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {

View file

@ -15,7 +15,7 @@ import SwiftProtobuf
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
typealias Version = _2
}
@ -245,7 +245,7 @@ extension LocalModuleConfig: @unchecked Sendable {}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
private let _protobuf_package = "meshtastic"
fileprivate let _protobuf_package = "meshtastic"
extension LocalConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".LocalConfig"
@ -257,17 +257,17 @@ extension LocalConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
5: .same(proto: "display"),
6: .same(proto: "lora"),
7: .same(proto: "bluetooth"),
8: .same(proto: "version")
8: .same(proto: "version"),
]
fileprivate class _StorageClass {
var _device: Config.DeviceConfig?
var _position: Config.PositionConfig?
var _power: Config.PowerConfig?
var _network: Config.NetworkConfig?
var _display: Config.DisplayConfig?
var _lora: Config.LoRaConfig?
var _bluetooth: Config.BluetoothConfig?
var _device: Config.DeviceConfig? = nil
var _position: Config.PositionConfig? = nil
var _power: Config.PowerConfig? = nil
var _network: Config.NetworkConfig? = nil
var _display: Config.DisplayConfig? = nil
var _lora: Config.LoRaConfig? = nil
var _bluetooth: Config.BluetoothConfig? = nil
var _version: UInt32 = 0
static let defaultInstance = _StorageClass()
@ -383,19 +383,19 @@ extension LocalModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem
7: .standard(proto: "canned_message"),
9: .same(proto: "audio"),
10: .standard(proto: "remote_hardware"),
8: .same(proto: "version")
8: .same(proto: "version"),
]
fileprivate class _StorageClass {
var _mqtt: ModuleConfig.MQTTConfig?
var _serial: ModuleConfig.SerialConfig?
var _externalNotification: ModuleConfig.ExternalNotificationConfig?
var _storeForward: ModuleConfig.StoreForwardConfig?
var _rangeTest: ModuleConfig.RangeTestConfig?
var _telemetry: ModuleConfig.TelemetryConfig?
var _cannedMessage: ModuleConfig.CannedMessageConfig?
var _audio: ModuleConfig.AudioConfig?
var _remoteHardware: ModuleConfig.RemoteHardwareConfig?
var _mqtt: ModuleConfig.MQTTConfig? = nil
var _serial: ModuleConfig.SerialConfig? = nil
var _externalNotification: ModuleConfig.ExternalNotificationConfig? = nil
var _storeForward: ModuleConfig.StoreForwardConfig? = nil
var _rangeTest: ModuleConfig.RangeTestConfig? = nil
var _telemetry: ModuleConfig.TelemetryConfig? = nil
var _cannedMessage: ModuleConfig.CannedMessageConfig? = nil
var _audio: ModuleConfig.AudioConfig? = nil
var _remoteHardware: ModuleConfig.RemoteHardwareConfig? = nil
var _version: UInt32 = 0
static let defaultInstance = _StorageClass()

View file

@ -15,7 +15,7 @@ import SwiftProtobuf
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
typealias Version = _2
}
@ -302,7 +302,7 @@ extension HardwareModel: CaseIterable {
.heltecWslV3,
.betafpv2400Tx,
.betafpv900NanoTx,
.privateHw
.privateHw,
]
}
@ -353,7 +353,7 @@ extension Constants: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
static var allCases: [Constants] = [
.zero,
.dataPayloadLen
.dataPayloadLen,
]
}
@ -476,7 +476,7 @@ extension CriticalErrorCode: CaseIterable {
.transmitFailed,
.brownout,
.sx1262Failure,
.radioSpiBug
.radioSpiBug,
]
}
@ -781,7 +781,7 @@ extension Position.LocSource: CaseIterable {
.locUnset,
.locManual,
.locInternal,
.locExternal
.locExternal,
]
}
@ -792,7 +792,7 @@ extension Position.AltSource: CaseIterable {
.altManual,
.altInternal,
.altExternal,
.altBarometric
.altBarometric,
]
}
@ -886,7 +886,7 @@ struct Routing {
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
var variant: Routing.OneOf_Variant?
var variant: Routing.OneOf_Variant? = nil
///
/// A route request going from the requester
@ -1075,7 +1075,7 @@ extension Routing.Error: CaseIterable {
.noResponse,
.dutyCycleLimit,
.badRequest,
.notAuthorized
.notAuthorized,
]
}
@ -1503,7 +1503,7 @@ extension MeshPacket.Priority: CaseIterable {
.default,
.reliable,
.ack,
.max
.max,
]
}
@ -1512,7 +1512,7 @@ extension MeshPacket.Delayed: CaseIterable {
static var allCases: [MeshPacket.Delayed] = [
.noDelay,
.broadcast,
.direct
.direct,
]
}
@ -1591,9 +1591,9 @@ struct NodeInfo {
init() {}
fileprivate var _user: User?
fileprivate var _position: Position?
fileprivate var _deviceMetrics: DeviceMetrics?
fileprivate var _user: User? = nil
fileprivate var _position: Position? = nil
fileprivate var _deviceMetrics: DeviceMetrics? = nil
}
///
@ -1796,7 +1796,7 @@ extension LogRecord.Level: CaseIterable {
.warning,
.info,
.debug,
.trace
.trace,
]
}
@ -2102,7 +2102,7 @@ struct ToRadio {
///
/// Log levels, chosen to match python logging conventions.
var payloadVariant: ToRadio.OneOf_PayloadVariant?
var payloadVariant: ToRadio.OneOf_PayloadVariant? = nil
///
/// Send this packet on the mesh
@ -2308,7 +2308,7 @@ extension DeviceMetadata: @unchecked Sendable {}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
private let _protobuf_package = "meshtastic"
fileprivate let _protobuf_package = "meshtastic"
extension HardwareModel: SwiftProtobuf._ProtoNameProviding {
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
@ -2346,14 +2346,14 @@ extension HardwareModel: SwiftProtobuf._ProtoNameProviding {
44: .same(proto: "HELTEC_WSL_V3"),
45: .same(proto: "BETAFPV_2400_TX"),
46: .same(proto: "BETAFPV_900_NANO_TX"),
255: .same(proto: "PRIVATE_HW")
255: .same(proto: "PRIVATE_HW"),
]
}
extension Constants: SwiftProtobuf._ProtoNameProviding {
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
0: .same(proto: "ZERO"),
237: .same(proto: "DATA_PAYLOAD_LEN")
237: .same(proto: "DATA_PAYLOAD_LEN"),
]
}
@ -2370,7 +2370,7 @@ extension CriticalErrorCode: SwiftProtobuf._ProtoNameProviding {
8: .same(proto: "TRANSMIT_FAILED"),
9: .same(proto: "BROWNOUT"),
10: .same(proto: "SX1262_FAILURE"),
11: .same(proto: "RADIO_SPI_BUG")
11: .same(proto: "RADIO_SPI_BUG"),
]
}
@ -2398,7 +2398,7 @@ extension Position: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
19: .standard(proto: "sats_in_view"),
20: .standard(proto: "sensor_id"),
21: .standard(proto: "next_update"),
22: .standard(proto: "seq_number")
22: .standard(proto: "seq_number"),
]
fileprivate class _StorageClass {
@ -2611,7 +2611,7 @@ extension Position.LocSource: SwiftProtobuf._ProtoNameProviding {
0: .same(proto: "LOC_UNSET"),
1: .same(proto: "LOC_MANUAL"),
2: .same(proto: "LOC_INTERNAL"),
3: .same(proto: "LOC_EXTERNAL")
3: .same(proto: "LOC_EXTERNAL"),
]
}
@ -2621,7 +2621,7 @@ extension Position.AltSource: SwiftProtobuf._ProtoNameProviding {
1: .same(proto: "ALT_MANUAL"),
2: .same(proto: "ALT_INTERNAL"),
3: .same(proto: "ALT_EXTERNAL"),
4: .same(proto: "ALT_BAROMETRIC")
4: .same(proto: "ALT_BAROMETRIC"),
]
}
@ -2633,7 +2633,7 @@ extension User: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase,
3: .standard(proto: "short_name"),
4: .same(proto: "macaddr"),
5: .standard(proto: "hw_model"),
6: .standard(proto: "is_licensed")
6: .standard(proto: "is_licensed"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -2690,7 +2690,7 @@ extension User: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase,
extension RouteDiscovery: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".RouteDiscovery"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "route")
1: .same(proto: "route"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -2724,7 +2724,7 @@ extension Routing: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .standard(proto: "route_request"),
2: .standard(proto: "route_reply"),
3: .standard(proto: "error_reason")
3: .standard(proto: "error_reason"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -2815,7 +2815,7 @@ extension Routing.Error: SwiftProtobuf._ProtoNameProviding {
8: .same(proto: "NO_RESPONSE"),
9: .same(proto: "DUTY_CYCLE_LIMIT"),
32: .same(proto: "BAD_REQUEST"),
33: .same(proto: "NOT_AUTHORIZED")
33: .same(proto: "NOT_AUTHORIZED"),
]
}
@ -2829,7 +2829,7 @@ extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
5: .same(proto: "source"),
6: .standard(proto: "request_id"),
7: .standard(proto: "reply_id"),
8: .same(proto: "emoji")
8: .same(proto: "emoji"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -2903,7 +2903,7 @@ extension Waypoint: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
5: .standard(proto: "locked_to"),
6: .same(proto: "name"),
7: .same(proto: "description"),
8: .same(proto: "icon")
8: .same(proto: "icon"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -2982,7 +2982,7 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio
10: .standard(proto: "want_ack"),
11: .same(proto: "priority"),
12: .standard(proto: "rx_rssi"),
13: .same(proto: "delayed")
13: .same(proto: "delayed"),
]
fileprivate class _StorageClass {
@ -3160,7 +3160,7 @@ extension MeshPacket.Priority: SwiftProtobuf._ProtoNameProviding {
64: .same(proto: "DEFAULT"),
70: .same(proto: "RELIABLE"),
120: .same(proto: "ACK"),
127: .same(proto: "MAX")
127: .same(proto: "MAX"),
]
}
@ -3168,7 +3168,7 @@ extension MeshPacket.Delayed: SwiftProtobuf._ProtoNameProviding {
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
0: .same(proto: "NO_DELAY"),
1: .same(proto: "DELAYED_BROADCAST"),
2: .same(proto: "DELAYED_DIRECT")
2: .same(proto: "DELAYED_DIRECT"),
]
}
@ -3180,7 +3180,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB
3: .same(proto: "position"),
4: .same(proto: "snr"),
5: .standard(proto: "last_heard"),
6: .standard(proto: "device_metrics")
6: .standard(proto: "device_metrics"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -3256,7 +3256,7 @@ extension MyNodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio
13: .standard(proto: "air_period_rx"),
14: .standard(proto: "has_wifi"),
15: .standard(proto: "channel_utilization"),
16: .standard(proto: "air_util_tx")
16: .standard(proto: "air_util_tx"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -3366,7 +3366,7 @@ extension LogRecord: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation
1: .same(proto: "message"),
2: .same(proto: "time"),
3: .same(proto: "source"),
4: .same(proto: "level")
4: .same(proto: "level"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -3418,7 +3418,7 @@ extension LogRecord.Level: SwiftProtobuf._ProtoNameProviding {
20: .same(proto: "INFO"),
30: .same(proto: "WARNING"),
40: .same(proto: "ERROR"),
50: .same(proto: "CRITICAL")
50: .same(proto: "CRITICAL"),
]
}
@ -3428,7 +3428,7 @@ extension QueueStatus: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
1: .same(proto: "res"),
2: .same(proto: "free"),
3: .same(proto: "maxlen"),
4: .standard(proto: "mesh_packet_id")
4: .standard(proto: "mesh_packet_id"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -3487,7 +3487,7 @@ extension FromRadio: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation
10: .same(proto: "channel"),
11: .same(proto: "queueStatus"),
12: .same(proto: "xmodemPacket"),
13: .same(proto: "metadata")
13: .same(proto: "metadata"),
]
fileprivate class _StorageClass {
@ -3758,7 +3758,7 @@ extension ToRadio: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBa
1: .same(proto: "packet"),
3: .standard(proto: "want_config_id"),
4: .same(proto: "disconnect"),
5: .same(proto: "xmodemPacket")
5: .same(proto: "xmodemPacket"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -3852,7 +3852,7 @@ extension Compressed: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio
static let protoMessageName: String = _protobuf_package + ".Compressed"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "portnum"),
2: .same(proto: "data")
2: .same(proto: "data"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -3897,7 +3897,7 @@ extension DeviceMetadata: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement
6: .same(proto: "hasEthernet"),
7: .same(proto: "role"),
8: .standard(proto: "position_flags"),
9: .standard(proto: "hw_model")
9: .standard(proto: "hw_model"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {

View file

@ -15,7 +15,7 @@ import SwiftProtobuf
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
typealias Version = _2
}
@ -29,7 +29,7 @@ struct ModuleConfig {
///
/// TODO: REPLACE
var payloadVariant: ModuleConfig.OneOf_PayloadVariant?
var payloadVariant: ModuleConfig.OneOf_PayloadVariant? = nil
///
/// TODO: REPLACE
@ -829,7 +829,7 @@ extension ModuleConfig.AudioConfig.Audio_Baud: CaseIterable {
.codec21300,
.codec21200,
.codec2700,
.codec2700B
.codec2700B,
]
}
@ -851,7 +851,7 @@ extension ModuleConfig.SerialConfig.Serial_Baud: CaseIterable {
.baud230400,
.baud460800,
.baud576000,
.baud921600
.baud921600,
]
}
@ -862,7 +862,7 @@ extension ModuleConfig.SerialConfig.Serial_Mode: CaseIterable {
.simple,
.proto,
.textmsg,
.nmea
.nmea,
]
}
@ -876,7 +876,7 @@ extension ModuleConfig.CannedMessageConfig.InputEventChar: CaseIterable {
.right,
.select,
.back,
.cancel
.cancel,
]
}
@ -902,7 +902,7 @@ extension ModuleConfig.CannedMessageConfig.InputEventChar: @unchecked Sendable {
// MARK: - Code below here is support for the SwiftProtobuf runtime.
private let _protobuf_package = "meshtastic"
fileprivate let _protobuf_package = "meshtastic"
extension ModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".ModuleConfig"
@ -915,7 +915,7 @@ extension ModuleConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat
6: .same(proto: "telemetry"),
7: .standard(proto: "canned_message"),
8: .same(proto: "audio"),
9: .standard(proto: "remote_hardware")
9: .standard(proto: "remote_hardware"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -1108,7 +1108,7 @@ extension ModuleConfig.MQTTConfig: SwiftProtobuf.Message, SwiftProtobuf._Message
3: .same(proto: "username"),
4: .same(proto: "password"),
5: .standard(proto: "encryption_enabled"),
6: .standard(proto: "json_enabled")
6: .standard(proto: "json_enabled"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -1165,7 +1165,7 @@ extension ModuleConfig.MQTTConfig: SwiftProtobuf.Message, SwiftProtobuf._Message
extension ModuleConfig.RemoteHardwareConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = ModuleConfig.protoMessageName + ".RemoteHardwareConfig"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "enabled")
1: .same(proto: "enabled"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -1203,7 +1203,7 @@ extension ModuleConfig.AudioConfig: SwiftProtobuf.Message, SwiftProtobuf._Messag
4: .standard(proto: "i2s_ws"),
5: .standard(proto: "i2s_sd"),
6: .standard(proto: "i2s_din"),
7: .standard(proto: "i2s_sck")
7: .standard(proto: "i2s_sck"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -1272,7 +1272,7 @@ extension ModuleConfig.AudioConfig.Audio_Baud: SwiftProtobuf._ProtoNameProviding
5: .same(proto: "CODEC2_1300"),
6: .same(proto: "CODEC2_1200"),
7: .same(proto: "CODEC2_700"),
8: .same(proto: "CODEC2_700B")
8: .same(proto: "CODEC2_700B"),
]
}
@ -1285,7 +1285,7 @@ extension ModuleConfig.SerialConfig: SwiftProtobuf.Message, SwiftProtobuf._Messa
4: .same(proto: "txd"),
5: .same(proto: "baud"),
6: .same(proto: "timeout"),
7: .same(proto: "mode")
7: .same(proto: "mode"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -1361,7 +1361,7 @@ extension ModuleConfig.SerialConfig.Serial_Baud: SwiftProtobuf._ProtoNameProvidi
12: .same(proto: "BAUD_230400"),
13: .same(proto: "BAUD_460800"),
14: .same(proto: "BAUD_576000"),
15: .same(proto: "BAUD_921600")
15: .same(proto: "BAUD_921600"),
]
}
@ -1371,7 +1371,7 @@ extension ModuleConfig.SerialConfig.Serial_Mode: SwiftProtobuf._ProtoNameProvidi
1: .same(proto: "SIMPLE"),
2: .same(proto: "PROTO"),
3: .same(proto: "TEXTMSG"),
4: .same(proto: "NMEA")
4: .same(proto: "NMEA"),
]
}
@ -1391,7 +1391,7 @@ extension ModuleConfig.ExternalNotificationConfig: SwiftProtobuf.Message, SwiftP
12: .standard(proto: "alert_bell_vibra"),
13: .standard(proto: "alert_bell_buzzer"),
7: .standard(proto: "use_pwm"),
14: .standard(proto: "nag_timeout")
14: .standard(proto: "nag_timeout"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -1492,7 +1492,7 @@ extension ModuleConfig.StoreForwardConfig: SwiftProtobuf.Message, SwiftProtobuf.
2: .same(proto: "heartbeat"),
3: .same(proto: "records"),
4: .standard(proto: "history_return_max"),
5: .standard(proto: "history_return_window")
5: .standard(proto: "history_return_window"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -1546,7 +1546,7 @@ extension ModuleConfig.RangeTestConfig: SwiftProtobuf.Message, SwiftProtobuf._Me
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "enabled"),
2: .same(proto: "sender"),
3: .same(proto: "save")
3: .same(proto: "save"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -1594,7 +1594,7 @@ extension ModuleConfig.TelemetryConfig: SwiftProtobuf.Message, SwiftProtobuf._Me
4: .standard(proto: "environment_screen_enabled"),
5: .standard(proto: "environment_display_fahrenheit"),
6: .standard(proto: "air_quality_enabled"),
7: .standard(proto: "air_quality_interval")
7: .standard(proto: "air_quality_interval"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -1666,7 +1666,7 @@ extension ModuleConfig.CannedMessageConfig: SwiftProtobuf.Message, SwiftProtobuf
8: .standard(proto: "updown1_enabled"),
9: .same(proto: "enabled"),
10: .standard(proto: "allow_input_source"),
11: .standard(proto: "send_bell")
11: .standard(proto: "send_bell"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -1754,6 +1754,6 @@ extension ModuleConfig.CannedMessageConfig.InputEventChar: SwiftProtobuf._ProtoN
19: .same(proto: "LEFT"),
20: .same(proto: "RIGHT"),
24: .same(proto: "CANCEL"),
27: .same(proto: "BACK")
27: .same(proto: "BACK"),
]
}

View file

@ -15,7 +15,7 @@ import SwiftProtobuf
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
typealias Version = _2
}
@ -52,7 +52,7 @@ struct ServiceEnvelope {
init() {}
fileprivate var _packet: MeshPacket?
fileprivate var _packet: MeshPacket? = nil
}
#if swift(>=5.5) && canImport(_Concurrency)
@ -61,14 +61,14 @@ extension ServiceEnvelope: @unchecked Sendable {}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
private let _protobuf_package = "meshtastic"
fileprivate let _protobuf_package = "meshtastic"
extension ServiceEnvelope: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".ServiceEnvelope"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "packet"),
2: .standard(proto: "channel_id"),
3: .standard(proto: "gateway_id")
3: .standard(proto: "gateway_id"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {

View file

@ -15,7 +15,7 @@ import SwiftProtobuf
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
typealias Version = _2
}
@ -238,7 +238,7 @@ extension PortNum: CaseIterable {
.tracerouteApp,
.privateApp,
.atakForwarder,
.max
.max,
]
}
@ -273,6 +273,6 @@ extension PortNum: SwiftProtobuf._ProtoNameProviding {
70: .same(proto: "TRACEROUTE_APP"),
256: .same(proto: "PRIVATE_APP"),
257: .same(proto: "ATAK_FORWARDER"),
511: .same(proto: "MAX")
511: .same(proto: "MAX"),
]
}

View file

@ -15,7 +15,7 @@ import SwiftProtobuf
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
typealias Version = _2
}
@ -125,7 +125,7 @@ extension HardwareMessage.TypeEnum: CaseIterable {
.watchGpios,
.gpiosChanged,
.readGpios,
.readGpiosReply
.readGpiosReply,
]
}
@ -138,14 +138,14 @@ extension HardwareMessage.TypeEnum: @unchecked Sendable {}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
private let _protobuf_package = "meshtastic"
fileprivate let _protobuf_package = "meshtastic"
extension HardwareMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".HardwareMessage"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "type"),
2: .standard(proto: "gpio_mask"),
3: .standard(proto: "gpio_value")
3: .standard(proto: "gpio_value"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -191,6 +191,6 @@ extension HardwareMessage.TypeEnum: SwiftProtobuf._ProtoNameProviding {
2: .same(proto: "WATCH_GPIOS"),
3: .same(proto: "GPIOS_CHANGED"),
4: .same(proto: "READ_GPIOS"),
5: .same(proto: "READ_GPIOS_REPLY")
5: .same(proto: "READ_GPIOS_REPLY"),
]
}

View file

@ -15,7 +15,7 @@ import SwiftProtobuf
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
typealias Version = _2
}
@ -42,12 +42,12 @@ extension RTTTLConfig: @unchecked Sendable {}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
private let _protobuf_package = "meshtastic"
fileprivate let _protobuf_package = "meshtastic"
extension RTTTLConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".RTTTLConfig"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "ringtone")
1: .same(proto: "ringtone"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {

View file

@ -15,7 +15,7 @@ import SwiftProtobuf
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
typealias Version = _2
}
@ -33,7 +33,7 @@ struct StoreAndForward {
///
/// TODO: REPLACE
var variant: StoreAndForward.OneOf_Variant?
var variant: StoreAndForward.OneOf_Variant? = nil
///
/// TODO: REPLACE
@ -345,7 +345,7 @@ extension StoreAndForward.RequestResponse: CaseIterable {
.clientStats,
.clientPing,
.clientPong,
.clientAbort
.clientAbort,
]
}
@ -362,7 +362,7 @@ extension StoreAndForward.Heartbeat: @unchecked Sendable {}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
private let _protobuf_package = "meshtastic"
fileprivate let _protobuf_package = "meshtastic"
extension StoreAndForward: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".StoreAndForward"
@ -371,7 +371,7 @@ extension StoreAndForward: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen
2: .same(proto: "stats"),
3: .same(proto: "history"),
4: .same(proto: "heartbeat"),
5: .same(proto: "empty")
5: .same(proto: "empty"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -486,7 +486,7 @@ extension StoreAndForward.RequestResponse: SwiftProtobuf._ProtoNameProviding {
66: .same(proto: "CLIENT_STATS"),
67: .same(proto: "CLIENT_PING"),
68: .same(proto: "CLIENT_PONG"),
106: .same(proto: "CLIENT_ABORT")
106: .same(proto: "CLIENT_ABORT"),
]
}
@ -501,7 +501,7 @@ extension StoreAndForward.Statistics: SwiftProtobuf.Message, SwiftProtobuf._Mess
6: .standard(proto: "requests_history"),
7: .same(proto: "heartbeat"),
8: .standard(proto: "return_max"),
9: .standard(proto: "return_window")
9: .standard(proto: "return_window"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -575,7 +575,7 @@ extension StoreAndForward.History: SwiftProtobuf.Message, SwiftProtobuf._Message
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .standard(proto: "history_messages"),
2: .same(proto: "window"),
3: .standard(proto: "last_request")
3: .standard(proto: "last_request"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -618,7 +618,7 @@ extension StoreAndForward.Heartbeat: SwiftProtobuf.Message, SwiftProtobuf._Messa
static let protoMessageName: String = StoreAndForward.protoMessageName + ".Heartbeat"
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "period"),
2: .same(proto: "secondary")
2: .same(proto: "secondary"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {

View file

@ -15,7 +15,7 @@ import SwiftProtobuf
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
typealias Version = _2
}
@ -146,7 +146,7 @@ extension TelemetrySensorType: CaseIterable {
.qmi8658,
.qmc5883L,
.sht31,
.pmsa003I
.pmsa003I,
]
}
@ -160,7 +160,7 @@ struct DeviceMetrics {
// methods supported on all messages.
///
/// 1-100 (0 means powered)
/// 0-100 (>100 means powered)
var batteryLevel: UInt32 = 0
///
@ -291,7 +291,7 @@ struct Telemetry {
/// seconds since 1970
var time: UInt32 = 0
var variant: Telemetry.OneOf_Variant?
var variant: Telemetry.OneOf_Variant? = nil
///
/// Key native device metrics such as battery level
@ -374,7 +374,7 @@ extension Telemetry.OneOf_Variant: @unchecked Sendable {}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
private let _protobuf_package = "meshtastic"
fileprivate let _protobuf_package = "meshtastic"
extension TelemetrySensorType: SwiftProtobuf._ProtoNameProviding {
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
@ -391,7 +391,7 @@ extension TelemetrySensorType: SwiftProtobuf._ProtoNameProviding {
10: .same(proto: "QMI8658"),
11: .same(proto: "QMC5883L"),
12: .same(proto: "SHT31"),
13: .same(proto: "PMSA003I")
13: .same(proto: "PMSA003I"),
]
}
@ -401,7 +401,7 @@ extension DeviceMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa
1: .standard(proto: "battery_level"),
2: .same(proto: "voltage"),
3: .standard(proto: "channel_utilization"),
4: .standard(proto: "air_util_tx")
4: .standard(proto: "air_util_tx"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -453,7 +453,7 @@ extension EnvironmentMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImple
3: .standard(proto: "barometric_pressure"),
4: .standard(proto: "gas_resistance"),
5: .same(proto: "voltage"),
6: .same(proto: "current")
6: .same(proto: "current"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -521,7 +521,7 @@ extension AirQualityMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem
9: .standard(proto: "particles_10um"),
10: .standard(proto: "particles_25um"),
11: .standard(proto: "particles_50um"),
12: .standard(proto: "particles_100um")
12: .standard(proto: "particles_100um"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -611,7 +611,7 @@ extension Telemetry: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation
1: .same(proto: "time"),
2: .standard(proto: "device_metrics"),
3: .standard(proto: "environment_metrics"),
4: .standard(proto: "air_quality_metrics")
4: .standard(proto: "air_quality_metrics"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {

View file

@ -15,7 +15,7 @@ import SwiftProtobuf
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that you are building against the same version of the API
// that was used to generate this file.
private struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
typealias Version = _2
}
@ -96,7 +96,7 @@ extension XModem.Control: CaseIterable {
.ack,
.nak,
.can,
.ctrlz
.ctrlz,
]
}
@ -109,7 +109,7 @@ extension XModem.Control: @unchecked Sendable {}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
private let _protobuf_package = "meshtastic"
fileprivate let _protobuf_package = "meshtastic"
extension XModem: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
static let protoMessageName: String = _protobuf_package + ".XModem"
@ -117,7 +117,7 @@ extension XModem: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBas
1: .same(proto: "control"),
2: .same(proto: "seq"),
3: .same(proto: "crc16"),
4: .same(proto: "buffer")
4: .same(proto: "buffer"),
]
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@ -170,6 +170,6 @@ extension XModem.Control: SwiftProtobuf._ProtoNameProviding {
6: .same(proto: "ACK"),
21: .same(proto: "NAK"),
24: .same(proto: "CAN"),
26: .same(proto: "CTRLZ")
26: .same(proto: "CTRLZ"),
]
}

View file

@ -162,9 +162,16 @@ struct Connect: View {
Section(header: Text("available.radios").font(.title)) {
ForEach(bleManager.peripherals.filter({ $0.peripheral.state == CBPeripheralState.disconnected }).sorted(by: { $0.name > $1.name })) { peripheral in
HStack {
Image(systemName: "circle.fill")
.imageScale(.large).foregroundColor(.gray)
.padding(.trailing)
if userSettings.preferredPeripheralId == peripheral.peripheral.identifier.uuidString {
Image(systemName: "star.fill")
.imageScale(.large).foregroundColor(.yellow)
.padding(.trailing)
} else {
Image(systemName: "circle.fill")
.imageScale(.large).foregroundColor(.gray)
.padding(.trailing)
}
Button(action: {
if userSettings.preferredPeripheralId.count > 0 && peripheral.peripheral.identifier.uuidString != userSettings.preferredPeripheralId {
presentingSwitchPreferredPeripheral = true
@ -173,7 +180,7 @@ struct Connect: View {
self.bleManager.connectTo(peripheral: peripheral.peripheral)
}
}) {
Text(peripheral.name).font(.title3)
Text(peripheral.name).font(.callout)
}
Spacer()
VStack {
@ -289,13 +296,13 @@ struct Connect: View {
liveActivityStarted = true
let timerSeconds = 60
let mostRecent = node?.telemetries?.lastObject as! TelemetryEntity
let mostRecent = node?.telemetries?.lastObject as? TelemetryEntity
let activityAttributes = MeshActivityAttributes(nodeNum: Int(node?.num ?? 0), name: node?.user?.longName ?? "unknown")
let future = Date(timeIntervalSinceNow: Double(timerSeconds))
let initialContentState = MeshActivityAttributes.ContentState(timerRange: Date.now...future, connected: true, channelUtilization: mostRecent.channelUtilization, airtime: mostRecent.airUtilTx, batteryLevel: UInt32(mostRecent.batteryLevel))
let initialContentState = MeshActivityAttributes.ContentState(timerRange: Date.now...future, connected: true, channelUtilization: mostRecent?.channelUtilization ?? 0.0, airtime: mostRecent?.airUtilTx ?? 0.0, batteryLevel: UInt32(mostRecent?.batteryLevel ?? 0))
let activityContent = ActivityContent(state: initialContentState, staleDate: Calendar.current.date(byAdding: .minute, value: 2, to: Date())!)

View file

@ -10,12 +10,12 @@ import Charts
struct BatteryGauge: View {
@State var batteryLevel = 0.0
private let minValue = 1.0
private let minValue = 0.0
private let maxValue = 100.00
var body: some View {
VStack {
if batteryLevel == 0.0 {
if batteryLevel > 100.0 {
// Plugged in
Image(systemName: "powerplug")
.font(.largeTitle)
@ -24,7 +24,7 @@ struct BatteryGauge: View {
} else {
let gradient = Gradient(colors: [.red, .orange, .green])
Gauge(value: batteryLevel, in: minValue...maxValue) {
if batteryLevel > 1.0 && batteryLevel < 10 {
if batteryLevel >= 0.0 && batteryLevel < 10 {
Label("Battery Level %", systemImage: "battery.0")
} else if batteryLevel >= 10.0 && batteryLevel < 25.00 {
Label("Battery Level %", systemImage: "battery.25")
@ -38,7 +38,11 @@ struct BatteryGauge: View {
Label("Battery Level %", systemImage: "battery.100.bolt")
}
} currentValueLabel: {
Text(Int(batteryLevel), format: .percent)
if batteryLevel == 0.0 {
Text("< 1%")
} else {
Text(Int(batteryLevel), format: .percent)
}
}
.tint(gradient)
.gaugeStyle(.accessoryCircular)
@ -57,6 +61,7 @@ struct BatteryGauge_Previews: PreviewProvider {
BatteryGauge(batteryLevel: 74.0)
BatteryGauge(batteryLevel: 99.0)
BatteryGauge(batteryLevel: 100.0)
BatteryGauge(batteryLevel: 111.0)
}
}
}

View file

@ -199,7 +199,7 @@ struct MapViewSwiftUI: UIViewRepresentable {
annotationView.leftCalloutAccessoryView = leftIcon
let subtitle = UILabel()
subtitle.text = "Long Name: \(positionAnnotation.nodePosition?.user?.longName ?? "Unknown") \n"
subtitle.text! += "Latitude: \(String(format: "%.5f", positionAnnotation.coordinate.latitude)) \n"
subtitle.text? += "Latitude: \(String(format: "%.5f", positionAnnotation.coordinate.latitude)) \n"
subtitle.text! += "Longitude: \(String(format: "%.5f", positionAnnotation.coordinate.longitude)) \n"
let distanceFormatter = MKDistanceFormatter()
subtitle.text! += "Altitude: \(distanceFormatter.string(fromDistance: Double(positionAnnotation.altitude))) \n"

View file

@ -185,7 +185,11 @@ struct UserMessageList: View {
let ackErrorVal = RoutingError(rawValue: Int(message.ackError))
if currentUser && message.receivedACK {
// Ack Received
Text("\(ackErrorVal?.display ?? "Empty Ack Error")").font(.caption2).foregroundColor(message.realACK ? .gray : .orange)
if message.realACK {
Text("\(ackErrorVal?.display ?? "Empty Ack Error")").font(.caption2).foregroundColor(.gray)
} else {
Text("Implicit ACK from Unknown Node").font(.caption2).foregroundColor(.orange)
}
} else if currentUser && message.ackError == 0 {
// Empty Error
Text("Waiting to be acknowledged. . .").font(.caption2).foregroundColor(.orange)

View file

@ -23,7 +23,7 @@ struct DeviceMetricsLog: View {
let data = node.telemetries?.filtered(using: NSPredicate(format: "metricsType == 0 && time !=nil && time >= %@", oneDayAgo! as CVarArg)) ?? []
if data.count > 0 {
GroupBox(label: Label("battery.level.trend", systemImage: "battery.100")) {
Chart(data.array as! [TelemetryEntity], id: \.self) {
Chart(data.array as? [TelemetryEntity] ?? [], id: \.self) {
LineMark(
x: .value("Hour", $0.time!.formattedDate(format: "ha")),
y: .value("Value", $0.batteryLevel)
@ -40,7 +40,7 @@ struct DeviceMetricsLog: View {
let dateFormatString = (localeDateFormat ?? "MM/dd/YY j:mma").replacingOccurrences(of: ",", with: "")
if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac {
// Add a table for mac and ipad
Table(node.telemetries!.reversed() as! [TelemetryEntity]) {
Table(node.telemetries?.reversed() as? [TelemetryEntity] ?? []) {
TableColumn("battery.level") { dm in
if dm.metricsType == 0 {
@ -102,7 +102,7 @@ struct DeviceMetricsLog: View {
.font(.caption)
.fontWeight(.bold)
}
ForEach(node.telemetries!.reversed() as! [TelemetryEntity], id: \.self) { (dm: TelemetryEntity) in
ForEach(node.telemetries?.reversed() as? [TelemetryEntity] ?? [], id: \.self) { (dm: TelemetryEntity) in
if dm.metricsType == 0 {
GridRow {
if dm.batteryLevel == 0 {

View file

@ -33,17 +33,17 @@ struct EnvironmentMetricsLog: View {
}
TableColumn("Humidity") { em in
if em.metricsType == 1 {
Text("\(String(format: "%.2f", em.relativeHumidity))")
Text("\(String(format: "%.2f", em.relativeHumidity))%")
}
}
TableColumn("Barometric Pressure") { em in
if em.metricsType == 1 {
Text("\(String(format: "%.2f", em.barometricPressure))")
Text("\(String(format: "%.2f", em.barometricPressure)) hPa")
}
}
TableColumn("gas.resistance") { em in
if em.metricsType == 1 {
Text("\(String(format: "%.2f", em.gasResistance))")
Text("\(String(format: "%.2f", em.gasResistance)) ohms")
}
}
TableColumn("current") { em in
@ -90,7 +90,7 @@ struct EnvironmentMetricsLog: View {
.font(.caption)
.fontWeight(.bold)
}
ForEach(node.telemetries!.reversed() as! [TelemetryEntity], id: \.self) { (em: TelemetryEntity) in
ForEach(node.telemetries?.reversed() as? [TelemetryEntity] ?? [], id: \.self) { (em: TelemetryEntity) in
if em.metricsType == 1 {
@ -98,7 +98,7 @@ struct EnvironmentMetricsLog: View {
Text(em.temperature.formattedTemperature())
.font(.caption)
Text("\(String(format: "%.2f", em.relativeHumidity))")
Text("\(String(format: "%.2f", em.relativeHumidity))%")
.font(.caption)
Text("\(String(format: "%.2f", em.barometricPressure))")
.font(.caption)

View file

@ -56,7 +56,7 @@ struct NodeDetail: View {
VStack {
if node.positions?.count ?? 0 > 0 {
ZStack {
let annotations = node.positions?.array as? [PositionEntity] ?? []
let annotations = node.positions?.array as? [PositionEntity] ?? []
ZStack {
MapViewSwiftUI(onLongPress: { coord in
waypointCoordinate = coord
@ -104,7 +104,8 @@ struct NodeDetail: View {
Text("Today's Weather Forecast")
.font(.title)
.padding()
NodeWeatherForecastView(location: CLLocation(latitude: LocationHelper.currentLocation.latitude, longitude: LocationHelper.currentLocation.longitude) )
let nodeLocation = node.positions?.lastObject as? PositionEntity
NodeWeatherForecastView(location: CLLocation(latitude: nodeLocation?.nodeCoordinate!.latitude ?? LocationHelper.currentLocation.latitude, longitude: nodeLocation?.nodeCoordinate!.longitude ?? LocationHelper.currentLocation.longitude) )
.frame(height: 250)
}
#else
@ -112,8 +113,8 @@ struct NodeDetail: View {
Text("Today's Weather Forecast")
.font(.title)
.padding()
NodeWeatherForecastView(location: CLLocation(latitude: LocationHelper.currentLocation.latitude, longitude: LocationHelper.currentLocation.longitude) )
.frame(height: 250)
let nodeLocation = node.positions?.lastObject as? PositionEntity
NodeWeatherForecastView(location: CLLocation(latitude: nodeLocation?.nodeCoordinate!.latitude ?? LocationHelper.currentLocation.latitude, longitude: nodeLocation?.nodeCoordinate!.longitude ?? LocationHelper.currentLocation.longitude) ).frame(height: 250)
.presentationDetents([.medium])
.presentationDragIndicator(.automatic)
}
@ -177,13 +178,13 @@ struct NodeDetail: View {
if node.telemetries?.count ?? 0 >= 1 {
let mostRecent = node.telemetries?.lastObject as! TelemetryEntity
let mostRecent = node.telemetries?.lastObject as? TelemetryEntity
Divider()
VStack(alignment: .center) {
BatteryGauge(batteryLevel: Double(mostRecent.batteryLevel))
if mostRecent.voltage > 0 {
BatteryGauge(batteryLevel: Double(mostRecent?.batteryLevel ?? 0))
if mostRecent?.voltage ?? 0 > 0 {
Text(String(format: "%.2f", mostRecent.voltage) + " V")
Text(String(format: "%.2f", mostRecent?.voltage ?? 0.0) + " V")
.font(.title)
.foregroundColor(.gray)
.fixedSize()
@ -286,13 +287,13 @@ struct NodeDetail: View {
}
if node.telemetries?.count ?? 0 >= 1 {
let mostRecent = node.telemetries?.lastObject as! TelemetryEntity
let mostRecent = node.telemetries?.lastObject as? TelemetryEntity
Divider()
VStack(alignment: .center) {
BatteryGauge(batteryLevel: Double(mostRecent.batteryLevel))
if mostRecent.voltage > 0 {
BatteryGauge(batteryLevel: Double(mostRecent?.batteryLevel ?? 0))
if mostRecent?.voltage ?? 0 > 0 {
Text(String(format: "%.2f", mostRecent.voltage) + " V")
Text(String(format: "%.2f", mostRecent?.voltage ?? 0) + " V")
.font(.callout)
.foregroundColor(.gray)
.fixedSize()
@ -389,12 +390,11 @@ struct NodeDetail: View {
HStack {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral?.num ?? -1, context: context)
if node.metadata?.canShutdown ?? false || hwModelString == "RAK4631" {// node.metadata?.hwModel ?? "UNSET" == "RAK4631" {
if node.metadata?.canShutdown ?? false {
Button(action: {
showingShutdownConfirm = true
}) {
Label("Power Off", systemImage: "power")
}
.buttonStyle(.bordered)
@ -491,9 +491,9 @@ struct NodeDetail: View {
if node.positions?.count ?? 0 > 0 {
let mostRecent = node.positions?.lastObject as! PositionEntity
let mostRecent = node.positions?.lastObject as? PositionEntity
let weather = try await WeatherService.shared.weather(for: mostRecent.nodeLocation!)
let weather = try await WeatherService.shared.weather(for: mostRecent?.nodeLocation ?? CLLocation(latitude: LocationHelper.currentLocation.latitude, longitude: LocationHelper.currentLocation.longitude))
condition = weather.currentWeather.condition
temperature = weather.currentWeather.temperature
humidity = Int(weather.currentWeather.humidity * 100)

View file

@ -57,6 +57,10 @@ struct NodeMap: View {
)
@State private var overlays: [MapViewSwiftUI.Overlay] = []
// init() {
// _positions = FetchRequest<PositionEntity>(sortDescriptors: [NSSortDescriptor(key: "time", ascending: true)], predicate: NSPredicate(format: "time >= %@ && nodePosition != nil", Calendar.current.startOfDay(for: Date()) as NSDate), animation: .none)
// }
var body: some View {
NavigationStack {

View file

@ -26,7 +26,7 @@ struct PositionLog: View {
if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac {
// Add a table for mac and ipad
Table(node.positions!.reversed() as! [PositionEntity]) {
Table(node.positions?.reversed() as? [PositionEntity] ?? []) {
TableColumn("SeqNo") { position in
Text(String(position.seqNo))
}

View file

@ -41,14 +41,21 @@ struct AdminMessageList: View {
let ackErrorVal = RoutingError(rawValue: Int(am.ackError))
if am.ackTimestamp > 0 {
Text(ackErrorVal?.display ?? "Empty Ack Error")
.foregroundColor(am.receivedACK ? .gray : .red)
.font(.caption2)
if am.realACK {
Text(ackErrorVal?.display ?? "Empty Ack Error")
.foregroundColor(am.receivedACK ? .gray : .red)
.font(.caption2)
} else {
Text("Implicit ACK from Unknown Node")
.foregroundColor(.orange)
.font(.caption2)
}
}
if am.receivedACK && am.ackTimestamp > 0 {
if am.receivedACK && am.ackTimestamp > 0 {
Text(" \(Date(timeIntervalSince1970: TimeInterval(am.ackTimestamp)).formattedDate(format: "h:mm:ss a"))")
.foregroundColor(.gray)
.foregroundColor(am.realACK ? .gray : .orange)
.font(.caption2)
}
}

View file

@ -40,7 +40,7 @@ struct Channels: View {
NavigationStack {
List {
if node != nil && node?.myInfo != nil {
ForEach(node!.myInfo!.channels?.array as! [ChannelEntity], id: \.self) { (channel: ChannelEntity) in
ForEach(node?.myInfo?.channels?.array as? [ChannelEntity] ?? [], id: \.self) { (channel: ChannelEntity) in
Button(action: {
channelIndex = channel.index
channelRole = Int(channel.role)
@ -123,7 +123,6 @@ struct Channels: View {
.disableAutocorrection(true)
.keyboardType(.alphabet)
.foregroundColor(Color.gray)
.disabled(channelRole == 1 && channelName.count > 0)
.onChange(of: channelName, perform: { _ in
channelName = channelName.replacing(" ", with: "")
let totalBytes = channelName.utf8.count

View file

@ -26,6 +26,29 @@ struct BluetoothConfig: View {
}()
var body: some View {
Form {
if node != nil && node?.metadata == nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
Text("There has been no response to a request for device metadata over the admin channel for this node.")
.font(.callout)
.foregroundColor(.orange)
} else if node != nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
// Let users know what is going on if they are using remote admin and don't have the config yet
if node?.bluetoothConfig == nil {
Text("Bluetooth config data was requested over the admin channel but no response has been returned from the remote node. You can check the status of admin message requests in the admin message log.")
.font(.callout)
.foregroundColor(.orange)
} else {
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
}
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
} else {
Text("Please connect to a radio to configure settings.")
.font(.callout)
.foregroundColor(.orange)
}
Section(header: Text("options")) {
Toggle(isOn: $enabled) {
Label("enabled", systemImage: "antenna.radiowaves.left.and.right")
@ -93,7 +116,7 @@ struct BluetoothConfig: View {
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: connectedNode!.user!, toUser: node!.user!, adminIndex: node?.myInfo?.adminIndex ?? 0)
let adminMessageId = bleManager.saveBluetoothConfig(config: bc, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.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

View file

@ -31,7 +31,29 @@ struct DeviceConfig: View {
VStack {
Form {
if node != nil && node?.metadata == nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
Text("There has been no response to a request for device metadata over the admin channel for this node.")
.font(.callout)
.foregroundColor(.orange)
} else if node != nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
// Let users know what is going on if they are using remote admin and don't have the config yet
if node?.deviceConfig == nil {
Text("Device config data was requested over the admin channel but no response has been returned from the remote node. You can check the status of admin message requests in the admin message log.")
.font(.callout)
.foregroundColor(.orange)
} else {
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
}
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
} else {
Text("Please connect to a radio to configure settings.")
.font(.callout)
.foregroundColor(.orange)
}
Section(header: Text("options")) {
Picker("Device Role", selection: $deviceRole ) {
@ -183,7 +205,7 @@ struct DeviceConfig: View {
dc.buttonGpio = UInt32(buttonGPIO)
dc.buzzerGpio = UInt32(buzzerGPIO)
let adminMessageId = bleManager.saveDeviceConfig(config: dc, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: node?.myInfo?.adminIndex ?? 0)
let adminMessageId = bleManager.saveDeviceConfig(config: dc, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.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

View file

@ -29,8 +29,30 @@ struct DisplayConfig: View {
var body: some View {
Form {
Section(header: Text("Device Screen")) {
if node != nil && node?.metadata == nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
Text("There has been no response to a request for device metadata over the admin channel for this node.")
.font(.callout)
.foregroundColor(.orange)
} else if node != nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
// Let users know what is going on if they are using remote admin and don't have the config yet
if node?.displayConfig == nil {
Text("Display config data was requested over the admin channel but no response has been returned from the remote node. You can check the status of admin message requests in the admin message log.")
.font(.callout)
.foregroundColor(.orange)
} else {
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
}
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
} else {
Text("Please connect to a radio to configure settings.")
.font(.callout)
.foregroundColor(.orange)
}
Section(header: Text("Device Screen")) {
Picker("Display Mode", selection: $displayMode ) {
ForEach(DisplayModes.allCases) { dm in
Text(dm.description)
@ -130,7 +152,7 @@ struct DisplayConfig: View {
dc.oled = OledTypes(rawValue: oledType)!.protoEnumValue()
dc.displaymode = DisplayModes(rawValue: displayMode)!.protoEnumValue()
let adminMessageId = bleManager.saveDisplayConfig(config: dc, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: node?.myInfo?.adminIndex ?? 0)
let adminMessageId = bleManager.saveDisplayConfig(config: dc, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
if adminMessageId > 0 {
// Should show a saved successfully alert once I know that to be true
@ -163,7 +185,7 @@ struct DisplayConfig: View {
// 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)
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral?.num ?? 0, context: context)
if node != nil && connectedNode != nil {
_ = bleManager.requestDisplayConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
}

View file

@ -40,11 +40,35 @@ struct LoRaConfig: View {
@State var bandwidth = 0
@State var spreadFactor = 0
@State var codingRate = 0
@State var rxBoostedGain = false
var body: some View {
VStack {
Form {
if node != nil && node?.metadata == nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
Text("There has been no response to a request for device metadata over the admin channel for this node.")
.font(.callout)
.foregroundColor(.orange)
} else if node != nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
// Let users know what is going on if they are using remote admin and don't have the config yet
if node?.loRaConfig == nil {
Text("LoRa config data was requested over the admin channel but no response has been returned from the remote node. You can check the status of admin message requests in the admin message log.")
.font(.callout)
.foregroundColor(.orange)
} else {
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
}
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
} else {
Text("Please connect to a radio to configure settings.")
.font(.callout)
.foregroundColor(.orange)
}
Section(header: Text("Options")) {
Picker("Region", selection: $region ) {
@ -142,8 +166,12 @@ struct LoRaConfig: View {
.scrollDismissesKeyboard(.immediately)
.focused($focusedField, equals: .channelNum)
}
Text("A hash of the primary channel's name sets the LoRa channel number, this determines the actual frequency you are transmitting on in the band. To ensure devices with different primary channel names transmit on the same frequency, you must explicitly set the LoRa channel number.")
Text("This determines the actual frequency you are transmitting on in the band.")
.font(.caption)
Toggle(isOn: $rxBoostedGain) {
Label("RX Boosted Gain", systemImage: "waveform.badge.plus")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
}
}
.disabled(self.bleManager.connectedPeripheral == nil || node?.loRaConfig == nil)
@ -166,7 +194,7 @@ 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)
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral?.num ?? 0, context: context)
if connectedNode != nil {
var lc = Config.LoRaConfig()
lc.hopLimit = UInt32(hopLimit)
@ -178,7 +206,8 @@ struct LoRaConfig: View {
lc.bandwidth = UInt32(bandwidth)
lc.codingRate = UInt32(codingRate)
lc.spreadFactor = UInt32(spreadFactor)
let adminMessageId = bleManager.saveLoRaConfig(config: lc, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: node?.myInfo?.adminIndex ?? 0)
lc.sx126XRxBoostedGain = rxBoostedGain
let adminMessageId = bleManager.saveLoRaConfig(config: lc, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.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
@ -209,8 +238,8 @@ struct LoRaConfig: View {
self.bandwidth = Int(node?.loRaConfig?.bandwidth ?? 0)
self.codingRate = Int(node?.loRaConfig?.codingRate ?? 0)
self.spreadFactor = Int(node?.loRaConfig?.spreadFactor ?? 0)
print("Spreadum: \(self.spreadFactor)")
self.rxBoostedGain = node?.loRaConfig?.sx126xRxBoostedGain ?? false
print(rxBoostedGain)
self.hasChanges = false
// Need to request a LoRaConfig from the remote node before allowing changes
@ -262,5 +291,10 @@ struct LoRaConfig: View {
if newSpreadFactor != node!.loRaConfig!.spreadFactor { hasChanges = true }
}
}
.onChange(of: rxBoostedGain) { newRxBoostedGain in
if node != nil && node!.loRaConfig != nil {
if newRxBoostedGain != node!.loRaConfig!.sx126xRxBoostedGain { hasChanges = true }
}
}
}
}

View file

@ -39,6 +39,29 @@ struct CannedMessagesConfig: View {
VStack {
Form {
if node != nil && node?.metadata == nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
Text("There has been no response to a request for device metadata over the admin channel for this node.")
.font(.callout)
.foregroundColor(.orange)
} else if node != nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
// Let users know what is going on if they are using remote admin and don't have the config yet
if node?.cannedMessageConfig == nil {
Text("Canned messages config data was requested over the admin channel but no response has been returned from the remote node. You can check the status of admin message requests in the admin message log.")
.font(.callout)
.foregroundColor(.orange)
} else {
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
}
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
} else {
Text("Please connect to a radio to configure settings.")
.font(.callout)
.foregroundColor(.orange)
}
Section(header: Text("options")) {
Toggle(isOn: $enabled) {
@ -184,37 +207,40 @@ struct CannedMessagesConfig: View {
let nodeName = bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.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 ?? -1, context: context)
if hasChanges {
var cmc = ModuleConfig.CannedMessageConfig()
cmc.enabled = enabled
cmc.sendBell = sendBell
cmc.rotary1Enabled = rotary1Enabled
cmc.updown1Enabled = updown1Enabled
if rotary1Enabled {
/// Input event origin accepted by the canned messages
/// Can be e.g. "rotEnc1", "upDownEnc1", "cardkb", or keyword "_any"
cmc.allowInputSource = "rotEnc1"
} else if updown1Enabled {
cmc.allowInputSource = "upDown1"
} else {
cmc.allowInputSource = "_any"
}
cmc.inputbrokerPinA = UInt32(inputbrokerPinA)
cmc.inputbrokerPinB = UInt32(inputbrokerPinB)
cmc.inputbrokerPinPress = UInt32(inputbrokerPinPress)
cmc.inputbrokerEventCw = InputEventChars(rawValue: inputbrokerEventCw)!.protoEnumValue()
cmc.inputbrokerEventCcw = InputEventChars(rawValue: inputbrokerEventCcw)!.protoEnumValue()
cmc.inputbrokerEventPress = InputEventChars(rawValue: inputbrokerEventPress)!.protoEnumValue()
let adminMessageId = bleManager.saveCannedMessageModuleConfig(config: cmc, fromUser: node!.user!, toUser: node!.user!, 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
hasChanges = false
goBack()
if connectedNode != nil {
var cmc = ModuleConfig.CannedMessageConfig()
cmc.enabled = enabled
cmc.sendBell = sendBell
cmc.rotary1Enabled = rotary1Enabled
cmc.updown1Enabled = updown1Enabled
if rotary1Enabled {
/// Input event origin accepted by the canned messages
/// Can be e.g. "rotEnc1", "upDownEnc1", "cardkb", or keyword "_any"
cmc.allowInputSource = "rotEnc1"
} else if updown1Enabled {
cmc.allowInputSource = "upDown1"
} else {
cmc.allowInputSource = "_any"
}
cmc.inputbrokerPinA = UInt32(inputbrokerPinA)
cmc.inputbrokerPinB = UInt32(inputbrokerPinB)
cmc.inputbrokerPinPress = UInt32(inputbrokerPinPress)
cmc.inputbrokerEventCw = InputEventChars(rawValue: inputbrokerEventCw)!.protoEnumValue()
cmc.inputbrokerEventCcw = InputEventChars(rawValue: inputbrokerEventCcw)!.protoEnumValue()
cmc.inputbrokerEventPress = InputEventChars(rawValue: inputbrokerEventPress)!.protoEnumValue()
let adminMessageId = bleManager.saveCannedMessageModuleConfig(config: cmc, fromUser: node!.user!, toUser: node!.user!, adminIndex: connectedNode?.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
hasChanges = false
goBack()
}
}
}
if hasMessagesChanges {
let adminMessageId = bleManager.saveCannedMessageModuleMessages(messages: messages, fromUser: node!.user!, toUser: node!.user!, adminIndex: node?.myInfo?.adminIndex ?? 0)
let adminMessageId = bleManager.saveCannedMessageModuleMessages(messages: messages, fromUser: node!.user!, toUser: node!.user!, adminIndex: connectedNode?.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

View file

@ -34,6 +34,29 @@ struct ExternalNotificationConfig: View {
var body: some View {
Form {
if node != nil && node?.metadata == nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
Text("There has been no response to a request for device metadata over the admin channel for this node.")
.font(.callout)
.foregroundColor(.orange)
} else if node != nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
// Let users know what is going on if they are using remote admin and don't have the config yet
if node?.externalNotificationConfig == nil {
Text("External notification config data was requested over the admin channel but no response has been returned from the remote node. You can check the status of admin message requests in the admin message log.")
.font(.callout)
.foregroundColor(.orange)
} else {
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
}
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
} else {
Text("Please connect to a radio to configure settings.")
.font(.callout)
.foregroundColor(.orange)
}
Section(header: Text("options")) {
Toggle(isOn: $enabled) {
Label("enabled", systemImage: "megaphone")

View file

@ -24,6 +24,29 @@ struct MQTTConfig: View {
var body: some View {
Form {
if node != nil && node?.metadata == nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
Text("There has been no response to a request for device metadata over the admin channel for this node.")
.font(.callout)
.foregroundColor(.orange)
} else if node != nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
// Let users know what is going on if they are using remote admin and don't have the config yet
if node?.mqttConfig == nil {
Text("MQTT config data was requested over the admin channel but no response has been returned from the remote node. You can check the status of admin message requests in the admin message log.")
.font(.callout)
.foregroundColor(.orange)
} else {
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
}
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
} else {
Text("Please connect to a radio to configure settings.")
.font(.callout)
.foregroundColor(.orange)
}
Section(header: Text("options")) {
Toggle(isOn: $enabled) {

View file

@ -23,6 +23,29 @@ struct RangeTestConfig: View {
var body: some View {
VStack {
Form {
if node != nil && node?.metadata == nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
Text("There has been no response to a request for device metadata over the admin channel for this node.")
.font(.callout)
.foregroundColor(.orange)
} else if node != nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
// Let users know what is going on if they are using remote admin and don't have the config yet
if node?.rangeTestConfig == nil {
Text("Range test config data was requested over the admin channel but no response has been returned from the remote node. You can check the status of admin message requests in the admin message log.")
.font(.callout)
.foregroundColor(.orange)
} else {
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
}
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
} else {
Text("Please connect to a radio to configure settings.")
.font(.callout)
.foregroundColor(.orange)
}
Section(header: Text("options")) {
Toggle(isOn: $enabled) {

View file

@ -30,7 +30,29 @@ struct SerialConfig: View {
VStack {
Form {
if node != nil && node?.metadata == nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
Text("There has been no response to a request for device metadata over the admin channel for this node.")
.font(.callout)
.foregroundColor(.orange)
} else if node != nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
// Let users know what is going on if they are using remote admin and don't have the config yet
if node?.serialConfig == nil {
Text("Serial config data was requested over the admin channel but no response has been returned from the remote node. You can check the status of admin message requests in the admin message log.")
.font(.callout)
.foregroundColor(.orange)
} else {
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
}
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
} else {
Text("Please connect to a radio to configure settings.")
.font(.callout)
.foregroundColor(.orange)
}
Section(header: Text("options")) {
Toggle(isOn: $enabled) {

View file

@ -26,6 +26,29 @@ struct TelemetryConfig: View {
VStack {
Form {
if node != nil && node?.metadata == nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
Text("There has been no response to a request for device metadata over the admin channel for this node.")
.font(.callout)
.foregroundColor(.orange)
} else if node != nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
// Let users know what is going on if they are using remote admin and don't have the config yet
if node?.telemetryConfig == nil {
Text("Telemetry config data was requested over the admin channel but no response has been returned from the remote node. You can check the status of admin message requests in the admin message log.")
.font(.callout)
.foregroundColor(.orange)
} else {
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
}
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
} else {
Text("Please connect to a radio to configure settings.")
.font(.callout)
.foregroundColor(.orange)
}
Section(header: Text("update.interval")) {
Picker("Device Metrics", selection: $deviceUpdateInterval ) {
ForEach(UpdateIntervals.allCases) { ui in
@ -61,7 +84,7 @@ struct TelemetryConfig: View {
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
}
}
.disabled(self.bleManager.connectedPeripheral == nil || node?.positionConfig == nil)
.disabled(self.bleManager.connectedPeripheral == nil || node?.telemetryConfig == nil)
Button {
isPresentingSaveConfirm = true
} label: {

View file

@ -29,8 +29,30 @@ struct NetworkConfig: View {
VStack {
Form {
Section(header: Text("WiFi Options (ESP32 Only)")) {
if node != nil && node?.metadata == nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
Text("There has been no response to a request for device metadata over the admin channel for this node.")
.font(.callout)
.foregroundColor(.orange)
} else if node != nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
// Let users know what is going on if they are using remote admin and don't have the config yet
if node?.networkConfig == nil {
Text("Network config data was requested over the admin channel but no response has been returned from the remote node. You can check the status of admin message requests in the admin message log.")
.font(.callout)
.foregroundColor(.orange)
} else {
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
}
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
} else {
Text("Please connect to a radio to configure settings.")
.font(.callout)
.foregroundColor(.orange)
}
Section(header: Text("WiFi Options (ESP32 Only)")) {
Toggle(isOn: $wifiEnabled) {
Label("enabled", systemImage: "wifi")
}
@ -119,7 +141,7 @@ struct NetworkConfig: View {
network.ethEnabled = self.ethEnabled
// network.addressMode = Config.NetworkConfig.AddressMode.dhcp
let adminMessageId = bleManager.saveNetworkConfig(config: network, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: node?.myInfo?.adminIndex ?? 0)
let adminMessageId = bleManager.saveNetworkConfig(config: network, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.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

View file

@ -72,6 +72,29 @@ struct PositionConfig: View {
VStack {
Form {
if node != nil && node?.metadata == nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
Text("There has been no response to a request for device metadata over the admin channel for this node.")
.font(.callout)
.foregroundColor(.orange)
} else if node != nil && node?.num ?? 0 != bleManager.connectedPeripheral?.num ?? 0 {
// Let users know what is going on if they are using remote admin and don't have the config yet
if node?.positionConfig == nil {
Text("Position config data was requested over the admin channel but no response has been returned from the remote node. You can check the status of admin message requests in the admin message log.")
.font(.callout)
.foregroundColor(.orange)
} else {
Text("Remote administration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
}
} else if node != nil && node?.num ?? 0 == bleManager.connectedPeripheral?.num ?? 0 {
Text("Configuration for: \(node?.user?.longName ?? "Unknown")")
.font(.title3)
} else {
Text("Please connect to a radio to configure settings.")
.font(.callout)
.foregroundColor(.orange)
}
Section(header: Text("Device GPS")) {
Toggle(isOn: $deviceGpsEnabled) {
Label("Device GPS Enabled", systemImage: "location")
@ -230,7 +253,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: connectedNode!.user!, toUser: node!.user!, adminIndex: node?.myInfo?.adminIndex ?? 0)
let adminMessageId = bleManager.savePositionConfig(config: pc, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.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

View file

@ -0,0 +1,291 @@
//
// Firmware.swift
// Meshtastic
//
// Created by Garth Vander Houwen on 3/10/23.
//
//
// About.swift
// Meshtastic
//
// Copyright(c) Garth Vander Houwen 10/6/22.
//
import SwiftUI
import StoreKit
struct Firmware: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
var node: NodeInfoEntity?
@State var minimumVersion = "2.1.0"
@State var version = ""
@State private var firmwareReleaseData: FirmwareRelease = FirmwareRelease()
var body: some View {
// NavigationSplitView {
NavigationStack {
let hwModel: HardwareModels = HardwareModels.allCases.first(where: { $0.rawValue == node?.user?.hwModel ?? "UNSET" }) ?? HardwareModels.UNSET
VStack(alignment: .leading) {
Text("Current Version: \(bleManager.connectedVersion)")
.font(.largeTitle)
Text("Your device supports the following firmware: ")
.font(.callout)
HStack {
ForEach(hwModel.firmwareStrings, id: \.self) { fs in
Text(fs).font(.callout)
}
}
.padding(.bottom)
if hwModel.platform() == HardwarePlatforms.NRF52 {
VStack(alignment: .leading) {
if hwModel == HardwareModels.RAK4631 {
Text("nRF OTA Device Firmware Update App")
.font(.title3)
Text("You can update your Meshtastic device over bluetooth using the Nordic DFU app. This currently works for RAK NRF devices.")
.font(.caption)
Link("Get NRF DFU from the App Store", destination: URL(string: "https://apps.apple.com/us/app/nrf-device-firmware-update/id1624454660")!)
.font(.callout)
} else {
Text("OTA Updates are not supported on the this NRF Device.")
.font(.title3)
Link("Drag & Drop Firmware Update", destination: URL(string: "https://meshtastic.org/docs/getting-started/flashing-firmware/nrf52/drag-n-drop")!)
.font(.callout)
}
}
} else if hwModel.platform() == HardwarePlatforms.ESP32 {
VStack(alignment: .leading) {
Text("ESP32 Device Firmware Update")
.font(.title3)
Text("Currently the reccomended way to update ESP32 devices is using the web flasher from a chrome based browser. It does not work on mobile devices or over BLE.")
.font(.caption)
Link("Web Flasher", destination: URL(string: "https://flasher.meshtastic.org")!)
.font(.callout)
.padding(.bottom)
Text("ESP 32 OTA update is a work in progress, click the button below to sent your device a reboot into ota admin message.")
.font(.caption)
HStack(alignment: .center) {
Spacer()
Button {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
if connectedNode != nil {
if !bleManager.sendRebootOta(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode!.myInfo!.adminIndex) {
print("Reboot Failed")
} else {
bleManager.disconnectPeripheral(reconnect: false)
}
}
} label: {
Label("Send Reboot OTA", systemImage: "square.and.arrow.down")
}
.buttonStyle(.bordered)
.buttonBorderShape(.capsule)
.controlSize(.regular)
.padding(5)
Spacer()
}
}
} else {
Text("OTA Updates are not supported on your platform.")
.font(.title3)
}
}.padding()
VStack(alignment: .leading) {
Text("Firmware Releases")
.font(.title3)
.padding([.leading, .trailing])
List {
Section(header: Text("Stable")) {
ForEach(firmwareReleaseData.releases?.stable ?? [], id: \.id) { fr in
Link(destination: URL(string: fr.zipUrl ?? "")!) {
HStack {
Text(fr.title ?? "Unknown")
.font(.caption)
Spacer()
Image(systemName: "square.and.arrow.down")
.font(.title3)
}
}
}
}
Section("Alpha") {
ForEach(firmwareReleaseData.releases?.alpha ?? [], id: \.id) { fr in
Link(destination: URL(string: fr.zipUrl ?? "")!) {
HStack {
Text(fr.title ?? "Unknown")
.font(.caption)
Spacer()
Image(systemName: "square.and.arrow.down")
.font(.title3)
}
}
}
}
Section("Pull Requests") {
ForEach(firmwareReleaseData.pullRequests ?? [], id: \.id) { fr in
Link(destination: URL(string: fr.zipUrl ?? "")!) {
HStack {
Text(fr.title ?? "Unknown")
.font(.caption)
Spacer()
Image(systemName: "square.and.arrow.down")
.font(.title3)
}
}
}
}
}
}
.padding(.bottom, 5)
.onAppear(perform: loadData)
.navigationTitle("Firmware Updates")
.navigationBarTitleDisplayMode(.inline)
}
}
func loadData() {
guard let url = URL(string: "https://api.meshtastic.org/github/firmware/list") else {
return
}
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) { data, _, _ in
if let data = data {
if let response_obj = try? JSONDecoder().decode(FirmwareRelease.self, from: data) {
DispatchQueue.main.async {
self.firmwareReleaseData = response_obj
}
}
}
}.resume()
}
}
struct FirmwareRelease: Codable {
var releases: Releases? = Releases()
var pullRequests: [PullRequests]? = []
enum CodingKeys: String, CodingKey {
case releases = "releases"
case pullRequests = "pullRequests"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
releases = try values.decodeIfPresent(Releases.self, forKey: .releases )
pullRequests = try values.decodeIfPresent([PullRequests].self, forKey: .pullRequests )
}
init() {
}
}
struct Releases: Codable {
var stable: [Stable]? = []
var alpha: [Alpha]? = []
enum CodingKeys: String, CodingKey {
case stable = "stable"
case alpha = "alpha"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
stable = try values.decodeIfPresent([Stable].self, forKey: .stable )
alpha = try values.decodeIfPresent([Alpha].self, forKey: .alpha )
}
init() {}
}
struct Alpha: Codable {
var id: String?
var title: String?
var pageUrl: String?
var zipUrl: String?
enum CodingKeys: String, CodingKey {
case id = "id"
case title = "title"
case pageUrl = "page_url"
case zipUrl = "zip_url"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
id = try values.decodeIfPresent(String.self, forKey: .id )
title = try values.decodeIfPresent(String.self, forKey: .title )
pageUrl = try values.decodeIfPresent(String.self, forKey: .pageUrl )
zipUrl = try values.decodeIfPresent(String.self, forKey: .zipUrl )
}
init() {}
}
struct Stable: Codable {
var id: String?
var title: String?
var pageUrl: String?
var zipUrl: String?
enum CodingKeys: String, CodingKey {
case id = "id"
case title = "title"
case pageUrl = "page_url"
case zipUrl = "zip_url"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
id = try values.decodeIfPresent(String.self, forKey: .id )
title = try values.decodeIfPresent(String.self, forKey: .title )
pageUrl = try values.decodeIfPresent(String.self, forKey: .pageUrl )
zipUrl = try values.decodeIfPresent(String.self, forKey: .zipUrl )
}
init() {}
}
struct PullRequests: Codable {
var id: String?
var title: String?
var pageUrl: String?
var zipUrl: String?
enum CodingKeys: String, CodingKey {
case id = "id"
case title = "title"
case pageUrl = "page_url"
case zipUrl = "zip_url"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
id = try values.decodeIfPresent(String.self, forKey: .id )
title = try values.decodeIfPresent(String.self, forKey: .title )
pageUrl = try values.decodeIfPresent(String.self, forKey: .pageUrl )
zipUrl = try values.decodeIfPresent(String.self, forKey: .zipUrl )
}
init() {}
}

View file

@ -45,6 +45,15 @@ struct Settings: View {
var body: some View {
NavigationSplitView {
List {
NavigationLink {
AboutMeshtastic()
} label: {
Image(systemName: "questionmark.app")
.symbolRenderingMode(.hierarchical)
Text("about.meshtastic")
}
.tag(SettingsSidebar.about)
NavigationLink {
AppSettings()
} label: {
@ -260,16 +269,17 @@ struct Settings: View {
}
.tag(SettingsSidebar.adminMessageLog)
}
Section(header: Text("about")) {
Section(header: Text("Firmware")) {
NavigationLink {
AboutMeshtastic()
Firmware(node: nodes.first(where: { $0.num == connectedNodeNum }))
} label: {
Image(systemName: "questionmark.app")
Image(systemName: "arrow.up.arrow.down.square")
.symbolRenderingMode(.hierarchical)
Text("about.meshtastic")
Text("Firmware Updates")
}
.tag(SettingsSidebar.about)
.disabled(selectedNode > 0 && selectedNode != connectedNodeNum)
}
}
.onAppear {

View file

@ -68,7 +68,7 @@ struct ShareChannels: View {
.font(.caption)
.fontWeight(.bold)
}
ForEach(node!.myInfo!.channels?.array as! [ChannelEntity], id: \.self) { (channel: ChannelEntity) in
ForEach(node?.myInfo?.channels?.array as? [ChannelEntity] ?? [], id: \.self) { (channel: ChannelEntity) in
GridRow {
Spacer()
if channel.index == 0 {
@ -287,9 +287,10 @@ struct ShareChannels: View {
loRaConfig.txPower = node?.loRaConfig?.txPower ?? 0
loRaConfig.usePreset = node?.loRaConfig?.usePreset ?? true
loRaConfig.channelNum = UInt32(node?.loRaConfig?.channelNum ?? 0)
loRaConfig.sx126XRxBoostedGain = node?.loRaConfig?.sx126xRxBoostedGain ?? false
channelSet.loraConfig = loRaConfig
if node?.myInfo?.channels != nil && node?.myInfo?.channels?.count ?? 0 > 0 {
for ch in node!.myInfo!.channels!.array as! [ChannelEntity] {
for ch in node?.myInfo?.channels?.array as? [ChannelEntity] ?? [] {
if ch.role > 0 {
if ch.index == 0 && includeChannel0 || ch.index == 1 && includeChannel1 || ch.index == 2 && includeChannel2 || ch.index == 3 && includeChannel3 ||

View file

@ -100,8 +100,12 @@ struct LiveActivityView: View {
var body: some View {
HStack {
Image(colorScheme == .light ? "logo-black" : "logo-white")
.resizable()
.clipShape(ContainerRelativeShape())
.opacity(isLuminanceReduced ? 0.5 : 1.0)
.aspectRatio(contentMode: .fit)
.frame(width: 65)
Spacer()
NodeInfoView(nodeName: nodeName, timerRange: timerRange, channelUtilization: channelUtilization, airtime: airtime, batteryLevel: batteryLevel)
Spacer()
TimerView(timerRange: timerRange)
@ -126,42 +130,41 @@ struct NodeInfoView: View {
var body: some View {
VStack(alignment: .leading, spacing: 0) {
Text(nodeName)
.font(.title3)
.font(nodeName.count > 14 ? .callout : .title3)
.fontWeight(.semibold)
.foregroundStyle(.tint)
.fixedSize()
Text("\(String(format: "Ch. Util: %.2f", channelUtilization))%")
.font(.subheadline)
.fontWeight(.medium)
.foregroundStyle(.secondary)
.opacity(isLuminanceReduced ? 0.5 : 1.0)
.opacity(isLuminanceReduced ? 0.8 : 1.0)
.fixedSize()
Text("\(String(format: "Airtime: %.2f", airtime))%")
.font(.subheadline)
.fontWeight(.medium)
.foregroundStyle(.secondary)
.opacity(isLuminanceReduced ? 0.5 : 1.0)
.opacity(isLuminanceReduced ? 0.8 : 1.0)
.fixedSize()
if batteryLevel < 101 {
Text("Battery Level: \(batteryLevel > 0 ? String(batteryLevel) : "< 1")%")
.font(.subheadline)
.fontWeight(.medium)
.foregroundStyle(.secondary)
.opacity(isLuminanceReduced ? 0.5 : 1.0)
.opacity(isLuminanceReduced ? 0.8 : 1.0)
.fixedSize()
} else {
Text("Plugged In")
.font(.subheadline)
.fontWeight(.medium)
.foregroundStyle(.secondary)
.opacity(isLuminanceReduced ? 0.5 : 1.0)
.opacity(isLuminanceReduced ? 0.8 : 1.0)
.fixedSize()
}
Text(Date().formatted())
.font(.subheadline)
.fontWeight(.medium)
.foregroundStyle(.secondary)
.opacity(isLuminanceReduced ? 0.5 : 1.0)
.opacity(isLuminanceReduced ? 0.8 : 1.0)
.fixedSize()
}
}