This repository has been archived on 2023-11-18. You can view files and clone it, but cannot push or open issues or pull requests.
ha_client/lib/managers/location_manager.class.dart

237 lines
8.6 KiB
Dart
Raw Normal View History

part of '../main.dart';
class LocationManager {
2019-10-20 20:54:29 +03:00
static final LocationManager _instance = LocationManager
._internal();
factory LocationManager() {
return _instance;
}
LocationManager._internal() {
init();
}
2019-10-21 21:22:25 +03:00
final int defaultUpdateIntervalMinutes = 20;
final String backgroundTaskId = "haclocationtask0";
2019-10-21 21:22:25 +03:00
final String backgroundTaskTag = "haclocation";
2019-10-20 20:54:29 +03:00
Duration _updateInterval;
2019-10-24 21:34:38 +03:00
bool _isRunning;
2019-10-20 20:54:29 +03:00
void init() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.reload();
_updateInterval = Duration(minutes: prefs.getInt("location-interval") ??
defaultUpdateIntervalMinutes);
2019-10-24 21:34:38 +03:00
_isRunning = prefs.getBool("location-enabled") ?? false;
if (_isRunning) {
await _startLocationService();
2019-10-20 20:54:29 +03:00
}
}
2019-10-24 21:58:48 +03:00
setSettings(bool enabled, int interval) async {
2019-10-20 20:54:29 +03:00
SharedPreferences prefs = await SharedPreferences.getInstance();
if (interval != _updateInterval.inMinutes) {
prefs.setInt("location-interval", interval);
_updateInterval = Duration(minutes: interval);
2019-10-24 21:34:38 +03:00
if (_isRunning) {
Logger.d("Stopping location tracking...");
_isRunning = false;
await _stopLocationService();
}
2019-10-20 20:54:29 +03:00
}
2019-10-24 21:34:38 +03:00
if (enabled && !_isRunning) {
Logger.d("Starting location tracking");
2019-10-20 20:54:29 +03:00
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setBool("location-enabled", enabled);
2019-10-24 21:34:38 +03:00
_isRunning = true;
await _startLocationService();
} else if (!enabled && _isRunning) {
Logger.d("Stopping location tracking...");
2019-10-20 20:54:29 +03:00
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setBool("location-enabled", enabled);
2019-10-24 21:34:38 +03:00
_isRunning = false;
await _stopLocationService();
2019-10-20 20:54:29 +03:00
}
}
2019-10-24 21:34:38 +03:00
_startLocationService() async {
2019-10-21 21:22:25 +03:00
String webhookId = ConnectionManager().webhookId;
String httpWebHost = ConnectionManager().httpWebHost;
if (webhookId != null && webhookId.isNotEmpty) {
Duration interval;
int delayFactor;
int taskCount;
Logger.d("Starting location update for every ${_updateInterval
.inMinutes} minutes...");
if (_updateInterval.inMinutes == 10) {
interval = Duration(minutes: 20);
taskCount = 2;
delayFactor = 10;
} else if (_updateInterval.inMinutes == 5) {
interval = Duration(minutes: 15);
taskCount = 3;
delayFactor = 5;
} else {
interval = _updateInterval;
taskCount = 1;
delayFactor = 0;
}
for (int i = 1; i <= taskCount; i++) {
int delay = i*delayFactor;
Logger.d("Scheduling location update task #$i for every ${interval.inMinutes} minutes in $delay minutes...");
await workManager.Workmanager.registerPeriodicTask(
"$backgroundTaskId$i",
"haClientLocationTracking-0$i",
tag: backgroundTaskTag,
inputData: {
"webhookId": webhookId,
"httpWebHost": httpWebHost
},
frequency: interval,
initialDelay: Duration(minutes: delay),
existingWorkPolicy: workManager.ExistingWorkPolicy.keep,
backoffPolicy: workManager.BackoffPolicy.linear,
backoffPolicyDelay: interval,
constraints: workManager.Constraints(
2020-02-17 21:22:38 +02:00
networkType: workManager.NetworkType.connected,
),
);
}
2019-10-21 21:22:25 +03:00
}
2019-10-20 20:54:29 +03:00
}
2019-10-24 21:34:38 +03:00
_stopLocationService() async {
2019-10-20 20:54:29 +03:00
Logger.d("Canceling previous schedule if any...");
await workManager.Workmanager.cancelAll();
2019-10-20 20:54:29 +03:00
}
updateDeviceLocation() async {
2019-11-10 23:53:28 +02:00
Logger.d("[Foreground location] Started");
Geolocator geolocator = Geolocator();
var battery = Battery();
String webhookId = ConnectionManager().webhookId;
String httpWebHost = ConnectionManager().httpWebHost;
if (webhookId != null && webhookId.isNotEmpty) {
2019-11-10 23:53:28 +02:00
Logger.d("[Foreground location] Getting battery level...");
int batteryLevel = await battery.batteryLevel;
Logger.d("[Foreground location] Getting device location...");
Position position = await geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high,
locationPermissionLevel: GeolocationPermission.locationAlways
);
if (position != null) {
Logger.d("[Foreground location] Location: ${position.latitude} ${position.longitude}. Accuracy: ${position.accuracy}. (${position.timestamp})");
String url = "$httpWebHost/api/webhook/$webhookId";
Map data = {
"type": "update_location",
"data": {
"gps": [position.latitude, position.longitude],
"gps_accuracy": position.accuracy,
"battery": batteryLevel ?? 100
}
2019-11-10 23:53:28 +02:00
};
Logger.d("[Foreground location] Sending data home...");
var response = await http.post(
url,
headers: {"Content-Type": "application/json"},
body: json.encode(data)
);
Logger.d("[Foreground location] Got HTTP ${response.statusCode}");
} else {
Logger.d("[Foreground location] No location. Aborting.");
}
2019-10-20 20:54:29 +03:00
}
}
}
void updateDeviceLocationIsolate() {
2020-03-05 11:08:47 +02:00
workManager.Workmanager.executeTask((backgroundTask, data) async {
2020-04-03 16:17:24 +03:00
//print("[Background $backgroundTask] Started");
Geolocator geolocator = Geolocator();
2019-10-24 21:34:38 +03:00
var battery = Battery();
2019-10-21 21:22:25 +03:00
String webhookId = data["webhookId"];
String httpWebHost = data["httpWebHost"];
2020-04-03 16:17:24 +03:00
//String logData = '==> ${DateTime.now()} [Background $backgroundTask]:';
//print("[Background $backgroundTask] Getting path for log file...");
//final logFileDirectory = await getExternalStorageDirectory();
//print("[Background $backgroundTask] Opening log file...");
//File logFile = File('${logFileDirectory.path}/ha-client-background-log.txt');
//print("[Background $backgroundTask] Log file path: ${logFile.path}");
2019-10-21 21:22:25 +03:00
if (webhookId != null && webhookId.isNotEmpty) {
2020-02-17 21:22:38 +02:00
String url = "$httpWebHost/api/webhook/$webhookId";
Map<String, String> headers = {};
headers["Content-Type"] = "application/json";
Map data = {
"type": "update_location",
"data": {
"gps": [],
"gps_accuracy": 0,
2020-03-05 11:08:47 +02:00
"battery": 100
2020-02-17 21:22:38 +02:00
}
};
2020-04-03 16:17:24 +03:00
//print("[Background $backgroundTask] Getting battery level...");
2020-03-09 15:11:16 +02:00
int batteryLevel;
try {
batteryLevel = await battery.batteryLevel;
2020-04-03 16:17:24 +03:00
//print("[Background $backgroundTask] Got battery level: $batteryLevel");
2020-03-09 15:11:16 +02:00
} catch(e) {
2020-04-03 16:17:24 +03:00
//print("[Background $backgroundTask] Error getting battery level: $e. Setting zero");
2020-03-09 15:11:16 +02:00
batteryLevel = 0;
2020-04-03 16:17:24 +03:00
//logData += 'Battery: error, $e';
2020-03-09 15:11:16 +02:00
}
2020-03-05 11:08:47 +02:00
if (batteryLevel != null) {
data["data"]["battery"] = batteryLevel;
2020-04-03 16:17:24 +03:00
//logData += 'Battery: success, $batteryLevel';
}/* else {
2020-03-09 15:11:16 +02:00
logData += 'Battery: error, level is null';
2020-04-03 16:17:24 +03:00
}*/
2020-03-09 15:11:16 +02:00
Position location;
try {
location = await geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high, locationPermissionLevel: GeolocationPermission.locationAlways);
if (location != null && location.latitude != null) {
2020-04-03 16:17:24 +03:00
//logData += ' || Location: success, ${location.latitude} ${location.longitude} (${location.timestamp})';
2020-03-09 15:11:16 +02:00
data["data"]["gps"] = [location.latitude, location.longitude];
data["data"]["gps_accuracy"] = location.accuracy;
try {
http.Response response = await http.post(
url,
headers: headers,
body: json.encode(data)
);
2020-04-03 16:17:24 +03:00
/*if (response.statusCode >= 200 && response.statusCode < 300) {
logData += ' || Post: success, ${response.statusCode}';
} else {
logData += ' || Post: error, ${response.statusCode}';
2020-04-03 16:17:24 +03:00
}*/
} catch(e) {
2020-04-03 16:17:24 +03:00
//logData += ' || Post: error, $e';
}
2020-04-03 16:17:24 +03:00
}/* else {
2020-03-09 15:11:16 +02:00
logData += ' || Location: error, location is null';
2020-04-03 16:17:24 +03:00
}*/
2020-03-09 15:11:16 +02:00
} catch (e) {
2020-04-03 16:17:24 +03:00
//print("[Background $backgroundTask] Location error: $e");
//logData += ' || Location: error, $e';
2020-03-05 11:08:47 +02:00
}
2020-04-03 16:17:24 +03:00
}/* else {
2020-03-09 15:11:16 +02:00
logData += 'Not configured';
2020-04-03 16:17:24 +03:00
}*/
//print("[Background $backgroundTask] Writing log data...");
/*try {
var fileMode;
if (logFile.existsSync() && logFile.lengthSync() < 5000000) {
fileMode = FileMode.append;
} else {
fileMode = FileMode.write;
}
await logFile.writeAsString('$logData\n', mode: fileMode);
2020-03-09 15:11:16 +02:00
} catch (e) {
print("[Background $backgroundTask] Error writing log: $e");
2019-10-21 21:22:25 +03:00
}
2020-04-03 16:17:24 +03:00
print("[Background $backgroundTask] Finished.");*/
2020-03-05 11:08:47 +02:00
return true;
2019-10-20 20:54:29 +03:00
});
}