Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
9c1d240962 | |||
a76652b552 | |||
a140f993d0 | |||
ded60a2867 | |||
b86602bcdb | |||
02ea45469f | |||
90105c3b09 | |||
3d828914cc | |||
8cd5776bc6 | |||
17ec73b176 |
@ -140,9 +140,9 @@ class HomeAssistant {
|
|||||||
|
|
||||||
Future _getConfig(SharedPreferences sharedPrefs) async {
|
Future _getConfig(SharedPreferences sharedPrefs) async {
|
||||||
_instanceConfig?.clear();
|
_instanceConfig?.clear();
|
||||||
if (sharedPrefs != null) {
|
if (sharedPrefs != null && sharedPrefs.containsKey('cached_config')) {
|
||||||
try {
|
try {
|
||||||
var data = json.decode(sharedPrefs.getString('cached_config') ?? '{}');
|
var data = json.decode(sharedPrefs.getString('cached_config'));
|
||||||
_parseConfig(data);
|
_parseConfig(data);
|
||||||
} catch (e, stacktrace) {
|
} catch (e, stacktrace) {
|
||||||
Logger.e('Error gettong config from cache: $e', stacktrace: stacktrace);
|
Logger.e('Error gettong config from cache: $e', stacktrace: stacktrace);
|
||||||
@ -160,9 +160,9 @@ class HomeAssistant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future _getStates(SharedPreferences sharedPrefs) async {
|
Future _getStates(SharedPreferences sharedPrefs) async {
|
||||||
if (sharedPrefs != null) {
|
if (sharedPrefs != null && sharedPrefs.containsKey('cached_states')) {
|
||||||
try {
|
try {
|
||||||
var data = json.decode(sharedPrefs.getString('cached_states') ?? '[]');
|
var data = json.decode(sharedPrefs.getString('cached_states'));
|
||||||
_parseStates(data);
|
_parseStates(data);
|
||||||
} catch (e, stacktrace) {
|
} catch (e, stacktrace) {
|
||||||
Logger.e('Error getting cached states: $e', stacktrace: stacktrace);
|
Logger.e('Error getting cached states: $e', stacktrace: stacktrace);
|
||||||
@ -171,7 +171,7 @@ class HomeAssistant {
|
|||||||
await ConnectionManager().sendSocketMessage(type: "get_states").then(
|
await ConnectionManager().sendSocketMessage(type: "get_states").then(
|
||||||
(data) => _parseStates(data)
|
(data) => _parseStates(data)
|
||||||
).catchError((e) {
|
).catchError((e) {
|
||||||
Logger.e('get_states error: $e');
|
Logger.e('get_states error: $e');
|
||||||
throw HACException("Error getting states: $e");
|
throw HACException("Error getting states: $e");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -183,9 +183,9 @@ class HomeAssistant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future _getLovelace(SharedPreferences sharedPrefs) {
|
Future _getLovelace(SharedPreferences sharedPrefs) {
|
||||||
if (sharedPrefs != null) {
|
if (sharedPrefs != null && sharedPrefs.containsKey('cached_lovelace')) {
|
||||||
try {
|
try {
|
||||||
var data = json.decode(sharedPrefs.getString('cached_lovelace') ?? '{}');
|
var data = json.decode(sharedPrefs.getString('cached_lovelace'));
|
||||||
_rawLovelaceData = data;
|
_rawLovelaceData = data;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
autoUi = true;
|
autoUi = true;
|
||||||
@ -221,9 +221,9 @@ class HomeAssistant {
|
|||||||
|
|
||||||
Future _getServices(SharedPreferences prefs) async {
|
Future _getServices(SharedPreferences prefs) async {
|
||||||
services?.clear();
|
services?.clear();
|
||||||
if (prefs != null) {
|
if (prefs != null && prefs.containsKey('cached_services')) {
|
||||||
try {
|
try {
|
||||||
var data = json.decode(prefs.getString('cached_services') ?? '{}');
|
var data = json.decode(prefs.getString('cached_services'));
|
||||||
_parseServices(data);
|
_parseServices(data);
|
||||||
} catch (e, stacktrace) {
|
} catch (e, stacktrace) {
|
||||||
Logger.e(e, stacktrace: stacktrace);
|
Logger.e(e, stacktrace: stacktrace);
|
||||||
@ -240,9 +240,19 @@ class HomeAssistant {
|
|||||||
|
|
||||||
Future _getUserInfo(SharedPreferences sharedPrefs) async {
|
Future _getUserInfo(SharedPreferences sharedPrefs) async {
|
||||||
_userName = null;
|
_userName = null;
|
||||||
await ConnectionManager().sendSocketMessage(type: "auth/current_user").then((data) => _parseUserInfo(data)).catchError((e) {
|
if (sharedPrefs != null && sharedPrefs.containsKey('cached_user')) {
|
||||||
Logger.e('auth/current_user error: $e');
|
try {
|
||||||
});
|
var data = json.decode(sharedPrefs.getString('cached_user'));
|
||||||
|
_parseUserInfo(data);
|
||||||
|
} catch (e, stacktrace) {
|
||||||
|
Logger.e('Error getting cached user info: $e', stacktrace: stacktrace);
|
||||||
|
}
|
||||||
|
return Future.value();
|
||||||
|
} else {
|
||||||
|
await ConnectionManager().sendSocketMessage(type: "auth/current_user").then((data) => _parseUserInfo(data)).catchError((e) {
|
||||||
|
Logger.e('auth/current_user error: $e');
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _parseUserInfo(data) {
|
void _parseUserInfo(data) {
|
||||||
@ -251,9 +261,9 @@ class HomeAssistant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future _getPanels(SharedPreferences sharedPrefs) async {
|
Future _getPanels(SharedPreferences sharedPrefs) async {
|
||||||
if (sharedPrefs != null) {
|
if (sharedPrefs != null && sharedPrefs.containsKey('cached_panels')) {
|
||||||
try {
|
try {
|
||||||
var data = json.decode(sharedPrefs.getString('cached_panels') ?? '{}');
|
var data = json.decode(sharedPrefs.getString('cached_panels'));
|
||||||
_parsePanels(data);
|
_parsePanels(data);
|
||||||
} catch (e, stacktrace) {
|
} catch (e, stacktrace) {
|
||||||
Logger.e(e, stacktrace: stacktrace);
|
Logger.e(e, stacktrace: stacktrace);
|
||||||
|
@ -157,10 +157,11 @@ part 'popups.dart';
|
|||||||
EventBus eventBus = new EventBus();
|
EventBus eventBus = new EventBus();
|
||||||
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
|
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
|
||||||
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = new FlutterLocalNotificationsPlugin();
|
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = new FlutterLocalNotificationsPlugin();
|
||||||
const String appName = "HA Client";
|
const String appName = 'HA Client';
|
||||||
const appVersionNumber = "1.0.0";
|
const appVersionNumber = '1.0.1';
|
||||||
const appVersionAdd = "";
|
final String appVersionAdd = secrets['version_type'] ?? '';
|
||||||
const appVersion = "$appVersionNumber$appVersionAdd";
|
final String appVersion = '$appVersionNumber${appVersionAdd.isNotEmpty ? '-' : ''}$appVersionAdd';
|
||||||
|
const whatsNewUrl = 'http://ha-client.app/service/whats_new_1.0.1.md';
|
||||||
|
|
||||||
Future<void> _reportError(dynamic error, dynamic stackTrace) async {
|
Future<void> _reportError(dynamic error, dynamic stackTrace) async {
|
||||||
// Print the exception to the console.
|
// Print the exception to the console.
|
||||||
|
@ -19,6 +19,7 @@ class ConnectionManager {
|
|||||||
String _tempToken;
|
String _tempToken;
|
||||||
String oauthUrl;
|
String oauthUrl;
|
||||||
String webhookId;
|
String webhookId;
|
||||||
|
double haVersion;
|
||||||
String mobileAppDeviceName;
|
String mobileAppDeviceName;
|
||||||
bool settingsLoaded = false;
|
bool settingsLoaded = false;
|
||||||
int appIntegrationVersion;
|
int appIntegrationVersion;
|
||||||
@ -154,7 +155,12 @@ class ConnectionManager {
|
|||||||
if (!connecting.isCompleted) connecting.completeError(e);
|
if (!connecting.isCompleted) connecting.completeError(e);
|
||||||
});
|
});
|
||||||
} else if (data["type"] == "auth_ok") {
|
} else if (data["type"] == "auth_ok") {
|
||||||
Logger.d("[Received] <== ${data.toString()}");
|
String v = data["ha_version"];
|
||||||
|
if (v != null && v.isNotEmpty) {
|
||||||
|
haVersion = double.tryParse(v.replaceFirst('0.','')) ?? 0;
|
||||||
|
}
|
||||||
|
Logger.d("Home assistant version: $v ($haVersion)");
|
||||||
|
Crashlytics.instance.setString('ha_version', v);
|
||||||
Logger.d("[Connection] Subscribing to events");
|
Logger.d("[Connection] Subscribing to events");
|
||||||
sendSocketMessage(
|
sendSocketMessage(
|
||||||
type: "subscribe_events",
|
type: "subscribe_events",
|
||||||
|
@ -108,40 +108,47 @@ class LocationManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateDeviceLocation() async {
|
updateDeviceLocation() async {
|
||||||
Logger.d("[Foreground location] Started");
|
try {
|
||||||
Geolocator geolocator = Geolocator();
|
Logger.d("[Foreground location] Started");
|
||||||
var battery = Battery();
|
Geolocator geolocator = Geolocator();
|
||||||
String webhookId = ConnectionManager().webhookId;
|
var battery = Battery();
|
||||||
String httpWebHost = ConnectionManager().httpWebHost;
|
String webhookId = ConnectionManager().webhookId;
|
||||||
if (webhookId != null && webhookId.isNotEmpty) {
|
String httpWebHost = ConnectionManager().httpWebHost;
|
||||||
Logger.d("[Foreground location] Getting battery level...");
|
if (webhookId != null && webhookId.isNotEmpty) {
|
||||||
int batteryLevel = await battery.batteryLevel;
|
Logger.d("[Foreground location] Getting battery level...");
|
||||||
Logger.d("[Foreground location] Getting device location...");
|
int batteryLevel = await battery.batteryLevel;
|
||||||
Position position = await geolocator.getCurrentPosition(
|
Logger.d("[Foreground location] Getting device location...");
|
||||||
desiredAccuracy: LocationAccuracy.high,
|
Position position = await geolocator.getCurrentPosition(
|
||||||
locationPermissionLevel: GeolocationPermission.locationAlways
|
desiredAccuracy: LocationAccuracy.high,
|
||||||
);
|
locationPermissionLevel: GeolocationPermission.locationAlways
|
||||||
if (position != null) {
|
);
|
||||||
Logger.d("[Foreground location] Location: ${position.latitude} ${position.longitude}. Accuracy: ${position.accuracy}. (${position.timestamp})");
|
if (position != null) {
|
||||||
String url = "$httpWebHost/api/webhook/$webhookId";
|
Logger.d("[Foreground location] Location: ${position.latitude} ${position.longitude}. Accuracy: ${position.accuracy}. (${position.timestamp})");
|
||||||
Map data = {
|
String url = "$httpWebHost/api/webhook/$webhookId";
|
||||||
"type": "update_location",
|
Map data = {
|
||||||
"data": {
|
"type": "update_location",
|
||||||
"gps": [position.latitude, position.longitude],
|
"data": {
|
||||||
"gps_accuracy": position.accuracy,
|
"gps": [position.latitude, position.longitude],
|
||||||
"battery": batteryLevel ?? 100
|
"gps_accuracy": position.accuracy,
|
||||||
|
"battery": batteryLevel ?? 100
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Logger.d("[Foreground location] Sending data home...");
|
||||||
|
http.Response response = await http.post(
|
||||||
|
url,
|
||||||
|
headers: {"Content-Type": "application/json"},
|
||||||
|
body: json.encode(data)
|
||||||
|
);
|
||||||
|
if (response.statusCode >= 300) {
|
||||||
|
Logger.e('Foreground location update error: ${response.body}');
|
||||||
}
|
}
|
||||||
};
|
Logger.d("[Foreground location] Got HTTP ${response.statusCode}");
|
||||||
Logger.d("[Foreground location] Sending data home...");
|
} else {
|
||||||
var response = await http.post(
|
Logger.d("[Foreground location] No location. Aborting.");
|
||||||
url,
|
}
|
||||||
headers: {"Content-Type": "application/json"},
|
}
|
||||||
body: json.encode(data)
|
} catch (e, stack) {
|
||||||
);
|
Logger.e('Foreground location error: ${e.toSTring()}', stacktrace: stack);
|
||||||
Logger.d("[Foreground location] Got HTTP ${response.statusCode}");
|
|
||||||
} else {
|
|
||||||
Logger.d("[Foreground location] No location. Aborting.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,12 +31,16 @@ class MobileAppIntegrationManager {
|
|||||||
Logger.d("Mobile app was not registered yet. Registering...");
|
Logger.d("Mobile app was not registered yet. Registering...");
|
||||||
var registrationData = Map.from(_appRegistrationData);
|
var registrationData = Map.from(_appRegistrationData);
|
||||||
registrationData.addAll({
|
registrationData.addAll({
|
||||||
"device_id": "${DeviceInfoManager().unicDeviceId}",
|
|
||||||
"app_id": "ha_client",
|
"app_id": "ha_client",
|
||||||
"app_name": "$appName",
|
"app_name": "$appName",
|
||||||
"os_name": DeviceInfoManager().osName,
|
"os_name": DeviceInfoManager().osName,
|
||||||
"supports_encryption": false,
|
"supports_encryption": false,
|
||||||
});
|
});
|
||||||
|
if (ConnectionManager().haVersion >= 104) {
|
||||||
|
registrationData.addAll({
|
||||||
|
"device_id": "${DeviceInfoManager().unicDeviceId}"
|
||||||
|
});
|
||||||
|
}
|
||||||
ConnectionManager().sendHTTPPost(
|
ConnectionManager().sendHTTPPost(
|
||||||
endPoint: "/api/mobile_app/registrations",
|
endPoint: "/api/mobile_app/registrations",
|
||||||
includeAuthHeader: true,
|
includeAuthHeader: true,
|
||||||
|
@ -14,13 +14,13 @@ class StartupUserMessagesManager {
|
|||||||
bool _supportAppDevelopmentMessageShown;
|
bool _supportAppDevelopmentMessageShown;
|
||||||
bool _whatsNewMessageShown;
|
bool _whatsNewMessageShown;
|
||||||
static final _supportAppDevelopmentMessageKey = "user-message-shown-support-development_3";
|
static final _supportAppDevelopmentMessageKey = "user-message-shown-support-development_3";
|
||||||
static final _whatsNewMessageKey = "user-message-shown-whats-new-1006";
|
static final _whatsNewMessageKey = "user-msg-whats-new-url";
|
||||||
|
|
||||||
void checkMessagesToShow() async {
|
void checkMessagesToShow() async {
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
await prefs.reload();
|
await prefs.reload();
|
||||||
_supportAppDevelopmentMessageShown = prefs.getBool(_supportAppDevelopmentMessageKey) ?? false;
|
_supportAppDevelopmentMessageShown = prefs.getBool(_supportAppDevelopmentMessageKey) ?? false;
|
||||||
_whatsNewMessageShown = prefs.getBool(_whatsNewMessageKey) ?? false;
|
_whatsNewMessageShown = '${prefs.getString(_whatsNewMessageKey)}' == whatsNewUrl;
|
||||||
if (!_whatsNewMessageShown) {
|
if (!_whatsNewMessageShown) {
|
||||||
_showWhatsNewMessage();
|
_showWhatsNewMessage();
|
||||||
} else if (!_supportAppDevelopmentMessageShown) {
|
} else if (!_supportAppDevelopmentMessageShown) {
|
||||||
@ -52,7 +52,7 @@ class StartupUserMessagesManager {
|
|||||||
|
|
||||||
void _showWhatsNewMessage() {
|
void _showWhatsNewMessage() {
|
||||||
SharedPreferences.getInstance().then((prefs) {
|
SharedPreferences.getInstance().then((prefs) {
|
||||||
prefs.setBool(_whatsNewMessageKey, true);
|
prefs.setString(_whatsNewMessageKey, whatsNewUrl);
|
||||||
eventBus.fire(ShowPageEvent(path: "/whats-new"));
|
eventBus.fire(ShowPageEvent(path: "/whats-new"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ class _WhatsNewPageState extends State<WhatsNewPage> {
|
|||||||
error = "";
|
error = "";
|
||||||
});
|
});
|
||||||
http.Response response;
|
http.Response response;
|
||||||
response = await http.get("http://ha-client.app/service/whats_new_1.0.0_stable.md");
|
response = await http.get(whatsNewUrl);
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
setState(() {
|
setState(() {
|
||||||
data = response.body;
|
data = response.body;
|
||||||
|
@ -54,7 +54,7 @@ class _EntityHistoryWidgetState extends State<EntityHistoryWidget> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).catchError((e) {
|
}).catchError((e) {
|
||||||
Logger.e("Error loading $entityId history: $e");
|
Logger.e("Error loading $entityId history: $e", skipCrashlytics: true);
|
||||||
if (!_disposed) {
|
if (!_disposed) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_history = [];
|
_history = [];
|
||||||
|
@ -18,8 +18,8 @@ class Logger {
|
|||||||
print(data);
|
print(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void e(String message, {dynamic stacktrace, bool skipCrashlytics: false}) {
|
static void e(dynamic message, {dynamic stacktrace, bool skipCrashlytics: false}) {
|
||||||
_writeToLog(ErrorLevel.ERROR, message, stacktrace, skipCrashlytics);
|
_writeToLog(ErrorLevel.ERROR, message.toString(), stacktrace, skipCrashlytics);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void w(String message) {
|
static void w(String message) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
name: hass_client
|
name: hass_client
|
||||||
description: Home Assistant Android Client
|
description: Home Assistant Android Client
|
||||||
|
|
||||||
version: 1.0.0+1008
|
version: 1.0.1+1013
|
||||||
|
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
@ -4,6 +4,7 @@ import 'dart:io';
|
|||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
final config = {
|
final config = {
|
||||||
'syncfusion_license_key': Platform.environment['SYNCFUSION_LICENSE_KEY'],
|
'syncfusion_license_key': Platform.environment['SYNCFUSION_LICENSE_KEY'],
|
||||||
|
'version_type': Platform.environment['HA_CLIENT_VERSION_TYPE'] ?? ''
|
||||||
};
|
};
|
||||||
|
|
||||||
final filename = 'lib/.secrets.dart';
|
final filename = 'lib/.secrets.dart';
|
||||||
|
Reference in New Issue
Block a user