diff --git a/lib/data_model.dart b/lib/data_model.dart index 2d15bde..d54c5fb 100644 --- a/lib/data_model.dart +++ b/lib/data_model.dart @@ -45,7 +45,7 @@ class HassioDataModel { if ((_fetchCompleter != null) && (!_fetchCompleter.isCompleted)) { debugPrint("Previous fetch is not complited"); } else { - //Fetch timeout timer + //TODO: Fetch timeout timer. Should be removed after #21 fix _fetchingTimer = Timer(Duration(seconds: 10), () { closeConnection(); _fetchCompleter.completeError({"errorCode" : 1,"errorMessage": "Connection timeout"}); @@ -306,13 +306,22 @@ class HassioDataModel { _statesCompleter.complete(); } - callService(String domain, String service, String entity_id) { + Future callService(String domain, String service, String entity_id) { + var sendCompleter = Completer(); + //TODO: Send service call timeout timer. Should be removed after #21 fix + Timer _sendTimer = Timer(Duration(seconds: 7), () { + sendCompleter.completeError({"errorCode" : 8,"errorMessage": "Connection timeout"}); + }); _reConnectSocket().then((r) { _incrementMessageId(); _sendMessageRaw('{"id": $_currentMssageId, "type": "call_service", "domain": "$domain", "service": "$service", "service_data": {"entity_id": "$entity_id"}}'); + _sendTimer.cancel(); + sendCompleter.complete(); }).catchError((e){ - debugPrint("Unable to connect for service call: $entity_id $domain.$service"); + _sendTimer.cancel(); + sendCompleter.completeError(e); }); + return sendCompleter.future; } } diff --git a/lib/main.dart b/lib/main.dart index fe726e9..da7b96a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -130,15 +130,30 @@ class _MainPageState extends State with WidgetsBindingObserver { _isLoading = false; }); }).catchError((e) { - setState(() { - _errorCodeToBeShown = e["errorCode"] != null ? e["errorCode"] : 99; - _lastErrorMessage = e["errorMessage"] ?? "Unknown error"; - _isLoading = false; - }); + _setErrorState(e); }); } } + _setErrorState(e) { + setState(() { + _errorCodeToBeShown = e["errorCode"] != null ? e["errorCode"] : 99; + _lastErrorMessage = e["errorMessage"] ?? "Unknown error"; + _isLoading = false; + }); + } + + void _callService(String domain, String service, String entityId) { + setState(() { + _isLoading = true; + }); + _dataModel.callService(domain, service, entityId).then((r) { + setState(() { + _isLoading = false; + }); + }).catchError((e) => _setErrorState(e)); + } + Widget _buildEntityAction(String entityId) { var entity = _entitiesData[entityId]; Widget result; @@ -146,7 +161,7 @@ class _MainPageState extends State with WidgetsBindingObserver { result = Switch( value: (entity["state"] == "on"), onChanged: ((state) { - _dataModel.callService( + _callService( entity["domain"], state ? "turn_on" : "turn_off", entityId); setState(() { _entitiesData[entityId]["state"] = state ? "on" : "off"; @@ -158,7 +173,7 @@ class _MainPageState extends State with WidgetsBindingObserver { width: 60.0, child: FlatButton( onPressed: (() { - _dataModel.callService(entity["domain"], "turn_on", entityId); + _callService(entity["domain"], "turn_on", entityId); }), child: Text( "Run", @@ -369,6 +384,17 @@ class _MainPageState extends State with WidgetsBindingObserver { ); break; } + + case 8: { + action = SnackBarAction( + label: "Reconnect", + onPressed: () { + _scaffoldKey?.currentState?.hideCurrentSnackBar(); + _refreshData(); + }, + ); + break; + } } Timer(Duration(seconds: 1), () { _scaffoldKey.currentState.hideCurrentSnackBar();