Move enums, add distance to node list work on BLE settings

This commit is contained in:
Garth Vander Houwen 2022-08-20 12:15:14 -07:00
parent 91ad258590
commit 07f28252fd
14 changed files with 559 additions and 375 deletions

View file

@ -73,6 +73,11 @@
DDB6ABD628AE742000384BA1 /* BluetoothConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB6ABD528AE742000384BA1 /* BluetoothConfig.swift */; };
DDB6ABD928B0A4BA00384BA1 /* BluetoothModes.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB6ABD828B0A4BA00384BA1 /* BluetoothModes.swift */; };
DDB6ABDB28B0AC6000384BA1 /* DistanceText.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB6ABDA28B0AC6000384BA1 /* DistanceText.swift */; };
DDB6ABE028B13AC700384BA1 /* DeviceRoles.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB6ABDF28B13AC700384BA1 /* DeviceRoles.swift */; };
DDB6ABE228B13FB500384BA1 /* GpsFormats.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB6ABE128B13FB500384BA1 /* GpsFormats.swift */; };
DDB6ABE428B13FFF00384BA1 /* ScreenIntervals.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB6ABE328B13FFF00384BA1 /* ScreenIntervals.swift */; };
DDB6ABE628B1406100384BA1 /* LoraConfigEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB6ABE528B1406100384BA1 /* LoraConfigEnums.swift */; };
DDB6ABE828B141AF00384BA1 /* WiFiModes.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB6ABE728B141AF00384BA1 /* WiFiModes.swift */; };
DDC2E15826CE248E0042C5E4 /* MeshtasticApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E15726CE248E0042C5E4 /* MeshtasticApp.swift */; };
DDC2E15C26CE248F0042C5E4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDC2E15B26CE248F0042C5E4 /* Assets.xcassets */; };
DDC2E15F26CE248F0042C5E4 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDC2E15E26CE248F0042C5E4 /* Preview Assets.xcassets */; };
@ -178,6 +183,11 @@
DDB6ABD728AE8F5D00384BA1 /* MeshtasticDataModel v 7.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MeshtasticDataModel v 7.xcdatamodel"; sourceTree = "<group>"; };
DDB6ABD828B0A4BA00384BA1 /* BluetoothModes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BluetoothModes.swift; sourceTree = "<group>"; };
DDB6ABDA28B0AC6000384BA1 /* DistanceText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DistanceText.swift; sourceTree = "<group>"; };
DDB6ABDF28B13AC700384BA1 /* DeviceRoles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceRoles.swift; sourceTree = "<group>"; };
DDB6ABE128B13FB500384BA1 /* GpsFormats.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GpsFormats.swift; sourceTree = "<group>"; };
DDB6ABE328B13FFF00384BA1 /* ScreenIntervals.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenIntervals.swift; sourceTree = "<group>"; };
DDB6ABE528B1406100384BA1 /* LoraConfigEnums.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoraConfigEnums.swift; sourceTree = "<group>"; };
DDB6ABE728B141AF00384BA1 /* WiFiModes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WiFiModes.swift; sourceTree = "<group>"; };
DDC2E15426CE248E0042C5E4 /* Meshtastic.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Meshtastic.app; sourceTree = BUILT_PRODUCTS_DIR; };
DDC2E15726CE248E0042C5E4 /* MeshtasticApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshtasticApp.swift; sourceTree = "<group>"; };
DDC2E15B26CE248F0042C5E4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = ../Assets.xcassets; sourceTree = "<group>"; };
@ -321,8 +331,13 @@
DD8ED9C6289CE4A100B3B0AB /* Enums */ = {
isa = PBXGroup;
children = (
DD8ED9C7289CE4B900B3B0AB /* RoutingError.swift */,
DDB6ABD828B0A4BA00384BA1 /* BluetoothModes.swift */,
DDB6ABDF28B13AC700384BA1 /* DeviceRoles.swift */,
DDB6ABE528B1406100384BA1 /* LoraConfigEnums.swift */,
DDB6ABE128B13FB500384BA1 /* GpsFormats.swift */,
DD8ED9C7289CE4B900B3B0AB /* RoutingError.swift */,
DDB6ABE328B13FFF00384BA1 /* ScreenIntervals.swift */,
DDB6ABE728B141AF00384BA1 /* WiFiModes.swift */,
);
path = Enums;
sourceTree = "<group>";
@ -672,6 +687,7 @@
DD5394FE276BA0EF00AD86B1 /* PositionEntityExtension.swift in Sources */,
DD913639270DFF4C00D7ACF3 /* LocalNotificationManager.swift in Sources */,
DD4C158C2824A91E0032668E /* module_config.pb.swift in Sources */,
DDB6ABE828B141AF00384BA1 /* WiFiModes.swift in Sources */,
DD4F23CD28779A3C001D37CB /* TelemetryLog.swift in Sources */,
DD6B85A828009258000ACD6B /* ShareChannel.swift in Sources */,
DDB6ABD628AE742000384BA1 /* BluetoothConfig.swift in Sources */,
@ -691,6 +707,7 @@
DD6193772862F90F00E59241 /* CannedMessagesConfig.swift in Sources */,
DD41582628582E9B009B0E59 /* DeviceConfig.swift in Sources */,
DD1BF2F92776FE2E008C8D2F /* UserMessageList.swift in Sources */,
DDB6ABE628B1406100384BA1 /* LoraConfigEnums.swift in Sources */,
DDB2CC6E27F3EB47009C5FCC /* telemetry.pb.swift in Sources */,
DD23A50F26FD1B4400D9B90C /* PeripheralModel.swift in Sources */,
DDB6ABDB28B0AC6000384BA1 /* DistanceText.swift in Sources */,
@ -708,6 +725,7 @@
DD2553592855B52700E55709 /* PositionConfig.swift in Sources */,
DDB3107228A6224100F1DE3D /* device_metadata.pb.swift in Sources */,
DDAF8C6326ED0A230058C060 /* admin.pb.swift in Sources */,
DDB6ABE028B13AC700384BA1 /* DeviceRoles.swift in Sources */,
DD86D40C287F401000BAEB7A /* SaveChannelQRCode.swift in Sources */,
DD8ED9C8289CE4B900B3B0AB /* RoutingError.swift in Sources */,
C9483F6D2773017500998F6B /* MapView.swift in Sources */,
@ -721,11 +739,13 @@
DDA6B2E928419CF2003E8C16 /* MeshPackets.swift in Sources */,
DDCE4E2C2869F92900BE9F8F /* UserConfig.swift in Sources */,
DD6193752862F6E600E59241 /* ExternalNotificationConfig.swift in Sources */,
DDB6ABE428B13FFF00384BA1 /* ScreenIntervals.swift in Sources */,
DD86D40A287F04F100BAEB7A /* InvalidVersion.swift in Sources */,
DDD94A502845C8F5004A87A0 /* DateTimeText.swift in Sources */,
C9A88B57278B559900BD810A /* apponly.pb.swift in Sources */,
DD4C158E2824AA7E0032668E /* config.pb.swift in Sources */,
DD47E3D926F3093800029299 /* MessageBubble.swift in Sources */,
DDB6ABE228B13FB500384BA1 /* GpsFormats.swift in Sources */,
DD415828285859C4009B0E59 /* TelemetryConfig.swift in Sources */,
DD73FD1128750779000852D6 /* LocationHistory.swift in Sources */,
C9697F9D279336B700250207 /* LocalMBTileOverlay.swift in Sources */,

View file

@ -16,11 +16,11 @@ enum BluetoothModes: Int, CaseIterable, Identifiable {
get {
switch self {
case .randomPin:
return "Random"
return "Random PIN"
case .fixedPin:
return "Fixed"
return "Fixed PIN"
case .noPin:
return "None"
return "No PIN (Just Works)"
}
}
}

View file

@ -0,0 +1,48 @@
//
// DeviceRoles.swift
// Meshtastic
//
// Copyright(c) Garth Vander Houwen 8/20/22.
//
import Foundation
// Default of 0 is Client
enum DeviceRoles: Int, CaseIterable, Identifiable {
case client = 0
case clientMute = 1
case router = 2
case routerClient = 3
var id: Int { self.rawValue }
var description: String {
get {
switch self {
case .client:
return "Client (default) - App connected client."
case .clientMute:
return "Client Mute - Same as a client except packets will not hop over this node, does not contribute to routing packets for mesh."
case .router:
return "Router - Mesh packets will prefer to be routed over this node. This node will not be used by client apps. The wifi/ble radios and the oled screen will be put to sleep."
case .routerClient:
return "Router Client - Mesh packets will prefer to be routed over this node. The Router Client can be used as both a Router and an app connected Client."
}
}
}
func protoEnumValue() -> Config.DeviceConfig.Role {
switch self {
case .client:
return Config.DeviceConfig.Role.client
case .clientMute:
return Config.DeviceConfig.Role.clientMute
case .router:
return Config.DeviceConfig.Role.router
case .routerClient:
return Config.DeviceConfig.Role.routerClient
}
}
}

View file

@ -0,0 +1,56 @@
//
// GpsFormats.swift
// Meshtastic
//
// Copyright(c) Garth Vander Houwen 8/20/22.
//
import Foundation
enum GpsFormats: Int, CaseIterable, Identifiable {
case gpsFormatDec = 0
case gpsFormatDms = 1
case gpsFormatUtm = 2
case gpsFormatMgrs = 3
case gpsFormatOlc = 4
case gpsFormatOsgr = 5
var id: Int { self.rawValue }
var description: String {
get {
switch self {
case .gpsFormatDec:
return "Decimal Degrees Format"
case .gpsFormatDms:
return "Degrees Minutes Seconds"
case .gpsFormatUtm:
return "Universal Transverse Mercator"
case .gpsFormatMgrs:
return "Military Grid Reference System"
case .gpsFormatOlc:
return "Open Location Code (aka Plus Codes)"
case .gpsFormatOsgr:
return "Ordnance Survey Grid Reference"
}
}
}
func protoEnumValue() -> Config.DisplayConfig.GpsCoordinateFormat {
switch self {
case .gpsFormatDec:
return Config.DisplayConfig.GpsCoordinateFormat.gpsFormatDec
case .gpsFormatDms:
return Config.DisplayConfig.GpsCoordinateFormat.gpsFormatDms
case .gpsFormatUtm:
return Config.DisplayConfig.GpsCoordinateFormat.gpsFormatUtm
case .gpsFormatMgrs:
return Config.DisplayConfig.GpsCoordinateFormat.gpsFormatMgrs
case .gpsFormatOlc:
return Config.DisplayConfig.GpsCoordinateFormat.gpsFormatOlc
case .gpsFormatOsgr:
return Config.DisplayConfig.GpsCoordinateFormat.gpsFormatOsgr
}
}
}

View file

@ -0,0 +1,181 @@
//
// LoraConfig.swift
// Meshtastic
//
// Copyright(c) Garth Vander Houwen 8/20/22.
//
import Foundation
enum RegionCodes : Int, CaseIterable, Identifiable {
case unset = 0
case us = 1
case eu433 = 2
case eu868 = 3
case cn = 4
case jp = 5
case anz = 6
case kr = 7
case tw = 8
case ru = 9
case `in` = 10
case nz865 = 11
case th = 12
var id: Int { self.rawValue }
var description: String {
get {
switch self {
case .unset:
return "Please set a region"
case .us:
return "United States"
case .eu433:
return "European Union 433mhz"
case .eu868:
return "European Union 868mhz"
case .cn:
return "China"
case .jp:
return "Japan"
case .anz:
return "Australia / New Zealand"
case .kr:
return "Korea"
case .tw:
return "Taiwan"
case .ru:
return "Russia"
case .in:
return "India"
case .nz865:
return "New Zealand 865mhz"
case .th:
return "Thailand"
}
}
}
func protoEnumValue() -> Config.LoRaConfig.RegionCode {
switch self {
case .unset:
return Config.LoRaConfig.RegionCode.unset
case .us:
return Config.LoRaConfig.RegionCode.us
case .eu433:
return Config.LoRaConfig.RegionCode.eu433
case .eu868:
return Config.LoRaConfig.RegionCode.eu868
case .cn:
return Config.LoRaConfig.RegionCode.cn
case .jp:
return Config.LoRaConfig.RegionCode.jp
case .anz:
return Config.LoRaConfig.RegionCode.anz
case .kr:
return Config.LoRaConfig.RegionCode.kr
case .tw:
return Config.LoRaConfig.RegionCode.tw
case .ru:
return Config.LoRaConfig.RegionCode.ru
case .in:
return Config.LoRaConfig.RegionCode.in
case .nz865:
return Config.LoRaConfig.RegionCode.nz865
case .th:
return Config.LoRaConfig.RegionCode.th
}
}
}
enum ModemPresets : Int, CaseIterable, Identifiable {
case LongFast = 0
case LongSlow = 1
case VLongSlow = 2
case MedSlow = 3
case MedFast = 4
case ShortSlow = 5
case ShortFast = 6
var id: Int { self.rawValue }
var description: String {
get {
switch self {
case .LongFast:
return "Long Range - Fast"
case .LongSlow:
return "Long Range - Slow"
case .VLongSlow:
return "Very Long Range - Slow"
case .MedSlow:
return "Medium Range - Slow"
case .MedFast:
return "Medium Range - Fast"
case .ShortSlow:
return "Short Range - Slow"
case .ShortFast:
return "Short Range - Fast"
}
}
}
func protoEnumValue() -> Config.LoRaConfig.ModemPreset {
switch self {
case .LongFast:
return Config.LoRaConfig.ModemPreset.longFast
case .LongSlow:
return Config.LoRaConfig.ModemPreset.longSlow
case .VLongSlow:
return Config.LoRaConfig.ModemPreset.vlongSlow
case .MedSlow:
return Config.LoRaConfig.ModemPreset.medSlow
case .MedFast:
return Config.LoRaConfig.ModemPreset.medFast
case .ShortSlow:
return Config.LoRaConfig.ModemPreset.shortSlow
case .ShortFast:
return Config.LoRaConfig.ModemPreset.shortFast
}
}
}
enum HopValues : Int, CaseIterable, Identifiable {
case oneHop = 1
case twoHops = 2
case threeHops = 0
case fourHops = 4
case fiveHops = 5
case sixHops = 6
case sevenHops = 7
var id: Int { self.rawValue }
var description: String {
get {
switch self {
case .oneHop:
return "One Hop"
case .twoHops:
return "Two Hops"
case .threeHops:
return "Three Hops"
case .fourHops:
return "Four Hops"
case .fiveHops:
return "Five Hops"
case .sixHops:
return "Six Hops"
case .sevenHops:
return "Seven Hops"
}
}
}
}

View file

@ -0,0 +1,73 @@
//
// ScreenIntervals.swift
// Meshtastic
//
// Copyright(c) Garth Vander Houwen 8/20/22.
//
import Foundation
// Default of 0 is One Minute
enum ScreenOnIntervals: Int, CaseIterable, Identifiable {
case oneMinute = 60
case fiveMinutes = 300
case tenMinutes = 0
case fifteenMinutes = 900
case thirtyMinutes = 1800
case oneHour = 3600
case max = 31536000 // One Year
var id: Int { self.rawValue }
var description: String {
get {
switch self {
case .oneMinute:
return "One Minute"
case .fiveMinutes:
return "Five Minutes"
case .tenMinutes:
return "Ten Minutes"
case .fifteenMinutes:
return "Fifteen Minutes"
case .thirtyMinutes:
return "Thirty Minutes"
case .oneHour:
return "One Hour"
case .max:
return "Always On"
}
}
}
}
// Default of 0 is off
enum ScreenCarouselIntervals: Int, CaseIterable, Identifiable {
case off = 0
case thirtySeconds = 30
case oneMinute = 60
case fiveMinutes = 300
case tenMinutes = 600
case fifteenMinutes = 900
var id: Int { self.rawValue }
var description: String {
get {
switch self {
case .off:
return "Off"
case .thirtySeconds:
return "Thirty Seconds"
case .oneMinute:
return "One Minute"
case .fiveMinutes:
return "Five Minutes"
case .tenMinutes:
return "Ten Minutes"
case .fifteenMinutes:
return "Fifteen Minutes"
}
}
}
}

View file

@ -0,0 +1,42 @@
//
// WiFiModes.swift
// Meshtastic
//
// Copyright(c) Garth Vander Houwen 8/20/22.
//
import Foundation
enum WiFiModes: Int, CaseIterable, Identifiable {
case client = 0
case accessPoint = 1
case accessPointHidden = 2
var id: Int { self.rawValue }
var description: String {
get {
switch self {
case .client:
return "Client"
case .accessPoint:
return "Software Access Point"
case .accessPointHidden:
return "Software Access Point (Hidden)"
}
}
}
func protoEnumValue() -> Config.WiFiConfig.WiFiMode {
switch self {
case .client:
return Config.WiFiConfig.WiFiMode.client
case .accessPoint:
return Config.WiFiConfig.WiFiMode.accessPoint
case .accessPointHidden:
return Config.WiFiConfig.WiFiMode.accessPointHidden
}
}
}

View file

@ -23,6 +23,17 @@ extension Date {
}
}
extension Int {
func numberOfDigits() -> Int {
if abs(self) < 10 {
return 1
} else {
return 1 + (self/10).numberOfDigits()
}
}
}
extension String {
/// Create `Data` from hexadecimal string representation

View file

@ -92,6 +92,92 @@ func localConfig (config: Config, meshlogging: Bool, context:NSManagedObjectCont
}
}
if config.payloadVariant == Config.OneOf_PayloadVariant.bluetooth(config.bluetooth) {
var isDefault = false
if (try! config.bluetooth.jsonString()) == "{}" {
isDefault = true
print("📶 Default Bluetooth config")
if meshlogging { MeshLogger.log("🖥️ Default Bluetooth config \(String(nodeNum))") }
} else {
if meshlogging { MeshLogger.log("🖥️ Custom Bluetooth config \(String(nodeNum))") }
print("📶 Custom Bluetooth config")
}
let fetchNodeInfoRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "NodeInfoEntity")
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
// Found a node, save Device Config
if !fetchedNode.isEmpty {
if fetchedNode[0].bluetoothConfig == nil {
let newBluetoothConfig = BluetoothConfigEntity(context: context)
if isDefault {
newBluetoothConfig.enabled = true
newBluetoothConfig.mode = Int32(config.bluetooth.mode.rawValue)
newBluetoothConfig.fixedPin = Int32("123456") ?? 123456
} else {
newBluetoothConfig.enabled = config.bluetooth.enabled
newBluetoothConfig.mode = Int32(config.bluetooth.mode.rawValue)
newBluetoothConfig.fixedPin = Int32(config.display.autoScreenCarouselSecs)
}
fetchedNode[0].bluetoothConfig = newBluetoothConfig
} else {
if isDefault {
fetchedNode[0].displayConfig?.screenOnSeconds = 0
fetchedNode[0].displayConfig?.screenCarouselInterval = 0
fetchedNode[0].displayConfig?.gpsFormat = 0
fetchedNode[0].displayConfig?.compassNorthTop = false
} else {
fetchedNode[0].displayConfig?.gpsFormat = Int32(config.display.gpsFormat.rawValue)
fetchedNode[0].displayConfig?.screenOnSeconds = Int32(config.display.screenOnSecs)
fetchedNode[0].displayConfig?.screenCarouselInterval = Int32(config.display.autoScreenCarouselSecs)
fetchedNode[0].displayConfig?.compassNorthTop = config.display.compassNorthTop
}
}
do {
try context.save()
if meshlogging { MeshLogger.log("💾 Updated Display Config for node number: \(String(nodeNum))") }
} catch {
context.rollback()
let nsError = error as NSError
print("💥 Error Updating Core Data DisplayConfigEntity: \(nsError)")
}
} else {
print("💥 No Nodes found in local database matching node number \(nodeNum) unable to save Display Config")
}
} catch {
let nsError = error as NSError
print("💥 Fetching node for core data DisplayConfigEntity failed: \(nsError)")
}
}
if config.payloadVariant == Config.OneOf_PayloadVariant.display(config.display) {
var isDefault = false
@ -99,11 +185,12 @@ func localConfig (config: Config, meshlogging: Bool, context:NSManagedObjectCont
if (try! config.display.jsonString()) == "{}" {
isDefault = true
print("🖥️ Default Display config")
if meshlogging { MeshLogger.log("🖥️ Default Display config \(String(nodeNum))") }
} else {
print("🖥️ Custom Display config")
if meshlogging { MeshLogger.log("🖥️ Custom Display config \(String(nodeNum))") }
}
let fetchNodeInfoRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "NodeInfoEntity")

View file

@ -23,7 +23,13 @@ struct BluetoothConfig: View {
@State var mode = 0
/// Specified pin for PairingMode.FixedPin
@State var fixedPin = 123456
@State var fixedPin = "123456"
let numberFormatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .none
return formatter
}()
var body: some View {
@ -40,16 +46,36 @@ struct BluetoothConfig: View {
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
Picker("Pairing PIN", selection: $mode ) {
Picker("Pairing Mode", selection: $mode ) {
ForEach(BluetoothModes.allCases) { bm in
Text(bm.description)
}
}
.pickerStyle(DefaultPickerStyle())
if mode == 2 {
if mode == 1 {
HStack {
Label("Fixed PIN", systemImage: "wallet.pass")
TextField("Fixed PIN", text: $fixedPin)
.foregroundColor(.gray)
.onChange(of: fixedPin, perform: { value in
let digitCount = fixedPin.utf8.count
// Only mess with the value if it is too big
if digitCount > 6 || digitCount < 6 {
fixedPin = "123456"
}
if digitCount < 6 {
fixedPin = "123456"
}
})
.foregroundColor(.gray)
}
.keyboardType(.decimalPad)
}
}
}
@ -78,7 +104,7 @@ struct BluetoothConfig: View {
var bc = Config.BluetoothConfig()
bc.enabled = enabled
bc.mode = BluetoothModes(rawValue: mode)?.protoEnumValue() ?? Config.BluetoothConfig.PairingMode.randomPin
bc.fixedPin = UInt32(fixedPin)
bc.fixedPin = UInt32(fixedPin) ?? 123456
let adminMessageId = 0//bleManager.saveBluetoothConfig(config: bc, fromUser: node!.user!, toUser: node!.user!)
@ -109,7 +135,7 @@ struct BluetoothConfig: View {
self.enabled = node!.bluetoothConfig?.enabled ?? true
self.mode = Int(node!.bluetoothConfig?.mode ?? 0)
self.fixedPin = Int(node!.bluetoothConfig?.fixedPin ?? 123456)
//self.fixedPin = (String(node!.bluetoothConfig?.fixedPin) ?? "123456")
self.hasChanges = false
self.initialLoad = false
}
@ -132,7 +158,7 @@ struct BluetoothConfig: View {
if node != nil && node!.bluetoothConfig != nil {
if newFixedPin != node!.bluetoothConfig!.fixedPin { hasChanges = true }
if newFixedPin != String(node!.bluetoothConfig!.fixedPin) { hasChanges = true }
}
}

View file

@ -6,46 +6,6 @@
//
import SwiftUI
// Default of 0 is Client
enum DeviceRoles: Int, CaseIterable, Identifiable {
case client = 0
case clientMute = 1
case router = 2
case routerClient = 3
var id: Int { self.rawValue }
var description: String {
get {
switch self {
case .client:
return "Client (default) - App connected client."
case .clientMute:
return "Client Mute - Same as a client except packets will not hop over this node, does not contribute to routing packets for mesh."
case .router:
return "Router - Mesh packets will prefer to be routed over this node. This node will not be used by client apps. The wifi/ble radios and the oled screen will be put to sleep."
case .routerClient:
return "Router Client - Mesh packets will prefer to be routed over this node. The Router Client can be used as both a Router and an app connected Client."
}
}
}
func protoEnumValue() -> Config.DeviceConfig.Role {
switch self {
case .client:
return Config.DeviceConfig.Role.client
case .clientMute:
return Config.DeviceConfig.Role.clientMute
case .router:
return Config.DeviceConfig.Role.router
case .routerClient:
return Config.DeviceConfig.Role.routerClient
}
}
}
struct DeviceConfig: View {
@Environment(\.managedObjectContext) var context

View file

@ -7,119 +7,6 @@
import SwiftUI
enum GpsFormats: Int, CaseIterable, Identifiable {
case gpsFormatDec = 0
case gpsFormatDms = 1
case gpsFormatUtm = 2
case gpsFormatMgrs = 3
case gpsFormatOlc = 4
case gpsFormatOsgr = 5
var id: Int { self.rawValue }
var description: String {
get {
switch self {
case .gpsFormatDec:
return "Decimal Degrees Format"
case .gpsFormatDms:
return "Degrees Minutes Seconds"
case .gpsFormatUtm:
return "Universal Transverse Mercator"
case .gpsFormatMgrs:
return "Military Grid Reference System"
case .gpsFormatOlc:
return "Open Location Code (aka Plus Codes)"
case .gpsFormatOsgr:
return "Ordnance Survey Grid Reference"
}
}
}
func protoEnumValue() -> Config.DisplayConfig.GpsCoordinateFormat {
switch self {
case .gpsFormatDec:
return Config.DisplayConfig.GpsCoordinateFormat.gpsFormatDec
case .gpsFormatDms:
return Config.DisplayConfig.GpsCoordinateFormat.gpsFormatDms
case .gpsFormatUtm:
return Config.DisplayConfig.GpsCoordinateFormat.gpsFormatUtm
case .gpsFormatMgrs:
return Config.DisplayConfig.GpsCoordinateFormat.gpsFormatMgrs
case .gpsFormatOlc:
return Config.DisplayConfig.GpsCoordinateFormat.gpsFormatOlc
case .gpsFormatOsgr:
return Config.DisplayConfig.GpsCoordinateFormat.gpsFormatOsgr
}
}
}
// Default of 0 is One Minute
enum ScreenOnIntervals: Int, CaseIterable, Identifiable {
case oneMinute = 60
case fiveMinutes = 300
case tenMinutes = 0
case fifteenMinutes = 900
case thirtyMinutes = 1800
case oneHour = 3600
case max = 31536000 // One Year
var id: Int { self.rawValue }
var description: String {
get {
switch self {
case .oneMinute:
return "One Minute"
case .fiveMinutes:
return "Five Minutes"
case .tenMinutes:
return "Ten Minutes"
case .fifteenMinutes:
return "Fifteen Minutes"
case .thirtyMinutes:
return "Thirty Minutes"
case .oneHour:
return "One Hour"
case .max:
return "Always On"
}
}
}
}
// Default of 0 is off
enum ScreenCarouselIntervals: Int, CaseIterable, Identifiable {
case off = 0
case thirtySeconds = 30
case oneMinute = 60
case fiveMinutes = 300
case tenMinutes = 600
case fifteenMinutes = 900
var id: Int { self.rawValue }
var description: String {
get {
switch self {
case .off:
return "Off"
case .thirtySeconds:
return "Thirty Seconds"
case .oneMinute:
return "One Minute"
case .fiveMinutes:
return "Five Minutes"
case .tenMinutes:
return "Ten Minutes"
case .fifteenMinutes:
return "Fifteen Minutes"
}
}
}
}
struct DisplayConfig: View {
@Environment(\.managedObjectContext) var context

View file

@ -7,179 +7,6 @@
import SwiftUI
enum RegionCodes : Int, CaseIterable, Identifiable {
case unset = 0
case us = 1
case eu433 = 2
case eu868 = 3
case cn = 4
case jp = 5
case anz = 6
case kr = 7
case tw = 8
case ru = 9
case `in` = 10
case nz865 = 11
case th = 12
var id: Int { self.rawValue }
var description: String {
get {
switch self {
case .unset:
return "Please set a region"
case .us:
return "United States"
case .eu433:
return "European Union 433mhz"
case .eu868:
return "European Union 868mhz"
case .cn:
return "China"
case .jp:
return "Japan"
case .anz:
return "Australia / New Zealand"
case .kr:
return "Korea"
case .tw:
return "Taiwan"
case .ru:
return "Russia"
case .in:
return "India"
case .nz865:
return "New Zealand 865mhz"
case .th:
return "Thailand"
}
}
}
func protoEnumValue() -> Config.LoRaConfig.RegionCode {
switch self {
case .unset:
return Config.LoRaConfig.RegionCode.unset
case .us:
return Config.LoRaConfig.RegionCode.us
case .eu433:
return Config.LoRaConfig.RegionCode.eu433
case .eu868:
return Config.LoRaConfig.RegionCode.eu868
case .cn:
return Config.LoRaConfig.RegionCode.cn
case .jp:
return Config.LoRaConfig.RegionCode.jp
case .anz:
return Config.LoRaConfig.RegionCode.anz
case .kr:
return Config.LoRaConfig.RegionCode.kr
case .tw:
return Config.LoRaConfig.RegionCode.tw
case .ru:
return Config.LoRaConfig.RegionCode.ru
case .in:
return Config.LoRaConfig.RegionCode.in
case .nz865:
return Config.LoRaConfig.RegionCode.nz865
case .th:
return Config.LoRaConfig.RegionCode.th
}
}
}
enum ModemPresets : Int, CaseIterable, Identifiable {
case LongFast = 0
case LongSlow = 1
case VLongSlow = 2
case MedSlow = 3
case MedFast = 4
case ShortSlow = 5
case ShortFast = 6
var id: Int { self.rawValue }
var description: String {
get {
switch self {
case .LongFast:
return "Long Range - Fast"
case .LongSlow:
return "Long Range - Slow"
case .VLongSlow:
return "Very Long Range - Slow"
case .MedSlow:
return "Medium Range - Slow"
case .MedFast:
return "Medium Range - Fast"
case .ShortSlow:
return "Short Range - Slow"
case .ShortFast:
return "Short Range - Fast"
}
}
}
func protoEnumValue() -> Config.LoRaConfig.ModemPreset {
switch self {
case .LongFast:
return Config.LoRaConfig.ModemPreset.longFast
case .LongSlow:
return Config.LoRaConfig.ModemPreset.longSlow
case .VLongSlow:
return Config.LoRaConfig.ModemPreset.vlongSlow
case .MedSlow:
return Config.LoRaConfig.ModemPreset.medSlow
case .MedFast:
return Config.LoRaConfig.ModemPreset.medFast
case .ShortSlow:
return Config.LoRaConfig.ModemPreset.shortSlow
case .ShortFast:
return Config.LoRaConfig.ModemPreset.shortFast
}
}
}
enum HopValues : Int, CaseIterable, Identifiable {
case oneHop = 1
case twoHops = 2
case threeHops = 0
case fourHops = 4
case fiveHops = 5
case sixHops = 6
case sevenHops = 7
var id: Int { self.rawValue }
var description: String {
get {
switch self {
case .oneHop:
return "One Hop"
case .twoHops:
return "Two Hops"
case .threeHops:
return "Three Hops"
case .fourHops:
return "Four Hops"
case .fiveHops:
return "Five Hops"
case .sixHops:
return "Six Hops"
case .sevenHops:
return "Seven Hops"
}
}
}
}
struct LoRaConfig: View {
@Environment(\.managedObjectContext) var context

View file

@ -7,40 +7,6 @@
import SwiftUI
enum WiFiModes: Int, CaseIterable, Identifiable {
case client = 0
case accessPoint = 1
case accessPointHidden = 2
var id: Int { self.rawValue }
var description: String {
get {
switch self {
case .client:
return "Client"
case .accessPoint:
return "Software Access Point"
case .accessPointHidden:
return "Software Access Point (Hidden)"
}
}
}
func protoEnumValue() -> Config.WiFiConfig.WiFiMode {
switch self {
case .client:
return Config.WiFiConfig.WiFiMode.client
case .accessPoint:
return Config.WiFiConfig.WiFiMode.accessPoint
case .accessPointHidden:
return Config.WiFiConfig.WiFiMode.accessPointHidden
}
}
}
struct WiFiConfig: View {
@Environment(\.managedObjectContext) var context
@ -125,12 +91,12 @@ struct WiFiConfig: View {
// Only mess with the value if it is too big
if totalBytes > 63 {
let firstNBytes = Data(ssid.utf8.prefix(63))
let firstNBytes = Data(password.utf8.prefix(63))
if let maxBytesString = String(data: firstNBytes, encoding: String.Encoding.utf8) {
// Set the shortName back to the last place where it was the right size
ssid = maxBytesString
password = maxBytesString
}
}
})