Skip to content

Commit

Permalink
Add timer support. Implement #192
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasloven committed Nov 11, 2023
1 parent 79341a6 commit 39a7b56
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ entities:
- `input_number` - set value (only if `mode: slider`)
- `input_select` - select option
- `number` - set value
- `timer` - set number of seconds remaining

If you want to control more than one entity with the same slider, use [light group](https://www.home-assistant.io/integrations/light.group/), [cover group](https://www.home-assistant.io/integrations/cover.group/) or a custom made [template entity](https://www.home-assistant.io/integrations/#search/template).

Expand Down
2 changes: 1 addition & 1 deletion src/controllers/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export abstract class Controller {
abstract _max?: number;
abstract _step?: number;

constructor(config: ControllerConfig) {
constructor(config: ControllerConfig, parent) {
this._config = config;
}

Expand Down
2 changes: 2 additions & 0 deletions src/controllers/get-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { InputSelectController } from "./input-select-controller";
import { NumberController } from "./number-controller";
import { WaterHeaterController } from "./water-heater-controller";
import { HumidifierController } from "./humidifier-controller";
import { TimerController } from "./timer-controller";

export function getController(domain: string) {
return {
Expand All @@ -21,5 +22,6 @@ export function getController(domain: string) {
input_select: InputSelectController,
number: NumberController,
humidifier: HumidifierController,
timer: TimerController,
}[domain];
}
79 changes: 79 additions & 0 deletions src/controllers/timer-controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { Controller } from "./controller";

export class TimerController extends Controller {
_calcvalue = 0;
_interval;

constructor(config, parent) {
super(config, parent);
this._calcvalue = 0;
this._interval = window.setInterval(() => {
this._calcvalue = this.calculate_value();
parent.requestUpdate();
}, 1000);
}

get _value() {
return this._calcvalue;
}

calculate_value() {
let timeRemaining = this.stateObj.attributes.remaining;
if (!timeRemaining) return 0;

const parts = timeRemaining.split(":").map(Number);
timeRemaining = parts[0] * 3600 + parts[1] * 60 + parts[2];

if (this.stateObj.state === "active") {
const now = new Date().getTime();
const madeActive = new Date(this.stateObj.last_changed).getTime();
timeRemaining = Math.max(timeRemaining - (now - madeActive) / 1000, 0);
}

return timeRemaining;
}

set _value(value) {
if (!value) {
this._hass.callService("timer", "finish", {
entity_id: this.stateObj.entity_id,
});
} else {
this._hass.callService("timer", "start", {
entity_id: this.stateObj.entity_id,
duration: value,
});
}
}

get string() {
if (this.stateObj.state === "active") {
const leftpad = (num) => (num < 10 ? `0${num}` : `${num}`);
const h = Math.floor(this.value / 3600);
const m = Math.floor((this.value % 3600) / 60);
const s = Math.floor(this.value % 60);
if (h > 0) {
return `${h}:${leftpad(m)}:${leftpad(s)}`;
}
if (m > 0) {
return `${m}:${leftpad(s)}`;
}
return `${s}`;
}
return this._hass.localize("component.timer.entity_component._.state.idle");
}

get isOff() {
return this.stateObj.state !== "active";
}

get _min() {
return 0;
}
get _max() {
return 300;
}
get _step() {
return 1;
}
}
2 changes: 1 addition & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class SliderEntityRow extends LitElement {
const domain = config.entity.split(".")[0];
const ctrlClass = getController(domain);
if (!ctrlClass) throw new Error(`Unsupported entity type: ${domain}`);
this.ctrl = new ctrlClass(config);
this.ctrl = new ctrlClass(config, this);
}

async resized() {
Expand Down
3 changes: 3 additions & 0 deletions test/views/1_types.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,6 @@ cards:
- type: custom:slider-entity-row
entity: humidifier.hygrostat
name: humidifier
- type: custom:slider-entity-row
entity: timer.timer
name: timer

0 comments on commit 39a7b56

Please sign in to comment.