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 .
//
import SwiftUI
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
@ State var address = " "
@ State var username = " "
@ State var password = " "
@ State var encryptionEnabled = false
@ State var jsonEnabled = false
2023-03-06 10:33:18 -08:00
2022-09-04 21:45:03 -07:00
var body : some View {
2023-03-06 10:33:18 -08:00
2022-12-30 11:08:59 -08:00
Form {
2023-03-13 19:17:43 -07:00
if node != nil && node ? . metadata = = nil && node ? . num ? ? 0 != bleManager . connectedPeripheral ? . num ? ? 0 {
Text ( " There has been no response to a request for device metadata over the admin channel for this node. " )
. font ( . callout )
. foregroundColor ( . orange )
2023-03-14 12:44:10 -07:00
2023-03-13 19:17:43 -07:00
} else if node != nil && node ? . num ? ? 0 != bleManager . connectedPeripheral ? . num ? ? 0 {
// L e t u s e r s k n o w w h a t i s g o i n g o n i f t h e y a r e u s i n g r e m o t e a d m i n a n d d o n ' t h a v e t h e c o n f i g y e t
2023-03-14 12:44:10 -07:00
if node ? . mqttConfig = = nil {
2023-03-13 19:17:43 -07:00
Text ( " MQTT config data was requested over the admin channel but no response has been returned from the remote node. You can check the status of admin message requests in the admin message log. " )
. font ( . callout )
. foregroundColor ( . orange )
} else {
Text ( " Remote administration for: \( node ? . user ? . longName ? ? " Unknown " ) " )
. font ( . title3 )
2023-03-19 18:37:23 -07:00
. onAppear {
setMqttValues ( )
}
2023-03-13 19:17:43 -07:00
}
2023-03-14 12:44:10 -07:00
} else if node != nil && node ? . num ? ? 0 = = bleManager . connectedPeripheral ? . num ? ? 0 {
2023-03-13 19:17:43 -07:00
Text ( " Configuration for: \( node ? . user ? . longName ? ? " Unknown " ) " )
. font ( . title3 )
} else {
Text ( " Please connect to a radio to configure settings. " )
. font ( . callout )
. foregroundColor ( . orange )
}
2022-12-30 11:08:59 -08:00
Section ( header : Text ( " options " ) ) {
Toggle ( isOn : $ enabled ) {
2022-09-04 21:45:03 -07:00
2022-12-30 11:08:59 -08:00
Label ( " enabled " , systemImage : " dot.radiowaves.right " )
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2023-03-06 10:33:18 -08:00
2022-12-30 11:08:59 -08:00
Toggle ( isOn : $ encryptionEnabled ) {
2022-09-04 21:45:03 -07:00
2022-12-30 11:08:59 -08:00
Label ( " Encryption Enabled " , systemImage : " lock.icloud " )
2022-09-04 21:45:03 -07:00
}
2022-12-30 11:08:59 -08:00
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2022-09-04 21:45:03 -07:00
2022-12-30 11:08:59 -08:00
Toggle ( isOn : $ jsonEnabled ) {
2022-09-04 21:45:03 -07:00
2022-12-30 11:08:59 -08:00
Label ( " JSON Enabled " , systemImage : " ellipsis.curlybraces " )
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
}
Section ( header : Text ( " Custom Server " ) ) {
HStack {
Label ( " Address " , systemImage : " server.rack " )
TextField ( " Server Address " , text : $ address )
. foregroundColor ( . gray )
. autocapitalization ( . none )
. disableAutocorrection ( true )
2023-03-06 10:33:18 -08:00
. onChange ( of : address , perform : { _ in
2022-12-30 11:08:59 -08:00
let totalBytes = address . utf8 . count
// 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
2023-03-24 10:35:54 -07:00
if totalBytes > 62 {
let firstNBytes = Data ( username . utf8 . prefix ( 62 ) )
2022-12-30 11:08:59 -08:00
if let maxBytesString = String ( data : firstNBytes , encoding : String . Encoding . utf8 ) {
// S e t t h e s h o r t N a m e b a c k t o t h e l a s t p l a c e w h e r e i t w a s t h e r i g h t s i z e
address = maxBytesString
}
}
hasChanges = true
} )
. foregroundColor ( . gray )
. keyboardType ( . default )
}
. autocorrectionDisabled ( )
2023-03-06 10:33:18 -08:00
2022-12-30 11:08:59 -08:00
HStack {
Label ( " mqtt.username " , systemImage : " person.text.rectangle " )
TextField ( " mqtt.username " , text : $ username )
. foregroundColor ( . gray )
. autocapitalization ( . none )
. disableAutocorrection ( true )
2023-03-06 10:33:18 -08:00
. onChange ( of : username , perform : { _ in
2022-09-04 21:45:03 -07:00
2022-12-30 11:08:59 -08:00
let totalBytes = username . utf8 . count
2023-03-06 10:33:18 -08:00
2022-12-30 11:08:59 -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
if totalBytes > 62 {
2022-09-04 21:45:03 -07:00
2022-12-30 11:08:59 -08:00
let firstNBytes = Data ( username . utf8 . prefix ( 62 ) )
2023-03-06 10:33:18 -08:00
2022-12-30 11:08:59 -08:00
if let maxBytesString = String ( data : firstNBytes , encoding : String . Encoding . utf8 ) {
2023-03-06 10:33:18 -08:00
2022-12-30 11:08:59 -08:00
// S e t t h e s h o r t N a m e b a c k t o t h e l a s t p l a c e w h e r e i t w a s t h e r i g h t s i z e
username = maxBytesString
}
}
hasChanges = true
} )
. foregroundColor ( . gray )
}
. keyboardType ( . default )
. scrollDismissesKeyboard ( . interactively )
HStack {
Label ( " password " , systemImage : " wallet.pass " )
TextField ( " password " , text : $ password )
. foregroundColor ( . gray )
. autocapitalization ( . none )
. disableAutocorrection ( true )
2023-03-06 10:33:18 -08:00
. onChange ( of : password , perform : { _ in
2022-09-04 21:45:03 -07:00
2022-12-30 11:08:59 -08:00
let totalBytes = password . utf8 . count
2023-03-06 10:33:18 -08:00
2022-12-30 11:08:59 -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
if totalBytes > 62 {
let firstNBytes = Data ( password . utf8 . prefix ( 62 ) )
2023-03-06 10:33:18 -08:00
2022-12-30 11:08:59 -08:00
if let maxBytesString = String ( data : firstNBytes , encoding : String . Encoding . utf8 ) {
2023-03-06 10:33:18 -08:00
2022-12-30 11:08:59 -08:00
// S e t t h e s h o r t N a m e b a c k t o t h e l a s t p l a c e w h e r e i t w a s t h e r i g h t s i z e
password = maxBytesString
2022-09-04 21:45:03 -07:00
}
2022-12-30 11:08:59 -08:00
}
hasChanges = true
} )
. foregroundColor ( . gray )
2022-09-04 21:45:03 -07:00
}
2022-12-30 11:08:59 -08:00
. keyboardType ( . default )
. scrollDismissesKeyboard ( . interactively )
2022-09-04 21:45:03 -07:00
}
2022-12-30 11:08:59 -08:00
Text ( " WiFi or Ethernet must also be enabled for MQTT to work. You can set uplink and downlink for each channel. " )
. font ( . callout )
}
. scrollDismissesKeyboard ( . interactively )
2023-02-01 09:19:45 -08:00
. disabled ( self . bleManager . connectedPeripheral = = nil || node ? . mqttConfig = = nil )
2023-03-06 10:33:18 -08:00
2022-12-30 11:08:59 -08:00
Button {
isPresentingSaveConfirm = true
} label : {
Label ( " save " , systemImage : " square.and.arrow.down " )
}
. disabled ( bleManager . connectedPeripheral = = nil || ! hasChanges )
. buttonStyle ( . bordered )
. buttonBorderShape ( . capsule )
. controlSize ( . large )
. padding ( )
. confirmationDialog (
" are.you.sure " ,
isPresented : $ isPresentingSaveConfirm ,
titleVisibility : . visible
) {
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 {
let nodeName = node ? . user ? . longName ? ? NSLocalizedString ( " unknown " , comment : " Unknown " )
let buttonText = String . localizedStringWithFormat ( NSLocalizedString ( " save.config %@ " , comment : " Save Config for %@ " ) , nodeName )
Button ( buttonText ) {
var mqtt = ModuleConfig . MQTTConfig ( )
mqtt . enabled = self . enabled
mqtt . address = self . address
mqtt . username = self . username
mqtt . password = self . password
mqtt . encryptionEnabled = self . encryptionEnabled
mqtt . jsonEnabled = self . jsonEnabled
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-30 11:08:59 -08:00
message : {
Text ( " config.save.confirm " )
}
2022-12-13 07:49:46 -08:00
. navigationTitle ( " mqtt.config " )
2022-09-04 21:45:03 -07:00
. navigationBarItems ( trailing :
ZStack {
2022-11-15 20:11:37 -08:00
ConnectedDevice ( bluetoothOn : bleManager . isSwitchedOn , deviceConnected : bleManager . connectedPeripheral != nil , name : ( bleManager . connectedPeripheral != nil ) ? bleManager . connectedPeripheral . shortName : " ???? " )
2022-09-04 21:45:03 -07:00
} )
. onAppear {
2022-10-15 01:00:13 -07:00
self . bleManager . context = context
2023-03-19 18:37:23 -07:00
setMqttValues ( )
2023-03-06 10:33:18 -08:00
2023-02-01 09:19:45 -08:00
// N e e d t o r e q u e s t a T e l e m e t r y 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
2023-03-19 08:31:16 -07:00
if bleManager . connectedPeripheral != nil && node ? . mqttConfig = = nil {
2023-02-01 09:19:45 -08:00
print ( " empty mqtt module config " )
let connectedNode = getNodeInfo ( id : bleManager . connectedPeripheral . num , context : context )
2023-03-05 14:40:07 -08:00
if node != nil && connectedNode != nil {
2023-02-06 18:45:03 -08:00
_ = bleManager . requestMqttModuleConfig ( fromUser : connectedNode ! . user ! , toUser : node ! . user ! , adminIndex : connectedNode ? . myInfo ? . adminIndex ? ? 0 )
2023-02-01 09:19:45 -08:00
}
}
2022-09-04 21:45:03 -07:00
}
. onChange ( of : enabled ) { newEnabled in
2023-01-02 20:11:58 -08:00
if node != nil && node ? . mqttConfig != nil {
2022-09-10 17:14:03 -07:00
if newEnabled != node ! . mqttConfig ! . enabled { hasChanges = true }
2022-09-04 21:45:03 -07:00
}
}
. onChange ( of : encryptionEnabled ) { newEncryptionEnabled in
2023-01-02 20:11:58 -08:00
if node != nil && node ? . mqttConfig != nil {
2022-09-04 21:45:03 -07:00
if newEncryptionEnabled != node ! . mqttConfig ! . encryptionEnabled { hasChanges = true }
}
}
. onChange ( of : jsonEnabled ) { newJsonEnabled in
2023-01-02 20:11:58 -08:00
if node != nil && node ? . mqttConfig != nil {
2022-09-04 21:45:03 -07:00
if newJsonEnabled != node ! . mqttConfig ! . jsonEnabled { hasChanges = true }
}
}
}
2023-03-19 18:37:23 -07:00
func setMqttValues ( ) {
self . enabled = ( node ? . mqttConfig ? . enabled ? ? false )
self . address = node ? . mqttConfig ? . address ? ? " "
self . username = node ? . mqttConfig ? . username ? ? " "
self . password = node ? . mqttConfig ? . password ? ? " "
self . encryptionEnabled = ( node ? . mqttConfig ? . encryptionEnabled ? ? false )
self . jsonEnabled = ( node ? . mqttConfig ? . jsonEnabled ? ? false )
self . hasChanges = false
}
2022-09-04 21:45:03 -07:00
}