From 6e604440c0a1e155afa6544f92cc3054cd2f616b Mon Sep 17 00:00:00 2001 From: Yegor Vialov Date: Tue, 16 Oct 2018 15:14:54 +0300 Subject: [PATCH] Resolves #106 Climate support --- lib/entity_class/entity.class.dart | 36 ++-- lib/entity_class/stateful_widgets.dart | 230 ++++++++++++++++++------- lib/main.dart | 2 +- pubspec.yaml | 2 +- 4 files changed, 183 insertions(+), 87 deletions(-) diff --git a/lib/entity_class/entity.class.dart b/lib/entity_class/entity.class.dart index c5a0125..14e6823 100644 --- a/lib/entity_class/entity.class.dart +++ b/lib/entity_class/entity.class.dart @@ -298,9 +298,14 @@ class ClimateEntity extends Entity { List get swingList => attributes["swing_list"] != null ? (attributes["swing_list"] as List).cast() : null; - double get temperature => _getTemperature(); - double get targetHigh => _getTargetHigh(); - double get targetLow => _getTargetLow(); + double get temperature => _getDoubleAttributeValue('temperature'); + double get targetHigh => _getDoubleAttributeValue('target_temp_high'); + double get targetLow => _getDoubleAttributeValue('target_temp_low'); + double get maxTemp => _getDoubleAttributeValue('max_temp') ?? 100.0; + double get minTemp => _getDoubleAttributeValue('min_temp') ?? -100.0; + double get targetHumidity => _getDoubleAttributeValue('humidity'); + double get maxHumidity => _getDoubleAttributeValue('max_humidity'); + double get minHumidity => _getDoubleAttributeValue('min_humidity'); String get operationMode => attributes['operation_mode']; String get fanMode => attributes['fan_mode']; String get swingMode => attributes['swing_mode']; @@ -320,8 +325,8 @@ class ClimateEntity extends Entity { return ClimateControlWidget(); } - double _getTemperature() { - var temp1 = attributes['temperature']; + double _getDoubleAttributeValue(String attributeName) { + var temp1 = attributes["$attributeName"]; if (temp1 is int) { return temp1.toDouble(); } else if (temp1 is double) { @@ -331,27 +336,6 @@ class ClimateEntity extends Entity { } } - double _getTargetHigh() { - var temp1 = attributes['target_temp_high']; - if (temp1 is int) { - return temp1.toDouble(); - } else if (temp1 is double) { - return temp1; - } else { - return null; - } - } - - double _getTargetLow() { - var temp1 = attributes['target_temp_low']; - if (temp1 is int) { - return temp1.toDouble(); - } else if (temp1 is double) { - return temp1; - } else { - return null; - } - } } class SelectEntity extends Entity { diff --git a/lib/entity_class/stateful_widgets.dart b/lib/entity_class/stateful_widgets.dart index cbf5199..26cbc33 100644 --- a/lib/entity_class/stateful_widgets.dart +++ b/lib/entity_class/stateful_widgets.dart @@ -240,13 +240,13 @@ class _ClimateControlWidgetState extends State { double _tmpTemperature = 0.0; double _tmpTargetLow = 0.0; double _tmpTargetHigh = 0.0; + double _tmpTargetHumidity = 0.0; String _tmpOperationMode; String _tmpFanMode; String _tmpSwingMode; bool _tmpAwayMode = false; bool _tmpIsOff = false; bool _tmpAuxHeat = false; - double _temperatureStep = 0.2; void _resetVars(ClimateEntity entity) { _tmpTemperature = entity.temperature; @@ -258,38 +258,39 @@ class _ClimateControlWidgetState extends State { _tmpAwayMode = entity.awayMode; _tmpIsOff = entity.isOff; _tmpAuxHeat = entity.auxHeat; + _tmpTargetHumidity = entity.targetHumidity; _showPending = false; _changedHere = false; } - void _temperatureUp(ClimateEntity entity) { - _tmpTemperature += _temperatureStep; + void _temperatureUp(ClimateEntity entity, double step) { + _tmpTemperature = ((_tmpTemperature + step) <= entity.maxTemp) ? _tmpTemperature + step : entity.maxTemp; _setTemperature(entity); } - void _temperatureDown(ClimateEntity entity) { - _tmpTemperature -= _temperatureStep; + void _temperatureDown(ClimateEntity entity, double step) { + _tmpTemperature = ((_tmpTemperature - step) >= entity.minTemp) ? _tmpTemperature - step : entity.minTemp; _setTemperature(entity); } - void _targetLowUp(ClimateEntity entity) { - _tmpTargetLow += _temperatureStep; + void _targetLowUp(ClimateEntity entity, double step) { + _tmpTargetLow = ((_tmpTargetLow + step) <= entity.maxTemp) ? _tmpTargetLow + step : entity.maxTemp; _setTargetTemp(entity); } - void _targetLowDown(ClimateEntity entity) { - _tmpTargetLow -= _temperatureStep; + void _targetLowDown(ClimateEntity entity, double step) { + _tmpTargetLow = ((_tmpTargetLow - step) >= entity.minTemp) ? _tmpTargetLow - step : entity.minTemp; _setTargetTemp(entity); } - void _targetHighUp(ClimateEntity entity) { - _tmpTargetHigh += _temperatureStep; + void _targetHighUp(ClimateEntity entity, double step) { + _tmpTargetHigh = ((_tmpTargetHigh + step) <= entity.maxTemp) ? _tmpTargetHigh + step : entity.maxTemp; _setTargetTemp(entity); } - void _targetHighDown(ClimateEntity entity) { - _tmpTargetHigh -= _temperatureStep; + void _targetHighDown(ClimateEntity entity, double step) { + _tmpTargetHigh = ((_tmpTargetHigh - step) >= entity.minTemp) ? _tmpTargetHigh - step : entity.minTemp; _setTargetTemp(entity); } @@ -312,6 +313,15 @@ class _ClimateControlWidgetState extends State { }); } + void _setTargetHumidity(ClimateEntity entity, double value) { + setState(() { + _tmpTargetHumidity = value.roundToDouble(); + _changedHere = true; + eventBus.fire(new ServiceCallEvent(entity.domain, "set_humidity", entity.entityId,{"humidity": "$_tmpTargetHumidity"})); + _resetStateTimer(entity); + }); + } + void _setOperationMode(ClimateEntity entity, value) { setState(() { _tmpOperationMode = value; @@ -394,6 +404,7 @@ class _ClimateControlWidgetState extends State { children: [ _buildOnOffControl(entity), _buildTemperatureControls(entity), + _buildHumidityControls(entity), _buildOperationControl(entity), _buildFanControl(entity), _buildSwingControl(entity), @@ -451,7 +462,7 @@ class _ClimateControlWidgetState extends State { } Widget _buildAuxHeatControl(ClimateEntity entity) { - if (entity.supportAwayMode) { + if (entity.supportAuxHeat ) { return Row( children: [ Expanded( @@ -568,96 +579,197 @@ class _ClimateControlWidgetState extends State { Widget _buildTemperatureControls(ClimateEntity entity) { List result = []; + bool empty = true; if (entity.supportTargetTemperature) { + empty = false; result.addAll([ - Expanded( - child: Text( - "$_tmpTemperature", - style: TextStyle( - fontSize: entity.largeFontSize, - color: _showPending ? Colors.red : Colors.black - ), + Text( + "$_tmpTemperature", + style: TextStyle( + fontSize: entity.largeFontSize, + color: _showPending ? Colors.red : Colors.black ), ), Column( children: [ IconButton( - icon: Icon(Icons.keyboard_arrow_up), + icon: Icon(MaterialDesignIcons.createIconDataFromIconName('mdi:chevron-up')), iconSize: 30.0, - onPressed: () => _temperatureUp(entity), + onPressed: () => _temperatureUp(entity, 0.1), ), IconButton( - icon: Icon(Icons.keyboard_arrow_down), + icon: Icon(MaterialDesignIcons.createIconDataFromIconName('mdi:chevron-down')), iconSize: 30.0, - onPressed: () => _temperatureDown(entity), + onPressed: () => _temperatureDown(entity, 0.1), + ) + ], + ), + Column( + children: [ + IconButton( + icon: Icon(MaterialDesignIcons.createIconDataFromIconName('mdi:chevron-double-up')), + iconSize: 30.0, + onPressed: () => _temperatureUp(entity, 0.5), + ), + IconButton( + icon: Icon(MaterialDesignIcons.createIconDataFromIconName('mdi:chevron-double-down')), + iconSize: 30.0, + onPressed: () => _temperatureDown(entity, 0.5), ) ], ) ]); } else if (entity.supportTargetTemperatureHigh && entity.supportTargetTemperatureLow) { + empty = false; result.addAll([ - Expanded( - child: Text( - "$_tmpTargetLow", - style: TextStyle( - fontSize: entity.largeFontSize, - color: _showPending ? Colors.red : Colors.black - ), + Text( + "$_tmpTargetLow", + style: TextStyle( + fontSize: entity.largeFontSize, + color: _showPending ? Colors.red : Colors.black ), ), Column( children: [ IconButton( - icon: Icon(Icons.keyboard_arrow_up), + icon: Icon(MaterialDesignIcons.createIconDataFromIconName('mdi:chevron-up')), iconSize: 30.0, - onPressed: () => _targetLowUp(entity), + onPressed: () => _targetLowUp(entity, 0.1), ), IconButton( - icon: Icon(Icons.keyboard_arrow_down), + icon: Icon(MaterialDesignIcons.createIconDataFromIconName('mdi:chevron-down')), iconSize: 30.0, - onPressed: () => _targetLowDown(entity), + onPressed: () => _targetLowDown(entity, 0.1), ) ], ), - Container(width: 20.0,), - Expanded( - child: Text( - "$_tmpTargetHigh", - style: TextStyle( - fontSize: entity.largeFontSize, - color: _showPending ? Colors.red : Colors.black + Column( + children: [ + IconButton( + icon: Icon(MaterialDesignIcons.createIconDataFromIconName('mdi:chevron-double-up')), + iconSize: 30.0, + onPressed: () => _targetLowUp(entity, 0.5), ), + IconButton( + icon: Icon(MaterialDesignIcons.createIconDataFromIconName('mdi:chevron-double-down')), + iconSize: 30.0, + onPressed: () => _targetLowDown(entity, 0.5), + ) + ], + ), + Expanded( + child: Container(height: 10.0), + ), + Text( + "$_tmpTargetHigh", + style: TextStyle( + fontSize: entity.largeFontSize, + color: _showPending ? Colors.red : Colors.black ), ), Column( children: [ IconButton( - icon: Icon(Icons.keyboard_arrow_up), + icon: Icon(MaterialDesignIcons.createIconDataFromIconName('mdi:chevron-up')), iconSize: 30.0, - onPressed: () => _targetHighUp(entity), + onPressed: () => _targetHighUp(entity, 0.1), ), IconButton( - icon: Icon(Icons.keyboard_arrow_down), + icon: Icon(MaterialDesignIcons.createIconDataFromIconName('mdi:chevron-down')), iconSize: 30.0, - onPressed: () => _targetHighDown(entity), + onPressed: () => _targetHighDown(entity, 0.1), + ) + ], + ), + Column( + children: [ + IconButton( + icon: Icon(MaterialDesignIcons.createIconDataFromIconName('mdi:chevron-double-up')), + iconSize: 30.0, + onPressed: () => _targetHighUp(entity, 0.5), + ), + IconButton( + icon: Icon(MaterialDesignIcons.createIconDataFromIconName('mdi:chevron-double-down')), + iconSize: 30.0, + onPressed: () => _targetHighDown(entity, 0.5), ) ], ) ]); - } else { - result.add(Text("Unsupported temperature controls =(")); + } else if (entity.supportTargetTemperatureHigh || entity.supportTargetTemperatureLow) { + empty = false; + result.add(Text("Unsupported temperature control. Please, report an issue.")); } - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text("Target temperature", style: TextStyle( - fontSize: entity.stateFontSize - )), - Row( - children: result, + if (!empty) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("Target temperature", style: TextStyle( + fontSize: entity.stateFontSize + )), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: result, + ) + ], + ); + } else { + return Container(height: 0.0, width: 0.0,); + } + } + + Widget _buildHumidityControls(ClimateEntity entity) { + List result = []; + bool empty = true; + if (entity.supportTargetHumidity) { + empty = false; + result.addAll([ + Text( + "$_tmpTargetHumidity%", + style: TextStyle(fontSize: entity.largeFontSize), + ), + Expanded( + child: Slider( + value: _tmpTargetHumidity, + max: entity.maxHumidity, + min: entity.minHumidity, + onChanged: ((double val) { + setState(() { + _changedHere = true; + _tmpTargetHumidity = val.roundToDouble(); + }); + }), + onChangeEnd: (double v) => _setTargetHumidity(entity, v), + ), ) - ], - ); + ]); + } + if (!empty) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.fromLTRB( + 0.0, entity.rowPadding, 0.0, entity.rowPadding), + child: Text("Target humidity", style: TextStyle( + fontSize: entity.stateFontSize + )), + ), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: result, + ), + Container( + height: entity.rowPadding, + ) + ], + ); + } else { + return Container( + width: 0.0, + height: 0.0, + ); + } } diff --git a/lib/main.dart b/lib/main.dart index fea4f71..6da5f94 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -30,7 +30,7 @@ part 'card_class.dart'; EventBus eventBus = new EventBus(); const String appName = "HA Client"; -const appVersion = "0.2.5.35"; +const appVersion = "0.2.5.36"; String homeAssistantWebHost; diff --git a/pubspec.yaml b/pubspec.yaml index ced6ae4..23dabbe 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: hass_client description: Home Assistant Android Client -version: 0.2.5+35 +version: 0.2.5+36 environment: sdk: ">=2.0.0-dev.68.0 <3.0.0"