Merge pull request #112 from meshtastic/feature/module_settings

Admin Message History
This commit is contained in:
Garth Vander Houwen 2022-07-02 22:23:56 -07:00 committed by GitHub
commit e347154e76
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 344 additions and 133 deletions

View file

@ -13,6 +13,7 @@
C9A7BC1027759A9600760B50 /* PositionAnnotationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A7BC0F27759A9600760B50 /* PositionAnnotationView.swift */; };
C9A88B55278B503C00BD810A /* MapViewModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A88B54278B503C00BD810A /* MapViewModule.swift */; };
C9A88B57278B559900BD810A /* apponly.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A88B56278B559900BD810A /* apponly.pb.swift */; };
DD0F791B28713C8A00A6FDAD /* AdminMessageList.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD0F791A28713C8A00A6FDAD /* AdminMessageList.swift */; };
DD17E5DE277D49D400010EC2 /* storeforward.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD17E5DC277D49D400010EC2 /* storeforward.pb.swift */; };
DD1BF2F92776FE2E008C8D2F /* UserMessageList.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1BF2F82776FE2E008C8D2F /* UserMessageList.swift */; };
DD23A50F26FD1B4400D9B90C /* PeripheralModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD23A50E26FD1B4400D9B90C /* PeripheralModel.swift */; };
@ -99,6 +100,7 @@
C9A7BC0F27759A9600760B50 /* PositionAnnotationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionAnnotationView.swift; sourceTree = "<group>"; };
C9A88B54278B503C00BD810A /* MapViewModule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MapViewModule.swift; sourceTree = "<group>"; };
C9A88B56278B559900BD810A /* apponly.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = apponly.pb.swift; sourceTree = "<group>"; };
DD0F791A28713C8A00A6FDAD /* AdminMessageList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminMessageList.swift; sourceTree = "<group>"; };
DD17E5DC277D49D400010EC2 /* storeforward.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = storeforward.pb.swift; sourceTree = "<group>"; };
DD1BF2F82776FE2E008C8D2F /* UserMessageList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserMessageList.swift; sourceTree = "<group>"; };
DD23A50E26FD1B4400D9B90C /* PeripheralModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeripheralModel.swift; sourceTree = "<group>"; };
@ -244,6 +246,7 @@
DD8169FE272476C700F4AB02 /* LogDocument.swift */,
DD6B85A728009258000ACD6B /* ShareChannel.swift */,
DDCE4E2B2869F92900BE9F8F /* UserConfig.swift */,
DD0F791A28713C8A00A6FDAD /* AdminMessageList.swift */,
DD61937A2863876A00E59241 /* Config */,
);
path = Settings;
@ -659,6 +662,7 @@
DD47E3D926F3093800029299 /* MessageBubble.swift in Sources */,
DD415828285859C4009B0E59 /* TelemetryConfig.swift in Sources */,
C9697F9D279336B700250207 /* LocalMBTileOverlay.swift in Sources */,
DD0F791B28713C8A00A6FDAD /* AdminMessageList.swift in Sources */,
DD8169F9271F1A6100F4AB02 /* MeshLogger.swift in Sources */,
DD539502276DAA6A00AD86B1 /* MapLocation.swift in Sources */,
DD41582A28585C32009B0E59 /* RangeTestConfig.swift in Sources */,

View file

@ -892,65 +892,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
return false
}
public func saveUser(config: User, entity: UserEntity, wantResponse: Bool) -> Int64 {
var newMessageId: Int64 = 0
var adminPacket = AdminMessage()
adminPacket.setOwner = config
var meshPacket: MeshPacket = MeshPacket()
meshPacket.to = UInt32(connectedPeripheral.num)
meshPacket.from = 0 //UInt32(connectedPeripheral.num)
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
meshPacket.priority = MeshPacket.Priority.reliable
meshPacket.wantAck = wantResponse
meshPacket.hopLimit = 0
var dataMessage = DataMessage()
dataMessage.payload = try! adminPacket.serializedData()
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
var toRadio: ToRadio!
toRadio = ToRadio()
toRadio.packet = meshPacket
let binaryData: Data = try! toRadio.serializedData()
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
let newMessage = MessageEntity(context: context!)
newMessage.messageId = Int64(UInt32.random(in: UInt32(UInt8.max)..<UInt32.max))
newMessageId = newMessage.messageId
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
newMessage.receivedACK = false
newMessage.direction = "OUT"
newMessage.admin = true
newMessage.fromUser = entity
newMessage.toUser = entity
newMessage.messagePayload = try! dataMessage.jsonString()
do {
try context!.save()
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new Admin Message for node number: \(String(entity.num))") }
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
} catch {
context!.rollback()
let nsError = error as NSError
print("💥 Error Inserting New Core Data MessageEntity: \(nsError)")
}
}
return newMessageId
}
public func sendFactoryReset(destNum: Int64, wantResponse: Bool) -> Bool {
var deviceConfig = Config.DeviceConfig()
@ -989,7 +930,69 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
return false
}
public func saveDeviceConfig(config: Config.DeviceConfig, destNum: Int64, wantResponse: Bool) -> Bool {
public func saveUser(config: User, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 {
var newMessageId: Int64 = 0
var adminPacket = AdminMessage()
adminPacket.setOwner = config
var meshPacket: MeshPacket = MeshPacket()
meshPacket.to = UInt32(connectedPeripheral.num)
meshPacket.from = 0 //UInt32(connectedPeripheral.num)
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
meshPacket.priority = MeshPacket.Priority.reliable
meshPacket.wantAck = wantResponse
meshPacket.hopLimit = 0
var dataMessage = DataMessage()
dataMessage.payload = try! adminPacket.serializedData()
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
var toRadio: ToRadio!
toRadio = ToRadio()
toRadio.packet = meshPacket
let binaryData: Data = try! toRadio.serializedData()
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
let newMessage = MessageEntity(context: context!)
newMessage.messageId = Int64(meshPacket.id)
newMessageId = newMessage.messageId
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
newMessage.receivedACK = false
newMessage.direction = "OUT"
newMessage.admin = true
newMessage.adminDescription = "Saved User Config for \(toUser.longName ?? "Unknown")"
newMessage.fromUser = fromUser
newMessage.toUser = toUser
newMessage.messagePayload = try! dataMessage.jsonString()
do {
try context!.save()
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new User Config Admin Message for node: \(String(toUser.num))") }
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
} catch {
context!.rollback()
let nsError = error as NSError
print("💥 Error Inserting New Core Data MessageEntity: \(nsError)")
}
}
return newMessageId
}
public func saveDeviceConfig(config: Config.DeviceConfig, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 {
var newMessageId: Int64 = 0
var adminPacket = AdminMessage()
adminPacket.setConfig.device = config
@ -1015,16 +1018,40 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
let binaryData: Data = try! toRadio.serializedData()
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
let newMessage = MessageEntity(context: context!)
newMessage.messageId = Int64(meshPacket.id)
newMessageId = newMessage.messageId
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
newMessage.receivedACK = false
newMessage.direction = "OUT"
newMessage.admin = true
newMessage.adminDescription = "Saved Device Config for \(toUser.longName ?? "Unknown")"
newMessage.fromUser = fromUser
newMessage.toUser = toUser
newMessage.messagePayload = try! dataMessage.jsonString()
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
return true
do {
try context!.save()
if meshLoggingEnabled { MeshLogger.log("💾 Saved Device Config Admin Message for node: \(String(toUser.num))") }
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
} catch {
context!.rollback()
let nsError = error as NSError
print("💥 Error Inserting New Core Data MessageEntity: \(nsError)")
}
}
return false
return newMessageId
}
public func saveDisplayConfig(config: Config.DisplayConfig, destNum: Int64, wantResponse: Bool) -> Bool {
public func saveDisplayConfig(config: Config.DisplayConfig, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 {
var newMessageId: Int64 = 0
var adminPacket = AdminMessage()
adminPacket.setConfig.display = config
@ -1050,16 +1077,40 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
let binaryData: Data = try! toRadio.serializedData()
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
let newMessage = MessageEntity(context: context!)
newMessage.messageId = Int64(meshPacket.id)
newMessageId = newMessage.messageId
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
newMessage.receivedACK = false
newMessage.direction = "OUT"
newMessage.admin = true
newMessage.adminDescription = "Saved Display Config for \(toUser.longName ?? "Unknown")"
newMessage.fromUser = fromUser
newMessage.toUser = toUser
newMessage.messagePayload = try! dataMessage.jsonString()
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
return true
do {
try context!.save()
if meshLoggingEnabled { MeshLogger.log("💾 Saved Display Config Admin Message for node: \(String(toUser.num))") }
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
} catch {
context!.rollback()
let nsError = error as NSError
print("💥 Error Inserting New Core Data MessageEntity: \(nsError)")
}
}
return false
return newMessageId
}
public func saveLoRaConfig(config: Config.LoRaConfig, destNum: Int64, wantResponse: Bool) -> Bool {
public func saveLoRaConfig(config: Config.LoRaConfig, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 {
var newMessageId: Int64 = 0
var adminPacket = AdminMessage()
adminPacket.setConfig.lora = config
@ -1068,6 +1119,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
meshPacket.to = UInt32(connectedPeripheral.num)
meshPacket.from = 0 //UInt32(connectedPeripheral.num)
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
meshPacket.priority = MeshPacket.Priority.reliable
meshPacket.wantAck = wantResponse
meshPacket.hopLimit = 0
@ -1085,16 +1137,40 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
let binaryData: Data = try! toRadio.serializedData()
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
let newMessage = MessageEntity(context: context!)
newMessage.messageId = Int64(meshPacket.id)
newMessageId = newMessage.messageId
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
newMessage.receivedACK = false
newMessage.direction = "IN"
newMessage.admin = true
newMessage.adminDescription = "Saved LoRa Config for \(toUser.longName ?? "Unknown")"
newMessage.fromUser = fromUser
newMessage.toUser = toUser
newMessage.messagePayload = try! dataMessage.jsonString()
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
return true
do {
try context!.save()
if meshLoggingEnabled { MeshLogger.log("💾 Saved LoRa Config Admin Message for node: \(String(toUser.num))") }
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
} catch {
context!.rollback()
let nsError = error as NSError
print("💥 Error Inserting New Core Data MessageEntity: \(nsError)")
}
}
return false
return newMessageId
}
public func savePositionConfig(config: Config.PositionConfig, destNum: Int64, wantResponse: Bool) -> Bool {
public func savePositionConfig(config: Config.PositionConfig, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 {
var newMessageId: Int64 = 0
var adminPacket = AdminMessage()
adminPacket.setConfig.position = config
@ -1120,16 +1196,39 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
let binaryData: Data = try! toRadio.serializedData()
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
let newMessage = MessageEntity(context: context!)
newMessage.messageId = Int64(meshPacket.id)
newMessageId = newMessage.messageId
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
newMessage.receivedACK = false
newMessage.direction = "OUT"
newMessage.admin = true
newMessage.adminDescription = "Saved Position Config for \(toUser.longName ?? "Unknown")"
newMessage.fromUser = fromUser
newMessage.toUser = toUser
newMessage.messagePayload = try! dataMessage.jsonString()
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
return true
do {
try context!.save()
if meshLoggingEnabled { MeshLogger.log("💾 Saved Position Config Admin Message for node: \(String(toUser.num))") }
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
} catch {
context!.rollback()
let nsError = error as NSError
print("💥 Error Inserting New Core Data MessageEntity: \(nsError)")
}
}
return newMessageId
return false
}
public func saveCannedMessageModuleConfig(config: ModuleConfig.CannedMessageConfig, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 {
public func saveCannedMessageModuleConfig(config: ModuleConfig.CannedMessageConfig, fromUser: UserEntity, toUser: UserEntity, wantResponse: Bool) -> Int64 {
var newMessageId: Int64 = 0
@ -1158,12 +1257,13 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
let newMessage = MessageEntity(context: context!)
newMessage.messageId = Int64(UInt32.random(in: UInt32(UInt8.max)..<UInt32.max))
newMessage.messageId = Int64(meshPacket.id)
newMessageId = newMessage.messageId
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
newMessage.receivedACK = false
newMessage.direction = "OUT"
newMessage.admin = true
newMessage.adminDescription = "Saved Canned Message Module Config for \(toUser.longName ?? "Unknown")"
newMessage.fromUser = fromUser
newMessage.toUser = toUser
newMessage.messagePayload = try! dataMessage.jsonString()
@ -1172,7 +1272,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
try context!.save()
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new Canned Message Module Config Admin Message for node number: \(String(toUser.num))") }
if meshLoggingEnabled { MeshLogger.log("💾 Saved Canned Message Module Config Admin Message for node: \(String(toUser.num))") }
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
} catch {
@ -1215,12 +1315,13 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
let newMessage = MessageEntity(context: context!)
newMessage.messageId = Int64(UInt32.random(in: UInt32(UInt8.max)..<UInt32.max))
newMessage.messageId = Int64(meshPacket.id)
newMessageId = newMessage.messageId
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
newMessage.receivedACK = false
newMessage.direction = "OUT"
newMessage.admin = true
newMessage.adminDescription = "Saved External Notification Module Config for \(toUser.longName ?? "Unknown")"
newMessage.fromUser = fromUser
newMessage.toUser = toUser
newMessage.messagePayload = try! dataMessage.jsonString()
@ -1229,7 +1330,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
try context!.save()
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new Canned Message Module Config Admin Message for node number: \(String(toUser.num))") }
if meshLoggingEnabled { MeshLogger.log("💾 Saved External Notification Module Config Admin Message for node: \(String(toUser.num))") }
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
} catch {
@ -1274,12 +1375,13 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
let newMessage = MessageEntity(context: context!)
newMessage.messageId = Int64(UInt32.random(in: UInt32(UInt8.max)..<UInt32.max))
newMessage.messageId = Int64(meshPacket.id)
newMessageId = newMessage.messageId
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
newMessage.receivedACK = false
newMessage.direction = "OUT"
newMessage.admin = true
newMessage.adminDescription = "Saved Range Test Module Config for \(toUser.longName ?? "Unknown")"
newMessage.fromUser = fromUser
newMessage.toUser = toUser
newMessage.messagePayload = try! dataMessage.jsonString()
@ -1288,7 +1390,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
try context!.save()
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new Range Test Module Config Admin Message for node number: \(String(toUser.num))") }
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new Range Test Module Config Admin Message for node: \(String(toUser.num))") }
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
} catch {
@ -1334,12 +1436,13 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
let newMessage = MessageEntity(context: context!)
newMessage.messageId = Int64(UInt32.random(in: UInt32(UInt8.max)..<UInt32.max))
newMessage.messageId = Int64(meshPacket.id)
newMessageId = newMessage.messageId
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
newMessage.receivedACK = false
newMessage.direction = "OUT"
newMessage.admin = true
newMessage.adminDescription = "Saved Serial Module Config for \(toUser.longName ?? "Unknown")"
newMessage.fromUser = fromUser
newMessage.toUser = toUser
newMessage.messagePayload = try! dataMessage.jsonString()
@ -1348,7 +1451,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
try context!.save()
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new Telemetry Module Config Admin Message for node number: \(String(toUser.num))") }
if meshLoggingEnabled { MeshLogger.log("💾 Saved Serial Module Config Admin Message for node: \(String(toUser.num))") }
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
} catch {
@ -1392,12 +1495,13 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
let newMessage = MessageEntity(context: context!)
newMessage.messageId = Int64(UInt32.random(in: UInt32(UInt8.max)..<UInt32.max))
newMessage.messageId = Int64(meshPacket.id)
newMessageId = newMessage.messageId
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
newMessage.receivedACK = false
newMessage.direction = "OUT"
newMessage.admin = true
newMessage.adminDescription = "Saved Telemetry Module Config for \(toUser.longName ?? "Unknown")"
newMessage.fromUser = fromUser
newMessage.toUser = toUser
newMessage.messagePayload = try! dataMessage.jsonString()
@ -1406,7 +1510,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
try context!.save()
if meshLoggingEnabled { MeshLogger.log("💾 Saved a new Canned Message Module Config Admin Message for node number: \(String(toUser.num))") }
if meshLoggingEnabled { MeshLogger.log("💾 Saved Telemetry Module Config Admin Message for node number: \(String(toUser.num))") }
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
} catch {

View file

@ -49,6 +49,7 @@
<attribute name="ackSNR" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
<attribute name="ackTimestamp" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="admin" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="adminDescription" optional="YES" attributeType="String"/>
<attribute name="direction" attributeType="String"/>
<attribute name="isEmoji" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="messageId" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
@ -183,6 +184,9 @@
<relationship name="receivedMessages" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="MessageEntity" inverseName="toUser" inverseEntity="MessageEntity"/>
<relationship name="sentMessages" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="MessageEntity" inverseName="fromUser" inverseEntity="MessageEntity"/>
<relationship name="userNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="user" inverseEntity="NodeInfoEntity"/>
<fetchedProperty name="adminMessages" optional="YES">
<fetchRequest name="fetchedPropertyFetchRequest" entity="MessageEntity" predicateString="(toUser.num == $FETCH_SOURCE.num) AND isEmoji == false AND admin = true"/>
</fetchedProperty>
<fetchedProperty name="allMessages" optional="YES">
<fetchRequest name="fetchedPropertyFetchRequest" entity="MessageEntity" predicateString="((toUser.num == $FETCH_SOURCE.num) OR (fromUser.num == $FETCH_SOURCE.num)) AND isEmoji == false AND admin = false"/>
</fetchedProperty>
@ -192,14 +196,14 @@
<element name="DeviceConfigEntity" positionX="45" positionY="144" width="128" height="104"/>
<element name="DisplayConfigEntity" positionX="54" positionY="153" width="128" height="104"/>
<element name="LoRaConfigEntity" positionX="45" positionY="144" width="128" height="104"/>
<element name="MessageEntity" positionX="-36" positionY="63" width="128" height="230"/>
<element name="MessageEntity" positionX="-36" positionY="63" width="128" height="245"/>
<element name="MyInfoEntity" positionX="-18" positionY="81" width="128" height="209"/>
<element name="NodeInfoEntity" positionX="-63" positionY="-18" width="128" height="299"/>
<element name="PositionConfigEntity" positionX="63" positionY="162" width="128" height="149"/>
<element name="PositionEntity" positionX="-54" positionY="54" width="128" height="119"/>
<element name="RangeTestConfigEntity" positionX="72" positionY="171" width="128" height="104"/>
<element name="TelemetryEntity" positionX="160" positionY="192" width="128" height="194"/>
<element name="UserEntity" positionX="0" positionY="144" width="128" height="200"/>
<element name="UserEntity" positionX="0" positionY="144" width="128" height="215"/>
<element name="SerialConfigEntity" positionX="54" positionY="153" width="128" height="164"/>
<element name="ExternalNotificationConfigEntity" positionX="63" positionY="162" width="128" height="149"/>
<element name="TelemetryConfigEntity" positionX="72" positionY="171" width="128" height="179"/>

View file

@ -13,4 +13,9 @@ extension UserEntity {
self.value(forKey: "allMessages") as! [MessageEntity]
}
var adminMessageList: [MessageEntity] {
self.value(forKey: "adminMessages") as! [MessageEntity]
}
}

View file

@ -1,8 +1,8 @@
//
// DateTimeText.swift
// MeshtasticApple
// Meshtastic Apple
//
// Created by Garth Vander Houwen on 5/30/22.
// Copyright(C) Garth Vander Houwen 5/30/22.
//
import SwiftUI

View file

@ -24,16 +24,15 @@ struct Contacts: View {
List(users) { (user: UserEntity) in
let allMessages = user.value(forKey: "allMessages") as! [MessageEntity]
let connectedNodeNum = bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.num : 0
if user.num != connectedNodeNum {
NavigationLink(destination: UserMessageList(user: user)) {
if allMessages.count > 0 {
if user.messageList.count > 0 {
let mostRecent = allMessages.last
let mostRecent = user.messageList.last
let lastMessageTime = Date(timeIntervalSince1970: TimeInterval(Int64((mostRecent!.messageTimestamp ))))
let lastMessageDay = Calendar.current.dateComponents([.day], from: lastMessageTime).day ?? 0
let currentDay = Calendar.current.dateComponents([.day], from: Date()).day ?? 0

View file

@ -0,0 +1,72 @@
//
// AdminMessageList.swift
// Meshtastic
//
// Created by Garth Vander Houwen on 7/2/22.
//
/*
Abstract:
A view showing the details for a node.
*/
import SwiftUI
import MapKit
import CoreLocation
struct AdminMessageList: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
var user: UserEntity?
var body: some View {
List {
if user != nil {
ForEach ( user!.adminMessageList ) { am in
HStack {
Text("\(am.adminDescription ?? "Unknown") - \(Date(timeIntervalSince1970: TimeInterval(am.messageTimestamp)), style: .date) \(Date(timeIntervalSince1970: TimeInterval(am.messageTimestamp)), style: .time)")
.font(.caption)
if am.receivedACK {
Image(systemName: "checkmark.square")
.foregroundColor(.gray)
.font(.caption)
Text("Acknowledged: ")
.foregroundColor(.gray)
.font(.caption)
DateTimeText(dateTime: Date(timeIntervalSince1970: TimeInterval(am.messageTimestamp)))
.foregroundColor(.gray)
.font(.caption)
} else {
Image(systemName: "square")
.foregroundColor(.gray)
.font(.caption)
Text("Acknowledged")
.foregroundColor(.gray)
.font(.caption)
}
}
}
}
}
.navigationTitle("Admin Message History")
.navigationBarItems(trailing:
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "????")
})
.onAppear {
self.bleManager.context = context
}
}
}

View file

@ -156,12 +156,6 @@ struct AppSettings: View {
.pickerStyle(DefaultPickerStyle())
}
Section(header: Text("DEBUG")) {
NavigationLink(destination: MeshLog()) {
Text("View Mesh Log")
}
}
}
}
.navigationTitle("App Settings")

View file

@ -124,7 +124,9 @@ struct DeviceConfig: View {
dc.serialDisabled = !serialEnabled
dc.debugLogEnabled = debugLogEnabled
if bleManager.saveDeviceConfig(config: dc, destNum: bleManager.connectedPeripheral.num, wantResponse: false) {
let adminMessageId = bleManager.saveDeviceConfig(config: dc, fromUser: node.user!, toUser: node.user!, wantResponse: true)
if adminMessageId > 0 {
// Should show a saved successfully alert once I know that to be true
// for now just disable the button after a successful save

View file

@ -203,7 +203,9 @@ struct DisplayConfig: View {
dc.screenOnSecs = UInt32(screenOnSeconds)
dc.autoScreenCarouselSecs = UInt32(screenCarouselInterval)
if bleManager.saveDisplayConfig(config: dc, destNum: bleManager.connectedPeripheral.num, wantResponse: false) {
let adminMessageId = bleManager.saveDisplayConfig(config: dc, fromUser: node.user!, toUser: node.user!, wantResponse: true)
if adminMessageId > 0 {
// Should show a saved successfully alert once I know that to be true
// for now just disable the button after a successful save

View file

@ -263,7 +263,9 @@ struct LoRaConfig: View {
lc.region = RegionCodes(rawValue: region)!.protoEnumValue()
lc.modemPreset = ModemPresets(rawValue: modemPreset)!.protoEnumValue()
if bleManager.saveLoRaConfig(config: lc, destNum: bleManager.connectedPeripheral.num, wantResponse: false) {
let adminMessageId = bleManager.saveLoRaConfig(config: lc, fromUser: node.user!, toUser: node.user!, wantResponse: true)
if adminMessageId > 0 {
// Should show a saved successfully alert once I know that to be true
// for now just disable the button after a successful save

View file

@ -311,15 +311,17 @@ struct TelemetryConfig: View {
tc.environmentRecoveryInterval = UInt32(environmentRecoveryInterval)
tc.environmentReadErrorCountThreshold = UInt32(environmentReadErrorCountThreshold)
//if bleManager.saveRangeTestModuleConfig(config: rtc, destNum: bleManager.connectedPeripheral.num, wantResponse: false) {
let adminMessageId = bleManager.saveTelemetryModuleConfig(config: tc, fromUser: node.user!, toUser: node.user!, wantResponse: true)
if adminMessageId > 0 {
// Should show a saved successfully alert once I know that to be true
// for now just disable the button after a successful save
hasChanges = false
//} else {
} else {
//}
}
}
}

View file

@ -282,7 +282,9 @@ struct PositionConfig: View {
pc.gpsAttemptTime = UInt32(gpsAttemptTime)
pc.positionBroadcastSecs = UInt32(positionBroadcastSeconds)
if bleManager.savePositionConfig(config: pc, destNum: bleManager.connectedPeripheral.num, wantResponse: false) {
let adminMessageId = bleManager.savePositionConfig(config: pc, fromUser: node.user!, toUser: node.user!, wantResponse: true)
if adminMessageId > 0{
// Should show a saved successfully alert once I know that to be true
// for now just disable the button after a successful save

View file

@ -42,7 +42,7 @@ struct MeshLog: View {
)
.textSelection(.enabled)
.font(.caption2)
.font(.caption)
HStack(alignment: .center) {
Spacer()

View file

@ -25,27 +25,17 @@ struct Settings: View {
let connectedNodeNum = bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.num : 0
Section("General") {
NavigationLink {
AppSettings()
} label: {
Image(systemName: "gearshape")
.symbolRenderingMode(.hierarchical)
Text("App Settings")
}
Text("Apple app specific settings and features, app username, share position with mesh options, map and keyboard type, mesh log.")
.font(.caption)
.fixedSize(horizontal: false, vertical: true)
NavigationLink {
AppSettings()
} label: {
Image(systemName: "gearshape")
.symbolRenderingMode(.hierarchical)
Text("App Settings")
}
Section("Radio Configuration") {
Text("Radio config views will be be enabled when there is a connected node. Save buttons will be enabled when there are config changes to save.")
.font(.caption)
.fixedSize(horizontal: false, vertical: true)
NavigationLink {
ShareChannel(node: nodes.first(where: { $0.num == connectedNodeNum }) ?? NodeInfoEntity())
} label: {
@ -109,7 +99,7 @@ struct Settings: View {
}
.disabled(bleManager.connectedPeripheral == nil)
Text("Default settings values are prefered whenever possible as they consume no bandwidth when sent over the mesh.")
Text("Default settings values are prefered as they consume no bandwidth when sent over the mesh.")
.font(.caption2)
.fixedSize(horizontal: false, vertical: true)
}
@ -173,6 +163,35 @@ struct Settings: View {
}
.disabled(bleManager.connectedPeripheral == nil)
}
Section(header: Text("Logging")) {
NavigationLink {
MeshLog()
} label: {
Image(systemName: "list.bullet.rectangle")
.symbolRenderingMode(.hierarchical)
Text("Mesh Log")
}
NavigationLink {
let connectedNode = nodes.first(where: { $0.num == connectedNodeNum })
AdminMessageList(user: connectedNode?.user ?? UserEntity())
} label: {
Image(systemName: "building.columns")
.symbolRenderingMode(.hierarchical)
Text("Admin Message Log")
}
.disabled(bleManager.connectedPeripheral == nil)
}
// Not Implemented:
// Store Forward Config - Not Working, TBEAM Only
// WiFi Config - Would break connection to device

View file

@ -112,7 +112,7 @@ struct UserConfig: View {
u.shortName = shortName
u.longName = longName
let adminMessageId = bleManager.saveUser(config: u, entity: node.user!, wantResponse: true)
let adminMessageId = bleManager.saveUser(config: u, fromUser: node.user!, toUser: node.user!, wantResponse: true)
if adminMessageId > 0 {