2022-09-04 21:45:03 -07:00
//
// M Q T T . s w i f t
// M e s h t a s t i c
//
// C o p y r i g h t ( c ) G a r t h V a n d e r H o u w e n 9 / 4 / 2 2 .
//
2024-03-13 05:52:31 -07:00
import CoreLocation
2024-06-07 22:09:20 -05:00
import MeshtasticProtobufs
2024-06-03 02:17:55 -07:00
import OSLog
2024-06-07 22:09:20 -05:00
import SwiftUI
2022-09-04 21:45:03 -07:00
struct MQTTConfig : View {
2023-03-06 10:33:18 -08:00
2022-09-04 21:45:03 -07:00
@ Environment ( \ . managedObjectContext ) var context
@ EnvironmentObject var bleManager : BLEManager
2022-12-09 18:19:00 -08:00
@ Environment ( \ . dismiss ) private var goBack
2022-09-04 21:45:03 -07:00
var node : NodeInfoEntity ?
@ State private var isPresentingSaveConfirm : Bool = false
@ State var hasChanges : Bool = false
@ State var enabled = false
2023-08-06 17:41:46 -07:00
@ State var proxyToClientEnabled = false
2022-09-04 21:45:03 -07:00
@ State var address = " "
@ State var username = " "
@ State var password = " "
2023-10-03 08:41:44 -07:00
@ State var encryptionEnabled = true
2022-09-04 21:45:03 -07:00
@ State var jsonEnabled = false
2024-08-25 23:02:43 -07:00
@ State var tlsEnabled = false
2023-05-04 21:49:35 -07:00
@ State var root = " msh "
2024-03-13 05:52:31 -07:00
@ State var selectedTopic = " "
2024-01-20 21:25:02 -08:00
@ State var mqttConnected : Bool = false
2024-03-14 18:58:05 -07:00
@ State var defaultTopic = " msh/US "
2024-03-13 05:52:31 -07:00
@ State var nearbyTopics = [ String ] ( )
2024-03-26 13:26:23 -07:00
@ State var mapReportingEnabled = false
@ State var mapPublishIntervalSecs = 3600
2024-09-08 11:10:58 -07:00
@ State var mapPositionPrecision : Double = 14.0
2024-05-29 16:40:07 -05:00
2024-03-14 18:58:05 -07:00
let locale = Locale . current
2023-03-06 10:33:18 -08:00
2022-09-04 21:45:03 -07:00
var body : some View {
2023-12-06 12:32:17 -08:00
VStack {
Form {
2024-02-06 09:13:57 -08:00
if node != nil && node ? . loRaConfig != nil {
let rc = RegionCodes ( rawValue : Int ( node ? . loRaConfig ? . regionCode ? ? 0 ) )
2024-05-29 16:40:07 -05:00
if rc ? . dutyCycle ? ? 0 > 0 && rc ? . dutyCycle ? ? 0 < 100 {
2024-02-14 21:43:29 -08:00
Text ( " Your region has a \( rc ? . dutyCycle ? ? 0 ) % duty cycle. MQTT is not advised when you are duty cycle restricted, the extra traffic will quickly overwhelm your LoRa mesh. " )
2024-02-06 09:13:57 -08:00
. font ( . callout )
. foregroundColor ( . red )
}
}
2024-02-17 22:39:22 -07:00
ConfigHeader ( title : " MQTT " , config : \ . mqttConfig , node : node , onAppear : setMqttValues )
2023-12-06 12:32:17 -08:00
Section ( header : Text ( " options " ) ) {
2024-05-29 16:40:07 -05:00
2023-12-06 12:32:17 -08:00
Toggle ( isOn : $ enabled ) {
2024-03-26 07:54:16 -07:00
Label ( " enabled " , systemImage : " dot.radiowaves.up.forward " )
2023-12-06 12:32:17 -08:00
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2024-05-29 16:40:07 -05:00
2023-12-06 12:32:17 -08:00
Toggle ( isOn : $ proxyToClientEnabled ) {
2024-05-29 16:40:07 -05:00
2023-12-06 12:32:17 -08:00
Label ( " mqtt.clientproxy " , systemImage : " iphone.radiowaves.left.and.right " )
2024-03-13 05:52:31 -07:00
Text ( " Utilizes the network connection on your phone to connect to MQTT. " )
2023-12-06 12:32:17 -08:00
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2024-05-29 16:40:07 -05:00
2024-03-26 13:26:23 -07:00
if enabled && proxyToClientEnabled && node ! . mqttConfig ! . proxyToClientEnabled = = true {
2024-01-20 21:25:02 -08:00
Toggle ( isOn : $ mqttConnected ) {
Label ( mqttConnected ? " mqtt.disconnect " . localized : " mqtt.connect " . localized , systemImage : " server.rack " )
2024-04-05 17:14:04 -07:00
if bleManager . mqttError . count > 0 {
Text ( bleManager . mqttError )
. fixedSize ( horizontal : false , vertical : true )
. foregroundColor ( . red )
}
2024-05-29 16:40:07 -05:00
2024-01-20 21:25:02 -08:00
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
}
2024-05-29 16:40:07 -05:00
2023-12-06 12:32:17 -08:00
Toggle ( isOn : $ encryptionEnabled ) {
Label ( " Encryption Enabled " , systemImage : " lock.icloud " )
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2024-05-29 16:40:07 -05:00
2023-12-06 12:32:17 -08:00
Toggle ( isOn : $ jsonEnabled ) {
Label ( " JSON Enabled " , systemImage : " ellipsis.curlybraces " )
2024-03-13 05:52:31 -07:00
Text ( " JSON mode is a limited, unencrypted MQTT output for locally integrating with home assistant " )
2023-12-06 12:32:17 -08:00
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2024-03-26 13:26:23 -07:00
}
2024-05-29 16:40:07 -05:00
2024-03-26 13:26:23 -07:00
Section ( header : Text ( " Map Report " ) ) {
2024-05-29 16:40:07 -05:00
2024-03-26 13:26:23 -07:00
Toggle ( isOn : $ mapReportingEnabled ) {
Label ( " enabled " , systemImage : " map " )
2023-12-06 12:32:17 -08:00
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2024-03-26 13:26:23 -07:00
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 ) {
2024-09-06 17:05:25 -07:00
Label ( " Approximate Location " , systemImage : " location.slash.circle.fill " )
Slider ( value : $ mapPositionPrecision , in : 11. . . 14 , step : 1 ) {
} minimumValueLabel : {
Image ( systemName : " minus " )
} maximumValueLabel : {
Image ( systemName : " plus " )
2024-03-26 13:26:23 -07:00
}
2024-09-06 17:05:25 -07:00
Text ( PositionPrecision ( rawValue : Int ( mapPositionPrecision ) ) ? . description ? ? " " )
. foregroundColor ( . gray )
. font ( . callout )
2024-03-26 13:26:23 -07:00
}
}
}
Section ( header : Text ( " Root Topic " ) ) {
HStack {
Label ( " Root Topic " , systemImage : " tree " )
TextField ( " Root Topic " , text : $ root )
. foregroundColor ( . gray )
2024-10-05 15:50:57 -07:00
. onChange ( of : root ) {
2024-09-22 08:03:18 -07:00
var totalBytes = root . utf8 . count
2024-03-26 13:26:23 -07:00
// O n l y m e s s w i t h t h e v a l u e i f i t i s t o o b i g
2024-09-22 08:03:18 -07:00
while totalBytes > 30 {
2024-04-04 09:39:03 -07:00
root = String ( root . dropLast ( ) )
2024-09-22 08:03:18 -07:00
totalBytes = root . utf8 . count
2024-03-26 13:26:23 -07:00
}
2024-10-05 15:50:57 -07:00
}
2024-03-26 13:26:23 -07:00
. foregroundColor ( . gray )
}
. keyboardType ( . asciiCapable )
. scrollDismissesKeyboard ( . interactively )
. disableAutocorrection ( true )
. listRowSeparator ( . hidden )
Text ( " The root topic to use for MQTT. " )
. foregroundColor ( . gray )
. font ( . callout )
2024-05-29 16:40:07 -05:00
2024-03-26 13:26:23 -07:00
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 )
}
2022-12-30 11:08:59 -08:00
}
2024-05-29 16:40:07 -05:00
2024-03-13 05:52:31 -07:00
Section ( header : Text ( " Server " ) ) {
2023-12-06 12:32:17 -08:00
HStack {
Label ( " Address " , systemImage : " server.rack " )
TextField ( " Server Address " , text : $ address )
. foregroundColor ( . gray )
. autocapitalization ( . none )
. disableAutocorrection ( true )
2024-10-05 15:50:57 -07:00
. onChange ( of : address ) {
2024-09-22 08:03:18 -07:00
var totalBytes = address . utf8 . count
2023-12-06 12:32:17 -08:00
// O n l y m e s s w i t h t h e v a l u e i f i t i s t o o b i g
2024-09-22 08:03:18 -07:00
while totalBytes > 62 {
2024-04-04 09:39:03 -07:00
address = String ( address . dropLast ( ) )
2024-09-22 08:03:18 -07:00
totalBytes = address . utf8 . count
2022-12-30 11:08:59 -08:00
}
2023-12-06 12:32:17 -08:00
hasChanges = true
2024-10-05 15:50:57 -07:00
}
2023-12-06 12:32:17 -08:00
. keyboardType ( . default )
}
. autocorrectionDisabled ( )
2024-05-29 16:40:07 -05:00
2023-12-06 12:32:17 -08:00
HStack {
Label ( " mqtt.username " , systemImage : " person.text.rectangle " )
TextField ( " mqtt.username " , text : $ username )
. foregroundColor ( . gray )
. autocapitalization ( . none )
. disableAutocorrection ( true )
2024-10-05 15:50:57 -07:00
. onChange ( of : username ) {
2024-09-22 08:03:18 -07:00
var totalBytes = username . utf8 . count
2023-12-06 12:32:17 -08:00
// O n l y m e s s w i t h t h e v a l u e i f i t i s t o o b i g
2024-09-22 08:03:18 -07:00
while totalBytes > 62 {
2024-04-04 09:39:03 -07:00
username = String ( username . dropLast ( ) )
2024-09-22 08:03:18 -07:00
totalBytes = username . utf8 . count
2022-12-30 11:08:59 -08:00
}
2023-12-06 12:32:17 -08:00
hasChanges = true
2024-10-05 15:50:57 -07:00
}
2023-12-06 12:32:17 -08:00
. foregroundColor ( . gray )
}
. keyboardType ( . default )
. scrollDismissesKeyboard ( . interactively )
HStack {
Label ( " password " , systemImage : " wallet.pass " )
TextField ( " password " , text : $ password )
. foregroundColor ( . gray )
. autocapitalization ( . none )
. disableAutocorrection ( true )
2024-10-05 15:50:57 -07:00
. onChange ( of : password ) {
2024-09-22 08:03:18 -07:00
var totalBytes = password . utf8 . count
2023-12-06 12:32:17 -08:00
// O n l y m e s s w i t h t h e v a l u e i f i t i s t o o b i g
2024-09-22 08:03:18 -07:00
while totalBytes > 62 {
2024-04-04 09:39:03 -07:00
password = String ( password . dropLast ( ) )
2024-09-22 08:03:18 -07:00
totalBytes = password . utf8 . count
2022-09-04 21:45:03 -07:00
}
2023-12-06 12:32:17 -08:00
hasChanges = true
2024-10-05 15:50:57 -07:00
}
2023-12-06 12:32:17 -08:00
. foregroundColor ( . gray )
}
. keyboardType ( . default )
. scrollDismissesKeyboard ( . interactively )
2024-03-13 05:52:31 -07:00
. listRowSeparator ( /* @ S T A R T _ M E N U _ T O K E N @ */ . visible /* @ E N D _ M E N U _ T O K E N @ */ )
2024-03-26 13:26:23 -07:00
Toggle ( isOn : $ tlsEnabled ) {
Label ( " TLS Enabled " , systemImage : " checkmark.shield.fill " )
2024-08-25 23:02:43 -07:00
Text ( " Your MQTT Server must support TLS. Not available via the public mqtt server. " )
2024-03-13 05:52:31 -07:00
}
2024-03-26 13:26:23 -07:00
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2023-05-04 21:49:35 -07:00
}
2024-03-26 14:57:00 -07:00
Text ( " For all Mqtt functionality other than the map report you must also set uplink and downlink for each channel you want to bridge over Mqtt. " )
2023-12-06 12:32:17 -08:00
. font ( . callout )
2022-09-04 21:45:03 -07:00
}
2023-12-06 12:32:17 -08:00
. scrollDismissesKeyboard ( . interactively )
. disabled ( self . bleManager . connectedPeripheral = = nil || node ? . mqttConfig = = nil )
2022-12-30 11:08:59 -08:00
}
2024-02-18 00:03:34 -07:00
SaveConfigButton ( node : node , hasChanges : $ hasChanges ) {
2023-02-22 20:31:08 -08:00
let connectedNode = getNodeInfo ( id : bleManager . connectedPeripheral ? . num ? ? - 1 , context : context )
2023-02-06 18:45:03 -08:00
if connectedNode != nil {
2024-02-18 00:03:34 -07:00
var mqtt = ModuleConfig . MQTTConfig ( )
mqtt . enabled = self . enabled
mqtt . proxyToClientEnabled = self . proxyToClientEnabled
mqtt . address = self . address
mqtt . username = self . username
mqtt . password = self . password
mqtt . root = self . root
mqtt . encryptionEnabled = self . encryptionEnabled
mqtt . jsonEnabled = self . jsonEnabled
mqtt . tlsEnabled = self . tlsEnabled
2024-03-26 13:26:23 -07:00
mqtt . mapReportingEnabled = self . mapReportingEnabled
mqtt . mapReportSettings . positionPrecision = UInt32 ( self . mapPositionPrecision )
mqtt . mapReportSettings . publishIntervalSecs = UInt32 ( self . mapPublishIntervalSecs )
2024-02-18 00:03:34 -07:00
let adminMessageId = bleManager . saveMQTTConfig ( config : mqtt , fromUser : connectedNode ! . user ! , toUser : node ! . user ! , adminIndex : connectedNode ? . myInfo ? . adminIndex ? ? 0 )
if adminMessageId > 0 {
// S h o u l d s h o w a s a v e d s u c c e s s f u l l y a l e r t o n c e I k n o w t h a t t o b e t r u e
// f o r n o w j u s t d i s a b l e t h e b u t t o n a f t e r a s u c c e s s f u l s a v e
hasChanges = false
goBack ( )
2022-09-04 21:45:03 -07:00
}
}
}
2022-12-13 07:49:46 -08:00
. navigationTitle ( " mqtt.config " )
2024-08-11 09:07:22 -07:00
. navigationBarItems (
trailing : ZStack {
ConnectedDevice (
bluetoothOn : bleManager . isSwitchedOn ,
deviceConnected : bleManager . connectedPeripheral != nil ,
name : bleManager . connectedPeripheral ? . shortName ? ? " ? "
)
}
)
2024-10-06 08:50:12 -07:00
. onChange ( of : enabled ) { _ , newEnabled in
if newEnabled != node ? . mqttConfig ? . enabled { hasChanges = true }
2024-08-11 17:31:27 -07:00
}
2024-10-06 08:50:12 -07:00
. onChange ( of : proxyToClientEnabled ) { _ , newProxyToClientEnabled in
2024-08-11 17:31:27 -07:00
if newProxyToClientEnabled {
jsonEnabled = false
}
if newProxyToClientEnabled != node ? . mqttConfig ? . proxyToClientEnabled { hasChanges = true }
}
2024-10-06 08:50:12 -07:00
. onChange ( of : address ) { _ , newAddress in
if newAddress != node ? . mqttConfig ? . address ? ? " " { hasChanges = true }
2023-05-04 21:49:35 -07:00
}
. onChange ( of : username ) { newUsername in
2024-10-06 08:50:12 -07:00
if newUsername != node ? . mqttConfig ? . username ? ? " " { hasChanges = true }
2023-05-04 21:49:35 -07:00
}
. onChange ( of : password ) { newPassword in
2024-10-06 09:07:55 -07:00
if newPassword != node ? . mqttConfig ? . password ? ? " " { hasChanges = true }
2023-05-04 21:49:35 -07:00
}
. onChange ( of : root ) { newRoot in
2024-10-06 09:07:55 -07:00
if newRoot != node ? . mqttConfig ? . root ? ? " " { hasChanges = true }
2023-05-04 21:49:35 -07:00
}
2024-10-06 08:50:12 -07:00
. onChange ( of : selectedTopic ) { _ , newSelectedTopic in
2024-03-13 05:52:31 -07:00
root = newSelectedTopic
}
2024-10-06 08:50:12 -07:00
. onChange ( of : encryptionEnabled ) { _ , newEncryptionEnabled in
if newEncryptionEnabled != node ? . mqttConfig ? . encryptionEnabled { hasChanges = true }
2022-09-04 21:45:03 -07:00
}
2024-10-06 08:50:12 -07:00
. onChange ( of : jsonEnabled ) { _ , newJsonEnabled in
2024-03-24 22:31:47 -07:00
if newJsonEnabled {
proxyToClientEnabled = false
}
2024-08-11 17:31:27 -07:00
if newJsonEnabled != node ? . mqttConfig ? . jsonEnabled { hasChanges = true }
2022-09-04 21:45:03 -07:00
}
2024-10-06 08:50:12 -07:00
. onChange ( of : tlsEnabled ) { _ , newTlsEnabled in
2024-08-25 23:02:43 -07:00
if address . lowercased ( ) = = " mqtt.meshtastic.org " {
tlsEnabled = false
} else {
if newTlsEnabled != node ? . mqttConfig ? . tlsEnabled { hasChanges = true }
}
2023-05-04 21:49:35 -07:00
}
2024-10-06 08:50:12 -07:00
. onChange ( of : mqttConnected ) { _ , newMqttConnected in
2024-01-20 21:25:02 -08:00
if newMqttConnected = = false {
if bleManager . mqttProxyConnected {
bleManager . mqttManager . disconnect ( )
}
} else {
if ! bleManager . mqttProxyConnected && node != nil {
bleManager . mqttManager . connectFromConfigSettings ( node : node ! )
}
}
}
2024-10-06 08:50:12 -07:00
. onChange ( of : mapReportingEnabled ) { _ , newMapReportingEnabled in
if newMapReportingEnabled != node ? . mqttConfig ? . mapReportingEnabled { hasChanges = true }
2024-03-26 13:26:23 -07:00
}
2024-10-06 09:07:55 -07:00
. onChange ( of : mapPublishIntervalSecs ) { _ , newMapPublishIntervalSecs in
if newMapPublishIntervalSecs != node ? . mqttConfig ? . mapPublishIntervalSecs ? ? - 1 { hasChanges = true }
2024-03-26 13:26:23 -07:00
}
2024-09-05 19:31:29 -07:00
. onFirstAppear {
// N e e d t o r e q u e s t a M q t t M o d u l e C o n f i g f r o m t h e r e m o t e n o d e b e f o r e a l l o w i n g c h a n g e s
if let connectedPeripheral = bleManager . connectedPeripheral , let node {
2024-06-03 02:17:55 -07:00
Logger . mesh . info ( " empty mqtt module config " )
2024-09-05 19:31:29 -07:00
let connectedNode = getNodeInfo ( id : connectedPeripheral . num , context : context )
if let connectedNode {
if node . num != connectedNode . num {
if UserDefaults . enableAdministration && node . num != connectedNode . num {
// / 2 . 5 A d m i n i s t r a t i o n w i t h s e s s i o n p a s s k e y
let expiration = node . sessionExpiration ? ? Date ( )
if expiration < Date ( ) || node . mqttConfig = = nil {
_ = bleManager . requestMqttModuleConfig ( fromUser : connectedNode . user ! , toUser : node . user ! , adminIndex : connectedNode . myInfo ? . adminIndex ? ? 0 )
}
} else {
// / L e g a c y A d m i n i s t r a t i o n
_ = bleManager . requestMqttModuleConfig ( fromUser : connectedNode . user ! , toUser : node . user ! , adminIndex : connectedNode . myInfo ? . adminIndex ? ? 0 )
}
}
2024-03-26 13:26:23 -07:00
}
}
}
2022-09-04 21:45:03 -07:00
}
2023-03-19 18:37:23 -07:00
func setMqttValues ( ) {
2024-05-29 16:40:07 -05:00
2024-10-05 10:44:46 -07:00
nearbyTopics = [ ]
let geocoder = CLGeocoder ( )
if LocationsHandler . shared . locationsArray . count > 0 {
let region = RegionCodes ( rawValue : Int ( node ? . loRaConfig ? . regionCode ? ? 0 ) ) ? . topic
defaultTopic = " msh/ " + ( region ? ? " UNSET " )
geocoder . reverseGeocodeLocation ( LocationsHandler . shared . locationsArray . first ! , completionHandler : { ( placemarks , error ) in
if let error {
Logger . services . error ( " Failed to reverse geocode location: \( error . localizedDescription ) " )
return
}
2024-05-29 16:40:07 -05:00
2024-10-05 10:44:46 -07:00
if let placemarks = placemarks , let placemark = placemarks . first {
let cc = locale . region ? . identifier ? ? " UNK "
// / C o u n t r y T o p i c u n l e s s y o u a r e U S
if placemark . isoCountryCode ? ? " unknown " != cc {
let countryTopic = defaultTopic + " / " + ( placemark . isoCountryCode ? ? " " )
if ! countryTopic . isEmpty {
nearbyTopics . append ( countryTopic )
2024-03-13 05:52:31 -07:00
}
}
2024-10-05 10:44:46 -07:00
let stateTopic = defaultTopic + " / " + ( placemark . administrativeArea ? ? " " )
if ! stateTopic . isEmpty {
nearbyTopics . append ( stateTopic )
}
let countyTopic = defaultTopic + " / " + ( placemark . administrativeArea ? ? " " ) + " / " + ( placemark . subAdministrativeArea ? . lowercased ( ) . replacingOccurrences ( of : " " , with : " " ) ? ? " " )
if ! countyTopic . isEmpty {
nearbyTopics . append ( countyTopic )
}
let cityTopic = defaultTopic + " / " + ( placemark . administrativeArea ? ? " " ) + " / " + ( placemark . locality ? . lowercased ( ) . replacingOccurrences ( of : " " , with : " " ) ? ? " " )
if ! cityTopic . isEmpty {
nearbyTopics . append ( cityTopic )
}
let neightborhoodTopic = defaultTopic + " / " + ( placemark . administrativeArea ? ? " " ) + " / " + ( placemark . subLocality ? . lowercased ( )
. replacingOccurrences ( of : " " , with : " " )
. replacingOccurrences ( of : " ' " , with : " " ) ? ? " " )
if ! neightborhoodTopic . isEmpty {
nearbyTopics . append ( neightborhoodTopic )
}
} else {
Logger . services . debug ( " No Location " )
}
} )
2024-03-13 05:52:31 -07:00
}
2024-10-05 10:44:46 -07:00
2024-03-26 13:26:23 -07:00
self . enabled = node ? . mqttConfig ? . enabled ? ? false
self . proxyToClientEnabled = node ? . mqttConfig ? . proxyToClientEnabled ? ? false
2023-03-19 18:37:23 -07:00
self . address = node ? . mqttConfig ? . address ? ? " "
self . username = node ? . mqttConfig ? . username ? ? " "
self . password = node ? . mqttConfig ? . password ? ? " "
2023-05-04 21:49:35 -07:00
self . root = node ? . mqttConfig ? . root ? ? " msh "
2024-03-26 13:26:23 -07:00
self . encryptionEnabled = node ? . mqttConfig ? . encryptionEnabled ? ? false
self . jsonEnabled = node ? . mqttConfig ? . jsonEnabled ? ? false
self . tlsEnabled = node ? . mqttConfig ? . tlsEnabled ? ? false
2024-01-20 21:25:02 -08:00
self . mqttConnected = bleManager . mqttProxyConnected
2024-03-26 13:26:23 -07:00
self . mapReportingEnabled = node ? . mqttConfig ? . mapReportingEnabled ? ? false
self . mapPublishIntervalSecs = Int ( node ? . mqttConfig ? . mapPublishIntervalSecs ? ? 3600 )
2024-09-06 17:05:25 -07:00
self . mapPositionPrecision = Double ( node ? . mqttConfig ? . mapPositionPrecision ? ? 14 )
if mapPositionPrecision < 11 || mapPositionPrecision > 14 {
self . mapPositionPrecision = 14
self . hasChanges = true
} else {
self . hasChanges = false
2024-03-26 13:26:23 -07:00
}
2023-03-19 18:37:23 -07:00
}
2022-09-04 21:45:03 -07:00
}