diff --git a/README.md b/README.md index 7ca10ba..801204c 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,7 @@ sensors: - temperature: sensor.temperature_2 humidity: sensor.humidity_2 leaf_temperature: sensor.infrared_sensor #optional + show_calculated_rh: true # optional name: Tent 1 - temperature: sensor.temperature_tent_2 humidity: sensor.humidity_tent_2 @@ -169,6 +170,7 @@ calculateVPD: |2- | is_bar_view | boolean | optional | `true` | Enable Bar view of this chart for fast information of sensors | | enable_axes | boolean | optional | `true` | Enable Axes on the Chart | | enable_ghostmap | boolean | optional | `true` | Enable Ghostmap on the Chart | +| enable_ghostclick | boolean | optional | `true` | Enable Ghostclick instead of Hover | | enable_triangle | boolean | optional | `true` | Enable Triangle instead of Circle for tooltip marker | | enable_crosshair | boolean | optional | `true` | Enable MouseHover Crosshair | | enable_fahrenheit | boolean | optional | `false` | Enable Fahrenheit instead of Celsius | diff --git a/dist/bar.css b/dist/bar.css index e6b41dc..0bf95a5 100644 --- a/dist/bar.css +++ b/dist/bar.css @@ -1,3 +1,7 @@ +.vpd-bar-view { + display: block !important; +} + .vpd-bar-view .type-custom-ha-vpd-chart { margin-bottom: 5px; } diff --git a/dist/bar.js b/dist/bar.js index 26f7d43..61487c6 100644 --- a/dist/bar.js +++ b/dist/bar.js @@ -1,10 +1,9 @@ export const bar = { - buildBarChart() { - if (!this.content) { - this.innerHTML = ` - + async initializeBar() { + this.htmlTemplate = ` + - `; - this.content = this.querySelector("div.card-content"); + `; + await fetch(`/hacsfiles/ha-vpd-chart/bar.css?v=${window.vpdChartVersion}`) + .then(response => { + if (response.ok) { + this.innerHTML = this.htmlTemplate.replace('##url##', `/hacsfiles/ha-vpd-chart/bar.css?v=${window.vpdChartVersion}`); + this.content = this.querySelector("div.card-content"); + return; + } + throw new Error('fallback to local/community'); + }) + .catch(error => { + this.innerHTML = this.htmlTemplate.replace('##url##', `/local/community/ha-vpd-chart/bar.css?v=${window.vpdChartVersion}`); + this.content = this.querySelector("div.card-content"); + }); + + }, + async buildBarChart() { + if (!this.content) { + await this.initializeBar(); if (this._hass) { let vpd = 0; @@ -115,7 +131,7 @@ export const bar = { let showHumidity = humidity; if (sensor.show_calculated_rh === true) { - showHumidity = this.calculateRH(temperature - 2, temperature, vpd).toFixed(1); + showHumidity = this.calculateRH(leafTemperature, temperature, vpd).toFixed(1); } let sensorName = sensor.name; if (sensorName === undefined) { diff --git a/dist/chart.css b/dist/chart.css index 41a3a2f..17be196 100644 --- a/dist/chart.css +++ b/dist/chart.css @@ -11,7 +11,7 @@ div.vpd-chart-view, div.vpd-chart-view .vpd-card-container { } .vpd-chart-view { - display: grid; + display: grid !important; } .vpd-chart-view .gray-danger-zone { diff --git a/dist/chart.js b/dist/chart.js index 1863c42..80b205d 100644 --- a/dist/chart.js +++ b/dist/chart.js @@ -1,34 +1,52 @@ export const chart = { - initializeChart() { + async initializeChart() { this.zoomLevel = 1; this.minZoom = 1; this.maxZoom = 3; - this.innerHTML = ` - -
- -
-
-
-
-
-
-
+ this.htmlTemplate = ` + + -
-
- - `; - this.content = this.querySelector("div.vpd-card-container"); - this.sensordom = this.querySelector("div#sensors"); - this.ghostmapDom = this.querySelector("div#ghostmap"); - this.mouseTooltip = this.querySelector("div#mouse-tooltip"); + + `; + await fetch(`/hacsfiles/ha-vpd-chart/chart.css?v=${window.vpdChartVersion}`) + .then(response => { + if (response.ok) { + this.innerHTML = this.htmlTemplate.replace('##url##', `/hacsfiles/ha-vpd-chart/chart.css?v=${window.vpdChartVersion}`); + this.content = this.querySelector("div.vpd-card-container"); + this.sensordom = this.querySelector("div#sensors"); + this.ghostmapDom = this.querySelector("div#ghostmap"); + this.mouseTooltip = this.querySelector("div#mouse-tooltip"); + return; + } + throw new Error('fallback to local/community'); + }) + .catch(error => { + this.innerHTML = this.htmlTemplate.replace('##url##', `/local/community/ha-vpd-chart/chart.css?v=${window.vpdChartVersion}`); + this.content = this.querySelector("div.vpd-card-container"); + this.sensordom = this.querySelector("div#sensors"); + this.ghostmapDom = this.querySelector("div#ghostmap"); + this.mouseTooltip = this.querySelector("div#mouse-tooltip"); + }); + }, - buildChart() { + async buildChart() { if (!this.content) { - this.initializeChart.call(this); + + await this.initializeChart.call(this); + const table = this.buildTable(); if (!table.isConnected) { this.content.appendChild(table); diff --git a/dist/ghostmap.js b/dist/ghostmap.js index 8e329b9..8a2c4b3 100644 --- a/dist/ghostmap.js +++ b/dist/ghostmap.js @@ -21,12 +21,14 @@ export const ghostmap = { const ghostmap = this.querySelector('#ghostmap'); const sensorPromises = this.config.sensors.map(async (sensor, index) => { - const [temperatures, humidities] = await Promise.all([ - this.getEntityHistory(sensor.temperature, this.config.ghostmap_hours), - this.getEntityHistory(sensor.humidity, this.config.ghostmap_hours) - ]); + if (this._hass.states[sensor.humidity] && this._hass.states[sensor.temperature]) { + const [temperatures, humidities] = await Promise.all([ + this.getEntityHistory(sensor.temperature, this.config.ghostmap_hours), + this.getEntityHistory(sensor.humidity, this.config.ghostmap_hours) + ]); - this.processSensorData(fragment, temperatures, humidities, index); + this.processSensorData(fragment, temperatures, humidities, index); + } }); await Promise.all(sensorPromises); diff --git a/dist/ha-vpd-chart-editor.css b/dist/ha-vpd-chart-editor.css index 04296e9..b5246af 100644 --- a/dist/ha-vpd-chart-editor.css +++ b/dist/ha-vpd-chart-editor.css @@ -298,4 +298,54 @@ input[type="color"]::-webkit-color-swatch-wrapper { input[type="color"]::-webkit-color-swatch { border: none; border-radius: 4px; +} + +[data-title] { + position: relative; +} + +[data-title]:hover:after { + opacity: 1; + transition: all 0.1s ease 0.5s; + visibility: visible; + position: absolute; +} + +[data-title]:after { + content: attr(data-title); + width: auto; + position: absolute; + bottom: -1.6em; + left: 100%; + padding: 4px 4px 4px 8px; + white-space: nowrap; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + background-color: hsla(0, 0%, 20%, 0.9); + color: #ffffff; + text-align: center; + font-style: normal; + font-size: 12px; + opacity: 0; + z-index: 99999; + visibility: hidden; +} + +.vpd-chart-config ha-textfield { + width: 100%; +} + +.vpd-chart-config .infoIcon { + position: relative; +} + +.vpd-chart-config .infoIcon:hover { + position: absolute; + cursor: pointer; +} + +.vpd-chart-config .infoIcon i { + line-height: 25px; + margin-left: 5px; } \ No newline at end of file diff --git a/dist/ha-vpd-chart-editor.js b/dist/ha-vpd-chart-editor.js index fdf1644..f8efb20 100644 --- a/dist/ha-vpd-chart-editor.js +++ b/dist/ha-vpd-chart-editor.js @@ -1,11 +1,10 @@ import {methods} from './methods.js'; + import {MultiRange} from './ha-vpd-chart-editor-multiRange.js'; export class HaVpdChartEditor extends HTMLElement { config = { - type: 'custom:ha-vpd-chart', - sensors: [], - vpd_phases: [] + type: 'custom:ha-vpd-chart', sensors: [], vpd_phases: [] }; constructor() { @@ -20,23 +19,14 @@ export class HaVpdChartEditor extends HTMLElement { config.vpd_phases = []; } if (config.vpd_phases.length === 0) { - config.vpd_phases = [ - {upper: 0, className: 'gray-danger-zone', color: '#999999'}, - {lower: 0, upper: 0.4, className: 'under-transpiration', color: '#1a6c9c'}, - {lower: 0.4, upper: 0.8, className: 'early-veg', color: '#22ab9c'}, - {lower: 0.8, upper: 1.2, className: 'late-veg', color: '#9cc55b'}, - {lower: 1.2, upper: 1.6, className: 'mid-late-flower', color: '#e7c12b'}, - {lower: 1.6, className: 'danger-zone', color: '#ce4234'}, - ]; + config.vpd_phases = [{upper: 0, className: 'gray-danger-zone', color: '#999999'}, {lower: 0, upper: 0.4, className: 'under-transpiration', color: '#1a6c9c'}, {lower: 0.4, upper: 0.8, className: 'early-veg', color: '#22ab9c'}, {lower: 0.8, upper: 1.2, className: 'late-veg', color: '#9cc55b'}, {lower: 1.2, upper: 1.6, className: 'mid-late-flower', color: '#e7c12b'}, {lower: 1.6, className: 'danger-zone', color: '#ce4234'},]; } if (config.sensors === undefined) { config.sensors = []; } if (config.sensors.length === 0) { config.sensors = [{ - temperature: '', - humidity: '', - name: '' + temperature: '', humidity: '', name: '' }]; } if (config.is_bar_view === undefined) { @@ -127,14 +117,7 @@ export class HaVpdChartEditor extends HTMLElement { } get _vpd_phases() { - return this.config.vpd_phases !== undefined ? this.config.vpd_phases : [ - {upper: 0, className: 'gray-danger-zone', color: '#999999'}, - {lower: 0, upper: 0.4, className: 'under-transpiration', color: '#1a6c9c'}, - {lower: 0.4, upper: 0.8, className: 'early-veg', color: '#22ab9c'}, - {lower: 0.8, upper: 1.2, className: 'late-veg', color: '#9cc55b'}, - {lower: 1.2, upper: 1.6, className: 'mid-late-flower', color: '#e7c12b'}, - {lower: 1.6, className: 'danger-zone', color: '#ce4234'}, - ]; + return this.config.vpd_phases !== undefined ? this.config.vpd_phases : [{upper: 0, className: 'gray-danger-zone', color: '#999999'}, {lower: 0, upper: 0.4, className: 'under-transpiration', color: '#1a6c9c'}, {lower: 0.4, upper: 0.8, className: 'early-veg', color: '#22ab9c'}, {lower: 0.8, upper: 1.2, className: 'late-veg', color: '#9cc55b'}, {lower: 1.2, upper: 1.6, className: 'mid-late-flower', color: '#e7c12b'}, {lower: 1.6, className: 'danger-zone', color: '#ce4234'},]; } get _min_temperature() { @@ -223,8 +206,13 @@ export class HaVpdChartEditor extends HTMLElement { } checkValue(target) { - let value = target.type === 'checkbox' ? target.checked : target.value; - + let value = target.value; + if (target.tagName === "HA-CHECKBOX") { + if (target.checked === "checked") { + target.checked = true; + } + value = target.checked; + } if (typeof value === 'string' && !isNaN(value)) { value = this.toFixedNumber(value); } @@ -258,12 +246,13 @@ export class HaVpdChartEditor extends HTMLElement { } handleValueChange = (ev) => { - const target = ev.target; - const configValue = target.getAttribute('data-configvalue'); + let target = ev.target; + if (ev.target === undefined) { + target = ev; + } + const configValue = target.getAttribute('id'); let value = this.checkValue(target); let configCopy = this.copyConfig(); - - if (configCopy[configValue] !== value) { configCopy[configValue] = value; this.fireEvent(this, 'config-changed', {config: configCopy}); @@ -287,12 +276,25 @@ export class HaVpdChartEditor extends HTMLElement { } connectedCallback() { - this.render(); - this.initValues(); - this.initSensors(); - this.initColorEditor(); - this.initAddButton(); - this.initFormulaEditor(); + import('./lang/' + this._hass.language + '.js').then((module) => { + this.language = module.language; + this.render(); + this.initValues(); + this.initSensors(); + this.initColorEditor(); + this.initAddButton(); + this.initFormulaEditor(); + }).catch((error) => { + import('./lang/en.js').then((module) => { + this.language = module.language; + this.render(); + this.initValues(); + this.initSensors(); + this.initColorEditor(); + this.initAddButton(); + this.initFormulaEditor(); + }); + }); } render() { @@ -300,139 +302,138 @@ export class HaVpdChartEditor extends HTMLElement { @import '/local/community/ha-vpd-chart/ha-vpd-chart-editor.css?v=${window.vpdChartVersion}'
- +
-
- +
+
- + - +
- + - +
- + - +
- + - +
- + - +
- +
- + @@ -440,7 +441,7 @@ export class HaVpdChartEditor extends HTMLElement {
- + + + - + + +
- + + + - + + +
- + + + - + + + +
- + + + + - + + + +
- + + + + - + + + +
- + + + + + +
- +
@@ -449,14 +450,24 @@ export class HaVpdChartEditor extends HTMLElement {
- +
-
+
`; - this.shadowRoot.querySelectorAll('ha-switch, ha-textfield, ha-checkbox, label, input').forEach(input => { - input.addEventListener('input', this.handleValueChange); + const debouncedHandleInputChange = this.debounce(this.handleValueChange, 500); + + this.shadowRoot.querySelectorAll('ha-switch, ha-textfield, input').forEach(input => { + let target = input; + + input.addEventListener('input', event => { + debouncedHandleInputChange(target); + }); }); + this.shadowRoot.querySelectorAll('ha-checkbox').forEach(input => { + + input.addEventListener('change', this.handleValueChange); + }) this.shadowRoot.querySelectorAll('.collapsible').forEach(collapsible => { collapsible.onclick = () => { collapsible.classList.toggle("active"); @@ -470,41 +481,18 @@ export class HaVpdChartEditor extends HTMLElement { initValues() { - const configValues = [ - {id: 'air_text', prop: '_air_text', type: 'value'}, - {id: 'rh_text', prop: '_rh_text', type: 'value'}, - {id: 'kpa_text', prop: '_kpa_text', type: 'value'}, - {id: 'min_temperature', prop: '_min_temperature', type: 'value'}, - {id: 'max_temperature', prop: '_max_temperature', type: 'value'}, - {id: 'min_humidity', prop: '_min_humidity', type: 'value'}, - {id: 'max_humidity', prop: '_max_humidity', type: 'value'}, - {id: 'leaf_temperature_offset', prop: '_leaf_temperature_offset', type: 'value'}, - {id: 'min_height', prop: '_min_height', type: 'value'}, - {id: 'is_bar_view', prop: '_is_bar_view', type: 'checked'}, - {id: 'enable_axes', prop: '_enable_axes', type: 'checked'}, - {id: 'enable_ghostclick', prop: '_enable_ghostclick', type: 'checked'}, - {id: 'enable_ghostmap', prop: '_enable_ghostmap', type: 'checked'}, - {id: 'enable_triangle', prop: '_enable_triangle', type: 'checked'}, - {id: 'enable_crosshair', prop: '_enable_crosshair', type: 'checked'}, - {id: 'enable_tooltip', prop: '_enable_tooltip', type: 'checked'}, - {id: 'enable_fahrenheit', prop: '_enable_fahrenheit', type: 'checked'}, - {id: 'enable_zoom', prop: '_enable_zoom', type: 'checked'}, - {id: 'enable_legend', prop: '_enable_legend', type: 'checked'}, - {id: 'enable_show_always_informations', prop: '_enable_show_always_informations', type: 'checked'}, - {id: 'ghostmap_hours', prop: '_ghostmap_hours', type: 'value'}, - {id: 'unit_temperature', prop: '_unit_temperature', type: 'value'} - ]; + const configValues = [{id: 'air_text', prop: '_air_text', type: 'value'}, {id: 'rh_text', prop: '_rh_text', type: 'value'}, {id: 'kpa_text', prop: '_kpa_text', type: 'value'}, {id: 'min_temperature', prop: '_min_temperature', type: 'value'}, {id: 'max_temperature', prop: '_max_temperature', type: 'value'}, {id: 'min_humidity', prop: '_min_humidity', type: 'value'}, {id: 'max_humidity', prop: '_max_humidity', type: 'value'}, {id: 'leaf_temperature_offset', prop: '_leaf_temperature_offset', type: 'value'}, {id: 'min_height', prop: '_min_height', type: 'value'}, {id: 'is_bar_view', prop: '_is_bar_view', type: 'checked'}, {id: 'enable_axes', prop: '_enable_axes', type: 'checked'}, {id: 'enable_ghostclick', prop: '_enable_ghostclick', type: 'checked'}, {id: 'enable_ghostmap', prop: '_enable_ghostmap', type: 'checked'}, {id: 'enable_triangle', prop: '_enable_triangle', type: 'checked'}, {id: 'enable_crosshair', prop: '_enable_crosshair', type: 'checked'}, { + id: 'enable_tooltip', + prop: '_enable_tooltip', + type: 'checked' + }, {id: 'enable_fahrenheit', prop: '_enable_fahrenheit', type: 'checked'}, {id: 'enable_zoom', prop: '_enable_zoom', type: 'checked'}, {id: 'enable_legend', prop: '_enable_legend', type: 'checked'}, {id: 'enable_show_always_informations', prop: '_enable_show_always_informations', type: 'checked'}, {id: 'ghostmap_hours', prop: '_ghostmap_hours', type: 'value'}, {id: 'unit_temperature', prop: '_unit_temperature', type: 'value'}]; configValues.forEach(({id, prop, type}) => { const element = this.shadowRoot.querySelector(`#${id}`); if (element) { if (Object.isExtensible(element)) { if (type === "checked") { - if (this[prop]) { - element[type] = 'checked'; - } else { - element[type] = ''; - } + element[type] = this[prop] ? 'checked' : ''; } else { element[type] = this[prop]; } @@ -514,7 +502,15 @@ export class HaVpdChartEditor extends HTMLElement { } }); - let vpdPhases = this.config.vpd_phases; + // Use requestAnimationFrame to update the multiRange + requestAnimationFrame(() => { + this.updateMultiRange(); + }); + + } + + updateMultiRange() { + const vpdPhases = this.config.vpd_phases; const sliderContainer = this.shadowRoot.querySelector('#slider-container'); let rangesArray = this.generateRangesArray(vpdPhases); @@ -529,7 +525,6 @@ export class HaVpdChartEditor extends HTMLElement { this.multiRange = new MultiRange(sliderContainer, settings); this.multiRange.on("changed", (event) => { - if (event.detail.idx === undefined || event.detail.value === undefined) return; let configCopy = this.copyConfig(); const idx = event.detail.idx; @@ -550,8 +545,8 @@ export class HaVpdChartEditor extends HTMLElement { } this.config = configCopy; this.fireEvent(this, 'config-changed', {config: this.config}); - }); + }); } initSensors() { @@ -574,7 +569,7 @@ export class HaVpdChartEditor extends HTMLElement { const container = document.createElement('div'); container.style = "border: 1px solid rgba(127,127,127,0.3); padding: 5px; border-radius: 15px;"; - const fields = ['Name', 'Temperature Sensor*', 'Leaf Temperature Sensor', 'Humidity Sensor*', /*'VPD Helper',*/ 'Calculated RH?']; + const fields = [this.language.name, this.language.temperature_sensor + '*', this.language.leaf_temperature_sensor, this.language.humidity_sensor + '*', /*'VPD Helper',*/ this.language.use_leaf_position]; const properties = ['name', 'temperature', 'leaf_temperature', 'humidity', /*'vpd_helper',*/ 'show_calculated_rh']; fields.forEach((field, i) => { @@ -588,14 +583,17 @@ export class HaVpdChartEditor extends HTMLElement { element = this.createComboBox(field, index, sensor[properties[i]], properties[i], 'humidity'); break; case 'show_calculated_rh': - element = this.createCheckbox(field, index, sensor[properties[i]], properties[i]); + element = this.createCheckbox(field, index, sensor[properties[i]], properties[i], this.language.description.use_leaf_position); break; default: element = this.createTextField(field, index, sensor[properties[i]]); break; } element.addEventListener('value-changed', (ev) => updateSensors(index, properties[i], ev)); - element.addEventListener('input', (ev) => updateSensors(index, properties[i], ev.target)); + const debouncedHandleInputChange = this.debounce(updateSensors, 500); + element.addEventListener('input', function (event) { + debouncedHandleInputChange(index, properties[i], event.target); + }); container.appendChild(element); }); const removeButton = document.createElement('button'); @@ -614,14 +612,11 @@ export class HaVpdChartEditor extends HTMLElement { }); } const addButton = document.createElement('button'); - addButton.innerHTML = 'Add Sensor'; + addButton.innerHTML = this.language.buttons.addSensor; addButton.className = 'addButton'; addButton.addEventListener('click', () => { let configCopy = this.copyConfig(); - configCopy.sensors[configCopy.sensors.length] = [ - {name: '', temperature: '', humidity: '', leaf_temperature: null, vpd_helper: false, show_calculated_rh: false} - ]; - + configCopy.sensors[configCopy.sensors.length] = [{name: '', temperature: '', humidity: '', leaf_temperature: null, vpd_helper: false, show_calculated_rh: false}]; this.config = configCopy; this.fireEvent(this, 'config-changed', {config: this.config}); this.initSensors(); @@ -636,7 +631,6 @@ export class HaVpdChartEditor extends HTMLElement { colorEditor.style.display = 'grid'; colorEditor.style.gridTemplateColumns = 'repeat(2, 1fr)'; colorEditor.style.gap = '10px'; - this._vpd_phases.forEach((phase, index) => { const container = document.createElement('div'); const input = document.createElement('ha-textfield'); @@ -684,8 +678,7 @@ export class HaVpdChartEditor extends HTMLElement { let idx = index; let copyConfig = this.copyConfig(); copyConfig.vpd_phases[idx] = { - ...this.copyConfig().vpd_phases[idx], - color: ev.target.value + ...this.copyConfig().vpd_phases[idx], color: ev.target.value }; let vpdPhases = [...copyConfig.vpd_phases]; @@ -709,7 +702,7 @@ export class HaVpdChartEditor extends HTMLElement { } const addButton = document.createElement('button'); - addButton.innerHTML = 'Add Phase'; + addButton.innerHTML = this.language.buttons.addPhase; addButton.className = 'addButton'; addButton.addEventListener('click', () => { let copyConfig = this.copyConfig(); @@ -729,10 +722,7 @@ export class HaVpdChartEditor extends HTMLElement { let newLowerValue = this.toFixedNumber(lowerValue + ((this.toFixedNumber(this.multiRange.settings.max) - lowerValue) / 2)) newVpdPhases[newVpdPhases.length - 1].upper = newLowerValue; newVpdPhases.push({ - lower: newLowerValue, - upper: maxVPD, - className: randomPhaseName, - color: randomColor + lower: newLowerValue, upper: maxVPD, className: randomPhaseName, color: randomColor }); let rangesArray = this.generateRangesArray(newVpdPhases); @@ -758,8 +748,7 @@ export class HaVpdChartEditor extends HTMLElement { color = newVpdPhases[i + 1].color; } rangesArray.push({ - value: newVpdPhases[i].upper, - color: color + value: newVpdPhases[i].upper, color: color }); } return rangesArray; diff --git a/dist/ha-vpd-chart.js b/dist/ha-vpd-chart.js index a1c328e..b4f875f 100644 --- a/dist/ha-vpd-chart.js +++ b/dist/ha-vpd-chart.js @@ -1,5 +1,5 @@ // Set version for the card -window.vpdChartVersion = "1.5.0"; +window.vpdChartVersion = "1.6.0"; import {methods} from './methods.js'; import {chart} from './chart.js'; diff --git a/dist/lang/cz.js b/dist/lang/cz.js new file mode 100644 index 0000000..ba47b27 --- /dev/null +++ b/dist/lang/cz.js @@ -0,0 +1,53 @@ +export const language = { + name: 'Nombre', + air_text: "Texto de aire", + rh_text: "Texto de RH", + kpa_text: "Texto de kPa", + min_height: "Altura mínima de la mesa", + min_temperature: "Temperatura mínima", + max_temperature: "Temperatura máxima", + min_humidity: "Humedad mínima", + max_humidity: "Humedad máxima", + leaf_temperature_offset: "Compensación de temperatura de la hoja", + ghostmap_hours: "Horas de Ghostmap", + temperature_sensor: "Sensor de temperatura", + humidity_sensor: "Sensor de humedad", + leaf_temperature_sensor: "Sensor de temperatura de la hoja", + use_leaf_position: "¿Usar posición de la hoja?", + description: { + use_leaf_position: "Usar la temperatura de la hoja como posición para la visualización de VPD (recalcula RH)", + is_bar_view: "Habilitar vista de barras de este gráfico para información rápida de los sensores", + enable_axes: "Habilitar ejes en el gráfico", + enable_ghostmap: "Habilitar Ghostmap en el gráfico para obtener el historial del sensor", + enable_ghostclick: "Habilitar Ghostclick en lugar de pasar el ratón", + enable_triangle: "Habilitar triángulo en lugar de círculo para el marcador de tooltip", + enable_tooltip: "Habilitar tooltip en el gráfico", + enable_crosshair: "Habilitar mira al pasar el ratón por el gráfico", + enable_fahrenheit: "Habilitar Fahrenheit en lugar de Celsius", + enable_zoom: "Habilitar función de zoom en el gráfico (presionar rueda del ratón para restablecer)", + enable_legend: "Habilitar leyenda para las fases", + enable_show_always_informations: "Habilitar mostrar siempre la información del tooltip para el gráfico" + }, + titles: { + is_bar_view: "Vista de barras", + enable_axes: "Habilitar ejes", + enable_ghostmap: "Habilitar Ghostmap", + enable_ghostclick: "Habilitar Ghostclick", + enable_triangle: "Habilitar triángulo", + enable_tooltip: "Habilitar tooltip", + enable_crosshair: "Habilitar mira", + enable_fahrenheit: "Habilitar Fahrenheit", + enable_zoom: "Habilitar zoom", + enable_legend: "Habilitar leyenda", + enable_show_always_informations: "Mostrar siempre info" + }, + buttons: { + sensors: "Sensores", + addSensor: "Añadir sensor", + addPhase: "Añadir fase", + main_settings: "Ajustes principales", + features: "Características", + phases: "Configurar fases", + vpd_calibration: "Fórmula de calibración de VPD" + } +} diff --git a/dist/lang/da.js b/dist/lang/da.js new file mode 100644 index 0000000..00a21d0 --- /dev/null +++ b/dist/lang/da.js @@ -0,0 +1,53 @@ +export const language = { + name: 'Navn', + air_text: "Luft tekst", + rh_text: "RH tekst", + kpa_text: "kPa tekst", + min_height: "Min. højde på bord", + min_temperature: "Min. temperatur", + max_temperature: "Max. temperatur", + min_humidity: "Min. luftfugtighed", + max_humidity: "Max. luftfugtighed", + leaf_temperature_offset: "Bladtemperatur-offset", + ghostmap_hours: "Ghostmap timer", + temperature_sensor: "Temperatursensor", + humidity_sensor: "Fugtighedssensor", + leaf_temperature_sensor: "Bladtemperatursensor", + use_leaf_position: "Brug bladposition?", + description: { + use_leaf_position: "Brug bladtemperatur som position til VPD-værktøjstip (beregner RH igen)", + is_bar_view: "Aktiver søjlediagram for hurtig sensorinformation", + enable_axes: "Aktiver akser i diagrammet", + enable_ghostmap: "Aktiver Ghostmap i diagrammet for at få historik over sensor", + enable_ghostclick: "Aktiver Ghostclick i stedet for hover", + enable_triangle: "Aktiver trekant i stedet for cirkel som værktøjstipmarkør", + enable_tooltip: "Aktiver værktøjstip i diagrammet", + enable_crosshair: "Aktiver krydshår ved MouseHover i diagrammet", + enable_fahrenheit: "Aktiver Fahrenheit i stedet for Celsius", + enable_zoom: "Aktiver zoomfunktion i diagrammet (tryk på midterste museknap for at nulstille)", + enable_legend: "Aktiver legend for faser", + enable_show_always_informations: "Aktiver altid værktøjstipinformation i diagrammet" + }, + titles: { + is_bar_view: "Søjlediagram", + enable_axes: "Aktiver akser", + enable_ghostmap: "Aktiver Ghostmap", + enable_ghostclick: "Aktiver Ghostclick", + enable_triangle: "Aktiver trekant", + enable_tooltip: "Aktiver værktøjstip", + enable_crosshair: "Aktiver krydshår", + enable_fahrenheit: "Aktiver Fahrenheit", + enable_zoom: "Aktiver zoom", + enable_legend: "Aktiver legend", + enable_show_always_informations: "Vis altid info" + }, + buttons: { + sensors: "Sensorer", + addSensor: "Tilføj sensor", + addPhase: "Tilføj fase", + main_settings: "Hovedindstillinger", + features: "Funktioner", + phases: "Konfigurer faser", + vpd_calibration: "VPD Kalibreringsformel" + } +} diff --git a/dist/lang/de.js b/dist/lang/de.js new file mode 100644 index 0000000..98bbc0e --- /dev/null +++ b/dist/lang/de.js @@ -0,0 +1,53 @@ +export const language = { + name: 'Name', + air_text: "Luft Text", + rh_text: "RH Text", + kpa_text: "kPa Text", + min_height: "Minimale Höhe des Tisches", + min_temperature: "Minimale Temperatur", + max_temperature: "Maximale Temperatur", + min_humidity: "Minimale Luftfeuchtigkeit", + max_humidity: "Maximale Luftfeuchtigkeit", + leaf_temperature_offset: "Blatttemperatur-Offset", + ghostmap_hours: "Ghostmap Stunden", + temperature_sensor: "Temperatursensor", + humidity_sensor: "Feuchtigkeitssensor", + leaf_temperature_sensor: "Blatttemperatursensor", + use_leaf_position: "Blattposition verwenden?", + description: { + use_leaf_position: "Blatttemperatur als Position für die VPD-Tooltip-Anzeige verwenden (berechnet RH neu)", + is_bar_view: "Balkenansicht dieses Diagramms für schnelle Sensorinformationen aktivieren", + enable_axes: "Achsen im Diagramm aktivieren", + enable_ghostmap: "Ghostmap im Diagramm aktivieren, um die Sensorhistorie anzuzeigen", + enable_ghostclick: "Ghostclick anstelle von Hover aktivieren", + enable_triangle: "Dreieck anstelle eines Kreises als Tooltip-Marker aktivieren", + enable_tooltip: "Tooltip im Diagramm aktivieren", + enable_crosshair: "MouseHover Fadenkreuz im Diagramm aktivieren", + enable_fahrenheit: "Fahrenheit anstelle von Celsius aktivieren", + enable_zoom: "Zoomfunktion im Diagramm aktivieren (Mittlere Maustaste drücken, um zurückzusetzen)", + enable_legend: "Legende für Phasen aktivieren", + enable_show_always_informations: "Immer Tooltip-Informationen für das Diagramm anzeigen" + }, + titles: { + is_bar_view: "Balkenansicht", + enable_axes: "Achsen aktivieren", + enable_ghostmap: "Ghostmap aktivieren", + enable_ghostclick: "Ghostclick aktivieren", + enable_triangle: "Dreieck aktivieren", + enable_tooltip: "Tooltip aktivieren", + enable_crosshair: "Fadenkreuz aktivieren", + enable_fahrenheit: "Fahrenheit aktivieren", + enable_zoom: "Zoom aktivieren", + enable_legend: "Legende aktivieren", + enable_show_always_informations: "Immer Info anzeigen" + }, + buttons: { + sensors: "Sensoren", + addSensor: "Sensor hinzufügen", + addPhase: "Phase hinzufügen", + main_settings: "Haupteinstellungen", + features: "Funktionen", + phases: "Phasen konfigurieren", + vpd_calibration: "VPD-Kalibrierungsformel" + } +} diff --git a/dist/lang/en.js b/dist/lang/en.js new file mode 100644 index 0000000..9debc14 --- /dev/null +++ b/dist/lang/en.js @@ -0,0 +1,54 @@ +export const language = { + name: 'Name', + air_text: "Air Text", + rh_text: "RH Text", + kpa_text: "kPa Text", + min_height: "Min. Height of Table", + min_temperature: "Min. Temperature", + max_temperature: "Max. Temperature", + min_humidity: "Min. Humidity", + max_humidity: "Max. Humidity", + leaf_temperature_offset: "Leaf Temperature Offset", + ghostmap_hours: "Ghostmap Hours", + temperature_sensor: "Temperature Sensor", + humidity_sensor: "Humidity Sensor", + leaf_temperature_sensor: "Leaf Temperature Sensor", + use_leaf_position: "Use Leaf Position?", + description: { + use_leaf_position: "Use Leaf Temperature as Position for VPD Tooltip Rendering (recalculates RH)", + is_bar_view: "Enable Bar view of this chart for fast information of sensors", + enable_axes: "Enable Axes on the Chart", + enable_ghostmap: "Enable Ghostmap on the Chart to get history of Sensor", + enable_ghostclick: "Enable Ghostclick instead of Hover", + enable_triangle: "Enable Triangle instead of Circle for tooltip marker", + enable_tooltip: "Enable tooltip on the Chart", + enable_crosshair: "Enable MouseHover Crosshair on the Chart", + enable_fahrenheit: "Enable Fahrenheit instead of Celsius", + enable_zoom: "Enable Zoomfunction on the Chart (MouseWheel Press to reset)", + enable_legend: "Enable Legend for Phases", + enable_show_always_informations: "Enable show always tooltip information for chart" + }, + titles: { + is_bar_view: "Bar View", + enable_axes: "Enable Axes", + enable_ghostmap: "Enable Ghostmap", + enable_ghostclick: "Enable Ghostclick", + enable_triangle: "Enable Triangle", + enable_tooltip: "Enable Tooltip", + enable_crosshair: "Enable MouseHover Crosshair", + enable_fahrenheit: "Enable Fahrenheit", + enable_zoom: "Enable Zoom", + enable_legend: "Enable Legend", + enable_show_always_informations: "Always Show Info" + }, + buttons: { + sensors: "Sensors", + addSensor: "Add Sensor", + addPhase: "Add Phase", + main_settings: "Main Settings", + features: "Features", + phases: "Configure Phases", + vpd_calibration: "VPD Calibration Formula" + + } +} \ No newline at end of file diff --git a/dist/lang/es.js b/dist/lang/es.js new file mode 100644 index 0000000..ba47b27 --- /dev/null +++ b/dist/lang/es.js @@ -0,0 +1,53 @@ +export const language = { + name: 'Nombre', + air_text: "Texto de aire", + rh_text: "Texto de RH", + kpa_text: "Texto de kPa", + min_height: "Altura mínima de la mesa", + min_temperature: "Temperatura mínima", + max_temperature: "Temperatura máxima", + min_humidity: "Humedad mínima", + max_humidity: "Humedad máxima", + leaf_temperature_offset: "Compensación de temperatura de la hoja", + ghostmap_hours: "Horas de Ghostmap", + temperature_sensor: "Sensor de temperatura", + humidity_sensor: "Sensor de humedad", + leaf_temperature_sensor: "Sensor de temperatura de la hoja", + use_leaf_position: "¿Usar posición de la hoja?", + description: { + use_leaf_position: "Usar la temperatura de la hoja como posición para la visualización de VPD (recalcula RH)", + is_bar_view: "Habilitar vista de barras de este gráfico para información rápida de los sensores", + enable_axes: "Habilitar ejes en el gráfico", + enable_ghostmap: "Habilitar Ghostmap en el gráfico para obtener el historial del sensor", + enable_ghostclick: "Habilitar Ghostclick en lugar de pasar el ratón", + enable_triangle: "Habilitar triángulo en lugar de círculo para el marcador de tooltip", + enable_tooltip: "Habilitar tooltip en el gráfico", + enable_crosshair: "Habilitar mira al pasar el ratón por el gráfico", + enable_fahrenheit: "Habilitar Fahrenheit en lugar de Celsius", + enable_zoom: "Habilitar función de zoom en el gráfico (presionar rueda del ratón para restablecer)", + enable_legend: "Habilitar leyenda para las fases", + enable_show_always_informations: "Habilitar mostrar siempre la información del tooltip para el gráfico" + }, + titles: { + is_bar_view: "Vista de barras", + enable_axes: "Habilitar ejes", + enable_ghostmap: "Habilitar Ghostmap", + enable_ghostclick: "Habilitar Ghostclick", + enable_triangle: "Habilitar triángulo", + enable_tooltip: "Habilitar tooltip", + enable_crosshair: "Habilitar mira", + enable_fahrenheit: "Habilitar Fahrenheit", + enable_zoom: "Habilitar zoom", + enable_legend: "Habilitar leyenda", + enable_show_always_informations: "Mostrar siempre info" + }, + buttons: { + sensors: "Sensores", + addSensor: "Añadir sensor", + addPhase: "Añadir fase", + main_settings: "Ajustes principales", + features: "Características", + phases: "Configurar fases", + vpd_calibration: "Fórmula de calibración de VPD" + } +} diff --git a/dist/lang/it.js b/dist/lang/it.js new file mode 100644 index 0000000..c9cddc4 --- /dev/null +++ b/dist/lang/it.js @@ -0,0 +1,53 @@ +export const language = { + name: 'Nome', + air_text: "Testo Aria", + rh_text: "Testo RH", + kpa_text: "Testo kPa", + min_height: "Altezza minima del tavolo", + min_temperature: "Temperatura minima", + max_temperature: "Temperatura massima", + min_humidity: "Umidità minima", + max_humidity: "Umidità massima", + leaf_temperature_offset: "Offset della temperatura della foglia", + ghostmap_hours: "Ore Ghostmap", + temperature_sensor: "Sensore di temperatura", + humidity_sensor: "Sensore di umidità", + leaf_temperature_sensor: "Sensore di temperatura della foglia", + use_leaf_position: "Usa la posizione della foglia?", + description: { + use_leaf_position: "Usa la temperatura della foglia come posizione per la visualizzazione del tooltip VPD (ricalcola RH)", + is_bar_view: "Abilita la visualizzazione a barre di questo grafico per informazioni rapide sui sensori", + enable_axes: "Abilita gli assi sul grafico", + enable_ghostmap: "Abilita Ghostmap sul grafico per ottenere la cronologia del sensore", + enable_ghostclick: "Abilita Ghostclick al posto del passaggio del mouse", + enable_triangle: "Abilita il triangolo al posto del cerchio per il marcatore del tooltip", + enable_tooltip: "Abilita il tooltip sul grafico", + enable_crosshair: "Abilita il mirino durante il passaggio del mouse sul grafico", + enable_fahrenheit: "Abilita Fahrenheit al posto di Celsius", + enable_zoom: "Abilita la funzione di zoom sul grafico (premere il pulsante centrale del mouse per reimpostare)", + enable_legend: "Abilita la legenda per le fasi", + enable_show_always_informations: "Mostra sempre le informazioni sul tooltip per il grafico" + }, + titles: { + is_bar_view: "Vista a barre", + enable_axes: "Abilita assi", + enable_ghostmap: "Abilita Ghostmap", + enable_ghostclick: "Abilita Ghostclick", + enable_triangle: "Abilita triangolo", + enable_tooltip: "Abilita tooltip", + enable_crosshair: "Abilita mirino", + enable_fahrenheit: "Abilita Fahrenheit", + enable_zoom: "Abilita zoom", + enable_legend: "Abilita legenda", + enable_show_always_informations: "Mostra sempre le info" + }, + buttons: { + sensors: "Sensori", + addSensor: "Aggiungi sensore", + addPhase: "Aggiungi fase", + main_settings: "Impostazioni principali", + features: "Funzionalità", + phases: "Configura fasi", + vpd_calibration: "Formula di calibrazione VPD" + } +} diff --git a/dist/lang/pl.js b/dist/lang/pl.js new file mode 100644 index 0000000..fd0d625 --- /dev/null +++ b/dist/lang/pl.js @@ -0,0 +1,53 @@ +export const language = { + name: 'Nazwa', + air_text: "Tekst powietrza", + rh_text: "Tekst RH", + kpa_text: "Tekst kPa", + min_height: "Minimalna wysokość stołu", + min_temperature: "Minimalna temperatura", + max_temperature: "Maksymalna temperatura", + min_humidity: "Minimalna wilgotność", + max_humidity: "Maksymalna wilgotność", + leaf_temperature_offset: "Offset temperatury liścia", + ghostmap_hours: "Godziny Ghostmap", + temperature_sensor: "Czujnik temperatury", + humidity_sensor: "Czujnik wilgotności", + leaf_temperature_sensor: "Czujnik temperatury liścia", + use_leaf_position: "Użyj pozycji liścia?", + description: { + use_leaf_position: "Użyj temperatury liścia jako pozycji do renderowania VPD Tooltip (ponownie oblicza RH)", + is_bar_view: "Włącz widok słupkowy tego wykresu dla szybkiej informacji o czujnikach", + enable_axes: "Włącz osie na wykresie", + enable_ghostmap: "Włącz Ghostmap na wykresie, aby uzyskać historię czujnika", + enable_ghostclick: "Włącz Ghostclick zamiast najeżdżania kursorem", + enable_triangle: "Włącz trójkąt zamiast koła dla wskaźnika narzędzi", + enable_tooltip: "Włącz tooltip na wykresie", + enable_crosshair: "Włącz celownik na wykresie podczas najeżdżania kursorem", + enable_fahrenheit: "Włącz Fahrenheita zamiast Celsjusza", + enable_zoom: "Włącz funkcję zoomu na wykresie (naciśnij środkowy przycisk myszy, aby zresetować)", + enable_legend: "Włącz legendę dla faz", + enable_show_always_informations: "Zawsze wyświetlaj informacje tooltip na wykresie" + }, + titles: { + is_bar_view: "Widok słupkowy", + enable_axes: "Włącz osie", + enable_ghostmap: "Włącz Ghostmap", + enable_ghostclick: "Włącz Ghostclick", + enable_triangle: "Włącz trójkąt", + enable_tooltip: "Włącz tooltip", + enable_crosshair: "Włącz celownik", + enable_fahrenheit: "Włącz Fahrenheita", + enable_zoom: "Włącz zoom", + enable_legend: "Włącz legendę", + enable_show_always_informations: "Zawsze pokazuj informacje" + }, + buttons: { + sensors: "Czujniki", + addSensor: "Dodaj czujnik", + addPhase: "Dodaj fazę", + main_settings: "Ustawienia główne", + features: "Funkcje", + phases: "Konfiguruj fazy", + vpd_calibration: "Formuła kalibracji VPD" + } +} diff --git a/dist/lang/ru.js b/dist/lang/ru.js new file mode 100644 index 0000000..de23b39 --- /dev/null +++ b/dist/lang/ru.js @@ -0,0 +1,53 @@ +export const language = { + name: 'Имя', + air_text: "Текст воздуха", + rh_text: "Текст RH", + kpa_text: "Текст кПа", + min_height: "Минимальная высота стола", + min_temperature: "Минимальная температура", + max_temperature: "Максимальная температура", + min_humidity: "Минимальная влажность", + max_humidity: "Максимальная влажность", + leaf_temperature_offset: "Смещение температуры листа", + ghostmap_hours: "Часы Ghostmap", + temperature_sensor: "Датчик температуры", + humidity_sensor: "Датчик влажности", + leaf_temperature_sensor: "Датчик температуры листа", + use_leaf_position: "Использовать положение листа?", + description: { + use_leaf_position: "Использовать температуру листа как положение для отображения VPD подсказки (пересчитывает RH)", + is_bar_view: "Включить отображение графика в виде столбцов для быстрой информации о датчиках", + enable_axes: "Включить оси на графике", + enable_ghostmap: "Включить Ghostmap на графике для отображения истории датчика", + enable_ghostclick: "Включить Ghostclick вместо наведения мыши", + enable_triangle: "Включить треугольник вместо круга для маркера подсказки", + enable_tooltip: "Включить подсказку на графике", + enable_crosshair: "Включить прицел при наведении курсора на график", + enable_fahrenheit: "Включить Фаренгейт вместо Цельсия", + enable_zoom: "Включить функцию увеличения на графике (нажмите среднюю кнопку мыши для сброса)", + enable_legend: "Включить легенду для фаз", + enable_show_always_informations: "Всегда показывать информацию подсказки для графика" + }, + titles: { + is_bar_view: "Просмотр столбцов", + enable_axes: "Включить оси", + enable_ghostmap: "Включить Ghostmap", + enable_ghostclick: "Включить Ghostclick", + enable_triangle: "Включить треугольник", + enable_tooltip: "Включить подсказку", + enable_crosshair: "Включить прицел", + enable_fahrenheit: "Включить Фаренгейт", + enable_zoom: "Включить увеличение", + enable_legend: "Включить легенду", + enable_show_always_informations: "Всегда показывать информацию" + }, + buttons: { + sensors: "Датчики", + addSensor: "Добавить датчик", + addPhase: "Добавить фазу", + main_settings: "Основные настройки", + features: "Функции", + phases: "Настроить фазы", + vpd_calibration: "Формула калибровки VPD" + } +} diff --git a/dist/methods.js b/dist/methods.js index 615fc4b..a194288 100644 --- a/dist/methods.js +++ b/dist/methods.js @@ -42,6 +42,15 @@ export const methods = { return false; }, + debounce(func, timeout = 300) { + let timer; + return (...args) => { + clearTimeout(timer); + timer = setTimeout(() => { + func.apply(this, args); + }, timeout); + }; + }, async getEntityHistory(entityId, hours = 24) { const endTime = new Date(); const startTime = new Date(endTime.getTime() - hours * 60 * 60 * 1000); @@ -98,23 +107,15 @@ export const methods = { getLeafTemperatureOffset() { let offset = 2; if (typeof this.config.leaf_temperature_offset === 'number') { - if (this.config.leaf_temperature_offset < 2) { - return 2; - } + return this.config.leaf_temperature_offset; } if (typeof this.config.leaf_temperature_offset === 'string') { offset = this._hass.states[this.config.leaf_temperature_offset].state; if (!isNaN(offset)) { - if (offset < 2) { - return 2; - } return offset; } } - if (offset < 2) { - offset = 2; - } return offset; }, copyConfig() { @@ -178,21 +179,17 @@ export const methods = { return haComboBox; }, - createCheckbox(label, index, value, property) { - const divElement = document.createElement('div'); - divElement.style = 'display: flex; align-items: center; padding:13px;'; - const labelElement = document.createElement('label'); - const checkbox = document.createElement('input'); - checkbox.type = 'checkbox'; + createCheckbox(label, index, value, property, title = '') { + const haFormfield = document.createElement('ha-formfield'); + haFormfield.label = label; + if (title !== '') haFormfield.title = title; + haFormfield.setAttribute('data-index', index); + const checkbox = document.createElement('ha-checkbox'); checkbox.id = property; - if (value) { - checkbox.setAttribute('checked', 'checked'); - } + checkbox.checked = value; checkbox.setAttribute('data-configvalue', property); - labelElement.appendChild(checkbox); - labelElement.innerHTML += label; - divElement.appendChild(labelElement); - return divElement; + haFormfield.appendChild(checkbox); + return haFormfield; }, fireEvent(node, type, detail = {}, options = {}) { const event = new Event(type, {