From e399a426ade66b0dc42ce95ed234332dfe474d3f Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sun, 3 Sep 2023 22:14:59 -0700 Subject: [PATCH] Only show logs when there is data. Move coredata extentions. Allow turning off of mqtt client proxy. Save unread message badges on configcomplete --- Meshtastic.xcodeproj/project.pbxproj | 24 ++++++++++++----- .../CoreData}/ChannelEntityExtension.swift | 0 .../CoreData}/MessageEntityExtension.swift | 0 .../CoreData}/MyInfoEntityExtension.swift | 0 .../CoreData/NodeInfoEntityExtension.swift | 27 +++++++++++++++++++ .../CoreData}/PositionEntityExtension.swift | 0 .../CoreData}/UserEntityExtension.swift | 0 .../CoreData}/WaypointEntityExtension.swift | 0 Meshtastic/Helpers/BLEManager.swift | 12 ++++++--- .../Views/Helpers/Node/NodeInfoView.swift | 17 +++++++----- Meshtastic/Views/Nodes/NodeDetail.swift | 4 +-- 11 files changed, 65 insertions(+), 19 deletions(-) rename Meshtastic/{Persistence => Extensions/CoreData}/ChannelEntityExtension.swift (100%) rename Meshtastic/{Persistence => Extensions/CoreData}/MessageEntityExtension.swift (100%) rename Meshtastic/{Persistence => Extensions/CoreData}/MyInfoEntityExtension.swift (100%) create mode 100644 Meshtastic/Extensions/CoreData/NodeInfoEntityExtension.swift rename Meshtastic/{Persistence => Extensions/CoreData}/PositionEntityExtension.swift (100%) rename Meshtastic/{Persistence => Extensions/CoreData}/UserEntityExtension.swift (100%) rename Meshtastic/{Persistence => Extensions/CoreData}/WaypointEntityExtension.swift (100%) diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index fe9506d9..765de0df 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ C9697F9D279336B700250207 /* LocalMBTileOverlay.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9697F9C279336B700250207 /* LocalMBTileOverlay.swift */; }; C9697FA527933B8C00250207 /* SQLite in Frameworks */ = {isa = PBXBuildFile; productRef = C9697FA427933B8C00250207 /* SQLite */; }; DD007BAE2AA4E91200F5FA12 /* MyInfoEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD007BAD2AA4E91200F5FA12 /* MyInfoEntityExtension.swift */; }; + DD007BB02AA5981000F5FA12 /* NodeInfoEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD007BAF2AA5981000F5FA12 /* NodeInfoEntityExtension.swift */; }; DD0D3D222A55CEB10066DB71 /* CocoaMQTT in Frameworks */ = {isa = PBXBuildFile; productRef = DD0D3D212A55CEB10066DB71 /* CocoaMQTT */; }; DD0F791B28713C8A00A6FDAD /* AdminMessageList.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD0F791A28713C8A00A6FDAD /* AdminMessageList.swift */; }; DD14E72E2A82A614006E39BC /* RemoteHardware.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD14E72D2A82A614006E39BC /* RemoteHardware.swift */; }; @@ -209,6 +210,7 @@ A65FA974296876BF00A97686 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; C9697F9C279336B700250207 /* LocalMBTileOverlay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalMBTileOverlay.swift; sourceTree = ""; }; DD007BAD2AA4E91200F5FA12 /* MyInfoEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyInfoEntityExtension.swift; sourceTree = ""; }; + DD007BAF2AA5981000F5FA12 /* NodeInfoEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeInfoEntityExtension.swift; sourceTree = ""; }; DD0E9C222A30CE3A00580CBB /* MeshtasticDataModelV14.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV14.xcdatamodel; sourceTree = ""; }; DD0F791A28713C8A00A6FDAD /* AdminMessageList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdminMessageList.swift; sourceTree = ""; }; DD14E72C2A80738F006E39BC /* MeshtasticDataModelV15.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV15.xcdatamodel; sourceTree = ""; }; @@ -439,6 +441,20 @@ path = Custom; sourceTree = ""; }; + DD007BB12AA59B9A00F5FA12 /* CoreData */ = { + isa = PBXGroup; + children = ( + DD58C5F12919AD3C00D5BEFB /* ChannelEntityExtension.swift */, + 6DEDA55B2A9592F900321D2E /* MessageEntityExtension.swift */, + DD007BAD2AA4E91200F5FA12 /* MyInfoEntityExtension.swift */, + DD007BAF2AA5981000F5FA12 /* NodeInfoEntityExtension.swift */, + DD5394FD276BA0EF00AD86B1 /* PositionEntityExtension.swift */, + DDD9E4E3284B208E003777C5 /* UserEntityExtension.swift */, + DD964FC1297272AE007C176F /* WaypointEntityExtension.swift */, + ); + path = CoreData; + sourceTree = ""; + }; DD47E3CA26F0E50300029299 /* Nodes */ = { isa = PBXGroup; children = ( @@ -759,15 +775,9 @@ DDC4D5662754996200A4208E /* Persistence */ = { isa = PBXGroup; children = ( - DD58C5F12919AD3C00D5BEFB /* ChannelEntityExtension.swift */, - 6DEDA55B2A9592F900321D2E /* MessageEntityExtension.swift */, - DD007BAD2AA4E91200F5FA12 /* MyInfoEntityExtension.swift */, DDC4D567275499A500A4208E /* Persistence.swift */, - DD5394FD276BA0EF00AD86B1 /* PositionEntityExtension.swift */, DD964FC52975DBFD007C176F /* QueryCoreData.swift */, DD3CC6C128EB9D4900FA9159 /* UpdateCoreData.swift */, - DDD9E4E3284B208E003777C5 /* UserEntityExtension.swift */, - DD964FC1297272AE007C176F /* WaypointEntityExtension.swift */, ); path = Persistence; sourceTree = ""; @@ -783,6 +793,7 @@ DDDB443E29F79A9400EE2349 /* Extensions */ = { isa = PBXGroup; children = ( + DD007BB12AA59B9A00F5FA12 /* CoreData */, DDDB444529F8A96500EE2349 /* Character.swift */, DDDB444929F8AA3A00EE2349 /* CLLocationCoordinate2D.swift */, DDDB444B29F8AAA600EE2349 /* Color.swift */, @@ -1085,6 +1096,7 @@ DDB6ABE628B1406100384BA1 /* LoraConfigEnums.swift in Sources */, DDB8F4142A9EE5F000230ECE /* ChannelList.swift in Sources */, DDD43FE32A78C8900083A3E9 /* MqttClientProxyManager.swift in Sources */, + DD007BB02AA5981000F5FA12 /* NodeInfoEntityExtension.swift in Sources */, DDDB444629F8A96500EE2349 /* Character.swift in Sources */, DD23A50F26FD1B4400D9B90C /* PeripheralModel.swift in Sources */, DDB6ABDB28B0AC6000384BA1 /* DistanceText.swift in Sources */, diff --git a/Meshtastic/Persistence/ChannelEntityExtension.swift b/Meshtastic/Extensions/CoreData/ChannelEntityExtension.swift similarity index 100% rename from Meshtastic/Persistence/ChannelEntityExtension.swift rename to Meshtastic/Extensions/CoreData/ChannelEntityExtension.swift diff --git a/Meshtastic/Persistence/MessageEntityExtension.swift b/Meshtastic/Extensions/CoreData/MessageEntityExtension.swift similarity index 100% rename from Meshtastic/Persistence/MessageEntityExtension.swift rename to Meshtastic/Extensions/CoreData/MessageEntityExtension.swift diff --git a/Meshtastic/Persistence/MyInfoEntityExtension.swift b/Meshtastic/Extensions/CoreData/MyInfoEntityExtension.swift similarity index 100% rename from Meshtastic/Persistence/MyInfoEntityExtension.swift rename to Meshtastic/Extensions/CoreData/MyInfoEntityExtension.swift diff --git a/Meshtastic/Extensions/CoreData/NodeInfoEntityExtension.swift b/Meshtastic/Extensions/CoreData/NodeInfoEntityExtension.swift new file mode 100644 index 00000000..d24f69f1 --- /dev/null +++ b/Meshtastic/Extensions/CoreData/NodeInfoEntityExtension.swift @@ -0,0 +1,27 @@ +// +// NodeInfoEntityExtension.swift +// Meshtastic +// +// Copyright(c) Garth Vander Houwen 9/3/23. +// + +import Foundation + +extension NodeInfoEntity { + + var hasPositions: Bool { + return positions?.count ?? 0 > 0 + } + + var hasDeviceMetrics: Bool { + + let deviceMetrics = telemetries?.filter{ ($0 as AnyObject).metricsType == 0 } + return deviceMetrics?.count ?? 0 > 0 + } + + var hasEnvironmentMetrics: Bool { + + let environmentMetrics = telemetries?.filter{ ($0 as AnyObject).metricsType == 1 } + return environmentMetrics?.count ?? 0 > 0 + } +} diff --git a/Meshtastic/Persistence/PositionEntityExtension.swift b/Meshtastic/Extensions/CoreData/PositionEntityExtension.swift similarity index 100% rename from Meshtastic/Persistence/PositionEntityExtension.swift rename to Meshtastic/Extensions/CoreData/PositionEntityExtension.swift diff --git a/Meshtastic/Persistence/UserEntityExtension.swift b/Meshtastic/Extensions/CoreData/UserEntityExtension.swift similarity index 100% rename from Meshtastic/Persistence/UserEntityExtension.swift rename to Meshtastic/Extensions/CoreData/UserEntityExtension.swift diff --git a/Meshtastic/Persistence/WaypointEntityExtension.swift b/Meshtastic/Extensions/CoreData/WaypointEntityExtension.swift similarity index 100% rename from Meshtastic/Persistence/WaypointEntityExtension.swift rename to Meshtastic/Extensions/CoreData/WaypointEntityExtension.swift diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index 4e5db2f0..e3d3e43b 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -613,16 +613,20 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(connectedPeripheral.num)) do { let fetchedNodeInfo = try context?.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity] ?? [] - if fetchedNodeInfo.count == 1 && fetchedNodeInfo[0].mqttConfig != nil { + if fetchedNodeInfo.count == 1 { // Subscribe to Mqtt Client Proxy if enabled - if fetchedNodeInfo[0].mqttConfig?.enabled ?? false && fetchedNodeInfo[0].mqttConfig?.proxyToClientEnabled ?? false { + if fetchedNodeInfo[0].mqttConfig != nil && fetchedNodeInfo[0].mqttConfig?.enabled ?? false && fetchedNodeInfo[0].mqttConfig?.proxyToClientEnabled ?? false { mqttManager.connectFromConfigSettings(node: fetchedNodeInfo[0]) + } else { + if mqttProxyConnected { + mqttManager.mqttClientProxy?.disconnect() + } } // Set initial unread message badge states - var appState = AppState.shared + let appState = AppState.shared appState.unreadChannelMessages = fetchedNodeInfo[0].myInfo?.unreadMessages ?? 0 appState.unreadDirectMessages = fetchedNodeInfo[0].user?.unreadMessages ?? 0 - appState.connectedNode = fetchedNodeInfo[0] + //appState.connectedNode = fetchedNodeInfo[0] UIApplication.shared.applicationIconBadgeNumber = appState.unreadChannelMessages + appState.unreadDirectMessages } diff --git a/Meshtastic/Views/Helpers/Node/NodeInfoView.swift b/Meshtastic/Views/Helpers/Node/NodeInfoView.swift index 8e30b7ea..362de937 100644 --- a/Meshtastic/Views/Helpers/Node/NodeInfoView.swift +++ b/Meshtastic/Views/Helpers/Node/NodeInfoView.swift @@ -58,8 +58,9 @@ struct NodeInfoView: View { } Divider() } - let deviceMetrics = node.telemetries?.filtered(using: NSPredicate(format: "metricsType == 0")) - if deviceMetrics?.count ?? 0 >= 1 { + + if node.hasDeviceMetrics { + let deviceMetrics = node.telemetries?.filtered(using: NSPredicate(format: "metricsType == 0")) let mostRecent = deviceMetrics?.lastObject as? TelemetryEntity VStack(alignment: .center) { BatteryGauge(batteryLevel: Double(mostRecent?.batteryLevel ?? 0)) @@ -196,7 +197,7 @@ struct NodeInfoView: View { VStack { - if (node.positions?.count ?? 0) > 0 { + if node.hasPositions{ NavigationLink { PositionLog(node: node) @@ -213,20 +214,22 @@ struct NodeInfoView: View { Divider() } - if (node.telemetries?.count ?? 0) > 0 { - + if node.hasDeviceMetrics { + NavigationLink { DeviceMetricsLog(node: node) } label: { - + Image(systemName: "flipphone") .symbolRenderingMode(.hierarchical) .font(.title) - + Text("Device Metrics Log") .font(.title3) } Divider() + } + if node.hasEnvironmentMetrics { NavigationLink { EnvironmentMetricsLog(node: node) } label: { diff --git a/Meshtastic/Views/Nodes/NodeDetail.swift b/Meshtastic/Views/Nodes/NodeDetail.swift index 768f172f..6992dea3 100644 --- a/Meshtastic/Views/Nodes/NodeDetail.swift +++ b/Meshtastic/Views/Nodes/NodeDetail.swift @@ -55,7 +55,7 @@ struct NodeDetail: View { NavigationStack { GeometryReader { bounds in VStack { - if node.positions?.count ?? 0 > 0 { + if node.hasPositions { ZStack { let positionArray = node.positions?.array as? [PositionEntity] ?? [] let lastTenThousand = Array(positionArray.prefix(10000)) @@ -232,7 +232,7 @@ struct NodeDetail: View { .task(id: node.num) { if !loadedWeather { do { - if node.positions?.count ?? 0 > 0 { + if node.hasPositions { let mostRecent = node.positions?.lastObject as? PositionEntity let weather = try await WeatherService.shared.weather(for: mostRecent?.nodeLocation ?? CLLocation(latitude: LocationHelper.currentLocation.latitude, longitude: LocationHelper.currentLocation.longitude)) condition = weather.currentWeather.condition