From 35302a4fea0662928226e1d63c9ac779b194c755 Mon Sep 17 00:00:00 2001 From: rfdarter Date: Thu, 3 Oct 2024 03:30:25 +0200 Subject: [PATCH] revert formatter chaos 2 --- packages/v3/src/esp-entity-table.ts | 601 +++++++++++++--------------- 1 file changed, 289 insertions(+), 312 deletions(-) diff --git a/packages/v3/src/esp-entity-table.ts b/packages/v3/src/esp-entity-table.ts index 4b9822e..2d587fb 100644 --- a/packages/v3/src/esp-entity-table.ts +++ b/packages/v3/src/esp-entity-table.ts @@ -1,12 +1,14 @@ -import { html, css, LitElement, TemplateResult, nothing } from "lit"; -import { customElement, state, property } from "lit/decorators.js"; -import cssReset from "./css/reset"; -import cssButton from "./css/button"; -import cssInput from "./css/input"; -import cssEntityTable from "./css/esp-entity-table"; -import cssTab from "./css/tab"; -import "./esp-entity-chart"; -import "iconify-icon"; +import './esp-entity-chart'; +import 'iconify-icon'; + +import {css, html, LitElement, nothing, TemplateResult} from 'lit'; +import {customElement, property, state} from 'lit/decorators.js'; + +import cssButton from './css/button'; +import cssEntityTable from './css/esp-entity-table'; +import cssInput from './css/input'; +import cssReset from './css/reset'; +import cssTab from './css/tab'; interface entityConfig { unique_id: string; @@ -50,19 +52,19 @@ interface entityConfig { is_disabled_by_default?: boolean; } -export const stateOn = "ON"; -export const stateOff = "OFF"; +export const stateOn = 'ON'; +export const stateOff = 'OFF'; export function getBasePath() { let str = window.location.pathname; - return str.endsWith("/") ? str.slice(0, -1) : str; + return str.endsWith('/') ? str.slice(0, -1) : str; } interface RestAction { restAction(entity?: entityConfig, action?: string): void; } -@customElement("esp-entity-table") +@customElement('esp-entity-table') export class EntityTable extends LitElement implements RestAction { @state() entities: entityConfig[] = []; @state() has_controls: boolean = false; @@ -70,53 +72,24 @@ export class EntityTable extends LitElement implements RestAction { private _actionRenderer = new ActionRenderer(); private _basePath = getBasePath(); - private static ENTITY_UNDEFINED = "States"; + private static ENTITY_UNDEFINED = 'States'; private static ENTITY_CATEGORIES = [ - "Sensor and Control", - "Configuration", - "Diagnostic", + 'Sensor and Control', + 'Configuration', + 'Diagnostic', ]; + private _unknown_state_events: {[key: string]: number} = {}; + connectedCallback() { super.connectedCallback(); - window.source?.addEventListener("state", (e: Event) => { + + window.source?.addEventListener('state', async (e: Event) => { const messageEvent = e as MessageEvent; const data = JSON.parse(messageEvent.data); let idx = this.entities.findIndex((x) => x.unique_id === data.id); - if (idx === -1 && data.id) { - // Dynamically add discovered.. - let parts = data.id.split("-"); - let entity = { - ...data, - domain: parts[0], - unique_id: data.id, - id: parts.slice(1).join("-"), - entity_category: data.entity_category, - value_numeric_history: [data.value], - } as entityConfig; - entity.has_action = this.hasAction(entity); - if (entity.has_action) { - this.has_controls = true; - } - this.entities.push(entity); - this.entities.sort((a, b) => { - const sortA = a.sorting_weight ?? a.name; - const sortB = b.sorting_weight ?? b.name; - return a.entity_category < b.entity_category - ? -1 - : a.entity_category == b.entity_category - ? sortA === sortB - ? a.name.toLowerCase() < b.name.toLowerCase() - ? -1 - : 1 - : sortA < sortB - ? -1 - : 1 - : 1 - }); - this.requestUpdate(); - } else { - if (typeof data.value === "number") { + if (idx != -1 && data.id) { + if (typeof data.value === 'number') { let history = [...this.entities[idx].value_numeric_history]; history.push(data.value); this.entities[idx].value_numeric_history = history.splice(-50); @@ -127,10 +100,84 @@ export class EntityTable extends LitElement implements RestAction { delete data.unique_id; Object.assign(this.entities[idx], data); this.requestUpdate(); + } else { + // is it a `detail_all` event already? + if (data?.name) { + this.addEntity(data); + } else { + if (this._unknown_state_events[data.id]) { + this._unknown_state_events[data.id]++; + } else { + this._unknown_state_events[data.id] = 1; + } + + // ignore the first few events, maybe the esp will send a init_entity + // event soon + if (this._unknown_state_events[data.id] < 5) { + return; + } + + let parts = data.id.split('-'); + let domain = parts[0]; + let id = parts.slice(1).join('-'); + + fetch(`${this._basePath}/${domain}/${id}?detail=all`, { + method: 'GET', + }) + .then((r) => { + console.log(r); + if (!r.ok) { + throw new Error(`HTTP error! Status: ${r.status}`); + } + return r.json(); + }) + .then((data) => { + console.log(data); + this.addEntity(data); + this._unknown_state_events.delete(data.id); + }) + .catch((error) => { + console.error('Fetch error:', error); + }); + } } }); } + addEntity(data: any) { + let idx = this.entities.findIndex((x) => x.unique_id === data.id); + if (idx === -1 && data.id) { + // Dynamically add discovered.. + let parts = data.id.split('-'); + let entity = { + ...data, + domain: parts[0], + unique_id: data.id, + id: parts.slice(1).join('-'), + entity_category: data.entity_category, + value_numeric_history: [data.value], + } as entityConfig; + entity.has_action = this.hasAction(entity); + if (entity.has_action) { + this.has_controls = true; + } + this.entities.push(entity); + this.entities.sort((a, b) => { + const sortA = a.sorting_weight ?? a.name; + const sortB = b.sorting_weight ?? b.name; + return a.entity_category < b.entity_category ? + -1 : + a.entity_category == b.entity_category ? + sortA === sortB ? + a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1 : + sortA < sortB ? -1 : + 1 : + 1 + }); + this.requestUpdate(); + } + } + hasAction(entity: entityConfig): boolean { return `render_${entity.domain}` in this._actionRenderer; } @@ -139,24 +186,21 @@ export class EntityTable extends LitElement implements RestAction { this._actionRenderer.entity = entity; this._actionRenderer.actioner = this; return this._actionRenderer.exec( - `render_${entity.domain}` as ActionRendererMethodKey - ); + `render_${entity.domain}` as ActionRendererMethodKey); } restAction(entity: entityConfig, action: string) { fetch(`${this._basePath}/${entity.domain}/${entity.id}/${action}`, { - method: "POST", - body: "true", + method: 'POST', + body: 'true', }).then((r) => { console.log(r); }); } renderShowAll() { - if ( - !this.show_all && - this.entities.find((elem) => elem.is_disabled_by_default) - ) { + if (!this.show_all && + this.entities.find((elem) => elem.is_disabled_by_default)) { return html`
`; } else { return html` e.target)?.value; + this.actioner?.restAction(entity, `${action}?${opt}=${e.detail.state}`); + }}" >`; } - } private _textinput( - entity: entityConfig, - action: string, - opt: string, - value: string | number, - min: number | undefined, - max: number | undefined, - pattern: string | undefined - ) { + entity: entityConfig, action: string, opt: string, value: string|number, + min: number|undefined, max: number|undefined, pattern: string|undefined) { return html` e.target)?.value; + this.actioner?.restAction( + entity, `${action}?${opt}=${encodeURIComponent(val)}`); + }}" /> `; } private _colorpicker(entity: entityConfig, action: string, value: any) { function u16tohex(d: number) { - return Number(d).toString(16).padStart(2, "0"); + return Number(d).toString(16).padStart(2, '0'); } function rgb_to_str(rgbhex: string) { - const rgb = rgbhex - .match(/[0-9a-f]{2}/gi) - ?.map((x) => parseInt(x, 16)) || [0, 0, 0]; + const rgb = rgbhex.match(/[0-9a-f]{2}/gi)?.map((x) => parseInt(x, 16)) || + [0, 0, 0]; return `r=${rgb[0]}&g=${rgb[1]}&b=${rgb[2]}`; } @@ -442,9 +456,9 @@ class ActionRenderer { id="${entity.unique_id}" value="#${u16tohex(value?.r)}${u16tohex(value?.g)}${u16tohex(value?.b)}" @change="${(e: Event) => { - const val = (e.target)?.value; - this.actioner?.restAction(entity, `${action}?${rgb_to_str(val)}`); - }}" + const val = (e.target)?.value; + this.actioner?.restAction(entity, `${action}?${rgb_to_str(val)}`); + }}" /> `; } @@ -454,7 +468,7 @@ class ActionRenderer { const isOn = this.entity.state == stateOn; return html``; } @@ -462,68 +476,68 @@ class ActionRenderer { render_date() { if (!this.entity) return; return html` - ${this._datetime( - this.entity, - "date", - "set", - "value", - this.entity.value, - )} + ${ + this._datetime( + this.entity, + 'date', + 'set', + 'value', + this.entity.value, + )} `; } render_time() { if (!this.entity) return; return html` - ${this._datetime( - this.entity, - "time", - "set", - "value", - this.entity.value, - )} + ${ + this._datetime( + this.entity, + 'time', + 'set', + 'value', + this.entity.value, + )} `; } render_datetime() { if (!this.entity) return; return html` - ${this._datetime( - this.entity, - "datetime-local", - "set", - "value", - this.entity.value, - )} + ${ + this._datetime( + this.entity, + 'datetime-local', + 'set', + 'value', + this.entity.value, + )} `; } render_switch() { if (!this.entity) return; if (this.entity.assumed_state) - return html`${this._actionButton(this.entity, "❌", "turn_off")} - ${this._actionButton(this.entity, "✔️", "turn_on")}`; - else return this._switch(this.entity); + return html`${this._actionButton(this.entity, '❌', 'turn_off')} + ${this._actionButton(this.entity, '✔️', 'turn_on')}`; + else + return this._switch(this.entity); } render_fan() { if (!this.entity) return; return [ this.entity.speed, - " ", + ' ', this.entity.speed_level, this._switch(this.entity), - this.entity.speed_count - ? this._range( - this.entity, - `turn_${this.entity.state.toLowerCase()}`, - "speed_level", - this.entity.speed_level ? this.entity.speed_level : 0, - 0, - this.entity.speed_count, - 1 - ) - : "", + this.entity.speed_count ? + this._range( + this.entity, `turn_${this.entity.state.toLowerCase()}`, + 'speed_level', + this.entity.speed_level ? this.entity.speed_level : 0, 0, + this.entity.speed_count, 1) : + '', ]; } @@ -533,75 +547,59 @@ class ActionRenderer { html`
${this._switch(this.entity)} - ${this.entity.brightness - ? this._range( - this.entity, - "turn_on", - "brightness", - this.entity.brightness, - 0, - 255, - 1 - ) - : ""} - ${this.entity.color_mode === "rgb" || this.entity.color_mode === "rgbw" - ? this._colorpicker(this.entity, "turn_on", this.entity?.color) - : ""} - ${this.entity.effects?.filter((v) => v != "None").length - ? this._select( - this.entity, - "turn_on", - "effect", - this.entity.effects || [], - this.entity.effect - ) - : ""} + ${ + this.entity.brightness ? this._range( + this.entity, 'turn_on', 'brightness', + this.entity.brightness, 0, 255, 1) : + ''} + ${ + this.entity.color_mode === 'rgb' || + this.entity.color_mode === 'rgbw' ? + this._colorpicker(this.entity, 'turn_on', this.entity?.color) : + ''} + ${ + this.entity.effects?.filter((v) => v != 'None').length ? + this._select( + this.entity, 'turn_on', 'effect', this.entity.effects || [], + this.entity.effect) : + ''}
`, ]; } render_lock() { if (!this.entity) return; - return html`${this._actionButton(this.entity, "🔐", "lock")} - ${this._actionButton(this.entity, "🔓", "unlock")} - ${this._actionButton(this.entity, "↑", "open")} `; + return html`${this._actionButton(this.entity, '🔐', 'lock')} + ${this._actionButton(this.entity, '🔓', 'unlock')} + ${this._actionButton(this.entity, '↑', 'open')} `; } render_cover() { if (!this.entity) return; - return html`${this._actionButton(this.entity, "↑", "open")} - ${this._actionButton(this.entity, "☐", "stop")} - ${this._actionButton(this.entity, "↓", "close")}`; + return html`${this._actionButton(this.entity, '↑', 'open')} + ${this._actionButton(this.entity, '☐', 'stop')} + ${this._actionButton(this.entity, '↓', 'close')}`; } render_button() { if (!this.entity) return; - return html`${this._actionButton(this.entity, "PRESS", "press")}`; + return html`${this._actionButton(this.entity, 'PRESS', 'press')}`; } render_select() { if (!this.entity) return; return this._select( - this.entity, - "set", - "option", - this.entity.option || [], - this.entity.value - ); + this.entity, 'set', 'option', this.entity.option || [], + this.entity.value); } render_number() { if (!this.entity) return; return html` - ${this._range( - this.entity, - "set", - "value", - this.entity.value, - this.entity.min_value, - this.entity.max_value, - this.entity.step - )} + ${ + this._range( + this.entity, 'set', 'value', this.entity.value, + this.entity.min_value, this.entity.max_value, this.entity.step)} ${this.entity.uom} `; } @@ -609,65 +607,47 @@ class ActionRenderer { render_text() { if (!this.entity) return; return this._textinput( - this.entity, - "set", - "value", - this.entity.value, - this.entity.min_length, - this.entity.max_length, - this.entity.pattern - ); + this.entity, 'set', 'value', this.entity.value, this.entity.min_length, + this.entity.max_length, this.entity.pattern); } render_climate() { if (!this.entity) return; let target_temp_slider, target_temp_label, target_temp; - let current_temp = html`
- + let current_temp = + html`
+
`; - - if ( - this.entity.target_temperature_low !== undefined && - this.entity.target_temperature_high !== undefined - ) { + + if (this.entity.target_temperature_low !== undefined && + this.entity.target_temperature_high !== undefined) { target_temp = html`
- ${this._range( - this.entity, - "set", - "target_temperature_low", - this.entity.target_temperature_low, - this.entity.min_temp, - this.entity.max_temp, - this.entity.step - )} + ${ + this._range( + this.entity, 'set', 'target_temperature_low', + this.entity.target_temperature_low, this.entity.min_temp, + this.entity.max_temp, this.entity.step)}
- ${this._range( - this.entity, - "set", - "target_temperature_high", - this.entity.target_temperature_high, - this.entity.min_temp, - this.entity.max_temp, - this.entity.step - )} + ${ + this._range( + this.entity, 'set', 'target_temperature_high', + this.entity.target_temperature_high, this.entity.min_temp, + this.entity.max_temp, this.entity.step)}
`; } else { target_temp = html`
- ${this._range( - this.entity, - "set", - "target_temperature", - this.entity.target_temperature!!, - this.entity.min_temp, - this.entity.max_temp, - this.entity.step - )} + ${ + this._range( + this.entity, 'set', 'target_temperature', + this.entity.target_temperature!!, this.entity.min_temp, + this.entity.max_temp, this.entity.step)}
`; } let modes = html``; @@ -675,13 +655,10 @@ class ActionRenderer { modes = html`
- ${this._select( - this.entity, - "set", - "mode", - this.entity.modes || [], - this.entity.mode || "" - )} + ${ + this._select( + this.entity, 'set', 'mode', this.entity.modes || [], + this.entity.mode || '')}
`; } return html`