From b9e07abba9e0886f1739b23495e50a119ed68af9 Mon Sep 17 00:00:00 2001 From: estevez Date: Sat, 15 Sep 2018 12:56:42 +0300 Subject: [PATCH] [#12] Parse default_view to build main screen --- lib/data_model.dart | 29 ++++++--- lib/main.dart | 152 ++++++++++++++++++++++++++++++++------------ 2 files changed, 131 insertions(+), 50 deletions(-) diff --git a/lib/data_model.dart b/lib/data_model.dart index 588febf..d780f1b 100644 --- a/lib/data_model.dart +++ b/lib/data_model.dart @@ -150,11 +150,6 @@ class HassioDataModel { } void _parseEntities(List data) async { - Map switchServices = { - "turn_on": {}, - "turn_off": {}, - "toggle": {} - }; debugPrint("Parsing ${data.length} Home Assistant entities"); data.forEach((entity) { var composedEntity = Map.from(entity); @@ -164,22 +159,38 @@ class HassioDataModel { composedEntity["display_name"] = "${entity["attributes"]!=null ? entity["attributes"]["friendly_name"] ?? entity["attributes"]["name"] : "_"}"; composedEntity["domain"] = entityDomain; - if ((entityDomain == "automation") || (entityDomain == "light") || (entityDomain == "switch") || (entityDomain == "script")) { - composedEntity["services"] = Map.from(switchServices); + if ((entityDomain == "automation") || (entityDomain == "switch")) { + composedEntity["actionType"] = "switch"; + } else if (entityDomain == "light") { + composedEntity["actionType"] = "stateIcon"; + } else if ((entityDomain == "script") || (entityDomain == "scene")) { + composedEntity["actionType"] = "statelessIcon"; + } else { + composedEntity["actionType"] = "stateText"; } _entitiesData[entityId] = Map.from(composedEntity); }); + + //Gethering information for UI var defaultView = _entitiesData["group.default_view"]; debugPrint("Gethering default view"); if (defaultView!= null) { + _uiStructure["standalone"] = []; + _uiStructure["groups"] = []; defaultView["attributes"]["entity_id"].forEach((entityId) { if (_entitiesData[entityId]["domain"] != "group") { - _uiStructure[entityId] = _entitiesData[entityId]; + _uiStructure["standalone"].add(entityId); } else { + Map newGroup = {}; + newGroup["entity_id"] = entityId; + newGroup["friendly_name"] = (_entitiesData[entityId]['attributes']!=null) ? (_entitiesData[entityId]['attributes']['friendly_name'] ?? "") : ""; + newGroup["children"] = List(); _entitiesData[entityId]["attributes"]["entity_id"].forEach((groupedEntityId) { - _uiStructure[groupedEntityId] = _entitiesData[groupedEntityId]; + newGroup["children"].add(groupedEntityId); + }); + _uiStructure["groups"].add(Map.from(newGroup)); } }); } diff --git a/lib/main.dart b/lib/main.dart index 1ab43e4..00b4fd8 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,6 @@ import 'dart:convert'; import 'dart:async'; +import 'package:flutter/rendering.dart'; import 'package:http/http.dart' as http; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -43,6 +44,7 @@ class _MainPageState extends State { HassioDataModel _dataModel; Map _entitiesData; + Map _uiStructure; String _dataModelErrorMessage = ""; bool loading = true; @@ -68,7 +70,8 @@ class _MainPageState extends State { if (_dataModel != null) { await _dataModel.fetch().then((result) { setState(() { - _entitiesData = _dataModel._uiStructure; + _entitiesData = _dataModel.entities; + _uiStructure = _dataModel.uiStructure; loading = false; }); }).catchError((e) { @@ -80,60 +83,127 @@ class _MainPageState extends State { } } - Widget buildEntityButtons(String entityId) { - if (_entitiesData[entityId]["services"] == null || _entitiesData[entityId]["services"].length == 0) { - return new Container(width: 0.0, height: 0.0); + Widget _buildEntityAction(String entityId) { + var entity = _entitiesData[entityId]; + if (entity["actionType"] == "switch") { + return Switch( + value: (entity["state"] == "on"), + onChanged: ((state) { + _dataModel.callService(entity["domain"], state ? "turn_on" : "turn_off", entityId); + setState(() { + _entitiesData[entityId]["state"] = state ? "on" : "off"; + }); + }), + ); + } else { + return Text( + "${entity["state"]}" + ); } - List buttons = []; - _entitiesData[entityId]["services"].forEach((key, value) { - buttons.add(new FlatButton( - child: Text('$key'), - onPressed: () { - _dataModel.callService(_entitiesData[entityId]["domain"], key, _entitiesData[entityId]["entity_id"]); - }, - )); - }); - return ButtonBar( - children: buttons - ); } - Widget buildEntityCard(data) { - return Card( - child: new Column( - mainAxisSize: MainAxisSize.min, - children: [ +/* Widget buildEntityCard(String entityId) { + var data = _entitiesData[entityId]; + if (data != null) { + return Card( + child: new Column( + mainAxisSize: MainAxisSize.min, + children: [ + new ListTile( + leading: const Icon(Icons.device_hub), + subtitle: Text("${data['entity_id']}"), + trailing: Text("${data["state"]}"), + title: Text("${data["display_name"]}"), + ), + new ButtonTheme + .bar( // make buttons use the appropriate styles for cards + child: buildEntityButtons(data['entity_id']), + ), + ], + ), + ); + } else { + return Card( + child: new Column( + mainAxisSize: MainAxisSize.min, + children: [ + new Text("Unknown entity: $entityId") + ], + ), + ); + } + }*/ + + Card _buildEntityGroup(List ids, String name) { + List body = []; + body.add(_buildEntityGroupHeader(name)); + body.addAll(_buildEntityGroupBody(ids)); + Card result = Card( + child: new Column( + mainAxisSize: MainAxisSize.min, + children: body + ) + ); + return result; + } + + Widget _buildEntityGroupHeader(String name) { + var result; + if (name.length > 0) { + result = new ListTile( + //leading: const Icon(Icons.device_hub), + //subtitle: Text(".."), + //trailing: Text("${data["state"]}"), + title: Text( + "$name", + textAlign: TextAlign.left, + overflow: TextOverflow.ellipsis, + style: new TextStyle(fontWeight: FontWeight.bold, fontSize: 25.0) + ), + ); + } else { + result = new Container(width: 0.0, height: 0.0); + } + return result; + } + + List _buildEntityGroupBody(List ids) { + List entities = []; + ids.forEach((id){ + var data = _entitiesData[id]; + entities.add( new ListTile( leading: const Icon(Icons.device_hub), - subtitle: Text("${data['entity_id']}"), - trailing: Text("${data["state"]}"), - title: Text("${data["display_name"]}"), - ), - new ButtonTheme.bar( // make buttons use the appropriate styles for cards - child: buildEntityButtons(data['entity_id']), - ), - ], - ), - ); + //subtitle: Text("${data['entity_id']}"), + trailing: _buildEntityAction(id), + title: Text( + "${data["display_name"]}", + overflow: TextOverflow.ellipsis, + ), + ) + ); + }); + return entities; } List buildEntitiesView() { - if (_entitiesData != null) { + if ((_entitiesData != null)&&(_uiStructure != null)) { List result = []; if (_dataModelErrorMessage.length == 0) { - _entitiesData.forEach((key, data) { - if (data != null) { - result.add(buildEntityCard(data)); - } else { - debugPrint("Unknown entity: $key"); - } + _uiStructure["standalone"].forEach((entityId) { + result.add(_buildEntityGroup([entityId], "")); + }); + _uiStructure["groups"].forEach((group) { + result.add(_buildEntityGroup(group["children"], group["friendly_name"].toString())); }); } else { - result.add(Text(_dataModelErrorMessage)); + //TODO + //result.add(Text(_dataModelErrorMessage)); } return result; } else { - return [Container(width: 0.0, height: 0.0)]; + //TODO + return []; } } @@ -196,7 +266,7 @@ class _MainPageState extends State { ), ), body: ListView( - children: buildEntitiesView(), + children: buildEntitiesView() ), floatingActionButton: new FloatingActionButton( onPressed: _refreshData,