|
import { |
|
LitElement, |
|
html, |
|
css, |
|
} from "https://unpkg.com/[email protected]/lit-element.js?module"; // i dont like the idea that something is downloaded from somewhere |
|
|
|
class StopWatchCard extends LitElement { |
|
static get properties() { |
|
return { |
|
hass: {}, |
|
config: {}, |
|
elapsedTime: "", // TODO: is this really needed? probably not, formatting should happen on render level |
|
elapsed_timestamp: 0, |
|
}; |
|
} |
|
|
|
connectedCallback() { |
|
// no idea what this actually does, but copypasting from internet is the way to go |
|
super.connectedCallback(); |
|
|
|
console.log("this is now2"); |
|
|
|
this.interval = window.setInterval(() => { |
|
const entityId = this.config.entity_datetime; |
|
const state = this.hass.states[entityId]; |
|
const epoch = state.attributes.timestamp; |
|
if (epoch > 1) { |
|
const start = new Date(epoch * 1000); |
|
const now = new Date(); |
|
const difference = now - start; |
|
this.elapsed_timestamp = difference; |
|
const time_str = this.timeToString(difference); |
|
this.elapsedTime = time_str; |
|
} else { |
|
this.elapsedTime = "00:00:00"; |
|
} |
|
}, 100); |
|
} |
|
|
|
disconnectedCallback() { |
|
super.disconnectedCallback(); |
|
window.clearInterval(this.interval); |
|
} |
|
|
|
render() { |
|
return html` |
|
<ha-card> |
|
<div |
|
class="card-content" |
|
style="display: flex; justify-content: center;" |
|
> |
|
<div class="button-content" style="padding: 16px;"> |
|
<button |
|
@click="${(ev) => this.play()}" |
|
icon="mdi:play-circle-outline" |
|
> |
|
PLAY |
|
</button> |
|
<button |
|
@click="${(ev) => this.pause()}" |
|
icon="mdi:play-circle-outline" |
|
> |
|
PAUSE |
|
</button> |
|
<button |
|
@click="${(ev) => this.continue()}" |
|
icon="mdi:play-circle-outline" |
|
> |
|
CONTINUE |
|
</button> |
|
<button |
|
@click="${(ev) => this.reset()}" |
|
icon="mdi:play-circle-outline" |
|
> |
|
RESET |
|
</button> |
|
</div> |
|
<div |
|
class="time-content" |
|
style="font-size: 4rem; padding: 16px; text-align: center;" |
|
> |
|
${this.elapsedTime} |
|
</div> |
|
</div> |
|
</ha-card> |
|
`; |
|
} |
|
|
|
timeToString(time) { |
|
let diffInHrs = time / 3600000; |
|
let hh = Math.floor(diffInHrs); |
|
|
|
let diffInMin = (diffInHrs - hh) * 60; |
|
let mm = Math.floor(diffInMin); |
|
|
|
let diffInSec = (diffInMin - mm) * 60; |
|
let ss = Math.floor(diffInSec); |
|
|
|
let diffInMs = (diffInSec - ss) * 100; |
|
let ms = Math.floor(diffInMs); |
|
|
|
let formattedMM = mm.toString().padStart(2, "0"); |
|
let formattedSS = ss.toString().padStart(2, "0"); |
|
let formattedMS = ms.toString().padStart(2, "0"); |
|
|
|
return `${formattedMM}:${formattedSS}:${formattedMS}`; |
|
} |
|
|
|
play() { |
|
console.log("play"); |
|
const entityId = this.config.entity_datetime; |
|
const now = Date.now() / 1000; |
|
this.setStartTime(entityId, now); |
|
this.disconnectedCallback(); |
|
this.connectedCallback(); |
|
} |
|
|
|
reset() { |
|
console.log("reset"); |
|
const entityId = this.config.entity_datetime; |
|
this.setStartTime(entityId, 1); |
|
this.connectedCallback(); |
|
} |
|
|
|
pause() { |
|
console.log("pause"); |
|
const entityId = this.config.entity_number; |
|
const timeToSet = this.elapsed_timestamp; |
|
this.setSaveTime(entityId, timeToSet); |
|
this.disconnectedCallback(); |
|
} |
|
|
|
continue() { |
|
console.log("continue"); |
|
const { entity_number, entity_datetime } = this.config; |
|
const timeToContinueFrom = +this.hass.states[entity_number].state; |
|
console.log("time to continue from", timeToContinueFrom); |
|
const now = Date.now() / 1000; |
|
const timeToSet = parseInt(now - timeToContinueFrom / 1000); |
|
console.log("now", now); |
|
console.log("set", timeToSet); |
|
this.setStartTime(entity_datetime, timeToSet); |
|
this.connectedCallback(); |
|
} |
|
|
|
setConfig(config) { |
|
if (!config.entity_datetime) { |
|
throw new Error( |
|
"You need to define an input_datetime entity (entity_datetime)" |
|
); |
|
} |
|
if (!config.entity_number) { |
|
throw new Error( |
|
"You need to define an input_number entity (entity_number)" |
|
); |
|
} |
|
this.config = config; |
|
} |
|
|
|
getCardSize() { |
|
return 1; |
|
} |
|
|
|
setStartTime(entity, time) { |
|
console.log("setting time to", time); |
|
this.hass.callService("input_datetime", "set_datetime", { |
|
entity_id: entity, |
|
timestamp: time, |
|
}); |
|
} |
|
|
|
setSaveTime(entity, value) { |
|
console.log("setting number to", value); |
|
this.hass.callService("input_number", "set_value", { |
|
entity_id: entity, |
|
value: value, |
|
}); |
|
} |
|
|
|
// TODO: all styles should be here |
|
static get styles() { |
|
return css` |
|
ha-icon-button { |
|
width: 64px; |
|
height: 64px; |
|
cursor: pointer; |
|
--mdc-icon-size: 100%; |
|
} |
|
`; |
|
} |
|
} |
|
customElements.define("stop-watch", StopWatchCard); |
so time only passes when the sensor is visible, am i correct?