Refactoring: Entity classes by action type. Wntity widget building in
entity
This commit is contained in:
parent
4b4fc338f6
commit
067ccfde02
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
161
lib/main.dart
161
lib/main.dart
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
Reference in New Issue
Block a user