2022-10-03 16:52:00 -07:00
//
// U p d a t e C o r e D a t a . 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 1 0 / 3 / 2 2 .
2022-10-03 20:13:33 -07:00
2022-10-03 16:52:00 -07:00
import CoreData
2024-06-07 22:09:20 -05:00
import MeshtasticProtobufs
2024-06-03 02:17:55 -07:00
import OSLog
2022-10-03 16:52:00 -07:00
2024-02-27 11:26:26 -08:00
public func clearPax ( destNum : Int64 , context : NSManagedObjectContext ) -> Bool {
2024-06-28 08:50:49 -05:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
2024-02-27 11:26:26 -08:00
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( destNum ) )
do {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
2024-02-27 11:26:26 -08:00
let newPax = [ PaxCounterLog ] ( )
fetchedNode [ 0 ] . pax ? = NSOrderedSet ( array : newPax )
do {
try context . save ( )
return true
} catch {
context . rollback ( )
return false
}
} catch {
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [NodeInfoEntity] fetch data error " )
2024-02-27 11:26:26 -08:00
return false
}
}
2022-10-03 16:52:00 -07:00
public func clearPositions ( destNum : Int64 , context : NSManagedObjectContext ) -> Bool {
2023-03-06 10:33:18 -08:00
2024-06-28 08:50:49 -05:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
2022-10-03 16:52:00 -07:00
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( destNum ) )
2023-03-06 10:33:18 -08:00
2022-10-03 16:52:00 -07:00
do {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
2022-10-03 16:52:00 -07:00
let newPostions = [ PositionEntity ] ( )
fetchedNode [ 0 ] . positions ? = NSOrderedSet ( array : newPostions )
do {
try context . save ( )
return true
2023-03-06 10:33:18 -08:00
2022-10-03 16:52:00 -07:00
} catch {
context . rollback ( )
return false
}
} catch {
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [NodeInfoEntity] fetch data error " )
2022-10-03 16:52:00 -07:00
return false
}
2022-10-03 20:13:33 -07:00
}
public func clearTelemetry ( destNum : Int64 , metricsType : Int32 , context : NSManagedObjectContext ) -> Bool {
2023-03-06 10:33:18 -08:00
2024-06-28 08:50:49 -05:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
2022-10-03 20:13:33 -07:00
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( destNum ) )
2023-03-06 10:33:18 -08:00
2022-10-03 20:13:33 -07:00
do {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
2022-10-03 20:13:33 -07:00
let emptyTelemetry = [ TelemetryEntity ] ( )
fetchedNode [ 0 ] . telemetries ? = NSOrderedSet ( array : emptyTelemetry )
do {
try context . save ( )
return true
2023-03-06 10:33:18 -08:00
2022-10-03 20:13:33 -07:00
} catch {
context . rollback ( )
return false
}
} catch {
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [NodeInfoEntity] fetch data error " )
2022-10-03 20:13:33 -07:00
return false
}
2022-10-03 16:52:00 -07:00
}
2022-10-03 21:19:10 -07:00
2022-12-17 23:53:06 -08:00
public func deleteChannelMessages ( channel : ChannelEntity , context : NSManagedObjectContext ) {
2022-11-24 23:25:44 -08:00
do {
2023-01-25 23:01:45 -08:00
let objects = channel . allPrivateMessages
2023-02-01 09:19:45 -08:00
for object in objects {
context . delete ( object )
}
2022-11-24 23:25:44 -08:00
try context . save ( )
} catch let error as NSError {
2024-06-03 02:17:55 -07:00
Logger . data . error ( " \( error . localizedDescription ) " )
2022-11-24 23:25:44 -08:00
}
}
2022-11-25 00:22:51 -08:00
public func deleteUserMessages ( user : UserEntity , context : NSManagedObjectContext ) {
2023-03-06 10:33:18 -08:00
2022-11-25 00:22:51 -08:00
do {
2023-01-25 23:01:45 -08:00
let objects = user . messageList
2023-02-01 09:19:45 -08:00
for object in objects {
context . delete ( object )
}
2022-11-25 00:22:51 -08:00
try context . save ( )
} catch let error as NSError {
2024-06-03 02:17:55 -07:00
Logger . data . error ( " \( error . localizedDescription ) " )
2022-11-25 00:22:51 -08:00
}
}
2024-04-21 20:36:29 -07:00
public func clearCoreDataDatabase ( context : NSManagedObjectContext , includeRoutes : Bool ) {
2023-03-06 10:33:18 -08:00
2022-10-03 21:19:10 -07:00
let persistenceController = PersistenceController . shared . container
for i in 0. . . persistenceController . managedObjectModel . entities . count - 1 {
2024-05-29 16:40:07 -05:00
2022-10-03 21:19:10 -07:00
let entity = persistenceController . managedObjectModel . entities [ i ]
2022-10-06 08:56:15 -07:00
let query = NSFetchRequest < NSFetchRequestResult > ( entityName : entity . name ! )
2024-04-21 20:36:29 -07:00
var deleteRequest = NSBatchDeleteRequest ( fetchRequest : query )
let entityName = entity . name ? ? " UNK "
2024-05-29 16:40:07 -05:00
2024-04-21 20:36:29 -07:00
if includeRoutes {
deleteRequest = NSBatchDeleteRequest ( fetchRequest : query )
} else if ! includeRoutes {
if ! ( entityName . contains ( " RouteEntity " ) || entityName . contains ( " LocationEntity " ) ) {
deleteRequest = NSBatchDeleteRequest ( fetchRequest : query )
}
}
2022-11-24 23:25:44 -08:00
do {
try context . executeAndMergeChanges ( using : deleteRequest )
2024-05-31 16:42:34 -05:00
} catch {
2024-06-03 02:17:55 -07:00
Logger . data . error ( " \( error . localizedDescription ) " )
2022-11-25 00:26:13 -08:00
}
2022-10-03 21:19:10 -07:00
}
}
2023-01-20 19:14:49 -08:00
2023-03-10 19:41:26 -08:00
func upsertNodeInfoPacket ( packet : MeshPacket , context : NSManagedObjectContext ) {
2023-03-14 12:44:10 -07:00
2024-06-23 12:25:08 -07:00
let logString = String . localizedStringWithFormat ( " mesh.log.nodeinfo.received %@ " . localized , packet . from . toHex ( ) )
2023-03-10 19:41:26 -08:00
MeshLogger . log ( " 📟 \( logString ) " )
2023-03-14 12:44:10 -07:00
2023-03-10 19:41:26 -08:00
guard packet . from > 0 else { return }
2023-03-14 12:44:10 -07:00
2024-06-28 08:50:49 -05:00
let fetchNodeInfoAppRequest = NodeInfoEntity . fetchRequest ( )
2023-03-10 19:41:26 -08:00
fetchNodeInfoAppRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( packet . from ) )
2023-03-14 12:44:10 -07:00
2023-03-10 19:41:26 -08:00
do {
2023-03-14 12:44:10 -07:00
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoAppRequest )
2023-03-10 19:41:26 -08:00
if fetchedNode . count = = 0 {
// N o t F o u n d I n s e r t
let newNode = NodeInfoEntity ( context : context )
newNode . id = Int64 ( packet . from )
newNode . num = Int64 ( packet . from )
2024-07-10 00:08:17 -07:00
if packet . rxTime > 0 {
2024-07-09 20:47:26 -05:00
newNode . firstHeard = Date ( timeIntervalSince1970 : TimeInterval ( Int64 ( packet . rxTime ) ) )
newNode . lastHeard = Date ( timeIntervalSince1970 : TimeInterval ( Int64 ( packet . rxTime ) ) )
2024-08-15 13:43:31 -07:00
} else {
newNode . firstHeard = Date ( )
newNode . lastHeard = Date ( )
2024-07-09 20:47:26 -05:00
}
2023-03-10 19:41:26 -08:00
newNode . snr = packet . rxSnr
2023-05-04 22:20:22 -07:00
newNode . rssi = packet . rxRssi
2024-02-05 23:02:33 -08:00
newNode . viaMqtt = packet . viaMqtt
2024-05-29 16:40:07 -05:00
2024-07-17 00:20:35 -07:00
if packet . to = = Constants . maximumNodeNum || packet . to = = UserDefaults . preferredPeripheralNum {
2024-03-14 23:05:05 -07:00
newNode . channel = Int32 ( packet . channel )
}
2023-04-02 15:00:15 -07:00
if let nodeInfoMessage = try ? NodeInfo ( serializedData : packet . decoded . payload ) {
2024-03-23 09:01:44 -07:00
newNode . hopsAway = Int32 ( nodeInfoMessage . hopsAway )
2024-03-26 09:59:07 -07:00
newNode . favorite = nodeInfoMessage . isFavorite
2023-04-02 15:00:15 -07:00
}
2024-05-29 16:40:07 -05:00
2023-03-10 19:41:26 -08:00
if let newUserMessage = try ? User ( serializedData : packet . decoded . payload ) {
2024-05-29 16:40:07 -05:00
if newUserMessage . id . isEmpty {
2024-07-16 16:31:25 -05:00
if packet . from > Constants . minimumNodeNum {
2024-05-26 12:15:50 -07:00
let newUser = createUser ( num : Int64 ( packet . from ) , context : context )
newNode . user = newUser
}
2024-02-29 21:26:17 -08:00
} else {
2024-05-29 16:40:07 -05:00
2024-02-29 21:26:17 -08:00
let newUser = UserEntity ( context : context )
2023-03-10 19:41:26 -08:00
newUser . userId = newUserMessage . id
newUser . num = Int64 ( packet . from )
newUser . longName = newUserMessage . longName
newUser . shortName = newUserMessage . shortName
2023-12-20 10:24:01 -08:00
newUser . role = Int32 ( newUserMessage . role . rawValue )
2023-03-10 19:41:26 -08:00
newUser . hwModel = String ( describing : newUserMessage . hwModel ) . uppercased ( )
2024-08-06 14:53:32 -07:00
newUser . hwModelId = Int32 ( newUserMessage . hwModel . rawValue )
2024-08-12 10:29:15 -07:00
newUser . pkiEncrypted = packet . pkiEncrypted
newUser . publicKey = packet . publicKey
2024-08-06 14:53:32 -07:00
Task {
Api ( ) . loadDeviceHardwareData { ( hw ) in
let dh = hw . first ( where : { $0 . hwModel = = newUser . hwModelId } )
newUser . hwDisplayName = dh ? . displayName
}
}
2023-03-10 19:41:26 -08:00
newNode . user = newUser
2024-05-29 16:40:07 -05:00
if UserDefaults . newNodeNotifications {
2024-04-09 16:59:34 -07:00
let manager = LocalNotificationManager ( )
manager . notifications = [
Notification (
id : ( UUID ( ) . uuidString ) ,
title : " New Node " ,
subtitle : " \( newUser . longName ? ? " unknown " . localized ) " ,
content : " New Node has been discovered " ,
2024-05-14 22:39:07 -07:00
target : " nodes " ,
2024-07-10 21:17:14 -05:00
path : " meshtastic:///nodes?nodenum= \( newUser . num ) "
2024-04-09 16:59:34 -07:00
)
]
manager . schedule ( )
}
2024-02-29 21:26:17 -08:00
}
} else {
2024-07-16 16:31:25 -05:00
if packet . from > Constants . minimumNodeNum {
2024-05-26 12:15:50 -07:00
let newUser = createUser ( num : Int64 ( packet . from ) , context : context )
2024-09-05 13:42:46 -07:00
newNode . user ? . pkiEncrypted = packet . pkiEncrypted
newNode . user ? . publicKey = packet . publicKey
2024-06-26 15:12:24 -07:00
newNode . user = newUser
2024-05-26 12:15:50 -07:00
}
2023-03-10 19:41:26 -08:00
}
2024-05-29 16:40:07 -05:00
2024-07-16 16:31:25 -05:00
if newNode . user = = nil && packet . from > Constants . minimumNodeNum {
2024-05-26 12:15:50 -07:00
newNode . user = createUser ( num : Int64 ( packet . from ) , context : context )
2023-09-30 12:42:49 -07:00
}
2023-08-27 08:49:09 -07:00
let myInfoEntity = MyInfoEntity ( context : context )
myInfoEntity . myNodeNum = Int64 ( packet . from )
myInfoEntity . rebootCount = 0
do {
try context . save ( )
2024-06-23 18:25:22 -07:00
Logger . data . info ( " 💾 [MyInfoEntity] Saved a new myInfo for node number: \( packet . from . toHex ( ) , privacy : . public ) " )
2023-08-27 08:49:09 -07:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [MyInfoEntity] Error Inserting New Core Data: \( nsError , privacy : . public ) " )
2023-08-27 08:49:09 -07:00
}
newNode . myInfo = myInfoEntity
2024-05-29 16:40:07 -05:00
2023-03-10 19:41:26 -08:00
} else {
// U p d a t e a n e x i s t i n g n o d e
fetchedNode [ 0 ] . id = Int64 ( packet . from )
fetchedNode [ 0 ] . num = Int64 ( packet . from )
2023-12-22 06:31:27 -08:00
if packet . rxTime > 0 {
fetchedNode [ 0 ] . lastHeard = Date ( timeIntervalSince1970 : TimeInterval ( Int64 ( packet . rxTime ) ) )
2024-08-15 13:43:31 -07:00
} else {
fetchedNode [ 0 ] . lastHeard = Date ( )
2023-12-22 06:31:27 -08:00
}
2023-03-10 19:41:26 -08:00
fetchedNode [ 0 ] . snr = packet . rxSnr
2023-05-04 22:20:22 -07:00
fetchedNode [ 0 ] . rssi = packet . rxRssi
2024-02-05 23:02:33 -08:00
fetchedNode [ 0 ] . viaMqtt = packet . viaMqtt
2024-07-17 00:20:35 -07:00
if packet . to = = Constants . maximumNodeNum || packet . to = = UserDefaults . preferredPeripheralNum {
2024-03-14 23:05:05 -07:00
fetchedNode [ 0 ] . channel = Int32 ( packet . channel )
}
2023-03-14 12:44:10 -07:00
2023-03-10 19:41:26 -08:00
if let nodeInfoMessage = try ? NodeInfo ( serializedData : packet . decoded . payload ) {
2024-03-23 09:01:44 -07:00
fetchedNode [ 0 ] . hopsAway = Int32 ( nodeInfoMessage . hopsAway )
2024-03-26 09:59:07 -07:00
fetchedNode [ 0 ] . favorite = nodeInfoMessage . isFavorite
2023-03-10 19:41:26 -08:00
if nodeInfoMessage . hasDeviceMetrics {
let telemetry = TelemetryEntity ( context : context )
telemetry . batteryLevel = Int32 ( nodeInfoMessage . deviceMetrics . batteryLevel )
telemetry . voltage = nodeInfoMessage . deviceMetrics . voltage
telemetry . channelUtilization = nodeInfoMessage . deviceMetrics . channelUtilization
telemetry . airUtilTx = nodeInfoMessage . deviceMetrics . airUtilTx
var newTelemetries = [ TelemetryEntity ] ( )
newTelemetries . append ( telemetry )
fetchedNode [ 0 ] . telemetries ? = NSOrderedSet ( array : newTelemetries )
}
if nodeInfoMessage . hasUser {
2023-09-25 19:30:21 -07:00
// / S e e i n g S o m e c r a s h e s h e r e ?
2023-03-10 19:41:26 -08:00
fetchedNode [ 0 ] . user ! . userId = nodeInfoMessage . user . id
fetchedNode [ 0 ] . user ! . num = Int64 ( nodeInfoMessage . num )
fetchedNode [ 0 ] . user ! . longName = nodeInfoMessage . user . longName
fetchedNode [ 0 ] . user ! . shortName = nodeInfoMessage . user . shortName
2023-12-20 10:24:01 -08:00
fetchedNode [ 0 ] . user ! . role = Int32 ( nodeInfoMessage . user . role . rawValue )
2023-03-10 19:41:26 -08:00
fetchedNode [ 0 ] . user ! . hwModel = String ( describing : nodeInfoMessage . user . hwModel ) . uppercased ( )
2024-08-06 14:53:32 -07:00
fetchedNode [ 0 ] . user ! . hwModelId = Int32 ( nodeInfoMessage . user . hwModel . rawValue )
2024-09-05 10:39:54 -07:00
if ! packet . publicKey . isEmpty {
fetchedNode [ 0 ] . user ! . pkiEncrypted = packet . pkiEncrypted
fetchedNode [ 0 ] . user ! . publicKey = packet . publicKey
}
2024-08-06 14:53:32 -07:00
Task {
Api ( ) . loadDeviceHardwareData { ( hw ) in
2024-08-06 15:26:16 -07:00
let dh = hw . first ( where : { $0 . hwModel = = fetchedNode [ 0 ] . user ? . hwModelId ? ? 0 } )
2024-08-06 14:53:32 -07:00
fetchedNode [ 0 ] . user ! . hwDisplayName = dh ? . displayName
}
}
2023-03-10 19:41:26 -08:00
}
2024-03-23 09:01:44 -07:00
} else if packet . hopStart != 0 && packet . hopLimit <= packet . hopStart {
fetchedNode [ 0 ] . hopsAway = Int32 ( packet . hopStart - packet . hopLimit )
2023-03-10 19:41:26 -08:00
}
2024-05-29 16:40:07 -05:00
if fetchedNode [ 0 ] . user = = nil {
2024-07-06 09:02:44 -07:00
let newUser = createUser ( num : Int64 ( truncatingIfNeeded : packet . from ) , context : context )
2024-07-18 16:15:11 -07:00
fetchedNode [ 0 ] . user ? = newUser
2024-07-09 20:03:40 -05:00
2024-02-29 21:26:17 -08:00
}
2023-03-10 19:41:26 -08:00
do {
try context . save ( )
2024-06-23 18:25:22 -07:00
Logger . data . info ( " 💾 [NodeInfoEntity] Updated from Node Info App Packet For: \( fetchedNode [ 0 ] . num . toHex ( ) , privacy : . public ) " )
2023-03-10 19:41:26 -08:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [NodeInfoEntity] Error Saving from NODEINFO_APP \( nsError , privacy : . public ) " )
2023-03-10 19:41:26 -08:00
}
}
} catch {
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [NodeInfoEntity] fetch data error for NODEINFO_APP " )
2023-03-10 19:41:26 -08:00
}
}
2023-01-25 23:01:45 -08:00
func upsertPositionPacket ( packet : MeshPacket , context : NSManagedObjectContext ) {
2023-03-06 10:33:18 -08:00
2023-05-05 09:27:24 -07:00
let logString = String . localizedStringWithFormat ( " mesh.log.position.received %@ " . localized , String ( packet . from ) )
2023-01-25 23:01:45 -08:00
MeshLogger . log ( " 📍 \( logString ) " )
2023-03-06 10:33:18 -08:00
2024-06-28 08:50:49 -05:00
let fetchNodePositionRequest = NodeInfoEntity . fetchRequest ( )
2023-01-25 23:01:45 -08:00
fetchNodePositionRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( packet . from ) )
2023-03-06 10:33:18 -08:00
2023-01-25 23:01:45 -08:00
do {
2023-03-06 10:33:18 -08:00
2023-01-25 23:01:45 -08:00
if let positionMessage = try ? Position ( serializedData : packet . decoded . payload ) {
2023-03-06 10:33:18 -08:00
2023-10-03 16:47:36 -07:00
// / D o n ' t s a v e e m p t y p o s i t i o n p a c k e t s f r o m n u l l i s l a n d o r a p p l e p a r k
if ( positionMessage . longitudeI != 0 && positionMessage . latitudeI != 0 ) && ( positionMessage . latitudeI != 373346000 && positionMessage . longitudeI != - 1220090000 ) {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodePositionRequest )
2023-01-25 23:01:45 -08:00
if fetchedNode . count = = 1 {
2023-03-06 10:33:18 -08:00
2023-02-22 09:37:31 -08:00
// U n s e t t h e c u r r e n t l a t e s t p o s i t i o n f o r t h i s n o d e
2024-06-28 08:50:49 -05:00
let fetchCurrentLatestPositionsRequest = PositionEntity . fetchRequest ( )
2023-02-22 09:37:31 -08:00
fetchCurrentLatestPositionsRequest . predicate = NSPredicate ( format : " nodePosition.num == %lld && latest = true " , Int64 ( packet . from ) )
2023-03-14 12:44:10 -07:00
2024-06-28 08:50:49 -05:00
let fetchedPositions = try context . fetch ( fetchCurrentLatestPositionsRequest )
2023-02-22 09:37:31 -08:00
if fetchedPositions . count > 0 {
for position in fetchedPositions {
position . latest = false
}
}
2023-01-25 23:01:45 -08:00
let position = PositionEntity ( context : context )
2023-02-22 09:37:31 -08:00
position . latest = true
2023-01-25 23:01:45 -08:00
position . snr = packet . rxSnr
2023-05-04 22:20:22 -07:00
position . rssi = packet . rxRssi
2023-01-25 23:01:45 -08:00
position . seqNo = Int32 ( positionMessage . seqNumber )
position . latitudeI = positionMessage . latitudeI
position . longitudeI = positionMessage . longitudeI
position . altitude = positionMessage . altitude
position . satsInView = Int32 ( positionMessage . satsInView )
2024-05-14 22:39:07 -07:00
position . speed = Int32 ( positionMessage . groundSpeed )
2024-05-29 12:52:35 -07:00
let heading = Int32 ( positionMessage . groundTrack )
// T h r o w o u t b a d h a e a d i n g s f r o m t h e d e v i c e
if heading >= 0 && heading <= 360 {
position . heading = Int32 ( positionMessage . groundTrack )
}
2024-02-25 00:36:03 -08:00
position . precisionBits = Int32 ( positionMessage . precisionBits )
2023-01-25 23:01:45 -08:00
if positionMessage . timestamp != 0 {
position . time = Date ( timeIntervalSince1970 : TimeInterval ( Int64 ( positionMessage . timestamp ) ) )
} else {
position . time = Date ( timeIntervalSince1970 : TimeInterval ( Int64 ( positionMessage . time ) ) )
}
2023-03-06 15:30:10 -08:00
guard let mutablePositions = fetchedNode [ 0 ] . positions ! . mutableCopy ( ) as ? NSMutableOrderedSet else {
return
}
2023-11-26 17:50:10 -08:00
// / D o n ' t s a v e n e a r l y t h e s a m e p o s i t i o n o v e r a n d o v e r . I f t h e n e x t p o s i t i o n i s l e s s t h a n 1 0 m e t e r s f r o m t h e n e w p o s i t i o n , d e l e t e t h e p r e v i o u s p o s i t i o n a n d s a v e t h e n e w o n e .
2024-03-23 09:01:44 -07:00
if mutablePositions . count > 0 && ( position . precisionBits = = 32 || position . precisionBits = = 0 ) {
2024-05-29 16:40:07 -05:00
if let mostRecent = mutablePositions . lastObject as ? PositionEntity , mostRecent . coordinate . distance ( from : position . coordinate ) < 15.0 {
2023-11-17 23:07:11 -08:00
mutablePositions . remove ( mostRecent )
}
2024-05-04 08:20:53 -07:00
} else if mutablePositions . count > 0 {
2024-02-24 16:25:08 -08:00
// / D o n ' t s t o r e a n y h i s t o r y f o r r e d u c e d a c c u r a c y p o s i t i o n s , w e w i l l j u s t s h o w a c i r c l e
mutablePositions . removeAllObjects ( )
2023-11-17 23:07:11 -08:00
}
2023-01-25 23:01:45 -08:00
mutablePositions . add ( position )
fetchedNode [ 0 ] . id = Int64 ( packet . from )
fetchedNode [ 0 ] . num = Int64 ( packet . from )
2023-12-22 06:31:27 -08:00
if positionMessage . time > 0 {
fetchedNode [ 0 ] . lastHeard = Date ( timeIntervalSince1970 : TimeInterval ( Int64 ( positionMessage . time ) ) )
} else if packet . rxTime > 0 {
fetchedNode [ 0 ] . lastHeard = Date ( timeIntervalSince1970 : TimeInterval ( Int64 ( packet . rxTime ) ) )
2024-08-15 13:43:31 -07:00
} else {
fetchedNode [ 0 ] . lastHeard = Date ( )
2023-12-22 06:31:27 -08:00
}
2023-01-25 23:01:45 -08:00
fetchedNode [ 0 ] . snr = packet . rxSnr
2023-05-04 22:20:22 -07:00
fetchedNode [ 0 ] . rssi = packet . rxRssi
2024-02-05 23:48:23 -08:00
fetchedNode [ 0 ] . viaMqtt = packet . viaMqtt
2024-02-10 17:21:31 -08:00
fetchedNode [ 0 ] . channel = Int32 ( packet . channel )
2023-01-25 23:01:45 -08:00
fetchedNode [ 0 ] . positions = mutablePositions . copy ( ) as ? NSOrderedSet
2023-03-06 10:33:18 -08:00
2023-01-25 23:01:45 -08:00
do {
try context . save ( )
2024-06-28 19:30:12 -07:00
Logger . data . info ( " 💾 [Position] Saved from Position App Packet For: \( fetchedNode [ 0 ] . num . toHex ( ) , privacy : . public ) " )
2023-01-25 23:01:45 -08:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 Error Saving NodeInfoEntity from POSITION_APP \( nsError , privacy : . public ) " )
2023-01-25 23:01:45 -08:00
}
}
} else {
2024-08-23 20:19:24 -07:00
Logger . data . error ( " 💥 Empty POSITION_APP Packet: \( ( try ? packet . jsonString ( ) ) ? ? " JSON Decode Failure " , privacy : . public ) " )
2023-01-25 23:01:45 -08:00
}
}
} catch {
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 Error Deserializing POSITION_APP packet. " )
2023-01-25 23:01:45 -08:00
}
}
2024-08-18 08:36:30 -07:00
func upsertBluetoothConfigPacket ( config : Config . BluetoothConfig , nodeNum : Int64 , sessionPasskey : Data ? = Data ( ) , context : NSManagedObjectContext ) {
2023-03-06 10:33:18 -08:00
2023-05-05 09:27:24 -07:00
let logString = String . localizedStringWithFormat ( " mesh.log.bluetooth.config %@ " . localized , String ( nodeNum ) )
2023-01-23 17:56:04 -08:00
MeshLogger . log ( " 📶 \( logString ) " )
2023-03-06 10:33:18 -08:00
2024-06-28 08:50:49 -05:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
2023-01-23 17:56:04 -08:00
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( nodeNum ) )
2023-03-06 10:33:18 -08:00
2023-01-23 17:56:04 -08:00
do {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
2023-01-23 17:56:04 -08:00
// F o u n d a n o d e , s a v e D e v i c e C o n f i g
if ! fetchedNode . isEmpty {
if fetchedNode [ 0 ] . bluetoothConfig = = nil {
let newBluetoothConfig = BluetoothConfigEntity ( context : context )
2023-01-31 22:08:03 -08:00
newBluetoothConfig . enabled = config . enabled
newBluetoothConfig . mode = Int32 ( config . mode . rawValue )
newBluetoothConfig . fixedPin = Int32 ( config . fixedPin )
2023-01-23 17:56:04 -08:00
fetchedNode [ 0 ] . bluetoothConfig = newBluetoothConfig
} else {
2023-01-31 22:08:03 -08:00
fetchedNode [ 0 ] . bluetoothConfig ? . enabled = config . enabled
fetchedNode [ 0 ] . bluetoothConfig ? . mode = Int32 ( config . mode . rawValue )
fetchedNode [ 0 ] . bluetoothConfig ? . fixedPin = Int32 ( config . fixedPin )
2023-01-23 17:56:04 -08:00
}
2024-08-18 08:36:30 -07:00
if sessionPasskey != nil {
fetchedNode [ 0 ] . sessionPasskey = sessionPasskey
2024-08-18 08:53:59 -07:00
fetchedNode [ 0 ] . sessionExpiration = Date ( ) . addingTimeInterval ( 300 )
2024-08-18 08:36:30 -07:00
}
2023-01-23 17:56:04 -08:00
do {
try context . save ( )
2024-06-23 18:25:22 -07:00
Logger . data . info ( " 💾 [BluetoothConfigEntity] Updated for node: \( nodeNum . toHex ( ) , privacy : . public ) " )
2023-01-23 17:56:04 -08:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [BluetoothConfigEntity] Error Updating Core Data: \( nsError , privacy : . public ) " )
2023-01-23 17:56:04 -08:00
}
} else {
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [BluetoothConfigEntity] No Nodes found in local database matching node \( nodeNum . toHex ( ) , privacy : . public ) unable to save Bluetooth Config " )
2023-01-23 17:56:04 -08:00
}
} catch {
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [BluetoothConfigEntity] Fetching node for core data failed: \( nsError , privacy : . public ) " )
2023-01-23 17:56:04 -08:00
}
}
2024-08-18 08:36:30 -07:00
func upsertDeviceConfigPacket ( config : Config . DeviceConfig , nodeNum : Int64 , sessionPasskey : Data ? = Data ( ) , context : NSManagedObjectContext ) {
2023-03-06 10:33:18 -08:00
2023-05-05 09:27:24 -07:00
let logString = String . localizedStringWithFormat ( " mesh.log.device.config %@ " . localized , String ( nodeNum ) )
2023-01-23 17:56:04 -08:00
MeshLogger . log ( " 📟 \( logString ) " )
2024-06-28 08:50:49 -05:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
2023-01-23 17:56:04 -08:00
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( nodeNum ) )
2023-03-06 10:33:18 -08:00
2023-01-23 17:56:04 -08:00
do {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
2023-01-23 17:56:04 -08:00
// F o u n d a n o d e , s a v e D e v i c e C o n f i g
if ! fetchedNode . isEmpty {
if fetchedNode [ 0 ] . deviceConfig = = nil {
let newDeviceConfig = DeviceConfigEntity ( context : context )
2023-01-31 22:08:03 -08:00
newDeviceConfig . role = Int32 ( config . role . rawValue )
newDeviceConfig . serialEnabled = config . serialEnabled
newDeviceConfig . debugLogEnabled = config . debugLogEnabled
newDeviceConfig . buttonGpio = Int32 ( config . buttonGpio )
newDeviceConfig . buzzerGpio = Int32 ( config . buzzerGpio )
2023-03-05 23:01:09 -08:00
newDeviceConfig . rebroadcastMode = Int32 ( config . rebroadcastMode . rawValue )
2024-02-07 15:42:20 -08:00
newDeviceConfig . nodeInfoBroadcastSecs = Int32 ( truncating : config . nodeInfoBroadcastSecs as NSNumber )
2023-04-09 23:04:11 -07:00
newDeviceConfig . doubleTapAsButtonPress = config . doubleTapAsButtonPress
2024-04-26 18:06:23 -07:00
newDeviceConfig . ledHeartbeatEnabled = ! config . ledHeartbeatDisabled
2023-05-13 20:50:20 -07:00
newDeviceConfig . isManaged = config . isManaged
2024-04-08 11:41:54 -07:00
newDeviceConfig . tzdef = config . tzdef
2023-01-23 17:56:04 -08:00
fetchedNode [ 0 ] . deviceConfig = newDeviceConfig
} else {
2023-01-31 22:08:03 -08:00
fetchedNode [ 0 ] . deviceConfig ? . role = Int32 ( config . role . rawValue )
fetchedNode [ 0 ] . deviceConfig ? . serialEnabled = config . serialEnabled
fetchedNode [ 0 ] . deviceConfig ? . debugLogEnabled = config . debugLogEnabled
fetchedNode [ 0 ] . deviceConfig ? . buttonGpio = Int32 ( config . buttonGpio )
fetchedNode [ 0 ] . deviceConfig ? . buzzerGpio = Int32 ( config . buzzerGpio )
2023-03-05 23:01:09 -08:00
fetchedNode [ 0 ] . deviceConfig ? . rebroadcastMode = Int32 ( config . rebroadcastMode . rawValue )
2024-02-07 15:42:20 -08:00
fetchedNode [ 0 ] . deviceConfig ? . nodeInfoBroadcastSecs = Int32 ( truncating : config . nodeInfoBroadcastSecs as NSNumber )
2023-05-13 20:50:20 -07:00
fetchedNode [ 0 ] . deviceConfig ? . doubleTapAsButtonPress = config . doubleTapAsButtonPress
2024-04-26 18:06:23 -07:00
fetchedNode [ 0 ] . deviceConfig ? . ledHeartbeatEnabled = ! config . ledHeartbeatDisabled
2023-05-13 20:50:20 -07:00
fetchedNode [ 0 ] . deviceConfig ? . isManaged = config . isManaged
2024-04-08 11:41:54 -07:00
fetchedNode [ 0 ] . deviceConfig ? . tzdef = config . tzdef
2023-01-23 17:56:04 -08:00
}
2024-08-18 08:36:30 -07:00
if sessionPasskey != nil {
fetchedNode [ 0 ] . sessionPasskey = sessionPasskey
2024-08-18 08:53:59 -07:00
fetchedNode [ 0 ] . sessionExpiration = Date ( ) . addingTimeInterval ( 300 )
2024-08-18 08:36:30 -07:00
}
2023-01-23 17:56:04 -08:00
do {
try context . save ( )
2024-06-23 18:25:22 -07:00
Logger . data . info ( " 💾 [DeviceConfigEntity] Updated Device Config for node number: \( nodeNum . toHex ( ) , privacy : . public ) " )
2023-01-23 17:56:04 -08:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [DeviceConfigEntity] Error Updating Core Data: \( nsError , privacy : . public ) " )
2023-01-23 17:56:04 -08:00
}
}
} catch {
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [DeviceConfigEntity] Fetching node for core data failed: \( nsError , privacy : . public ) " )
2023-01-23 17:56:04 -08:00
}
}
2024-08-18 08:36:30 -07:00
func upsertDisplayConfigPacket ( config : Config . DisplayConfig , nodeNum : Int64 , sessionPasskey : Data ? = Data ( ) , context : NSManagedObjectContext ) {
2023-03-06 10:33:18 -08:00
2024-06-23 18:25:22 -07:00
let logString = String . localizedStringWithFormat ( " mesh.log.display.config %@ " . localized , nodeNum . toHex ( ) )
2023-01-23 17:56:04 -08:00
MeshLogger . log ( " 🖥️ \( logString ) " )
2023-03-06 10:33:18 -08:00
2024-06-28 08:50:49 -05:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
2023-01-23 17:56:04 -08:00
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( nodeNum ) )
2023-03-06 10:33:18 -08:00
2023-01-23 17:56:04 -08:00
do {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
2023-01-23 17:56:04 -08:00
// F o u n d a n o d e , s a v e D e v i c e C o n f i g
if ! fetchedNode . isEmpty {
2023-03-06 10:33:18 -08:00
2023-01-23 17:56:04 -08:00
if fetchedNode [ 0 ] . displayConfig = = nil {
2023-03-06 10:33:18 -08:00
2023-01-23 17:56:04 -08:00
let newDisplayConfig = DisplayConfigEntity ( context : context )
2023-01-31 22:08:03 -08:00
newDisplayConfig . gpsFormat = Int32 ( config . gpsFormat . rawValue )
2024-07-06 18:37:28 -05:00
newDisplayConfig . screenOnSeconds = Int32 ( truncatingIfNeeded : config . screenOnSecs )
newDisplayConfig . screenCarouselInterval = Int32 ( truncatingIfNeeded : config . autoScreenCarouselSecs )
2023-01-31 22:08:03 -08:00
newDisplayConfig . compassNorthTop = config . compassNorthTop
newDisplayConfig . flipScreen = config . flipScreen
newDisplayConfig . oledType = Int32 ( config . oled . rawValue )
newDisplayConfig . displayMode = Int32 ( config . displaymode . rawValue )
2023-11-26 12:54:45 -08:00
newDisplayConfig . units = Int32 ( config . units . rawValue )
2023-03-05 23:01:09 -08:00
newDisplayConfig . headingBold = config . headingBold
2023-01-23 17:56:04 -08:00
fetchedNode [ 0 ] . displayConfig = newDisplayConfig
} else {
2023-03-06 10:33:18 -08:00
2023-01-31 22:08:03 -08:00
fetchedNode [ 0 ] . displayConfig ? . gpsFormat = Int32 ( config . gpsFormat . rawValue )
2024-07-06 18:37:28 -05:00
fetchedNode [ 0 ] . displayConfig ? . screenOnSeconds = Int32 ( truncatingIfNeeded : config . screenOnSecs )
fetchedNode [ 0 ] . displayConfig ? . screenCarouselInterval = Int32 ( truncatingIfNeeded : config . autoScreenCarouselSecs )
2023-01-31 22:08:03 -08:00
fetchedNode [ 0 ] . displayConfig ? . compassNorthTop = config . compassNorthTop
fetchedNode [ 0 ] . displayConfig ? . flipScreen = config . flipScreen
fetchedNode [ 0 ] . displayConfig ? . oledType = Int32 ( config . oled . rawValue )
fetchedNode [ 0 ] . displayConfig ? . displayMode = Int32 ( config . displaymode . rawValue )
2023-11-26 12:54:45 -08:00
fetchedNode [ 0 ] . displayConfig ? . units = Int32 ( config . units . rawValue )
2023-03-05 23:01:09 -08:00
fetchedNode [ 0 ] . displayConfig ? . headingBold = config . headingBold
2023-01-23 17:56:04 -08:00
}
2024-08-18 08:36:30 -07:00
if sessionPasskey != nil {
fetchedNode [ 0 ] . sessionPasskey = sessionPasskey
2024-08-18 08:53:59 -07:00
fetchedNode [ 0 ] . sessionExpiration = Date ( ) . addingTimeInterval ( 300 )
2024-08-18 08:36:30 -07:00
}
2023-01-23 17:56:04 -08:00
do {
2023-03-06 10:33:18 -08:00
2023-01-23 17:56:04 -08:00
try context . save ( )
2024-06-23 18:25:22 -07:00
Logger . data . info ( " 💾 [DisplayConfigEntity] Updated for node: \( nodeNum . toHex ( ) , privacy : . public ) " )
2023-03-06 10:33:18 -08:00
2023-01-23 17:56:04 -08:00
} catch {
2023-03-06 10:33:18 -08:00
2023-01-23 17:56:04 -08:00
context . rollback ( )
2023-03-06 10:33:18 -08:00
2023-01-23 17:56:04 -08:00
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [DisplayConfigEntity] Error Updating Core Data: \( nsError , privacy : . public ) " )
2023-01-23 17:56:04 -08:00
}
} else {
2023-03-06 10:33:18 -08:00
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [DisplayConfigEntity] No Nodes found in local database matching node \( nodeNum . toHex ( ) ) unable to save Display Config " )
2023-01-23 17:56:04 -08:00
}
2023-03-06 10:33:18 -08:00
2023-01-23 17:56:04 -08:00
} catch {
2023-03-06 10:33:18 -08:00
2023-01-23 17:56:04 -08:00
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [DisplayConfigEntity] Fetching node for core data failed: \( nsError , privacy : . public ) " )
2023-01-23 17:56:04 -08:00
}
}
2024-08-18 08:36:30 -07:00
func upsertLoRaConfigPacket ( config : Config . LoRaConfig , nodeNum : Int64 , sessionPasskey : Data ? = Data ( ) , context : NSManagedObjectContext ) {
2023-03-06 10:33:18 -08:00
2024-06-23 18:25:22 -07:00
let logString = String . localizedStringWithFormat ( " mesh.log.lora.config %@ " . localized , nodeNum . toHex ( ) )
2023-01-20 19:14:49 -08:00
MeshLogger . log ( " 📻 \( logString ) " )
2023-03-06 10:33:18 -08:00
2024-06-28 08:50:49 -05:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
2023-01-20 19:14:49 -08:00
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , nodeNum )
do {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
2023-01-20 19:14:49 -08:00
// F o u n d a n o d e , s a v e L o R a C o n f i g
2023-01-23 17:56:04 -08:00
if fetchedNode . count > 0 {
2023-01-20 19:14:49 -08:00
if fetchedNode [ 0 ] . loRaConfig = = nil {
2023-01-23 17:56:04 -08:00
// N o l o r a c o n f i g f o r n o d e , s a v e a n e w l o r a c o n f i g
2023-01-20 19:14:49 -08:00
let newLoRaConfig = LoRaConfigEntity ( context : context )
2023-01-31 10:50:17 -08:00
newLoRaConfig . regionCode = Int32 ( config . region . rawValue )
newLoRaConfig . usePreset = config . usePreset
newLoRaConfig . modemPreset = Int32 ( config . modemPreset . rawValue )
newLoRaConfig . bandwidth = Int32 ( config . bandwidth )
newLoRaConfig . spreadFactor = Int32 ( config . spreadFactor )
newLoRaConfig . codingRate = Int32 ( config . codingRate )
newLoRaConfig . frequencyOffset = config . frequencyOffset
2023-02-06 19:06:15 -08:00
newLoRaConfig . overrideFrequency = config . overrideFrequency
newLoRaConfig . overrideDutyCycle = config . overrideDutyCycle
2023-01-31 10:50:17 -08:00
newLoRaConfig . hopLimit = Int32 ( config . hopLimit )
newLoRaConfig . txPower = Int32 ( config . txPower )
newLoRaConfig . txEnabled = config . txEnabled
newLoRaConfig . channelNum = Int32 ( config . channelNum )
2023-03-11 09:26:52 -08:00
newLoRaConfig . sx126xRxBoostedGain = config . sx126XRxBoostedGain
2024-01-26 17:42:13 -08:00
newLoRaConfig . ignoreMqtt = config . ignoreMqtt
2023-01-20 19:14:49 -08:00
fetchedNode [ 0 ] . loRaConfig = newLoRaConfig
} else {
2023-01-31 10:50:17 -08:00
fetchedNode [ 0 ] . loRaConfig ? . regionCode = Int32 ( config . region . rawValue )
fetchedNode [ 0 ] . loRaConfig ? . usePreset = config . usePreset
fetchedNode [ 0 ] . loRaConfig ? . modemPreset = Int32 ( config . modemPreset . rawValue )
fetchedNode [ 0 ] . loRaConfig ? . bandwidth = Int32 ( config . bandwidth )
fetchedNode [ 0 ] . loRaConfig ? . spreadFactor = Int32 ( config . spreadFactor )
fetchedNode [ 0 ] . loRaConfig ? . codingRate = Int32 ( config . codingRate )
fetchedNode [ 0 ] . loRaConfig ? . frequencyOffset = config . frequencyOffset
2023-02-06 19:06:15 -08:00
fetchedNode [ 0 ] . loRaConfig ? . overrideFrequency = config . overrideFrequency
fetchedNode [ 0 ] . loRaConfig ? . overrideDutyCycle = config . overrideDutyCycle
2023-01-31 10:50:17 -08:00
fetchedNode [ 0 ] . loRaConfig ? . hopLimit = Int32 ( config . hopLimit )
fetchedNode [ 0 ] . loRaConfig ? . txPower = Int32 ( config . txPower )
fetchedNode [ 0 ] . loRaConfig ? . txEnabled = config . txEnabled
fetchedNode [ 0 ] . loRaConfig ? . channelNum = Int32 ( config . channelNum )
2023-03-11 09:26:52 -08:00
fetchedNode [ 0 ] . loRaConfig ? . sx126xRxBoostedGain = config . sx126XRxBoostedGain
2024-01-26 17:42:13 -08:00
fetchedNode [ 0 ] . loRaConfig ? . ignoreMqtt = config . ignoreMqtt
fetchedNode [ 0 ] . loRaConfig ? . sx126xRxBoostedGain = config . sx126XRxBoostedGain
2023-01-20 19:14:49 -08:00
}
2024-08-18 08:36:30 -07:00
if sessionPasskey != nil {
fetchedNode [ 0 ] . sessionPasskey = sessionPasskey
2024-08-18 08:53:59 -07:00
fetchedNode [ 0 ] . sessionExpiration = Date ( ) . addingTimeInterval ( 300 )
2024-08-18 08:36:30 -07:00
}
2023-01-20 19:14:49 -08:00
do {
try context . save ( )
2024-06-23 18:25:22 -07:00
Logger . data . info ( " 💾 [LoRaConfigEntity] Updated for node: \( nodeNum . toHex ( ) , privacy : . public ) " )
2023-01-20 19:14:49 -08:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [LoRaConfigEntity] Error Updating Core Data: \( nsError , privacy : . public ) " )
2023-01-20 19:14:49 -08:00
}
} else {
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [LoRaConfigEntity] No Nodes found in local database matching node \( nodeNum . toHex ( ) , privacy : . public ) unable to save Lora Config " )
2023-01-20 19:14:49 -08:00
}
} catch {
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [LoRaConfigEntity] Fetching node for core data failed: \( nsError , privacy : . public ) " )
2023-01-20 19:14:49 -08:00
}
}
2023-01-23 17:56:04 -08:00
2024-08-18 08:36:30 -07:00
func upsertNetworkConfigPacket ( config : Config . NetworkConfig , nodeNum : Int64 , sessionPasskey : Data ? = Data ( ) , context : NSManagedObjectContext ) {
2023-03-06 10:33:18 -08:00
2023-05-05 09:27:24 -07:00
let logString = String . localizedStringWithFormat ( " mesh.log.network.config %@ " . localized , String ( nodeNum ) )
2023-01-23 17:56:04 -08:00
MeshLogger . log ( " 🌐 \( logString ) " )
2023-03-06 10:33:18 -08:00
2024-06-28 08:50:49 -05:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
2023-01-23 17:56:04 -08:00
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( nodeNum ) )
2023-03-06 10:33:18 -08:00
2023-01-23 17:56:04 -08:00
do {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
2023-01-23 17:56:04 -08:00
// F o u n d a n o d e , s a v e W i F i C o n f i g
if ! fetchedNode . isEmpty {
if fetchedNode [ 0 ] . networkConfig = = nil {
let newNetworkConfig = NetworkConfigEntity ( context : context )
2023-01-31 22:20:16 -08:00
newNetworkConfig . wifiEnabled = config . wifiEnabled
newNetworkConfig . wifiSsid = config . wifiSsid
newNetworkConfig . wifiPsk = config . wifiPsk
newNetworkConfig . ethEnabled = config . ethEnabled
2023-01-23 17:56:04 -08:00
fetchedNode [ 0 ] . networkConfig = newNetworkConfig
} else {
2023-01-31 22:20:16 -08:00
fetchedNode [ 0 ] . networkConfig ? . ethEnabled = config . ethEnabled
fetchedNode [ 0 ] . networkConfig ? . wifiEnabled = config . wifiEnabled
fetchedNode [ 0 ] . networkConfig ? . wifiSsid = config . wifiSsid
fetchedNode [ 0 ] . networkConfig ? . wifiPsk = config . wifiPsk
2023-01-23 17:56:04 -08:00
}
2024-08-18 08:36:30 -07:00
if sessionPasskey != nil {
fetchedNode [ 0 ] . sessionPasskey = sessionPasskey
2024-08-18 08:53:59 -07:00
fetchedNode [ 0 ] . sessionExpiration = Date ( ) . addingTimeInterval ( 300 )
2024-08-18 08:36:30 -07:00
}
2023-01-23 17:56:04 -08:00
do {
try context . save ( )
2024-06-23 18:25:22 -07:00
Logger . data . info ( " 💾 [NetworkConfigEntity] Updated Network Config for node: \( nodeNum . toHex ( ) , privacy : . public ) " )
2023-03-06 10:33:18 -08:00
2023-01-23 17:56:04 -08:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [NetworkConfigEntity] Error Updating Core Data: \( nsError , privacy : . public ) " )
2023-01-23 17:56:04 -08:00
}
} else {
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [NetworkConfigEntity] No Nodes found in local database matching node \( nodeNum . toHex ( ) , privacy : . public ) unable to save Network Config " )
2023-01-23 17:56:04 -08:00
}
} catch {
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [NetworkConfigEntity] Fetching node for core data failed: \( nsError , privacy : . public ) " )
2023-01-23 17:56:04 -08:00
}
}
2024-08-18 08:36:30 -07:00
func upsertPositionConfigPacket ( config : Config . PositionConfig , nodeNum : Int64 , sessionPasskey : Data ? = Data ( ) , context : NSManagedObjectContext ) {
2023-03-06 10:33:18 -08:00
2023-05-05 09:27:24 -07:00
let logString = String . localizedStringWithFormat ( " mesh.log.position.config %@ " . localized , String ( nodeNum ) )
2023-01-23 17:56:04 -08:00
MeshLogger . log ( " 🗺️ \( logString ) " )
2023-03-06 10:33:18 -08:00
2024-06-28 08:50:49 -05:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
2023-01-23 17:56:04 -08:00
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( nodeNum ) )
2023-03-06 10:33:18 -08:00
2023-01-23 17:56:04 -08:00
do {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
2023-01-23 17:56:04 -08:00
// F o u n d a n o d e , s a v e L o R a C o n f i g
if ! fetchedNode . isEmpty {
if fetchedNode [ 0 ] . positionConfig = = nil {
let newPositionConfig = PositionConfigEntity ( context : context )
2023-01-31 22:20:16 -08:00
newPositionConfig . smartPositionEnabled = config . positionBroadcastSmartEnabled
newPositionConfig . deviceGpsEnabled = config . gpsEnabled
2024-02-06 11:11:03 -08:00
newPositionConfig . gpsMode = Int32 ( config . gpsMode . rawValue )
2023-03-27 10:43:01 -07:00
newPositionConfig . rxGpio = Int32 ( config . rxGpio )
newPositionConfig . txGpio = Int32 ( config . txGpio )
2023-12-21 11:31:40 -08:00
newPositionConfig . gpsEnGpio = Int32 ( config . gpsEnGpio )
2023-01-31 22:20:16 -08:00
newPositionConfig . fixedPosition = config . fixedPosition
2023-11-15 11:25:29 -06:00
newPositionConfig . positionBroadcastSeconds = Int32 ( truncatingIfNeeded : config . positionBroadcastSecs )
2023-03-27 10:43:01 -07:00
newPositionConfig . broadcastSmartMinimumIntervalSecs = Int32 ( config . broadcastSmartMinimumIntervalSecs )
newPositionConfig . broadcastSmartMinimumDistance = Int32 ( config . broadcastSmartMinimumDistance )
2023-01-31 22:20:16 -08:00
newPositionConfig . positionFlags = Int32 ( config . positionFlags )
2023-12-22 19:08:32 -08:00
newPositionConfig . gpsAttemptTime = 900
2024-02-06 11:11:03 -08:00
newPositionConfig . gpsUpdateInterval = Int32 ( config . gpsUpdateInterval )
2023-01-23 17:56:04 -08:00
fetchedNode [ 0 ] . positionConfig = newPositionConfig
} else {
2023-01-31 22:20:16 -08:00
fetchedNode [ 0 ] . positionConfig ? . smartPositionEnabled = config . positionBroadcastSmartEnabled
fetchedNode [ 0 ] . positionConfig ? . deviceGpsEnabled = config . gpsEnabled
2024-02-06 11:11:03 -08:00
fetchedNode [ 0 ] . positionConfig ? . gpsMode = Int32 ( config . gpsMode . rawValue )
2023-03-27 10:43:01 -07:00
fetchedNode [ 0 ] . positionConfig ? . rxGpio = Int32 ( config . rxGpio )
fetchedNode [ 0 ] . positionConfig ? . txGpio = Int32 ( config . txGpio )
2023-12-21 11:31:40 -08:00
fetchedNode [ 0 ] . positionConfig ? . gpsEnGpio = Int32 ( config . gpsEnGpio )
2023-01-31 22:20:16 -08:00
fetchedNode [ 0 ] . positionConfig ? . fixedPosition = config . fixedPosition
2024-02-07 15:42:20 -08:00
fetchedNode [ 0 ] . positionConfig ? . positionBroadcastSeconds = Int32 ( truncatingIfNeeded : config . positionBroadcastSecs )
2023-03-27 10:43:01 -07:00
fetchedNode [ 0 ] . positionConfig ? . broadcastSmartMinimumIntervalSecs = Int32 ( config . broadcastSmartMinimumIntervalSecs )
fetchedNode [ 0 ] . positionConfig ? . broadcastSmartMinimumDistance = Int32 ( config . broadcastSmartMinimumDistance )
2023-12-22 19:08:32 -08:00
fetchedNode [ 0 ] . positionConfig ? . gpsAttemptTime = 900
2024-02-06 11:11:03 -08:00
fetchedNode [ 0 ] . positionConfig ? . gpsUpdateInterval = Int32 ( config . gpsUpdateInterval )
2023-01-31 22:20:16 -08:00
fetchedNode [ 0 ] . positionConfig ? . positionFlags = Int32 ( config . positionFlags )
2023-01-23 17:56:04 -08:00
}
2024-08-18 08:36:30 -07:00
if sessionPasskey != nil {
fetchedNode [ 0 ] . sessionPasskey = sessionPasskey
2024-08-18 08:53:59 -07:00
fetchedNode [ 0 ] . sessionExpiration = Date ( ) . addingTimeInterval ( 300 )
2024-08-18 08:36:30 -07:00
}
2023-01-23 17:56:04 -08:00
do {
try context . save ( )
2024-06-23 18:25:22 -07:00
Logger . data . info ( " 💾 [PositionConfigEntity] Updated for node: \( nodeNum . toHex ( ) , privacy : . public ) " )
2023-01-23 17:56:04 -08:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [PositionConfigEntity] Error Updating Core Data: \( nsError , privacy : . public ) " )
2023-01-23 17:56:04 -08:00
}
} else {
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [PositionConfigEntity] No Nodes found in local database matching node \( nodeNum . toHex ( ) , privacy : . public ) unable to save Position Config " )
2023-01-23 17:56:04 -08:00
}
} catch {
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [PositionConfigEntity] Fetching node for core data failed: \( nsError , privacy : . public ) " )
2023-01-23 17:56:04 -08:00
}
}
2023-02-01 09:19:45 -08:00
2024-08-18 08:36:30 -07:00
func upsertPowerConfigPacket ( config : Config . PowerConfig , nodeNum : Int64 , sessionPasskey : Data ? = Data ( ) , context : NSManagedObjectContext ) {
2024-02-19 21:30:19 -07:00
let logString = String . localizedStringWithFormat ( " mesh.log.power.config %@ " . localized , String ( nodeNum ) )
MeshLogger . log ( " 🗺️ \( logString ) " )
2024-06-28 08:50:49 -05:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
2024-02-19 21:30:19 -07:00
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( nodeNum ) )
do {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
2024-02-19 21:30:19 -07:00
// F o u n d a n o d e , s a v e P o w e r C o n f i g
if ! fetchedNode . isEmpty {
if fetchedNode [ 0 ] . powerConfig = = nil {
let newPowerConfig = PowerConfigEntity ( context : context )
newPowerConfig . adcMultiplierOverride = config . adcMultiplierOverride
newPowerConfig . deviceBatteryInaAddress = Int32 ( config . deviceBatteryInaAddress )
newPowerConfig . isPowerSaving = config . isPowerSaving
2024-07-06 18:37:28 -05:00
newPowerConfig . lsSecs = Int32 ( truncatingIfNeeded : config . lsSecs )
newPowerConfig . minWakeSecs = Int32 ( truncatingIfNeeded : config . minWakeSecs )
newPowerConfig . onBatteryShutdownAfterSecs = Int32 ( truncatingIfNeeded : config . onBatteryShutdownAfterSecs )
newPowerConfig . waitBluetoothSecs = Int32 ( truncatingIfNeeded : config . waitBluetoothSecs )
2024-02-19 21:30:19 -07:00
fetchedNode [ 0 ] . powerConfig = newPowerConfig
} else {
fetchedNode [ 0 ] . powerConfig ? . adcMultiplierOverride = config . adcMultiplierOverride
fetchedNode [ 0 ] . powerConfig ? . deviceBatteryInaAddress = Int32 ( config . deviceBatteryInaAddress )
fetchedNode [ 0 ] . powerConfig ? . isPowerSaving = config . isPowerSaving
2024-07-06 18:37:28 -05:00
fetchedNode [ 0 ] . powerConfig ? . lsSecs = Int32 ( truncatingIfNeeded : config . lsSecs )
fetchedNode [ 0 ] . powerConfig ? . minWakeSecs = Int32 ( truncatingIfNeeded : config . minWakeSecs )
fetchedNode [ 0 ] . powerConfig ? . onBatteryShutdownAfterSecs = Int32 ( truncatingIfNeeded : config . onBatteryShutdownAfterSecs )
fetchedNode [ 0 ] . powerConfig ? . waitBluetoothSecs = Int32 ( truncatingIfNeeded : config . waitBluetoothSecs )
2024-02-19 21:30:19 -07:00
}
2024-08-18 08:36:30 -07:00
if sessionPasskey != nil {
fetchedNode [ 0 ] . sessionPasskey = sessionPasskey
2024-08-18 08:53:59 -07:00
fetchedNode [ 0 ] . sessionExpiration = Date ( ) . addingTimeInterval ( 300 )
2024-08-18 08:36:30 -07:00
}
2024-02-19 21:30:19 -07:00
do {
try context . save ( )
2024-06-23 18:25:22 -07:00
Logger . data . info ( " 💾 [PowerConfigEntity] Updated Power Config for node: \( nodeNum . toHex ( ) , privacy : . public ) " )
2024-02-19 21:30:19 -07:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [PowerConfigEntity] Error Updating Core Data PowerConfigEntity: \( nsError , privacy : . public ) " )
2024-02-19 21:30:19 -07:00
}
} else {
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [PowerConfigEntity] No Nodes found in local database matching node \( nodeNum . toHex ( ) , privacy : . public ) unable to save Power Config " )
2024-02-19 21:30:19 -07:00
}
} catch {
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [PowerConfigEntity] Fetching node for core data failed: \( nsError , privacy : . public ) " )
2024-02-19 21:30:19 -07:00
}
}
2024-08-18 08:36:30 -07:00
func upsertSecurityConfigPacket ( config : Config . SecurityConfig , nodeNum : Int64 , sessionPasskey : Data ? = Data ( ) , context : NSManagedObjectContext ) {
2024-08-08 07:33:31 -07:00
let logString = String . localizedStringWithFormat ( " mesh.log.security.config %@ " . localized , String ( nodeNum ) )
2024-08-09 21:12:27 -07:00
MeshLogger . log ( " 🛡️ \( logString ) " )
2024-08-08 07:33:31 -07:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( nodeNum ) )
do {
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
// F o u n d a n o d e , s a v e S e c u r i t y C o n f i g
if ! fetchedNode . isEmpty {
if fetchedNode [ 0 ] . securityConfig = = nil {
let newSecurityConfig = SecurityConfigEntity ( context : context )
newSecurityConfig . publicKey = config . publicKey
newSecurityConfig . privateKey = config . privateKey
newSecurityConfig . adminKey = config . adminKey
newSecurityConfig . isManaged = config . isManaged
newSecurityConfig . serialEnabled = config . serialEnabled
2024-08-08 10:39:45 -07:00
newSecurityConfig . debugLogApiEnabled = config . debugLogApiEnabled
2024-08-08 07:33:31 -07:00
newSecurityConfig . bluetoothLoggingEnabled = config . bluetoothLoggingEnabled
2024-08-21 16:59:36 -07:00
newSecurityConfig . adminChannelEnabled = config . adminChannelEnabled
2024-08-11 00:08:43 -07:00
fetchedNode [ 0 ] . securityConfig = newSecurityConfig
2024-08-08 07:33:31 -07:00
} else {
fetchedNode [ 0 ] . securityConfig ? . publicKey = config . publicKey
fetchedNode [ 0 ] . securityConfig ? . privateKey = config . privateKey
fetchedNode [ 0 ] . securityConfig ? . adminKey = config . adminKey
fetchedNode [ 0 ] . securityConfig ? . isManaged = config . isManaged
fetchedNode [ 0 ] . securityConfig ? . serialEnabled = config . serialEnabled
2024-08-08 10:39:45 -07:00
fetchedNode [ 0 ] . securityConfig ? . debugLogApiEnabled = config . debugLogApiEnabled
2024-08-08 07:33:31 -07:00
fetchedNode [ 0 ] . securityConfig ? . bluetoothLoggingEnabled = config . bluetoothLoggingEnabled
2024-08-21 16:59:36 -07:00
fetchedNode [ 0 ] . securityConfig ? . adminChannelEnabled = config . adminChannelEnabled
2024-08-08 07:33:31 -07:00
}
2024-08-19 12:30:26 -07:00
if sessionPasskey ? . count != 0 {
2024-08-18 08:36:30 -07:00
fetchedNode [ 0 ] . sessionPasskey = sessionPasskey
2024-08-18 08:53:59 -07:00
fetchedNode [ 0 ] . sessionExpiration = Date ( ) . addingTimeInterval ( 300 )
2024-08-18 08:36:30 -07:00
}
2024-08-08 07:33:31 -07:00
do {
try context . save ( )
2024-08-09 21:12:27 -07:00
Logger . data . info ( " 💾 [SecurityConfigEntity] Updated Security Config for node: \( nodeNum . toHex ( ) , privacy : . public ) " )
2024-08-08 07:33:31 -07:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-08-09 21:12:27 -07:00
Logger . data . error ( " 💥 [SecurityConfigEntity] Error Updating Core Data: \( nsError , privacy : . public ) " )
2024-08-08 07:33:31 -07:00
}
} else {
2024-08-09 21:12:27 -07:00
Logger . data . error ( " 💥 [SecurityConfigEntity] No Nodes found in local database matching node \( nodeNum . toHex ( ) , privacy : . public ) unable to save Security Config " )
2024-08-08 07:33:31 -07:00
}
} catch {
let nsError = error as NSError
2024-08-09 21:12:27 -07:00
Logger . data . error ( " 💥 [SecurityConfigEntity] Fetching node for core data failed: \( nsError , privacy : . public ) " )
2024-08-08 07:33:31 -07:00
}
}
2024-08-18 08:36:30 -07:00
func upsertAmbientLightingModuleConfigPacket ( config : ModuleConfig . AmbientLightingConfig , nodeNum : Int64 , sessionPasskey : Data ? = Data ( ) , context : NSManagedObjectContext ) {
2023-11-28 20:03:08 -08:00
let logString = String . localizedStringWithFormat ( " mesh.log.ambientlighting.config %@ " . localized , String ( nodeNum ) )
MeshLogger . log ( " 🏮 \( logString ) " )
2024-06-28 08:50:49 -05:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
2023-11-28 20:03:08 -08:00
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( nodeNum ) )
do {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
2023-11-28 20:03:08 -08:00
// F o u n d a n o d e , s a v e A m b i e n t L i g h t i n g C o n f i g
if ! fetchedNode . isEmpty {
if fetchedNode [ 0 ] . cannedMessageConfig = = nil {
let newAmbientLightingConfig = AmbientLightingConfigEntity ( context : context )
newAmbientLightingConfig . ledState = config . ledState
newAmbientLightingConfig . current = Int32 ( config . current )
newAmbientLightingConfig . red = Int32 ( config . red )
newAmbientLightingConfig . green = Int32 ( config . green )
newAmbientLightingConfig . blue = Int32 ( config . blue )
fetchedNode [ 0 ] . ambientLightingConfig = newAmbientLightingConfig
} else {
2024-05-29 16:40:07 -05:00
2023-11-28 20:03:08 -08:00
if fetchedNode [ 0 ] . ambientLightingConfig = = nil {
fetchedNode [ 0 ] . ambientLightingConfig = AmbientLightingConfigEntity ( context : context )
}
fetchedNode [ 0 ] . ambientLightingConfig ? . ledState = config . ledState
fetchedNode [ 0 ] . ambientLightingConfig ? . current = Int32 ( config . current )
fetchedNode [ 0 ] . ambientLightingConfig ? . red = Int32 ( config . red )
fetchedNode [ 0 ] . ambientLightingConfig ? . green = Int32 ( config . green )
fetchedNode [ 0 ] . ambientLightingConfig ? . blue = Int32 ( config . blue )
}
2024-08-18 08:36:30 -07:00
if sessionPasskey != nil {
fetchedNode [ 0 ] . sessionPasskey = sessionPasskey
2024-08-18 08:53:59 -07:00
fetchedNode [ 0 ] . sessionExpiration = Date ( ) . addingTimeInterval ( 300 )
2024-08-18 08:36:30 -07:00
}
2023-11-28 20:03:08 -08:00
do {
try context . save ( )
2024-06-23 18:25:22 -07:00
Logger . data . info ( " 💾 [AmbientLightingConfigEntity] Updated for node: \( nodeNum . toHex ( ) , privacy : . public ) " )
2023-11-28 20:03:08 -08:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [AmbientLightingConfigEntity] Error Updating Core Data: \( nsError , privacy : . public ) " )
2023-11-28 20:03:08 -08:00
}
} else {
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [AmbientLightingConfigEntity] No Nodes found in local database matching node \( nodeNum . toHex ( ) , privacy : . public ) unable to save Ambient Lighting Module Config " )
2023-11-28 20:03:08 -08:00
}
} catch {
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [AmbientLightingConfigEntity] Fetching node for core data failed: \( nsError , privacy : . public ) " )
2023-11-28 20:03:08 -08:00
}
}
2024-08-18 08:36:30 -07:00
func upsertCannedMessagesModuleConfigPacket ( config : ModuleConfig . CannedMessageConfig , nodeNum : Int64 , sessionPasskey : Data ? = Data ( ) , context : NSManagedObjectContext ) {
2023-03-06 10:33:18 -08:00
2023-05-05 09:27:24 -07:00
let logString = String . localizedStringWithFormat ( " mesh.log.cannedmessage.config %@ " . localized , String ( nodeNum ) )
2023-02-01 09:19:45 -08:00
MeshLogger . log ( " 🥫 \( logString ) " )
2023-03-06 10:33:18 -08:00
2024-06-28 08:50:49 -05:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
2023-02-01 09:19:45 -08:00
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( nodeNum ) )
2023-03-06 10:33:18 -08:00
2023-02-01 09:19:45 -08:00
do {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
2023-02-01 09:19:45 -08:00
// F o u n d a n o d e , s a v e C a n n e d M e s s a g e C o n f i g
if ! fetchedNode . isEmpty {
2023-03-06 10:33:18 -08:00
2023-02-01 09:19:45 -08:00
if fetchedNode [ 0 ] . cannedMessageConfig = = nil {
let newCannedMessageConfig = CannedMessageConfigEntity ( context : context )
newCannedMessageConfig . enabled = config . enabled
newCannedMessageConfig . sendBell = config . sendBell
newCannedMessageConfig . rotary1Enabled = config . rotary1Enabled
newCannedMessageConfig . updown1Enabled = config . updown1Enabled
newCannedMessageConfig . inputbrokerPinA = Int32 ( config . inputbrokerPinA )
newCannedMessageConfig . inputbrokerPinB = Int32 ( config . inputbrokerPinB )
newCannedMessageConfig . inputbrokerPinPress = Int32 ( config . inputbrokerPinPress )
newCannedMessageConfig . inputbrokerEventCw = Int32 ( config . inputbrokerEventCw . rawValue )
newCannedMessageConfig . inputbrokerEventCcw = Int32 ( config . inputbrokerEventCcw . rawValue )
newCannedMessageConfig . inputbrokerEventPress = Int32 ( config . inputbrokerEventPress . rawValue )
fetchedNode [ 0 ] . cannedMessageConfig = newCannedMessageConfig
} else {
fetchedNode [ 0 ] . cannedMessageConfig ? . enabled = config . enabled
fetchedNode [ 0 ] . cannedMessageConfig ? . sendBell = config . sendBell
fetchedNode [ 0 ] . cannedMessageConfig ? . rotary1Enabled = config . rotary1Enabled
fetchedNode [ 0 ] . cannedMessageConfig ? . updown1Enabled = config . updown1Enabled
fetchedNode [ 0 ] . cannedMessageConfig ? . inputbrokerPinA = Int32 ( config . inputbrokerPinA )
fetchedNode [ 0 ] . cannedMessageConfig ? . inputbrokerPinB = Int32 ( config . inputbrokerPinB )
fetchedNode [ 0 ] . cannedMessageConfig ? . inputbrokerPinPress = Int32 ( config . inputbrokerPinPress )
fetchedNode [ 0 ] . cannedMessageConfig ? . inputbrokerEventCw = Int32 ( config . inputbrokerEventCw . rawValue )
fetchedNode [ 0 ] . cannedMessageConfig ? . inputbrokerEventCcw = Int32 ( config . inputbrokerEventCcw . rawValue )
fetchedNode [ 0 ] . cannedMessageConfig ? . inputbrokerEventPress = Int32 ( config . inputbrokerEventPress . rawValue )
}
2024-08-18 08:36:30 -07:00
if sessionPasskey != nil {
fetchedNode [ 0 ] . sessionPasskey = sessionPasskey
2024-08-18 08:53:59 -07:00
fetchedNode [ 0 ] . sessionExpiration = Date ( ) . addingTimeInterval ( 300 )
2024-08-18 08:36:30 -07:00
}
2023-02-01 09:19:45 -08:00
do {
try context . save ( )
2024-06-23 18:25:22 -07:00
Logger . data . info ( " 💾 [CannedMessageConfigEntity] Updated for node: \( nodeNum . toHex ( ) , privacy : . public ) " )
2023-02-01 09:19:45 -08:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [CannedMessageConfigEntity] Error Updating Core Data: \( nsError , privacy : . public ) " )
2023-02-01 09:19:45 -08:00
}
} else {
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [CannedMessageConfigEntity] No Nodes found in local database matching node \( nodeNum . toHex ( ) , privacy : . public ) unable to save Canned Message Module Config " )
2023-02-01 09:19:45 -08:00
}
} catch {
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [CannedMessageConfigEntity] Fetching node for core data failed: \( nsError , privacy : . public ) " )
2023-02-01 09:19:45 -08:00
}
}
2024-08-18 08:36:30 -07:00
func upsertDetectionSensorModuleConfigPacket ( config : ModuleConfig . DetectionSensorConfig , nodeNum : Int64 , sessionPasskey : Data ? = Data ( ) , context : NSManagedObjectContext ) {
2023-08-26 20:45:15 -07:00
let logString = String . localizedStringWithFormat ( " mesh.log.detectionsensor.config %@ " . localized , String ( nodeNum ) )
2023-08-26 21:31:50 -07:00
MeshLogger . log ( " 🕵️ \( logString ) " )
2023-08-26 20:45:15 -07:00
2024-06-28 08:50:49 -05:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
2023-08-26 20:45:15 -07:00
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( nodeNum ) )
do {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
2023-08-26 20:45:15 -07:00
// F o u n d a n o d e , s a v e D e t e c t i o n S e n s o r C o n f i g
if ! fetchedNode . isEmpty {
if fetchedNode [ 0 ] . detectionSensorConfig = = nil {
let newConfig = DetectionSensorConfigEntity ( context : context )
newConfig . enabled = config . enabled
newConfig . sendBell = config . sendBell
newConfig . name = config . name
newConfig . monitorPin = Int32 ( config . monitorPin )
newConfig . detectionTriggeredHigh = config . detectionTriggeredHigh
newConfig . usePullup = config . usePullup
2024-07-06 18:37:28 -05:00
newConfig . minimumBroadcastSecs = Int32 ( truncatingIfNeeded : config . minimumBroadcastSecs )
newConfig . stateBroadcastSecs = Int32 ( truncatingIfNeeded : config . stateBroadcastSecs )
2023-08-26 20:45:15 -07:00
fetchedNode [ 0 ] . detectionSensorConfig = newConfig
} else {
fetchedNode [ 0 ] . detectionSensorConfig ? . enabled = config . enabled
fetchedNode [ 0 ] . detectionSensorConfig ? . sendBell = config . sendBell
fetchedNode [ 0 ] . detectionSensorConfig ? . name = config . name
fetchedNode [ 0 ] . detectionSensorConfig ? . monitorPin = Int32 ( config . monitorPin )
fetchedNode [ 0 ] . detectionSensorConfig ? . usePullup = config . usePullup
fetchedNode [ 0 ] . detectionSensorConfig ? . detectionTriggeredHigh = config . detectionTriggeredHigh
2024-07-06 18:37:28 -05:00
fetchedNode [ 0 ] . detectionSensorConfig ? . minimumBroadcastSecs = Int32 ( truncatingIfNeeded : config . minimumBroadcastSecs )
fetchedNode [ 0 ] . detectionSensorConfig ? . stateBroadcastSecs = Int32 ( truncatingIfNeeded : config . stateBroadcastSecs )
2023-08-26 20:45:15 -07:00
}
2024-08-18 08:36:30 -07:00
if sessionPasskey != nil {
fetchedNode [ 0 ] . sessionPasskey = sessionPasskey
2024-08-18 08:53:59 -07:00
fetchedNode [ 0 ] . sessionExpiration = Date ( ) . addingTimeInterval ( 300 )
2024-08-18 08:36:30 -07:00
}
2023-08-26 20:45:15 -07:00
do {
try context . save ( )
2024-06-23 18:25:22 -07:00
Logger . data . info ( " 💾 [DetectionSensorConfigEntity] Updated for node: \( nodeNum . toHex ( ) , privacy : . public ) " )
2023-08-26 20:45:15 -07:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [DetectionSensorConfigEntity] Error Updating Core Data : \( nsError , privacy : . public ) " )
2023-08-26 20:45:15 -07:00
}
} else {
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [DetectionSensorConfigEntity] No Nodes found in local database matching node \( nodeNum . toHex ( ) , privacy : . public ) unable to save Detection Sensor Module Config " )
2023-08-26 20:45:15 -07:00
}
} catch {
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [DetectionSensorConfigEntity] Fetching node for core data failed: \( nsError , privacy : . public ) " )
2023-08-26 20:45:15 -07:00
}
}
2024-08-18 08:36:30 -07:00
func upsertExternalNotificationModuleConfigPacket ( config : ModuleConfig . ExternalNotificationConfig , nodeNum : Int64 , sessionPasskey : Data ? = Data ( ) , context : NSManagedObjectContext ) {
2023-03-06 10:33:18 -08:00
2023-05-05 09:27:24 -07:00
let logString = String . localizedStringWithFormat ( " mesh.log.externalnotification.config %@ " . localized , String ( nodeNum ) )
2023-02-01 09:19:45 -08:00
MeshLogger . log ( " 📣 \( logString ) " )
2023-03-06 10:33:18 -08:00
2024-06-28 08:50:49 -05:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
2023-02-01 09:19:45 -08:00
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( nodeNum ) )
2023-03-06 10:33:18 -08:00
2023-02-01 09:19:45 -08:00
do {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
2023-02-01 09:19:45 -08:00
// F o u n d a n o d e , s a v e E x t e r n a l N o t i f i c a i t o n e C o n f i g
if ! fetchedNode . isEmpty {
2023-03-06 10:33:18 -08:00
2023-02-01 09:19:45 -08:00
if fetchedNode [ 0 ] . externalNotificationConfig = = nil {
let newExternalNotificationConfig = ExternalNotificationConfigEntity ( context : context )
newExternalNotificationConfig . enabled = config . enabled
newExternalNotificationConfig . usePWM = config . usePwm
newExternalNotificationConfig . alertBell = config . alertBell
newExternalNotificationConfig . alertBellBuzzer = config . alertBellBuzzer
newExternalNotificationConfig . alertBellVibra = config . alertBellVibra
newExternalNotificationConfig . alertMessage = config . alertMessage
newExternalNotificationConfig . alertMessageBuzzer = config . alertMessageBuzzer
newExternalNotificationConfig . alertMessageVibra = config . alertMessageVibra
newExternalNotificationConfig . active = config . active
newExternalNotificationConfig . output = Int32 ( config . output )
newExternalNotificationConfig . outputBuzzer = Int32 ( config . outputBuzzer )
newExternalNotificationConfig . outputVibra = Int32 ( config . outputVibra )
newExternalNotificationConfig . outputMilliseconds = Int32 ( config . outputMs )
newExternalNotificationConfig . nagTimeout = Int32 ( config . nagTimeout )
2023-12-20 10:24:01 -08:00
newExternalNotificationConfig . useI2SAsBuzzer = config . useI2SAsBuzzer
2023-02-01 09:19:45 -08:00
fetchedNode [ 0 ] . externalNotificationConfig = newExternalNotificationConfig
} else {
fetchedNode [ 0 ] . externalNotificationConfig ? . enabled = config . enabled
fetchedNode [ 0 ] . externalNotificationConfig ? . usePWM = config . usePwm
fetchedNode [ 0 ] . externalNotificationConfig ? . alertBell = config . alertBell
fetchedNode [ 0 ] . externalNotificationConfig ? . alertBellBuzzer = config . alertBellBuzzer
fetchedNode [ 0 ] . externalNotificationConfig ? . alertBellVibra = config . alertBellVibra
fetchedNode [ 0 ] . externalNotificationConfig ? . alertMessage = config . alertMessage
fetchedNode [ 0 ] . externalNotificationConfig ? . alertMessageBuzzer = config . alertMessageBuzzer
fetchedNode [ 0 ] . externalNotificationConfig ? . alertMessageVibra = config . alertMessageVibra
fetchedNode [ 0 ] . externalNotificationConfig ? . active = config . active
fetchedNode [ 0 ] . externalNotificationConfig ? . output = Int32 ( config . output )
fetchedNode [ 0 ] . externalNotificationConfig ? . outputBuzzer = Int32 ( config . outputBuzzer )
fetchedNode [ 0 ] . externalNotificationConfig ? . outputVibra = Int32 ( config . outputVibra )
fetchedNode [ 0 ] . externalNotificationConfig ? . outputMilliseconds = Int32 ( config . outputMs )
fetchedNode [ 0 ] . externalNotificationConfig ? . nagTimeout = Int32 ( config . nagTimeout )
2023-12-20 10:24:01 -08:00
fetchedNode [ 0 ] . externalNotificationConfig ? . useI2SAsBuzzer = config . useI2SAsBuzzer
2023-02-01 09:19:45 -08:00
}
2024-08-18 08:36:30 -07:00
if sessionPasskey != nil {
fetchedNode [ 0 ] . sessionPasskey = sessionPasskey
2024-08-18 08:53:59 -07:00
fetchedNode [ 0 ] . sessionExpiration = Date ( ) . addingTimeInterval ( 300 )
2024-08-18 08:36:30 -07:00
}
2023-02-01 09:19:45 -08:00
do {
try context . save ( )
2024-06-23 18:25:22 -07:00
Logger . data . info ( " 💾 [ExternalNotificationConfigEntity] Updated for node: \( nodeNum . toHex ( ) , privacy : . public ) " )
2023-02-01 09:19:45 -08:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [ExternalNotificationConfigEntity] Error Updating Core Data : \( nsError , privacy : . public ) " )
2023-02-01 09:19:45 -08:00
}
} else {
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [ExternalNotificationConfigEntity] No Nodes found in local database matching node \( nodeNum . toHex ( ) , privacy : . public ) unable to save External Notification Module Config " )
2023-02-01 09:19:45 -08:00
}
} catch {
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [ExternalNotificationConfigEntity] Fetching node for core data failed: \( nsError , privacy : . public ) " )
2023-02-01 09:19:45 -08:00
}
}
2024-08-18 08:36:30 -07:00
func upsertPaxCounterModuleConfigPacket ( config : ModuleConfig . PaxcounterConfig , nodeNum : Int64 , sessionPasskey : Data ? = Data ( ) , context : NSManagedObjectContext ) {
2024-02-25 11:24:01 -08:00
let logString = String . localizedStringWithFormat ( " mesh.log.paxcounter.config %@ " . localized , String ( nodeNum ) )
2024-02-27 12:24:50 -08:00
MeshLogger . log ( " 🧑🤝🧑 \( logString ) " )
2024-02-25 11:24:01 -08:00
2024-06-28 08:50:49 -05:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
2024-02-25 11:24:01 -08:00
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( nodeNum ) )
do {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
2024-02-25 11:24:01 -08:00
// F o u n d a n o d e , s a v e P A X C o u n t e r C o n f i g
if ! fetchedNode . isEmpty {
if fetchedNode [ 0 ] . paxCounterConfig = = nil {
let newPaxCounterConfig = PaxCounterConfigEntity ( context : context )
newPaxCounterConfig . enabled = config . enabled
2024-06-02 09:45:56 -07:00
newPaxCounterConfig . updateInterval = Int32 ( config . paxcounterUpdateInterval )
2024-02-25 11:24:01 -08:00
fetchedNode [ 0 ] . paxCounterConfig = newPaxCounterConfig
} else {
fetchedNode [ 0 ] . paxCounterConfig ? . enabled = config . enabled
2024-06-02 09:45:56 -07:00
fetchedNode [ 0 ] . paxCounterConfig ? . updateInterval = Int32 ( config . paxcounterUpdateInterval )
2024-02-25 11:24:01 -08:00
}
2024-08-18 08:36:30 -07:00
if sessionPasskey != nil {
fetchedNode [ 0 ] . sessionPasskey = sessionPasskey
2024-08-18 08:53:59 -07:00
fetchedNode [ 0 ] . sessionExpiration = Date ( ) . addingTimeInterval ( 300 )
2024-08-18 08:36:30 -07:00
}
2024-02-25 11:24:01 -08:00
do {
try context . save ( )
2024-06-23 18:25:22 -07:00
Logger . data . info ( " 💾 [PaxCounterConfigEntity] Updated for node number: \( nodeNum . toHex ( ) , privacy : . public ) " )
2024-02-25 11:24:01 -08:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [PaxCounterConfigEntity] Error Updating Core Data: \( nsError , privacy : . public ) " )
2024-02-25 11:24:01 -08:00
}
} else {
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [PaxCounterConfigEntity] No Nodes found in local database matching node number \( nodeNum . toHex ( ) , privacy : . public ) unable to save PAX Counter Module Config " )
2024-02-25 11:24:01 -08:00
}
} catch {
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [PaxCounterConfigEntity] Fetching node for core data failed: \( nsError , privacy : . public ) " )
2024-02-25 11:24:01 -08:00
}
}
2024-08-18 08:36:30 -07:00
func upsertRtttlConfigPacket ( ringtone : String , nodeNum : Int64 , sessionPasskey : Data ? = Data ( ) , context : NSManagedObjectContext ) {
2023-03-25 14:30:18 -07:00
2023-05-05 09:27:24 -07:00
let logString = String . localizedStringWithFormat ( " mesh.log.ringtone.config %@ " . localized , String ( nodeNum ) )
2023-03-25 14:30:18 -07:00
MeshLogger . log ( " ⛰️ \( logString ) " )
2024-06-28 08:50:49 -05:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
2023-03-25 14:30:18 -07:00
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( nodeNum ) )
do {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
2023-03-25 14:30:18 -07:00
// F o u n d a n o d e , s a v e R T T T L C o n f i g
if ! fetchedNode . isEmpty {
if fetchedNode [ 0 ] . rtttlConfig = = nil {
let newRtttlConfig = RTTTLConfigEntity ( context : context )
2023-03-25 22:14:39 -07:00
newRtttlConfig . ringtone = ringtone
2023-03-25 14:30:18 -07:00
fetchedNode [ 0 ] . rtttlConfig = newRtttlConfig
} else {
2023-03-25 22:14:39 -07:00
fetchedNode [ 0 ] . rtttlConfig ? . ringtone = ringtone
2023-03-25 14:30:18 -07:00
}
2024-08-18 08:36:30 -07:00
if sessionPasskey != nil {
fetchedNode [ 0 ] . sessionPasskey = sessionPasskey
2024-08-18 08:53:59 -07:00
fetchedNode [ 0 ] . sessionExpiration = Date ( ) . addingTimeInterval ( 300 )
2024-08-18 08:36:30 -07:00
}
2023-03-25 14:30:18 -07:00
do {
try context . save ( )
2024-06-23 18:25:22 -07:00
Logger . data . info ( " 💾 [RtttlConfigEntity] Updated for node: \( nodeNum . toHex ( ) , privacy : . public ) " )
2023-03-25 14:30:18 -07:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [RtttlConfigEntity] Error Updating Core Data: \( nsError , privacy : . public ) " )
2023-03-25 14:30:18 -07:00
}
} else {
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [RtttlConfigEntity] No nodes found in local database matching node \( nodeNum . toHex ( ) , privacy : . public ) unable to save RTTTL Ringtone Config " )
2023-03-25 14:30:18 -07:00
}
} catch {
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [RtttlConfigEntity] Fetching node for core data failed: \( nsError , privacy : . public ) " )
2023-03-25 14:30:18 -07:00
}
}
2024-08-18 08:36:30 -07:00
func upsertMqttModuleConfigPacket ( config : ModuleConfig . MQTTConfig , nodeNum : Int64 , sessionPasskey : Data ? = Data ( ) , context : NSManagedObjectContext ) {
2023-03-06 10:33:18 -08:00
2023-05-05 09:27:24 -07:00
let logString = String . localizedStringWithFormat ( " mesh.log.mqtt.config %@ " . localized , String ( nodeNum ) )
2023-02-01 09:19:45 -08:00
MeshLogger . log ( " 🌉 \( logString ) " )
2023-03-06 10:33:18 -08:00
2024-06-28 08:50:49 -05:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
2023-02-01 09:19:45 -08:00
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( nodeNum ) )
2023-03-06 10:33:18 -08:00
2023-02-01 09:19:45 -08:00
do {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
2023-02-01 09:19:45 -08:00
// F o u n d a n o d e , s a v e M Q T T C o n f i g
if ! fetchedNode . isEmpty {
if fetchedNode [ 0 ] . mqttConfig = = nil {
let newMQTTConfig = MQTTConfigEntity ( context : context )
newMQTTConfig . enabled = config . enabled
2023-08-06 17:41:46 -07:00
newMQTTConfig . proxyToClientEnabled = config . proxyToClientEnabled
2023-02-01 09:19:45 -08:00
newMQTTConfig . address = config . address
2023-03-24 10:35:54 -07:00
newMQTTConfig . username = config . username
2023-02-01 09:19:45 -08:00
newMQTTConfig . password = config . password
2023-05-04 21:49:35 -07:00
newMQTTConfig . root = config . root
2023-02-01 09:19:45 -08:00
newMQTTConfig . encryptionEnabled = config . encryptionEnabled
newMQTTConfig . jsonEnabled = config . jsonEnabled
2023-05-04 21:49:35 -07:00
newMQTTConfig . tlsEnabled = config . tlsEnabled
2024-03-26 13:26:23 -07:00
newMQTTConfig . mapReportingEnabled = config . mapReportingEnabled
newMQTTConfig . mapPositionPrecision = Int32 ( config . mapReportSettings . positionPrecision )
newMQTTConfig . mapPublishIntervalSecs = Int32 ( config . mapReportSettings . publishIntervalSecs )
2023-02-01 09:19:45 -08:00
fetchedNode [ 0 ] . mqttConfig = newMQTTConfig
} else {
fetchedNode [ 0 ] . mqttConfig ? . enabled = config . enabled
2023-08-06 17:41:46 -07:00
fetchedNode [ 0 ] . mqttConfig ? . proxyToClientEnabled = config . proxyToClientEnabled
2023-02-01 09:19:45 -08:00
fetchedNode [ 0 ] . mqttConfig ? . address = config . address
2023-03-24 10:35:54 -07:00
fetchedNode [ 0 ] . mqttConfig ? . username = config . username
2023-02-01 09:19:45 -08:00
fetchedNode [ 0 ] . mqttConfig ? . password = config . password
2023-05-04 21:49:35 -07:00
fetchedNode [ 0 ] . mqttConfig ? . root = config . root
2023-02-01 09:19:45 -08:00
fetchedNode [ 0 ] . mqttConfig ? . encryptionEnabled = config . encryptionEnabled
fetchedNode [ 0 ] . mqttConfig ? . jsonEnabled = config . jsonEnabled
2023-05-04 21:49:35 -07:00
fetchedNode [ 0 ] . mqttConfig ? . tlsEnabled = config . tlsEnabled
2024-03-26 13:26:23 -07:00
fetchedNode [ 0 ] . mqttConfig ? . mapReportingEnabled = config . mapReportingEnabled
fetchedNode [ 0 ] . mqttConfig ? . mapPositionPrecision = Int32 ( config . mapReportSettings . positionPrecision )
fetchedNode [ 0 ] . mqttConfig ? . mapPublishIntervalSecs = Int32 ( config . mapReportSettings . publishIntervalSecs )
2023-02-01 09:19:45 -08:00
}
2024-08-18 08:36:30 -07:00
if sessionPasskey != nil {
fetchedNode [ 0 ] . sessionPasskey = sessionPasskey
2024-08-18 08:53:59 -07:00
fetchedNode [ 0 ] . sessionExpiration = Date ( ) . addingTimeInterval ( 300 )
2024-08-18 08:36:30 -07:00
}
2023-02-01 09:19:45 -08:00
do {
try context . save ( )
2024-06-23 18:25:22 -07:00
Logger . data . info ( " 💾 [MQTTConfigEntity] Updated for node number: \( nodeNum . toHex ( ) , privacy : . public ) " )
2023-02-01 09:19:45 -08:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [MQTTConfigEntity] Error Updating Core Data: \( nsError , privacy : . public ) " )
2023-02-01 09:19:45 -08:00
}
} else {
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [MQTTConfigEntity] No Nodes found in local database matching node \( nodeNum . toHex ( ) , privacy : . public ) unable to save MQTT Module Config " )
2023-02-01 09:19:45 -08:00
}
} catch {
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [MQTTConfigEntity] Fetching node for core data failed: \( nsError , privacy : . public ) " )
2023-02-01 09:19:45 -08:00
}
}
2024-08-18 08:36:30 -07:00
func upsertRangeTestModuleConfigPacket ( config : ModuleConfig . RangeTestConfig , nodeNum : Int64 , sessionPasskey : Data ? = Data ( ) , context : NSManagedObjectContext ) {
2023-03-06 10:33:18 -08:00
2023-05-05 09:27:24 -07:00
let logString = String . localizedStringWithFormat ( " mesh.log.rangetest.config %@ " . localized , String ( nodeNum ) )
2023-02-01 09:19:45 -08:00
MeshLogger . log ( " ⛰️ \( logString ) " )
2023-03-06 10:33:18 -08:00
2024-06-28 08:50:49 -05:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
2023-02-01 09:19:45 -08:00
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( nodeNum ) )
2023-03-06 10:33:18 -08:00
2023-02-01 09:19:45 -08:00
do {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
2023-02-01 09:19:45 -08:00
// F o u n d a n o d e , s a v e D e v i c e C o n f i g
if ! fetchedNode . isEmpty {
if fetchedNode [ 0 ] . rangeTestConfig = = nil {
let newRangeTestConfig = RangeTestConfigEntity ( context : context )
newRangeTestConfig . sender = Int32 ( config . sender )
newRangeTestConfig . enabled = config . enabled
newRangeTestConfig . save = config . save
fetchedNode [ 0 ] . rangeTestConfig = newRangeTestConfig
} else {
fetchedNode [ 0 ] . rangeTestConfig ? . sender = Int32 ( config . sender )
fetchedNode [ 0 ] . rangeTestConfig ? . enabled = config . enabled
fetchedNode [ 0 ] . rangeTestConfig ? . save = config . save
}
2024-08-18 08:36:30 -07:00
if sessionPasskey != nil {
fetchedNode [ 0 ] . sessionPasskey = sessionPasskey
2024-08-18 08:53:59 -07:00
fetchedNode [ 0 ] . sessionExpiration = Date ( ) . addingTimeInterval ( 300 )
2024-08-18 08:36:30 -07:00
}
2023-02-01 09:19:45 -08:00
do {
try context . save ( )
2024-06-23 18:25:22 -07:00
Logger . data . info ( " 💾 [RangeTestConfigEntity] Updated for node: \( nodeNum . toHex ( ) , privacy : . public ) " )
2023-02-01 09:19:45 -08:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [RangeTestConfigEntity] Error Updating Core Data: \( nsError , privacy : . public ) " )
2023-02-01 09:19:45 -08:00
}
} else {
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [RangeTestConfigEntity] No Nodes found in local database matching node \( nodeNum . toHex ( ) , privacy : . public ) unable to save Range Test Module Config " )
2023-02-01 09:19:45 -08:00
}
} catch {
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [RangeTestConfigEntity] Fetching node for core data failed: \( nsError , privacy : . public ) " )
2023-02-01 09:19:45 -08:00
}
}
2024-08-18 08:36:30 -07:00
func upsertSerialModuleConfigPacket ( config : ModuleConfig . SerialConfig , nodeNum : Int64 , sessionPasskey : Data ? = Data ( ) , context : NSManagedObjectContext ) {
2023-03-06 10:33:18 -08:00
2023-05-05 09:27:24 -07:00
let logString = String . localizedStringWithFormat ( " mesh.log.serial.config %@ " . localized , String ( nodeNum ) )
2023-02-01 09:19:45 -08:00
MeshLogger . log ( " 🤖 \( logString ) " )
2023-03-06 10:33:18 -08:00
2024-06-28 08:50:49 -05:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
2023-02-01 09:19:45 -08:00
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( nodeNum ) )
2023-03-06 10:33:18 -08:00
2023-02-01 09:19:45 -08:00
do {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
2023-02-01 09:19:45 -08:00
// F o u n d a n o d e , s a v e D e v i c e C o n f i g
if ! fetchedNode . isEmpty {
if fetchedNode [ 0 ] . serialConfig = = nil {
let newSerialConfig = SerialConfigEntity ( context : context )
newSerialConfig . enabled = config . enabled
newSerialConfig . echo = config . echo
newSerialConfig . rxd = Int32 ( config . rxd )
newSerialConfig . txd = Int32 ( config . txd )
newSerialConfig . baudRate = Int32 ( config . baud . rawValue )
newSerialConfig . timeout = Int32 ( config . timeout )
newSerialConfig . mode = Int32 ( config . mode . rawValue )
fetchedNode [ 0 ] . serialConfig = newSerialConfig
} else {
fetchedNode [ 0 ] . serialConfig ? . enabled = config . enabled
fetchedNode [ 0 ] . serialConfig ? . echo = config . echo
fetchedNode [ 0 ] . serialConfig ? . rxd = Int32 ( config . rxd )
fetchedNode [ 0 ] . serialConfig ? . txd = Int32 ( config . txd )
fetchedNode [ 0 ] . serialConfig ? . baudRate = Int32 ( config . baud . rawValue )
fetchedNode [ 0 ] . serialConfig ? . timeout = Int32 ( config . timeout )
fetchedNode [ 0 ] . serialConfig ? . mode = Int32 ( config . mode . rawValue )
}
2024-08-18 08:36:30 -07:00
if sessionPasskey != nil {
fetchedNode [ 0 ] . sessionPasskey = sessionPasskey
2024-08-18 08:53:59 -07:00
fetchedNode [ 0 ] . sessionExpiration = Date ( ) . addingTimeInterval ( 300 )
2024-08-18 08:36:30 -07:00
}
2023-02-01 09:19:45 -08:00
do {
try context . save ( )
2024-06-23 18:25:22 -07:00
Logger . data . info ( " 💾 [SerialConfigEntity]Updated Serial Module Config for node: \( nodeNum . toHex ( ) , privacy : . public ) " )
2023-02-01 09:19:45 -08:00
} catch {
2023-03-06 10:33:18 -08:00
2023-02-01 09:19:45 -08:00
context . rollback ( )
2023-03-06 10:33:18 -08:00
2023-02-01 09:19:45 -08:00
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [SerialConfigEntity] Error Updating Core Data: \( nsError , privacy : . public ) " )
2023-02-01 09:19:45 -08:00
}
} else {
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [SerialConfigEntity] No Nodes found in local database matching node \( nodeNum . toHex ( ) , privacy : . public ) unable to save Serial Module Config " )
2023-02-01 09:19:45 -08:00
}
} catch {
2023-03-06 10:33:18 -08:00
2023-02-01 09:19:45 -08:00
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [SerialConfigEntity] Fetching node for core data failed: \( nsError , privacy : . public ) " )
2023-02-01 09:19:45 -08:00
}
}
2024-08-18 08:36:30 -07:00
func upsertStoreForwardModuleConfigPacket ( config : ModuleConfig . StoreForwardConfig , nodeNum : Int64 , sessionPasskey : Data ? = Data ( ) , context : NSManagedObjectContext ) {
2023-02-01 09:19:45 -08:00
2023-08-26 20:45:15 -07:00
let logString = String . localizedStringWithFormat ( " mesh.log.storeforward.config %@ " . localized , String ( nodeNum ) )
MeshLogger . log ( " 📬 \( logString ) " )
2023-03-06 10:33:18 -08:00
2024-06-28 08:50:49 -05:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
2023-02-01 09:19:45 -08:00
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( nodeNum ) )
2023-03-06 10:33:18 -08:00
2023-02-01 09:19:45 -08:00
do {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
2023-08-26 20:45:15 -07:00
// F o u n d a n o d e , s a v e S t o r e & F o r w a r d S e n s o r C o n f i g
2023-02-01 09:19:45 -08:00
if ! fetchedNode . isEmpty {
2023-08-26 20:45:15 -07:00
if fetchedNode [ 0 ] . storeForwardConfig = = nil {
let newConfig = StoreForwardConfigEntity ( context : context )
newConfig . enabled = config . enabled
newConfig . heartbeat = config . heartbeat
newConfig . records = Int32 ( config . records )
newConfig . historyReturnMax = Int32 ( config . historyReturnMax )
newConfig . historyReturnWindow = Int32 ( config . historyReturnWindow )
fetchedNode [ 0 ] . storeForwardConfig = newConfig
2023-02-01 09:19:45 -08:00
} else {
2023-08-26 20:45:15 -07:00
fetchedNode [ 0 ] . storeForwardConfig ? . enabled = config . enabled
fetchedNode [ 0 ] . storeForwardConfig ? . heartbeat = config . heartbeat
fetchedNode [ 0 ] . storeForwardConfig ? . records = Int32 ( config . records )
fetchedNode [ 0 ] . storeForwardConfig ? . historyReturnMax = Int32 ( config . historyReturnMax )
fetchedNode [ 0 ] . storeForwardConfig ? . historyReturnWindow = Int32 ( config . historyReturnWindow )
2023-02-01 09:19:45 -08:00
}
2024-08-18 08:36:30 -07:00
if sessionPasskey != nil {
fetchedNode [ 0 ] . sessionPasskey = sessionPasskey
2024-08-18 08:53:59 -07:00
fetchedNode [ 0 ] . sessionExpiration = Date ( ) . addingTimeInterval ( 300 )
2024-08-18 08:36:30 -07:00
}
2023-02-01 09:19:45 -08:00
do {
try context . save ( )
2024-06-23 18:25:22 -07:00
Logger . data . info ( " 💾 [StoreForwardConfigEntity] Updated for node: \( nodeNum . toHex ( ) , privacy : . public ) " )
2023-02-01 09:19:45 -08:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [StoreForwardConfigEntity] Error Updating Core Data: \( nsError , privacy : . public ) " )
2023-02-01 09:19:45 -08:00
}
} else {
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [StoreForwardConfigEntity] No Nodes found in local database matching node \( nodeNum . toHex ( ) , privacy : . public ) unable to save Store & Forward Module Config " )
2023-02-01 09:19:45 -08:00
}
} catch {
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [StoreForwardConfigEntity] Fetching node for core data failed: \( nsError , privacy : . public ) " )
2023-02-01 09:19:45 -08:00
}
}
2023-08-17 16:30:48 -05:00
2024-08-18 08:36:30 -07:00
func upsertTelemetryModuleConfigPacket ( config : ModuleConfig . TelemetryConfig , nodeNum : Int64 , sessionPasskey : Data ? = Data ( ) , context : NSManagedObjectContext ) {
2023-08-17 16:30:48 -05:00
2023-08-26 20:45:15 -07:00
let logString = String . localizedStringWithFormat ( " mesh.log.telemetry.config %@ " . localized , String ( nodeNum ) )
2023-08-17 16:30:48 -05:00
MeshLogger . log ( " 📈 \( logString ) " )
2024-06-28 08:50:49 -05:00
let fetchNodeInfoRequest = NodeInfoEntity . fetchRequest ( )
2023-08-17 16:30:48 -05:00
fetchNodeInfoRequest . predicate = NSPredicate ( format : " num == %lld " , Int64 ( nodeNum ) )
do {
2024-06-28 08:50:49 -05:00
let fetchedNode = try context . fetch ( fetchNodeInfoRequest )
2023-08-26 20:45:15 -07:00
// F o u n d a n o d e , s a v e T e l e m e t r y C o n f i g
2023-08-17 16:30:48 -05:00
if ! fetchedNode . isEmpty {
2023-08-26 20:45:15 -07:00
if fetchedNode [ 0 ] . telemetryConfig = = nil {
let newTelemetryConfig = TelemetryConfigEntity ( context : context )
newTelemetryConfig . deviceUpdateInterval = Int32 ( config . deviceUpdateInterval )
newTelemetryConfig . environmentUpdateInterval = Int32 ( config . environmentUpdateInterval )
newTelemetryConfig . environmentMeasurementEnabled = config . environmentMeasurementEnabled
newTelemetryConfig . environmentScreenEnabled = config . environmentScreenEnabled
newTelemetryConfig . environmentDisplayFahrenheit = config . environmentDisplayFahrenheit
2024-03-14 00:04:35 -07:00
newTelemetryConfig . powerMeasurementEnabled = config . powerMeasurementEnabled
newTelemetryConfig . powerUpdateInterval = Int32 ( config . powerUpdateInterval )
newTelemetryConfig . powerScreenEnabled = config . powerScreenEnabled
2023-08-26 20:45:15 -07:00
fetchedNode [ 0 ] . telemetryConfig = newTelemetryConfig
2023-08-17 16:30:48 -05:00
} else {
2023-08-26 20:45:15 -07:00
fetchedNode [ 0 ] . telemetryConfig ? . deviceUpdateInterval = Int32 ( config . deviceUpdateInterval )
fetchedNode [ 0 ] . telemetryConfig ? . environmentUpdateInterval = Int32 ( config . environmentUpdateInterval )
fetchedNode [ 0 ] . telemetryConfig ? . environmentMeasurementEnabled = config . environmentMeasurementEnabled
fetchedNode [ 0 ] . telemetryConfig ? . environmentScreenEnabled = config . environmentScreenEnabled
fetchedNode [ 0 ] . telemetryConfig ? . environmentDisplayFahrenheit = config . environmentDisplayFahrenheit
2024-03-14 00:04:35 -07:00
fetchedNode [ 0 ] . telemetryConfig ? . powerMeasurementEnabled = config . powerMeasurementEnabled
fetchedNode [ 0 ] . telemetryConfig ? . powerUpdateInterval = Int32 ( config . powerUpdateInterval )
fetchedNode [ 0 ] . telemetryConfig ? . powerScreenEnabled = config . powerScreenEnabled
2023-08-17 16:30:48 -05:00
}
2024-08-18 08:36:30 -07:00
if sessionPasskey != nil {
fetchedNode [ 0 ] . sessionPasskey = sessionPasskey
2024-08-18 08:53:59 -07:00
fetchedNode [ 0 ] . sessionExpiration = Date ( ) . addingTimeInterval ( 300 )
2024-08-18 08:36:30 -07:00
}
2023-08-17 16:30:48 -05:00
do {
try context . save ( )
2024-06-23 18:25:22 -07:00
Logger . data . info ( " 💾 [TelemetryConfigEntity] Updated Telemetry Module Config for node: \( nodeNum . toHex ( ) , privacy : . public ) " )
2023-08-17 16:30:48 -05:00
} catch {
context . rollback ( )
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [TelemetryConfigEntity] Error Updating Core Data: \( nsError , privacy : . public ) " )
2023-08-17 16:30:48 -05:00
}
} else {
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [TelemetryConfigEntity] No Nodes found in local database matching node \( nodeNum . toHex ( ) , privacy : . public ) unable to save Telemetry Module Config " )
2023-08-17 16:30:48 -05:00
}
} catch {
let nsError = error as NSError
2024-06-23 18:25:22 -07:00
Logger . data . error ( " 💥 [TelemetryConfigEntity] Fetching node for core data TelemetryConfigEntity failed: \( nsError , privacy : . public ) " )
2023-08-17 16:30:48 -05:00
}
}