Merge pull request #923 from meshtastic/live-activity-cleanup

Live activity cleanup
This commit is contained in:
Garth Vander Houwen 2024-09-11 08:25:56 -07:00 committed by GitHub
commit 7896dceeff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 80 additions and 58 deletions

View file

@ -1429,8 +1429,15 @@
"Bad" : {
},
"Bad Packets: %d" : {
"Bad Packets: %d %@%%" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Bad Packets: %1$d %2$@%%"
}
}
}
},
"Bandwidth" : {
@ -16079,11 +16086,15 @@
"Override automatic OLED screen detection." : {
},
"Packets Received: %d" : {
},
"Packets Sent: %d" : {
"Packets: Sent: %d Received: %d" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Packets: Sent: %1$d Received: %2$d"
}
}
}
},
"password" : {
"localizations" : {
@ -22314,6 +22325,9 @@
}
}
}
},
"Uptime: %@" : {
},
"Use a PWM output (like the RAK Buzzer) for tunes instead of an on/off output. This will ignore the output, output duration and active settings and use the device config buzzer GPIO option instead." : {

View file

@ -864,8 +864,10 @@ func textMessageAppPacket(
newMessage.isEmoji = packet.decoded.emoji == 1
newMessage.channel = Int32(packet.channel)
newMessage.portNum = Int32(packet.decoded.portnum.rawValue)
newMessage.publicKey = packet.publicKey
newMessage.pkiEncrypted = packet.pkiEncrypted
if newMessage.toUser?.pkiEncrypted ?? false {
newMessage.pkiEncrypted = true
newMessage.publicKey = packet.publicKey
}
if packet.decoded.portnum == PortNum.detectionSensorApp {
if !UserDefaults.enableDetectionNotifications {
newMessage.read = true
@ -889,9 +891,11 @@ func textMessageAppPacket(
newMessage.fromUser?.newPublicKey = newMessage.publicKey
}
} else {
/// We have no key, set it
newMessage.fromUser?.publicKey = packet.publicKey
newMessage.fromUser?.pkiEncrypted = packet.pkiEncrypted
/// We have no key, set it if it is not empty
if !packet.publicKey.isEmpty {
newMessage.fromUser?.pkiEncrypted = true
newMessage.fromUser?.publicKey = packet.publicKey
}
}
if packet.rxTime > 0 {
newMessage.fromUser?.userNode?.lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(packet.rxTime)))

View file

@ -181,8 +181,11 @@ func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext)
newUser.role = Int32(newUserMessage.role.rawValue)
newUser.hwModel = String(describing: newUserMessage.hwModel).uppercased()
newUser.hwModelId = Int32(newUserMessage.hwModel.rawValue)
newUser.pkiEncrypted = packet.pkiEncrypted
newUser.publicKey = packet.publicKey
if !newUserMessage.publicKey.isEmpty {
newUser.pkiEncrypted = true
newUser.publicKey = newUserMessage.publicKey
}
Task {
Api().loadDeviceHardwareData { (hw) in
let dh = hw.first(where: { $0.hwModel == newUser.hwModelId })
@ -209,8 +212,10 @@ func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext)
} else {
if packet.from > Constants.minimumNodeNum {
let newUser = createUser(num: Int64(packet.from), context: context)
newNode.user?.pkiEncrypted = packet.pkiEncrypted
newNode.user?.publicKey = packet.publicKey
if !packet.publicKey.isEmpty {
newNode.user?.pkiEncrypted = true
newNode.user?.publicKey = packet.publicKey
}
newNode.user = newUser
}
}
@ -224,6 +229,7 @@ func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext)
myInfoEntity.rebootCount = 0
do {
try context.save()
Logger.data.info("💾 [NodeInfo] Saved a NodeInfo for node number: \(packet.from.toHex(), privacy: .public)")
Logger.data.info("💾 [MyInfoEntity] Saved a new myInfo for node number: \(packet.from.toHex(), privacy: .public)")
} catch {
context.rollback()
@ -271,10 +277,9 @@ func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext)
fetchedNode[0].user!.role = Int32(nodeInfoMessage.user.role.rawValue)
fetchedNode[0].user!.hwModel = String(describing: nodeInfoMessage.user.hwModel).uppercased()
fetchedNode[0].user!.hwModelId = Int32(nodeInfoMessage.user.hwModel.rawValue)
if !packet.publicKey.isEmpty {
fetchedNode[0].user!.pkiEncrypted = packet.pkiEncrypted
fetchedNode[0].user!.publicKey = packet.publicKey
if !nodeInfoMessage.user.publicKey.isEmpty {
fetchedNode[0].user!.pkiEncrypted = true
fetchedNode[0].user!.publicKey = nodeInfoMessage.user.publicKey
}
Task {
Api().loadDeviceHardwareData { (hw) in

View file

@ -92,6 +92,7 @@ struct Connect: View {
}
VStack {
let localStats = node?.telemetries?.filtered(using: NSPredicate(format: "metricsType == 6")).lastObject as? TelemetryEntity
if localStats != nil {
Divider()
if localStats?.numTotalNodes ?? 0 >= 100 {
@ -111,25 +112,29 @@ struct Connect: View {
.font(.caption)
.fontWeight(.medium)
.foregroundStyle(.secondary)
Text("Packets Sent: \(localStats?.numPacketsTx ?? 0)")
Text("Packets: Sent: \(localStats?.numPacketsTx ?? 0) Received: \(localStats?.numPacketsRx ?? 0)")
.font(.caption)
.fontWeight(.medium)
.foregroundStyle(.secondary)
Text("Packets Received: \(localStats?.numPacketsRx ?? 0)")
.font(.caption)
.fontWeight(.medium)
.foregroundStyle(.secondary)
Text("Bad Packets: \(localStats?.numPacketsRxBad ?? 0)")
let errorRate = (Double(localStats?.numPacketsRxBad ?? -1) / Double(localStats?.numPacketsRx ?? -1)) * 100
Text("Bad Packets: \(localStats?.numPacketsRxBad ?? 0) \(String(format: "Error Rate: %.2f", errorRate))%")
.font(.caption)
.fontWeight(.medium)
.foregroundStyle(.secondary)
.fixedSize()
let now = Date.now
let later = now + TimeInterval(Double(localStats?.numPacketsRxBad ?? 0))
let uptime = (now..<later).formatted(.components(style: .narrow))
Text("Uptime: \(uptime)")
.font(.caption)
.fontWeight(.medium)
.foregroundStyle(.secondary)
}
}
}
.font(.caption)
.foregroundColor(Color.gray)
.padding([.top, .bottom])
.padding([.top])
.swipeActions {
Button(role: .destructive) {
if let connectedPeripheral = bleManager.connectedPeripheral,

View file

@ -38,7 +38,7 @@ struct WidgetsLiveActivity: Widget {
.fixedSize()
Spacer()
}
if context.state.nodesOnline >= 100 {
if context.state.totalNodes >= 100 {
Text("100+ online")
.font(.caption)
.foregroundStyle(.secondary)
@ -81,7 +81,7 @@ struct WidgetsLiveActivity: Widget {
.font(.caption)
.foregroundStyle(.secondary)
.fixedSize()
Text("Bad \(context.state.badReceivedPackets)")
Text("Bad: \(context.state.badReceivedPackets)")
.font(.caption)
.foregroundStyle(.secondary)
.fixedSize()
@ -97,7 +97,7 @@ struct WidgetsLiveActivity: Widget {
} compactLeading: {
Image("m-logo-black")
.resizable()
.frame(width: 30.0)
.frame(width: 25)
.padding(4)
.background(.green.gradient, in: ContainerRelativeShape())
} compactTrailing: {
@ -120,26 +120,25 @@ struct WidgetsLiveActivity: Widget {
}
}
//struct WidgetsLiveActivity_Previews: PreviewProvider {
// static let attributes = MeshActivityAttributes(nodeNum: 123456789, name: "RAK Compact Rotary Handset Gray 8E6G")
// static let state = MeshActivityAttributes.ContentState(
// timerRange: Date.now...Date(timeIntervalSinceNow: 60), connected: true, channelUtilization: 25.84, airtime: 10.01, batteryLevel: 39, nodes: 17, nodesOnline: 9)
//
// static var previews: some View {
// attributes
// .previewContext(state, viewKind: .dynamicIsland(.compact))
// .previewDisplayName("Compact")
// attributes
// .previewContext(state, viewKind: .dynamicIsland(.minimal))
// .previewDisplayName("Minimal")
// attributes
// .previewContext(state, viewKind: .dynamicIsland(.expanded))
// .previewDisplayName("Expanded")
// attributes
// .previewContext(state, viewKind: .content)
// .previewDisplayName("Notification")
// }
//}
struct WidgetsLiveActivity_Previews: PreviewProvider {
static let attributes = MeshActivityAttributes(nodeNum: 123456789, name: "RAK Compact Rotary Handset Gray 8E6G")
static let state = MeshActivityAttributes.ContentState(uptimeSeconds: 600, channelUtilization: 1.2, airtime: 3.5, sentPackets: 12587, receivedPackets: 12555, badReceivedPackets: 800, nodesOnline: 99, totalNodes: 100, timerRange: Date.now...Date(timeIntervalSinceNow: 300))
static var previews: some View {
attributes
.previewContext(state, viewKind: .dynamicIsland(.compact))
.previewDisplayName("Compact")
attributes
.previewContext(state, viewKind: .dynamicIsland(.minimal))
.previewDisplayName("Minimal")
attributes
.previewContext(state, viewKind: .dynamicIsland(.expanded))
.previewDisplayName("Expanded")
attributes
.previewContext(state, viewKind: .content)
.previewDisplayName("Notification")
}
}
struct LiveActivityView: View {
@Environment(\.colorScheme) private var colorScheme
@ -192,6 +191,7 @@ struct NodeInfoView: View {
var timerRange: ClosedRange<Date>
var body: some View {
let errorRate = (Double(badReceivedPackets) / Double(receivedPackets)) * 100
VStack(alignment: .leading, spacing: 0) {
Text(nodeName)
.font(nodeName.count > 14 ? .callout : .title3)
@ -203,19 +203,13 @@ struct NodeInfoView: View {
.foregroundStyle(.secondary)
.opacity(isLuminanceReduced ? 0.8 : 1.0)
.fixedSize()
Text("Packets Sent: \(sentPackets)")
Text("Packets: Sent \(sentPackets) Rec. \(receivedPackets)")
.font(.caption)
.fontWeight(.medium)
.foregroundStyle(.secondary)
.opacity(isLuminanceReduced ? 0.8 : 1.0)
.fixedSize()
Text("Packets Received: \(receivedPackets)")
.font(.caption)
.fontWeight(.medium)
.foregroundStyle(.secondary)
.opacity(isLuminanceReduced ? 0.8 : 1.0)
.fixedSize()
Text("Bad Packets: \(badReceivedPackets)")
Text("Bad: \(badReceivedPackets) \(String(format: "Error Rate: %.2f", errorRate))%")
.font(.caption)
.fontWeight(.medium)
.foregroundStyle(.secondary)