Resolves #122
This commit is contained in:
parent
54979b583b
commit
8fb0d61a84
@ -4,6 +4,7 @@ class HomeAssistant {
|
|||||||
String _webSocketAPIEndpoint;
|
String _webSocketAPIEndpoint;
|
||||||
String _password;
|
String _password;
|
||||||
String _authType;
|
String _authType;
|
||||||
|
bool _useLovelace;
|
||||||
|
|
||||||
IOWebSocketChannel _hassioChannel;
|
IOWebSocketChannel _hassioChannel;
|
||||||
SendMessageQueue _messageQueue;
|
SendMessageQueue _messageQueue;
|
||||||
@ -14,14 +15,18 @@ class HomeAssistant {
|
|||||||
int _subscriptionMessageId = 0;
|
int _subscriptionMessageId = 0;
|
||||||
int _configMessageId = 0;
|
int _configMessageId = 0;
|
||||||
int _userInfoMessageId = 0;
|
int _userInfoMessageId = 0;
|
||||||
|
int _lovelaceMessageId = 0;
|
||||||
EntityCollection entities;
|
EntityCollection entities;
|
||||||
GroupBasedUI ui;
|
HomeAssistantUI ui;
|
||||||
Map _instanceConfig = {};
|
Map _instanceConfig = {};
|
||||||
String _userName;
|
String _userName;
|
||||||
|
|
||||||
|
Map _rawLovelaceData;
|
||||||
|
|
||||||
Completer _fetchCompleter;
|
Completer _fetchCompleter;
|
||||||
Completer _statesCompleter;
|
Completer _statesCompleter;
|
||||||
Completer _servicesCompleter;
|
Completer _servicesCompleter;
|
||||||
|
Completer _lovelaceCompleter;
|
||||||
Completer _configCompleter;
|
Completer _configCompleter;
|
||||||
Completer _connectionCompleter;
|
Completer _connectionCompleter;
|
||||||
Completer _userInfoCompleter;
|
Completer _userInfoCompleter;
|
||||||
@ -45,10 +50,12 @@ class HomeAssistant {
|
|||||||
_messageQueue = SendMessageQueue(messageExpirationTime);
|
_messageQueue = SendMessageQueue(messageExpirationTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateConnectionSettings(String url, String password, String authType) {
|
void updateSettings(String url, String password, String authType, bool useLovelace) {
|
||||||
_webSocketAPIEndpoint = url;
|
_webSocketAPIEndpoint = url;
|
||||||
_password = password;
|
_password = password;
|
||||||
_authType = authType;
|
_authType = authType;
|
||||||
|
_useLovelace = useLovelace;
|
||||||
|
TheLogger.log("Debug", "Use lovelace is $_useLovelace");
|
||||||
}
|
}
|
||||||
|
|
||||||
Future fetch() {
|
Future fetch() {
|
||||||
@ -150,11 +157,15 @@ class HomeAssistant {
|
|||||||
_getData() async {
|
_getData() async {
|
||||||
List<Future> futures = [];
|
List<Future> futures = [];
|
||||||
futures.add(_getStates());
|
futures.add(_getStates());
|
||||||
|
if (_useLovelace) {
|
||||||
|
futures.add(_getLovelace());
|
||||||
|
}
|
||||||
futures.add(_getConfig());
|
futures.add(_getConfig());
|
||||||
futures.add(_getServices());
|
futures.add(_getServices());
|
||||||
futures.add(_getUserInfo());
|
futures.add(_getUserInfo());
|
||||||
try {
|
try {
|
||||||
await Future.wait(futures);
|
await Future.wait(futures);
|
||||||
|
_createUI();
|
||||||
_completeFetching(null);
|
_completeFetching(null);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
_completeFetching(error);
|
_completeFetching(error);
|
||||||
@ -202,6 +213,8 @@ class HomeAssistant {
|
|||||||
_parseConfig(data);
|
_parseConfig(data);
|
||||||
} else if (data["id"] == _statesMessageId) {
|
} else if (data["id"] == _statesMessageId) {
|
||||||
_parseEntities(data);
|
_parseEntities(data);
|
||||||
|
} else if (data["id"] == _lovelaceMessageId) {
|
||||||
|
_handleLovelace(data);
|
||||||
} else if (data["id"] == _servicesMessageId) {
|
} else if (data["id"] == _servicesMessageId) {
|
||||||
_parseServices(data);
|
_parseServices(data);
|
||||||
} else if (data["id"] == _userInfoMessageId) {
|
} else if (data["id"] == _userInfoMessageId) {
|
||||||
@ -247,6 +260,15 @@ class HomeAssistant {
|
|||||||
return _statesCompleter.future;
|
return _statesCompleter.future;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future _getLovelace() {
|
||||||
|
_lovelaceCompleter = new Completer();
|
||||||
|
_incrementMessageId();
|
||||||
|
_lovelaceMessageId = _currentMessageId;
|
||||||
|
_sendMessageRaw('{"id": $_lovelaceMessageId, "type": "lovelace/config"}', false);
|
||||||
|
|
||||||
|
return _lovelaceCompleter.future;
|
||||||
|
}
|
||||||
|
|
||||||
Future _getUserInfo() {
|
Future _getUserInfo() {
|
||||||
_userInfoCompleter = new Completer();
|
_userInfoCompleter = new Completer();
|
||||||
_incrementMessageId();
|
_incrementMessageId();
|
||||||
@ -336,28 +358,66 @@ class HomeAssistant {
|
|||||||
|
|
||||||
void _parseServices(response) {
|
void _parseServices(response) {
|
||||||
_servicesCompleter.complete();
|
_servicesCompleter.complete();
|
||||||
/*if (response["success"] == false) {
|
|
||||||
_servicesCompleter.completeError({"errorCode": 4, "errorMessage": response["error"]["message"]});
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
Map data = response["result"];
|
void _handleLovelace(response) {
|
||||||
Map result = {};
|
if (response["success"] == true) {
|
||||||
TheLogger.log("Debug","Parsing ${data.length} Home Assistant service domains");
|
_rawLovelaceData = response["result"];
|
||||||
data.forEach((domain, services) {
|
} else {
|
||||||
result[domain] = Map.from(services);
|
_rawLovelaceData = null;
|
||||||
services.forEach((serviceName, serviceData) {
|
}
|
||||||
if (_entitiesData.isExist("$domain.$serviceName")) {
|
_lovelaceCompleter.complete();
|
||||||
result[domain].remove(serviceName);
|
}
|
||||||
|
|
||||||
|
void _parseLovelace() {
|
||||||
|
ui = HomeAssistantUI();
|
||||||
|
TheLogger.log("debug","Parsing lovelace config");
|
||||||
|
TheLogger.log("debug","--Title: ${_rawLovelaceData["title"]}");
|
||||||
|
int viewCounter = 0;
|
||||||
|
TheLogger.log("debug","--Views count: ${_rawLovelaceData['views'].length}");
|
||||||
|
_rawLovelaceData["views"].forEach((rawView){
|
||||||
|
TheLogger.log("debug","----view id: ${rawView['id']}");
|
||||||
|
HAView view = HAView(
|
||||||
|
count: viewCounter,
|
||||||
|
id: rawView['id'],
|
||||||
|
name: rawView['title'],
|
||||||
|
iconName: rawView['icon']
|
||||||
|
);
|
||||||
|
view.cards.addAll(_createLovelaceCards(rawView["cards"] ?? []));
|
||||||
|
ui.views.add(
|
||||||
|
view
|
||||||
|
);
|
||||||
|
viewCounter += 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
List<HACard> _createLovelaceCards(List rawCards) {
|
||||||
|
List<HACard> result = [];
|
||||||
|
rawCards.forEach((rawCard){
|
||||||
|
if (rawCard["cards"] != null) {
|
||||||
|
TheLogger.log("debug","------card: ${rawCard['type']} has child cards");
|
||||||
|
result.addAll(_createLovelaceCards(rawCard["cards"]));
|
||||||
|
} else {
|
||||||
|
TheLogger.log("debug","------card: ${rawCard['type']}");
|
||||||
|
HACard card = HACard(
|
||||||
|
id: "card",
|
||||||
|
name: rawCard["title"]
|
||||||
|
);
|
||||||
|
rawCard["entities"]?.forEach((rawEntity) {
|
||||||
|
if (rawEntity is String) {
|
||||||
|
if (entities.isExist(rawEntity)) {
|
||||||
|
card.entities.add(entities.get(rawEntity));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (entities.isExist(rawEntity["entity"])) {
|
||||||
|
card.entities.add(entities.get(rawEntity["entity"]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
result.add(card);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
_servicesData = result;
|
return result;
|
||||||
_servicesCompleter.complete();
|
|
||||||
} catch (e) {
|
|
||||||
TheLogger.log("Error","Error parsing services. But they are not used :-)");
|
|
||||||
_servicesCompleter.complete();
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _parseEntities(response) async {
|
void _parseEntities(response) async {
|
||||||
@ -366,80 +426,46 @@ class HomeAssistant {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
entities.parse(response["result"]);
|
entities.parse(response["result"]);
|
||||||
|
_statesCompleter.complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _createUI() {
|
||||||
ui = GroupBasedUI();
|
if ((_useLovelace) && (_rawLovelaceData != null)) {
|
||||||
|
_parseLovelace();
|
||||||
|
} else {
|
||||||
|
ui = HomeAssistantUI();
|
||||||
int viewCounter = 0;
|
int viewCounter = 0;
|
||||||
//TODO add default_view
|
|
||||||
if (!entities.hasDefaultView) {
|
if (!entities.hasDefaultView) {
|
||||||
TheLogger.log("Debug","--Default view");
|
TheLogger.log("Debug", "--Default view");
|
||||||
HACView view = HACView(
|
HAView view = HAView(
|
||||||
count: viewCounter,
|
count: viewCounter,
|
||||||
id: "group.default_view",
|
id: "group.default_view",
|
||||||
name: "Home"
|
name: "Home",
|
||||||
|
childEntities: entities.filterEntitiesForDefaultView()
|
||||||
);
|
);
|
||||||
_createView(view, entities.filterEntitiesForDefaultView(), viewCounter);
|
|
||||||
ui.views.add(
|
ui.views.add(
|
||||||
view
|
view
|
||||||
);
|
);
|
||||||
viewCounter+=1;
|
viewCounter += 1;
|
||||||
}
|
}
|
||||||
entities.viewEntities.forEach((viewEntity) {
|
entities.viewEntities.forEach((viewEntity) {
|
||||||
TheLogger.log("Debug","--View: ${viewEntity.entityId}");
|
TheLogger.log("Debug", "--View: ${viewEntity.entityId}");
|
||||||
HACView view = HACView(
|
HAView view = HAView(
|
||||||
count: viewCounter,
|
count: viewCounter,
|
||||||
id: viewEntity.entityId,
|
id: viewEntity.entityId,
|
||||||
name: viewEntity.displayName
|
name: viewEntity.displayName,
|
||||||
|
childEntities: viewEntity.childEntities
|
||||||
);
|
);
|
||||||
view.linkedEntity = viewEntity;
|
view.linkedEntity = viewEntity;
|
||||||
_createView(view, viewEntity.childEntities, viewCounter);
|
|
||||||
ui.views.add(
|
ui.views.add(
|
||||||
view
|
view
|
||||||
);
|
);
|
||||||
viewCounter += 1;
|
viewCounter += 1;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
_statesCompleter.complete();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _createView(HACView view, List<Entity> childEntities, int viewCounter) {
|
Widget buildViews(BuildContext context, bool lovelace) {
|
||||||
List<HACCard> autoGeneratedCards = [];
|
|
||||||
childEntities.forEach((entity) {
|
|
||||||
if (entity.isBadge) {
|
|
||||||
view.badges.add(entity);
|
|
||||||
TheLogger.log("Debug","----Badge: ${entity.entityId}");
|
|
||||||
} else {
|
|
||||||
if (!entity.isGroup) {
|
|
||||||
String groupIdToAdd = "${entity.domain}.${entity.domain}$viewCounter";
|
|
||||||
if (autoGeneratedCards.every((HACCard card) => card.id != groupIdToAdd )) {
|
|
||||||
HACCard card = HACCard(
|
|
||||||
id: groupIdToAdd,
|
|
||||||
name: entity.domain
|
|
||||||
);
|
|
||||||
TheLogger.log("Debug","----Creating card: $groupIdToAdd");
|
|
||||||
card.entities.add(entity);
|
|
||||||
autoGeneratedCards.add(card);
|
|
||||||
} else {
|
|
||||||
autoGeneratedCards.firstWhere((card) => card.id == groupIdToAdd).entities.add(entity);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
TheLogger.log("Debug","----Card: ${entity.entityId}");
|
|
||||||
HACCard card = HACCard(
|
|
||||||
name: entity.displayName,
|
|
||||||
id: entity.entityId,
|
|
||||||
linkedEntity: entity
|
|
||||||
);
|
|
||||||
card.entities.addAll(entity.childEntities);
|
|
||||||
view.cards.add(card);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
view.cards.addAll(autoGeneratedCards);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget buildViews(BuildContext context) {
|
|
||||||
//return _viewBuilder.buildWidget(context);
|
|
||||||
return ui.build(context);
|
return ui.build(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ part 'entity.page.dart';
|
|||||||
part 'utils.class.dart';
|
part 'utils.class.dart';
|
||||||
part 'mdi.class.dart';
|
part 'mdi.class.dart';
|
||||||
part 'entity_collection.class.dart';
|
part 'entity_collection.class.dart';
|
||||||
part 'group_based_ui.dart';
|
part 'ui.dart';
|
||||||
|
|
||||||
EventBus eventBus = new EventBus();
|
EventBus eventBus = new EventBus();
|
||||||
const String appName = "HA Client";
|
const String appName = "HA Client";
|
||||||
@ -62,7 +62,7 @@ class HAClientApp extends StatelessWidget {
|
|||||||
initialRoute: "/",
|
initialRoute: "/",
|
||||||
routes: {
|
routes: {
|
||||||
"/": (context) => MainPage(title: 'HA Client'),
|
"/": (context) => MainPage(title: 'HA Client'),
|
||||||
"/connection-settings": (context) => ConnectionSettingsPage(title: "Connection Settings"),
|
"/connection-settings": (context) => ConnectionSettingsPage(title: "Settings"),
|
||||||
"/log-view": (context) => LogViewPage(title: "Log")
|
"/log-view": (context) => LogViewPage(title: "Log")
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -96,6 +96,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver {
|
|||||||
int _isLoading = 1;
|
int _isLoading = 1;
|
||||||
bool _settingsLoaded = false;
|
bool _settingsLoaded = false;
|
||||||
bool _accountMenuExpanded = false;
|
bool _accountMenuExpanded = false;
|
||||||
|
bool _useLovelaceUI;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -145,6 +146,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver {
|
|||||||
homeAssistantWebHost = "${prefs.getString('hassio-res-protocol')}://$domain:$port";
|
homeAssistantWebHost = "${prefs.getString('hassio-res-protocol')}://$domain:$port";
|
||||||
_password = prefs.getString('hassio-password');
|
_password = prefs.getString('hassio-password');
|
||||||
_authType = prefs.getString('hassio-auth-type');
|
_authType = prefs.getString('hassio-auth-type');
|
||||||
|
_useLovelaceUI = prefs.getBool('use-lovelace') ?? false;
|
||||||
if ((domain == null) || (port == null) || (_password == null) ||
|
if ((domain == null) || (port == null) || (_password == null) ||
|
||||||
(domain.length == 0) || (port.length == 0) || (_password.length == 0)) {
|
(domain.length == 0) || (port.length == 0) || (_password.length == 0)) {
|
||||||
throw("Check connection settings");
|
throw("Check connection settings");
|
||||||
@ -195,7 +197,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_refreshData() async {
|
_refreshData() async {
|
||||||
_homeAssistant.updateConnectionSettings(_webSocketApiEndpoint, _password, _authType);
|
_homeAssistant.updateSettings(_webSocketApiEndpoint, _password, _authType, _useLovelaceUI);
|
||||||
setState(() {
|
setState(() {
|
||||||
_hideErrorSnackBar();
|
_hideErrorSnackBar();
|
||||||
_isLoading = 1;
|
_isLoading = 1;
|
||||||
@ -239,14 +241,16 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver {
|
|||||||
|
|
||||||
List<Tab> buildUIViewTabs() {
|
List<Tab> buildUIViewTabs() {
|
||||||
List<Tab> result = [];
|
List<Tab> result = [];
|
||||||
|
|
||||||
if (_homeAssistant.ui.views.isNotEmpty) {
|
if (_homeAssistant.ui.views.isNotEmpty) {
|
||||||
_homeAssistant.ui.views.forEach((HACView view) {
|
_homeAssistant.ui.views.forEach((HAView view) {
|
||||||
if (view.linkedEntity == null) {
|
if (view.linkedEntity == null) {
|
||||||
result.add(
|
result.add(
|
||||||
Tab(
|
Tab(
|
||||||
icon:
|
icon:
|
||||||
Icon(
|
Icon(
|
||||||
MaterialDesignIcons.createIconDataFromIconName("mdi:home-assistant"),
|
MaterialDesignIcons.createIconDataFromIconName(
|
||||||
|
view.iconName ?? "mdi:home-assistant"),
|
||||||
size: 24.0,
|
size: 24.0,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -266,6 +270,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,7 +324,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver {
|
|||||||
menuItems.addAll([
|
menuItems.addAll([
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(Icons.settings),
|
leading: Icon(Icons.settings),
|
||||||
title: Text("Connection settings"),
|
title: Text("Settings"),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
Navigator.of(context).pushNamed('/connection-settings');
|
Navigator.of(context).pushNamed('/connection-settings');
|
||||||
@ -452,6 +457,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
primary: true,
|
||||||
bottom: empty ? null : TabBar(
|
bottom: empty ? null : TabBar(
|
||||||
tabs: buildUIViewTabs(),
|
tabs: buildUIViewTabs(),
|
||||||
isScrollable: true,
|
isScrollable: true,
|
||||||
@ -472,7 +478,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
_homeAssistant.buildViews(context)
|
_homeAssistant.buildViews(context, _useLovelaceUI)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@ class _ConnectionSettingsPageState extends State<ConnectionSettingsPage> {
|
|||||||
String _newSocketProtocol = "wss";
|
String _newSocketProtocol = "wss";
|
||||||
String _authType = "access_token";
|
String _authType = "access_token";
|
||||||
String _newAuthType = "access_token";
|
String _newAuthType = "access_token";
|
||||||
|
bool _useLovelace = false;
|
||||||
|
bool _newUseLovelace = false;
|
||||||
bool _edited = false;
|
bool _edited = false;
|
||||||
FocusNode _domainFocusNode;
|
FocusNode _domainFocusNode;
|
||||||
FocusNode _portFocusNode;
|
FocusNode _portFocusNode;
|
||||||
@ -46,6 +48,11 @@ class _ConnectionSettingsPageState extends State<ConnectionSettingsPage> {
|
|||||||
_hassioPassword = _newHassioPassword = prefs.getString("hassio-password") ?? "";
|
_hassioPassword = _newHassioPassword = prefs.getString("hassio-password") ?? "";
|
||||||
_socketProtocol = _newSocketProtocol = prefs.getString("hassio-protocol") ?? 'wss';
|
_socketProtocol = _newSocketProtocol = prefs.getString("hassio-protocol") ?? 'wss';
|
||||||
_authType = _newAuthType = prefs.getString("hassio-auth-type") ?? 'access_token';
|
_authType = _newAuthType = prefs.getString("hassio-auth-type") ?? 'access_token';
|
||||||
|
try {
|
||||||
|
_useLovelace = _newUseLovelace = prefs.getBool("use-lovelace") ?? false;
|
||||||
|
} catch (e) {
|
||||||
|
_useLovelace = _newUseLovelace = false;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +62,8 @@ class _ConnectionSettingsPageState extends State<ConnectionSettingsPage> {
|
|||||||
(_newHassioPort != _hassioPort) ||
|
(_newHassioPort != _hassioPort) ||
|
||||||
(_newHassioDomain != _hassioDomain) ||
|
(_newHassioDomain != _hassioDomain) ||
|
||||||
(_newSocketProtocol != _socketProtocol) ||
|
(_newSocketProtocol != _socketProtocol) ||
|
||||||
(_newAuthType != _authType));
|
(_newAuthType != _authType) ||
|
||||||
|
(_newUseLovelace != _useLovelace));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,6 +78,7 @@ class _ConnectionSettingsPageState extends State<ConnectionSettingsPage> {
|
|||||||
prefs.setString("hassio-protocol", _newSocketProtocol);
|
prefs.setString("hassio-protocol", _newSocketProtocol);
|
||||||
prefs.setString("hassio-res-protocol", _newSocketProtocol == "wss" ? "https" : "http");
|
prefs.setString("hassio-res-protocol", _newSocketProtocol == "wss" ? "https" : "http");
|
||||||
prefs.setString("hassio-auth-type", _newAuthType);
|
prefs.setString("hassio-auth-type", _newAuthType);
|
||||||
|
prefs.setBool("use-lovelace", _newUseLovelace);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -95,6 +104,13 @@ class _ConnectionSettingsPageState extends State<ConnectionSettingsPage> {
|
|||||||
body: ListView(
|
body: ListView(
|
||||||
padding: const EdgeInsets.all(20.0),
|
padding: const EdgeInsets.all(20.0),
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
Text(
|
||||||
|
"Connection settings",
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.black45,
|
||||||
|
fontSize: 20.0
|
||||||
|
),
|
||||||
|
),
|
||||||
new Row(
|
new Row(
|
||||||
children: [
|
children: [
|
||||||
Text("Use ssl (HTTPS)"),
|
Text("Use ssl (HTTPS)"),
|
||||||
@ -172,9 +188,31 @@ class _ConnectionSettingsPageState extends State<ConnectionSettingsPage> {
|
|||||||
},
|
},
|
||||||
focusNode: _passwordFocusNode,
|
focusNode: _passwordFocusNode,
|
||||||
onEditingComplete: _checkConfigChanged,
|
onEditingComplete: _checkConfigChanged,
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(top: 20.0),
|
||||||
|
child: Text(
|
||||||
|
"UI",
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.black45,
|
||||||
|
fontSize: 20.0
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
new Row(
|
||||||
|
children: [
|
||||||
|
Text("Use Lovelace UI"),
|
||||||
|
Switch(
|
||||||
|
value: _newUseLovelace,
|
||||||
|
onChanged: (value) {
|
||||||
|
_newUseLovelace = value;
|
||||||
|
_checkConfigChanged();
|
||||||
|
},
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
part of 'main.dart';
|
part of 'main.dart';
|
||||||
|
|
||||||
class GroupBasedUI {
|
class HomeAssistantUI {
|
||||||
List<HACView> views;
|
List<HAView> views;
|
||||||
|
|
||||||
GroupBasedUI() {
|
HomeAssistantUI() {
|
||||||
views = [];
|
views = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14,7 +14,6 @@ class GroupBasedUI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> _buildViews(BuildContext context) {
|
List<Widget> _buildViews(BuildContext context) {
|
||||||
TheLogger.log("Debug", "Building UI");
|
|
||||||
List<Widget> result = [];
|
List<Widget> result = [];
|
||||||
views.forEach((view) {
|
views.forEach((view) {
|
||||||
result.add(
|
result.add(
|
||||||
@ -26,19 +25,59 @@ class GroupBasedUI {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class HACView {
|
class HAView {
|
||||||
List<HACCard> cards = [];
|
List<HACard> cards = [];
|
||||||
List<Entity> badges = [];
|
List<Entity> badges = [];
|
||||||
Entity linkedEntity;
|
Entity linkedEntity;
|
||||||
String name;
|
String name;
|
||||||
String id;
|
String id;
|
||||||
|
String iconName;
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
HACView({
|
HAView({
|
||||||
this.name,
|
this.name,
|
||||||
this.id,
|
this.id,
|
||||||
this.count
|
this.count,
|
||||||
|
this.iconName,
|
||||||
|
List<Entity> childEntities
|
||||||
|
}) {
|
||||||
|
_fillView(childEntities ?? []);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _fillView(List<Entity> childEntities) {
|
||||||
|
List<HACard> autoGeneratedCards = [];
|
||||||
|
childEntities.forEach((entity) {
|
||||||
|
if (entity.isBadge) {
|
||||||
|
badges.add(entity);
|
||||||
|
TheLogger.log("Debug","----Badge: ${entity.entityId}");
|
||||||
|
} else {
|
||||||
|
if (!entity.isGroup) {
|
||||||
|
String groupIdToAdd = "${entity.domain}.${entity.domain}$count";
|
||||||
|
if (autoGeneratedCards.every((HACard card) => card.id != groupIdToAdd )) {
|
||||||
|
HACard card = HACard(
|
||||||
|
id: groupIdToAdd,
|
||||||
|
name: entity.domain
|
||||||
|
);
|
||||||
|
TheLogger.log("Debug","----Creating card: $groupIdToAdd");
|
||||||
|
card.entities.add(entity);
|
||||||
|
autoGeneratedCards.add(card);
|
||||||
|
} else {
|
||||||
|
autoGeneratedCards.firstWhere((card) => card.id == groupIdToAdd).entities.add(entity);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TheLogger.log("Debug","----Card: ${entity.entityId}");
|
||||||
|
HACard card = HACard(
|
||||||
|
name: entity.displayName,
|
||||||
|
id: entity.entityId,
|
||||||
|
linkedEntity: entity
|
||||||
|
);
|
||||||
|
card.entities.addAll(entity.childEntities);
|
||||||
|
cards.add(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
cards.addAll(autoGeneratedCards);
|
||||||
|
}
|
||||||
|
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return NewViewWidget(
|
return NewViewWidget(
|
||||||
@ -48,7 +87,7 @@ class HACView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class NewViewWidget extends StatefulWidget {
|
class NewViewWidget extends StatefulWidget {
|
||||||
final HACView view;
|
final HAView view;
|
||||||
|
|
||||||
const NewViewWidget({
|
const NewViewWidget({
|
||||||
Key key,
|
Key key,
|
||||||
@ -103,7 +142,7 @@ class NewViewWidgetState extends State<NewViewWidget> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
widget.view.cards.forEach((HACCard card){
|
widget.view.cards.forEach((HACard card){
|
||||||
result.add(
|
result.add(
|
||||||
card.build(context)
|
card.build(context)
|
||||||
);
|
);
|
||||||
@ -141,13 +180,13 @@ class NewViewWidgetState extends State<NewViewWidget> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class HACCard {
|
class HACard {
|
||||||
List<Entity> entities = [];
|
List<Entity> entities = [];
|
||||||
Entity linkedEntity;
|
Entity linkedEntity;
|
||||||
String name;
|
String name;
|
||||||
String id;
|
String id;
|
||||||
|
|
||||||
HACCard({
|
HACard({
|
||||||
this.name,
|
this.name,
|
||||||
this.id,
|
this.id,
|
||||||
this.linkedEntity
|
this.linkedEntity
|
||||||
@ -163,7 +202,7 @@ class HACCard {
|
|||||||
|
|
||||||
class NewCardWidget extends StatelessWidget {
|
class NewCardWidget extends StatelessWidget {
|
||||||
|
|
||||||
final HACCard card;
|
final HACard card;
|
||||||
|
|
||||||
const NewCardWidget({
|
const NewCardWidget({
|
||||||
Key key,
|
Key key,
|
Reference in New Issue
Block a user