Skip to content

Commit ea83c9b

Browse files
committed
[TASK] rework
1 parent 170e57f commit ea83c9b

File tree

9 files changed

+211
-174
lines changed

9 files changed

+211
-174
lines changed

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[![Version - 0.6.0](https://img.shields.io/badge/Version-0.6.0-009688?style=for-the-badge)](https://github.com/KartoffelToby/better-thermostat-ui-card)
1+
[![Version - 0.7.0](https://img.shields.io/badge/Version-0.7.0-009688?style=for-the-badge)](https://github.com/KartoffelToby/better-thermostat-ui-card)
22
[![Discord](https://img.shields.io/discord/925725316540923914.svg?style=for-the-badge)](https://discord.gg/9BUegWTG3K)
33
[![hacs_badge](https://img.shields.io/badge/HACS-Default-41BDF5.svg?style=for-the-badge)](https://github.com/hacs/integration)
44

@@ -8,20 +8,21 @@ This project is in a early stage of development. Its a 1:1 adaption of the defau
88

99
As for now the main improvment is the ability to see the extra status from better_thermostat like if a window open is deteteced, or nightmode is on or summer mode.
1010

11-
<img style="width:200px; height:200px; object-fit:cover;" src="assets/1.png" width="200px"><img style="width:200px; height:200px; object-fit:cover;" src="assets/2.png" width="200px"><img style="width:200px; height:200px; object-fit:cover;" src="assets/3.png" width="200px"><img style="width:200px; height:200px; object-fit:cover;" src="assets/4.png" width="200px"><img style="width:200px; height:200px; object-fit:cover;" src="assets/5.png" width="200px">
11+
<img style="width:200px; height:200px; object-fit:cover;" src="assets/1.png" width="200px">
1212

1313
## Goals
1414

1515
- [X] Add better_thermostat support for showing the extra status
16-
- [ ] Improve the UI for Touch devices
17-
- [ ] Show also the Humidity in the UI
16+
- [X] Improve the UI for Touch devices
17+
- [X] Show also the Humidity in the UI
1818

1919
## Options
2020

2121
| Name | Type | Default | Description |
2222
| -------------------- | ------- | ------------ | ------------------------------------------------------------------------------------------------------ |
2323
| type | string | **Required** | `custom:better-thermostat-ui-card` |
2424
| entity | string | **Required** | The entity id of climate entity (must be a better_thermostat entity). Example: `climate.hvac` |
25+
| eco_temperature | number | **optional** | target temp for night/away/eco mode triggerd by ui button |
2526

2627

2728
## Help wanted!

assets/1.png

281 Bytes
Loading

dist/better-thermostat-ui-card.js

Lines changed: 81 additions & 68 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "better-thermostat-ui",
3-
"version": "0.6.0",
3+
"version": "0.7.0",
44
"description": "Lovelace better-thermostat-ui",
55
"keywords": [
66
"home-assistant",

src/better-thermostat-ui-card.ts

Lines changed: 76 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -117,19 +117,18 @@ export class BetterThermostatUiCard extends LitElement {
117117
}) public hass ? : HomeAssistant;
118118

119119

120-
@state() private _config ? : BetterThermostatUiCardConfig;
120+
@state() private _config ? : any;
121121
@state() private _setTemp ? : number | number[];
122122

123123
@query("ha-card") private _card ? : any;
124124

125125
public getCardSize(): number {
126126
return 7;
127127
}
128-
public setConfig(config: BetterThermostatUiCardConfig): void {
128+
public setConfig(config: any): void {
129129
if (!config.entity || config.entity.split(".")[0] !== "climate") {
130130
throw new Error("Specify an entity from within the climate domain");
131131
}
132-
133132
this._config = config;
134133
}
135134

@@ -157,7 +156,6 @@ export class BetterThermostatUiCard extends LitElement {
157156
stateObj.attributes.temperature :
158157
stateObj.attributes.min_temp;
159158

160-
161159
const slider =
162160
stateObj.state === UNAVAILABLE ?
163161
html ` <bt-round-slider disabled="true"></bt-round-slider> ` :
@@ -181,9 +179,9 @@ export class BetterThermostatUiCard extends LitElement {
181179
<text
182180
x="50%"
183181
dx="1"
184-
y="60%"
182+
y="50%"
185183
text-anchor="middle"
186-
style="font-size: 8px;"
184+
style="font-size: 10px;"
187185
>
188186
${
189187
stateObj.state === UNAVAILABLE
@@ -223,7 +221,7 @@ export class BetterThermostatUiCard extends LitElement {
223221
})}
224222
`
225223
}
226-
<tspan dx="-1" dy="-3.5" style="font-size: 3px;">
224+
<tspan dx="-1" dy="-5.5" style="font-size: 3px;">
227225
${this.hass.config.unit_system.temperature}
228226
</tspan>
229227
</text>
@@ -232,13 +230,6 @@ export class BetterThermostatUiCard extends LitElement {
232230

233231
const currentHumidity = svg `
234232
<div class="humindity">
235-
<ha-svg-icon
236-
class="info-icon"
237-
tabindex="0"
238-
.path=${modeIcons['humidity']}
239-
.title=${localize(`common.current`)}
240-
>
241-
</ha-svg-icon>
242233
<span>
243234
${svg`${this.formatNumber(
244235
stateObj.attributes.humidity,
@@ -251,13 +242,6 @@ export class BetterThermostatUiCard extends LitElement {
251242

252243
const currentTemperature = svg `
253244
<div class="temperature">
254-
<ha-svg-icon
255-
class="info-icon"
256-
tabindex="0"
257-
.path=${modeIcons['temperature']}
258-
.title=${localize(`common.current`)}
259-
>
260-
</ha-svg-icon>
261245
<span>
262246
${svg`${this.formatNumber(
263247
stateObj.attributes.current_temperature,
@@ -308,43 +292,42 @@ export class BetterThermostatUiCard extends LitElement {
308292
<div class="content">
309293
<div id="controls">
310294
<div id="slider" class="${stateObj.attributes.window_open ? 'window': ''}">
311-
<div id="title">${name}</div><div id="bt_status">
312-
${
313-
stateObj.attributes.window_open &&
314-
stateObj.attributes.window_open !== "none" &&
315-
stateObj.state !== UNAVAILABLE
316-
? this._renderStatusIcon("window_open"): this._renderOffStatusIcon("window_open")}
317-
${
318-
stateObj.attributes.saved_temperature &&
319-
stateObj.attributes.saved_temperature !== "none" &&
320-
stateObj.state !== UNAVAILABLE
321-
? this._renderStatusIcon("eco"): this._renderOffStatusIcon("eco")}
322-
${
323-
!stateObj.attributes.call_for_heat &&
324-
stateObj.attributes.call_for_heat !== "none" &&
325-
stateObj.state !== UNAVAILABLE
326-
? this._renderStatusIcon("summer"): this._renderOffStatusIcon("summer")}
327-
</div>
295+
<div id="title">${name}</div>
328296
${slider}
329297
<div id="slider-center">
298+
<div id="bt_status">
299+
${
300+
stateObj.attributes.window_open &&
301+
stateObj.attributes.window_open !== "none" &&
302+
stateObj.state !== UNAVAILABLE
303+
? this._renderStatusIcon("window_open", true): this._renderStatusIcon("window_open", false)}
304+
${
305+
!stateObj.attributes.call_for_heat &&
306+
stateObj.attributes.call_for_heat !== "none" &&
307+
stateObj.state !== UNAVAILABLE
308+
? this._renderStatusIcon("summer", true): this._renderStatusIcon("summer", false)}
309+
</div>
330310
<div id="temperature">${setValues}</div>
311+
<div id="current-infos">
312+
${currentTemperature}
313+
${
314+
stateObj.attributes.humidity !== null && stateObj.attributes.humidity > 0 ? currentHumidity : ""
315+
}
316+
</div>
331317
</div>
332318
</div>
333319
</div>
334320
<div id="info" .title=${name}>
335321
<div id="modes">
336-
${(stateObj.attributes.hvac_modes || [])
337-
.concat()
338-
.sort(this.compareClimateHvacModes)
339-
.map((modeItem) => this._renderIcon(modeItem, mode))}
322+
${this._renderIcon("heat", mode)}
323+
${
324+
stateObj.attributes.saved_temperature &&
325+
stateObj.attributes.saved_temperature !== "none" &&
326+
stateObj.state !== UNAVAILABLE
327+
? this._renderIcon("eco","eco"): this._renderIcon("eco", "none")}
328+
${this._renderIcon("off", mode)}
340329
</div>
341330
</div>
342-
<div id="current-infos">
343-
${currentTemperature}
344-
${
345-
stateObj.attributes.humidity !== null && stateObj.attributes.humidity > 0 ? currentHumidity : ""
346-
}
347-
</div>
348331
</div>
349332
</ha-card>
350333
`;
@@ -415,6 +398,8 @@ export class BetterThermostatUiCard extends LitElement {
415398
const card = this._card;
416399
if (card) {
417400
card.updateComplete.then(() => {
401+
const currentText:any = this.shadowRoot!.querySelector("#current-infos") !;
402+
currentText?.setAttribute("data-before", localize("common.current"));
418403
const svgRoot = this.shadowRoot!.querySelector("#set-values") !;
419404
const box = svgRoot.querySelector("g") !.getBBox() !;
420405
svgRoot.setAttribute(
@@ -503,13 +488,13 @@ export class BetterThermostatUiCard extends LitElement {
503488
return Object.keys(Object.fromEntries(filtered));
504489
}
505490

506-
private _renderStatusIcon(type:string): TemplateResult {
491+
private _renderStatusIcon(type:string, state:boolean): TemplateResult {
507492
if (!modeIcons[type]) {
508493
return html ``;
509494
}
510495
return html `
511496
<ha-svg-icon
512-
class="status-icon ${type}"
497+
class="${state ? 'status-icon' : 'status-icon-off'} ${type}"
513498
tabindex="0"
514499
.path=${modeIcons[type]}
515500
.title=${localize(`extra_states.${type}`)}
@@ -518,27 +503,13 @@ export class BetterThermostatUiCard extends LitElement {
518503
`;
519504
}
520505

521-
private _renderOffStatusIcon(type:string): TemplateResult {
522-
if (!modeIcons[type]) {
523-
return html ``;
524-
}
525-
return html `
526-
<ha-svg-icon
527-
class="status-icon-off ${type}"
528-
tabindex="0"
529-
.path=${modeIcons[type]}
530-
.title=${localize(`extra_states.${type}`)}
531-
>
532-
</ha-svg-icon>
533-
`;
534-
}
535-
536506
private _renderIcon(mode: string, currentMode: string): TemplateResult {
537507
if (!modeIcons[mode]) {
538508
return html ``;
539509
}
540510
return html `
541511
<ha-icon-button
512+
title="${currentMode === mode ? mode : ''}"
542513
class=${classMap({ "selected-icon": currentMode === mode })}
543514
.mode=${mode}
544515
@click=${this._handleAction}
@@ -557,10 +528,24 @@ export class BetterThermostatUiCard extends LitElement {
557528
}
558529

559530
private _handleAction(e: MouseEvent): void {
560-
this.hass!.callService("climate", "set_hvac_mode", {
531+
if ((e.currentTarget as any).mode === "eco") {
532+
const stateObj = this.hass!.states[this._config!.entity] as any;
533+
if (stateObj.attributes.saved_temperature === null) {
534+
this.hass!.callService("better_thermostat", "set_temp_target_temperature", {
535+
entity_id: this._config!.entity,
536+
temperature: this._config?.eco_temperature || 18,
537+
});
538+
} else {
539+
this.hass!.callService("better_thermostat", "restore_saved_target_temperature", {
540+
entity_id: this._config!.entity,
541+
});
542+
}
543+
} else {
544+
this.hass!.callService("climate", "set_hvac_mode", {
561545
entity_id: this._config!.entity,
562546
hvac_mode: (e.currentTarget as any).mode,
563-
});
547+
});
548+
}
564549
}
565550

566551
private hasConfigChanged(element: any, changedProps: PropertyValues): boolean {
@@ -765,11 +750,15 @@ export class BetterThermostatUiCard extends LitElement {
765750
justify-content: center;
766751
gap: 1.2em;
767752
min-height: 30px;
753+
padding-top: 2em;
754+
}
755+
ha-svg-icon {
756+
transition: color 1.6s ease-in-out;
768757
}
769758
ha-svg-icon.status-icon.window_open {
770759
color: #00bcd4 !important;
771760
}
772-
ha-svg-icon.status-icon.eco {
761+
ha-svg-icon.status-icon.eco, ha-icon-button[title="eco"] {
773762
color: #6cff71 !important;
774763
}
775764
ha-svg-icon.status-icon.summer {
@@ -865,22 +854,34 @@ export class BetterThermostatUiCard extends LitElement {
865854
height: 100%;
866855
width: 100%;
867856
transform: translate(-50%, -35%);
857+
display: flex;
858+
flex-flow: column;
868859
}
869860
#temperature {
870-
position: absolute;
871-
transform: translate(-50%, -50%);
872-
width: 100%;
873-
top: 50%;
874-
left: 50%;
861+
height: 5em;
862+
display: inline-flex;
875863
}
876864
#current-infos {
877865
display: flex;
878866
flex-flow: row;
879867
justify-content: center;
880868
gap: 1.2em;
881869
padding-bottom: 0.5em;
882-
padding-top: 0.3em
883-
font-size: 16px;
870+
padding-top: 0.7em;
871+
font-size: 18px !important;
872+
}
873+
#current-infos:before {
874+
content: attr(data-before);
875+
width: 65%;
876+
height: 2px;
877+
display: inline-block;
878+
position: absolute;
879+
z-index: 9999;
880+
top: 45%;
881+
color: rgba(158, 158, 158, 0.44);
882+
border-bottom: 1px solid rgba(158, 158, 158, 0.44);
883+
padding: 2em;
884+
font-size: 9px;
884885
}
885886
#set-values {
886887
}

src/const.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export const CARD_VERSION = '0.6.0';
1+
export const CARD_VERSION = '0.7.0';

src/editor.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ export class BetterThermostatUiCardEditor extends LitElement implements Lovelace
4949
return this._config?.entity || '';
5050
}
5151

52+
get _eco_temperature(): number {
53+
return this._config?.eco_temperature || 18;
54+
}
55+
5256
get _show_warning(): boolean {
5357
return this._config?.show_warning || false;
5458
}

0 commit comments

Comments
 (0)