mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Add table to device metrics, add snr to position and message
This commit is contained in:
parent
8c76e14196
commit
1b5b146334
5 changed files with 89 additions and 59 deletions
|
|
@ -69,7 +69,7 @@ func PositionToCsvFile(positions: [PositionEntity]) -> String {
|
|||
var csvString: String = ""
|
||||
|
||||
// Create Position Header
|
||||
csvString = "SeqNo, Latitude, Longitude, Alt, Sats, Speed, Heading, Timestamp"
|
||||
csvString = "SeqNo, Latitude, Longitude, Alt, Sats, Speed, Heading, SNR, Timestamp"
|
||||
|
||||
for pos in positions {
|
||||
|
||||
|
|
@ -88,6 +88,8 @@ func PositionToCsvFile(positions: [PositionEntity]) -> String {
|
|||
csvString += ", "
|
||||
csvString += String(pos.heading)
|
||||
csvString += ", "
|
||||
csvString += String(pos.snr)
|
||||
csvString += ", "
|
||||
|
||||
csvString += pos.time?.formattedDate(format: "yyyy-MM-dd HH:mm:ss") ?? "Unknown Age"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1069,6 +1069,7 @@ func positionPacket (packet: MeshPacket, context: NSManagedObjectContext) {
|
|||
|
||||
let position = PositionEntity(context: context)
|
||||
|
||||
position.snr = packet.rxSnr
|
||||
position.seqNo = Int32(positionMessage.seqNumber)
|
||||
position.latitudeI = positionMessage.latitudeI
|
||||
position.longitudeI = positionMessage.longitudeI
|
||||
|
|
@ -1266,8 +1267,6 @@ func telemetryPacket(packet: MeshPacket, context: NSManagedObjectContext) {
|
|||
}
|
||||
|
||||
func textMessageAppPacket(packet: MeshPacket, connectedNode: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
let broadcastNodeNum: UInt32 = 4294967295
|
||||
|
||||
if let messageText = String(bytes: packet.decoded.payload, encoding: .utf8) {
|
||||
|
||||
|
|
@ -1282,6 +1281,7 @@ func textMessageAppPacket(packet: MeshPacket, connectedNode: Int64, context: NSM
|
|||
newMessage.messageId = Int64(packet.id)
|
||||
newMessage.messageTimestamp = Int32(bitPattern: packet.rxTime)
|
||||
newMessage.receivedACK = false
|
||||
newMessage.snr = packet.rxSnr
|
||||
newMessage.isEmoji = packet.decoded.emoji == 1
|
||||
newMessage.channel = Int32(packet.channel)
|
||||
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@
|
|||
<attribute name="messageTimestamp" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="receivedACK" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="replyID" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="snr" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<relationship name="fromUser" optional="YES" maxCount="1" deletionRule="Nullify" ordered="YES" destinationEntity="UserEntity" inverseName="sentMessages" inverseEntity="UserEntity"/>
|
||||
<relationship name="toUser" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="UserEntity" inverseName="receivedMessages" inverseEntity="UserEntity"/>
|
||||
<fetchedProperty name="tapbacks" optional="YES">
|
||||
|
|
@ -182,6 +183,7 @@
|
|||
<attribute name="longitudeI" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="satsInView" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="seqNo" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="snr" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="speed" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="time" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<relationship name="nodePosition" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="positions" inverseEntity="NodeInfoEntity"/>
|
||||
|
|
|
|||
|
|
@ -28,19 +28,11 @@ struct DeviceMetricsLog: View {
|
|||
}
|
||||
|
||||
var body: some View {
|
||||
|
||||
NavigationStack {
|
||||
|
||||
let oneDayAgo = Calendar.current.date(byAdding: .day, value: -3, to: Date())
|
||||
|
||||
let data = node.telemetries!.filtered(using: NSPredicate(format: "metricsType == 0 && time !=nil && time >= %@", oneDayAgo! as CVarArg))
|
||||
|
||||
if data.count > 0 {
|
||||
|
||||
#if canImport(Charts)
|
||||
|
||||
GroupBox(label: Label("Battery Level Trend", systemImage: "battery.100")) {
|
||||
|
||||
Chart(data.array as! [TelemetryEntity], id: \.self) {
|
||||
LineMark(
|
||||
x: .value("Hour", $0.time!.formattedDate(format: "ha")),
|
||||
|
|
@ -53,64 +45,95 @@ struct DeviceMetricsLog: View {
|
|||
}
|
||||
.frame(height: 150)
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
|
||||
Grid(alignment: .topLeading, horizontalSpacing: 2) {
|
||||
if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac {
|
||||
//Add a table for mac and ipad
|
||||
Table(node.telemetries!.reversed() as! [TelemetryEntity]) {
|
||||
|
||||
GridRow {
|
||||
|
||||
Text("Batt")
|
||||
.font(.callout)
|
||||
.fontWeight(.bold)
|
||||
Text("Voltage")
|
||||
.font(.callout)
|
||||
.fontWeight(.bold)
|
||||
Text("ChUtil")
|
||||
.font(.callout)
|
||||
.fontWeight(.bold)
|
||||
Text("AirTm")
|
||||
.font(.callout)
|
||||
.fontWeight(.bold)
|
||||
Text("Timestamp")
|
||||
.font(.callout)
|
||||
.fontWeight(.bold)
|
||||
}
|
||||
Divider()
|
||||
ForEach(node.telemetries!.reversed() as! [TelemetryEntity], id: \.self) { (dm: TelemetryEntity) in
|
||||
TableColumn("Battery Level") { dm in
|
||||
|
||||
if dm.metricsType == 0 {
|
||||
|
||||
GridRow {
|
||||
if dm.batteryLevel == 0 {
|
||||
|
||||
if dm.batteryLevel == 0 {
|
||||
|
||||
Text("USB")
|
||||
.font(.callout)
|
||||
|
||||
} else {
|
||||
|
||||
Text("\(String(dm.batteryLevel))%")
|
||||
.font(.callout)
|
||||
}
|
||||
Text("Powered")
|
||||
|
||||
Text(String(dm.voltage))
|
||||
.font(.callout)
|
||||
Text("\(String(format: "%.2f", dm.channelUtilization))%")
|
||||
.font(.callout)
|
||||
Text("\(String(format: "%.2f", dm.airUtilTx))%")
|
||||
.font(.callout)
|
||||
Text(dm.time?.formattedDate(format: "MM/dd/yy hh:mm") ?? "Unknown time")
|
||||
.font(.callout)
|
||||
} else {
|
||||
|
||||
Text("\(String(dm.batteryLevel))%")
|
||||
}
|
||||
}
|
||||
}
|
||||
TableColumn("Voltage") { dm in
|
||||
Text(String(format: "%.6f", dm.voltage ?? 0))
|
||||
}
|
||||
TableColumn("Channel Utilization") { dm in
|
||||
Text(String(format: "%.2f", dm.channelUtilization))
|
||||
}
|
||||
TableColumn("Airtime") { dm in
|
||||
Text("\(String(format: "%.2f", dm.airUtilTx))%")
|
||||
}
|
||||
TableColumn("Time Stamp") { dm in
|
||||
Text(dm.time?.formattedDate(format: "MM/dd/yy hh:mm") ?? "Unknown time")
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
ScrollView {
|
||||
|
||||
Grid(alignment: .topLeading, horizontalSpacing: 2) {
|
||||
|
||||
GridRow {
|
||||
|
||||
Text("Batt")
|
||||
.font(.callout)
|
||||
.fontWeight(.bold)
|
||||
Text("Voltage")
|
||||
.font(.callout)
|
||||
.fontWeight(.bold)
|
||||
Text("ChUtil")
|
||||
.font(.callout)
|
||||
.fontWeight(.bold)
|
||||
Text("AirTm")
|
||||
.font(.callout)
|
||||
.fontWeight(.bold)
|
||||
Text("Timestamp")
|
||||
.font(.callout)
|
||||
.fontWeight(.bold)
|
||||
}
|
||||
Divider()
|
||||
ForEach(node.telemetries!.reversed() as! [TelemetryEntity], id: \.self) { (dm: TelemetryEntity) in
|
||||
|
||||
if dm.metricsType == 0 {
|
||||
|
||||
GridRow {
|
||||
|
||||
if dm.batteryLevel == 0 {
|
||||
|
||||
Text("USB")
|
||||
.font(.callout)
|
||||
|
||||
} else {
|
||||
|
||||
Text("\(String(dm.batteryLevel))%")
|
||||
.font(.callout)
|
||||
}
|
||||
|
||||
Text(String(dm.voltage))
|
||||
.font(.callout)
|
||||
Text("\(String(format: "%.2f", dm.channelUtilization))%")
|
||||
.font(.callout)
|
||||
Text("\(String(format: "%.2f", dm.airUtilTx))%")
|
||||
.font(.callout)
|
||||
Text(dm.time?.formattedDate(format: "MM/dd/yy hh:mm") ?? "Unknown time")
|
||||
.font(.callout)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.leading, 15)
|
||||
.padding(.trailing, 5)
|
||||
}
|
||||
.padding(.leading, 15)
|
||||
.padding(.trailing, 5)
|
||||
}
|
||||
}
|
||||
HStack {
|
||||
|
|
|
|||
|
|
@ -46,6 +46,9 @@ struct PositionLog: View {
|
|||
TableColumn("Heading") { position in
|
||||
Text(String(position.heading))
|
||||
}
|
||||
TableColumn("SNR") { position in
|
||||
Text(String(position.snr))
|
||||
}
|
||||
TableColumn("Time Stamp") { position in
|
||||
Text(position.time?.formattedDate(format: "MM/dd/yy hh:mm") ?? "Unknown time")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue