[#12] Parse default_view to build main screen
This commit is contained in:
		@@ -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));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										152
									
								
								lib/main.dart
									
									
									
									
									
								
							
							
						
						
									
										152
									
								
								lib/main.dart
									
									
									
									
									
								
							@@ -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,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user