Display time only from mesh, remove all times set in the iOS app.

Add Bitrate
Format assorted things.
Fix battery display on node details
make node list more friendly on iPad and mac
This commit is contained in:
Garth Vander Houwen 2022-05-25 22:30:48 -07:00
parent e629e302d6
commit 233fb0a1e0
7 changed files with 78 additions and 43 deletions

View file

@ -55,6 +55,7 @@
DDC2E17A26CE248F0042C5E4 /* MeshtasticClientUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E17926CE248F0042C5E4 /* MeshtasticClientUITests.swift */; };
DDC2E18F26CE25FE0042C5E4 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E18E26CE25FE0042C5E4 /* ContentView.swift */; };
DDC2E1A726CEB3400042C5E4 /* LocationHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E1A626CEB3400042C5E4 /* LocationHelper.swift */; };
DDC3B274283F411B00AC321C /* LastHeardText.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC3B273283F411B00AC321C /* LastHeardText.swift */; };
DDC4D568275499A500A4208E /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC4D567275499A500A4208E /* Persistence.swift */; };
DDCA31322826009C00207175 /* PassKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDCA31312826009C00207175 /* PassKit.framework */; };
DDF924CA26FBB953009FE055 /* ConnectedDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF924C926FBB953009FE055 /* ConnectedDevice.swift */; };
@ -133,6 +134,7 @@
DDC2E17B26CE248F0042C5E4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
DDC2E18E26CE25FE0042C5E4 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
DDC2E1A626CEB3400042C5E4 /* LocationHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationHelper.swift; sourceTree = "<group>"; };
DDC3B273283F411B00AC321C /* LastHeardText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LastHeardText.swift; sourceTree = "<group>"; };
DDC4D567275499A500A4208E /* Persistence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = "<group>"; };
DDCA31312826009C00207175 /* PassKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PassKit.framework; path = System/Library/Frameworks/PassKit.framework; sourceTree = SDKROOT; };
DDF924C926FBB953009FE055 /* ConnectedDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectedDevice.swift; sourceTree = "<group>"; };
@ -356,6 +358,7 @@
DD47E3D826F3093800029299 /* MessageBubble.swift */,
DD90860B26F684AF00DC5189 /* BatteryIcon.swift */,
DDF924C926FBB953009FE055 /* ConnectedDevice.swift */,
DDC3B273283F411B00AC321C /* LastHeardText.swift */,
);
path = Helpers;
sourceTree = "<group>";
@ -574,6 +577,7 @@
C9483F6D2773017500998F6B /* MapView.swift in Sources */,
DDAF8C5826ED07FD0058C060 /* mesh.pb.swift in Sources */,
DD8169FB271F1F3A00F4AB02 /* MeshLog.swift in Sources */,
DDC3B274283F411B00AC321C /* LastHeardText.swift in Sources */,
DD2E65262767A01F00E45FC5 /* NodeDetail.swift in Sources */,
C9A88B57278B559900BD810A /* apponly.pb.swift in Sources */,
DD4C158E2824AA7E0032668E /* config.pb.swift in Sources */,

View file

@ -176,7 +176,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
peripheralName = name
}
let newPeripheral = Peripheral(id: peripheral.identifier.uuidString, num: 0, name: peripheralName, shortName: String(peripheralName.suffix(3)), longName: peripheralName, firmwareVersion: "Unknown", rssi: RSSI.intValue, channelUtilization: nil, airTime: nil, lastUpdate: Date(), subscribed: false, peripheral: peripheral)
let newPeripheral = Peripheral(id: peripheral.identifier.uuidString, num: 0, name: peripheralName, shortName: String(peripheralName.suffix(3)), longName: peripheralName, firmwareVersion: "Unknown", rssi: RSSI.intValue, bitrate: nil, channelUtilization: nil, airTime: nil, lastUpdate: Date(), subscribed: false, peripheral: peripheral)
let peripheralIndex = peripherals.firstIndex(where: { $0.id == newPeripheral.id })
if peripheralIndex != nil && newPeripheral.peripheral.state != CBPeripheralState.connected {
@ -407,6 +407,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
myInfo.myNodeNum = Int64(decodedInfo.myInfo.myNodeNum)
myInfo.hasGps = decodedInfo.myInfo.hasGps_p
myInfo.bitrate = decodedInfo.myInfo.bitrate
self.connectedPeripheral.bitrate = myInfo.bitrate
// Swift does strings weird, this does work to get the version without the github hash
let lastDotIndex = decodedInfo.myInfo.firmwareVersion.lastIndex(of: ".")
@ -460,6 +461,8 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
fetchedMyInfo[0].myNodeNum = Int64(decodedInfo.myInfo.myNodeNum)
fetchedMyInfo[0].hasGps = decodedInfo.myInfo.hasGps_p
fetchedMyInfo[0].bitrate = decodedInfo.myInfo.bitrate
let lastDotIndex = decodedInfo.myInfo.firmwareVersion.lastIndex(of: ".")//.lastIndex(of: ".", offsetBy: -1)
var version = decodedInfo.myInfo.firmwareVersion[...(lastDotIndex ?? String.Index(utf16Offset:6, in: decodedInfo.myInfo.firmwareVersion))]
version = version.dropLast()
@ -471,6 +474,8 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
self.connectedPeripheral.num = fetchedMyInfo[0].myNodeNum
self.connectedPeripheral.firmwareVersion = fetchedMyInfo[0].firmwareVersion ?? "Unknown"
self.connectedPeripheral.name = fetchedMyInfo[0].bleName ?? "Unknown"
self.connectedPeripheral.bitrate = fetchedMyInfo[0].bitrate
}
do {
@ -812,7 +817,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
// MARK: Incoming Packet from the POSITION_APP
} else if decodedInfo.packet.decoded.portnum == PortNum.positionApp {
let fetchNodePositionRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "NodeInfoEntity")
fetchNodePositionRequest.predicate = NSPredicate(format: "num == %lld", Int64(decodedInfo.packet.from))

View file

@ -9,13 +9,14 @@ struct Peripheral: Identifiable {
var longName: String
var firmwareVersion: String
var rssi: Int
var bitrate: Float?
var channelUtilization: Float?
var airTime: Float?
var lastUpdate: Date
var subscribed: Bool
var peripheral: CBPeripheral
init(id: String, num: Int64, name: String, shortName: String, longName: String, firmwareVersion: String, rssi: Int, channelUtilization: Float?, airTime: Float?, lastUpdate: Date, subscribed: Bool, peripheral: CBPeripheral) {
init(id: String, num: Int64, name: String, shortName: String, longName: String, firmwareVersion: String, rssi: Int, bitrate: Float?, channelUtilization: Float?, airTime: Float?, lastUpdate: Date, subscribed: Bool, peripheral: CBPeripheral) {
self.id = id
self.num = num
self.name = name
@ -23,6 +24,7 @@ struct Peripheral: Identifiable {
self.longName = longName
self.firmwareVersion = firmwareVersion
self.rssi = rssi
self.bitrate = bitrate
self.channelUtilization = channelUtilization
self.airTime = airTime
self.lastUpdate = lastUpdate

View file

@ -74,9 +74,13 @@ struct Connect: View {
if bleManager.connectedPeripheral != nil {
Text("FW Version: ").font(.caption)+Text(bleManager.connectedPeripheral.firmwareVersion)
.font(.caption).foregroundColor(Color.gray)
Text("Channel Utilization: ").font(.caption)+Text(String(bleManager.connectedPeripheral.channelUtilization ?? 0.00))
Text("Bitrate: ").font(.caption)+Text(String(format: "%.2f", bleManager.connectedPeripheral.bitrate ?? 0.00))
.font(.caption).foregroundColor(Color.gray)
Text("Air Time: ").font(.caption)+Text(String(bleManager.connectedPeripheral.airTime ?? 0.00))
Text("Channel Utilization: ").font(.caption)+Text(String(format: "%.2f", bleManager.connectedPeripheral.channelUtilization ?? 0.00))
.font(.caption).foregroundColor(Color.gray)
Text("Air Time: ").font(.caption)+Text(String(format: "%.2f", bleManager.connectedPeripheral.airTime ?? 0.00))
.font(.caption).foregroundColor(Color.gray)
}
if bleManager.connectedPeripheral.subscribed {

View file

@ -0,0 +1,22 @@
import SwiftUI
//
// LastHeardText.swift
// Meshtastic Apple
//
// Created by Garth Vander Houwen on 5/25/22.
//
struct LastHeardText: View {
var lastHeard: Date?
let sixMonthsAgo = Calendar.current.date(byAdding: .month, value: -6, to: Date())
var body: some View {
if (lastHeard != nil && lastHeard! >= sixMonthsAgo!){
Text("Last Heard: \(lastHeard!, style: .relative) ago")
} else {
Text("Last Heard: Unknown Age")
}
}
}

View file

@ -65,19 +65,19 @@ struct NodeDetail: View {
ScrollView {
if node.lastHeard != nil {
HStack {
HStack {
Image(systemName: "clock.badge.checkmark.fill")
.font(.title)
.foregroundColor(.accentColor)
.symbolRenderingMode(.hierarchical)
Text("Last Heard: \(node.lastHeard!, style: .relative) ago").font(.title3)
}
.padding()
Divider()
Image(systemName: "clock.badge.checkmark.fill")
.font(.title)
.foregroundColor(.accentColor)
.symbolRenderingMode(.hierarchical)
LastHeardText(lastHeard: node.lastHeard).font(.title3)
}
.padding()
Divider()
HStack {
@ -133,6 +133,15 @@ struct NodeDetail: View {
BatteryIcon(batteryLevel: mostRecent.batteryLevel, font: .title, color: .accentColor)
.padding(.bottom)
Text(String(mostRecent.batteryLevel) + "%")
.font(.title3)
.foregroundColor(.gray)
.fixedSize()
Text(String(format: "%.2f", mostRecent.voltage) + " V")
.font(.title3)
.foregroundColor(.gray)
.fixedSize()
}
.padding(5)
@ -194,6 +203,10 @@ struct NodeDetail: View {
Divider()
ForEach(node.positions!.array as! [PositionEntity], id: \.self) { (mappin: PositionEntity) in
if mappin.coordinate != nil {
}
}
// ForEach(node.positions!.array as! [PositionEntity], id: \.self) { (mappin: PositionEntity) in

View file

@ -65,11 +65,18 @@ struct NodeList: View {
.padding(.bottom, 10)
if connected {
HStack(alignment: .bottom) {
Image(systemName: "repeat.circle.fill").font(.title3)
.foregroundColor(.accentColor).symbolRenderingMode(.hierarchical)
Text("Currently Connected").font(.title3).foregroundColor(Color.accentColor)
if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac {
Text("Currently Connected").font(.headline).foregroundColor(Color.accentColor)
} else {
Text("Currently Connected").font(.title3).foregroundColor(Color.accentColor)
}
}
Spacer()
}
@ -77,44 +84,23 @@ struct NodeList: View {
HStack(alignment: .bottom) {
Image(systemName: "clock.badge.checkmark.fill").font(.title3).foregroundColor(.accentColor).symbolRenderingMode(.hierarchical)
if node.lastHeard != nil {
Text("Last Heard: \(node.lastHeard!, style: .relative) ago").font(.subheadline).foregroundColor(.gray)
if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac {
LastHeardText(lastHeard: node.lastHeard).font(.subheadline).foregroundColor(.gray)
} else {
Text("Last Heard: Unknown").font(.subheadline).foregroundColor(.gray)
LastHeardText(lastHeard: node.lastHeard).font(.title3).foregroundColor(.gray)
}
}
}
.padding([.leading, .top, .bottom])
}
// .swipeActions {
//
// Button {
//
// context.delete(node)
//
// do {
//
// try context.save()
// print("Successfully Deleted NodeInfoEntiy: \(node.num)")
//
// } catch {
//
// print("Failed to save context after deleting NodeInfoEntity Num: \(node.num)")
// }
//
// } label: {
//
// Label("Delete from app", systemImage: "trash")
// }
// .tint(.red)
// }
}
}
}
.navigationTitle("All Nodes")
.onAppear {
// self.nodes.returnsObjectsAsFaults = false
self.bleManager.context = context
self.bleManager.userSettings = userSettings