mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Mqtt config updates
This commit is contained in:
parent
457116657a
commit
5cd2b3342b
3 changed files with 147 additions and 61 deletions
|
|
@ -189,6 +189,8 @@
|
|||
<attribute name="enabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="encryptionEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="jsonEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="mapPositionPrecision" optional="YES" attributeType="Integer 32" defaultValueString="13" usesScalarValueType="YES"/>
|
||||
<attribute name="mapPublishIntervalSecs" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="mapReportingEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="password" optional="YES" attributeType="String" maxValueString="30"/>
|
||||
<attribute name="proxyToClientEnabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
|
|
|
|||
|
|
@ -1119,6 +1119,9 @@ func upsertMqttModuleConfigPacket(config: Meshtastic.ModuleConfig.MQTTConfig, no
|
|||
newMQTTConfig.encryptionEnabled = config.encryptionEnabled
|
||||
newMQTTConfig.jsonEnabled = config.jsonEnabled
|
||||
newMQTTConfig.tlsEnabled = config.tlsEnabled
|
||||
newMQTTConfig.mapReportingEnabled = config.mapReportingEnabled
|
||||
newMQTTConfig.mapPositionPrecision = Int32(config.mapReportSettings.positionPrecision)
|
||||
newMQTTConfig.mapPublishIntervalSecs = Int32(config.mapReportSettings.publishIntervalSecs)
|
||||
fetchedNode[0].mqttConfig = newMQTTConfig
|
||||
} else {
|
||||
fetchedNode[0].mqttConfig?.enabled = config.enabled
|
||||
|
|
@ -1130,6 +1133,9 @@ func upsertMqttModuleConfigPacket(config: Meshtastic.ModuleConfig.MQTTConfig, no
|
|||
fetchedNode[0].mqttConfig?.encryptionEnabled = config.encryptionEnabled
|
||||
fetchedNode[0].mqttConfig?.jsonEnabled = config.jsonEnabled
|
||||
fetchedNode[0].mqttConfig?.tlsEnabled = config.tlsEnabled
|
||||
fetchedNode[0].mqttConfig?.mapReportingEnabled = config.mapReportingEnabled
|
||||
fetchedNode[0].mqttConfig?.mapPositionPrecision = Int32(config.mapReportSettings.positionPrecision)
|
||||
fetchedNode[0].mqttConfig?.mapPublishIntervalSecs = Int32(config.mapReportSettings.publishIntervalSecs)
|
||||
}
|
||||
do {
|
||||
try context.save()
|
||||
|
|
|
|||
|
|
@ -28,6 +28,12 @@ struct MQTTConfig: View {
|
|||
@State var mqttConnected: Bool = false
|
||||
@State var defaultTopic = "msh/US"
|
||||
@State var nearbyTopics = [String]()
|
||||
@State var mapReportingEnabled = false
|
||||
@State var mapPublishIntervalSecs = 3600
|
||||
@State var preciseLocation: Bool = false
|
||||
@State var mapPositionPrecision: Double = 13.0
|
||||
|
||||
|
||||
let locale = Locale.current
|
||||
|
||||
var body: some View {
|
||||
|
|
@ -58,7 +64,7 @@ struct MQTTConfig: View {
|
|||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
|
||||
if enabled && proxyToClientEnabled {
|
||||
if enabled && proxyToClientEnabled && node!.mqttConfig!.proxyToClientEnabled == true {
|
||||
Toggle(isOn: $mqttConnected) {
|
||||
Label(mqttConnected ? "mqtt.disconnect".localized : "mqtt.connect".localized, systemImage: "server.rack")
|
||||
}
|
||||
|
|
@ -75,14 +81,95 @@ struct MQTTConfig: View {
|
|||
Text("JSON mode is a limited, unencrypted MQTT output for locally integrating with home assistant")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
}
|
||||
|
||||
Section(header: Text("Map Report")) {
|
||||
|
||||
Toggle(isOn: $tlsEnabled) {
|
||||
Label("TLS Enabled", systemImage: "checkmark.shield.fill")
|
||||
Text("Your MQTT Server must support TLS.")
|
||||
Toggle(isOn: $mapReportingEnabled) {
|
||||
Label("enabled", systemImage: "map")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
|
||||
if mapReportingEnabled {
|
||||
Picker("Map Publish Interval", selection: $mapPublishIntervalSecs ) {
|
||||
ForEach(UpdateIntervals.allCases) { ui in
|
||||
if ui.rawValue >= 3600 {
|
||||
Text(ui.description)
|
||||
}
|
||||
}
|
||||
}
|
||||
.pickerStyle(DefaultPickerStyle())
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
Toggle(isOn: $preciseLocation) {
|
||||
Label("Precise Location", systemImage: "scope")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
.listRowSeparator(.visible)
|
||||
.onChange(of: preciseLocation) { pl in
|
||||
if pl == false {
|
||||
mapPositionPrecision = 12
|
||||
} else {
|
||||
mapPositionPrecision = 32
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !preciseLocation {
|
||||
VStack(alignment: .leading) {
|
||||
Label("Approximate Location", systemImage: "location.slash.circle.fill")
|
||||
Slider(value: $mapPositionPrecision, in: 11...16, step: 1) {
|
||||
} minimumValueLabel: {
|
||||
Image(systemName: "minus")
|
||||
} maximumValueLabel: {
|
||||
Image(systemName: "plus")
|
||||
}
|
||||
Text(PositionPrecision(rawValue: Int(mapPositionPrecision))?.description ?? "")
|
||||
.foregroundColor(.gray)
|
||||
.font(.callout)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Section(header: Text("Root Topic")) {
|
||||
HStack {
|
||||
Label("Root Topic", systemImage: "tree")
|
||||
TextField("Root Topic", text: $root)
|
||||
.foregroundColor(.gray)
|
||||
.onChange(of: root, perform: { _ in
|
||||
let totalBytes = root.utf8.count
|
||||
// Only mess with the value if it is too big
|
||||
if totalBytes > 30 {
|
||||
let firstNBytes = Data(root.utf8.prefix(30))
|
||||
if let maxBytesString = String(data: firstNBytes, encoding: String.Encoding.utf8) {
|
||||
// Set the shortName back to the last place where it was the right size
|
||||
root = maxBytesString
|
||||
}
|
||||
}
|
||||
})
|
||||
.foregroundColor(.gray)
|
||||
}
|
||||
.keyboardType(.asciiCapable)
|
||||
.scrollDismissesKeyboard(.interactively)
|
||||
.disableAutocorrection(true)
|
||||
.listRowSeparator(.hidden)
|
||||
Text("The root topic to use for MQTT.")
|
||||
.foregroundColor(.gray)
|
||||
.font(.callout)
|
||||
|
||||
if nearbyTopics.count > 0 {
|
||||
Picker("Nearby Topics", selection: $selectedTopic ) {
|
||||
ForEach(nearbyTopics, id: \.self) { nt in
|
||||
Text(nt)
|
||||
}
|
||||
}
|
||||
.pickerStyle(InlinePickerStyle())
|
||||
.listRowSeparator(.hidden)
|
||||
Text("If the default region topic is too busy you can choose a more local topic.")
|
||||
.foregroundColor(.gray)
|
||||
.font(.callout)
|
||||
}
|
||||
}
|
||||
|
||||
Section(header: Text("Server")) {
|
||||
HStack {
|
||||
Label("Address", systemImage: "server.rack")
|
||||
|
|
@ -161,45 +248,13 @@ struct MQTTConfig: View {
|
|||
.keyboardType(.default)
|
||||
.scrollDismissesKeyboard(.interactively)
|
||||
.listRowSeparator(/*@START_MENU_TOKEN@*/.visible/*@END_MENU_TOKEN@*/)
|
||||
HStack {
|
||||
Label("Root Topic", systemImage: "tree")
|
||||
TextField("Root Topic", text: $root)
|
||||
.foregroundColor(.gray)
|
||||
.onChange(of: root, perform: { _ in
|
||||
let totalBytes = root.utf8.count
|
||||
// Only mess with the value if it is too big
|
||||
if totalBytes > 30 {
|
||||
let firstNBytes = Data(root.utf8.prefix(30))
|
||||
if let maxBytesString = String(data: firstNBytes, encoding: String.Encoding.utf8) {
|
||||
// Set the shortName back to the last place where it was the right size
|
||||
root = maxBytesString
|
||||
}
|
||||
}
|
||||
})
|
||||
.foregroundColor(.gray)
|
||||
}
|
||||
.keyboardType(.asciiCapable)
|
||||
.scrollDismissesKeyboard(.interactively)
|
||||
.disableAutocorrection(true)
|
||||
.listRowSeparator(.hidden)
|
||||
Text("The root topic to use for MQTT.")
|
||||
.foregroundColor(.gray)
|
||||
.font(.callout)
|
||||
|
||||
if nearbyTopics.count > 0 {
|
||||
Picker("Nearby Topics", selection: $selectedTopic ) {
|
||||
ForEach(nearbyTopics, id: \.self) { nt in
|
||||
Text(nt)
|
||||
}
|
||||
}
|
||||
.pickerStyle(InlinePickerStyle())
|
||||
.listRowSeparator(.hidden)
|
||||
Text("If the default region topic is too busy you can choose a more local topic.")
|
||||
.foregroundColor(.gray)
|
||||
.font(.callout)
|
||||
Toggle(isOn: $tlsEnabled) {
|
||||
Label("TLS Enabled", systemImage: "checkmark.shield.fill")
|
||||
Text("Your MQTT Server must support TLS.")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
}
|
||||
Text("You can set uplink and downlink for each channel.")
|
||||
Text("For all Mqtt functionality other than the map report you must also set uplink and downlink for each channel you want to brige over Mqtt.")
|
||||
.font(.callout)
|
||||
}
|
||||
.scrollDismissesKeyboard(.interactively)
|
||||
|
|
@ -219,6 +274,9 @@ struct MQTTConfig: View {
|
|||
mqtt.encryptionEnabled = self.encryptionEnabled
|
||||
mqtt.jsonEnabled = self.jsonEnabled
|
||||
mqtt.tlsEnabled = self.tlsEnabled
|
||||
mqtt.mapReportingEnabled = self.mapReportingEnabled
|
||||
mqtt.mapReportSettings.positionPrecision = UInt32(self.mapPositionPrecision)
|
||||
mqtt.mapReportSettings.publishIntervalSecs = UInt32(self.mapPublishIntervalSecs)
|
||||
let adminMessageId = bleManager.saveMQTTConfig(config: mqtt, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
|
||||
if adminMessageId > 0 {
|
||||
// Should show a saved successfully alert once I know that to be true
|
||||
|
|
@ -233,20 +291,6 @@ struct MQTTConfig: View {
|
|||
ZStack {
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?", mqttProxyConnected: bleManager.mqttProxyConnected)
|
||||
})
|
||||
.onAppear {
|
||||
if self.bleManager.context == nil {
|
||||
self.bleManager.context = context
|
||||
}
|
||||
setMqttValues()
|
||||
// Need to request a TelemetryModuleConfig from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.mqttConfig == nil {
|
||||
print("empty mqtt module config")
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
if node != nil && connectedNode != nil {
|
||||
_ = bleManager.requestMqttModuleConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: address) { newAddress in
|
||||
if node != nil && node?.mqttConfig != nil {
|
||||
if newAddress != node!.mqttConfig!.address { hasChanges = true }
|
||||
|
|
@ -315,6 +359,33 @@ struct MQTTConfig: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: mapReportingEnabled) { newMapReportingEnabled in
|
||||
if node != nil && node?.mqttConfig != nil {
|
||||
if newMapReportingEnabled != node!.mqttConfig!.mapReportingEnabled { hasChanges = true }
|
||||
}
|
||||
}
|
||||
.onChange(of: preciseLocation) { _ in
|
||||
hasChanges = true
|
||||
}
|
||||
.onChange(of: mapPublishIntervalSecs) { newMapPublishIntervalSecs in
|
||||
if node != nil && node?.mqttConfig != nil {
|
||||
if newMapPublishIntervalSecs != node!.mqttConfig!.mapPublishIntervalSecs { hasChanges = true }
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
if self.bleManager.context == nil {
|
||||
self.bleManager.context = context
|
||||
}
|
||||
setMqttValues()
|
||||
// Need to request a TelemetryModuleConfig from the remote node before allowing changes
|
||||
if bleManager.connectedPeripheral != nil && node?.mqttConfig == nil {
|
||||
print("empty mqtt module config")
|
||||
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
|
||||
if node != nil && connectedNode != nil {
|
||||
_ = bleManager.requestMqttModuleConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func setMqttValues() {
|
||||
|
||||
|
|
@ -367,16 +438,23 @@ struct MQTTConfig: View {
|
|||
})
|
||||
}
|
||||
}
|
||||
self.enabled = (node?.mqttConfig?.enabled ?? false)
|
||||
self.proxyToClientEnabled = (node?.mqttConfig?.proxyToClientEnabled ?? false)
|
||||
self.enabled = node?.mqttConfig?.enabled ?? false
|
||||
self.proxyToClientEnabled = node?.mqttConfig?.proxyToClientEnabled ?? false
|
||||
self.address = node?.mqttConfig?.address ?? ""
|
||||
self.username = node?.mqttConfig?.username ?? ""
|
||||
self.password = node?.mqttConfig?.password ?? ""
|
||||
self.root = node?.mqttConfig?.root ?? "msh"
|
||||
self.encryptionEnabled = (node?.mqttConfig?.encryptionEnabled ?? false)
|
||||
self.jsonEnabled = (node?.mqttConfig?.jsonEnabled ?? false)
|
||||
self.tlsEnabled = (node?.mqttConfig?.tlsEnabled ?? false)
|
||||
self.encryptionEnabled = node?.mqttConfig?.encryptionEnabled ?? false
|
||||
self.jsonEnabled = node?.mqttConfig?.jsonEnabled ?? false
|
||||
self.tlsEnabled = node?.mqttConfig?.tlsEnabled ?? false
|
||||
self.mqttConnected = bleManager.mqttProxyConnected
|
||||
self.mapReportingEnabled = node?.mqttConfig?.mapReportingEnabled ?? false
|
||||
self.mapPublishIntervalSecs = Int(node?.mqttConfig?.mapPublishIntervalSecs ?? 3600)
|
||||
self.mapPositionPrecision = Double(node?.mqttConfig?.mapPositionPrecision ?? 12)
|
||||
if mapPositionPrecision == 0.0 {
|
||||
self.mapPositionPrecision = 12
|
||||
}
|
||||
self.preciseLocation = mapPositionPrecision == 32
|
||||
self.hasChanges = false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue