mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Pax Counter Config
This commit is contained in:
parent
5d9b25b0aa
commit
9ee3df519c
9 changed files with 255 additions and 3 deletions
|
|
@ -34,6 +34,7 @@
|
|||
DD0E21012B8A6F1300F2D100 /* DeviceHardware.json in Resources */ = {isa = PBXBuildFile; fileRef = DD0E21002B8A6BC500F2D100 /* DeviceHardware.json */; };
|
||||
DD0F791B28713C8A00A6FDAD /* AdminMessageList.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD0F791A28713C8A00A6FDAD /* AdminMessageList.swift */; };
|
||||
DD13AA492AB73BF400BA0C98 /* PositionPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD13AA482AB73BF400BA0C98 /* PositionPopover.swift */; };
|
||||
DD15E4F32B8BA56E00654F61 /* PaxCounterConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD15E4F22B8BA56E00654F61 /* PaxCounterConfig.swift */; };
|
||||
DD1925B728CDA5A400720036 /* CannedMessagesConfigEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1925B628CDA5A400720036 /* CannedMessagesConfigEnums.swift */; };
|
||||
DD1925B928CDA93900720036 /* SerialConfigEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1925B828CDA93900720036 /* SerialConfigEnums.swift */; };
|
||||
DD1933762B0835D500771CD5 /* PositionAltitudeChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1933752B0835D500771CD5 /* PositionAltitudeChart.swift */; };
|
||||
|
|
@ -270,6 +271,7 @@
|
|||
DD0F791A28713C8A00A6FDAD /* AdminMessageList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminMessageList.swift; sourceTree = "<group>"; };
|
||||
DD13AA482AB73BF400BA0C98 /* PositionPopover.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionPopover.swift; sourceTree = "<group>"; };
|
||||
DD14E72C2A80738F006E39BC /* MeshtasticDataModelV15.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV15.xcdatamodel; sourceTree = "<group>"; };
|
||||
DD15E4F22B8BA56E00654F61 /* PaxCounterConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaxCounterConfig.swift; sourceTree = "<group>"; };
|
||||
DD1925B628CDA5A400720036 /* CannedMessagesConfigEnums.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CannedMessagesConfigEnums.swift; sourceTree = "<group>"; };
|
||||
DD1925B828CDA93900720036 /* SerialConfigEnums.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SerialConfigEnums.swift; sourceTree = "<group>"; };
|
||||
DD1933752B0835D500771CD5 /* PositionAltitudeChart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionAltitudeChart.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -682,6 +684,7 @@
|
|||
DD6193782863875F00E59241 /* SerialConfig.swift */,
|
||||
DDF6B2472A9AEBF500BA6931 /* StoreForwardConfig.swift */,
|
||||
DD415827285859C4009B0E59 /* TelemetryConfig.swift */,
|
||||
DD15E4F22B8BA56E00654F61 /* PaxCounterConfig.swift */,
|
||||
);
|
||||
path = Module;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -1223,6 +1226,7 @@
|
|||
DD4640202AFF10F4002A5ECB /* WaypointForm.swift in Sources */,
|
||||
DD769E0328D18BF1001A3F05 /* DeviceMetricsLog.swift in Sources */,
|
||||
DDAF8C5326EB1DF10058C060 /* BLEManager.swift in Sources */,
|
||||
DD15E4F32B8BA56E00654F61 /* PaxCounterConfig.swift in Sources */,
|
||||
DDDB445229F8ACF900EE2349 /* Date.swift in Sources */,
|
||||
DDC4D568275499A500A4208E /* Persistence.swift in Sources */,
|
||||
DDD6EEAF29BC024700383354 /* Firmware.swift in Sources */,
|
||||
|
|
|
|||
|
|
@ -1704,6 +1704,33 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
return 0
|
||||
}
|
||||
|
||||
public func savePaxcounterModuleConfig(config: ModuleConfig.PaxcounterConfig, fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Int64 {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setModuleConfig.paxcounter = config
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(toUser.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
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛟 Saved PAX Counter Module Config for \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
upsertPaxCounterModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
|
||||
return Int64(meshPacket.id)
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
public func saveRtttlConfig(ringtone: String, fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Int64 {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
|
|
@ -2204,6 +2231,33 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
return false
|
||||
}
|
||||
|
||||
public func requestPaxCounterModuleConfig(fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Bool {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.getModuleConfigRequest = AdminMessage.ModuleConfigType.paxcounterConfig
|
||||
|
||||
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.channel = UInt32(adminIndex)
|
||||
meshPacket.wantAck = true
|
||||
|
||||
var dataMessage = DataMessage()
|
||||
dataMessage.payload = try! adminPacket.serializedData()
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
dataMessage.wantResponse = true
|
||||
|
||||
meshPacket.decoded = dataMessage
|
||||
|
||||
let messageDescription = "🛎️ Requested PAX Counter Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
|
||||
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription, fromUser: fromUser, toUser: toUser) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
public func requestRtttlConfig(fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Bool {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
|
|
|
|||
|
|
@ -68,6 +68,8 @@ func moduleConfig (config: ModuleConfig, context: NSManagedObjectContext, nodeNu
|
|||
upsertExternalNotificationModuleConfigPacket(config: config.externalNotification, nodeNum: nodeNum, context: context)
|
||||
} else if config.payloadVariant == ModuleConfig.OneOf_PayloadVariant.mqtt(config.mqtt) {
|
||||
upsertMqttModuleConfigPacket(config: config.mqtt, nodeNum: nodeNum, context: context)
|
||||
} else if config.payloadVariant == ModuleConfig.OneOf_PayloadVariant.paxcounter(config.paxcounter) {
|
||||
upsertPaxCounterModuleConfigPacket(config: config.paxcounter, nodeNum: nodeNum, context: context)
|
||||
} else if config.payloadVariant == ModuleConfig.OneOf_PayloadVariant.rangeTest(config.rangeTest) {
|
||||
upsertRangeTestModuleConfigPacket(config: config.rangeTest, nodeNum: nodeNum, context: context)
|
||||
} else if config.payloadVariant == ModuleConfig.OneOf_PayloadVariant.serial(config.serial) {
|
||||
|
|
@ -247,7 +249,7 @@ func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObje
|
|||
return nil
|
||||
}
|
||||
// Not Found Insert
|
||||
if fetchedNode.isEmpty {
|
||||
if fetchedNode.isEmpty && nodeInfo.num > 0 {
|
||||
|
||||
let newNode = NodeInfoEntity(context: context)
|
||||
newNode.id = Int64(nodeInfo.num)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22522" systemVersion="23E5196e" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22522" systemVersion="23E5205c" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<entity name="AmbientLightingConfigEntity" representedClassName="AmbientLightingConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="blue" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="current" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
|
|
@ -251,6 +251,8 @@
|
|||
<relationship name="mqttConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="MQTTConfigEntity" inverseName="mqttConfigNode" inverseEntity="MQTTConfigEntity"/>
|
||||
<relationship name="myInfo" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="MyInfoEntity" inverseName="myInfoNode" inverseEntity="MyInfoEntity"/>
|
||||
<relationship name="networkConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NetworkConfigEntity" inverseName="networkConfigNode" inverseEntity="NetworkConfigEntity"/>
|
||||
<relationship name="pax" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="PaxCountrerEntity" inverseName="paxNode" inverseEntity="PaxCountrerEntity"/>
|
||||
<relationship name="paxCounterConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="PaxCounterConfigEntity" inverseName="paxCounterConfigNode" inverseEntity="PaxCounterConfigEntity"/>
|
||||
<relationship name="positionConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="PositionConfigEntity" inverseName="positionConfigNode" inverseEntity="PositionConfigEntity"/>
|
||||
<relationship name="positions" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="PositionEntity" inverseName="nodePosition" inverseEntity="PositionEntity"/>
|
||||
<relationship name="powerConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="PowerConfigEntity" inverseName="powerConfigNode" inverseEntity="PowerConfigEntity"/>
|
||||
|
|
@ -268,6 +270,18 @@
|
|||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="PaxCounterConfigEntity" representedClassName="PaxCounterConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="enabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="paxcounterUpdateInterval" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="paxCounterConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="paxCounterConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="PaxCountrerEntity" representedClassName="PaxCountrerEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="ble" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="time" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="uptime" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="wifi" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="paxNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="pax" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="PositionConfigEntity" representedClassName="PositionConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="broadcastSmartMinimumDistance" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="broadcastSmartMinimumIntervalSecs" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
|
|
|
|||
|
|
@ -949,6 +949,51 @@ func upsertExternalNotificationModuleConfigPacket(config: Meshtastic.ModuleConfi
|
|||
}
|
||||
}
|
||||
|
||||
func upsertPaxCounterModuleConfigPacket(config: Meshtastic.ModuleConfig.PaxcounterConfig, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat("mesh.log.paxcounter.config %@".localized, String(nodeNum))
|
||||
MeshLogger.log("📣 \(logString)")
|
||||
|
||||
let fetchNodeInfoRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "NodeInfoEntity")
|
||||
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
|
||||
|
||||
do {
|
||||
|
||||
guard let fetchedNode = try context.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity] else {
|
||||
return
|
||||
}
|
||||
// Found a node, save PAX Counter Config
|
||||
if !fetchedNode.isEmpty {
|
||||
|
||||
if fetchedNode[0].paxCounterConfig == nil {
|
||||
let newPaxCounterConfig = PaxCounterConfigEntity(context: context)
|
||||
newPaxCounterConfig.enabled = config.enabled
|
||||
newPaxCounterConfig.paxcounterUpdateInterval = Int32(config.paxcounterUpdateInterval)
|
||||
|
||||
fetchedNode[0].paxCounterConfig = newPaxCounterConfig
|
||||
|
||||
} else {
|
||||
fetchedNode[0].paxCounterConfig?.enabled = config.enabled
|
||||
fetchedNode[0].paxCounterConfig?.paxcounterUpdateInterval = Int32(config.paxcounterUpdateInterval)
|
||||
}
|
||||
|
||||
do {
|
||||
try context.save()
|
||||
print("💾 Updated PAX Counter Module Config for node number: \(String(nodeNum))")
|
||||
} catch {
|
||||
context.rollback()
|
||||
let nsError = error as NSError
|
||||
print("💥 Error Updating Core Data ExternalNotificationConfigEntity: \(nsError)")
|
||||
}
|
||||
} else {
|
||||
print("💥 No Nodes found in local database matching node number \(nodeNum) unable to save PAX Counter Module Config")
|
||||
}
|
||||
} catch {
|
||||
let nsError = error as NSError
|
||||
print("💥 Fetching node for core data PaxCounterConfigEntity failed: \(nsError)")
|
||||
}
|
||||
}
|
||||
|
||||
func upsertRtttlConfigPacket(ringtone: String, nodeNum: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let logString = String.localizedStringWithFormat("mesh.log.ringtone.config %@".localized, String(nodeNum))
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ struct NodeListItem: View {
|
|||
Text("Role: \(role?.name ?? "unknown".localized)")
|
||||
.font(UIDevice.current.userInterfaceIdiom == .phone ? .callout : .caption)
|
||||
.foregroundColor(.gray)
|
||||
|
||||
}
|
||||
if node.isStoreForwardRouter {
|
||||
HStack {
|
||||
|
|
|
|||
114
Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift
Normal file
114
Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
//
|
||||
// PaxCounterConfig.swift
|
||||
// Meshtastic
|
||||
//
|
||||
// Copyright Garth Vander Houwen 2/25/24.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct PaxCounterConfig: View {
|
||||
@Environment(\.managedObjectContext) private var context
|
||||
@EnvironmentObject private var bleManager: BLEManager
|
||||
@Environment(\.dismiss) private var goBack
|
||||
|
||||
let node: NodeInfoEntity?
|
||||
|
||||
@State private var enabled = false
|
||||
@State private var paxcounterUpdateInterval = 0
|
||||
@State private var hasChanges: Bool = false
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
ConfigHeader(title: "paxcounter", config: \.powerConfig, node: node, onAppear: setPaxValues)
|
||||
|
||||
Section {
|
||||
Toggle(isOn: $enabled) {
|
||||
Label("enabled", systemImage: "figure.walk.departure")
|
||||
Text("config.module.paxcounter.enabled.description")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
.listRowSeparator(.visible)
|
||||
if enabled {
|
||||
Picker("config.module.paxcounter.updateinterval", selection: $paxcounterUpdateInterval) {
|
||||
ForEach(UpdateIntervals.allCases) { at in
|
||||
if at.rawValue >= 5 {
|
||||
Text(at.description)
|
||||
}
|
||||
}
|
||||
}
|
||||
.pickerStyle(DefaultPickerStyle())
|
||||
.listRowSeparator(.hidden)
|
||||
Text("config.module.paxcounter.updateinterval.description")
|
||||
.foregroundColor(.gray)
|
||||
.font(.callout)
|
||||
}
|
||||
} header: {
|
||||
Text("options")
|
||||
}
|
||||
}
|
||||
.disabled(self.bleManager.connectedPeripheral == nil || node?.powerConfig == nil)
|
||||
.navigationTitle("config.module.paxcounter.title")
|
||||
.navigationBarItems(trailing: ZStack {
|
||||
ConnectedDevice(
|
||||
bluetoothOn: bleManager.isSwitchedOn,
|
||||
deviceConnected: bleManager.connectedPeripheral != nil,
|
||||
name: "\(bleManager.connectedPeripheral?.shortName ?? "?")"
|
||||
)
|
||||
})
|
||||
.onAppear {
|
||||
if self.bleManager.context == nil {
|
||||
self.bleManager.context = context
|
||||
}
|
||||
|
||||
setPaxValues()
|
||||
// Need to request a PAX Counter module config from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.paxCounterConfig == nil {
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral?.num ?? 0, context: context)
|
||||
if node != nil && connectedNode != nil {
|
||||
_ = bleManager.requestPaxCounterModuleConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: enabled) {
|
||||
if let val = node?.paxCounterConfig?.enabled {
|
||||
hasChanges = $0 != val
|
||||
}
|
||||
}
|
||||
.onChange(of: paxcounterUpdateInterval) {
|
||||
if let val = node?.paxCounterConfig?.paxcounterUpdateInterval {
|
||||
hasChanges = $0 != val
|
||||
}
|
||||
}
|
||||
|
||||
SaveConfigButton(node: node, hasChanges: $hasChanges) {
|
||||
guard let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context),
|
||||
let fromUser = connectedNode.user,
|
||||
let toUser = node?.user else {
|
||||
return
|
||||
}
|
||||
|
||||
var config = ModuleConfig.PaxcounterConfig()
|
||||
config.enabled = enabled
|
||||
config.paxcounterUpdateInterval = UInt32(paxcounterUpdateInterval)
|
||||
|
||||
let adminMessageId = bleManager.savePaxcounterModuleConfig(
|
||||
config: config,
|
||||
fromUser: fromUser,
|
||||
toUser: toUser,
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func setPaxValues() {
|
||||
enabled = node?.paxCounterConfig?.enabled ?? enabled
|
||||
paxcounterUpdateInterval = Int(node?.paxCounterConfig?.paxcounterUpdateInterval ?? 900)
|
||||
}
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ struct Settings: View {
|
|||
case deviceConfig
|
||||
case displayConfig
|
||||
case networkConfig
|
||||
case paxCounterConfig
|
||||
case positionConfig
|
||||
case powerConfig
|
||||
case ambientLightingConfig
|
||||
|
|
@ -37,6 +38,7 @@ struct Settings: View {
|
|||
case rangeTestConfig
|
||||
case ringtoneConfig
|
||||
case serialConfig
|
||||
case storeAndForwardConfig
|
||||
case telemetryConfig
|
||||
case meshLog
|
||||
case adminMessageLog
|
||||
|
|
@ -283,6 +285,17 @@ struct Settings: View {
|
|||
.symbolRenderingMode(.hierarchical)
|
||||
Text("range.test")
|
||||
}
|
||||
.tag(SettingsSidebar.rangeTestConfig)
|
||||
if node?.metadata?.hasWifi ?? false {
|
||||
NavigationLink {
|
||||
PaxCounterConfig(node: nodes.first(where: { $0.num == selectedNode }))
|
||||
} label: {
|
||||
Image(systemName: "figure.walk.departure")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
Text("config.module.paxcounter.settings")
|
||||
}
|
||||
.tag(SettingsSidebar.paxCounterConfig)
|
||||
}
|
||||
NavigationLink {
|
||||
RtttlConfig(node: nodes.first(where: { $0.num == selectedNode }))
|
||||
} label: {
|
||||
|
|
@ -306,7 +319,7 @@ struct Settings: View {
|
|||
.symbolRenderingMode(.hierarchical)
|
||||
Text("storeforward")
|
||||
}
|
||||
.tag(SettingsSidebar.serialConfig)
|
||||
.tag(SettingsSidebar.storeAndForwardConfig)
|
||||
NavigationLink {
|
||||
TelemetryConfig(node: nodes.first(where: { $0.num == selectedNode }))
|
||||
} label: {
|
||||
|
|
|
|||
|
|
@ -51,6 +51,11 @@
|
|||
"clear.app.data"="Clear App Data";
|
||||
"clear.log"="Clear";
|
||||
"close"="Close";
|
||||
"config.module.paxcounter.settings"="PAX Counter";
|
||||
"config.module.paxcounter.title"="PAX Counter Config";
|
||||
"config.module.paxcounter.enabled.description"="When enabled the PAX Counter module counts the number of people passing by using WiFi and Bluetooth.";
|
||||
"config.module.paxcounter.updateinterval"="Update Interval";
|
||||
"config.module.paxcounter.updateinterval.description"="How often we can send a message to the mesh when people are detected.";
|
||||
"config.save.confirm"="After config values save the node will reboot.";
|
||||
"communicating"="Communicating with device. .";
|
||||
"connected.radio"="Connected Radio";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue