Connection improvements

This commit is contained in:
estevez-dev 2019-04-05 11:48:41 +03:00
parent 8b046b7313
commit b2773635f5
3 changed files with 82 additions and 76 deletions

View File

@ -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();

View File

@ -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 {

View File

@ -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();
});
}
});