2022-06-12 07:38:08 -07:00
//
// P o s i t i o n 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 / 1 1 / 2 2 .
//
import SwiftUI
2024-06-03 02:17:55 -07:00
import OSLog
2022-06-12 07:38:08 -07:00
2023-03-06 10:33:18 -08:00
struct PositionFlags : OptionSet {
2022-09-01 11:54:39 -07:00
let rawValue : Int
2023-03-06 10:33:18 -08:00
2022-09-23 21:41:07 -07:00
static let Altitude = PositionFlags ( rawValue : 1 )
static let AltitudeMsl = PositionFlags ( rawValue : 2 )
2022-09-30 17:10:03 -07:00
static let GeoidalSeparation = PositionFlags ( rawValue : 4 )
2022-09-23 21:41:07 -07:00
static let Dop = PositionFlags ( rawValue : 8 )
static let Hvdop = PositionFlags ( rawValue : 16 )
static let Satsinview = PositionFlags ( rawValue : 32 )
2022-10-04 18:10:40 -07:00
static let SeqNo = PositionFlags ( rawValue : 64 )
2022-09-23 21:41:07 -07:00
static let Timestamp = PositionFlags ( rawValue : 128 )
static let Speed = PositionFlags ( rawValue : 256 )
static let Heading = PositionFlags ( rawValue : 512 )
2022-09-01 11:54:39 -07:00
}
2022-06-12 07:38:08 -07:00
struct PositionConfig : View {
2023-03-06 10:33:18 -08:00
2022-06-12 07:38:08 -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-21 10:15:47 -07:00
@ State var hasChanges = false
2022-10-04 18:10:40 -07:00
@ State var hasFlagChanges = false
2023-03-06 10:33:18 -08:00
2022-06-12 10:28:26 -07:00
@ State var smartPositionEnabled = true
@ State var deviceGpsEnabled = true
2024-02-05 21:46:16 -08:00
@ State var gpsMode = 0
2023-03-27 10:43:01 -07:00
@ State var rxGpio = 0
@ State var txGpio = 0
2023-12-21 11:31:40 -08:00
@ State var gpsEnGpio = 0
2022-06-12 10:28:26 -07:00
@ State var fixedPosition = false
2024-02-05 21:46:16 -08:00
@ State var gpsUpdateInterval = 0
2022-06-12 22:07:58 -07:00
@ State var positionBroadcastSeconds = 0
2023-03-27 10:43:01 -07:00
@ State var broadcastSmartMinimumDistance = 0
@ State var broadcastSmartMinimumIntervalSecs = 0
2024-02-05 21:46:16 -08:00
@ State var positionFlags = 811
2023-03-06 10:33:18 -08:00
2022-07-13 08:32:34 -07:00
// / P o s i t i o n F l a g s
// / A l t i t u d e v a l u e - 1
2022-09-23 21:41:07 -07:00
@ State var includeAltitude = false
2022-07-13 08:32:34 -07:00
// / A l t i t u d e v a l u e i s M S L - 2
2022-09-23 21:41:07 -07:00
@ State var includeAltitudeMsl = false
2022-07-13 08:32:34 -07:00
// / I n c l u d e g e o i d a l s e p a r a t i o n - 4
2022-09-30 17:10:03 -07:00
@ State var includeGeoidalSeparation = false
2022-07-13 08:32:34 -07:00
// / I n c l u d e t h e D O P v a l u e ; P D O P u s e d b y d e f a u l t , s e e b e l o w - 8
2022-09-23 21:41:07 -07:00
@ State var includeDop = false
2022-07-13 08:32:34 -07:00
// / I f P O S _ D O P s e t , s e n d s e p a r a t e H D O P / V D O P v a l u e s i n s t e a d o f P D O P - 1 6
2022-09-23 21:41:07 -07:00
@ State var includeHvdop = false
2022-07-13 08:32:34 -07:00
// / I n c l u d e n u m b e r o f " s a t e l l i t e s i n v i e w " - 3 2
2022-09-23 21:41:07 -07:00
@ State var includeSatsinview = false
2022-07-13 08:32:34 -07:00
// / I n c l u d e a s e q u e n c e n u m b e r i n c r e m e n t e d p e r p a c k e t - 6 4
2022-09-30 17:10:03 -07:00
@ State var includeSeqNo = false
2022-07-13 08:32:34 -07:00
// / I n c l u d e p o s i t i o n a l t i m e s t a m p ( f r o m G P S s o l u t i o n ) - 1 2 8
2022-09-23 21:41:07 -07:00
@ State var includeTimestamp = false
2022-07-13 08:32:34 -07:00
// / I n c l u d e p o s i t i o n a l h e a d i n g - 2 5 6
// / I n t e n d e d f o r u s e w i t h v e h i c l e n o t w a l k i n g s p e e d s
// / w a l k i n g s p e e d s a r e l i k e l y t o b e e r r o r p r o n e l i k e t h e c o m p a s s
2022-09-23 21:41:07 -07:00
@ State var includeSpeed = false
2022-07-13 08:32:34 -07:00
// / I n c l u d e p o s i t i o n a l s p e e d - 5 1 2
// / I n t e n d e d f o r u s e w i t h v e h i c l e n o t w a l k i n g s p e e d s
// / w a l k i n g s p e e d s a r e l i k e l y t o b e e r r o r p r o n e l i k e t h e c o m p a s s
2022-09-23 21:41:07 -07:00
@ State var includeHeading = false
2023-03-06 10:33:18 -08:00
2024-03-25 15:21:38 -07:00
// / M i n i m u m V e r s i o n f o r f i x e d p o s t i o n a d m i n m e s s a g e s
2024-03-27 16:06:24 -07:00
@ State var minimumVersion = " 2.3.3 "
2024-03-25 15:21:38 -07:00
@ State private var supportedVersion = true
2024-03-26 23:36:11 -07:00
@ State private var showingSetFixedAlert = false
2024-05-29 16:40:07 -05:00
// @ S t a t e p r i v a t e v a r s h o w i n g R e m o v e F i x e d A l e r t = f a l s e
2022-06-12 07:38:08 -07:00
var body : some View {
VStack {
Form {
2024-02-17 22:39:22 -07:00
ConfigHeader ( title : " Position " , config : \ . positionConfig , node : node , onAppear : setPositionValues )
2023-03-06 10:33:18 -08:00
2022-06-13 20:43:51 -07:00
Section ( header : Text ( " Position Packet " ) ) {
2023-03-06 10:33:18 -08:00
2024-02-21 20:41:27 -08:00
VStack ( alignment : . leading ) {
Picker ( " Broadcast Interval " , selection : $ positionBroadcastSeconds ) {
ForEach ( UpdateIntervals . allCases ) { at in
2024-02-25 00:36:03 -08:00
if at . rawValue >= 300 {
2024-02-21 20:41:27 -08:00
Text ( at . description )
}
2024-02-12 22:09:22 -08:00
}
2022-06-12 10:28:26 -07:00
}
2024-02-21 20:41:27 -08:00
. pickerStyle ( DefaultPickerStyle ( ) )
Text ( " The maximum interval that can elapse without a node broadcasting a position " )
. foregroundColor ( . gray )
2024-02-21 23:35:28 -08:00
. font ( . callout )
2022-06-12 10:28:26 -07:00
}
2024-05-29 16:40:07 -05:00
2023-03-27 10:43:01 -07:00
Toggle ( isOn : $ smartPositionEnabled ) {
2024-02-21 20:41:27 -08:00
Label ( " Smart Position " , systemImage : " brain " )
2023-03-27 10:43:01 -07:00
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2024-05-29 16:40:07 -05:00
2023-03-27 10:43:01 -07:00
if smartPositionEnabled {
2024-02-21 20:41:27 -08:00
VStack ( alignment : . leading ) {
Picker ( " Minimum Interval " , selection : $ broadcastSmartMinimumIntervalSecs ) {
ForEach ( UpdateIntervals . allCases ) { at in
Text ( at . description )
}
2023-03-27 10:43:01 -07:00
}
2024-02-21 20:41:27 -08:00
. pickerStyle ( DefaultPickerStyle ( ) )
Text ( " The fastest that position updates will be sent if the minimum distance has been satisfied " )
. foregroundColor ( . gray )
2024-02-21 23:35:28 -08:00
. font ( . callout )
2023-03-27 10:43:01 -07:00
}
2024-02-21 20:41:27 -08:00
VStack ( alignment : . leading ) {
Picker ( " Minimum Distance " , selection : $ broadcastSmartMinimumDistance ) {
ForEach ( 10. . < 151 ) {
if $0 = = 0 {
Text ( " unset " )
} else {
if $0 . isMultiple ( of : 5 ) {
Text ( " \( $0 ) " )
. tag ( $0 )
}
2023-03-27 10:43:01 -07:00
}
}
}
2024-02-21 20:41:27 -08:00
. pickerStyle ( DefaultPickerStyle ( ) )
Text ( " The minimum distance change in meters to be considered for a smart position broadcast. " )
. foregroundColor ( . gray )
2024-02-21 23:35:28 -08:00
. font ( . callout )
2023-03-27 10:43:01 -07:00
}
}
2022-06-12 10:28:26 -07:00
}
2024-02-05 21:46:16 -08:00
Section ( header : Text ( " Device GPS " ) ) {
Picker ( " " , selection : $ gpsMode ) {
ForEach ( GpsMode . allCases , id : \ . self ) { at in
Text ( at . description )
. tag ( at . id )
}
}
. pickerStyle ( SegmentedPickerStyle ( ) )
. padding ( . top , 5 )
. padding ( . bottom , 5 )
if gpsMode = = 1 {
2024-05-29 16:40:07 -05:00
2024-05-04 16:03:38 -07:00
Text ( " Positions will be provided by your device GPS, if you select disabled or not present you can set a fixed position. " )
. foregroundColor ( . gray )
. font ( . callout )
2024-02-21 20:41:27 -08:00
VStack ( alignment : . leading ) {
Picker ( " Update Interval " , selection : $ gpsUpdateInterval ) {
ForEach ( GpsUpdateIntervals . allCases ) { ui in
Text ( ui . description )
}
2024-02-05 21:46:16 -08:00
}
2024-02-21 20:41:27 -08:00
Text ( " How often should we try to get a GPS position. " )
. foregroundColor ( . gray )
2024-02-21 23:35:28 -08:00
. font ( . callout )
2024-02-05 21:46:16 -08:00
}
2024-03-27 16:06:24 -07:00
}
2024-05-11 10:50:58 -07:00
if gpsMode != 1 && node ? . num ? ? 0 = = bleManager . connectedPeripheral ? . num ? ? - 1 {
2024-04-11 19:30:05 -07:00
VStack ( alignment : . leading ) {
Toggle ( isOn : $ fixedPosition ) {
Label ( " Fixed Position " , systemImage : " location.square.fill " )
2024-05-04 16:03:38 -07:00
if ! ( node ? . positionConfig ? . fixedPosition ? ? false ) {
Text ( " Your current location will be set as the fixed position and broadcast over the mesh on the position interval. " )
} else {
2024-05-29 16:40:07 -05:00
2024-05-04 16:03:38 -07:00
}
2024-04-11 19:30:05 -07:00
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2024-03-26 23:36:11 -07:00
}
2024-02-05 21:46:16 -08:00
}
}
2022-09-01 11:54:39 -07:00
Section ( header : Text ( " Position Flags " ) ) {
2023-03-06 10:33:18 -08:00
2022-06-14 16:45:43 -07:00
Text ( " Optional fields to include when assembling position messages. the more fields are included, the larger the message will be - leading to longer airtime and a higher risk of packet loss " )
2024-02-21 20:41:27 -08:00
. foregroundColor ( . gray )
2024-02-21 23:35:28 -08:00
. font ( . callout )
2023-03-06 10:33:18 -08:00
2022-09-23 21:41:07 -07:00
Toggle ( isOn : $ includeAltitude ) {
2022-06-20 12:51:55 -07:00
Label ( " Altitude " , systemImage : " arrow.up " )
}
2022-06-21 01:12:08 -07:00
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2023-03-06 10:33:18 -08:00
2022-09-23 21:41:07 -07:00
Toggle ( isOn : $ includeSatsinview ) {
2022-06-20 12:51:55 -07:00
Label ( " Number of satellites " , systemImage : " skew " )
}
2022-06-21 01:12:08 -07:00
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2023-03-06 10:33:18 -08:00
Toggle ( isOn : $ includeSeqNo ) { // 6 4
2022-06-20 12:51:55 -07:00
Label ( " Sequence number " , systemImage : " number " )
2022-06-14 16:45:43 -07:00
}
2022-06-21 01:12:08 -07:00
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2023-03-06 10:33:18 -08:00
Toggle ( isOn : $ includeTimestamp ) { // 1 2 8
2022-12-31 02:23:21 -08:00
Label ( " timestamp " , systemImage : " clock " )
2022-06-14 16:45:43 -07:00
}
2022-06-21 01:12:08 -07:00
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2023-03-06 10:33:18 -08:00
Toggle ( isOn : $ includeHeading ) { // 1 2 8
2022-06-20 12:51:55 -07:00
Label ( " Vehicle heading " , systemImage : " location.circle " )
2022-06-14 16:45:43 -07:00
}
2022-06-21 01:12:08 -07:00
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2023-03-06 10:33:18 -08:00
Toggle ( isOn : $ includeSpeed ) { // 1 2 8
2022-06-14 16:45:43 -07:00
2022-06-20 12:51:55 -07:00
Label ( " Vehicle speed " , systemImage : " speedometer " )
2022-06-14 16:45:43 -07:00
}
2022-06-21 01:12:08 -07:00
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2022-07-13 08:32:34 -07:00
}
2022-09-01 11:54:39 -07:00
Section ( header : Text ( " Advanced Position Flags " ) ) {
2024-05-29 16:40:07 -05:00
2024-01-18 10:14:51 -08:00
if includeAltitude {
Toggle ( isOn : $ includeAltitudeMsl ) {
Label ( " Altitude is Mean Sea Level " , systemImage : " arrow.up.to.line.compact " )
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
Toggle ( isOn : $ includeGeoidalSeparation ) {
Label ( " Altitude Geoidal Separation " , systemImage : " globe.americas " )
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
}
2023-03-06 10:33:18 -08:00
2022-09-23 21:41:07 -07:00
Toggle ( isOn : $ includeDop ) {
2022-07-13 08:32:34 -07:00
Text ( " Dilution of precision (DOP) PDOP used by default " )
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2023-03-06 10:33:18 -08:00
2022-10-06 08:56:15 -07:00
if includeDop {
Toggle ( isOn : $ includeHvdop ) {
Text ( " If DOP is set use, HDOP / VDOP values instead of PDOP " )
}
. toggleStyle ( SwitchToggleStyle ( tint : . accentColor ) )
2022-07-13 08:32:34 -07:00
}
2022-06-12 07:38:08 -07:00
}
2024-05-29 16:40:07 -05:00
2024-02-05 21:46:16 -08:00
if gpsMode = = 1 {
Section ( header : Text ( " Advanced Device GPS " ) ) {
2023-03-27 17:41:34 -07:00
Picker ( " GPS Receive GPIO " , selection : $ rxGpio ) {
2024-01-22 13:21:17 -08:00
ForEach ( 0. . < 49 ) {
2023-03-27 17:41:34 -07:00
if $0 = = 0 {
Text ( " unset " )
} else {
Text ( " Pin \( $0 ) " )
}
}
}
. pickerStyle ( DefaultPickerStyle ( ) )
Picker ( " GPS Transmit GPIO " , selection : $ txGpio ) {
2024-01-22 13:21:17 -08:00
ForEach ( 0. . < 49 ) {
2023-03-27 17:41:34 -07:00
if $0 = = 0 {
Text ( " unset " )
} else {
Text ( " Pin \( $0 ) " )
}
}
}
. pickerStyle ( DefaultPickerStyle ( ) )
2023-12-21 11:31:40 -08:00
Picker ( " GPS EN GPIO " , selection : $ gpsEnGpio ) {
2024-01-22 13:21:17 -08:00
ForEach ( 0. . < 49 ) {
2023-12-21 11:31:40 -08:00
if $0 = = 0 {
Text ( " unset " )
} else {
Text ( " Pin \( $0 ) " )
}
}
}
. pickerStyle ( DefaultPickerStyle ( ) )
Text ( " (Re)define PIN_GPS_EN for your board. " )
. font ( . caption )
2023-03-27 17:41:34 -07:00
}
}
2022-06-12 07:38:08 -07:00
}
2023-01-31 22:59:43 -08:00
. disabled ( self . bleManager . connectedPeripheral = = nil || node ? . positionConfig = = nil )
2024-03-27 16:06:24 -07:00
. alert ( node ? . positionConfig ? . fixedPosition ? ? false ? " Remove Fixed Position " : " Set Fixed Position " , isPresented : $ showingSetFixedAlert ) {
Button ( " Cancel " , role : . cancel ) {
fixedPosition = ! fixedPosition
}
if node ? . positionConfig ? . fixedPosition ? ? false {
Button ( " Remove " , role : . destructive ) {
if ! bleManager . removeFixedPosition ( fromUser : node ! . user ! , channel : 0 ) {
2024-06-03 02:17:55 -07:00
Logger . mesh . error ( " Remove Fixed Position Failed " )
2024-03-27 16:06:24 -07:00
}
2024-05-04 14:27:31 -07:00
let mutablePositions = node ? . positions ? . mutableCopy ( ) as ? NSMutableOrderedSet
mutablePositions ? . removeAllObjects ( )
node ? . positions = mutablePositions
2024-03-27 16:06:24 -07:00
node ? . positionConfig ? . fixedPosition = false
do {
try context . save ( )
2024-06-03 02:17:55 -07:00
Logger . data . info ( " 💾 Updated Position Config with Fixed Position = false " )
2024-03-27 16:06:24 -07:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-06-03 02:17:55 -07:00
Logger . data . error ( " Error Saving Position Config Entity \( nsError ) " )
2024-03-27 16:06:24 -07:00
}
}
} else {
Button ( " Set " ) {
if ! bleManager . setFixedPosition ( fromUser : node ! . user ! , channel : 0 ) {
2024-06-03 02:17:55 -07:00
Logger . mesh . error ( " Set Position Failed " )
2024-03-27 16:06:24 -07:00
}
node ? . positionConfig ? . fixedPosition = true
do {
try context . save ( )
2024-06-03 02:17:55 -07:00
Logger . data . info ( " 💾 Updated Position Config with Fixed Position = true " )
2024-03-27 16:06:24 -07:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-06-03 02:17:55 -07:00
Logger . data . error ( " Error Saving Position Config Entity \( nsError ) " )
2024-03-27 16:06:24 -07:00
}
}
}
} message : {
Text ( node ? . positionConfig ? . fixedPosition ? ? false ? " This will disable fixed position and remove the currently set position. " : " This will send a current position from your phone and enable fixed position. " )
}
2023-03-06 10:33:18 -08:00
2024-02-18 00:03:34 -07:00
SaveConfigButton ( node : node , hasChanges : $ hasChanges ) {
2024-03-27 16:06:24 -07:00
if fixedPosition && ! supportedVersion {
2024-02-18 00:03:34 -07:00
_ = bleManager . sendPosition ( channel : 0 , destNum : node ? . num ? ? 0 , wantResponse : true )
}
let connectedNode = getNodeInfo ( id : bleManager . connectedPeripheral . num , context : context )
2023-03-06 10:33:18 -08:00
2024-02-18 00:03:34 -07:00
if connectedNode != nil {
var pc = Config . PositionConfig ( )
pc . positionBroadcastSmartEnabled = smartPositionEnabled
pc . gpsEnabled = gpsMode = = 1
pc . gpsMode = Config . PositionConfig . GpsMode ( rawValue : gpsMode ) ? ? Config . PositionConfig . GpsMode . notPresent
pc . fixedPosition = fixedPosition
pc . gpsUpdateInterval = UInt32 ( gpsUpdateInterval )
pc . positionBroadcastSecs = UInt32 ( positionBroadcastSeconds )
pc . broadcastSmartMinimumIntervalSecs = UInt32 ( broadcastSmartMinimumIntervalSecs )
pc . broadcastSmartMinimumDistance = UInt32 ( broadcastSmartMinimumDistance )
pc . rxGpio = UInt32 ( rxGpio )
pc . txGpio = UInt32 ( txGpio )
pc . gpsEnGpio = UInt32 ( gpsEnGpio )
var pf : PositionFlags = [ ]
if includeAltitude { pf . insert ( . Altitude ) }
if includeAltitudeMsl { pf . insert ( . AltitudeMsl ) }
if includeGeoidalSeparation { pf . insert ( . GeoidalSeparation ) }
if includeDop { pf . insert ( . Dop ) }
if includeHvdop { pf . insert ( . Hvdop ) }
if includeSatsinview { pf . insert ( . Satsinview ) }
if includeSeqNo { pf . insert ( . SeqNo ) }
if includeTimestamp { pf . insert ( . Timestamp ) }
if includeSpeed { pf . insert ( . Speed ) }
if includeHeading { pf . insert ( . Heading ) }
pc . positionFlags = UInt32 ( pf . rawValue )
let adminMessageId = bleManager . savePositionConfig ( config : pc , fromUser : connectedNode ! . user ! , toUser : node ! . user ! , adminIndex : connectedNode ? . myInfo ? . adminIndex ? ? 0 )
if adminMessageId > 0 {
// 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-21 13:10:30 -07:00
}
}
}
2022-06-12 07:38:08 -07:00
}
2022-12-13 07:49:46 -08:00
. navigationTitle ( " position.config " )
2022-06-12 07:38:08 -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-12 07:38:08 -07:00
} )
. onAppear {
2024-01-14 11:25:00 -08:00
if self . bleManager . context = = nil {
self . bleManager . context = context
}
2023-03-19 18:37:23 -07:00
setPositionValues ( )
2024-03-25 15:21:38 -07:00
supportedVersion = bleManager . connectedVersion = = " 0.0.0 " || self . minimumVersion . compare ( bleManager . connectedVersion , options : . numeric ) = = . orderedAscending || minimumVersion . compare ( bleManager . connectedVersion , options : . numeric ) = = . orderedSame
2023-01-31 22:08:03 -08:00
// N e e d t o r e q u e s t a P o s i t i o n 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 ? . positionConfig = = nil {
2024-06-03 02:17:55 -07:00
Logger . mesh . info ( " empty position config " )
2023-01-31 22:08:03 -08:00
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 . requestPositionConfig ( fromUser : connectedNode ! . user ! , toUser : node ! . user ! , adminIndex : connectedNode ? . myInfo ? . adminIndex ? ? 0 )
2023-01-31 22:08:03 -08:00
}
}
2022-06-21 13:10:30 -07:00
}
2024-03-27 16:06:24 -07:00
. onChange ( of : fixedPosition ) { newFixed in
if supportedVersion {
if node != nil && node ! . positionConfig != nil {
// / F i x e d P o s i t i o n i s o f f t o s t a r t
if ! node ! . positionConfig ! . fixedPosition && newFixed {
showingSetFixedAlert = true
} else if node ! . positionConfig ! . fixedPosition && ! newFixed {
// / F i x e d P o s i t i o n i s o n t o s t a r t
showingSetFixedAlert = true
}
}
}
}
2022-09-23 21:41:07 -07:00
. onChange ( of : deviceGpsEnabled ) { newDeviceGps in
2022-07-11 16:18:16 -07:00
if node != nil && node ! . positionConfig != nil {
2022-09-23 21:41:07 -07:00
if newDeviceGps != node ! . positionConfig ! . deviceGpsEnabled { hasChanges = true }
2022-07-11 16:18:16 -07:00
}
2022-06-21 13:10:30 -07:00
}
2024-02-05 21:46:16 -08:00
. onChange ( of : gpsMode ) { newGpsMode in
if node != nil && node ! . positionConfig != nil {
if newGpsMode != node ! . positionConfig ! . gpsMode { hasChanges = true }
}
}
2023-03-27 10:43:01 -07:00
. onChange ( of : rxGpio ) { newRxGpio in
if node != nil && node ! . positionConfig != nil {
if newRxGpio != node ! . positionConfig ! . rxGpio { hasChanges = true }
}
}
. onChange ( of : txGpio ) { newTxGpio in
if node != nil && node ! . positionConfig != nil {
if newTxGpio != node ! . positionConfig ! . txGpio { hasChanges = true }
}
}
2023-12-21 11:31:40 -08:00
. onChange ( of : txGpio ) { newGpsEnGpio in
if node != nil && node ! . positionConfig != nil {
if newGpsEnGpio != node ! . positionConfig ! . gpsEnGpio { hasChanges = true }
}
}
2022-09-24 11:28:36 -07:00
. onChange ( of : smartPositionEnabled ) { newSmartPositionEnabled in
if node != nil && node ! . positionConfig != nil {
if newSmartPositionEnabled != node ! . positionConfig ! . smartPositionEnabled { hasChanges = true }
}
}
2022-09-23 21:41:07 -07:00
. onChange ( of : positionBroadcastSeconds ) { newPositionBroadcastSeconds in
if node != nil && node ! . positionConfig != nil {
if newPositionBroadcastSeconds != node ! . positionConfig ! . positionBroadcastSeconds { hasChanges = true }
}
}
2023-03-27 10:43:01 -07:00
. onChange ( of : broadcastSmartMinimumIntervalSecs ) { newBroadcastSmartMinimumIntervalSecs in
if node != nil && node ! . positionConfig != nil {
if newBroadcastSmartMinimumIntervalSecs != node ! . positionConfig ! . broadcastSmartMinimumIntervalSecs { hasChanges = true }
}
}
. onChange ( of : broadcastSmartMinimumDistance ) { newBroadcastSmartMinimumDistance in
if node != nil && node ! . positionConfig != nil {
if newBroadcastSmartMinimumDistance != node ! . positionConfig ! . broadcastSmartMinimumDistance { hasChanges = true }
}
}
2024-02-05 21:46:16 -08:00
. onChange ( of : gpsUpdateInterval ) { newGpsUpdateInterval in
if node != nil && node ! . positionConfig != nil {
if newGpsUpdateInterval != node ! . positionConfig ! . gpsUpdateInterval { hasChanges = true }
}
}
2022-10-04 18:10:40 -07:00
. onChange ( of : includeAltitude ) { altFlag in
let pf = PositionFlags ( rawValue : self . positionFlags )
let existingValue = pf . contains ( . Altitude )
if existingValue != altFlag { hasChanges = true }
}
. onChange ( of : includeAltitudeMsl ) { altMslFlag in
let pf = PositionFlags ( rawValue : self . positionFlags )
let existingValue = pf . contains ( . AltitudeMsl )
if existingValue != altMslFlag { hasChanges = true }
}
. onChange ( of : includeSatsinview ) { satsFlag in
let pf = PositionFlags ( rawValue : self . positionFlags )
let existingValue = pf . contains ( . Satsinview )
if existingValue != satsFlag { hasChanges = true }
}
. onChange ( of : includeSeqNo ) { seqFlag in
let pf = PositionFlags ( rawValue : self . positionFlags )
let existingValue = pf . contains ( . SeqNo )
if existingValue != seqFlag { hasChanges = true }
}
. onChange ( of : includeTimestamp ) { timestampFlag in
let pf = PositionFlags ( rawValue : self . positionFlags )
let existingValue = pf . contains ( . Timestamp )
if existingValue != timestampFlag { hasChanges = true }
}
. onChange ( of : includeTimestamp ) { timestampFlag in
let pf = PositionFlags ( rawValue : self . positionFlags )
let existingValue = pf . contains ( . Timestamp )
if existingValue != timestampFlag { hasChanges = true }
}
. onChange ( of : includeSpeed ) { speedFlag in
let pf = PositionFlags ( rawValue : self . positionFlags )
let existingValue = pf . contains ( . Speed )
if existingValue != speedFlag { hasChanges = true }
}
. onChange ( of : includeHeading ) { headingFlag in
let pf = PositionFlags ( rawValue : self . positionFlags )
let existingValue = pf . contains ( . Heading )
if existingValue != headingFlag { hasChanges = true }
}
. onChange ( of : includeGeoidalSeparation ) { geoSepFlag in
let pf = PositionFlags ( rawValue : self . positionFlags )
let existingValue = pf . contains ( . GeoidalSeparation )
if existingValue != geoSepFlag { hasChanges = true }
}
. onChange ( of : includeDop ) { dopFlag in
let pf = PositionFlags ( rawValue : self . positionFlags )
let existingValue = pf . contains ( . Dop )
if existingValue != dopFlag { hasChanges = true }
}
. onChange ( of : includeHvdop ) { hvdopFlag in
let pf = PositionFlags ( rawValue : self . positionFlags )
let existingValue = pf . contains ( . Hvdop )
if existingValue != hvdopFlag { hasChanges = true }
2022-09-01 18:37:41 -07:00
}
2022-06-12 07:38:08 -07:00
}
2023-03-19 18:37:23 -07:00
func setPositionValues ( ) {
self . smartPositionEnabled = node ? . positionConfig ? . smartPositionEnabled ? ? true
2024-02-05 21:46:16 -08:00
self . deviceGpsEnabled = node ? . positionConfig ? . deviceGpsEnabled ? ? false
self . gpsMode = Int ( node ? . positionConfig ? . gpsMode ? ? 0 )
if node ? . positionConfig ? . deviceGpsEnabled ? ? false && gpsMode != 1 {
self . gpsMode = 1
}
2023-03-27 10:43:01 -07:00
self . rxGpio = Int ( node ? . positionConfig ? . rxGpio ? ? 0 )
self . txGpio = Int ( node ? . positionConfig ? . txGpio ? ? 0 )
2023-12-21 11:31:40 -08:00
self . gpsEnGpio = Int ( node ? . positionConfig ? . gpsEnGpio ? ? 0 )
2023-03-19 18:37:23 -07:00
self . fixedPosition = node ? . positionConfig ? . fixedPosition ? ? false
2024-02-05 21:46:16 -08:00
self . gpsUpdateInterval = Int ( node ? . positionConfig ? . gpsUpdateInterval ? ? 30 )
2023-03-19 18:37:23 -07:00
self . positionBroadcastSeconds = Int ( node ? . positionConfig ? . positionBroadcastSeconds ? ? 900 )
2023-03-27 10:43:01 -07:00
self . broadcastSmartMinimumIntervalSecs = Int ( node ? . positionConfig ? . broadcastSmartMinimumIntervalSecs ? ? 30 )
2023-03-27 17:04:24 -07:00
self . broadcastSmartMinimumDistance = Int ( node ? . positionConfig ? . broadcastSmartMinimumDistance ? ? 50 )
2023-03-19 18:37:23 -07:00
self . positionFlags = Int ( node ? . positionConfig ? . positionFlags ? ? 3 )
let pf = PositionFlags ( rawValue : self . positionFlags )
if pf . contains ( . Altitude ) { self . includeAltitude = true } else { self . includeAltitude = false }
if pf . contains ( . AltitudeMsl ) { self . includeAltitudeMsl = true } else { self . includeAltitudeMsl = false }
if pf . contains ( . GeoidalSeparation ) { self . includeGeoidalSeparation = true } else { self . includeGeoidalSeparation = false }
if pf . contains ( . Dop ) { self . includeDop = true } else { self . includeDop = false }
if pf . contains ( . Hvdop ) { self . includeHvdop = true } else { self . includeHvdop = false }
if pf . contains ( . Satsinview ) { self . includeSatsinview = true } else { self . includeSatsinview = false }
if pf . contains ( . SeqNo ) { self . includeSeqNo = true } else { self . includeSeqNo = false }
if pf . contains ( . Timestamp ) { self . includeTimestamp = true } else { self . includeTimestamp = false }
if pf . contains ( . Speed ) { self . includeSpeed = true } else { self . includeSpeed = false }
if pf . contains ( . Heading ) { self . includeHeading = true } else { self . includeHeading = false }
self . hasChanges = false
}
2022-06-12 07:38:08 -07:00
}