diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index bf5b0949..531d4206 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -880,17 +880,19 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate var positionPacket = Position() positionPacket.latitudeI = Int32(LocationHelper.currentLocation.latitude * 1e7) positionPacket.longitudeI = Int32(LocationHelper.currentLocation.longitude * 1e7) - positionPacket.time = UInt32(LocationHelper.currentTimestamp.timeIntervalSince1970) - positionPacket.timestamp = UInt32(LocationHelper.currentTimestamp.timeIntervalSince1970) - positionPacket.altitude = Int32(LocationHelper.currentAltitude) + let timestamp = LocationHelper.shared.locationManager.location?.timestamp ?? Date() + positionPacket.time = UInt32(timestamp.timeIntervalSince1970) + positionPacket.timestamp = UInt32(timestamp.timeIntervalSince1970) + positionPacket.altitude = Int32(LocationHelper.shared.locationManager.location?.altitude ?? 0) positionPacket.satsInView = UInt32(LocationHelper.satsInView) - if LocationHelper.currentSpeed > 0 && (!LocationHelper.currentSpeed.isNaN || !LocationHelper.currentSpeed.isInfinite) { - positionPacket.groundSpeed = UInt32(LocationHelper.currentSpeed * 3.6) + let currentSpeed = LocationHelper.shared.locationManager.location?.speed ?? 0 + if currentSpeed > 0 && (!currentSpeed.isNaN || !currentSpeed.isInfinite) { + positionPacket.groundSpeed = UInt32(currentSpeed * 3.6) } - if LocationHelper.currentHeading > 0 && (!LocationHelper.currentHeading.isNaN || !LocationHelper.currentHeading.isInfinite) { - positionPacket.groundTrack = UInt32(LocationHelper.currentHeading) + let currentHeading = LocationHelper.shared.locationManager.location?.course ?? 0 + if currentHeading > 0 && (!currentHeading.isNaN || !currentHeading.isInfinite) { + positionPacket.groundTrack = UInt32(currentHeading) } - var meshPacket = MeshPacket() meshPacket.to = UInt32(destNum) meshPacket.from = UInt32(fromNodeNum) @@ -2175,7 +2177,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate /// send a request for ClientHistory with a time period matching the heartbeat var sfPacket = StoreAndForward() sfPacket.rr = StoreAndForward.RequestResponse.clientHistory - sfPacket.history.window = storeAndForwardMessage.heartbeat.period + sfPacket.history.window = 18000000 // storeAndForwardMessage.heartbeat.period var meshPacket: MeshPacket = MeshPacket() meshPacket.to = UInt32(packet.from) meshPacket.from = UInt32(connectedNodeNum) diff --git a/Meshtastic/Helpers/LocationHelper.swift b/Meshtastic/Helpers/LocationHelper.swift index 118623b8..857fdc63 100644 --- a/Meshtastic/Helpers/LocationHelper.swift +++ b/Meshtastic/Helpers/LocationHelper.swift @@ -14,43 +14,16 @@ class LocationHelper: NSObject, ObservableObject, CLLocationManagerDelegate { locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters locationManager.pausesLocationUpdatesAutomatically = true locationManager.allowsBackgroundLocationUpdates = true - locationManager.activityType = .otherNavigation + locationManager.activityType = .other } // Apple Park static let DefaultLocation = CLLocationCoordinate2D(latitude: 37.3346, longitude: -122.0090) - static let DefaultAltitude = CLLocationDistance(integerLiteral: 0) - static let DefaultSpeed = CLLocationSpeed(integerLiteral: 0) - static let DefaultHeading = CLLocationDirection(integerLiteral: 0) static var currentLocation: CLLocationCoordinate2D { guard let location = shared.locationManager.location else { return DefaultLocation } return location.coordinate } - static var currentAltitude: CLLocationDistance { - guard let altitude = shared.locationManager.location?.altitude else { - return DefaultAltitude - } - return altitude - } - static var currentSpeed: CLLocationSpeed { - guard let speed = shared.locationManager.location?.speed else { - return DefaultSpeed - } - return speed - } - static var currentHeading: CLLocationDirection { - guard let heading = shared.locationManager.location?.course else { - return DefaultHeading - } - return heading - } - static var currentTimestamp: Date { - guard let timestamp = shared.locationManager.location?.timestamp else { - return Date.now - } - return timestamp - } static var satsInView: Int { // If we have a position we have a sat var sats = 1 @@ -74,9 +47,11 @@ class LocationHelper: NSObject, ObservableObject, CLLocationManagerDelegate { } return sats } - + func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { switch manager.authorizationStatus { + case .authorizedAlways: + authorizationStatus = .authorizedAlways case .authorizedWhenInUse: authorizationStatus = .authorizedWhenInUse locationManager.requestLocation() @@ -86,19 +61,32 @@ class LocationHelper: NSObject, ObservableObject, CLLocationManagerDelegate { authorizationStatus = .denied case .notDetermined: authorizationStatus = .notDetermined - locationManager.requestWhenInUseAuthorization() + locationManager.requestAlwaysAuthorization() default: break } } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { -// locationManager.stopUpdatingLocation() -// locations.last.map { -// region = MKCoordinateRegion( -// center: $0.coordinate, -// span: .init(latitudeDelta: 0.01, longitudeDelta: 0.01) -// ) -// } + let chimeOnLocationUpdate = true + // locationManager.stopUpdatingLocation() + // locations.last.map { + // region = MKCoordinateRegion( + // center: $0.coordinate, + // span: .init(latitudeDelta: 0.01, longitudeDelta: 0.01) + // ) + // } + // Play a sound so it's easy to tell when a location update occurs while the app is in the background. + if chimeOnLocationUpdate && !locations.isEmpty { + // setSessionActiveWithMixing(true) // Ducks the audio of other apps when playing the chime. + // playSound() + } + + // Always process all of the provided locations. Don't assume the array only contains a single location. + for location in locations { + + print("process a location") + // displayNewBreadcrumbOnMap(location) + } } func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { print("Location manager error: \(error.localizedDescription)") diff --git a/Meshtastic/Info.plist b/Meshtastic/Info.plist index c41afa05..b24ff3d9 100644 --- a/Meshtastic/Info.plist +++ b/Meshtastic/Info.plist @@ -55,6 +55,8 @@ We use your location to display it on the mesh map as well as to have GPS coordinatess to send to the connected device. NSLocationWhenInUseUsageDescription We use your location to display it on the mesh map as well as to have GPS coordinatess to send to the connected device. + NSLocationAlwaysUsageDescription + We use your location to display it on the mesh map as well as to have GPS coordinatess to send to the connected device. NSSupportsLiveActivities Privacy – Bluetooth Always Usage Description diff --git a/Meshtastic/Views/Nodes/DetectionSensorLog.swift b/Meshtastic/Views/Nodes/DetectionSensorLog.swift index 410dfb11..c59fd318 100644 --- a/Meshtastic/Views/Nodes/DetectionSensorLog.swift +++ b/Meshtastic/Views/Nodes/DetectionSensorLog.swift @@ -15,7 +15,6 @@ struct DetectionSensorLog: View { @State var isExporting = false @State var exportString = "" @ObservedObject var node: NodeInfoEntity - @FetchRequest(sortDescriptors: [NSSortDescriptor(key: "messageTimestamp", ascending: false)], predicate: NSPredicate(format: "portNum == %d", Int32(PortNum.detectionSensorApp.rawValue)), animation: .none) private var detections: FetchedResults @@ -23,12 +22,12 @@ struct DetectionSensorLog: View { var body: some View { let oneDayAgo = Calendar.current.date(byAdding: .day, value: -1, to: Date()) let chartData = detections - .filter { $0.timestamp >= oneDayAgo! } + .filter { $0.timestamp >= oneDayAgo! && $0.fromUser?.num ?? -1 == node.user?.num ?? 0 } .sorted { $0.timestamp < $1.timestamp } VStack { if chartData.count > 0 { - GroupBox(label: Label("\(detections.count) Total Detection Events", systemImage: "sensor")) { + GroupBox(label: Label("\(chartData.count) Total Detection Events", systemImage: "sensor")) { Chart { ForEach(chartData, id: \.self) { point in Plot { @@ -90,7 +89,7 @@ struct DetectionSensorLog: View { .font(.caption) .fontWeight(.bold) } - ForEach(detections) { d in + ForEach(detections.filter( {$0.fromUser?.num ?? -1 == node.user?.num ?? 0})) { d in GridRow { Text(d.messagePayload ?? "Detected") .font(.caption) diff --git a/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift b/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift index 778412eb..868aaf85 100644 --- a/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift @@ -76,6 +76,7 @@ struct DetectionSensorConfig: View { Text("Enables the detection sensor module, it needs to be enabled on both the node with the sensor, and any nodes that you want to receive detection sensor text messages or view the detection sensor log and chart.") .font(.caption) } + .toggleStyle(SwitchToggleStyle(tint: .accentColor)) .listRowSeparator(.visible) if enabled { HStack { @@ -108,6 +109,7 @@ struct DetectionSensorConfig: View { Text("Send ASCII bell with alert message. Useful for triggering external notification on bell.") .font(.caption) } + .toggleStyle(SwitchToggleStyle(tint: .accentColor)) .listRowSeparator(.visible) HStack { Label("Name", systemImage: "signature")