diff --git a/Shared/API/HAAPI.swift b/Shared/API/HAAPI.swift index 25535685b..7e5717179 100644 --- a/Shared/API/HAAPI.swift +++ b/Shared/API/HAAPI.swift @@ -83,6 +83,9 @@ public class HomeAssistantAPI { var tokenManager: TokenManager? public var connectionInfo: ConnectionInfo + public let pedometer = CMPedometer() + public let motionActivityManager = CMMotionActivityManager() + /// Initialize an API object with an authenticated tokenManager. public init(connectionInfo: ConnectionInfo, authenticationMethod: AuthenticationMethod) { self.connectionInfo = connectionInfo @@ -745,8 +748,6 @@ public class HomeAssistantAPI { private func getLatestMotionActivity() -> Promise { return Promise { seal in - let motionActivityManager = CMMotionActivityManager() - guard CMMotionActivityManager.isActivityAvailable() else { return seal.fulfill(nil) } @@ -758,12 +759,35 @@ public class HomeAssistantAPI { let end = Date() let start = Calendar.current.date(byAdding: .minute, value: -10, to: end)! let queue = OperationQueue.main - motionActivityManager.queryActivityStarting(from: start, to: end, to: queue) { (activities, _) in + self.motionActivityManager.queryActivityStarting(from: start, to: end, to: queue) { (activities, _) in seal.fulfill(activities?.last) } } } + private func getLatestPedometerData() -> Promise { + return Promise { seal in + guard CMPedometer.isStepCountingAvailable() else { + Current.Log.warning("Step counting is not available") + return seal.fulfill(nil) + } + + guard Current.settingsStore.motionEnabled else { + return seal.fulfill(nil) + } + + var startDate = Calendar.current.startOfDay(for: Date()) + + if let lastEntry = Current.realm().objects(LocationHistoryEntry.self).sorted(byKeyPath: "CreatedAt").last { + startDate = lastEntry.CreatedAt + } + + self.pedometer.queryPedometerData(from: startDate, to: Date()) { (pedometerData, _) in + seal.fulfill(pedometerData) + } + } + } + private func geocodeLocation(_ loc: CLLocation?) -> Promise { guard let loc = loc else { return Promise.value(nil) } return Promise { seal in @@ -796,12 +820,17 @@ public class HomeAssistantAPI { #endif return firstly { - when(fulfilled: self.getLatestMotionActivity(), self.geocodeLocation(location)) - }.then { activity, placemark -> Promise in - if let activity = activity { + when(fulfilled: self.getLatestMotionActivity(), self.getLatestPedometerData(), + self.geocodeLocation(location)) + }.then { motion, pedometer, placemark -> Promise in + if let activity = motion { payload.SetActivity(activity: activity) } + if let pedometerData = pedometer { + payload.SetPedometerData(pedometerData: pedometerData) + } + if let placemark = placemark { payload.SetPlacemark(placemark: placemark) } diff --git a/Shared/API/Models/DeviceTrackerSee.swift b/Shared/API/Models/DeviceTrackerSee.swift index a282613e6..62a40a585 100644 --- a/Shared/API/Models/DeviceTrackerSee.swift +++ b/Shared/API/Models/DeviceTrackerSee.swift @@ -37,6 +37,17 @@ public class DeviceTrackerSee: Mappable { public var ActivityConfidence: String? public var ActivityStartDate: Date? + // CMPedometerData + public var StartDate: Date? + public var EndDate: Date? + public var NumberOfSteps: Int? + public var Distance: Int? + public var AverageActivePace: Int? + public var CurrentPace: Int? + public var CurrentCadence: Int? + public var FloorsAscended: Int? + public var FloorsDescended: Int? + // CLPlacemark public var PlacemarkName: String? public var ISOCountryCode: String? @@ -129,6 +140,18 @@ public class DeviceTrackerSee: Mappable { self.ActivityStartDate = activity.startDate } + public func SetPedometerData(pedometerData: CMPedometerData) { + self.StartDate = pedometerData.startDate + self.EndDate = pedometerData.endDate + self.NumberOfSteps = pedometerData.numberOfSteps.intValue + self.Distance = pedometerData.distance?.intValue + self.AverageActivePace = pedometerData.averageActivePace?.intValue + self.CurrentPace = pedometerData.currentPace?.intValue + self.CurrentCadence = pedometerData.currentCadence?.intValue + self.FloorsAscended = pedometerData.floorsAscended?.intValue + self.FloorsDescended = pedometerData.floorsDescended?.intValue + } + public func SetPlacemark(placemark: CLPlacemark) { self.PlacemarkName = placemark.name self.ISOCountryCode = placemark.isoCountryCode @@ -166,6 +189,7 @@ public class DeviceTrackerSee: Mappable { } // Mappable + // swiftlint:disable:next function_body_length public func mapping(map: Map) { Attributes <- map["attributes"] Battery <- map["battery"] @@ -189,6 +213,16 @@ public class DeviceTrackerSee: Mappable { ActivityConfidence <- map["attributes.activity.confidence"] ActivityStartDate <- (map["attributes.activity.start_date"], HomeAssistantTimestampTransform()) + StartDate <- (map["attributes.pedometer.start_date"], HomeAssistantTimestampTransform()) + EndDate <- (map["attributes.pedometer.end_date"], HomeAssistantTimestampTransform()) + NumberOfSteps <- map["attributes.pedometer.number_of_steps"] + Distance <- map["attributes.pedometer.distance"] + AverageActivePace <- map["attributes.pedometer.average_active_pace"] + CurrentPace <- map["attributes.pedometer.current_pace"] + CurrentCadence <- map["attributes.pedometer.current_cadence"] + FloorsAscended <- map["attributes.pedometer.floors_ascended"] + FloorsDescended <- map["attributes.pedometer.floors_descended"] + PlacemarkName <- map["attributes.location.name"] ISOCountryCode <- map["attributes.location.iso_country_code"] Country <- map["attributes.location.country"]