For anyone interested, I have created a template for my pool pump smart switch and timer.
I use an input_boolean to control the timer duration and input_datetime functions to control start and end times (shown bottom right, converted to template sensors to remove seconds for ease of reading in button) based on my solar production and sunset. The timer button essentially overrides any functions to turn on and off the pump.
Here is the code for the template, its rough and probably a long way to achieve this goal, so if anyone wants to clean it up please go ahead
Template:
card_pool:
# templates:
# - "ulm_language_variables"
variables:
ulm_card_input_number_name: "n/a"
ulm_card_switch_name: "n/a"
timer_entity: "n/a"
start_entity: "n/a"
finish_entity: "n/a"
triggers_update: "all"
show_icon: false
show_name: false
show_label: false
styles:
grid:
- grid-template-areas: '"item1" "item2" "item3"'
- grid-template-columns: "1fr"
- grid-template-rows: "min-content min-content min-content"
- row-gap: "12px"
card:
- border-radius: "var(--border-radius)"
- box-shadow: "var(--box-shadow)"
- padding: "12px"
- background-color: >
[[[
if(hass.themes.darkMode)
if( entity.state === 'on' ){
return 'rgba(var(--color-blue),0.1)'
}
]]]
custom_fields:
item1:
card:
type: "custom:button-card"
template:
- "icon_info"
- "ulm_language_variables"
- "pool"
tap_action:
action: "toggle"
entity: "[[[ return entity.entity_id ]]]"
name: "[[[ return variables.ulm_card_switch_name ]]]"
styles:
card:
- background-color: "rgba(0,0,0,0)"
# icon:
# - color: >
# [[[
# if( entity.state === 'on' ){
# return 'rgba(var(--color-blue),1)'
# }
# ]]]
# img_cell:
# - background-color: >
# [[[
# if( entity.state === 'on' ){
# return 'rgba(var(--color-blue),0.2)'
# } else {
# return 'rgba(var(--color-theme),0.05)'
# }
# ]]]
# label:
# - color: "rgba(var(--color-blue-text),1)"
# name:
# - color: "rgba(var(--color-blue-text),1)"
item2:
card:
type: "custom:button-card"
template: "list_3_items"
styles:
card:
- background-color: "rgba(0,0,0,0)"
custom_fields:
item1:
card:
type: "custom:button-card"
template: "widget_icon"
tap_action:
action: "call-service"
service: "input_number.decrement"
service_data:
entity_id: "[[[ return variables.ulm_card_input_number_entity ]]]"
icon: "mdi:arrow-down"
item2:
card:
type: "custom:button-card"
template: "widget_text"
entity: "[[[ return variables.ulm_card_input_number_entity ]]]"
tap_action:
action: "call-service"
service: "cover.stop_cover"
service_data:
entity_id: "[[[ return variables.ulm_card_input_number_entity ]]]"
item3:
card:
type: "custom:button-card"
template: "widget_icon"
tap_action:
action: "call-service"
service: "input_number.increment"
service_data:
entity_id: "[[[ return variables.ulm_card_input_number_entity ]]]"
icon: "mdi:arrow-up"
item3:
card:
type: "custom:button-card"
template: "list_two_third_items"
styles:
card:
- background-color: "rgba(0,0,0,0)"
custom_fields:
item1:
card:
type: "custom:button-card"
template: "widget_icon"
tap_action:
action: "toggle"
haptic: "success"
entity: "[[[ return variables.timer_entity ]]]"
icon: "mdi:timer-off-outline"
state:
- value: "on"
styles:
icon:
- color: "rgba(var(--color-red),1)"
- value: "off"
styles:
icon:
- color: "rgba(var(--color-theme),0.2)"
item2:
card:
type: "custom:button-card"
template: "widget_text_only_combined"
variables:
start_entity_x: "[[[ return variables.start_entity ]]]"
finish_entity_x: "[[[ return variables.finish_entity ]]]"
entity: "[[[ return variables.start_entity ]]]"
tap_action:
action: "none"
pool:
label: >-
[[[
if (entity.state == 'on') {
return variables.ulm_on;
} else if (entity.state == 'off') {
return variables.ulm_off;
} else if (entity.state == 'unavailable') {
return variables.ulm_unavailable;
} else {
return entity.state;
}
]]]
state:
- value: "on"
styles:
icon:
- color: "rgba(var(--color-blue),1)"
img_cell:
- background-color: "rgba(var(--color-blue),0.2)"
label:
- color: "rgba(var(--color-blue-text),1)"
name:
- color: "rgba(var(--color-blue-text),1)"
- value: "off"
styles:
icon:
- color: "rgba(var(--color-theme),0.2)"
input_number:
tap_action:
action: "more-info"
show_last_changed: true
widget_text:
tap_action:
action: "toggle"
show_icon: false
show_label: true
show_name: false
label: >-
[[[
var unit = entity.attributes.unit_of_measurement != null ? ' ' + entity.attributes.unit_of_measurement : ''
if (entity.state == 'on') {
return variables.ulm_on;
} else if (entity.state == 'off') {
return variables.ulm_off;
} else if (entity.state == 'unavailable') {
return variables.ulm_unavailable;
} else if (entity.state == 'idle') {
return variables.ulm_idle;
} else if (entity.state == 'open') {
return variables.ulm_open;
} else if (entity.state == 'closed') {
return variables.ulm_closed;
} else {
return entity.state + unit;
}
]]]
styles:
grid:
- grid-template-areas: "'l'"
card:
- box-shadow: "none"
- padding: "0px"
- background-color: "rgba(var(--color-theme),0.05)"
- border-radius: "14px"
- place-self: "center"
- height: "42px"
# state:
# - color: "rgba(var(--color-theme),0.9)"
size: "20px"
# color: "var(--google-grey)"
widget_text_icon:
tap_action:
action: "toggle"
show_icon: true
show_label: true
show_name: false
label: >-
[[[
var unit = entity.attributes.unit_of_measurement != null ? ' ' + entity.attributes.unit_of_measurement : ''
if (entity.state == 'on') {
return variables.ulm_on;
} else if (entity.state == 'off') {
return variables.ulm_off;
} else if (entity.state == 'unavailable') {
return variables.ulm_unavailable;
} else if (entity.state == 'idle') {
return variables.ulm_idle;
} else if (entity.state == 'open') {
return variables.ulm_open;
} else if (entity.state == 'closed') {
return variables.ulm_closed;
} else {
return entity.state + unit;
}
]]]
styles:
grid:
- grid-template-areas: "'l'"
card:
- box-shadow: "none"
- padding: "0px"
- background-color: "rgba(var(--color-theme),0.05)"
- border-radius: "14px"
- place-self: "center"
- height: "42px"
label:
- font-size: "12px"
# state:
# - color: "rgba(var(--color-theme),0.9)"
size: "20px"
# color: "var(--google-grey)"
widget_text_only:
show_icon: false
show_label: true
show_name: false
label: "[[[ return entity.state ]]]"
styles:
grid:
- grid-template-areas: "'l'"
card:
- box-shadow: "none"
- padding: "0px"
- background-color: "rgba(var(--color-theme),0.05)"
- border-radius: "14px"
- place-self: "center"
- height: "42px"
label:
- font-size: "8px"
# state:
# - color: "rgba(var(--color-theme),0.9)"
size: "20px"
# color: "var(--google-grey)"
widget_text_only_combined:
variables:
start_entity_x: ""
finish_entity_x: ""
show_icon: false
show_label: true
show_name: false
label: |
[[[
var state1 = "";
if (states[variables.start_entity_x].state){
var state1 = states[variables.start_entity_x].state;
}
var state2 = "";
if (states[variables.finish_entity_x].state){
var state2 = states[variables.finish_entity_x].state;
}
return state1 + " → " + state2;
]]]
styles:
grid:
- grid-template-areas: "'l'"
card:
- box-shadow: "none"
- padding: "0px"
- background-color: "rgba(var(--color-theme),0.05)"
- border-radius: "14px"
- place-self: "center"
- height: "42px"
label:
- font-size: "14px"
# state:
# - color: "rgba(var(--color-theme),0.9)"
size: "20px"
# color: "var(--google-grey)"
Button code:
- type: 'custom:button-card'
entity: "switch.pool_pump"
template:
- "card_pool"
variables:
ulm_card_input_number_name: "Duration"
ulm_card_input_number_entity: "input_number.pool_pump_duration"
ulm_card_switch_name: "Pool"
start_entity: "sensor.pool_pump_start"
finish_entity: "sensor.pool_pump_finish"
timer_entity: "input_boolean.pool_pump_override"