From 920e200593e618bd3559097e2e1dcb941a425768 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Wed, 20 Jul 2022 15:06:18 -0700 Subject: [PATCH 1/3] Add txPower to loraConfigEntity, isLicensed to user --- .../MeshtasticDataModel v 4.xcdatamodel/contents | 6 ++++-- Meshtastic/Views/Bluetooth/Connect.swift | 2 +- Meshtastic/Views/Messages/UserMessageList.swift | 11 ++++++++++- Meshtastic/Views/Nodes/NodeDetail.swift | 5 +++-- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents index d8b141ee..525bc183 100644 --- a/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents +++ b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModel v 4.xcdatamodel/contents @@ -43,6 +43,7 @@ + @@ -175,6 +176,7 @@ + @@ -196,7 +198,7 @@ - + @@ -206,6 +208,6 @@ - + \ No newline at end of file diff --git a/Meshtastic/Views/Bluetooth/Connect.swift b/Meshtastic/Views/Bluetooth/Connect.swift index 53ea4be8..5268c5e2 100644 --- a/Meshtastic/Views/Bluetooth/Connect.swift +++ b/Meshtastic/Views/Bluetooth/Connect.swift @@ -146,7 +146,7 @@ struct Connect: View { if bleManager.peripherals.count > 0 { Section(header: Text("Available Radios").font(.title)) { - ForEach(bleManager.peripherals.filter({ $0.peripheral.state == CBPeripheralState.disconnected }).sorted(by: { $0.name < $1.name })) { peripheral in + ForEach(bleManager.peripherals.filter({ $0.peripheral.state == CBPeripheralState.disconnected }).sorted(by: { $0.rssi > $1.rssi })) { peripheral in HStack { Image(systemName: "circle.fill") .imageScale(.large).foregroundColor(.gray) diff --git a/Meshtastic/Views/Messages/UserMessageList.swift b/Meshtastic/Views/Messages/UserMessageList.swift index 9e87f10c..e4941797 100644 --- a/Meshtastic/Views/Messages/UserMessageList.swift +++ b/Meshtastic/Views/Messages/UserMessageList.swift @@ -225,7 +225,16 @@ struct UserMessageList: View { VStack { let ackDate = Date(timeIntervalSince1970: TimeInterval(message.ackTimestamp)) - Text("ACK \(ackDate, style: .date) \(ackDate, style: .time)").font(.caption2).foregroundColor(.gray) + + let sixMonthsAgo = Calendar.current.date(byAdding: .month, value: -6, to: Date()) + if ackDate >= sixMonthsAgo! { + + Text("ACK \(ackDate, style: .date) \(ackDate, style: .time)").font(.caption2).foregroundColor(.gray) + + } else { + + Text("Unknown Age").font(.caption2).foregroundColor(.gray) + } } } if message.ackSNR != 0 { diff --git a/Meshtastic/Views/Nodes/NodeDetail.swift b/Meshtastic/Views/Nodes/NodeDetail.swift index 5d784f4e..0d3a2262 100644 --- a/Meshtastic/Views/Nodes/NodeDetail.swift +++ b/Meshtastic/Views/Nodes/NodeDetail.swift @@ -79,10 +79,12 @@ struct NodeDetail: View { ScrollView { if self.bleManager.connectedPeripheral != nil && self.bleManager.connectedPeripheral.num == node.num && self.bleManager.connectedPeripheral.num == node.num { + + Divider() HStack { if hwModelString == "TBEAM" || hwModelString == "TECHO" || hwModelString.contains("4631") { - + Button(action: { isPresentingShutdownConfirm = true @@ -136,7 +138,6 @@ struct NodeDetail: View { } } .padding(5) - Divider() } if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac { From 0a386c531e71087be2624e379da5d9be2b73d45b Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Tue, 26 Jul 2022 07:35:16 -0700 Subject: [PATCH 2/3] Clean up phone telemetry --- Meshtastic/Helpers/BLEManager.swift | 49 ++++++ Meshtastic/Helpers/MeshPackets.swift | 16 +- Meshtastic/Views/Nodes/TelemetryLog.swift | 148 +++++++++++------- .../Config/Module/CannedMessagesConfig.swift | 3 + 4 files changed, 150 insertions(+), 66 deletions(-) diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index 13fe4124..8bc54686 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -1169,6 +1169,55 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph return 0 } + public func getCannedMessageModuleMessages(destNum: Int64, wantResponse: Bool) -> Bool { + + var adminPacket = AdminMessage() + adminPacket.getCannedMessageModulePart1Request = true + + //adminPacket.getOwnerRequest = true + + var meshPacket: MeshPacket = MeshPacket() + meshPacket.to = UInt32(connectedPeripheral.num) + meshPacket.from = 0 //UInt32(connectedPeripheral.num) + meshPacket.id = UInt32.random(in: UInt32(UInt8.max).. Int64 { var adminPacket = AdminMessage() diff --git a/Meshtastic/Helpers/MeshPackets.swift b/Meshtastic/Helpers/MeshPackets.swift index 17c1028b..90724201 100644 --- a/Meshtastic/Helpers/MeshPackets.swift +++ b/Meshtastic/Helpers/MeshPackets.swift @@ -190,14 +190,16 @@ func localConfig (config: Config, meshlogging: Bool, context:NSManagedObjectCont newLoRaConfig.modemPreset = 0 // 3 Hops default protobuf value of 0 newLoRaConfig.hopLimit = 0 + // Default value of 0 is 22dbm + newLoRaConfig.txPower = 0 + } else { - // UNSET default protobuf value of 0 newLoRaConfig.regionCode = Int32(config.lora.region.rawValue) - // LongFast default protobuf value of 0 newLoRaConfig.modemPreset = Int32(config.lora.modemPreset.rawValue) - // 3 Hops default protobuf value of 0 newLoRaConfig.hopLimit = Int32(config.lora.hopLimit) + newLoRaConfig.txPower = Int32(config.lora.txPower) + } fetchedNode[0].loRaConfig = newLoRaConfig @@ -212,14 +214,15 @@ func localConfig (config: Config, meshlogging: Bool, context:NSManagedObjectCont fetchedNode[0].loRaConfig?.modemPreset = 0 // 3 Hops default protobuf value of 0 fetchedNode[0].loRaConfig?.hopLimit = 0 + // Default value of 0 is 22dbm + fetchedNode[0].loRaConfig?.txPower = 0 } else { - // UNSET default protobuf value of 0 + fetchedNode[0].loRaConfig?.regionCode = Int32(config.lora.region.rawValue) - // LongFast default protobuf value of 0 fetchedNode[0].loRaConfig?.modemPreset = Int32(config.lora.modemPreset.rawValue) - // 3 Hops default protobuf value of 0 fetchedNode[0].loRaConfig?.hopLimit = Int32(config.lora.hopLimit) + fetchedNode[0].loRaConfig?.txPower = Int32(config.lora.txPower) } } @@ -417,6 +420,7 @@ func moduleConfig (config: ModuleConfig, meshlogging: Bool, context:NSManagedObj try context.save() if meshlogging { MeshLogger.log("💾 Updated Canned Message Module Config for node number: \(String(nodeNum))") } + print(try config.cannedMessage.jsonString()) } catch { diff --git a/Meshtastic/Views/Nodes/TelemetryLog.swift b/Meshtastic/Views/Nodes/TelemetryLog.swift index 270f76f3..0c7cfdf1 100644 --- a/Meshtastic/Views/Nodes/TelemetryLog.swift +++ b/Meshtastic/Views/Nodes/TelemetryLog.swift @@ -88,7 +88,7 @@ struct TelemetryLog: View { let sensor = SensorTypes(rawValue: Int(node.telemetryConfig?.environmentSensorType ?? 0)) - let tempReadingType = (!(node.telemetryConfig?.environmentDisplayFahrenheit ?? true)) ? "°F" : "°C" + let tempReadingType = (!(node.telemetryConfig?.environmentDisplayFahrenheit ?? true)) ? "°C" : "°F" if sensor == SensorTypes.bme280 || sensor == SensorTypes.bme680 || @@ -178,8 +178,9 @@ struct TelemetryLog: View { if tel.metricsType == 0 { - // Device Metrics + // Device Metrics iPhone Template VStack { + HStack { Spacer() @@ -243,94 +244,121 @@ struct TelemetryLog: View { // Environment Metrics let sensor = SensorTypes(rawValue: Int(node.telemetryConfig?.environmentSensorType ?? 0)) - let tempReadingType = (!(node.telemetryConfig?.environmentDisplayFahrenheit ?? true)) ? "°F" : "°C" + let tempReadingType = (!(node.telemetryConfig?.environmentDisplayFahrenheit ?? true)) ? "°C" : "°F" + + // Environment Metrics iPhone Template VStack { - Text("Environment Metrics") - .font(.title3) - - if sensor == SensorTypes.bme280 || - sensor == SensorTypes.bme680 || - sensor == SensorTypes.shtc3 || - sensor == SensorTypes.mcp9808 { + HStack { - Image(systemName: "thermometer") - .font(.callout) - .foregroundColor(.accentColor) - .symbolRenderingMode(.hierarchical) - Text("Temperature: \(String(format: "%.2f", tel.temperature))\(tempReadingType)") - .foregroundColor(.gray) - .font(.callout) + Spacer() + Text("Environment Metrics") + .font(.title3) + Spacer() } - - if sensor == SensorTypes.bme280 || - sensor == SensorTypes.bme680 || - sensor == SensorTypes.shtc3 { - - Image(systemName: "humidity") + + HStack { + + if sensor == SensorTypes.bme280 || + sensor == SensorTypes.bme680 || + sensor == SensorTypes.shtc3 || + sensor == SensorTypes.mcp9808 { + + Image(systemName: "thermometer") + .font(.callout) + .foregroundColor(.accentColor) + .symbolRenderingMode(.hierarchical) + Text("Temperature: \(String(format: "%.2f", tel.temperature))\(tempReadingType)") + .foregroundColor(.gray) .font(.callout) - .foregroundColor(.accentColor) - .symbolRenderingMode(.hierarchical) - Text("Relative Humidity: \(String(format: "%.2f", tel.relativeHumidity))") - .foregroundColor(.gray) - .font(.callout) + } + } + + HStack { + + if sensor == SensorTypes.bme280 || + sensor == SensorTypes.bme680 || + sensor == SensorTypes.shtc3 { + + Image(systemName: "humidity") + .font(.callout) + .foregroundColor(.accentColor) + .symbolRenderingMode(.hierarchical) + Text("Relative Humidity: \(String(format: "%.2f", tel.relativeHumidity))") + .foregroundColor(.gray) + .font(.callout) + } } if sensor == SensorTypes.ina219 || sensor == SensorTypes.ina260 { - Image(systemName: "directcurrent") + HStack { + + Image(systemName: "directcurrent") + .font(.callout) + .foregroundColor(.accentColor) + .symbolRenderingMode(.hierarchical) + Text("Current: \(String(format: "%.2f", tel.current))") + .foregroundColor(.gray) .font(.callout) - .foregroundColor(.accentColor) - .symbolRenderingMode(.hierarchical) - Text("Current: \(String(format: "%.2f", tel.current))") - .foregroundColor(.gray) - .font(.callout) + } - Image(systemName: "bolt") + HStack { + + Image(systemName: "bolt") + .font(.callout) + .foregroundColor(.accentColor) + .symbolRenderingMode(.hierarchical) + Text("Voltage: \(String(format: "%.2f", tel.voltage))") + .foregroundColor(.gray) .font(.callout) - .foregroundColor(.accentColor) - .symbolRenderingMode(.hierarchical) - Text("Voltage: \(String(format: "%.2f", tel.voltage))") - .foregroundColor(.gray) - .font(.callout) + } } if sensor == SensorTypes.bme280 || sensor == SensorTypes.bme680 { - Image(systemName: "barometer") + HStack { + + Image(systemName: "barometer") + .font(.callout) + .foregroundColor(.accentColor) + .symbolRenderingMode(.hierarchical) + Text("Barometric Pressure: \(String(format: "%.2f", tel.barometricPressure))") + .foregroundColor(.gray) .font(.callout) - .foregroundColor(.accentColor) - .symbolRenderingMode(.hierarchical) - Text("Barometric Pressure: \(String(format: "%.2f", tel.barometricPressure))") - .foregroundColor(.gray) - .font(.callout) + } } if sensor == SensorTypes.bme680 { - Image(systemName: "aqi.medium") + HStack { + + Image(systemName: "aqi.medium") + .font(.callout) + .foregroundColor(.accentColor) + .symbolRenderingMode(.hierarchical) + Text("Gas Resistance: \(String(format: "%.2f", tel.gasResistance))") + .foregroundColor(.gray) + .font(.callout) + } + } + + HStack { + + Image(systemName: "clock.badge.checkmark.fill") .font(.callout) .foregroundColor(.accentColor) .symbolRenderingMode(.hierarchical) - Text("Gas Resistance: \(String(format: "%.2f", tel.gasResistance))") + Text("Time:") + .foregroundColor(.gray) + .font(.callout) + DateTimeText(dateTime: tel.time) .foregroundColor(.gray) .font(.callout) } - - Image(systemName: "clock.badge.checkmark.fill") - .font(.callout) - .foregroundColor(.accentColor) - .symbolRenderingMode(.hierarchical) - Text("Time:") - .foregroundColor(.gray) - .font(.callout) - DateTimeText(dateTime: tel.time) - .foregroundColor(.gray) - .font(.callout) - } } } diff --git a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift index 47b3eea2..fe3ec406 100644 --- a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift @@ -362,6 +362,9 @@ struct CannedMessagesConfig: View { 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 } From f79b1d0cf49e290a66626628895ac0890ff16daa Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Tue, 26 Jul 2022 09:24:35 -0700 Subject: [PATCH 3/3] Fix broken enum on loraconfig page --- .../Views/Settings/Config/LoRaConfig.swift | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Meshtastic/Views/Settings/Config/LoRaConfig.swift b/Meshtastic/Views/Settings/Config/LoRaConfig.swift index b3d7bb17..d3a708e5 100644 --- a/Meshtastic/Views/Settings/Config/LoRaConfig.swift +++ b/Meshtastic/Views/Settings/Config/LoRaConfig.swift @@ -20,8 +20,8 @@ enum RegionCodes : Int, CaseIterable, Identifiable { case tw = 8 case ru = 9 case `in` = 10 - case nz865 - case th + case nz865 = 11 + case th = 12 var id: Int { self.rawValue } var description: String { @@ -187,13 +187,14 @@ struct LoRaConfig: View { var node: NodeInfoEntity? - @State private var isPresentingSaveConfirm: Bool = false - @State var initialLoad: Bool = true + @State var isPresentingSaveConfirm = false + @State var initialLoad = true @State var hasChanges = false @State var region = 0 @State var modemPreset = 0 @State var hopLimit = 0 + @State var txPower = 0 var body: some View { @@ -210,7 +211,6 @@ struct LoRaConfig: View { .pickerStyle(DefaultPickerStyle()) Text("The region where you will be using your radios.") .font(.caption) - .listRowSeparator(.visible) } Section(header: Text("Modem")) { Picker("Presets", selection: $modemPreset ) { @@ -221,7 +221,6 @@ struct LoRaConfig: View { .pickerStyle(DefaultPickerStyle()) Text("Available modem presets, default is Long Fast.") .font(.caption) - .listRowSeparator(.visible) } Section(header: Text("Mesh Options")) { @@ -233,10 +232,9 @@ struct LoRaConfig: View { .pickerStyle(DefaultPickerStyle()) Text("Sets the maximum number of hops, default is 3. Increasing hops also increases air time utilization and should be used carefully.") .font(.caption) - .listRowSeparator(.visible) } } - .disabled(bleManager.connectedPeripheral == nil) + .disabled(self.bleManager.connectedPeripheral == nil) Button { @@ -286,13 +284,16 @@ struct LoRaConfig: View { ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????") }) .onAppear { + + self.bleManager.context = context if self.initialLoad{ - self.bleManager.context = context + self.hopLimit = Int(node!.loRaConfig?.hopLimit ?? 0) self.region = Int(node!.loRaConfig?.regionCode ?? 0) self.modemPreset = Int(node!.loRaConfig?.modemPreset ?? 0) + self.txPower = Int(node!.loRaConfig?.txPower ?? 0) self.hasChanges = false self.initialLoad = false }