Refactoring: Entity classes by action type. Wntity widget building in

entity
This commit is contained in:
estevez 2018-09-29 13:49:25 +03:00
parent 4b4fc338f6
commit 067ccfde02
5 changed files with 180 additions and 148 deletions

View File

@ -1,6 +1,13 @@
part of 'main.dart'; part of 'main.dart';
class Entity { class Entity {
static Map<String, Color> stateIconColors = {
"on": Colors.amber,
"off": Color.fromRGBO(68, 115, 158, 1.0),
"unavailable": Colors.black12,
"unknown": Colors.black12,
"playing": Colors.amber
};
Map _attributes; Map _attributes;
String _domain; String _domain;
String _entityId; String _entityId;
@ -43,4 +50,123 @@ class Entity {
_state = rawData["state"]; _state = rawData["state"];
} }
Widget buildWidget() {
return SizedBox(
height: 34.0,
child: Row(
children: <Widget>[
Padding(
padding: EdgeInsets.fromLTRB(8.0, 0.0, 12.0, 0.0),
child: MaterialDesignIcons.createIconWidgetFromEntityData(this, 28.0, Entity.stateIconColors[_state] ?? Colors.blueGrey),
),
Expanded(
child: Text(
"${this.displayName}",
overflow: TextOverflow.fade,
softWrap: false,
style: TextStyle(
fontSize: 16.0
),
),
),
_buildActionWidget()
],
),
);
}
Widget _buildActionWidget() {
return Padding(
padding: EdgeInsets.fromLTRB(0.0, 0.0, 14.0, 0.0),
child: Text(
"${_state}${this.unitOfMeasurement}",
textAlign: TextAlign.right,
style: new TextStyle(
fontSize: 16.0,
)
)
);
}
}
class SwitchEntity extends Entity {
SwitchEntity(Map rawData) : super(rawData);
@override
Widget _buildActionWidget() {
return Switch(
value: this.isOn,
onChanged: ((switchState) {
eventBus.fire(new ServiceCallEvent(_domain, switchState ? "turn_on" : "turn_off", entityId, null));
}),
);
}
}
class ButtonEntity extends Entity {
ButtonEntity(Map rawData) : super(rawData);
@override
Widget _buildActionWidget() {
return FlatButton(
onPressed: (() {
eventBus.fire(new ServiceCallEvent(_domain, "turn_on", _entityId, null));
}),
child: Text(
"EXECUTE",
textAlign: TextAlign.right,
style: new TextStyle(fontSize: 16.0, color: Colors.blue),
),
);
}
}
class InputEntity extends Entity {
InputEntity(Map rawData) : super(rawData);
@override
Widget _buildActionWidget() {
if (this.isSlider) {
return Container(
width: 200.0,
child: Row(
children: <Widget>[
Expanded(
child: Slider(
min: this.minValue*10,
max: this.maxValue*10,
value: this.doubleState*10,
divisions: this.getValueDivisions(),
onChanged: (value) {
eventBus.fire(new StateChangedEvent(_entityId, (value.roundToDouble() / 10).toString(), true));
},
onChangeEnd: (value) {
eventBus.fire(new ServiceCallEvent(_domain, "set_value", _entityId,{"value": "${_state}"}));
},
),
),
Padding(
padding: EdgeInsets.only(right: 16.0),
child: Text(
"${_state}${this.unitOfMeasurement}",
textAlign: TextAlign.right,
style: new TextStyle(
fontSize: 16.0,
)
),
)
],
),
);
} else {
//TODO draw box instead of slider
return Text("Not implemented");
}
}
} }

View File

@ -26,6 +26,30 @@ class EntityCollection {
}); });
} }
Entity _createEntityInstance(rawEntityData) {
switch (rawEntityData["entity_id"].split(".")[0]) {
case "automation":
case "input_boolean ":
case "switch":
case "light": {
return SwitchEntity(rawEntityData);
}
case "script":
case "scene": {
return ButtonEntity(rawEntityData);
}
case "input_number": {
return InputEntity(rawEntityData);
}
default: {
return Entity(rawEntityData);
}
}
}
void updateState(Map rawStateData) { void updateState(Map rawStateData) {
if (isExist(rawStateData["entity_id"])) { if (isExist(rawStateData["entity_id"])) {
updateFromRaw(rawStateData["new_state"] ?? rawStateData["old_state"]); updateFromRaw(rawStateData["new_state"] ?? rawStateData["old_state"]);
@ -39,7 +63,7 @@ class EntityCollection {
} }
Entity addFromRaw(Map rawEntityData) { Entity addFromRaw(Map rawEntityData) {
Entity entity = Entity(rawEntityData); Entity entity = _createEntityInstance(rawEntityData);
_entities[entity.entityId] = entity; _entities[entity.entityId] = entity;
return entity; return entity;
} }

View File

@ -185,7 +185,7 @@ class HomeAssistant {
void _handleEntityStateChange(Map eventData) { void _handleEntityStateChange(Map eventData) {
TheLogger.log("Debug", "Parsing new state for ${eventData['entity_id']}"); TheLogger.log("Debug", "Parsing new state for ${eventData['entity_id']}");
_entities.updateState(eventData); _entities.updateState(eventData);
eventBus.fire(new StateChangedEvent(eventData["entity_id"])); eventBus.fire(new StateChangedEvent(eventData["entity_id"], null, false));
} }
void _parseConfig(Map data) { void _parseConfig(Map data) {

View File

@ -85,14 +85,9 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver {
String _lastErrorMessage = ""; String _lastErrorMessage = "";
StreamSubscription _stateSubscription; StreamSubscription _stateSubscription;
StreamSubscription _settingsSubscription; StreamSubscription _settingsSubscription;
StreamSubscription _serviceCallSubscription;
bool _isLoading = true; bool _isLoading = true;
Map<String, Color> _stateIconColors = {
"on": Colors.amber,
"off": Color.fromRGBO(68, 115, 158, 1.0),
"unavailable": Colors.black12,
"unknown": Colors.black12,
"playing": Colors.amber
};
Map<String, Color> _badgeColors = { Map<String, Color> _badgeColors = {
"default": Color.fromRGBO(223, 76, 30, 1.0), "default": Color.fromRGBO(223, 76, 30, 1.0),
"binary_sensor": Color.fromRGBO(3, 155, 229, 1.0) "binary_sensor": Color.fromRGBO(3, 155, 229, 1.0)
@ -146,9 +141,17 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver {
if (_stateSubscription != null) _stateSubscription.cancel(); if (_stateSubscription != null) _stateSubscription.cancel();
_stateSubscription = eventBus.on<StateChangedEvent>().listen((event) { _stateSubscription = eventBus.on<StateChangedEvent>().listen((event) {
setState(() { setState(() {
_entities = _homeAssistant.entities; if (event.setToCollection) {
_entities
.get(event.entityId)
.state = event.newState;
}
}); });
}); });
if (_serviceCallSubscription != null) _serviceCallSubscription.cancel();
_serviceCallSubscription = eventBus.on<ServiceCallEvent>().listen((event) {
_callService(event.domain, event.service, event.entityId, event.additionalParams);
});
} }
_refreshData() async { _refreshData() async {
@ -384,151 +387,18 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver {
List<Widget> _buildCardBody(List ids) { List<Widget> _buildCardBody(List ids) {
List<Widget> entities = []; List<Widget> entities = [];
ids.forEach((id) { ids.forEach((id) {
var data = _entities.get(id); var entity = _entities.get(id);
if (data != null) { if (entity != null) {
entities.add( entities.add(
Padding( Padding(
padding: EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0), padding: EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0),
child: SizedBox( child: entity.buildWidget(),
height: 34.0, ));
child: Row(
children: <Widget>[
Padding(
padding: EdgeInsets.fromLTRB(8.0, 0.0, 12.0, 0.0),
child: MaterialDesignIcons.createIconWidgetFromEntityData(data, 28.0, _stateIconColors[data.state] ?? Colors.blueGrey),
),
Expanded(
child: Text(
"${data.displayName}",
overflow: TextOverflow.fade,
softWrap: false,
style: TextStyle(
fontSize: 16.0
),
),
),
_buildEntityActionWidget(data)
],
),
),
)
/*new ListTile(
leading: MaterialDesignIcons.createIconWidgetFromEntityData(data, 28.0, _stateIconColors[data.state] ?? Colors.blueGrey),
//subtitle: Text("${data['entity_id']}"),
trailing: _buildEntityActionWidget(data),
title: Text(
"${data.displayName}",
overflow: TextOverflow.fade,
softWrap: false,
),
)*/);
} }
}); });
return entities; return entities;
} }
Widget _buildEntityActionWidget(Entity entity) {
String entityId = entity.entityId;
Widget result;
switch (entity.domain) {
case "automation":
case "input_boolean":
case "switch":
case "light": {
result = Switch(
value: entity.isOn,
onChanged: ((state) {
_callService(
entity.domain, state ? "turn_on" : "turn_off", entityId, null
);
//TODO remove after checking if state will chenge without setState but after socket event
/*setState(() {
_entities[entityId]["state"] = state ? "on" : "off";
});*/
}),
);
break;
}
case "script":
case "scene": {
result = FlatButton(
onPressed: (() {
_callService(entity.domain, "turn_on", entityId, null);
}),
child: Text(
"EXECUTE",
textAlign: TextAlign.right,
style: new TextStyle(fontSize: 16.0, color: Colors.blue),
),
);
break;
}
case "input_number": {
if (entity.isSlider) {
result = Container(
width: 200.0,
child: Row(
children: <Widget>[
Expanded(
child: Slider(
min: entity.minValue*10,
max: entity.maxValue*10,
value: entity.doubleState*10,
divisions: entity.getValueDivisions(),
onChanged: (value) {
setState(() {
entity.state = (value.roundToDouble() / 10).toString();
});
},
onChangeEnd: (value) {
_callService(entity.domain, "set_value", entityId,
{"value": "${entity.state}"});
},
),
),
Padding(
padding: EdgeInsets.only(right: 16.0),
child: Text(
"${entity.state}${entity.unitOfMeasurement}",
textAlign: TextAlign.right,
style: new TextStyle(
fontSize: 16.0,
)
),
)
],
),
);
} else {
//TODO draw box instead of slider
}
break;
}
default: {
result = Padding(
padding: EdgeInsets.fromLTRB(0.0, 0.0, 14.0, 0.0),
child: Text(
"${entity.state}${entity.unitOfMeasurement}",
textAlign: TextAlign.right,
style: new TextStyle(
fontSize: 16.0,
)
)
);
}
}
/*return SizedBox(
width: 60.0,
// height: double.infinity,
child: result
);*/
return result;
}
List<Tab> buildUIViewTabs() { List<Tab> buildUIViewTabs() {
List<Tab> result = []; List<Tab> result = [];
if ((_entities != null) && (!_homeAssistant.uiBuilder.isEmpty)) { if ((_entities != null) && (!_homeAssistant.uiBuilder.isEmpty)) {
@ -731,6 +601,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver {
WidgetsBinding.instance.removeObserver(this); WidgetsBinding.instance.removeObserver(this);
if (_stateSubscription != null) _stateSubscription.cancel(); if (_stateSubscription != null) _stateSubscription.cancel();
if (_settingsSubscription != null) _settingsSubscription.cancel(); if (_settingsSubscription != null) _settingsSubscription.cancel();
if (_serviceCallSubscription != null) _serviceCallSubscription.cancel();
_homeAssistant.closeConnection(); _homeAssistant.closeConnection();
super.dispose(); super.dispose();
} }

View File

@ -44,8 +44,10 @@ class haUtils {
class StateChangedEvent { class StateChangedEvent {
String entityId; String entityId;
String newState;
bool setToCollection;
StateChangedEvent(this.entityId); StateChangedEvent(this.entityId, this.newState, this.setToCollection);
} }
class SettingsChangedEvent { class SettingsChangedEvent {
@ -53,3 +55,12 @@ class SettingsChangedEvent {
SettingsChangedEvent(this.reconnect); SettingsChangedEvent(this.reconnect);
} }
class ServiceCallEvent {
String domain;
String service;
String entityId;
Map<String, String> additionalParams;
ServiceCallEvent(this.domain, this.service, this.entityId, this.additionalParams);
}