Hello there,
So, recently the electricity rates changed in Spain and I had to reconfigure my sensors in order to keep track of consumption. To give a bit of context the new rates are as follows.
I got a couple of templatsensors to keep track of the current rate and prices, all based on binary_sensor.workday
.
- platform: workday
country: ES
workdays: [mon, tue, wed, thu, fri]
excludes: [sat, sun, holiday]
add_holidays:
- 'XXXX-XX-XX'
The first one checks the current rate to trigger an automation which changes the rate in the utility_meter
platform:
tramos_hora_pvpc:
friendly_name: "Tramos Horarios PVPC"
value_template: >-
{% set current_hour = strptime(states('sensor.time'), "%H:%M").hour %}
{% if current_hour < 8 and (states('binary_sensor.workday') == 'on') %}
Tarifa Valle
{% elif 8 <= current_hour < 10 and (states('binary_sensor.workday') == 'on') %}
Tarifa Plana
{% elif 10 <= current_hour < 14 and (states('binary_sensor.workday') == 'on') %}
Tarifa Punta
{% elif 14 <= current_hour < 18 and (states('binary_sensor.workday') == 'on') %}
Tarifa Plana
{% elif 18 <= current_hour < 22 and (states('binary_sensor.workday') == 'on') %}
Tarifa Punta
{% elif 22 <= current_hour < 0 and (states('binary_sensor.workday') == 'on') %}
Tarifa Plana
{% else %}
Tarifa Valle
{% endif %}
The second template sensor calculates the total electricity bill based on the utility_meter
data as follows:
coste_energia_hora:
friendly_name: "Coste Energia Hora Workday"
unit_of_measurement: '€'
icon_template: mdi:currency-eur
value_template: "{%- if states('sensor.pvpc') -%}
{%- if now().hour < 8 and (states('binary_sensor.workday') == 'on') -%}
{{ (( states('sensor.hourly_energy_valle') | float * 0.002215 + states('sensor.hourly_energy_valle') | float * states('sensor.pvpc') | float) * 1.21 ) | round(2) }}
{%- elif now().hour >= 8 and now().hour < 10 and (states('binary_sensor.workday') == 'on') -%}
{{ (( states('sensor.hourly_energy_plana') | float * 0.0602012 + states('sensor.hourly_energy_plana') | float * states('sensor.pvpc') | float) * 1.21 ) | round(2) }}
{%- elif now().hour >= 10 and now().hour < 14 and (states('binary_sensor.workday') == 'on') -%}
{{ (( states('sensor.hourly_energy_punta') | float * 0.0602012 + states('sensor.hourly_energy_punta') | float * states('sensor.pvpc') | float) * 1.21 ) | round(2) }}
{%- elif now().hour >= 14 and now().hour < 18 and (states('binary_sensor.workday') == 'on') -%}
{{ (( states('sensor.hourly_energy_plana') | float * 0.0602012 + states('sensor.hourly_energy_plana') | float * states('sensor.pvpc') | float) * 1.21 ) | round(2) }}
{%- elif now().hour >= 18 and now().hour < 22 and (states('binary_sensor.workday') == 'on') -%}
{{ (( states('sensor.hourly_energy_punta') | float * 0.0602012 + states('sensor.hourly_energy_punta') | float * states('sensor.pvpc') | float) * 1.21 ) | round(2) }}
{%- elif now().hour >=22 and (states('binary_sensor.workday') == 'on') -%}
{{ (( states('sensor.hourly_energy_plana') | float * 0.0602012 + states('sensor.hourly_energy_plana') | float * states('sensor.pvpc') | float) * 1.21 ) | round(2) }}
{%- else -%}
{{ (( states('sensor.hourly_energy_valle') | float * 0.002215 + states('sensor.hourly_energy_valle') | float * states('sensor.pvpc') | float) * 1.21 ) | round(2) }}
{%- endif -%}
{%- else -%}unknown
{%- endif -%}"
The issue here is that it seems that the (states('binary_sensor.workday') == 'on')
is not being evaluated and therefore it allways jumps to the {%- else -%}
block.
Any advice would be much appreciated.
Thanks
Troon
(Troon)
June 7, 2021, 10:16am
2
By default, the sensor is created as binary_sensor.workday_sensor
. Is that your issue?
Juve_A
June 7, 2021, 10:23am
3
Juve_A:
{% set current_hour = strptime(states('sensor.time'), "%H:%M").hour %}
{% if current_hour < 8 and (states('binary_sensor.workday') == 'on') %}
Tarifa Valle
{% elif 8 <= current_hour < 10 and (states('binary_sensor.workday') == 'on') %}
Tarifa Plana
{% elif 10 <= current_hour < 14 and (states('binary_sensor.workday') == 'on') %}
Tarifa Punta
{% elif 14 <= current_hour < 18 and (states('binary_sensor.workday') == 'on') %}
Tarifa Plana
{% elif 18 <= current_hour < 22 and (states('binary_sensor.workday') == 'on') %}
Tarifa Punta
{% elif 22 <= current_hour < 0 and (states('binary_sensor.workday') == 'on') %}
Tarifa Plana
{% else %}
Tarifa Valle
{% endif %}
This is as funny as embarrassing, didn’t read through all the documentation.
Cheers man!
123
(Taras)
June 7, 2021, 11:54am
4
If you’re interested, you can reduce this:
tramos_hora_pvpc:
friendly_name: "Tramos Horarios PVPC"
value_template: >-
{% set current_hour = strptime(states('sensor.time'), "%H:%M").hour %}
{% if current_hour < 8 and (states('binary_sensor.workday') == 'on') %}
Tarifa Valle
{% elif 8 <= current_hour < 10 and (states('binary_sensor.workday') == 'on') %}
Tarifa Plana
{% elif 10 <= current_hour < 14 and (states('binary_sensor.workday') == 'on') %}
Tarifa Punta
{% elif 14 <= current_hour < 18 and (states('binary_sensor.workday') == 'on') %}
Tarifa Plana
{% elif 18 <= current_hour < 22 and (states('binary_sensor.workday') == 'on') %}
Tarifa Punta
{% elif 22 <= current_hour < 0 and (states('binary_sensor.workday') == 'on') %}
Tarifa Plana
{% else %}
Tarifa Valle
{% endif %}
to this:
tramos_hora_pvpc:
friendly_name: "Tramos Horarios PVPC"
value_template: >-
{% set current_hour = now().hour %}
{% if states('binary_sensor.workday') == 'on' and 0 < current_hour <= 22 %}
{% if current_hour < 8 %} Tarifa Valle
{% elif 8 <= current_hour < 10 %} Tarifa Plana
{% elif 10 <= current_hour < 14 %} Tarifa Punta
{% elif 14 <= current_hour < 18 %} Tarifa Plana
{% elif 18 <= current_hour < 22 %} Tarifa Punta
{% else %} Tarifa Plana
{% endif %}
{% else %} Tarifa Valle
{% endif %}
Juve_A
June 7, 2021, 12:35pm
5
Thank you! Always interested in learning something new and make my config more readable.
Troon
(Troon)
June 7, 2021, 12:43pm
6
value_template: "Tarifa {{ {'v':'Valle','l':'Plana','u':'Punta'}['vvvvvvvvlluuuulllluuuull'[now().hour if states('binary_sensor.workday_sensor') == 'on' else 0]] }}"
Oh wait, you said more readable…
Juve_A
June 7, 2021, 12:47pm
7
Is that syntax correct? Thanks but I think I prefer it a bit more verbose…
1 Like
Troon
(Troon)
June 7, 2021, 12:50pm
8
Yes, it’s correct and works in the template editor. It gives a nice visualisation of the different tariff times in the 'vvvvvvvvlluuuulllluuuull'
string, but I agree it’s not that user-friendly. I’d use it in my config though .
EDIT: final answer — I challenge anyone to do it in fewer characters than this, without renaming the workday sensor:
value_template: "Tarifa {{'VPPalulanlnteaa'[(('0'*8+'11222211'*2)[now().hour*is_state('binary_sensor.workday_sensor','on')])|int::3]}}"
EDIT2: with 2022.7’s new bool
function, can save another two characters:
value_template: "Tarifa {{'VPPalulanlnteaa'[(('0'*8+'11222211'*2)[now().hour*states('binary_sensor.workday_sensor')|bool])|int::3]}}"
petro
(Petro)
June 8, 2021, 12:10pm
9
2 less
value_template: Tarifa {{'VPPalulanlnteaa'[(('0'*8+'11222211'*2)[now().hour*is_state('binary_sensor.workday_sensor','on')])|int::3]}}
Take advantage of the yaml string parsing
EDIT: It’s cheating though because I didn’t change the template. Either way, if a template starts with a string, you don’t need the quotes.
1 Like
Troon
(Troon)
June 8, 2021, 12:13pm
10
Oooh, bending rule 1 ! Presumably works because it’s not just a template?
petro
(Petro)
June 8, 2021, 12:14pm
11
Yeah, it’s bending rule 1 for sure. You don’t need quotes if your template starts with characters that make it a string.
petro
(Petro)
June 8, 2021, 12:18pm
12
I think it could be shortened by 1 char too if you use
states('binary_sensor.workday_sensor')=='on'
Outside that, I can’t see anything else. It’s a nice template. Definitely something i’d use if trying to save memory. We used to use stuff like this in our software from the 90’s when memory was tight.
1 Like
Troon
(Troon)
June 8, 2021, 12:22pm
13
I tried that. Needs an extra set of brackets to evaluate correctly, so ends up 1 char longer.
petro
(Petro)
June 8, 2021, 12:24pm
14
odd, I would think that == is resolved before the *, but maybe not