158 lines
5.8 KiB
JavaScript
158 lines
5.8 KiB
JavaScript
import {cssData} from './styles.js?v=1.3.0';
|
|
import ThermostatUI from './thermostat_card.lib.js?v=1.3.0';
|
|
console.info("%c Thermostat Card \n%c Version 1.3.0 ", "color: orange; font-weight: bold; background: black", "color: white; font-weight: bold; background: dimgray");
|
|
class ThermostatCard extends HTMLElement {
|
|
constructor() {
|
|
super();
|
|
this.attachShadow({ mode: 'open' });
|
|
}
|
|
set hass(hass) {
|
|
const config = this._config;
|
|
const entity = hass.states[config.entity];
|
|
if(!entity)return;
|
|
let ambient_temperature = entity.attributes.current_temperature || 0;
|
|
if (config.ambient_temperature && hass.states[config.ambient_temperature])
|
|
ambient_temperature = hass.states[config.ambient_temperature].state;
|
|
let hvac_state = entity.state;
|
|
|
|
const new_state = {
|
|
entity: entity,
|
|
min_value: entity.attributes.min_temp,
|
|
max_value: entity.attributes.max_temp,
|
|
ambient_temperature: ambient_temperature,
|
|
target_temperature: entity.attributes.temperature,
|
|
target_temperature_low: entity.attributes.target_temp_low,
|
|
target_temperature_high: entity.attributes.target_temp_high,
|
|
hvac_state: entity.state,
|
|
hvac_modes:entity.attributes.hvac_modes,
|
|
preset_mode: entity.attributes.preset_mode,
|
|
away: (entity.attributes.away_mode == 'on' ? true : false)
|
|
}
|
|
|
|
if (!this._saved_state ||
|
|
(this._saved_state.min_value != new_state.min_value ||
|
|
this._saved_state.max_value != new_state.max_value ||
|
|
this._saved_state.ambient_temperature != new_state.ambient_temperature ||
|
|
this._saved_state.target_temperature != new_state.target_temperature ||
|
|
this._saved_state.target_temperature_low != new_state.target_temperature_low ||
|
|
this._saved_state.target_temperature_high != new_state.target_temperature_high ||
|
|
this._saved_state.hvac_state != new_state.hvac_state ||
|
|
this._saved_state.preset_mode != new_state.preset_mode ||
|
|
this._saved_state.away != new_state.away)) {
|
|
this._saved_state = new_state;
|
|
this.thermostat.updateState(new_state,hass);
|
|
}
|
|
this._hass = hass;
|
|
}
|
|
|
|
openProp(entityId) {
|
|
this.fire('hass-more-info', { entityId });
|
|
}
|
|
fire(type, detail, options) {
|
|
|
|
options = options || {}
|
|
detail = detail === null || detail === undefined ? {} : detail
|
|
const e = new Event(type, {
|
|
bubbles: options.bubbles === undefined ? true : options.bubbles,
|
|
cancelable: Boolean(options.cancelable),
|
|
composed: options.composed === undefined ? true : options.composed,
|
|
})
|
|
|
|
e.detail = detail
|
|
this.dispatchEvent(e)
|
|
return e
|
|
}
|
|
|
|
_controlSetPoints() {
|
|
|
|
if (this.thermostat.dual) {
|
|
if (this.thermostat.temperature.high != this._saved_state.target_temperature_high ||
|
|
this.thermostat.temperature.low != this._saved_state.target_temperature_low)
|
|
this._hass.callService('climate', 'set_temperature', {
|
|
entity_id: this._config.entity,
|
|
target_temp_high: this.thermostat.temperature.high,
|
|
target_temp_low: this.thermostat.temperature.low,
|
|
});
|
|
} else {
|
|
if (this.thermostat.temperature.target != this._saved_state.target_temperature)
|
|
this._hass.callService('climate', 'set_temperature', {
|
|
entity_id: this._config.entity,
|
|
temperature: this.thermostat.temperature.target,
|
|
});
|
|
}
|
|
}
|
|
|
|
setConfig(config) {
|
|
// Check config
|
|
if (!config.entity && config.entity.split(".")[0] === 'climate') {
|
|
throw new Error('Please define an entity');
|
|
}
|
|
|
|
// Cleanup DOM
|
|
const root = this.shadowRoot;
|
|
|
|
if (root.lastChild) root.removeChild(root.lastChild);
|
|
|
|
// Prepare config defaults
|
|
const cardConfig = deepClone(config);
|
|
// cardConfig.hvac = Object.assign({}, config.hvac);
|
|
|
|
if (!cardConfig.diameter) cardConfig.diameter = 400;
|
|
if (!cardConfig.pending) cardConfig.pending = 3;
|
|
if (!cardConfig.idle_zone) cardConfig.idle_zone = 2;
|
|
if (!cardConfig.step) cardConfig.step = 0.5;
|
|
if (!cardConfig.highlight_tap) cardConfig.highlight_tap = false;
|
|
if (!cardConfig.no_card) cardConfig.no_card = false;
|
|
if (!cardConfig.chevron_size) cardConfig.chevron_size = 50;
|
|
if (!cardConfig.num_ticks) cardConfig.num_ticks = 150;
|
|
if (!cardConfig.tick_degrees) cardConfig.tick_degrees = 300;
|
|
|
|
// Extra config values generated for simplicity of updates
|
|
cardConfig.radius = cardConfig.diameter / 2;
|
|
cardConfig.ticks_outer_radius = cardConfig.diameter / 30;
|
|
cardConfig.ticks_inner_radius = cardConfig.diameter / 8;
|
|
cardConfig.offset_degrees = 180 - (360 - cardConfig.tick_degrees) / 2;
|
|
cardConfig.control = this._controlSetPoints.bind(this);
|
|
cardConfig.propWin = this.openProp.bind(this);
|
|
this.thermostat = new ThermostatUI(cardConfig);
|
|
|
|
if (cardConfig.no_card === true) {
|
|
|
|
const card = document.createElement('ha-card');
|
|
card.className = "no_card";
|
|
const style = document.createElement('style');
|
|
style.textContent = cssData();
|
|
card.appendChild(style);
|
|
card.appendChild(this.thermostat.container);
|
|
root.appendChild(card);
|
|
|
|
}
|
|
else {
|
|
|
|
const card = document.createElement('ha-card');
|
|
const style = document.createElement('style');
|
|
style.textContent = cssData();
|
|
card.appendChild(style);
|
|
card.appendChild(this.thermostat.container);
|
|
root.appendChild(card);
|
|
}
|
|
this._config = cardConfig;
|
|
}
|
|
}
|
|
customElements.define('thermostat-card', ThermostatCard);
|
|
|
|
function deepClone(value) {
|
|
if (!(!!value && typeof value == 'object')) {
|
|
return value;
|
|
}
|
|
if (Object.prototype.toString.call(value) == '[object Date]') {
|
|
return new Date(value.getTime());
|
|
}
|
|
if (Array.isArray(value)) {
|
|
return value.map(deepClone);
|
|
}
|
|
var result = {};
|
|
Object.keys(value).forEach(
|
|
function(key) { result[key] = deepClone(value[key]); });
|
|
return result;
|
|
} |