From cbb11b78567cbca44d28713fc89ff5bfc881d939 Mon Sep 17 00:00:00 2001 From: RFDarter Date: Thu, 2 May 2024 00:22:18 +0200 Subject: [PATCH 1/3] Add support for sorting entitys via the config (#58) Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- packages/v3/src/esp-entity-table.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/packages/v3/src/esp-entity-table.ts b/packages/v3/src/esp-entity-table.ts index 2c72fa2..fd0f98b 100644 --- a/packages/v3/src/esp-entity-table.ts +++ b/packages/v3/src/esp-entity-table.ts @@ -10,6 +10,7 @@ import "iconify-icon"; interface entityConfig { unique_id: string; + sorting_weight: number; domain: string; id: string; state: string; @@ -98,15 +99,17 @@ export class EntityTable extends LitElement implements RestAction { this.has_controls = true; } this.entities.push(entity); - this.entities.sort((a, b) => - a.entity_category < b.entity_category - ? -1 - : a.entity_category == b.entity_category - ? a.name < b.name - ? -1 - : 1 - : 1 - ); + 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 + ? -1 + : 1 + : 1 + }); this.requestUpdate(); } else { if (typeof data.value === "number") { From 994b43489ce3efca94e70dd63a8cc00d7b8d6d48 Mon Sep 17 00:00:00 2001 From: Rebbe Pod <66928914+RebbePod@users.noreply.github.com> Date: Fri, 3 May 2024 02:22:24 -0400 Subject: [PATCH 2/3] Update esp-entity-table.ts (#96) --- packages/v3/src/esp-entity-table.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/v3/src/esp-entity-table.ts b/packages/v3/src/esp-entity-table.ts index fd0f98b..3b31e5b 100644 --- a/packages/v3/src/esp-entity-table.ts +++ b/packages/v3/src/esp-entity-table.ts @@ -408,7 +408,7 @@ class ActionRenderer { minlength="${min || Math.min(0, value as number)}" maxlength="${max || Math.max(255, value as number)}" pattern="${pattern || ""}" - value="${value!}" + .value="${value!}" @change="${(e: Event) => { const val = (e.target)?.value; this.actioner?.restAction( From b09657b8d9012b8d3007c3db4c9247a93574cb1b Mon Sep 17 00:00:00 2001 From: mattsgreen Date: Wed, 8 May 2024 00:07:35 +0100 Subject: [PATCH 3/3] v3 Climate Component (#86) Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- packages/v3/src/css/esp-entity-table.ts | 10 ++ packages/v3/src/esp-entity-table.ts | 184 +++++++++++++++--------- 2 files changed, 130 insertions(+), 64 deletions(-) diff --git a/packages/v3/src/css/esp-entity-table.ts b/packages/v3/src/css/esp-entity-table.ts index 82a93a6..0fc3fbb 100644 --- a/packages/v3/src/css/esp-entity-table.ts +++ b/packages/v3/src/css/esp-entity-table.ts @@ -76,4 +76,14 @@ export default css` input[type="color"]::-webkit-color-swatch-wrapper { padding: 0 !important; } + + .climate { + width: 100%; + display: grid; + text-align: center; + grid-template-columns: repeat(3, 1fr); + gap: 6px; + padding: 10px; + align-items: center; + } `; diff --git a/packages/v3/src/esp-entity-table.ts b/packages/v3/src/esp-entity-table.ts index 3b31e5b..fd94157 100644 --- a/packages/v3/src/esp-entity-table.ts +++ b/packages/v3/src/esp-entity-table.ts @@ -39,6 +39,8 @@ interface entityConfig { current_temperature?: number; modes?: number[]; mode?: number; + presets?: number[]; + preset?: number; speed_count?: number; speed_level?: number; speed: string; @@ -92,8 +94,12 @@ export class EntityTable extends LitElement implements RestAction { unique_id: data.id, id: parts.slice(1).join("-"), entity_category: data.entity_category, - value_numeric_history: [data.value], } as entityConfig; + if (typeof data.value === "number") { + entity.value_numeric_history = [data.value]; + } else if (data.current_temperature) { + entity.value_numeric_history = [Number(data.current_temperature)]; + } entity.has_action = this.hasAction(entity); if (entity.has_action) { this.has_controls = true; @@ -112,11 +118,13 @@ export class EntityTable extends LitElement implements RestAction { }); this.requestUpdate(); } else { + let history = [...this.entities[idx].value_numeric_history]; 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); + } else if (data.current_temperature) { + history.push(Number(data.current_temperature)); } + this.entities[idx].value_numeric_history = history.splice(-50); delete data.id; delete data.domain; @@ -217,7 +225,8 @@ export class EntityTable extends LitElement implements RestAction { ? this.control(component) : html`
${component.state}
`} - ${component.domain === "sensor" + ${component.domain === "sensor" || + component.domain === "climate" ? html`` @@ -238,7 +247,10 @@ export class EntityTable extends LitElement implements RestAction { } _handleEntityRowClick(e: any) { - if (e?.currentTarget?.domain === "sensor") { + if ( + e?.currentTarget?.domain === "sensor" || + e?.currentTarget?.domain === "climate" + ) { if (!e?.ctrlKey) e.stopPropagation(); e?.currentTarget?.classList.toggle( "expanded", @@ -285,25 +297,71 @@ class ActionRenderer { `; } + private _tempSelector(entity: entityConfig, target: string) { + if (!entity) return; + let targetTemp = + target === "high" + ? entity.target_temperature_high + : entity.target_temperature || entity.target_temperature_low; + let upValue = + target === "high" + ? Number(entity.target_temperature_high) + Number(entity.step) + : Number(entity.target_temperature || entity.target_temperature_low) + + Number(entity.step); + let downValue = + target === "high" + ? Number(entity.target_temperature_high) - Number(entity.step) + : Number(entity.target_temperature || entity.target_temperature_low) - + Number(entity.step); + upValue = + upValue > Number(entity.max_temp) ? Number(entity.max_temp) : upValue; + downValue = + downValue > Number(entity.max_temp) ? Number(entity.max_temp) : downValue; + + let upAction = target + ? `set?target_temperature_${target}=${upValue}` + : `set?target_temperature=${upValue}`; + let downAction = target + ? `set?target_temperature_${target}=${downValue}` + : `set?target_temperature=${downValue}`; + + return html`
+
+ `; + } + private _datetime( entity: entityConfig, type: string, action: string, opt: string, - value: string, + value: string ) { return html` - `; @@ -328,7 +386,11 @@ class ActionRenderer { val: string | number | undefined ) { return html` - `; + `; } else { - return html` - e.target)?.value; + this.actioner?.restAction( + entity, + `${action}?${opt}=${e.detail.state}` + ); + }}" >`; } - } private _textinput( @@ -612,57 +675,50 @@ class ActionRenderer { target_temp_label = html`${this.entity .target_temperature_low} .. ${this.entity .target_temperature_high}`; - target_temp_slider = 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_high", - this.entity.target_temperature_high, - this.entity.min_temp, - this.entity.max_temp, - this.entity.step - )} - `; } else { target_temp_label = html`${this.entity.target_temperature}`; - target_temp_slider = html` - ${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``; if ((this.entity.modes ? this.entity.modes.length : 0) > 0) { - modes = html`Mode:
- ${this._select( - this.entity, - "set", - "mode", - this.entity.modes || [], - this.entity.mode || "" - )}`; + modes = html` ${this._select( + this.entity, + "set", + "mode", + this.entity.modes || [], + this.entity.mode || "" + )}`; + } + let presets = html``; + if ((this.entity.presets ? this.entity.presets.length : 0) > 0) { + presets = html` ${this._select( + this.entity, + "set", + "preset", + this.entity.presets || [], + this.entity.preset || "" + )}`; } + return html` - - ${target_temp_slider} ${modes} +
+
+ ${this._tempSelector( + this.entity, + this.entity.target_temperature_low ? "low" : "" + )} +
+
+ +
+
+ ${this.entity.target_temperature_high + ? this._tempSelector(this.entity, "high") + : ""} +
+
${modes}
+
${this.entity.state}
+
${presets}
+
`; } }