mirror of
https://github.com/home-assistant/frontend.git
synced 2025-04-26 14:27:20 +00:00
Convert climate water heaters to new water_heaters component (#1661)
* Water heater support * Attempt to fix lint errors. * Fixed another lint issue
This commit is contained in:
parent
c91b28a850
commit
7aa37183b6
@ -21,6 +21,7 @@ export const DOMAINS_WITH_CARD = [
|
|||||||
'script',
|
'script',
|
||||||
'timer',
|
'timer',
|
||||||
'vacuum',
|
'vacuum',
|
||||||
|
'water_heater',
|
||||||
'weblink',
|
'weblink',
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -43,6 +44,7 @@ export const DOMAINS_WITH_MORE_INFO = [
|
|||||||
'sun',
|
'sun',
|
||||||
'updater',
|
'updater',
|
||||||
'vacuum',
|
'vacuum',
|
||||||
|
'water_heater',
|
||||||
'weather'
|
'weather'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ const fixedIcons = {
|
|||||||
timer: 'hass:timer',
|
timer: 'hass:timer',
|
||||||
updater: 'hass:cloud-upload',
|
updater: 'hass:cloud-upload',
|
||||||
vacuum: 'hass:robot-vacuum',
|
vacuum: 'hass:robot-vacuum',
|
||||||
|
water_heater: 'hass:thermometer',
|
||||||
weblink: 'hass:open-in-new',
|
weblink: 'hass:open-in-new',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
131
src/components/ha-water_heater-control.js
Normal file
131
src/components/ha-water_heater-control.js
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||||
|
import '@polymer/paper-icon-button/paper-icon-button.js';
|
||||||
|
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||||
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
|
import EventsMixin from '../mixins/events-mixin.js';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @appliesMixin EventsMixin
|
||||||
|
*/
|
||||||
|
class HaWaterHeaterControl extends EventsMixin(PolymerElement) {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<style include="iron-flex iron-flex-alignment"></style>
|
||||||
|
<style>
|
||||||
|
/* local DOM styles go here */
|
||||||
|
:host {
|
||||||
|
@apply --layout-flex;
|
||||||
|
@apply --layout-horizontal;
|
||||||
|
@apply --layout-justified;
|
||||||
|
}
|
||||||
|
.in-flux#target_temperature {
|
||||||
|
color: var(--google-red-500);
|
||||||
|
}
|
||||||
|
#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 id="target_temperature">
|
||||||
|
[[value]] [[units]]
|
||||||
|
</div>
|
||||||
|
<div class="control-buttons">
|
||||||
|
<div>
|
||||||
|
<paper-icon-button icon="hass:chevron-up" on-click="incrementValue"></paper-icon-button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<paper-icon-button icon="hass:chevron-down" on-click="decrementValue"></paper-icon-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
value: {
|
||||||
|
type: Number,
|
||||||
|
observer: 'valueChanged'
|
||||||
|
},
|
||||||
|
units: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
min: {
|
||||||
|
type: Number,
|
||||||
|
},
|
||||||
|
max: {
|
||||||
|
type: Number,
|
||||||
|
},
|
||||||
|
step: {
|
||||||
|
type: Number,
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
temperatureStateInFlux(inFlux) {
|
||||||
|
this.$.target_temperature.classList.toggle('in-flux', inFlux);
|
||||||
|
}
|
||||||
|
|
||||||
|
incrementValue() {
|
||||||
|
const newval = this.value + this.step;
|
||||||
|
if (this.value < this.max) {
|
||||||
|
this.last_changed = Date.now();
|
||||||
|
this.temperatureStateInFlux(true);
|
||||||
|
}
|
||||||
|
if (newval <= this.max) {
|
||||||
|
// If no initial target_temp
|
||||||
|
// this forces control to start
|
||||||
|
// from the min configured instead of 0
|
||||||
|
if (newval <= this.min) {
|
||||||
|
this.value = this.min;
|
||||||
|
} else {
|
||||||
|
this.value = newval;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.value = this.max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
decrementValue() {
|
||||||
|
const newval = this.value - this.step;
|
||||||
|
if (this.value > this.min) {
|
||||||
|
this.last_changed = Date.now();
|
||||||
|
this.temperatureStateInFlux(true);
|
||||||
|
}
|
||||||
|
if (newval >= this.min) {
|
||||||
|
this.value = newval;
|
||||||
|
} else {
|
||||||
|
this.value = this.min;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
valueChanged() {
|
||||||
|
// when the last_changed timestamp is changed,
|
||||||
|
// trigger a potential event fire in
|
||||||
|
// the future, as long as last changed is far enough in the
|
||||||
|
// past.
|
||||||
|
if (this.last_changed) {
|
||||||
|
window.setTimeout(() => {
|
||||||
|
const now = Date.now();
|
||||||
|
if (now - this.last_changed >= 2000) {
|
||||||
|
this.fire('change');
|
||||||
|
this.temperatureStateInFlux(false);
|
||||||
|
this.last_changed = null;
|
||||||
|
}
|
||||||
|
}, 2010);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define('ha-water_heater-control', HaWaterHeaterControl);
|
74
src/components/ha-water_heater-state.js
Normal file
74
src/components/ha-water_heater-state.js
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||||
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
|
import LocalizeMixin from '../mixins/localize-mixin.js';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @appliesMixin LocalizeMixin
|
||||||
|
*/
|
||||||
|
class HaWaterHeaterState extends LocalizeMixin(PolymerElement) {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.target {
|
||||||
|
color: var(--primary-text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.current {
|
||||||
|
color: var(--secondary-text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.state-label {
|
||||||
|
font-weight: bold;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="target">
|
||||||
|
<span class="state-label">
|
||||||
|
[[_localizeState(stateObj.state)]]
|
||||||
|
</span>
|
||||||
|
[[computeTarget(hass, stateObj)]]
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template is="dom-if" if="[[currentStatus]]">
|
||||||
|
<div class="current">
|
||||||
|
[[localize('ui.card.water_heater.currently')]]: [[currentStatus]]
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
hass: Object,
|
||||||
|
stateObj: Object,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
computeTarget(hass, stateObj) {
|
||||||
|
if (!hass || !stateObj) return null;
|
||||||
|
// We're using "!= null" on purpose so that we match both null and undefined.
|
||||||
|
if (stateObj.attributes.target_temp_low != null
|
||||||
|
&& stateObj.attributes.target_temp_high != null) {
|
||||||
|
return `${stateObj.attributes.target_temp_low} - ${stateObj.attributes.target_temp_high} ${hass.config.unit_system.temperature}`;
|
||||||
|
}
|
||||||
|
if (stateObj.attributes.temperature != null) {
|
||||||
|
return `${stateObj.attributes.temperature} ${hass.config.unit_system.temperature}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
_localizeState(state) {
|
||||||
|
return this.localize(`state.water_heater.${state}`) || state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('ha-water_heater-state', HaWaterHeaterState);
|
@ -137,7 +137,7 @@ class StateHistoryChartLine extends LocalizeMixin(PolymerElement) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (domain === 'thermostat' || domain === 'climate') {
|
if (domain === 'thermostat' || domain === 'climate' || domain === 'water_heater') {
|
||||||
// We differentiate between thermostats that have a target temperature
|
// We differentiate between thermostats that have a target temperature
|
||||||
// range versus ones that have just a target temperature
|
// range versus ones that have just a target temperature
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import LocalizeMixin from '../mixins/localize-mixin.js';
|
|||||||
|
|
||||||
const RECENT_THRESHOLD = 60000; // 1 minute
|
const RECENT_THRESHOLD = 60000; // 1 minute
|
||||||
const RECENT_CACHE = {};
|
const RECENT_CACHE = {};
|
||||||
const DOMAINS_USE_LAST_UPDATED = ['thermostat', 'climate'];
|
const DOMAINS_USE_LAST_UPDATED = ['thermostat', 'climate', 'water_heater'];
|
||||||
const LINE_ATTRIBUTES_TO_KEEP = ['temperature', 'current_temperature', 'target_temp_low', 'target_temp_high'];
|
const LINE_ATTRIBUTES_TO_KEEP = ['temperature', 'current_temperature', 'target_temp_low', 'target_temp_high'];
|
||||||
const stateHistoryCache = {};
|
const stateHistoryCache = {};
|
||||||
|
|
||||||
@ -33,6 +33,8 @@ function computeHistory(hass, stateHistory, localize, language) {
|
|||||||
unit = stateWithUnit.attributes.unit_of_measurement;
|
unit = stateWithUnit.attributes.unit_of_measurement;
|
||||||
} else if (computeStateDomain(stateInfo[0]) === 'climate') {
|
} else if (computeStateDomain(stateInfo[0]) === 'climate') {
|
||||||
unit = hass.config.unit_system.temperature;
|
unit = hass.config.unit_system.temperature;
|
||||||
|
} else if (computeStateDomain(stateInfo[0]) === 'water_heater') {
|
||||||
|
unit = hass.config.unit_system.temperature;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!unit) {
|
if (!unit) {
|
||||||
|
@ -18,6 +18,7 @@ import './more-info-script.js';
|
|||||||
import './more-info-sun.js';
|
import './more-info-sun.js';
|
||||||
import './more-info-updater.js';
|
import './more-info-updater.js';
|
||||||
import './more-info-vacuum.js';
|
import './more-info-vacuum.js';
|
||||||
|
import './more-info-water_heater.js';
|
||||||
import './more-info-weather.js';
|
import './more-info-weather.js';
|
||||||
|
|
||||||
import stateMoreInfoType from '../../../common/entity/state_more_info_type.js';
|
import stateMoreInfoType from '../../../common/entity/state_more_info_type.js';
|
||||||
|
244
src/dialogs/more-info/controls/more-info-water_heater.js
Normal file
244
src/dialogs/more-info/controls/more-info-water_heater.js
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||||
|
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
|
||||||
|
import '@polymer/paper-item/paper-item.js';
|
||||||
|
import '@polymer/paper-listbox/paper-listbox.js';
|
||||||
|
import '@polymer/paper-toggle-button/paper-toggle-button.js';
|
||||||
|
import { timeOut } from '@polymer/polymer/lib/utils/async.js';
|
||||||
|
import { Debouncer } from '@polymer/polymer/lib/utils/debounce.js';
|
||||||
|
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||||
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
|
import '../../../components/ha-water_heater-control.js';
|
||||||
|
import '../../../components/ha-paper-slider.js';
|
||||||
|
|
||||||
|
import featureClassNames from '../../../common/entity/feature_class_names';
|
||||||
|
|
||||||
|
import EventsMixin from '../../../mixins/events-mixin.js';
|
||||||
|
import LocalizeMixin from '../../../mixins/localize-mixin.js';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @appliesMixin EventsMixin
|
||||||
|
* @appliesMixin LocalizeMixin
|
||||||
|
*/
|
||||||
|
class MoreInfoWaterHeater extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<style include="iron-flex"></style>
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
color: var(--primary-text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container-away_mode,
|
||||||
|
.container-temperature,
|
||||||
|
.container-operation_list,
|
||||||
|
|
||||||
|
.has-away_mode .container-away_mode,
|
||||||
|
.has-target_temperature .container-temperature,
|
||||||
|
.has-operation_mode .container-operation_list,
|
||||||
|
|
||||||
|
.container-operation_list iron-icon,
|
||||||
|
|
||||||
|
paper-dropdown-menu {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
paper-item {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
ha-paper-slider {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
ha-water_heater-control.range-control-left,
|
||||||
|
ha-water_heater-control.range-control-right {
|
||||||
|
float: left;
|
||||||
|
width: 46%;
|
||||||
|
}
|
||||||
|
ha-water_heater-control.range-control-left {
|
||||||
|
margin-right: 4%;
|
||||||
|
}
|
||||||
|
ha-water_heater-control.range-control-right {
|
||||||
|
margin-left: 4%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.single-row {
|
||||||
|
padding: 8px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class$="[[computeClassNames(stateObj)]]">
|
||||||
|
|
||||||
|
<div class="container-temperature">
|
||||||
|
<div class$="[[stateObj.attributes.operation_mode]]">
|
||||||
|
<div hidden$="[[!supportsTemperatureControls(stateObj)]]">[[localize('ui.card.water_heater.target_temperature')]]</div>
|
||||||
|
<template is="dom-if" if="[[supportsTemperature(stateObj)]]">
|
||||||
|
<ha-water_heater-control value="[[stateObj.attributes.temperature]]" units="[[hass.config.unit_system.temperature]]" step="[[computeTemperatureStepSize(hass, stateObj)]]" min="[[stateObj.attributes.min_temp]]" max="[[stateObj.attributes.max_temp]]" on-change="targetTemperatureChanged">
|
||||||
|
</ha-water_heater-control>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template is="dom-if" if="[[supportsOperationMode(stateObj)]]">
|
||||||
|
<div class="container-operation_list">
|
||||||
|
<div class="controls">
|
||||||
|
<paper-dropdown-menu label-float="" dynamic-align="" label="[[localize('ui.card.water_heater.operation')]]">
|
||||||
|
<paper-listbox slot="dropdown-content" selected="{{operationIndex}}">
|
||||||
|
<template is="dom-repeat" items="[[stateObj.attributes.operation_list]]" on-dom-change="handleOperationListUpdate">
|
||||||
|
<paper-item>[[_localizeOperationMode(localize, item)]]</paper-item>
|
||||||
|
</template>
|
||||||
|
</paper-listbox>
|
||||||
|
</paper-dropdown-menu>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template is="dom-if" if="[[supportsAwayMode(stateObj)]]">
|
||||||
|
<div class="container-away_mode">
|
||||||
|
<div class="center horizontal layout single-row">
|
||||||
|
<div class="flex">[[localize('ui.card.water_heater.away_mode')]]</div>
|
||||||
|
<paper-toggle-button checked="[[awayToggleChecked]]" on-change="awayToggleChanged">
|
||||||
|
</paper-toggle-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
hass: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
|
||||||
|
stateObj: {
|
||||||
|
type: Object,
|
||||||
|
observer: 'stateObjChanged',
|
||||||
|
},
|
||||||
|
|
||||||
|
operationIndex: {
|
||||||
|
type: Number,
|
||||||
|
value: -1,
|
||||||
|
observer: 'handleOperationmodeChanged',
|
||||||
|
},
|
||||||
|
awayToggleChecked: Boolean,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
stateObjChanged(newVal, oldVal) {
|
||||||
|
if (newVal) {
|
||||||
|
this.setProperties({
|
||||||
|
awayToggleChecked: newVal.attributes.away_mode === 'on'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldVal) {
|
||||||
|
this._debouncer = Debouncer.debounce(
|
||||||
|
this._debouncer,
|
||||||
|
timeOut.after(500),
|
||||||
|
() => {
|
||||||
|
this.fire('iron-resize');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleOperationListUpdate() {
|
||||||
|
// force polymer to recognize selected item change (to update actual label)
|
||||||
|
this.operationIndex = -1;
|
||||||
|
if (this.stateObj.attributes.operation_list) {
|
||||||
|
this.operationIndex = this.stateObj.attributes.operation_list.indexOf(
|
||||||
|
this.stateObj.attributes.operation_mode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
computeTemperatureStepSize(hass, stateObj) {
|
||||||
|
if (stateObj.attributes.target_temp_step) {
|
||||||
|
return stateObj.attributes.target_temp_step;
|
||||||
|
}
|
||||||
|
if (hass.config.unit_system.temperature.indexOf('F') !== -1) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
supportsTemperatureControls(stateObj) {
|
||||||
|
return this.supportsTemperature(stateObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
supportsTemperature(stateObj) {
|
||||||
|
return (stateObj.attributes.supported_features & 1) !== 0
|
||||||
|
&& typeof stateObj.attributes.temperature === 'number';
|
||||||
|
}
|
||||||
|
|
||||||
|
supportsOperationMode(stateObj) {
|
||||||
|
return (stateObj.attributes.supported_features & 2) !== 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
supportsAwayMode(stateObj) {
|
||||||
|
return (stateObj.attributes.supported_features & 4) !== 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
computeClassNames(stateObj) {
|
||||||
|
const _featureClassNames = {
|
||||||
|
1: 'has-target_temperature',
|
||||||
|
2: 'has-operation_mode',
|
||||||
|
4: 'has-away_mode'
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var classes = [
|
||||||
|
featureClassNames(stateObj, _featureClassNames),
|
||||||
|
];
|
||||||
|
|
||||||
|
classes.push('more-info-water_heater');
|
||||||
|
|
||||||
|
return classes.join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
targetTemperatureChanged(ev) {
|
||||||
|
const temperature = ev.target.value;
|
||||||
|
if (temperature === this.stateObj.attributes.temperature) return;
|
||||||
|
this.callServiceHelper('set_temperature', { temperature: temperature });
|
||||||
|
}
|
||||||
|
|
||||||
|
awayToggleChanged(ev) {
|
||||||
|
const oldVal = this.stateObj.attributes.away_mode === 'on';
|
||||||
|
const newVal = ev.target.checked;
|
||||||
|
if (oldVal === newVal) return;
|
||||||
|
this.callServiceHelper('set_away_mode', { away_mode: newVal });
|
||||||
|
}
|
||||||
|
|
||||||
|
handleOperationmodeChanged(operationIndex) {
|
||||||
|
// Selected Option will transition to '' before transitioning to new value
|
||||||
|
if (operationIndex === '' || operationIndex === -1) return;
|
||||||
|
const operationInput = this.stateObj.attributes.operation_list[operationIndex];
|
||||||
|
if (operationInput === this.stateObj.attributes.operation_mode) return;
|
||||||
|
|
||||||
|
this.callServiceHelper('set_operation_mode', { operation_mode: operationInput });
|
||||||
|
}
|
||||||
|
|
||||||
|
callServiceHelper(service, data) {
|
||||||
|
// We call stateChanged after a successful call to re-sync the inputs
|
||||||
|
// with the state. It will be out of sync if our service call did not
|
||||||
|
// result in the entity to be turned on. Since the state is not changing,
|
||||||
|
// the resync is not called automatic.
|
||||||
|
/* eslint-disable no-param-reassign */
|
||||||
|
data.entity_id = this.stateObj.entity_id;
|
||||||
|
/* eslint-enable no-param-reassign */
|
||||||
|
this.hass.callService('water_heater', service, data)
|
||||||
|
.then(() => {
|
||||||
|
this.stateObjChanged(this.stateObj);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_localizeOperationMode(localize, mode) {
|
||||||
|
return localize(`state.water_heater.${mode}`) || mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define('more-info-water_heater', MoreInfoWaterHeater);
|
@ -14,6 +14,7 @@ import './state-card-script.js';
|
|||||||
import './state-card-timer.js';
|
import './state-card-timer.js';
|
||||||
import './state-card-toggle.js';
|
import './state-card-toggle.js';
|
||||||
import './state-card-vacuum.js';
|
import './state-card-vacuum.js';
|
||||||
|
import './state-card-water_heater.js';
|
||||||
import './state-card-weblink.js';
|
import './state-card-weblink.js';
|
||||||
|
|
||||||
import stateCardType from '../common/entity/state_card_type.js';
|
import stateCardType from '../common/entity/state_card_type.js';
|
||||||
|
52
src/state-summary/state-card-water_heater.js
Normal file
52
src/state-summary/state-card-water_heater.js
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
||||||
|
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||||
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
|
import '../components/entity/state-info.js';
|
||||||
|
import '../components/ha-water_heater-state.js';
|
||||||
|
|
||||||
|
class StateCardWaterHeater extends PolymerElement {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<style include="iron-flex iron-flex-alignment"></style>
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
@apply --paper-font-body1;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
ha-water_heater-state {
|
||||||
|
margin-left: 16px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="horizontal justified layout">
|
||||||
|
${this.stateInfoTemplate}
|
||||||
|
<ha-water_heater-state hass="[[hass]]" state-obj="[[stateObj]]"></ha-water_heater-state>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get stateInfoTemplate() {
|
||||||
|
return html`
|
||||||
|
<state-info
|
||||||
|
hass="[[hass]]"
|
||||||
|
state-obj="[[stateObj]]"
|
||||||
|
in-dialog="[[inDialog]]"
|
||||||
|
></state-info>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
hass: Object,
|
||||||
|
stateObj: Object,
|
||||||
|
inDialog: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('state-card-water_heater', StateCardWaterHeater);
|
@ -401,6 +401,13 @@
|
|||||||
"turn_off": "Turn off"
|
"turn_off": "Turn off"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"water_heater": {
|
||||||
|
"currently": "Currently",
|
||||||
|
"on_off": "On / off",
|
||||||
|
"target_temperature": "Target temperature",
|
||||||
|
"operation": "Operation",
|
||||||
|
"away_mode": "Away mode"
|
||||||
|
},
|
||||||
"weather": {
|
"weather": {
|
||||||
"attributes": {
|
"attributes": {
|
||||||
"air_pressure": "Air pressure",
|
"air_pressure": "Air pressure",
|
||||||
|
@ -81,7 +81,7 @@ hassAttributeUtil.LOGIC_STATE_ATTRIBUTES = hassAttributeUtil.LOGIC_STATE_ATTRIBU
|
|||||||
hidden: { type: 'boolean', description: 'Hide from UI' },
|
hidden: { type: 'boolean', description: 'Hide from UI' },
|
||||||
assumed_state: {
|
assumed_state: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
domains: ['switch', 'light', 'cover', 'climate', 'fan', 'group']
|
domains: ['switch', 'light', 'cover', 'climate', 'fan', 'group', 'water_heater']
|
||||||
},
|
},
|
||||||
initial_state: {
|
initial_state: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user