diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index 163bbbc1..a77cef84 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -17,7 +17,6 @@ DD47E3DD26F390A000029299 /* MessageDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD47E3DC26F390A000029299 /* MessageDetail.swift */; }; DD47E3DF26F39D9F00029299 /* MyInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD47E3DE26F39D9F00029299 /* MyInfoModel.swift */; }; DD836AE726F6B38600ABCC23 /* Connect.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD836AE626F6B38600ABCC23 /* Connect.swift */; }; - DD836AEB26F7AF9000ABCC23 /* nodeinfomodel2.json in Resources */ = {isa = PBXBuildFile; fileRef = DD836AEA26F7AF9000ABCC23 /* nodeinfomodel2.json */; }; DD836AED26F858F900ABCC23 /* MeshData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD836AEC26F858F900ABCC23 /* MeshData.swift */; }; DD836AEF26F85D8D00ABCC23 /* NodeInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD836AEE26F85D8D00ABCC23 /* NodeInfoModel.swift */; }; DD836AF126F8613500ABCC23 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD836AF026F8613500ABCC23 /* Color.swift */; }; @@ -43,9 +42,9 @@ DDC2E18F26CE25FE0042C5E4 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E18E26CE25FE0042C5E4 /* ContentView.swift */; }; DDC2E19126CE26290042C5E4 /* Messages.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E19026CE26290042C5E4 /* Messages.swift */; }; DDC2E1A726CEB3400042C5E4 /* LocationHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E1A626CEB3400042C5E4 /* LocationHelper.swift */; }; - DDC2E1AB26DD89EC0042C5E4 /* packets.json in Resources */ = {isa = PBXBuildFile; fileRef = DDC2E1AA26DD89EC0042C5E4 /* packets.json */; }; DDF924C626FA2375009FE055 /* MessageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF924C526FA2375009FE055 /* MessageModel.swift */; }; DDF924C826FA5BAD009FE055 /* TabBarIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF924C726FA5BAD009FE055 /* TabBarIcon.swift */; }; + DDF924CA26FBB953009FE055 /* ConnectedDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDF924C926FBB953009FE055 /* ConnectedDevice.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -75,9 +74,7 @@ DD47E3DA26F3901A00029299 /* MessageList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageList.swift; sourceTree = ""; }; DD47E3DC26F390A000029299 /* MessageDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageDetail.swift; sourceTree = ""; }; DD47E3DE26F39D9F00029299 /* MyInfoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyInfoModel.swift; sourceTree = ""; }; - DD7AA3F426F05D660077AF76 /* nodeinfomodel.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = nodeinfomodel.json; sourceTree = ""; }; DD836AE626F6B38600ABCC23 /* Connect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Connect.swift; sourceTree = ""; }; - DD836AEA26F7AF9000ABCC23 /* nodeinfomodel2.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = nodeinfomodel2.json; sourceTree = ""; }; DD836AEC26F858F900ABCC23 /* MeshData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshData.swift; sourceTree = ""; }; DD836AEE26F85D8D00ABCC23 /* NodeInfoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeInfoModel.swift; sourceTree = ""; }; DD836AF026F8613500ABCC23 /* Color.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = ""; }; @@ -95,7 +92,6 @@ DDAF8C6826ED0D070058C060 /* deviceonly.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = deviceonly.pb.swift; sourceTree = ""; }; DDAF8C6A26ED0DD80058C060 /* environmental_measurement.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = environmental_measurement.pb.swift; sourceTree = ""; }; DDAF8C6D26ED19040058C060 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; - DDAF8C7126ED2AD80058C060 /* nodeinfo.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = nodeinfo.json; sourceTree = ""; }; DDC2E15426CE248E0042C5E4 /* MeshtasticClient.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MeshtasticClient.app; sourceTree = BUILT_PRODUCTS_DIR; }; DDC2E15726CE248E0042C5E4 /* MeshtasticClientApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshtasticClientApp.swift; sourceTree = ""; }; DDC2E15B26CE248F0042C5E4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; @@ -110,9 +106,9 @@ DDC2E18E26CE25FE0042C5E4 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; DDC2E19026CE26290042C5E4 /* Messages.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Messages.swift; sourceTree = ""; }; DDC2E1A626CEB3400042C5E4 /* LocationHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationHelper.swift; sourceTree = ""; }; - DDC2E1AA26DD89EC0042C5E4 /* packets.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = packets.json; sourceTree = ""; }; DDF924C526FA2375009FE055 /* MessageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageModel.swift; sourceTree = ""; }; DDF924C726FA5BAD009FE055 /* TabBarIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarIcon.swift; sourceTree = ""; }; + DDF924C926FBB953009FE055 /* ConnectedDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectedDevice.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -274,10 +270,6 @@ DDC2E18926CE24F70042C5E4 /* Resources */ = { isa = PBXGroup; children = ( - DD836AEA26F7AF9000ABCC23 /* nodeinfomodel2.json */, - DDC2E1AA26DD89EC0042C5E4 /* packets.json */, - DDAF8C7126ED2AD80058C060 /* nodeinfo.json */, - DD7AA3F426F05D660077AF76 /* nodeinfomodel.json */, ); path = Resources; sourceTree = ""; @@ -299,6 +291,7 @@ DD47E3D826F3093800029299 /* MessageBubble.swift */, DD90860B26F684AF00DC5189 /* BatteryIcon.swift */, DDF924C726FA5BAD009FE055 /* TabBarIcon.swift */, + DDF924C926FBB953009FE055 /* ConnectedDevice.swift */, ); path = Helpers; sourceTree = ""; @@ -423,10 +416,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - DD836AEB26F7AF9000ABCC23 /* nodeinfomodel2.json in Resources */, DDC2E15F26CE248F0042C5E4 /* Preview Assets.xcassets in Resources */, DDC2E15C26CE248F0042C5E4 /* Assets.xcassets in Resources */, - DDC2E1AB26DD89EC0042C5E4 /* packets.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -469,6 +460,7 @@ DDAF8C6B26ED0DD80058C060 /* environmental_measurement.pb.swift in Sources */, DD90860C26F684AF00DC5189 /* BatteryIcon.swift in Sources */, DDAF8C6226ED0A230058C060 /* mqtt.pb.swift in Sources */, + DDF924CA26FBB953009FE055 /* ConnectedDevice.swift in Sources */, DDAF8C5D26ED09490058C060 /* portnums.pb.swift in Sources */, DD47E3DF26F39D9F00029299 /* MyInfoModel.swift in Sources */, DD47E3CE26F103C600029299 /* NodeList.swift in Sources */, @@ -651,7 +643,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.091; + MARKETING_VERSION = 1.092; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = NO; @@ -677,7 +669,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.091; + MARKETING_VERSION = 1.092; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = NO; diff --git a/MeshtasticClient/Assets.xcassets/techo.imageset/Contents.json b/MeshtasticClient/Assets.xcassets/techo.imageset/Contents.json new file mode 100644 index 00000000..aeb16a23 --- /dev/null +++ b/MeshtasticClient/Assets.xcassets/techo.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "techo-2.jpg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "techo-1.jpg", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "techo.jpg", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MeshtasticClient/Assets.xcassets/techo.imageset/techo-1.jpg b/MeshtasticClient/Assets.xcassets/techo.imageset/techo-1.jpg new file mode 100644 index 00000000..0f1ce811 Binary files /dev/null and b/MeshtasticClient/Assets.xcassets/techo.imageset/techo-1.jpg differ diff --git a/MeshtasticClient/Assets.xcassets/techo.imageset/techo-2.jpg b/MeshtasticClient/Assets.xcassets/techo.imageset/techo-2.jpg new file mode 100644 index 00000000..0f1ce811 Binary files /dev/null and b/MeshtasticClient/Assets.xcassets/techo.imageset/techo-2.jpg differ diff --git a/MeshtasticClient/Assets.xcassets/techo.imageset/techo.jpg b/MeshtasticClient/Assets.xcassets/techo.imageset/techo.jpg new file mode 100644 index 00000000..0f1ce811 Binary files /dev/null and b/MeshtasticClient/Assets.xcassets/techo.imageset/techo.jpg differ diff --git a/MeshtasticClient/Assets.xcassets/tlorav1.imageset/Contents.json b/MeshtasticClient/Assets.xcassets/tlorav1.imageset/Contents.json new file mode 100644 index 00000000..1ff58079 --- /dev/null +++ b/MeshtasticClient/Assets.xcassets/tlorav1.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "tlora-2.jpeg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "tlora-1.jpeg", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "tlora.jpeg", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MeshtasticClient/Assets.xcassets/tlorav1.imageset/tlora-1.jpeg b/MeshtasticClient/Assets.xcassets/tlorav1.imageset/tlora-1.jpeg new file mode 100644 index 00000000..450bbb05 Binary files /dev/null and b/MeshtasticClient/Assets.xcassets/tlorav1.imageset/tlora-1.jpeg differ diff --git a/MeshtasticClient/Assets.xcassets/tlorav1.imageset/tlora-2.jpeg b/MeshtasticClient/Assets.xcassets/tlorav1.imageset/tlora-2.jpeg new file mode 100644 index 00000000..450bbb05 Binary files /dev/null and b/MeshtasticClient/Assets.xcassets/tlorav1.imageset/tlora-2.jpeg differ diff --git a/MeshtasticClient/Assets.xcassets/tlorav1.imageset/tlora.jpeg b/MeshtasticClient/Assets.xcassets/tlorav1.imageset/tlora.jpeg new file mode 100644 index 00000000..450bbb05 Binary files /dev/null and b/MeshtasticClient/Assets.xcassets/tlorav1.imageset/tlora.jpeg differ diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index c3abbe64..dc757a7a 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -145,6 +145,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph //--------------------------------------------------------------------------------------- func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) { + meshData.load() if(peripheral.identifier == connectedPeripheral.identifier){ connectedPeripheral = nil } @@ -249,27 +250,36 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph { print("Save a nodeInfo") do { - meshData.nodes.append( - NodeInfoModel(id: UUID(), - num: decodedInfo.nodeInfo.num, - user: NodeInfoModel.User(id: decodedInfo.nodeInfo.user.id, - longName: decodedInfo.nodeInfo.user.longName, - shortName: decodedInfo.nodeInfo.user.shortName, - //macaddr: "", - hwModel: String(describing: decodedInfo.nodeInfo.user.hwModel) - .capitalized - - ), - position: NodeInfoModel.Position(latitudeI: decodedInfo.nodeInfo.position.latitudeI, - longitudeI: decodedInfo.nodeInfo.position.longitudeI, - altitude: decodedInfo.nodeInfo.position.altitude, - batteryLevel: decodedInfo.nodeInfo.position.batteryLevel, - time: decodedInfo.nodeInfo.position.time), - lastHeard: decodedInfo.nodeInfo.lastHeard, - snr: decodedInfo.nodeInfo.snr) - ) - meshData.save() + + if meshData.nodes.contains(where: {$0.id == decodedInfo.nodeInfo.num}) { + // it exists, do something + } + else { + meshData.nodes.append( + NodeInfoModel( + num: decodedInfo.nodeInfo.num, + user: NodeInfoModel.User( + id: decodedInfo.nodeInfo.user.id, + longName: decodedInfo.nodeInfo.user.longName, + shortName: decodedInfo.nodeInfo.user.shortName, + //macaddr: decodedInfo.nodeInfo.user.macaddr, + hwModel: String(describing: decodedInfo.nodeInfo.user.hwModel) + .uppercased()), + + position: NodeInfoModel.Position( + latitudeI: decodedInfo.nodeInfo.position.latitudeI, + longitudeI: decodedInfo.nodeInfo.position.longitudeI, + altitude: decodedInfo.nodeInfo.position.altitude, + batteryLevel: decodedInfo.nodeInfo.position.batteryLevel, + time: decodedInfo.nodeInfo.position.time), + + lastHeard: decodedInfo.nodeInfo.lastHeard, + snr: decodedInfo.nodeInfo.snr) + ) + meshData.save() + + } print(try decodedInfo.nodeInfo.jsonString()) } catch { fatalError("Failed to decode json") diff --git a/MeshtasticClient/MeshtasticClientApp.swift b/MeshtasticClient/MeshtasticClientApp.swift index c4928647..3e51d970 100644 --- a/MeshtasticClient/MeshtasticClientApp.swift +++ b/MeshtasticClient/MeshtasticClientApp.swift @@ -11,11 +11,14 @@ import SwiftUI struct MeshtasticClientApp: App { @ObservedObject private var meshData: MeshData = MeshData() - + @ObservedObject private var bleManager: BLEManager = BLEManager() + + //@ObservedObject var meshData: MeshData var body: some Scene { WindowGroup { ContentView() .environmentObject(meshData) + .environmentObject(bleManager) .onAppear{ meshData.load() } diff --git a/MeshtasticClient/Model/MeshData.swift b/MeshtasticClient/Model/MeshData.swift index f5f6975f..4ccaa186 100644 --- a/MeshtasticClient/Model/MeshData.swift +++ b/MeshtasticClient/Model/MeshData.swift @@ -6,14 +6,16 @@ class MeshData: ObservableObject { return try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, - create: false) + create: true) } catch { fatalError("Can't find documents directory.") } } + private static var fileURL: URL { - return documentsFolder.appendingPathComponent("scrums.data") + return documentsFolder.appendingPathComponent("nodeinfo.data") } + @Published var nodes: [NodeInfoModel] = [] func load() { diff --git a/MeshtasticClient/Model/NodeInfoModel.swift b/MeshtasticClient/Model/NodeInfoModel.swift index d8dddbc7..c27ae075 100644 --- a/MeshtasticClient/Model/NodeInfoModel.swift +++ b/MeshtasticClient/Model/NodeInfoModel.swift @@ -6,7 +6,7 @@ import CoreLocation struct NodeInfoModel: Identifiable, Codable { - let id: UUID + var id: UInt32 var num: UInt32 var user: User @@ -29,7 +29,9 @@ struct NodeInfoModel: Identifiable, Codable { var latitude: Double? { if let unwrappedLat = latitudeI { let d = Double(unwrappedLat) - + if d == 0 { + return nil + } return d / 1e7 } else { @@ -40,7 +42,9 @@ struct NodeInfoModel: Identifiable, Codable { var longitude: Double? { if let unwrappedLong = longitudeI { let d = Double(unwrappedLong) - + if d == 0 { + return nil + } return d / 1e7 } else { @@ -48,7 +52,7 @@ struct NodeInfoModel: Identifiable, Codable { } } var coordinate: CLLocationCoordinate2D? { - if longitude != nil { + if latitude != nil || longitude != nil { let coord = CLLocationCoordinate2D(latitude: latitude!, longitude: longitude!) return coord @@ -74,8 +78,8 @@ struct NodeInfoModel: Identifiable, Codable { var snr: Float? - init(id: UUID = UUID(), num: UInt32, user: User, position: Position, lastHeard: UInt32, snr: Float?) { - self.id = id + init(num: UInt32, user: User, position: Position, lastHeard: UInt32, snr: Float?) { + self.id = num self.num = num self.user = user self.position = position diff --git a/MeshtasticClient/Resources/nodeInfo.json b/MeshtasticClient/Resources/nodeInfo.json deleted file mode 100644 index 7950c36b..00000000 --- a/MeshtasticClient/Resources/nodeInfo.json +++ /dev/null @@ -1,43 +0,0 @@ -[ - { - "num":2792101487, - "user":{ - "id":"!a66c166f", - "longName":"RAK Solar 2", - "shortName":"RS2", - "macaddr":"8eambBZv", - "hwModel":"RAK4631" - }, - "position":{ - "batteryLevel":68}, - "lastHeard":1631593661 - } - }, - { - "num":1000569662, - "user":{ - "id":"!3ba37b3e", - "longName":"RAK Solar 1", - "shortName":"RS1", - "macaddr":"1Kc7o3s+", - "hwModel":"RAK4631" - }, - "position":{ - "latitudeI":476021390, - "longitudeI":-1221532609, - "altitude":71, - "batteryLevel":70, - "time":1629314497 - }, - "lastHeard":1629392801, - "snr":5.25 - }, - {"num":1133445808,"user":{"id":"!438f02b0","longName":"RAK DEV NODE","shortName":"RDN","macaddr":"92VDjwKw","hwModel":"RAK4631"},"position":{"latitudeI":476022071,"longitudeI":-1221533607,"altitude":91,"batteryLevel":88,"time":1629391435},"lastHeard":1629393577,"snr":4.5}, - {"num":84682040,"user":{"id":"!050c2538","longName":"Yellow Beam","shortName":"YB","macaddr":"PGEFDCU4","hwModel":"TBEAM"},"position":{"latitudeI":476020703,"longitudeI":-1221531973,"altitude":79,"batteryLevel":1,"time":1631593233},"lastHeard":1631593034,"snr":5.0}, - {"num":2354994191,"user":{"id":"!8c5e5c0f","longName":"RAK Solar 3","shortName":"RS3","macaddr":"+GKMXlwP","hwModel":"RAK4631"},"position":{"batteryLevel":91,"time":1629263310},"lastHeard":1629393330,"snr":4.5}, - {"num":2718727166,"user":{"id":"!a20c7bfe","longName":"RAK Large Node","shortName":"RLN","macaddr":"zXSiDHv+","hwModel":"RAK4631"},"position":{"batteryLevel":32,"time":1629061939},"lastHeard":1629102457,"snr":-17.5}, - {"num":84681200,"user":{"id":"!050c21f0","longName":"Unknown 21f0","shortName":"?F0","macaddr":"PGEFDCHw","hwModel":"TBEAM"},"position":{"latitudeI":476022115,"longitudeI":-1221531952,"altitude":85,"batteryLevel":100,"time":1631593830},"lastHeard":1631593584,"snr":6.75}, - {"num":2930161432,"user":{"id":"!aea6b718","longName":"Unknown b718","shortName":"?18","macaddr":"TBGuprcY","hwModel":"TBEAM"},"position":{"latitudeI":476020757,"longitudeI":-1221533124,"altitude":56,"batteryLevel":100,"time":1631593558},"lastHeard":1631593554,"snr":6.75}, - {"num":4064637200,"user":{"id":"!f2457110","longName":"Unknown 7110","shortName":"?10","macaddr":"CDryRXEQ","hwModel":"TBEAM"},"position":{"latitudeI":476021534,"longitudeI":-1221533621,"altitude":49,"batteryLevel":100,"time":1631593778},"lastHeard":1631593533,"snr":7.0} - -] diff --git a/MeshtasticClient/Resources/nodeInfoModel.json b/MeshtasticClient/Resources/nodeInfoModel.json deleted file mode 100644 index d319a099..00000000 --- a/MeshtasticClient/Resources/nodeInfoModel.json +++ /dev/null @@ -1,152 +0,0 @@ -[{ - "num": 2792101487, - "user": { - "id": "!a66c166f", - "longName": "RAK Solar 2", - "shortName": "RS2", - "macaddr": "8eambBZv", - "hwModel": "RAK4631" - }, - "position": { - "batteryLevel": 68 - }, - "lastHeard": 1631593661 -}, { - "num": 1000569662, - "user": { - "id": "!3ba37b3e", - "longName": "RAK Solar 1", - "shortName": "RS1", - "macaddr": "1Kc7o3s+", - "hwModel": "RAK4631" - }, - "position": { - "latitudeI": 476021390, - "longitudeI": -1221532609, - "altitude": 71, - "batteryLevel": 70, - "time": 1629314497 - }, - "lastHeard": 1629392801, - "snr": 5.25 -}, { - "num": 1133445808, - "user": { - "id": "!438f02b0", - "longName": "RAK DEV NODE", - "shortName": "RDN", - "macaddr": "92VDjwKw", - "hwModel": "RAK4631" - }, - "position": { - "latitudeI": 476022071, - "longitudeI": -1221533607, - "altitude": 91, - "batteryLevel": 88, - "time": 1629391435 - }, - "lastHeard": 1629393577, - "snr": 4.5 -}, { - "num": 84682040, - "user": { - "id": "!050c2538", - "longName": "Yellow Beam", - "shortName": "YB", - "macaddr": "PGEFDCU4", - "hwModel": "TBEAM" - }, - "position": { - "latitudeI": 476020703, - "longitudeI": -1221531973, - "altitude": 79, - "batteryLevel": 1, - "time": 1631593233 - }, - "lastHeard": 1631593034, - "snr": 5.0 -}, { - "num": 2354994191, - "user": { - "id": "!8c5e5c0f", - "longName": "RAK Solar 3", - "shortName": "RS3", - "macaddr": "+GKMXlwP", - "hwModel": "RAK4631" - }, - "position": { - "batteryLevel": 91, - "time": 1629263310 - }, - "lastHeard": 1629393330, - "snr": 4.5 -}, { - "num": 2718727166, - "user": { - "id": "!a20c7bfe", - "longName": "RAK Large Node", - "shortName": "RLN", - "macaddr": "zXSiDHv+", - "hwModel": "RAK4631" - }, - "position": { - "batteryLevel": 32, - "time": 1629061939 - }, - "lastHeard": 1629102457, - "snr": -17.5 -}, { - "num": 84681200, - "user": { - "id": "!050c21f0", - "longName": "Unknown 21f0", - "shortName": "?F0", - "macaddr": "PGEFDCHw", - "hwModel": "TBEAM" - }, - "position": { - "latitudeI": 476022115, - "longitudeI": -1221531952, - "altitude": 85, - "batteryLevel": 100, - "time": 1631593830 - }, - "lastHeard": 1631593584, - "snr": 6.75 -}, { - "num": 2930161432, - "user": { - "id": "!aea6b718", - "longName": "Unknown b718", - "shortName": "?18", - "macaddr": "TBGuprcY", - "hwModel": "TBEAM" - }, - "position": { - "latitudeI": 476020757, - "longitudeI": -1221533124, - "altitude": 56, - "batteryLevel": 100, - "time": 1631593558 - }, - "lastHeard": 1631593554, - "snr": 6.75 -}, { - "num": 4064637200, - "user": { - "id": "!f2457110", - "longName": "Unknown 7110", - "shortName": "?10", - "macaddr": "CDryRXEQ", - "hwModel": "TBEAM" - }, - "position": { - "latitudeI": 476021534, - "longitudeI": -1221533621, - "altitude": 49, - "batteryLevel": 100, - "time": 1631593778 - }, - "lastHeard": 1631593533, - "snr": 7.0 -}] diff --git a/MeshtasticClient/Resources/nodeinfo.json b/MeshtasticClient/Resources/nodeinfo.json deleted file mode 100644 index 7950c36b..00000000 --- a/MeshtasticClient/Resources/nodeinfo.json +++ /dev/null @@ -1,43 +0,0 @@ -[ - { - "num":2792101487, - "user":{ - "id":"!a66c166f", - "longName":"RAK Solar 2", - "shortName":"RS2", - "macaddr":"8eambBZv", - "hwModel":"RAK4631" - }, - "position":{ - "batteryLevel":68}, - "lastHeard":1631593661 - } - }, - { - "num":1000569662, - "user":{ - "id":"!3ba37b3e", - "longName":"RAK Solar 1", - "shortName":"RS1", - "macaddr":"1Kc7o3s+", - "hwModel":"RAK4631" - }, - "position":{ - "latitudeI":476021390, - "longitudeI":-1221532609, - "altitude":71, - "batteryLevel":70, - "time":1629314497 - }, - "lastHeard":1629392801, - "snr":5.25 - }, - {"num":1133445808,"user":{"id":"!438f02b0","longName":"RAK DEV NODE","shortName":"RDN","macaddr":"92VDjwKw","hwModel":"RAK4631"},"position":{"latitudeI":476022071,"longitudeI":-1221533607,"altitude":91,"batteryLevel":88,"time":1629391435},"lastHeard":1629393577,"snr":4.5}, - {"num":84682040,"user":{"id":"!050c2538","longName":"Yellow Beam","shortName":"YB","macaddr":"PGEFDCU4","hwModel":"TBEAM"},"position":{"latitudeI":476020703,"longitudeI":-1221531973,"altitude":79,"batteryLevel":1,"time":1631593233},"lastHeard":1631593034,"snr":5.0}, - {"num":2354994191,"user":{"id":"!8c5e5c0f","longName":"RAK Solar 3","shortName":"RS3","macaddr":"+GKMXlwP","hwModel":"RAK4631"},"position":{"batteryLevel":91,"time":1629263310},"lastHeard":1629393330,"snr":4.5}, - {"num":2718727166,"user":{"id":"!a20c7bfe","longName":"RAK Large Node","shortName":"RLN","macaddr":"zXSiDHv+","hwModel":"RAK4631"},"position":{"batteryLevel":32,"time":1629061939},"lastHeard":1629102457,"snr":-17.5}, - {"num":84681200,"user":{"id":"!050c21f0","longName":"Unknown 21f0","shortName":"?F0","macaddr":"PGEFDCHw","hwModel":"TBEAM"},"position":{"latitudeI":476022115,"longitudeI":-1221531952,"altitude":85,"batteryLevel":100,"time":1631593830},"lastHeard":1631593584,"snr":6.75}, - {"num":2930161432,"user":{"id":"!aea6b718","longName":"Unknown b718","shortName":"?18","macaddr":"TBGuprcY","hwModel":"TBEAM"},"position":{"latitudeI":476020757,"longitudeI":-1221533124,"altitude":56,"batteryLevel":100,"time":1631593558},"lastHeard":1631593554,"snr":6.75}, - {"num":4064637200,"user":{"id":"!f2457110","longName":"Unknown 7110","shortName":"?10","macaddr":"CDryRXEQ","hwModel":"TBEAM"},"position":{"latitudeI":476021534,"longitudeI":-1221533621,"altitude":49,"batteryLevel":100,"time":1631593778},"lastHeard":1631593533,"snr":7.0} - -] diff --git a/MeshtasticClient/Resources/nodeinfomodel2.json b/MeshtasticClient/Resources/nodeinfomodel2.json deleted file mode 100644 index 7950c36b..00000000 --- a/MeshtasticClient/Resources/nodeinfomodel2.json +++ /dev/null @@ -1,43 +0,0 @@ -[ - { - "num":2792101487, - "user":{ - "id":"!a66c166f", - "longName":"RAK Solar 2", - "shortName":"RS2", - "macaddr":"8eambBZv", - "hwModel":"RAK4631" - }, - "position":{ - "batteryLevel":68}, - "lastHeard":1631593661 - } - }, - { - "num":1000569662, - "user":{ - "id":"!3ba37b3e", - "longName":"RAK Solar 1", - "shortName":"RS1", - "macaddr":"1Kc7o3s+", - "hwModel":"RAK4631" - }, - "position":{ - "latitudeI":476021390, - "longitudeI":-1221532609, - "altitude":71, - "batteryLevel":70, - "time":1629314497 - }, - "lastHeard":1629392801, - "snr":5.25 - }, - {"num":1133445808,"user":{"id":"!438f02b0","longName":"RAK DEV NODE","shortName":"RDN","macaddr":"92VDjwKw","hwModel":"RAK4631"},"position":{"latitudeI":476022071,"longitudeI":-1221533607,"altitude":91,"batteryLevel":88,"time":1629391435},"lastHeard":1629393577,"snr":4.5}, - {"num":84682040,"user":{"id":"!050c2538","longName":"Yellow Beam","shortName":"YB","macaddr":"PGEFDCU4","hwModel":"TBEAM"},"position":{"latitudeI":476020703,"longitudeI":-1221531973,"altitude":79,"batteryLevel":1,"time":1631593233},"lastHeard":1631593034,"snr":5.0}, - {"num":2354994191,"user":{"id":"!8c5e5c0f","longName":"RAK Solar 3","shortName":"RS3","macaddr":"+GKMXlwP","hwModel":"RAK4631"},"position":{"batteryLevel":91,"time":1629263310},"lastHeard":1629393330,"snr":4.5}, - {"num":2718727166,"user":{"id":"!a20c7bfe","longName":"RAK Large Node","shortName":"RLN","macaddr":"zXSiDHv+","hwModel":"RAK4631"},"position":{"batteryLevel":32,"time":1629061939},"lastHeard":1629102457,"snr":-17.5}, - {"num":84681200,"user":{"id":"!050c21f0","longName":"Unknown 21f0","shortName":"?F0","macaddr":"PGEFDCHw","hwModel":"TBEAM"},"position":{"latitudeI":476022115,"longitudeI":-1221531952,"altitude":85,"batteryLevel":100,"time":1631593830},"lastHeard":1631593584,"snr":6.75}, - {"num":2930161432,"user":{"id":"!aea6b718","longName":"Unknown b718","shortName":"?18","macaddr":"TBGuprcY","hwModel":"TBEAM"},"position":{"latitudeI":476020757,"longitudeI":-1221533124,"altitude":56,"batteryLevel":100,"time":1631593558},"lastHeard":1631593554,"snr":6.75}, - {"num":4064637200,"user":{"id":"!f2457110","longName":"Unknown 7110","shortName":"?10","macaddr":"CDryRXEQ","hwModel":"TBEAM"},"position":{"latitudeI":476021534,"longitudeI":-1221533621,"altitude":49,"batteryLevel":100,"time":1631593778},"lastHeard":1631593533,"snr":7.0} - -] diff --git a/MeshtasticClient/Resources/packets.json b/MeshtasticClient/Resources/packets.json deleted file mode 100644 index d319a099..00000000 --- a/MeshtasticClient/Resources/packets.json +++ /dev/null @@ -1,152 +0,0 @@ -[{ - "num": 2792101487, - "user": { - "id": "!a66c166f", - "longName": "RAK Solar 2", - "shortName": "RS2", - "macaddr": "8eambBZv", - "hwModel": "RAK4631" - }, - "position": { - "batteryLevel": 68 - }, - "lastHeard": 1631593661 -}, { - "num": 1000569662, - "user": { - "id": "!3ba37b3e", - "longName": "RAK Solar 1", - "shortName": "RS1", - "macaddr": "1Kc7o3s+", - "hwModel": "RAK4631" - }, - "position": { - "latitudeI": 476021390, - "longitudeI": -1221532609, - "altitude": 71, - "batteryLevel": 70, - "time": 1629314497 - }, - "lastHeard": 1629392801, - "snr": 5.25 -}, { - "num": 1133445808, - "user": { - "id": "!438f02b0", - "longName": "RAK DEV NODE", - "shortName": "RDN", - "macaddr": "92VDjwKw", - "hwModel": "RAK4631" - }, - "position": { - "latitudeI": 476022071, - "longitudeI": -1221533607, - "altitude": 91, - "batteryLevel": 88, - "time": 1629391435 - }, - "lastHeard": 1629393577, - "snr": 4.5 -}, { - "num": 84682040, - "user": { - "id": "!050c2538", - "longName": "Yellow Beam", - "shortName": "YB", - "macaddr": "PGEFDCU4", - "hwModel": "TBEAM" - }, - "position": { - "latitudeI": 476020703, - "longitudeI": -1221531973, - "altitude": 79, - "batteryLevel": 1, - "time": 1631593233 - }, - "lastHeard": 1631593034, - "snr": 5.0 -}, { - "num": 2354994191, - "user": { - "id": "!8c5e5c0f", - "longName": "RAK Solar 3", - "shortName": "RS3", - "macaddr": "+GKMXlwP", - "hwModel": "RAK4631" - }, - "position": { - "batteryLevel": 91, - "time": 1629263310 - }, - "lastHeard": 1629393330, - "snr": 4.5 -}, { - "num": 2718727166, - "user": { - "id": "!a20c7bfe", - "longName": "RAK Large Node", - "shortName": "RLN", - "macaddr": "zXSiDHv+", - "hwModel": "RAK4631" - }, - "position": { - "batteryLevel": 32, - "time": 1629061939 - }, - "lastHeard": 1629102457, - "snr": -17.5 -}, { - "num": 84681200, - "user": { - "id": "!050c21f0", - "longName": "Unknown 21f0", - "shortName": "?F0", - "macaddr": "PGEFDCHw", - "hwModel": "TBEAM" - }, - "position": { - "latitudeI": 476022115, - "longitudeI": -1221531952, - "altitude": 85, - "batteryLevel": 100, - "time": 1631593830 - }, - "lastHeard": 1631593584, - "snr": 6.75 -}, { - "num": 2930161432, - "user": { - "id": "!aea6b718", - "longName": "Unknown b718", - "shortName": "?18", - "macaddr": "TBGuprcY", - "hwModel": "TBEAM" - }, - "position": { - "latitudeI": 476020757, - "longitudeI": -1221533124, - "altitude": 56, - "batteryLevel": 100, - "time": 1631593558 - }, - "lastHeard": 1631593554, - "snr": 6.75 -}, { - "num": 4064637200, - "user": { - "id": "!f2457110", - "longName": "Unknown 7110", - "shortName": "?10", - "macaddr": "CDryRXEQ", - "hwModel": "TBEAM" - }, - "position": { - "latitudeI": 476021534, - "longitudeI": -1221533621, - "altitude": 49, - "batteryLevel": 100, - "time": 1631593778 - }, - "lastHeard": 1631593533, - "snr": 7.0 -}] diff --git a/MeshtasticClient/Views/Bluetooth/Connect.swift b/MeshtasticClient/Views/Bluetooth/Connect.swift index 6f6594e6..3738ce2b 100644 --- a/MeshtasticClient/Views/Bluetooth/Connect.swift +++ b/MeshtasticClient/Views/Bluetooth/Connect.swift @@ -14,9 +14,9 @@ import CoreLocation struct Connect: View { - //@EnvironmentObject var meshData: MeshData + @EnvironmentObject var meshData: MeshData - @ObservedObject var bleManager = BLEManager() + @EnvironmentObject var bleManager: BLEManager var body: some View { NavigationView { @@ -109,38 +109,25 @@ struct Connect: View { } .navigationTitle("Bluetooth Radios") .navigationBarItems(trailing: - HStack { - VStack { - if bleManager.isSwitchedOn && bleManager.connectedPeripheral != nil { - Image(systemName: "antenna.radiowaves.left.and.right") - .imageScale(.large) - .foregroundColor(.green) - .symbolRenderingMode(.hierarchical) - Text("Connected").font(.caption2).foregroundColor(.gray) - } - else { - - Image(systemName: "antenna.radiowaves.left.and.right.slash") - .imageScale(.large) - .foregroundColor(.red) - .symbolRenderingMode(.hierarchical) - Text("Disconnected").font(.caption2).foregroundColor(.gray) - - } - } - }.offset(x: 10, y: -10) + + ZStack { + + ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.name : "Unknown") + + } ) }.navigationViewStyle(StackNavigationViewStyle()) } } struct Connect_Previews: PreviewProvider { - static let meshData = MeshData() - static let bleManager = BLEManager() + // static let meshData = MeshData() + // static let bleManager = BLEManager() static var previews: some View { - Connect(bleManager: bleManager) + Connect() .environmentObject(MeshData()) + .environmentObject(BLEManager()) } } diff --git a/MeshtasticClient/Views/Helpers/ConnectedDevice.swift b/MeshtasticClient/Views/Helpers/ConnectedDevice.swift new file mode 100644 index 00000000..52f08337 --- /dev/null +++ b/MeshtasticClient/Views/Helpers/ConnectedDevice.swift @@ -0,0 +1,53 @@ +/* +Abstract: +A view draws the indicator used in the upper right corner for views using BLE +*/ + +import SwiftUI + +struct ConnectedDevice: View { + var bluetoothOn: Bool + var deviceConnected: Bool + var name: String? + + var body: some View { + + HStack { + VStack { + + if bluetoothOn { + if deviceConnected { + Image(systemName: "antenna.radiowaves.left.and.right") + .imageScale(.large) + .foregroundColor(.green) + .symbolRenderingMode(.hierarchical) + Text(name!).font(.caption2).foregroundColor(.gray) + } + else { + + Image(systemName: "antenna.radiowaves.left.and.right.slash") + .imageScale(.large) + .foregroundColor(.red) + .symbolRenderingMode(.hierarchical) + Text("Disconnected").font(.caption2).foregroundColor(.gray) + + } + } + else { + Text("Bluetooth Off").font(.caption).foregroundColor(.red) + } + } + }.offset(x: 10, y: -10) + } +} + +struct ConnectedDevice_Previews: PreviewProvider { + static var previews: some View { + ConnectedDevice(bluetoothOn: true, deviceConnected: false, name: "Yellow Beam") + .previewLayout(.fixed(width: 80, height: 70)) + + ConnectedDevice(bluetoothOn: true, deviceConnected: false, name: "Yellow Beam") + .previewLayout(.fixed(width: 80, height: 70)) + } + +} diff --git a/MeshtasticClient/Views/Messages/MessageList.swift b/MeshtasticClient/Views/Messages/MessageList.swift index 4e77ef7a..43f41155 100644 --- a/MeshtasticClient/Views/Messages/MessageList.swift +++ b/MeshtasticClient/Views/Messages/MessageList.swift @@ -6,9 +6,9 @@ struct MessageList: View { @State var typingMessage: String = "" - @ObservedObject var bleManager = BLEManager() + @EnvironmentObject var bleManager: BLEManager + @EnvironmentObject var meshData: MeshData - @State var connectedPeripheral: CBPeripheral! var body: some View { NavigationView { @@ -22,6 +22,13 @@ struct MessageList: View { } .navigationTitle("Channels") + .navigationBarItems(trailing: + + ZStack { + + ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.name : "Unknown") + } + ) .navigationBarTitleDisplayMode(.inline) } } diff --git a/MeshtasticClient/Views/Nodes/NodeList.swift b/MeshtasticClient/Views/Nodes/NodeList.swift index 67d44103..e62459c0 100644 --- a/MeshtasticClient/Views/Nodes/NodeList.swift +++ b/MeshtasticClient/Views/Nodes/NodeList.swift @@ -11,6 +11,7 @@ import SwiftUI struct NodeList: View { + @EnvironmentObject var bleManager: BLEManager @EnvironmentObject var meshData: MeshData @State private var showLocationOnly = false @@ -31,6 +32,7 @@ struct NodeList: View { ForEach(filteredDevices.sorted(by: { $0.lastHeard > $1.lastHeard })) { node in NavigationLink(destination: NodeDetail(node: node)) { NodeRow(node: node, index : 0) + } } } diff --git a/MeshtasticClient/Views/Nodes/NodeMap.swift b/MeshtasticClient/Views/Nodes/NodeMap.swift index 15bab623..30c4b19f 100644 --- a/MeshtasticClient/Views/Nodes/NodeMap.swift +++ b/MeshtasticClient/Views/Nodes/NodeMap.swift @@ -12,8 +12,11 @@ import CoreLocation struct NodeMap: View { + + + @ObservedObject var bleManager = BLEManager() @EnvironmentObject var meshData: MeshData - + var locationNodes: [NodeInfoModel] { meshData.nodes.filter { node in (node.position.coordinate != nil) @@ -30,7 +33,7 @@ struct NodeMap: View { let currentCoordinatePosition = CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude) let regionBinding = Binding( get: { - MKCoordinateRegion(center: currentCoordinatePosition, span: MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02)) + MKCoordinateRegion(center: currentCoordinatePosition, span: MKCoordinateSpan(latitudeDelta: 0.09, longitudeDelta: 0.09)) }, set: { _ in } ) @@ -59,9 +62,10 @@ struct NodeMap: View { struct NodeMap_Previews: PreviewProvider { static let meshData = MeshData() + static let bleManager = BLEManager() static var previews: some View { - NodeMap() - .environmentObject(meshData) + NodeMap(bleManager: bleManager) + .environmentObject(MeshData()) } } diff --git a/MeshtasticClient/Views/Nodes/NodeRow.swift b/MeshtasticClient/Views/Nodes/NodeRow.swift index e507cfe3..831ad79b 100644 --- a/MeshtasticClient/Views/Nodes/NodeRow.swift +++ b/MeshtasticClient/Views/Nodes/NodeRow.swift @@ -9,14 +9,14 @@ struct NodeRow: View { HStack() { CircleText(text: node.user.shortName, color: Color.blue).offset(y: 1).padding(.trailing, 5) - Text(node.user.longName).font(.title) + Text(node.user.longName).font(.title2) }.padding(.bottom, 2) HStack (alignment: .top){ - Image(systemName: "clock").font(.subheadline).foregroundColor(.blue) + Image(systemName: "clock").font(.caption).foregroundColor(.blue).symbolRenderingMode(.hierarchical) let lastHeard = Date(timeIntervalSince1970: TimeInterval(node.lastHeard)) - Text("Last Heard:").font(.subheadline).foregroundColor(.gray) - Text(lastHeard, style: .relative).font(.subheadline).foregroundColor(.gray) + Text("Last Heard:").font(.caption).foregroundColor(.gray) + Text(lastHeard, style: .relative).font(.caption).foregroundColor(.gray) } }.padding([.leading, .top, .bottom]) }