Skip to content

Commit

Permalink
Merge pull request esphome#97 from esphome/dev
Browse files Browse the repository at this point in the history
  • Loading branch information
jesserockz authored May 7, 2024
2 parents 67bfc03 + b09657b commit 811813c
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 74 deletions.
10 changes: 10 additions & 0 deletions packages/v3/src/css/esp-entity-table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
`;
207 changes: 133 additions & 74 deletions packages/v3/src/esp-entity-table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import "iconify-icon";

interface entityConfig {
unique_id: string;
sorting_weight: number;
domain: string;
id: string;
state: string;
Expand Down Expand Up @@ -38,6 +39,8 @@ interface entityConfig {
current_temperature?: number;
modes?: number[];
mode?: number;
presets?: number[];
preset?: number;
speed_count?: number;
speed_level?: number;
speed: string;
Expand Down Expand Up @@ -91,29 +94,37 @@ 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;
}
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 {
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;
Expand Down Expand Up @@ -214,7 +225,8 @@ export class EntityTable extends LitElement implements RestAction {
? this.control(component)
: html`<div>${component.state}</div>`}
</div>
${component.domain === "sensor"
${component.domain === "sensor" ||
component.domain === "climate"
? html`<esp-entity-chart
.chartdata="${component.value_numeric_history}"
></esp-entity-chart>`
Expand All @@ -235,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",
Expand Down Expand Up @@ -282,25 +297,71 @@ class ActionRenderer {
</button>`;
}

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`<button
class="abutton"
@click=${(e: Event) => {
e.stopPropagation();
this.actioner?.restAction(entity, upAction);
}}
>
🔺</button
><br />
<label>${targetTemp}</label><br />
<button
class="abutton"
@click=${(e: Event) => {
e.stopPropagation();
this.actioner?.restAction(entity, downAction);
}}
>
🔻
</button> `;
}

private _datetime(
entity: entityConfig,
type: string,
action: string,
opt: string,
value: string,
value: string
) {
return html`
<input
type="${type}"
<input
type="${type}"
name="${entity.unique_id}"
id="${entity.unique_id}"
.value="${value}"
@change="${(e: Event) => {
const val = (<HTMLTextAreaElement>e.target)?.value;
this.actioner?.restAction(
entity,
`${action}?${opt}=${val}`
);
this.actioner?.restAction(entity, `${action}?${opt}=${val}`);
}}"
/>
`;
Expand All @@ -325,7 +386,11 @@ class ActionRenderer {
val: string | number | undefined
) {
return html`<select
@click=${(e: Event) => {
e.stopPropagation();
}}
@change="${(e: Event) => {
e.stopPropagation();
const val = (<HTMLTextAreaElement>e.target)?.value;
this.actioner?.restAction(
entity,
Expand Down Expand Up @@ -353,7 +418,7 @@ class ActionRenderer {
max?: string | undefined,
step = 1
) {
if(entity.mode == 1) {
if (entity.mode == 1) {
return html`<div class="range">
<label>${min || 0}</label>
<input
Expand All @@ -370,22 +435,23 @@ class ActionRenderer {
}}"
/>
<label>${max || 100}</label>
</div>`;
</div>`;
} else {
return html`
<esp-range-slider
return html` <esp-range-slider
name="${entity.unique_id}"
step="${step}"
min="${min}"
max="${max}"
.value="${value}"
@state="${(e: CustomEvent) => {
const val = (<HTMLTextAreaElement>e.target)?.value;
this.actioner?.restAction(entity, `${action}?${opt}=${e.detail.state}`);
}}"
const val = (<HTMLTextAreaElement>e.target)?.value;
this.actioner?.restAction(
entity,
`${action}?${opt}=${e.detail.state}`
);
}}"
></esp-range-slider>`;
}

}

private _textinput(
Expand All @@ -405,7 +471,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 = (<HTMLTextAreaElement>e.target)?.value;
this.actioner?.restAction(
Expand Down Expand Up @@ -609,57 +675,50 @@ class ActionRenderer {
target_temp_label = html`${this.entity
.target_temperature_low}&nbsp;..&nbsp;${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:<br />
${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`
<label
>Current:&nbsp;${this.entity.current_temperature},
Target:&nbsp;${target_temp_label}</label
>
${target_temp_slider} ${modes}
<section class="climate">
<div>
${this._tempSelector(
this.entity,
this.entity.target_temperature_low ? "low" : ""
)}
</div>
<div>
<label><strong>${this.entity.current_temperature}</strong></label>
</div>
<div>
${this.entity.target_temperature_high
? this._tempSelector(this.entity, "high")
: ""}
</div>
<div>${modes}</div>
<div>${this.entity.state}</div>
<div>${presets}</div>
</section>
`;
}
}

0 comments on commit 811813c

Please sign in to comment.