From 594ebfd552eea9cd2bbcb3c1d7e8c77446309f57 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sun, 12 Jun 2022 15:29:06 -0700 Subject: [PATCH] Update protobufs, add power config view --- Meshtastic Apple.xcodeproj/project.pbxproj | 4 + MeshtasticApple/Protobufs/config.pb.swift | 22 +-- .../Views/Settings/PowerConfig.swift | 140 ++++++++++++++++++ MeshtasticApple/Views/Settings/Settings.swift | 3 +- 4 files changed, 151 insertions(+), 18 deletions(-) create mode 100644 MeshtasticApple/Views/Settings/PowerConfig.swift diff --git a/Meshtastic Apple.xcodeproj/project.pbxproj b/Meshtastic Apple.xcodeproj/project.pbxproj index 6c012ab5..eb46a70b 100644 --- a/Meshtastic Apple.xcodeproj/project.pbxproj +++ b/Meshtastic Apple.xcodeproj/project.pbxproj @@ -18,6 +18,7 @@ DD23A50F26FD1B4400D9B90C /* PeripheralModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD23A50E26FD1B4400D9B90C /* PeripheralModel.swift */; }; DD2553572855B02500E55709 /* LoRaConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD2553562855B02500E55709 /* LoRaConfig.swift */; }; DD2553592855B52700E55709 /* PositionConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD2553582855B52700E55709 /* PositionConfig.swift */; }; + DD25535D285666C700E55709 /* PowerConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD25535C285666C700E55709 /* PowerConfig.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 */; }; @@ -98,6 +99,7 @@ DD23A50E26FD1B4400D9B90C /* PeripheralModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeripheralModel.swift; sourceTree = ""; }; DD2553562855B02500E55709 /* LoRaConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoRaConfig.swift; sourceTree = ""; }; DD2553582855B52700E55709 /* PositionConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionConfig.swift; sourceTree = ""; }; + DD25535C285666C700E55709 /* PowerConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PowerConfig.swift; sourceTree = ""; }; DD2E65252767A01F00E45FC5 /* NodeDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeDetail.swift; sourceTree = ""; }; DD3501882852FC3B000FC853 /* Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = ""; }; DD35018A2852FC79000FC853 /* UserSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSettings.swift; sourceTree = ""; }; @@ -233,6 +235,7 @@ DD2553582855B52700E55709 /* PositionConfig.swift */, DD8169FA271F1F3A00F4AB02 /* MeshLog.swift */, DD8169FE272476C700F4AB02 /* LogDocument.swift */, + DD25535C285666C700E55709 /* PowerConfig.swift */, ); path = Settings; sourceTree = ""; @@ -592,6 +595,7 @@ DDF924CA26FBB953009FE055 /* ConnectedDevice.swift in Sources */, DDAF8C5D26ED09490058C060 /* portnums.pb.swift in Sources */, DD9D8F2F2764403B00080993 /* Meshtastic.xcdatamodeld in Sources */, + DD25535D285666C700E55709 /* PowerConfig.swift in Sources */, DD1BF2F92776FE2E008C8D2F /* UserMessageList.swift in Sources */, DDB2CC6E27F3EB47009C5FCC /* telemetry.pb.swift in Sources */, DD23A50F26FD1B4400D9B90C /* PeripheralModel.swift in Sources */, diff --git a/MeshtasticApple/Protobufs/config.pb.swift b/MeshtasticApple/Protobufs/config.pb.swift index 10c67cc5..e0d8a2a0 100644 --- a/MeshtasticApple/Protobufs/config.pb.swift +++ b/MeshtasticApple/Protobufs/config.pb.swift @@ -390,7 +390,7 @@ struct Config { /// If set, we are powered from a low-current source (i.e. solar), so even if it looks like we have power flowing in /// we should try to minimize power consumption as much as possible. /// YOU DO NOT NEED TO SET THIS IF YOU'VE set is_router (it is implied in that case). - var isLowPower: Bool = false + var isPowerSaving: Bool = false /// /// Circumvents the logic block for determining whether the device is powered or not. @@ -401,10 +401,6 @@ struct Config { /// If non-zero, the device will fully power off this many seconds after external power is removed. var onBatteryShutdownAfterSecs: UInt32 = 0 - /// - /// If set to true, enable power saving features of the esp32 - var isPowerSaving: Bool = false - /// /// Ratio of voltage divider for battery pin eg. 3.20 (R1=100k, R2=220k) /// Overrides the ADC_MULTIPLIER defined in variant for battery voltage calculation. @@ -1350,10 +1346,9 @@ extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImple static let protoMessageName: String = Config.protoMessageName + ".PowerConfig" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 1: .standard(proto: "charge_current"), - 2: .standard(proto: "is_low_power"), + 2: .standard(proto: "is_power_saving"), 3: .standard(proto: "is_always_powered"), 4: .standard(proto: "on_battery_shutdown_after_secs"), - 5: .standard(proto: "is_power_saving"), 6: .standard(proto: "adc_multiplier_override"), 7: .standard(proto: "wait_bluetooth_secs"), 9: .standard(proto: "mesh_sds_timeout_secs"), @@ -1369,10 +1364,9 @@ extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImple // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { case 1: try { try decoder.decodeSingularEnumField(value: &self.chargeCurrent) }() - case 2: try { try decoder.decodeSingularBoolField(value: &self.isLowPower) }() + case 2: try { try decoder.decodeSingularBoolField(value: &self.isPowerSaving) }() case 3: try { try decoder.decodeSingularBoolField(value: &self.isAlwaysPowered) }() case 4: try { try decoder.decodeSingularUInt32Field(value: &self.onBatteryShutdownAfterSecs) }() - case 5: try { try decoder.decodeSingularBoolField(value: &self.isPowerSaving) }() case 6: try { try decoder.decodeSingularFloatField(value: &self.adcMultiplierOverride) }() case 7: try { try decoder.decodeSingularUInt32Field(value: &self.waitBluetoothSecs) }() case 9: try { try decoder.decodeSingularUInt32Field(value: &self.meshSdsTimeoutSecs) }() @@ -1388,8 +1382,8 @@ extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImple if self.chargeCurrent != .maunset { try visitor.visitSingularEnumField(value: self.chargeCurrent, fieldNumber: 1) } - if self.isLowPower != false { - try visitor.visitSingularBoolField(value: self.isLowPower, fieldNumber: 2) + if self.isPowerSaving != false { + try visitor.visitSingularBoolField(value: self.isPowerSaving, fieldNumber: 2) } if self.isAlwaysPowered != false { try visitor.visitSingularBoolField(value: self.isAlwaysPowered, fieldNumber: 3) @@ -1397,9 +1391,6 @@ extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImple if self.onBatteryShutdownAfterSecs != 0 { try visitor.visitSingularUInt32Field(value: self.onBatteryShutdownAfterSecs, fieldNumber: 4) } - if self.isPowerSaving != false { - try visitor.visitSingularBoolField(value: self.isPowerSaving, fieldNumber: 5) - } if self.adcMultiplierOverride != 0 { try visitor.visitSingularFloatField(value: self.adcMultiplierOverride, fieldNumber: 6) } @@ -1423,10 +1414,9 @@ extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImple static func ==(lhs: Config.PowerConfig, rhs: Config.PowerConfig) -> Bool { if lhs.chargeCurrent != rhs.chargeCurrent {return false} - if lhs.isLowPower != rhs.isLowPower {return false} + if lhs.isPowerSaving != rhs.isPowerSaving {return false} if lhs.isAlwaysPowered != rhs.isAlwaysPowered {return false} if lhs.onBatteryShutdownAfterSecs != rhs.onBatteryShutdownAfterSecs {return false} - if lhs.isPowerSaving != rhs.isPowerSaving {return false} if lhs.adcMultiplierOverride != rhs.adcMultiplierOverride {return false} if lhs.waitBluetoothSecs != rhs.waitBluetoothSecs {return false} if lhs.meshSdsTimeoutSecs != rhs.meshSdsTimeoutSecs {return false} diff --git a/MeshtasticApple/Views/Settings/PowerConfig.swift b/MeshtasticApple/Views/Settings/PowerConfig.swift new file mode 100644 index 00000000..99b0f0bd --- /dev/null +++ b/MeshtasticApple/Views/Settings/PowerConfig.swift @@ -0,0 +1,140 @@ +// +// PowerConfig.swift +// Meshtastic Apple +// +// Copyright (c) Garth Vander Houwen 6/12/22. +// + +import Foundation +import SwiftUI + +enum ChargeCurrents: Int, CaseIterable, Identifiable { + + case maunset = 0 + case ma100 = 1 + case ma190 = 2 + case ma280 = 3 + case ma360 = 4 + case ma450 = 5 + case ma550 = 6 + case ma630 = 7 + case ma700 = 8 + case ma780 = 9 + case ma880 = 10 + case ma960 = 11 + case ma1000 = 12 + case ma1080 = 13 + case ma1160 = 14 + case ma1240 = 15 + case ma1320 = 16 + + var id: Int { self.rawValue } + var description: String { + get { + switch self { + + case .maunset: + return "UNSET (default)" + case .ma100: + return "100 mA" + case .ma190: + return "190 mA" + case .ma280: + return "280 mA" + case .ma360: + return "360 mA" + case .ma450: + return "450 mA" + case .ma550: + return "550 mA" + case .ma630: + return "630 mA" + case .ma700: + return "700 mA" + case .ma780: + return "780 mA" + case .ma880: + return "880 mA" + case .ma960: + return "960 mA" + case .ma1000: + return "1000 mA" + case .ma1080: + return "1080 mA" + case .ma1160: + return "1160 mA" + case .ma1240: + return "1240 mA" + case .ma1320: + return "1320 mA" + } + } + } +} + + +struct PowerConfig: View { + + @Environment(\.managedObjectContext) var context + @EnvironmentObject var bleManager: BLEManager + + @State var chargeCurrent = 0 + @State var deviceGpsEnabled = true + @State var fixedPosition = false + @State var gpsUpdateInterval: Int32 = 0 + @State var gpsAttemptTime: Int32 = 0 + @State var positionBroadcastSeconds: Int32 = 0 + + var body: some View { + + VStack { + + Form { + + Section(header: Text("Charging Options")) { + + Picker("Charge Current", selection: $chargeCurrent) { + ForEach(ChargeCurrents.allCases) { cc in + Text(cc.description) + } + } + .pickerStyle(DefaultPickerStyle()) + + Text("Sets the charge control current of devices with a battery charger that can be configured. This is passed into the axp power management chip like on the tbeam.") + .font(.caption) + .listRowSeparator(.visible) + + + Toggle(isOn: $fixedPosition) { + + Label("Fixed Position", systemImage: "location.square.fill") + } + .toggleStyle(SwitchToggleStyle(tint: .accentColor)) + if fixedPosition { + + Text("Set to current location here") + .font(.caption) + .listRowSeparator(.visible) + } + } + Section(header: Text("Position Flags")) { + Text("TODO") + .font(.caption) + .listRowSeparator(.visible) + } + } + } + .navigationTitle("Power Config") + .navigationBarItems(trailing: + + ZStack { + + ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.lastFourCode : "????") + }) + .onAppear { + + self.bleManager.context = context + } + .navigationViewStyle(StackNavigationViewStyle()) + } +} diff --git a/MeshtasticApple/Views/Settings/Settings.swift b/MeshtasticApple/Views/Settings/Settings.swift index 4db480ad..cbedcebd 100644 --- a/MeshtasticApple/Views/Settings/Settings.swift +++ b/MeshtasticApple/Views/Settings/Settings.swift @@ -64,7 +64,7 @@ struct Settings: View { Text("Position") } NavigationLink { - PositionConfig() + PowerConfig() } label: { Image(systemName: "bolt") @@ -72,7 +72,6 @@ struct Settings: View { Text("Power") } - .disabled(true) } Section("Module Configuration") {