2022-06-22 15:52:51 -07:00
//
// S e r i a l C o n f i g . s w i f t
// M e s h t a s t i c A p p l e
//
// 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 6 / 2 2 / 2 2 .
//
import SwiftUI
struct SerialConfig : View {
2023-03-06 10:33:18 -08:00
2022-06-22 15:52:51 -07:00
@ Environment ( \ . managedObjectContext ) var context
@ EnvironmentObject var bleManager : BLEManager
2022-12-09 18:19:00 -08:00
@ Environment ( \ . dismiss ) private var goBack
2023-03-06 10:33:18 -08:00
2022-07-07 00:29:52 -07:00
var node : NodeInfoEntity ?
2023-03-06 10:33:18 -08:00
2022-06-28 20:20:02 -07:00
@ State private var isPresentingSaveConfirm : Bool = false
@ State var hasChanges = false
2023-03-06 10:33:18 -08:00
2022-06-22 15:52:51 -07:00
@ State var enabled = false
@ State var echo = false
@ State var rxd = 0
@ State var txd = 0
@ State var baudRate = 0
@ State var timeout = 0
2023-12-30 09:21:42 -08:00
@ State var overrideConsoleSerialPort = false
2022-06-22 15:52:51 -07:00
@ State var mode = 0
2023-12-30 09:21:42 -08:00
2023-03-06 10:33:18 -08:00
2022-06-22 15:52:51 -07:00
var body : some View {
VStack {
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 ? . serialConfig = = nil {
2023-03-13 19:17:43 -07:00
Text ( " Serial 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 {
setSerialValues ( )
}
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-13 08:47:14 -08:00
Section ( header : Text ( " options " ) ) {
2023-03-06 10:33:18 -08:00
2022-06-22 15:52:51 -07:00
Toggle ( isOn : $ enabled ) {
2022-12-13 08:47:14 -08:00
Label ( " enabled " , systemImage : " terminal " )
2022-06-22 15:52:51 -07:00
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2023-03-06 10:33:18 -08:00
2022-06-22 15:52:51 -07:00
Toggle ( isOn : $ echo ) {
2022-12-13 17:47:23 -08:00
Label ( " echo " , systemImage : " repeat " )
2022-06-22 15:52:51 -07:00
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2022-06-28 20:20:02 -07:00
Text ( " If set, any packets you send will be echoed back to your device. " )
. font ( . caption )
2023-03-06 10:33:18 -08:00
2022-12-13 17:47:23 -08:00
Picker ( " Baud " , selection : $ baudRate ) {
2022-06-22 15:52:51 -07:00
ForEach ( SerialBaudRates . allCases ) { sbr in
Text ( sbr . description )
}
}
. pickerStyle ( DefaultPickerStyle ( ) )
2023-03-06 10:33:18 -08:00
2022-12-13 17:47:23 -08:00
Picker ( " timeout " , selection : $ timeout ) {
2022-06-22 15:52:51 -07:00
ForEach ( SerialTimeoutIntervals . allCases ) { sti in
Text ( sti . description )
}
}
. pickerStyle ( DefaultPickerStyle ( ) )
2022-06-28 20:20:02 -07:00
Text ( " The amount of time to wait before we consider your packet as done. " )
. font ( . caption )
2023-03-06 10:33:18 -08:00
2022-12-13 17:47:23 -08:00
Picker ( " mode " , selection : $ mode ) {
2022-06-22 15:52:51 -07:00
ForEach ( SerialModeTypes . allCases ) { smt in
Text ( smt . description )
}
}
. pickerStyle ( DefaultPickerStyle ( ) )
}
Section ( header : Text ( " GPIO " ) ) {
2023-03-06 10:33:18 -08:00
2022-06-22 15:52:51 -07:00
Picker ( " Receive data (rxd) GPIO pin " , selection : $ rxd ) {
2023-04-03 17:48:58 -07:00
ForEach ( 0. . < 46 ) {
2022-06-22 15:52:51 -07:00
if $0 = = 0 {
2022-12-30 17:44:39 -08:00
Text ( " unset " )
2022-06-22 15:52:51 -07:00
} else {
Text ( " Pin \( $0 ) " )
}
}
}
. pickerStyle ( DefaultPickerStyle ( ) )
Picker ( " Transmit data (txd) GPIO pin " , selection : $ txd ) {
2023-04-03 17:48:58 -07:00
ForEach ( 0. . < 46 ) {
2022-06-22 15:52:51 -07:00
if $0 = = 0 {
2022-12-30 17:44:39 -08:00
Text ( " unset " )
2022-06-22 15:52:51 -07:00
} else {
Text ( " Pin \( $0 ) " )
}
}
}
. pickerStyle ( DefaultPickerStyle ( ) )
2022-06-28 20:20:02 -07:00
Text ( " Set the GPIO pins for RXD and TXD. " )
. font ( . caption )
}
}
2023-02-01 09:19:45 -08:00
. disabled ( self . bleManager . connectedPeripheral = = nil || node ? . serialConfig = = nil )
2023-03-06 10:33:18 -08:00
2022-06-28 20:20:02 -07:00
Button {
2023-03-06 10:33:18 -08:00
2022-06-28 20:20:02 -07:00
isPresentingSaveConfirm = true
2023-03-06 10:33:18 -08:00
2022-06-28 20:20:02 -07:00
} label : {
2023-03-06 10:33:18 -08:00
2022-12-12 20:35:38 -08:00
Label ( " save " , systemImage : " square.and.arrow.down " )
2022-06-28 20:20:02 -07:00
}
2022-10-19 14:11:36 -07:00
. disabled ( bleManager . connectedPeripheral = = nil || ! hasChanges )
2022-06-28 20:20:02 -07:00
. buttonStyle ( . bordered )
. buttonBorderShape ( . capsule )
. controlSize ( . large )
. padding ( )
. confirmationDialog (
2023-03-06 10:33:18 -08:00
2022-12-13 08:47:14 -08:00
" are.you.sure " ,
2022-10-04 18:19:02 -07:00
isPresented : $ isPresentingSaveConfirm ,
titleVisibility : . visible
2022-06-28 20:20:02 -07:00
) {
2023-05-05 09:27:24 -07:00
let nodeName = node ? . user ? . longName ? ? " unknown " . localized
let buttonText = String . localizedStringWithFormat ( " save.config %@ " . localized , nodeName )
2023-01-09 18:34:43 -08:00
Button ( buttonText ) {
2023-02-01 09:19:45 -08:00
let connectedNode = getNodeInfo ( id : bleManager . connectedPeripheral . num , context : context )
2023-02-06 18:45:03 -08:00
if connectedNode != nil {
var sc = ModuleConfig . SerialConfig ( )
sc . enabled = enabled
sc . echo = echo
sc . rxd = UInt32 ( rxd )
sc . txd = UInt32 ( txd )
sc . baud = SerialBaudRates ( rawValue : baudRate ) ! . protoEnumValue ( )
sc . timeout = UInt32 ( timeout )
2023-12-30 09:21:42 -08:00
sc . overrideConsoleSerialPort = overrideConsoleSerialPort
2023-02-06 18:45:03 -08:00
sc . mode = SerialModeTypes ( rawValue : mode ) ! . protoEnumValue ( )
2023-03-06 10:33:18 -08:00
2023-02-06 18:45:03 -08:00
let adminMessageId = bleManager . saveSerialModuleConfig ( config : sc , fromUser : connectedNode ! . user ! , toUser : node ! . user ! , adminIndex : connectedNode ? . myInfo ? . adminIndex ? ? 0 )
2023-03-06 10:33:18 -08:00
2023-02-06 18:45:03 -08:00
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-06-28 20:20:02 -07:00
}
2022-06-22 15:52:51 -07:00
}
}
2022-12-30 11:08:59 -08:00
message : {
Text ( " config.save.confirm " )
}
2022-12-12 22:33:06 -08:00
. navigationTitle ( " serial.config " )
2022-06-22 15:52:51 -07:00
. navigationBarItems ( trailing :
ZStack {
2023-09-02 17:37:35 -07:00
ConnectedDevice ( bluetoothOn : bleManager . isSwitchedOn , deviceConnected : bleManager . connectedPeripheral != nil , name : ( bleManager . connectedPeripheral != nil ) ? bleManager . connectedPeripheral . shortName : " ? " )
2022-06-22 15:52:51 -07:00
} )
. onAppear {
2023-03-06 10:33:18 -08:00
2022-10-19 14:11:36 -07:00
self . bleManager . context = context
2023-03-19 18:37:23 -07:00
setSerialValues ( )
2023-02-01 09:19:45 -08:00
// N e e d t o r e q u e s t a S e r i a l 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 bleManager . connectedPeripheral != nil && node ? . serialConfig = = nil {
print ( " empty serial 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 . requestSerialModuleConfig ( fromUser : connectedNode ! . user ! , toUser : node ! . user ! , adminIndex : connectedNode ? . myInfo ? . adminIndex ? ? 0 )
2023-02-01 09:19:45 -08:00
}
}
2022-10-19 14:11:36 -07:00
2022-07-02 11:28:25 -07:00
}
. onChange ( of : enabled ) { newEnabled in
2023-03-06 10:33:18 -08:00
2022-07-11 16:18:16 -07:00
if node != nil && node ! . serialConfig != nil {
2023-03-06 10:33:18 -08:00
2022-07-11 16:18:16 -07:00
if newEnabled != node ! . serialConfig ! . enabled { hasChanges = true }
}
2022-07-02 11:28:25 -07:00
}
. onChange ( of : echo ) { newEcho in
2023-03-06 10:33:18 -08:00
2022-07-11 16:18:16 -07:00
if node != nil && node ! . serialConfig != nil {
2023-03-06 10:33:18 -08:00
2022-07-11 16:18:16 -07:00
if newEcho != node ! . serialConfig ! . echo { hasChanges = true }
}
2022-07-02 11:28:25 -07:00
}
. onChange ( of : rxd ) { newRxd in
2023-03-06 10:33:18 -08:00
2022-07-11 16:18:16 -07:00
if node != nil && node ! . serialConfig != nil {
2023-03-06 10:33:18 -08:00
2022-07-11 16:18:16 -07:00
if newRxd != node ! . serialConfig ! . rxd { hasChanges = true }
}
2022-07-02 11:28:25 -07:00
}
. onChange ( of : txd ) { newTxd in
2023-03-06 10:33:18 -08:00
2022-07-11 16:18:16 -07:00
if node != nil && node ! . serialConfig != nil {
if newTxd != node ! . serialConfig ! . txd { hasChanges = true }
}
2022-07-02 11:28:25 -07:00
}
. onChange ( of : baudRate ) { newBaud in
2023-03-06 10:33:18 -08:00
2022-07-11 16:18:16 -07:00
if node != nil && node ! . serialConfig != nil {
2023-03-06 10:33:18 -08:00
2022-07-11 16:18:16 -07:00
if newBaud != node ! . serialConfig ! . baudRate { hasChanges = true }
}
2022-07-02 11:28:25 -07:00
}
. onChange ( of : timeout ) { newTimeout in
2023-03-06 10:33:18 -08:00
2022-07-11 16:18:16 -07:00
if node != nil && node ! . serialConfig != nil {
2023-03-06 10:33:18 -08:00
2022-07-11 16:18:16 -07:00
if newTimeout != node ! . serialConfig ! . timeout { hasChanges = true }
}
2022-07-02 11:28:25 -07:00
}
2023-12-30 09:21:42 -08:00
. onChange ( of : overrideConsoleSerialPort ) { newOverrideConsoleSerialPort in
if node != nil && node ! . serialConfig != nil {
if newOverrideConsoleSerialPort != node ! . serialConfig ! . overrideConsoleSerialPort { hasChanges = true }
}
}
2022-07-02 11:28:25 -07:00
. onChange ( of : mode ) { newMode in
2023-03-06 10:33:18 -08:00
2022-07-11 16:18:16 -07:00
if node != nil && node ! . serialConfig != nil {
2023-03-06 10:33:18 -08:00
2022-07-11 16:18:16 -07:00
if newMode != node ! . serialConfig ! . mode { hasChanges = true }
}
2022-06-22 15:52:51 -07:00
}
}
}
2023-03-19 18:37:23 -07:00
func setSerialValues ( ) {
self . enabled = node ? . serialConfig ? . enabled ? ? false
self . echo = node ? . serialConfig ? . echo ? ? false
self . rxd = Int ( node ? . serialConfig ? . rxd ? ? 0 )
self . txd = Int ( node ? . serialConfig ? . txd ? ? 0 )
self . baudRate = Int ( node ? . serialConfig ? . baudRate ? ? 0 )
self . timeout = Int ( node ? . serialConfig ? . timeout ? ? 0 )
self . mode = Int ( node ? . serialConfig ? . mode ? ? 0 )
2023-12-30 09:21:42 -08:00
self . overrideConsoleSerialPort = false // n o d e ? . s e r i a l C o n f i g ? . o v e r r i d e C o n s o l e S e r i a l P o r t ? ? f a l s e
2023-03-19 18:37:23 -07:00
self . hasChanges = false
}
2022-06-22 15:52:51 -07:00
}