Merge pull request #234 from meshtastic/2.0_Alpha_Launch

Bump Version, Code Cleanup
This commit is contained in:
Garth Vander Houwen 2022-11-12 09:00:47 -08:00 committed by GitHub
commit 3bcfd70aed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 64 additions and 374 deletions

View file

@ -964,7 +964,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 2.0.1;
MARKETING_VERSION = 2.0.2;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTS_MACCATALYST = YES;
@ -996,7 +996,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 2.0.1;
MARKETING_VERSION = 2.0.2;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTS_MACCATALYST = YES;

View file

@ -7,22 +7,15 @@
import SwiftUI
func TelemetryToCsvFile(telemetry: [TelemetryEntity], metricsType: Int) -> String {
var csvString: String = ""
if metricsType == 0 {
// Create Device Metrics Header
csvString = "Battery Level, Voltage, Channel Utilization, Airtime, Timestamp"
for dm in telemetry{
if dm.metricsType == 0 {
csvString += "\n"
csvString += String("\(dm.batteryLevel) %")
csvString += String(dm.batteryLevel)
csvString += ", "
csvString += String(dm.voltage)
csvString += ", "
@ -33,18 +26,13 @@ func TelemetryToCsvFile(telemetry: [TelemetryEntity], metricsType: Int) -> Strin
csvString += dm.time?.formattedDate(format: "yyyy-MM-dd HH:mm:ss") ?? "Unknown Age"
}
}
} else if metricsType == 1 {
// Create Environment Telemetry Header
csvString = "Temperature, Relative Humidity, Barometric Pressure, Gas Resistance, Voltage, Current"
for dm in telemetry{
if dm.metricsType == 1 {
csvString += "\n"
csvString += String("\(dm.temperature)°")
csvString += String(dm.temperature)
csvString += ", "
csvString += String(dm.relativeHumidity)
csvString += ", "
@ -60,19 +48,14 @@ func TelemetryToCsvFile(telemetry: [TelemetryEntity], metricsType: Int) -> Strin
}
}
}
return csvString
}
func PositionToCsvFile(positions: [PositionEntity]) -> String {
var csvString: String = ""
// Create Position Header
csvString = "SeqNo, Latitude, Longitude, Alt, Sats, Speed, Heading, SNR, Timestamp"
for pos in positions {
csvString += "\n"
csvString += String(pos.seqNo)
csvString += ", "
@ -90,9 +73,7 @@ func PositionToCsvFile(positions: [PositionEntity]) -> String {
csvString += ", "
csvString += String(pos.snr)
csvString += ", "
csvString += pos.time?.formattedDate(format: "yyyy-MM-dd HH:mm:ss") ?? "Unknown Age"
}
return csvString
}

View file

@ -26,7 +26,6 @@ extension PositionEntity {
var coordinate: CLLocationCoordinate2D? {
if latitudeI != 0 && longitudeI != 0 {
let coord = CLLocationCoordinate2D(latitude: latitude!, longitude: longitude!)
return coord
} else {
return nil
@ -36,10 +35,8 @@ extension PositionEntity {
var annotaton: MKPointAnnotation {
let pointAnn = MKPointAnnotation()
if coordinate != nil {
pointAnn.coordinate = coordinate!
}
return pointAnn
}
}

View file

@ -14,7 +14,6 @@ struct NodeDetail: View {
@State private var showingDetailsPopover = false
@State var initialLoad: Bool = true
@State var satsInView = 0
@State private var showingShutdownConfirm: Bool = false
@State private var showingRebootConfirm: Bool = false
@ -416,12 +415,7 @@ struct NodeDetail: View {
}
)
.onAppear {
if self.initialLoad{
self.bleManager.context = context
self.initialLoad = false
}
self.bleManager.context = context
}
}
}

View file

@ -15,9 +15,7 @@ struct BluetoothConfig: View {
var node: NodeInfoEntity?
@State private var isPresentingSaveConfirm: Bool = false
@State var initialLoad: Bool = true
@State var hasChanges = false
@State var enabled = true
@State var mode = 0
@State var fixedPin = "123456"
@ -132,40 +130,27 @@ struct BluetoothConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
})
.onAppear {
if self.initialLoad{
self.bleManager.context = context
self.enabled = node?.bluetoothConfig?.enabled ?? true
self.mode = Int(node?.bluetoothConfig?.mode ?? 0)
self.fixedPin = String(node?.bluetoothConfig?.fixedPin ?? 123456)
self.hasChanges = false
self.initialLoad = false
}
self.bleManager.context = context
self.enabled = node?.bluetoothConfig?.enabled ?? true
self.mode = Int(node?.bluetoothConfig?.mode ?? 0)
self.fixedPin = String(node?.bluetoothConfig?.fixedPin ?? 123456)
self.hasChanges = false
}
.onChange(of: enabled) { newEnabled in
if node != nil && node!.bluetoothConfig != nil {
if newEnabled != node!.bluetoothConfig!.enabled { hasChanges = true }
}
}
.onChange(of: mode) { newMode in
if node != nil && node!.bluetoothConfig != nil {
if newMode != node!.bluetoothConfig!.mode { hasChanges = true }
}
}
.onChange(of: fixedPin) { newFixedPin in
if node != nil && node!.bluetoothConfig != nil {
if newFixedPin != String(node!.bluetoothConfig!.fixedPin) { hasChanges = true }
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
}

View file

@ -15,9 +15,7 @@ struct LoRaConfig: View {
var node: NodeInfoEntity?
@State var isPresentingSaveConfirm = false
@State var initialLoad = true
@State var hasChanges = false
@State var region = 0
@State var modemPreset = 0
@State var hopLimit = 0
@ -28,10 +26,8 @@ struct LoRaConfig: View {
var body: some View {
VStack {
Form {
Section(header: Text("Region")) {
Picker("Region", selection: $region ) {
ForEach(RegionCodes.allCases) { r in
Text(r.description)
@ -52,7 +48,6 @@ struct LoRaConfig: View {
.font(.caption)
}
Section(header: Text("Mesh Options")) {
Picker("Number of hops", selection: $hopLimit) {
ForEach(HopValues.allCases) { hop in
Text(hop.description)
@ -64,13 +59,9 @@ struct LoRaConfig: View {
}
}
.disabled(self.bleManager.connectedPeripheral == nil)
Button {
isPresentingSaveConfirm = true
} label: {
Label("Save", systemImage: "square.and.arrow.down")
}
.disabled(bleManager.connectedPeripheral == nil || !hasChanges)
@ -79,22 +70,18 @@ struct LoRaConfig: View {
.controlSize(.large)
.padding()
.confirmationDialog(
"Are you sure you want to save?",
isPresented: $isPresentingSaveConfirm,
titleVisibility: .visible
) {
Button("Save Config for \(bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : "Unknown")") {
var lc = Config.LoRaConfig()
lc.hopLimit = UInt32(hopLimit)
lc.region = RegionCodes(rawValue: region)!.protoEnumValue()
lc.modemPreset = ModemPresets(rawValue: modemPreset)!.protoEnumValue()
lc.usePreset = true
lc.txEnabled = true
let adminMessageId = bleManager.saveLoRaConfig(config: lc, fromUser: node!.user!, toUser: node!.user!)
if adminMessageId > 0 {
// Should show a saved successfully alert once I know that to be true
@ -107,53 +94,36 @@ struct LoRaConfig: View {
}
} message: {
Text("After LoRa config saves the node will reboot.")
}
}
.navigationTitle("LoRa Config")
.navigationBarItems(trailing:
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
})
.onAppear {
self.bleManager.context = context
if self.initialLoad{
self.hopLimit = Int(node?.loRaConfig?.hopLimit ?? 0)
self.region = Int(node?.loRaConfig?.regionCode ?? 0)
self.usePreset = node?.loRaConfig?.usePreset ?? true
self.modemPreset = Int(node?.loRaConfig?.modemPreset ?? 0)
self.txEnabled = node?.loRaConfig?.txEnabled ?? true
self.txPower = Int(node?.loRaConfig?.txPower ?? 0)
self.hasChanges = false
self.initialLoad = false
}
self.hopLimit = Int(node?.loRaConfig?.hopLimit ?? 0)
self.region = Int(node?.loRaConfig?.regionCode ?? 0)
self.usePreset = node?.loRaConfig?.usePreset ?? true
self.modemPreset = Int(node?.loRaConfig?.modemPreset ?? 0)
self.txEnabled = node?.loRaConfig?.txEnabled ?? true
self.txPower = Int(node?.loRaConfig?.txPower ?? 0)
self.hasChanges = false
}
.onChange(of: region) { newRegion in
if node != nil && node!.loRaConfig != nil {
if newRegion != node!.loRaConfig!.regionCode { hasChanges = true }
}
}
.onChange(of: modemPreset) { newModemPreset in
if node != nil && node!.loRaConfig != nil {
if newModemPreset != node!.loRaConfig!.modemPreset { hasChanges = true }
}
}
.onChange(of: hopLimit) { newHopLimit in
if node != nil && node!.loRaConfig != nil {
if newHopLimit != node!.loRaConfig!.hopLimit { hasChanges = true }
}
}

View file

@ -14,7 +14,6 @@ struct CannedMessagesConfig: View {
var node: NodeInfoEntity?
@State private var isPresentingSaveConfirm: Bool = false
@State var initialLoad: Bool = true
@State var hasChanges = false
@State var hasMessagesChanges = false
@State var configPreset = 0
@ -213,7 +212,6 @@ struct CannedMessagesConfig: View {
isPresentingSaveConfirm = true
} label: {
Label("Save", systemImage: "square.and.arrow.down")
}
.disabled(bleManager.connectedPeripheral == nil || (!hasChanges && !hasMessagesChanges))
@ -222,7 +220,6 @@ struct CannedMessagesConfig: View {
.controlSize(.large)
.padding()
.confirmationDialog(
"Are you sure?",
isPresented: $isPresentingSaveConfirm,
titleVisibility: .visible
@ -230,24 +227,18 @@ struct CannedMessagesConfig: View {
Button("Save Canned Messages Module Config to \(bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : "Unknown")?") {
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 = "_any"
} else {
cmc.allowInputSource = "_any"
}
cmc.inputbrokerPinA = UInt32(inputbrokerPinA)
@ -256,55 +247,41 @@ struct CannedMessagesConfig: View {
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!)
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
}
}
if hasMessagesChanges {
let adminMessageId = bleManager.saveCannedMessageModuleMessages(messages: messages, fromUser: node!.user!, toUser: node!.user!, wantResponse: true)
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
hasMessagesChanges = false
}
}
}
}
.navigationTitle("Canned Messages Config")
.navigationBarItems(trailing:
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
})
.onAppear {
if self.initialLoad{
self.bleManager.context = context
self.enabled = node?.cannedMessageConfig?.enabled ?? false
self.sendBell = node?.cannedMessageConfig?.sendBell ?? false
self.rotary1Enabled = node?.cannedMessageConfig?.rotary1Enabled ?? false
self.updown1Enabled = node?.cannedMessageConfig?.updown1Enabled ?? false
self.inputbrokerPinA = Int(node?.cannedMessageConfig?.inputbrokerPinA ?? 0)
self.inputbrokerPinB = Int(node?.cannedMessageConfig?.inputbrokerPinB ?? 0)
self.inputbrokerPinPress = Int(node?.cannedMessageConfig?.inputbrokerPinPress ?? 0)
self.inputbrokerEventCw = Int(node?.cannedMessageConfig?.inputbrokerEventCw ?? 0)
self.inputbrokerEventCcw = Int(node?.cannedMessageConfig?.inputbrokerEventCcw ?? 0)
self.inputbrokerEventPress = Int(node?.cannedMessageConfig?.inputbrokerEventPress ?? 0)
self.hasChanges = false
self.initialLoad = false
}
self.bleManager.context = context
self.enabled = node?.cannedMessageConfig?.enabled ?? false
self.sendBell = node?.cannedMessageConfig?.sendBell ?? false
self.rotary1Enabled = node?.cannedMessageConfig?.rotary1Enabled ?? false
self.updown1Enabled = node?.cannedMessageConfig?.updown1Enabled ?? false
self.inputbrokerPinA = Int(node?.cannedMessageConfig?.inputbrokerPinA ?? 0)
self.inputbrokerPinB = Int(node?.cannedMessageConfig?.inputbrokerPinB ?? 0)
self.inputbrokerPinPress = Int(node?.cannedMessageConfig?.inputbrokerPinPress ?? 0)
self.inputbrokerEventCw = Int(node?.cannedMessageConfig?.inputbrokerEventCw ?? 0)
self.inputbrokerEventCcw = Int(node?.cannedMessageConfig?.inputbrokerEventCcw ?? 0)
self.inputbrokerEventPress = Int(node?.cannedMessageConfig?.inputbrokerEventPress ?? 0)
self.hasChanges = false
}
.onChange(of: configPreset) { newPreset in

View file

@ -54,9 +54,7 @@ struct ExternalNotificationConfig: View {
var node: NodeInfoEntity?
@State private var isPresentingSaveConfirm: Bool = false
@State var initialLoad: Bool = true
@State var hasChanges = false
@State var enabled = false
@State var alertBell = false
@State var alertMessage = false
@ -67,50 +65,34 @@ struct ExternalNotificationConfig: View {
var body: some View {
VStack {
Form {
Section(header: Text("Options")) {
Toggle(isOn: $enabled) {
Label("Enabled", systemImage: "megaphone")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
Toggle(isOn: $alertBell) {
Label("Alert when receiving a bell", systemImage: "bell")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
Toggle(isOn: $alertMessage) {
Label("Alert when receiving a message", systemImage: "message")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
}
Section(header: Text("GPIO")) {
Toggle(isOn: $active) {
Label("Active", systemImage: "togglepower")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
Text("Specifies whether the external circuit is triggered when the device's GPIO is low or high.")
.font(.caption)
.listRowSeparator(.visible)
Picker("GPIO to monitor", selection: $output) {
ForEach(0..<40) {
if $0 == 0 {
Text("Unset")
} else {
Text("Pin \($0)")
}
}
@ -118,7 +100,6 @@ struct ExternalNotificationConfig: View {
.pickerStyle(DefaultPickerStyle())
Text("Specifies the GPIO that your external circuit is attached to on the device.")
.font(.caption)
Picker("GPIO Output Duration", selection: $outputMilliseconds ) {
ForEach(OutputIntervals.allCases) { oi in
Text(oi.description)
@ -130,13 +111,9 @@ struct ExternalNotificationConfig: View {
}
}
.disabled(bleManager.connectedPeripheral == nil)
Button {
isPresentingSaveConfirm = true
} label: {
Label("Save", systemImage: "square.and.arrow.down")
}
.disabled(bleManager.connectedPeripheral == nil || !hasChanges)
@ -150,7 +127,6 @@ struct ExternalNotificationConfig: View {
titleVisibility: .visible
) {
Button("Save External Notification Module Config to \(bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : "Unknown")?") {
var enc = ModuleConfig.ExternalNotificationConfig()
enc.enabled = enabled
enc.alertBell = alertBell
@ -158,84 +134,58 @@ struct ExternalNotificationConfig: View {
enc.active = active
enc.output = UInt32(output)
enc.outputMs = UInt32(outputMilliseconds)
let adminMessageId = bleManager.saveExternalNotificationModuleConfig(config: enc, fromUser: node!.user!, toUser: node!.user!)
if adminMessageId > 0{
// Should show a saved successfully alert once I know that to be true
// for now just disable the button after a successful save
hasChanges = false
} else {
}
}
}
.navigationTitle("External Notification Config")
.navigationBarItems(trailing:
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
})
.onAppear {
if self.initialLoad{
self.bleManager.context = context
self.enabled = node?.externalNotificationConfig?.enabled ?? false
self.alertBell = node?.externalNotificationConfig?.alertBell ?? false
self.alertMessage = node?.externalNotificationConfig?.alertMessage ?? false
self.active = node?.externalNotificationConfig?.active ?? false
self.output = Int(node?.externalNotificationConfig?.output ?? 0)
self.outputMilliseconds = Int(node?.externalNotificationConfig?.outputMilliseconds ?? 0)
self.hasChanges = false
self.initialLoad = false
}
self.bleManager.context = context
self.enabled = node?.externalNotificationConfig?.enabled ?? false
self.alertBell = node?.externalNotificationConfig?.alertBell ?? false
self.alertMessage = node?.externalNotificationConfig?.alertMessage ?? false
self.active = node?.externalNotificationConfig?.active ?? false
self.output = Int(node?.externalNotificationConfig?.output ?? 0)
self.outputMilliseconds = Int(node?.externalNotificationConfig?.outputMilliseconds ?? 0)
self.hasChanges = false
}
.onChange(of: enabled) { newEnabled in
if node != nil && node!.externalNotificationConfig != nil {
if newEnabled != node!.externalNotificationConfig!.enabled { hasChanges = true }
}
}
.onChange(of: alertBell) { newAlertBell in
if node != nil && node!.externalNotificationConfig != nil {
if newAlertBell != node!.externalNotificationConfig!.alertBell { hasChanges = true }
}
}
.onChange(of: alertMessage) { newAlertMessage in
if node != nil && node!.externalNotificationConfig != nil {
if newAlertMessage != node!.externalNotificationConfig!.alertMessage { hasChanges = true }
}
}
.onChange(of: active) { newActuve in
if node != nil && node!.externalNotificationConfig != nil {
if newActuve != node!.externalNotificationConfig!.active { hasChanges = true }
}
}
.onChange(of: output) { newOutput in
if node != nil && node!.externalNotificationConfig != nil {
if newOutput != node!.externalNotificationConfig!.output { hasChanges = true }
}
}
.onChange(of: outputMilliseconds) { newOutputMs in
if node != nil && node!.externalNotificationConfig != nil {
if newOutputMs != node!.externalNotificationConfig!.outputMilliseconds { hasChanges = true }
}
}

View file

@ -52,27 +52,20 @@ struct RangeTestConfig: View {
var node: NodeInfoEntity?
@State private var isPresentingSaveConfirm: Bool = false
@State var initialLoad: Bool = true
@State var hasChanges = false
@State var enabled = false
@State var sender = 0
@State var save = false
var body: some View {
VStack {
Form {
Section(header: Text("Options")) {
Toggle(isOn: $enabled) {
Label("Enabled", systemImage: "figure.walk")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
Picker("Sender Interval", selection: $sender ) {
ForEach(SenderIntervals.allCases) { sci in
Text(sci.description)
@ -81,26 +74,19 @@ struct RangeTestConfig: View {
.pickerStyle(DefaultPickerStyle())
Text("This device will send out range test messages on the selected interval.")
.font(.caption)
Toggle(isOn: $save) {
Label("Save", systemImage: "square.and.arrow.down.fill")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
.disabled(!(node != nil && node!.myInfo?.hasWifi ?? false))
Text("Saves a CSV with the range test message details, currently only available on ESP32 devices with a web server.")
.font(.caption)
}
}
.disabled(!(node != nil && node!.myInfo?.hasWifi ?? false))
Button {
isPresentingSaveConfirm = true
} label: {
Label("Save", systemImage: "square.and.arrow.down")
}
.disabled(bleManager.connectedPeripheral == nil || !hasChanges || !(node!.myInfo?.hasWifi ?? false))
@ -114,63 +100,44 @@ struct RangeTestConfig: View {
titleVisibility: .visible
) {
Button("Save Range Test Module Config to \(bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : "Unknown")?") {
var rtc = ModuleConfig.RangeTestConfig()
rtc.enabled = enabled
rtc.save = save
rtc.sender = UInt32(sender)
let adminMessageId = bleManager.saveRangeTestModuleConfig(config: rtc, fromUser: node!.user!, toUser: node!.user!)
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
} else {
}
}
}
.navigationTitle("Range Test Config")
.navigationBarItems(trailing:
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
})
.onAppear {
if self.initialLoad{
self.bleManager.context = context
self.enabled = node?.rangeTestConfig?.enabled ?? false
self.save = node?.rangeTestConfig?.save ?? false
self.sender = Int(node?.rangeTestConfig?.sender ?? 0)
self.hasChanges = false
self.initialLoad = false
}
self.bleManager.context = context
self.enabled = node?.rangeTestConfig?.enabled ?? false
self.save = node?.rangeTestConfig?.save ?? false
self.sender = Int(node?.rangeTestConfig?.sender ?? 0)
self.hasChanges = false
}
.onChange(of: enabled) { newEnabled in
if node != nil && node!.rangeTestConfig != nil {
if newEnabled != node!.rangeTestConfig!.enabled { hasChanges = true }
}
}
.onChange(of: save) { newSave in
if node != nil && node!.rangeTestConfig != nil {
if newSave != node!.rangeTestConfig!.save { hasChanges = true }
}
}
.onChange(of: sender) { newSender in
if node != nil && node!.rangeTestConfig != nil {
if newSender != node!.rangeTestConfig!.sender { hasChanges = true }
}
}

View file

@ -74,9 +74,7 @@ struct TelemetryConfig: View {
var node: NodeInfoEntity?
@State private var isPresentingSaveConfirm: Bool = false
@State var initialLoad: Bool = true
@State var hasChanges = false
@State var deviceUpdateInterval = 0
@State var environmentUpdateInterval = 0
@State var environmentMeasurementEnabled = false
@ -86,11 +84,8 @@ struct TelemetryConfig: View {
var body: some View {
VStack {
Form {
Section(header: Text("Update Intervals")) {
Picker("Device Metrics", selection: $deviceUpdateInterval ) {
ForEach(UpdateIntervals.allCases) { ui in
Text(ui.description)
@ -99,7 +94,6 @@ struct TelemetryConfig: View {
.pickerStyle(DefaultPickerStyle())
Text("How often device metrics are sent out over the mesh. Default is 15 minutes.")
.font(.caption)
Picker("Sensor Metrics", selection: $environmentUpdateInterval ) {
ForEach(UpdateIntervals.allCases) { ui in
Text(ui.description)
@ -109,39 +103,27 @@ struct TelemetryConfig: View {
Text("How often sensor metrics are sent out over the mesh. Default is 15 minutes.")
.font(.caption)
}
Section(header: Text("Sensor Options")) {
Text("Supported I2C Connected sensors will be detected automatically, sensors are BMP280, BME280, BME680, MCP9808, INA219, INA260, LPS22 and SHTC3.")
.font(.caption)
Toggle(isOn: $environmentMeasurementEnabled) {
Label("Enabled", systemImage: "chart.xyaxis.line")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
Toggle(isOn: $environmentScreenEnabled) {
Label("Show on device screen", systemImage: "display")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
Toggle(isOn: $environmentDisplayFahrenheit) {
Label("Display Fahrenheit", systemImage: "thermometer")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
}
}
.disabled(bleManager.connectedPeripheral == nil)
Button {
isPresentingSaveConfirm = true
} label: {
Label("Save", systemImage: "square.and.arrow.down")
}
.disabled(bleManager.connectedPeripheral == nil || !hasChanges || node!.telemetryConfig == nil)
@ -150,28 +132,22 @@ struct TelemetryConfig: View {
.controlSize(.large)
.padding()
.confirmationDialog(
"Are you sure?",
isPresented: $isPresentingSaveConfirm,
titleVisibility: .visible
) {
Button("Save Telemetry Module Config to \(bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : "Unknown")?") {
var tc = ModuleConfig.TelemetryConfig()
tc.deviceUpdateInterval = UInt32(deviceUpdateInterval)
tc.environmentUpdateInterval = UInt32(environmentUpdateInterval)
tc.environmentMeasurementEnabled = environmentMeasurementEnabled
tc.environmentScreenEnabled = environmentScreenEnabled
tc.environmentDisplayFahrenheit = environmentDisplayFahrenheit
let adminMessageId = bleManager.saveTelemetryModuleConfig(config: tc, fromUser: node!.user!, toUser: node!.user!)
if adminMessageId > 0 {
// Should show a saved successfully alert once I know that to be true
// for now just disable the button after a successful save
hasChanges = false
} else {
}
@ -180,57 +156,40 @@ struct TelemetryConfig: View {
.navigationTitle("Telemetry Config")
.navigationBarItems(trailing:
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
})
.onAppear {
if self.initialLoad{
self.bleManager.context = context
self.deviceUpdateInterval = Int(node?.telemetryConfig?.deviceUpdateInterval ?? 0)
self.environmentUpdateInterval = Int(node?.telemetryConfig?.environmentUpdateInterval ?? 0)
self.environmentMeasurementEnabled = node?.telemetryConfig?.environmentMeasurementEnabled ?? false
self.environmentScreenEnabled = node?.telemetryConfig?.environmentScreenEnabled ?? false
self.environmentDisplayFahrenheit = node?.telemetryConfig?.environmentDisplayFahrenheit ?? false
self.hasChanges = false
self.initialLoad = false
}
self.bleManager.context = context
self.deviceUpdateInterval = Int(node?.telemetryConfig?.deviceUpdateInterval ?? 0)
self.environmentUpdateInterval = Int(node?.telemetryConfig?.environmentUpdateInterval ?? 0)
self.environmentMeasurementEnabled = node?.telemetryConfig?.environmentMeasurementEnabled ?? false
self.environmentScreenEnabled = node?.telemetryConfig?.environmentScreenEnabled ?? false
self.environmentDisplayFahrenheit = node?.telemetryConfig?.environmentDisplayFahrenheit ?? false
self.hasChanges = false
}
.onChange(of: deviceUpdateInterval) { newDeviceInterval in
if node != nil && node!.telemetryConfig != nil {
if newDeviceInterval != node!.telemetryConfig!.deviceUpdateInterval { hasChanges = true }
}
}
.onChange(of: environmentUpdateInterval) { newEnvInterval in
if node != nil && node!.telemetryConfig != nil {
if newEnvInterval != node!.telemetryConfig!.environmentUpdateInterval { hasChanges = true }
}
}
.onChange(of: environmentMeasurementEnabled) { newEnvEnabled in
if node != nil && node!.telemetryConfig != nil {
if newEnvEnabled != node!.telemetryConfig!.environmentMeasurementEnabled { hasChanges = true }
}
}
.onChange(of: environmentScreenEnabled) { newEnvScreenEnabled in
if node!.telemetryConfig != nil {
if newEnvScreenEnabled != node!.telemetryConfig!.environmentScreenEnabled { hasChanges = true }
}
}
.onChange(of: environmentDisplayFahrenheit) { newEnvDisplayF in
if node != nil && node!.telemetryConfig != nil {
if newEnvDisplayF != node!.telemetryConfig!.environmentDisplayFahrenheit { hasChanges = true }
}
}

View file

@ -15,9 +15,7 @@ struct NetworkConfig: View {
var node: NodeInfoEntity?
@State private var isPresentingSaveConfirm: Bool = false
@State var initialLoad: Bool = true
@State var hasChanges: Bool = false
@State var wifiEnabled = false
@State var wifiSsid = ""
@State var wifiPsk = ""
@ -27,20 +25,14 @@ struct NetworkConfig: View {
var body: some View {
VStack {
Form {
Section(header: Text("WiFi Options")) {
Text("Enabling WiFi will disable the bluetooth connection to the app.")
.font(.title3)
Toggle(isOn: $wifiEnabled) {
Label("Enabled", systemImage: "wifi")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
HStack {
Label("SSID", systemImage: "network")
TextField("SSID", text: $wifiSsid)
@ -48,16 +40,11 @@ struct NetworkConfig: View {
.autocapitalization(.none)
.disableAutocorrection(true)
.onChange(of: wifiSsid, perform: { value in
let totalBytes = wifiSsid.utf8.count
// Only mess with the value if it is too big
if totalBytes > 32 {
let firstNBytes = Data(wifiSsid.utf8.prefix(32))
if let maxBytesString = String(data: firstNBytes, encoding: String.Encoding.utf8) {
// Set the shortName back to the last place where it was the right size
wifiSsid = maxBytesString
}
@ -67,7 +54,6 @@ struct NetworkConfig: View {
.foregroundColor(.gray)
}
.keyboardType(.default)
HStack {
Label("Password", systemImage: "wallet.pass")
TextField("Password", text: $wifiPsk)
@ -75,16 +61,11 @@ struct NetworkConfig: View {
.autocapitalization(.none)
.disableAutocorrection(true)
.onChange(of: wifiPsk, perform: { value in
let totalBytes = wifiPsk.utf8.count
// Only mess with the value if it is too big
if totalBytes > 63 {
let firstNBytes = Data(wifiPsk.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
wifiPsk = maxBytesString
}
@ -98,13 +79,9 @@ struct NetworkConfig: View {
}
.scrollDismissesKeyboard(.interactively)
.disabled(!(node != nil && node!.myInfo?.hasWifi ?? false))
Button {
isPresentingSaveConfirm = true
} label: {
Label("Save", systemImage: "square.and.arrow.down")
}
.disabled(bleManager.connectedPeripheral == nil || !hasChanges)
@ -113,22 +90,17 @@ struct NetworkConfig: View {
.controlSize(.large)
.padding()
.confirmationDialog(
"Are you sure you want to save?",
isPresented: $isPresentingSaveConfirm,
titleVisibility: .visible
) {
Button("Save Config for \(bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : "Unknown")") {
var network = Config.NetworkConfig()
network.wifiEnabled = self.wifiEnabled
network.wifiSsid = self.wifiSsid
network.wifiPsk = self.wifiPsk
let adminMessageId = bleManager.saveWiFiConfig(config: network, fromUser: node!.user!, toUser: node!.user!)
if adminMessageId > 0 {
// Should show a saved successfully alert once I know that to be true
// for now just disable the button after a successful save
self.hasChanges = false
@ -138,57 +110,39 @@ struct NetworkConfig: View {
}
}
} message: {
Text("After network config saves the node will reboot.")
}
}
.navigationTitle("Network Config")
.navigationBarItems(trailing:
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
})
.onAppear {
if self.initialLoad{
self.bleManager.context = context
self.wifiEnabled = (node?.networkConfig?.wifiEnabled ?? false)
self.wifiSsid = node?.networkConfig?.wifiSsid ?? ""
self.wifiPsk = node?.networkConfig?.wifiPsk ?? ""
self.wifiMode = Int(node?.networkConfig?.wifiMode ?? 0)
self.hasChanges = false
self.initialLoad = false
}
self.bleManager.context = context
self.wifiEnabled = (node?.networkConfig?.wifiEnabled ?? false)
self.wifiSsid = node?.networkConfig?.wifiSsid ?? ""
self.wifiPsk = node?.networkConfig?.wifiPsk ?? ""
self.wifiMode = Int(node?.networkConfig?.wifiMode ?? 0)
self.hasChanges = false
}
.onChange(of: wifiEnabled) { newEnabled in
if node != nil && node!.networkConfig != nil {
if newEnabled != node!.networkConfig!.wifiEnabled { hasChanges = true }
}
}
.onChange(of: wifiSsid) { newSSID in
if node != nil && node!.networkConfig != nil {
if newSSID != node!.networkConfig!.wifiSsid { hasChanges = true }
}
}
.onChange(of: wifiPsk) { newPsk in
if node != nil && node!.networkConfig != nil {
if newPsk != node!.networkConfig!.wifiPsk { hasChanges = true }
}
}
.onChange(of: wifiMode) { newMode in
if node != nil && node!.networkConfig != nil {
if newMode != node!.networkConfig!.wifiMode { hasChanges = true }
}
}

View file

@ -15,61 +15,44 @@ struct UserConfig: View {
@State private var isPresentingFactoryResetConfirm: Bool = false
@State private var isPresentingSaveConfirm: Bool = false
@State var initialLoad: Bool = true
@State var hasChanges = false
@State var shortName = ""
@State var longName = ""
var body: some View {
VStack {
Form {
Section(header: Text("USER DETAILS")) {
HStack {
Label("Long Name", systemImage: "person.crop.rectangle.fill")
TextField("Long Name", text: $longName)
.onChange(of: longName, perform: { value in
let totalBytes = longName.utf8.count
// Only mess with the value if it is too big
if totalBytes > 36 {
let firstNBytes = Data(longName.utf8.prefix(36))
if let maxBytesString = String(data: firstNBytes, encoding: String.Encoding.utf8) {
// Set the longName back to the last place where it was the right size
longName = maxBytesString
}
}
})
}
.keyboardType(.default)
.disableAutocorrection(true)
Text("Long name can be up to 36 bytes long.")
.font(.caption)
HStack {
Label("Short Name", systemImage: "circlebadge.fill")
TextField("Long Name", text: $shortName)
.foregroundColor(.gray)
.onChange(of: shortName, perform: { value in
let totalBytes = shortName.utf8.count
// Only mess with the value if it is too big
if totalBytes > 4 {
let firstNBytes = Data(shortName.utf8.prefix(4))
if let maxBytesString = String(data: firstNBytes, encoding: String.Encoding.utf8) {
// Set the shortName back to the last place where it was the right size
shortName = maxBytesString
}
@ -81,20 +64,13 @@ struct UserConfig: View {
.disableAutocorrection(true)
Text("The short name is used in maps and messaging and will be appended to the last 4 of the device MAC address to set the device's BLE Name. It can be up to 4 bytes long.")
.font(.caption)
}
}
.disabled(bleManager.connectedPeripheral == nil)
HStack {
Button {
isPresentingSaveConfirm = true
} label: {
Label("Save", systemImage: "square.and.arrow.down")
}
.disabled(bleManager.connectedPeripheral == nil || !hasChanges)
@ -103,63 +79,43 @@ struct UserConfig: View {
.controlSize(.large)
.padding()
.confirmationDialog(
"Are you sure you want to save?",
isPresented: $isPresentingSaveConfirm,
titleVisibility: .visible
) {
Button("Save User Config to \(bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : "Unknown")?") {
var u = User()
u.shortName = shortName
u.longName = longName
let adminMessageId = bleManager.saveUser(config: u, fromUser: node!.user!, toUser: node!.user!)
if adminMessageId > 0 {
hasChanges = false
}
}
} message: {
Text("After user config saves the node will reboot.")
}
}
Spacer()
}
.navigationTitle("User Config")
.navigationBarItems(trailing:
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
})
.onAppear {
if self.initialLoad{
self.bleManager.context = context
self.shortName = node?.user!.shortName ?? ""
self.longName = node?.user!.longName ?? ""
self.hasChanges = false
self.initialLoad = false
}
self.bleManager.context = context
self.shortName = node?.user!.shortName ?? ""
self.longName = node?.user!.longName ?? ""
self.hasChanges = false
}
.onChange(of: shortName) { newShort in
if node != nil && node!.user != nil {
if newShort != node?.user!.shortName { hasChanges = true }
}
}
.onChange(of: longName) { newLong in
if node != nil && node!.user != nil {
if newLong != node?.user!.longName { hasChanges = true }
}
}