Connection improvements
This commit is contained in:
parent
8b046b7313
commit
b2773635f5
@ -10,6 +10,8 @@ class Connection {
|
||||
|
||||
Connection._internal();
|
||||
|
||||
String _domain;
|
||||
String _port;
|
||||
String displayHostname;
|
||||
String _webSocketAPIEndpoint;
|
||||
String httpWebHost;
|
||||
@ -17,6 +19,8 @@ class Connection {
|
||||
String _tempToken;
|
||||
String oauthUrl;
|
||||
String deviceName;
|
||||
bool useLovelace = true;
|
||||
bool settingsLoaded = false;
|
||||
bool get isAuthenticated => _token != null;
|
||||
StreamSubscription _socketSubscription;
|
||||
Duration connectTimeout = Duration(seconds: 15);
|
||||
@ -30,40 +34,55 @@ class Connection {
|
||||
int _currentMessageId = 0;
|
||||
Map<String, Completer> _messageResolver = {};
|
||||
|
||||
Future init(onStateChange) async {
|
||||
Future init({bool loadSettings, bool forceReconnect: false}) async {
|
||||
Completer completer = Completer();
|
||||
onStateChangeCallback = onStateChange;
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
String domain = prefs.getString('hassio-domain');
|
||||
String port = prefs.getString('hassio-port');
|
||||
displayHostname = "$domain:$port";
|
||||
_webSocketAPIEndpoint = "${prefs.getString('hassio-protocol')}://$domain:$port/api/websocket";
|
||||
httpWebHost = "${prefs.getString('hassio-res-protocol')}://$domain:$port";
|
||||
//_token = prefs.getString('hassio-token');
|
||||
final storage = new FlutterSecureStorage();
|
||||
try {
|
||||
_token = await storage.read(key: "hacl_llt");
|
||||
} catch (e) {
|
||||
Logger.e("Cannt read secure storage. Need to relogin.");
|
||||
_token = null;
|
||||
await storage.delete(key: "hacl_llt");
|
||||
}
|
||||
if ((domain == null) || (port == null) ||
|
||||
(domain.length == 0) || (port.length == 0)) {
|
||||
completer.completeError({"errorCode": 5, "errorMessage": "Check connection settings"});
|
||||
} else {
|
||||
if (loadSettings) {
|
||||
Logger.e("Loading settings...");
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
useLovelace = prefs.getBool('use-lovelace') ?? true;
|
||||
_domain = prefs.getString('hassio-domain');
|
||||
_port = prefs.getString('hassio-port');
|
||||
displayHostname = "$_domain:$_port";
|
||||
_webSocketAPIEndpoint = "${prefs.getString('hassio-protocol')}://$_domain:$_port/api/websocket";
|
||||
httpWebHost = "${prefs.getString('hassio-res-protocol')}://$_domain:$_port";
|
||||
//_token = prefs.getString('hassio-token');
|
||||
final storage = new FlutterSecureStorage();
|
||||
try {
|
||||
_token = await storage.read(key: "hacl_llt");
|
||||
Logger.e("Long-lived token read successful");
|
||||
} catch (e) {
|
||||
Logger.e("Cannt read secure storage. Need to relogin.");
|
||||
_token = null;
|
||||
await storage.delete(key: "hacl_llt");
|
||||
}
|
||||
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
|
||||
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
|
||||
deviceName = androidInfo.model;
|
||||
oauthUrl = "$httpWebHost/auth/authorize?client_id=${Uri.encodeComponent('http://ha-client.homemade.systems/')}&redirect_uri=${Uri.encodeComponent('http://ha-client.homemade.systems/service/auth_callback.html')}";
|
||||
if (_token == null) {
|
||||
await AuthManager().getTempToken(
|
||||
oauthUrl: oauthUrl
|
||||
).then((token) {
|
||||
Logger.d("Token from AuthManager recived");
|
||||
_tempToken = token;
|
||||
});
|
||||
}
|
||||
settingsLoaded = true;
|
||||
}
|
||||
if ((_domain == null) || (_port == null) ||
|
||||
(_domain.isEmpty) || (_port.isEmpty)) {
|
||||
completer.completeError({"errorCode": 5, "errorMessage": "Check connection settings"});
|
||||
}
|
||||
|
||||
if (_token == null) {
|
||||
AuthManager().getTempToken(
|
||||
oauthUrl: oauthUrl
|
||||
).then((token) {
|
||||
Logger.d("Token from AuthManager recived");
|
||||
_tempToken = token;
|
||||
_doConnect(completer: completer, forceReconnect: forceReconnect);
|
||||
});
|
||||
} else {
|
||||
_doConnect(completer: completer, forceReconnect: forceReconnect);
|
||||
}
|
||||
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
void _doConnect({Completer completer, bool forceReconnect}) {
|
||||
if (forceReconnect || !isConnected) {
|
||||
_connect().timeout(connectTimeout, onTimeout: () {
|
||||
_disconnect().then((_) {
|
||||
completer.completeError(
|
||||
@ -72,8 +91,9 @@ class Connection {
|
||||
}).then((_) => completer.complete()).catchError((e) {
|
||||
completer.completeError(e);
|
||||
});
|
||||
} else {
|
||||
completer.complete();
|
||||
}
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
Completer connecting;
|
||||
@ -121,6 +141,7 @@ class Connection {
|
||||
}
|
||||
|
||||
_disconnect() async {
|
||||
isConnected = false;
|
||||
Logger.d( "Socket disconnecting...");
|
||||
if (_socketSubscription != null) {
|
||||
await _socketSubscription?.cancel();
|
||||
|
@ -4,7 +4,7 @@ class HomeAssistant {
|
||||
|
||||
final Connection connection = Connection();
|
||||
|
||||
bool _useLovelace = false;
|
||||
//bool _useLovelace = false;
|
||||
//bool isSettingsLoaded = false;
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@ class HomeAssistant {
|
||||
Duration fetchTimeout = Duration(seconds: 30);
|
||||
|
||||
String get locationName {
|
||||
if (_useLovelace) {
|
||||
if (Connection().useLovelace) {
|
||||
return ui?.title ?? "";
|
||||
} else {
|
||||
return _instanceConfig["location_name"] ?? "";
|
||||
@ -36,38 +36,22 @@ class HomeAssistant {
|
||||
bool get isNoViews => ui == null || ui.isEmpty;
|
||||
//int get viewsCount => entities.views.length ?? 0;
|
||||
|
||||
HomeAssistant();
|
||||
|
||||
Completer _connectCompleter;
|
||||
|
||||
Future init() {
|
||||
if (_connectCompleter != null && !_connectCompleter.isCompleted) {
|
||||
Logger.w("Previous connection pending...");
|
||||
return _connectCompleter.future;
|
||||
}
|
||||
Logger.d("init...");
|
||||
_connectCompleter = Completer();
|
||||
connection.init(_handleEntityStateChange).then((_) {
|
||||
SharedPreferences.getInstance().then((prefs) {
|
||||
if (entities == null) entities = EntityCollection(connection.httpWebHost);
|
||||
_useLovelace = prefs.getBool('use-lovelace') ?? true;
|
||||
_connectCompleter.complete();
|
||||
}).catchError((e) => _connectCompleter.completeError(e));
|
||||
}).catchError((e) => _connectCompleter.completeError(e));
|
||||
return _connectCompleter.future;
|
||||
HomeAssistant() {
|
||||
Connection().onStateChangeCallback = _handleEntityStateChange;
|
||||
}
|
||||
|
||||
Completer _fetchCompleter;
|
||||
|
||||
Future fetch() {
|
||||
Future fetchData() {
|
||||
if (_fetchCompleter != null && !_fetchCompleter.isCompleted) {
|
||||
Logger.w("Previous data fetch is not completed yet");
|
||||
return _fetchCompleter.future;
|
||||
}
|
||||
if (entities == null) entities = EntityCollection(connection.httpWebHost);
|
||||
_fetchCompleter = Completer();
|
||||
List<Future> futures = [];
|
||||
futures.add(_getStates());
|
||||
if (_useLovelace) {
|
||||
if (Connection().useLovelace) {
|
||||
futures.add(_getLovelace());
|
||||
}
|
||||
futures.add(_getConfig());
|
||||
@ -319,7 +303,7 @@ class HomeAssistant {
|
||||
|
||||
void _createUI() {
|
||||
ui = HomeAssistantUI();
|
||||
if ((_useLovelace) && (_rawLovelaceData != null)) {
|
||||
if ((Connection().useLovelace) && (_rawLovelaceData != null)) {
|
||||
Logger.d("Creating Lovelace UI");
|
||||
_parseLovelace();
|
||||
} else {
|
||||
|
@ -191,27 +191,28 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
||||
_settingsSubscription = eventBus.on<SettingsChangedEvent>().listen((event) {
|
||||
Logger.d("Settings change event: reconnect=${event.reconnect}");
|
||||
if (event.reconnect) {
|
||||
_reLoad();
|
||||
_fullLoad();
|
||||
}
|
||||
});
|
||||
|
||||
_initialLoad();
|
||||
_fullLoad();
|
||||
}
|
||||
|
||||
void _initialLoad() async {
|
||||
void _fullLoad() async {
|
||||
_showInfoBottomBar(progress: true,);
|
||||
widget.homeAssistant.init().then((_){
|
||||
_subscribe();
|
||||
_fetchData();
|
||||
_subscribe().then((_) {
|
||||
Connection().init(loadSettings: true, forceReconnect: true).then((__){
|
||||
_fetchData();
|
||||
});
|
||||
}, onError: (e) {
|
||||
_setErrorState(e);
|
||||
});
|
||||
}
|
||||
|
||||
void _reLoad() {
|
||||
void _quickLoad() {
|
||||
_hideBottomBar();
|
||||
_showInfoBottomBar(progress: true,);
|
||||
widget.homeAssistant.init().then((_){
|
||||
Connection().init(loadSettings: false, forceReconnect: false).then((_){
|
||||
_fetchData();
|
||||
}, onError: (e) {
|
||||
_setErrorState(e);
|
||||
@ -219,7 +220,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
||||
}
|
||||
|
||||
_fetchData() async {
|
||||
await widget.homeAssistant.fetch().then((_) {
|
||||
await widget.homeAssistant.fetchData().then((_) {
|
||||
_hideBottomBar();
|
||||
int currentViewCount = widget.homeAssistant.ui?.views?.length ?? 0;
|
||||
if (_previousViewCount != currentViewCount) {
|
||||
@ -236,8 +237,8 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
Logger.d("$state");
|
||||
if (state == AppLifecycleState.resumed) {
|
||||
_reLoad();
|
||||
if (state == AppLifecycleState.resumed && Connection().settingsLoaded) {
|
||||
_quickLoad();
|
||||
}
|
||||
}
|
||||
|
||||
@ -247,7 +248,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
||||
_stateSubscription = eventBus.on<StateChangedEvent>().listen((event) {
|
||||
if (event.needToRebuildUI) {
|
||||
Logger.d("New entity. Need to rebuild UI");
|
||||
_reLoad();
|
||||
_quickLoad();
|
||||
} else {
|
||||
setState(() {});
|
||||
}
|
||||
@ -255,7 +256,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
||||
}
|
||||
if (_reloadUISubscription == null) {
|
||||
_reloadUISubscription = eventBus.on<ReloadUIEvent>().listen((event){
|
||||
_reLoad();
|
||||
_quickLoad();
|
||||
});
|
||||
}
|
||||
if (_serviceCallSubscription == null) {
|
||||
@ -549,7 +550,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
||||
child: Text("Retry", style: textStyle),
|
||||
onPressed: () {
|
||||
//_scaffoldKey?.currentState?.hideCurrentSnackBar();
|
||||
_reLoad();
|
||||
_quickLoad();
|
||||
},
|
||||
);
|
||||
break;
|
||||
@ -571,7 +572,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
||||
_bottomBarAction = FlatButton(
|
||||
child: Text("Login", style: textStyle),
|
||||
onPressed: () {
|
||||
_reLoad();
|
||||
_fullLoad();
|
||||
},
|
||||
);
|
||||
break;
|
||||
@ -582,7 +583,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
||||
_bottomBarAction = FlatButton(
|
||||
child: Text("Try again", style: textStyle),
|
||||
onPressed: () {
|
||||
_reLoad();
|
||||
_fullLoad();
|
||||
},
|
||||
);
|
||||
break;
|
||||
@ -592,7 +593,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
||||
_bottomBarAction = FlatButton(
|
||||
child: Text("Login again", style: textStyle),
|
||||
onPressed: () {
|
||||
_reLoad();
|
||||
_fullLoad();
|
||||
},
|
||||
);
|
||||
break;
|
||||
@ -603,7 +604,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
||||
child: Text("Reload", style: textStyle),
|
||||
onPressed: () {
|
||||
//_scaffoldKey?.currentState?.hideCurrentSnackBar();
|
||||
_reLoad();
|
||||
_fullLoad();
|
||||
},
|
||||
);
|
||||
break;
|
||||
@ -615,7 +616,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
||||
_bottomBarAction = FlatButton(
|
||||
child: Text("Reconnect", style: textStyle),
|
||||
onPressed: () {
|
||||
_reLoad();
|
||||
_fullLoad();
|
||||
},
|
||||
);
|
||||
break;
|
||||
@ -625,7 +626,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
||||
_bottomBarAction = FlatButton(
|
||||
child: Text("Try again", style: textStyle),
|
||||
onPressed: () {
|
||||
_reLoad();
|
||||
_fullLoad();
|
||||
},
|
||||
);
|
||||
break;
|
||||
@ -672,10 +673,10 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
||||
items: popupMenuItems
|
||||
).then((String val) {
|
||||
if (val == "reload") {
|
||||
_reLoad();
|
||||
_quickLoad();
|
||||
} else if (val == "logout") {
|
||||
widget.homeAssistant.logout().then((_) {
|
||||
_reLoad();
|
||||
_quickLoad();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
Reference in New Issue
Block a user