[#12] Parse default_view to build main screen

This commit is contained in:
estevez 2018-09-15 12:56:42 +03:00
parent cd17eabb63
commit b9e07abba9
2 changed files with 131 additions and 50 deletions

View File

@ -150,11 +150,6 @@ class HassioDataModel {
} }
void _parseEntities(List data) async { void _parseEntities(List data) async {
Map switchServices = {
"turn_on": {},
"turn_off": {},
"toggle": {}
};
debugPrint("Parsing ${data.length} Home Assistant entities"); debugPrint("Parsing ${data.length} Home Assistant entities");
data.forEach((entity) { data.forEach((entity) {
var composedEntity = Map.from(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["display_name"] = "${entity["attributes"]!=null ? entity["attributes"]["friendly_name"] ?? entity["attributes"]["name"] : "_"}";
composedEntity["domain"] = entityDomain; composedEntity["domain"] = entityDomain;
if ((entityDomain == "automation") || (entityDomain == "light") || (entityDomain == "switch") || (entityDomain == "script")) { if ((entityDomain == "automation") || (entityDomain == "switch")) {
composedEntity["services"] = Map.from(switchServices); 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); _entitiesData[entityId] = Map.from(composedEntity);
}); });
//Gethering information for UI
var defaultView = _entitiesData["group.default_view"]; var defaultView = _entitiesData["group.default_view"];
debugPrint("Gethering default view"); debugPrint("Gethering default view");
if (defaultView!= null) { if (defaultView!= null) {
_uiStructure["standalone"] = [];
_uiStructure["groups"] = [];
defaultView["attributes"]["entity_id"].forEach((entityId) { defaultView["attributes"]["entity_id"].forEach((entityId) {
if (_entitiesData[entityId]["domain"] != "group") { if (_entitiesData[entityId]["domain"] != "group") {
_uiStructure[entityId] = _entitiesData[entityId]; _uiStructure["standalone"].add(entityId);
} else { } else {
Map newGroup = {};
newGroup["entity_id"] = entityId;
newGroup["friendly_name"] = (_entitiesData[entityId]['attributes']!=null) ? (_entitiesData[entityId]['attributes']['friendly_name'] ?? "") : "";
newGroup["children"] = List<String>();
_entitiesData[entityId]["attributes"]["entity_id"].forEach((groupedEntityId) { _entitiesData[entityId]["attributes"]["entity_id"].forEach((groupedEntityId) {
_uiStructure[groupedEntityId] = _entitiesData[groupedEntityId]; newGroup["children"].add(groupedEntityId);
}); });
_uiStructure["groups"].add(Map.from(newGroup));
} }
}); });
} }

View File

@ -1,5 +1,6 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:async'; import 'dart:async';
import 'package:flutter/rendering.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -43,6 +44,7 @@ class _MainPageState extends State<MainPage> {
HassioDataModel _dataModel; HassioDataModel _dataModel;
Map _entitiesData; Map _entitiesData;
Map _uiStructure;
String _dataModelErrorMessage = ""; String _dataModelErrorMessage = "";
bool loading = true; bool loading = true;
@ -68,7 +70,8 @@ class _MainPageState extends State<MainPage> {
if (_dataModel != null) { if (_dataModel != null) {
await _dataModel.fetch().then((result) { await _dataModel.fetch().then((result) {
setState(() { setState(() {
_entitiesData = _dataModel._uiStructure; _entitiesData = _dataModel.entities;
_uiStructure = _dataModel.uiStructure;
loading = false; loading = false;
}); });
}).catchError((e) { }).catchError((e) {
@ -80,60 +83,127 @@ class _MainPageState extends State<MainPage> {
} }
} }
Widget buildEntityButtons(String entityId) { Widget _buildEntityAction(String entityId) {
if (_entitiesData[entityId]["services"] == null || _entitiesData[entityId]["services"].length == 0) { var entity = _entitiesData[entityId];
return new Container(width: 0.0, height: 0.0); 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<Widget> 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) { /* Widget buildEntityCard(String entityId) {
return Card( var data = _entitiesData[entityId];
child: new Column( if (data != null) {
mainAxisSize: MainAxisSize.min, return Card(
children: <Widget>[ child: new Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
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: <Widget>[
new Text("Unknown entity: $entityId")
],
),
);
}
}*/
Card _buildEntityGroup(List<String> ids, String name) {
List<Widget> 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<Widget> _buildEntityGroupBody(List<String> ids) {
List<Widget> entities = [];
ids.forEach((id){
var data = _entitiesData[id];
entities.add(
new ListTile( new ListTile(
leading: const Icon(Icons.device_hub), leading: const Icon(Icons.device_hub),
subtitle: Text("${data['entity_id']}"), //subtitle: Text("${data['entity_id']}"),
trailing: Text("${data["state"]}"), trailing: _buildEntityAction(id),
title: Text("${data["display_name"]}"), title: Text(
), "${data["display_name"]}",
new ButtonTheme.bar( // make buttons use the appropriate styles for cards overflow: TextOverflow.ellipsis,
child: buildEntityButtons(data['entity_id']), ),
), )
], );
), });
); return entities;
} }
List<Widget> buildEntitiesView() { List<Widget> buildEntitiesView() {
if (_entitiesData != null) { if ((_entitiesData != null)&&(_uiStructure != null)) {
List<Widget> result = []; List<Widget> result = [];
if (_dataModelErrorMessage.length == 0) { if (_dataModelErrorMessage.length == 0) {
_entitiesData.forEach((key, data) { _uiStructure["standalone"].forEach((entityId) {
if (data != null) { result.add(_buildEntityGroup([entityId], ""));
result.add(buildEntityCard(data)); });
} else { _uiStructure["groups"].forEach((group) {
debugPrint("Unknown entity: $key"); result.add(_buildEntityGroup(group["children"], group["friendly_name"].toString()));
}
}); });
} else { } else {
result.add(Text(_dataModelErrorMessage)); //TODO
//result.add(Text(_dataModelErrorMessage));
} }
return result; return result;
} else { } else {
return [Container(width: 0.0, height: 0.0)]; //TODO
return [];
} }
} }
@ -196,7 +266,7 @@ class _MainPageState extends State<MainPage> {
), ),
), ),
body: ListView( body: ListView(
children: buildEntitiesView(), children: buildEntitiesView()
), ),
floatingActionButton: new FloatingActionButton( floatingActionButton: new FloatingActionButton(
onPressed: _refreshData, onPressed: _refreshData,