iOS/Sources/Shared/API/Models/WebhookUpdateLocation.swift
Zac West 5c132da07f
Add "Location History" to Settings (#1521)
## Summary
Hopefully improve debugging location issues by providing a visualization of what we know about a location update.

## Screenshots
<img width="350" src="https://user-images.githubusercontent.com/74188/110420951-5ca5ad00-8051-11eb-82d9-b81dc28e20b7.png"><img width="350" src="https://user-images.githubusercontent.com/74188/110420954-5dd6da00-8051-11eb-9d78-61783873b08a.png">
<img width="350" src="https://user-images.githubusercontent.com/74188/110420959-60393400-8051-11eb-906c-74e19096e274.png"><img width="350" src="https://user-images.githubusercontent.com/74188/110420961-616a6100-8051-11eb-9aee-334234a6c59c.png">
<img width="350" src="https://user-images.githubusercontent.com/74188/110420972-63ccbb00-8051-11eb-855c-4e7d41a4e16f.png"><img width="350" src="https://user-images.githubusercontent.com/74188/110420975-64fde800-8051-11eb-9876-c0cb0f682727.png">
<img width="350" src="https://user-images.githubusercontent.com/74188/110420986-692a0580-8051-11eb-976b-1e2be659bcae.png"><img width="350" src="https://user-images.githubusercontent.com/74188/110420988-6af3c900-8051-11eb-982c-aaa903f4af5d.png">

## Any other notes
- Shows a blue circle for zones, an orange circle for non-single-region zones' regions, a purple circle for location and its accuracy.
- Allows sharing a bunch of debug data about the location and region states.
- Allows clearing of location history.
2021-03-08 22:57:49 -08:00

132 lines
3.6 KiB
Swift

import CoreLocation
import CoreMotion
import Foundation
import ObjectMapper
public enum LocationNames: String {
case Home = "home"
case NotHome = "not_home"
}
public class WebhookUpdateLocation: Mappable {
public var HorizontalAccuracy: CLLocationAccuracy?
public var Battery: Int?
public var Location: CLLocationCoordinate2D?
public var LocationName: String?
public var Speed: CLLocationSpeed?
public var Altitude: CLLocationDistance?
public var Course: CLLocationDirection?
public var VerticalAccuracy: CLLocationAccuracy?
// Not sent
public var Trigger: LocationUpdateTrigger = .Unknown
init() {}
public required init?(map: Map) {}
public convenience init?(trigger: LocationUpdateTrigger, location: CLLocation?, zone: RLMZone?) {
self.init()
self.Trigger = trigger
if let battery = Current.device.batteries().first {
self.Battery = battery.level
}
let useLocation: Bool
switch trigger {
case .BeaconRegionExit, .BeaconRegionEnter:
useLocation = false
default:
useLocation = true
}
if let location = location, useLocation {
SetLocation(location: location)
} else if let zone = zone {
SetZone(zone: zone)
} else {
return nil
}
}
public func SetZone(zone: RLMZone) {
HorizontalAccuracy = zone.Radius
Location = zone.center
#if os(iOS)
// https://github.com/home-assistant/home-assistant-iOS/issues/32
if let currentSSID = Current.connectivity.currentWiFiSSID(), zone.SSIDTrigger.contains(currentSSID) {
LocationName = zone.Name
return
}
#endif
if zone.isHome {
switch Trigger {
case .RegionEnter, .GPSRegionEnter, .BeaconRegionEnter:
LocationName = LocationNames.Home.rawValue
case .RegionExit, .GPSRegionExit:
LocationName = LocationNames.NotHome.rawValue
case .BeaconRegionExit:
ClearLocation()
default:
break
}
} else {
switch Trigger {
case .BeaconRegionEnter where !zone.isPassive:
LocationName = zone.Name
case .BeaconRegionExit:
ClearLocation()
default:
break
}
}
}
public func SetLocation(location: CLLocation) {
Location = location.coordinate
if location.speed > -1 {
Speed = location.speed
}
if location.course > -1 {
Course = location.course
}
if location.altitude > -1 {
Altitude = location.altitude
}
if location.verticalAccuracy > -1 {
VerticalAccuracy = location.verticalAccuracy
}
if location.horizontalAccuracy > -1 {
HorizontalAccuracy = location.horizontalAccuracy
}
}
public func ClearLocation() {
HorizontalAccuracy = nil
Location = nil
Speed = nil
Altitude = nil
Course = nil
VerticalAccuracy = nil
}
// Mappable
public func mapping(map: Map) {
Battery <- map["battery"]
Location <- (map["gps"], CLLocationCoordinate2DTransform())
HorizontalAccuracy <- map["gps_accuracy"]
LocationName <- map["location_name"]
Speed <- map["speed"]
Altitude <- map["altitude"]
Course <- map["course"]
VerticalAccuracy <- map["vertical_accuracy"]
}
}