Very nice work, I like your approach, and thanks for giving me inspiration.
I did a version of this to fits in my needs. One thing I don’t like about your solution is the need to pre-configure sensors before deploying it in the lovelace, my approach is a little different and more like the well known check button card which creates the sensor needed in the lovelace.
ui-lovelace.yaml
- !include
- ../templates/lovelace_gen/chore.yaml
- name: Limpeza Máq. Lavar loiça
sensor_name: chore_washdisher_cleaning
warning_before: 10
cycle_days: 90
lovelace_gen template
# lovelace_gen
{% set entity = 'sensor.'+sensor_name %}
type: 'custom:button-card'
name: {{name}}
entity: {{entity}}
label: >
[[[ return variables.var.label ]]]
show_label: true
icon: >
[[[ return variables.var.icon ]]]
custom_fields:
status: >
[[[ return '<span style="display: inline-block; color: white; background: '+variables.var.color+'; padding: 0 5px; border-radius: 5px;">'+variables.var.days_left+'</span>' ]]]
styles:
grid:
- grid-template-areas: '"i n status" "i l status"'
- grid-template-columns: 15% 1fr 1fr
- grid-template-rows: 1fr 1fr
icon:
- color: >
[[[ return variables.var.color ]]]
label:
- color: var(--disabled-text-color)
- justify-self: start
name:
- justify-self: start
variables:
var: >
[[[
let colors = {};
colors["success"] = "#8BC24A";
colors["warning"] = "#FFC107";
colors["error"] = "#FF5252";
colors["disabled"] = "var(--disabled-text-color)";
let result = {};
result.label = "Clique para criar";
result.color = colors["disabled"];
result.icon = "mdi:alert-plus";
result.days_left = "";
let timestamp;
let time;
let minutes;
let hours;
let days;
if (states['{{entity}}']) {
if (entity.state != 'unknown') {
timestamp = parseInt(entity.state);
time = (Date.now() / 1000) - timestamp;
minutes = Math.floor(((time % 3600) / 60));
hours = Math.floor(((time % 86400) / 3600));
days = Math.floor((time / 86400));
result.color = colors["success"];
result.icon = "mdi:checkbox-marked-circle-outline";
// LAST TRIGGER
if (time < 60)
result.label = 'menos de 1 minuto';
else if (days == 1)
result.label = '1 dia atrás';
else if (days > 1)
result.label = days+' dias atrás';
else if (hours >= 1)
result.label = hours+' horas atrás';
else if (hours < 1)
result.label = minutes+(minutes > 1 ? ' minutos atrás' : ' minuto atrás');
// DAYS LEFT
result.days_left = Math.round(((timestamp + ({{cycle_days|int}}*86400)) - (Date.now()/1000)) / 86400);
if (result.days_left <= {{warning_before|int}}) {
result.color = colors["warning"];
result.icon = "mdi:clock-alert";
}
if (result.days_left <= 0) {
result.color = colors["error"];
result.icon = "mdi:alert-circle"
}
result.days_left = result.days_left + (result.days_left == 1 ? " dia restante" : " dias restantes");
} else {
result.label = "Clique para publicar";
}
}
return result;
]]]
tap_action:
confirmation:
text: >
[[[
if (!states['{{entity}}'])
return 'A entidade com o nome {{entity}} vai ser criada'
else
return 'Tem a certeza que quer marcar a tarefa como concluída?'
]]]
action: call-service
service: mqtt.publish
service_data:
topic: >
[[[
if (!states['{{entity}}'])
return 'homeassistant/sensor/{{sensor_name}}/config'
else
return 'homeassistant/sensor/{{sensor_name}}/state'
]]]
payload: >
[[[
if (!states['{{entity}}'])
return '{ "name": "{{sensor_name}}", "state_topic": "homeassistant/sensor/{{sensor_name}}/state", "device_class": "timestamp" }'
else
return Date.now() / 1000
]]]
retain: true
