mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Merge pull request #332 from meshtastic/2.1.0_Working_Changes
2.1.0 working changes
This commit is contained in:
commit
b747634d4e
50 changed files with 1369 additions and 446 deletions
|
|
@ -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;
|
||||
|
|
|
|||
262
Meshtastic/Enums/HardwareModels.swift
Normal file
262
Meshtastic/Enums/HardwareModels.swift
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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())!)
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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: {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
291
Meshtastic/Views/Settings/Firmware.swift
Normal file
291
Meshtastic/Views/Settings/Firmware.swift
Normal 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() {}
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 ||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue