v1.5.1
For each HA-enabled zone in each enabled program, three new CONFIG-category entities have been added:
select.__duration_type — choose between suggested, custom, and not set. Options are translated into 5 languages via the native HA translation system. Selecting an option sets the active and duration fields on the device: not set disables the zone in the program, suggested zeros the duration letting WaterSense calculate it, custom restores the duration configured in the number entity.
number.__custom_duration — custom duration in minutes (0.5–299.5, step 0.5, box input). The value is independent of the current mode: it is not overwritten when the device is in suggested or not set, thanks to RestoreEntity which persists it across HA restarts.
number.__watering_percentage — WaterSense percentage (10–200%, step 5%). Directly writes userPercentage to the device.
Example (you can now click for editing):
Card code, only change language string
type: custom:html-template-card
ignore_line_breaks: true
content: >
{% set program = 'estate' %}{# Change to your program name #}
{% set lang = 'it' %}{# Available languages: it, en, de, fr, es #}
{% if lang == 'it' %}
{% set day_names = ['Lun','Mar','Mer','Gio','Ven','Sab','Dom'] %}
{% set active_label = 'Attivo' %}{% set inactive_label = 'Inattivo' %}{% set start_label = 'Inizio' %}{% set every_label = 'ogni' %}{% set days_label = 'giorni' %}{% set next_run_label = 'Prossimo avvio' %}{% set today_label = 'oggi' %}{% set tomorrow_label = 'domani' %}
{% set zone_label = 'Zona' %}{% set duration_label = 'Durata' %}{% set type_label = 'Tipo' %}{% set total_label = 'Totale' %}
{% set freq_daily = 'Ogni giorno' %}{% set freq_every_n = 'Ogni N giorni' %}{% set freq_odd = 'Giorni dispari' %}{% set freq_even = 'Giorni pari' %}{% set freq_selected = 'Giorni selezionati' %}
{% set type_map = {'suggested':'Suggerita','custom':'Personalizzata','not_set':'Non impostata'} %}
{% elif lang == 'de' %}
{% set day_names = ['Mo','Di','Mi','Do','Fr','Sa','So'] %}
{% set active_label = 'Aktiv' %}{% set inactive_label = 'Inaktiv' %}{% set start_label = 'Start' %}{% set every_label = 'alle' %}{% set days_label = 'Tage' %}{% set next_run_label = 'Nächster Start' %}{% set today_label = 'heute' %}{% set tomorrow_label = 'morgen' %}
{% set zone_label = 'Zone' %}{% set duration_label = 'Dauer' %}{% set type_label = 'Typ' %}{% set total_label = 'Gesamt' %}
{% set freq_daily = 'Täglich' %}{% set freq_every_n = 'Alle N Tage' %}{% set freq_odd = 'Ungerade Tage' %}{% set freq_even = 'Gerade Tage' %}{% set freq_selected = 'Ausgewählte Tage' %}
{% set type_map = {'suggested':'Vorgeschlagen','custom':'Benutzerdefiniert','not_set':'Nicht gesetzt'} %}
{% elif lang == 'fr' %}
{% set day_names = ['Lun','Mar','Mer','Jeu','Ven','Sam','Dim'] %}
{% set active_label = 'Actif' %}{% set inactive_label = 'Inactif' %}{% set start_label = 'Début' %}{% set every_label = 'tous les' %}{% set days_label = 'jours' %}{% set next_run_label = 'Prochain démarrage' %}{% set today_label = "aujourd'hui" %}{% set tomorrow_label = 'demain' %}
{% set zone_label = 'Zone' %}{% set duration_label = 'Durée' %}{% set type_label = 'Type' %}{% set total_label = 'Total' %}
{% set freq_daily = 'Quotidien' %}{% set freq_every_n = 'Tous les N jours' %}{% set freq_odd = 'Jours impairs' %}{% set freq_even = 'Jours pairs' %}{% set freq_selected = 'Jours sélectionnés' %}
{% set type_map = {'suggested':'Suggérée','custom':'Personnalisée','not_set':'Non définie'} %}
{% elif lang == 'es' %}
{% set day_names = ['Lun','Mar','Mié','Jue','Vie','Sáb','Dom'] %}
{% set active_label = 'Activo' %}{% set inactive_label = 'Inactivo' %}{% set start_label = 'Inicio' %}{% set every_label = 'cada' %}{% set days_label = 'días' %}{% set next_run_label = 'Próximo inicio' %}{% set today_label = 'hoy' %}{% set tomorrow_label = 'mañana' %}
{% set zone_label = 'Zona' %}{% set duration_label = 'Duración' %}{% set type_label = 'Tipo' %}{% set total_label = 'Total' %}
{% set freq_daily = 'Diario' %}{% set freq_every_n = 'Cada N días' %}{% set freq_odd = 'Días impares' %}{% set freq_even = 'Días pares' %}{% set freq_selected = 'Días seleccionados' %}
{% set type_map = {'suggested':'Sugerida','custom':'Personalizada','not_set':'No establecida'} %}
{% else %}
{% set day_names = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun'] %}
{% set active_label = 'Active' %}{% set inactive_label = 'Inactive' %}{% set start_label = 'Start' %}{% set every_label = 'every' %}{% set days_label = 'days' %}{% set next_run_label = 'Next run' %}{% set today_label = 'today' %}{% set tomorrow_label = 'tomorrow' %}
{% set zone_label = 'Zone' %}{% set duration_label = 'Duration' %}{% set type_label = 'Type' %}{% set total_label = 'Total' %}
{% set freq_daily = 'Daily' %}{% set freq_every_n = 'Every N days' %}{% set freq_odd = 'Odd days' %}{% set freq_even = 'Even days' %}{% set freq_selected = 'Selected days' %}
{% set type_map = {'suggested':'Suggested','custom':'Custom','not_set':'Not set'} %}
{% endif %}
{% set freq_map = {'daily':freq_daily,'every_n_days':freq_every_n,'odd_days':freq_odd,'even_days':freq_even,'selected_days':freq_selected} %}
{% set switch_entity = 'switch.rainmachine_' ~ program %}
{% set frequency_select = 'select.rainmachine_' ~ program ~ '_frequency' %}
{% set start_time_entity = 'time.rainmachine_' ~ program ~ '_start_time' %}
{% set frequency_interval = 'number.rainmachine_' ~ program ~ '_frequency_interval' %}
{% set decrease_button = 'button.rainmachine_' ~ program ~ '_decrease_duration' %}
{% set increase_button = 'button.rainmachine_' ~ program ~ '_increase_duration' %}
{% set frequency_mon = 'switch.rainmachine_' ~ program ~ '_frequency_mon' %}
{% set frequency_tue = 'switch.rainmachine_' ~ program ~ '_frequency_tue' %}
{% set frequency_wed = 'switch.rainmachine_' ~ program ~ '_frequency_wed' %}
{% set frequency_thu = 'switch.rainmachine_' ~ program ~ '_frequency_thu' %}
{% set frequency_fri = 'switch.rainmachine_' ~ program ~ '_frequency_fri' %}
{% set frequency_sat = 'switch.rainmachine_' ~ program ~ '_frequency_sat' %}
{% set frequency_sun = 'switch.rainmachine_' ~ program ~ '_frequency_sun' %}
{% set weather_adaptive = 'switch.rainmachine_' ~ program ~ '_weather_adaptive_watering' %}
{% set adaptive_freq = 'switch.rainmachine_' ~ program ~ '_use_adaptive_frequency' %}
{% macro fmt_dur(sec) %}{% set s = sec | int %}{% if s >= 3600 %}{{ s // 3600 }}h {{ (s % 3600) // 60 }}min {{ s % 60 }}s{% else %}{{ s // 60 }}min {{ s % 60 }}s{% endif %}{% endmacro %}
{% set skip = ['enabled','start_time','frequency','total_duration','device_class','icon','friendly_name','last_run','next_run','last_run_start','last_run_end'] %}
{% set attrs = states[switch_entity].attributes %}
{% set enabled = attrs.get('enabled') %}
{% set freq_raw = states(frequency_select) %}
{% set freq_label = freq_map.get(freq_raw, freq_raw) %}
{% set days = [(day_names[0],frequency_mon),(day_names[1],frequency_tue),(day_names[2],frequency_wed),(day_names[3],frequency_thu),(day_names[4],frequency_fri),(day_names[5],frequency_sat),(day_names[6],frequency_sun)] %}
{% set next_run_str = attrs.get('next_run') %}
<div>
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:6px">
<div style="display:flex;align-items:center;gap:6px">
<span style="font-weight:bold;font-size:1em">{{ attrs.friendly_name | replace('RainMachine ', '') }}</span>
<button onclick="document.querySelector('home-assistant').hass.callService('button','press',{entity_id:'{{ decrease_button }}'})"
style="width:22px;height:22px;background:var(--secondary-background-color);border:none;border-radius:6px;font-size:0.95em;cursor:pointer;color:var(--primary-text-color);display:flex;align-items:center;justify-content:center;padding:0">−</button>
<button onclick="document.querySelector('home-assistant').hass.callService('button','press',{entity_id:'{{ increase_button }}'})"
style="width:22px;height:22px;background:var(--secondary-background-color);border:none;border-radius:6px;font-size:0.95em;cursor:pointer;color:var(--primary-text-color);display:flex;align-items:center;justify-content:center;padding:0">+</button>
</div>
{% if enabled == true or enabled == 'on' %}
<span style="color:#4CAF50;font-size:0.85em">● {{ active_label }}</span>
{% else %}
<span style="color:grey;font-size:0.85em">● {{ inactive_label }}</span>
{% endif %}
</div>
<div style="color:grey;font-size:0.85em;margin-bottom:8px">
<div style="display:flex;align-items:center;gap:4px;flex-wrap:wrap">
{{ start_label }}:
<span onclick="var e=new Event('hass-more-info',{bubbles:true,composed:true});e.detail={entityId:'{{ start_time_entity }}'};this.dispatchEvent(e)" style="cursor:pointer;text-decoration:underline dotted">{{ states(start_time_entity)[:-3] }}</span>
·
<span onclick="var e=new Event('hass-more-info',{bubbles:true,composed:true});e.detail={entityId:'{{ frequency_select }}'};this.dispatchEvent(e)" style="cursor:pointer;text-decoration:underline dotted">{{ freq_label }}</span>
{% if freq_raw == 'every_n_days' %}
· {{ every_label }}
<span onclick="var e=new Event('hass-more-info',{bubbles:true,composed:true});e.detail={entityId:'{{ frequency_interval }}'};this.dispatchEvent(e)" style="cursor:pointer;text-decoration:underline dotted">{{ states(frequency_interval) | int }}</span>
{{ days_label }}
{% endif %}
{% if next_run_str %}
{% set next_dt = as_datetime(next_run_str) %}
{% set delta = (next_dt.date() - now().date()).days %}
{% set t = next_dt.strftime('%H:%M') %}
· {{ next_run_label }}:
{% if delta == 0 %}{{ today_label }} {{ t }}
{% elif delta == 1 %}{{ tomorrow_label }} {{ t }}
{% elif delta <= 6 %}{{ day_names[next_dt.weekday()] }} {{ t }}
{% else %}{{ next_dt.strftime('%d/%m') }} {{ t }}
{% endif %}
{% endif %}
</div>
{% if freq_raw == 'selected_days' %}
<div style="display:flex;gap:4px;margin-top:6px">
{% for label, entity in days %}
{% set active = states(entity) == 'on' %}
<button onclick="document.querySelector('home-assistant').hass.callService('switch','toggle',{entity_id:'{{ entity }}'})" style="flex:1;padding:3px 0;border:none;border-radius:4px;cursor:pointer;font-size:0.78em;background:{{ '#4CAF50' if active else 'var(--secondary-background-color)' }};color:{{ 'white' if active else 'grey' }}">{{ label }}</button>
{% endfor %}
</div>
{% endif %}
</div>
<table style="width:100%;border-collapse:collapse;font-size:0.85em;table-layout:fixed">
<colgroup>
<col style="width:38%">
<col style="width:22%">
<col style="width:15%">
<col style="width:25%">
</colgroup>
<tr style="color:grey;border-bottom:1px solid var(--divider-color)">
<th style="text-align:left;padding:3px 6px">{{ zone_label }}</th>
<th style="text-align:right;padding:3px 6px">{{ duration_label }}</th>
<th style="text-align:right;padding:3px 6px">%</th>
<th style="text-align:right;padding:3px 6px">{{ type_label }}</th>
</tr>
{% for key, val in attrs.items() %}
{% if key not in skip and not key.endswith('_type') and (val is number or val is none) %}
{% set zone_slug = key | lower | replace(' ', '_') %}
{% set type_select = 'select.rainmachine_' ~ program ~ '_' ~ zone_slug ~ '_duration_type' %}
{% set type_raw = states(type_select) %}
{% set custom_dur_entity = 'number.rainmachine_' ~ program ~ '_' ~ zone_slug ~ '_custom_duration' %}
{% set pct_entity = 'number.rainmachine_' ~ program ~ '_' ~ zone_slug ~ '_watering_percentage' %}
<tr style="border-bottom:1px solid var(--divider-color)">
<td style="padding:4px 6px">{{ key }}</td>
<td style="padding:4px 6px;text-align:right">
{% if type_raw == 'custom' %}
<span onclick="var e=new Event('hass-more-info',{bubbles:true,composed:true});e.detail={entityId:'{{ custom_dur_entity }}'};this.dispatchEvent(e)"
style="cursor:pointer;text-decoration:underline dotted">{{ fmt_dur(val) if val is number else '—' }}</span>
{% else %}
{{ fmt_dur(val) if val is number else '—' }}
{% endif %}
</td>
<td style="padding:4px 6px;text-align:right">
{% if type_raw == 'suggested' %}
<span onclick="var e=new Event('hass-more-info',{bubbles:true,composed:true});e.detail={entityId:'{{ pct_entity }}'};this.dispatchEvent(e)"
style="cursor:pointer;text-decoration:underline dotted">{{ states(pct_entity) | int }}%</span>
{% endif %}
</td>
<td style="padding:4px 6px;text-align:right;color:grey;font-style:italic">
<span onclick="var e=new Event('hass-more-info',{bubbles:true,composed:true});e.detail={entityId:'{{ type_select }}'};this.dispatchEvent(e)"
style="cursor:pointer;text-decoration:underline dotted">{{ type_map.get(type_raw, type_raw) }}</span>
</td>
</tr>
{% endif %}
{% endfor %}
<tr>
<td style="text-align:right;padding:4px 6px;color:grey;font-size:0.85em">{{ total_label }}</td>
<td style="text-align:right;padding:4px 6px;font-weight:bold">{{ fmt_dur(attrs.total_duration) }}</td>
<td colspan="2"></td>
</tr>
</table>
<div style="display:flex;gap:8px;margin-top:12px">
{% set wa_on = states(weather_adaptive) == 'on' %}
{% set af_on = states(adaptive_freq) == 'on' %}
<button onclick="document.querySelector('home-assistant').hass.callService('switch','toggle',{entity_id:'{{ weather_adaptive }}'})"
style="flex:1;height:32px;background:{{ '#4CAF50' if wa_on else 'var(--secondary-background-color)' }};border:none;border-radius:8px;font-size:0.75em;cursor:pointer;color:{{ 'white' if wa_on else 'grey' }};padding:0 4px">
{{ state_attr(weather_adaptive, 'friendly_name') | replace('RainMachine ', '') }}
</button>
<button onclick="document.querySelector('home-assistant').hass.callService('switch','toggle',{entity_id:'{{ adaptive_freq }}'})"
style="flex:1;height:32px;background:{{ '#4CAF50' if af_on else 'var(--secondary-background-color)' }};border:none;border-radius:8px;font-size:0.75em;cursor:pointer;color:{{ 'white' if af_on else 'grey' }};padding:0 4px">
{{ state_attr(adaptive_freq, 'friendly_name') | replace('RainMachine ', '') }}
</button>
</div>
</div>