ha-climate-control polymer widget (#212)

This replaces the climate paper-slider with a new control which is a
numerical display plus up/down buttons. The paper-slider control
really needs a fine pointer like a mouse or a stylus to function well,
and in my use case the most often time I want to quick manually adjust
the temperature is on a mobile device, where using the paper-slider is
extremely problematic.

The stepsize is now computed based on the units. 0.5 for C, 1.0 for F,
which provides about the same granularity for both.

The ha-climate-control widget is actually pretty generic, and could be
used in other places if anyone has suggestions on a good generic name.
This commit is contained in:
Sean Dague 2017-02-15 19:18:18 -08:00 committed by Paulus Schoutsen
parent f396c9acde
commit 116277acb4
2 changed files with 109 additions and 23 deletions

View File

@ -0,0 +1,88 @@
<link rel='import' href='../../bower_components/polymer/polymer.html'>
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
<dom-module id="ha-climate-control">
<template>
<style is="custom-style" include="iron-flex iron-flex-alignment"></style>
<style>
/* local DOM styles go here */
:host {
@apply(--layout-flex);
@apply(--layout-horizontal);
@apply(--layout-justified);
}
.target-temperature {
@apply(--layout-self-center);
font-size: 200%;
}
.control-buttons {
font-size: 200%;
text-align: right;
}
paper-icon-button {
height: 48px;
width: 48px;
}
</style>
<!-- local DOM goes here -->
<div class="target-temperature">
[[value]] [[units]]
</div>
<div class="control-buttons">
<div>
<paper-icon-button icon="mdi:chevron-up" on-tap="incrementValue"></paper-icon-button>
</div>
<div>
<paper-icon-button icon="mdi:chevron-down" on-tap="decrementValue"></paper-icon-button>
</div>
</div>
</template>
<script>
Polymer({
is: 'ha-climate-control',
properties: {
value: {
type: Number,
observer: 'valueChanged'
},
units: {
type: String,
},
min: {
type: Number,
},
max: {
type: Number,
},
step: {
type: Number,
value: 1,
},
},
incrementValue: function () {
var newval = this.value + this.step;
if (newval <= this.max) {
this.value = newval;
} else {
this.value = this.max;
}
},
decrementValue: function () {
var newval = this.value - this.step;
if (newval >= this.min) {
this.value = newval;
} else {
this.value = this.min;
}
},
valueChanged: function () {
this.fire('change');
},
}
);
</script>
</dom-module>

View File

@ -9,6 +9,8 @@
<link rel='import' href='../../bower_components/paper-toggle-button/paper-toggle-button.html'> <link rel='import' href='../../bower_components/paper-toggle-button/paper-toggle-button.html'>
<link rel="import" href="../../bower_components/paper-range-slider/paper-range-slider.html"> <link rel="import" href="../../bower_components/paper-range-slider/paper-range-slider.html">
<link rel="import" href='../components/ha-climate-control.html'>
<dom-module id='more-info-climate'> <dom-module id='more-info-climate'>
<template> <template>
<style is="custom-style" include="iron-flex"></style> <style is="custom-style" include="iron-flex"></style>
@ -95,28 +97,17 @@
<div class$='[[computeClassNames(stateObj)]]'> <div class$='[[computeClassNames(stateObj)]]'>
<div class='container-temperature'> <div class='container-temperature'>
<div class$='single-row, [[stateObj.attributes.operation_mode]]'> <div class$='single-row, [[stateObj.attributes.operation_mode]]'>
<div hidden$='[[computeTargetTempHidden(stateObj)]]'>Target Temperature</div> <div hidden$='[[computeTargetTempHidden(stateObj)]]'>Target
<paper-slider Temperature</div>
min='[[stateObj.attributes.min_temp]]' <ha-climate-control
max='[[stateObj.attributes.max_temp]]' value='[[stateObj.attributes.temperature]]'
secondary-progress='[[stateObj.attributes.max_temp]]' units='[[stateObj.attributes.unit_of_measurement]]'
pin step='[[computeTemperatureStepSize(stateObj.attributes.unit_of_measurement)]]'
step='0.5' min='[[stateObj.attributes.min_temp]]'
value='[[stateObj.attributes.temperature]]' max='[[stateObj.attributes.max_temp]]'
hidden$='[[computeHideTempSlider(stateObj)]]' on-change='targetTemperatureChanged'
on-change='targetTemperatureSliderChanged'> >
</paper-slider> </ha-climate-control>
<paper-range-slider
min='[[stateObj.attributes.min_temp]]'
max='[[stateObj.attributes.max_temp]]'
pin
step='0.5'
value-min='[[stateObj.attributes.target_temp_low]]'
value-max='[[stateObj.attributes.target_temp_high]]'
value-diff-min='2'
hidden$='[[computeHideTempRangeSlider(stateObj)]]'
on-change='targetTemperatureRangeSliderChanged'>
</paper-range-slider>
</div> </div>
</div> </div>
@ -267,6 +258,13 @@ Polymer({
} }
}, },
computeTemperatureStepSize: function (units) {
if (units.indexOf('F') !== -1) {
return 1;
}
return 0.5;
},
computeTargetTempHidden: function (stateObj) { computeTargetTempHidden: function (stateObj) {
return !stateObj.attributes.temperature && return !stateObj.attributes.temperature &&
!stateObj.attributes.target_temp_low && !stateObj.attributes.target_temp_low &&
@ -291,7 +289,7 @@ Polymer({
); );
}, },
targetTemperatureSliderChanged: function (ev) { targetTemperatureChanged: function (ev) {
var temperature = ev.target.value; var temperature = ev.target.value;
if (temperature === this.stateObj.attributes.temperature) return; if (temperature === this.stateObj.attributes.temperature) return;