Flow Details
Display Nordpool electricity prices on the Ulanzi Clock. The bottom of the display shows hourly prices for the whole day as colored pixels. Color values for the pixels and the current price can be mapped on the interface.
blueprint:
name: "AWTRIX Nordpool"
description: "Display Nordpool electricity prices on the Ulanzi Clock"
domain: automation
author: Kimmo
input:
awtrix:
name: AWTRIX Device
description: Select the Awtrix light device
selector:
device:
integration: mqtt
manufacturer: Blueforcer
model: AWTRIX Light
multiple: false
nordpool:
name: Nordpool sensor
description: "Select a nordpool sensor that provides hourly electricity prices."
selector:
entity:
filter:
- domain:
- sensor
multiple: false
hourly_attribute:
name: Hourly attribute
description: "Select an attribute in the above sensor containing the hourly prices in an array form."
selector:
text: {}
default: today
unit:
name: Unit
description: "Price unit to display."
selector:
text: {}
default: c/kWh
unit_multiplier:
name: Multiplier
description: "Multiplier to modify the raw price value. For example, use 100
if the raw price value is in Eur and you want to display it in cents.
Use 1 if you want the value to be unchanged."
selector:
number:
default: 100
color_matrix_json:
name: Color Map
description: "This will control how colors are mapped to a price range
on the display. The color mapping is in JSON format."
selector:
text:
multiline: true
default: "{\n \"0\": \"#00FF00\",\n \"20\": \"#FFFF00\",\n \"40\": \"#FF0000\"\n}"
message_duration:
name: Duration
description: How long should the message remain on the screen (in seconds). *If
you select `0` it will use the Global App Time*
selector:
number:
min: 0.0
max: 300.0
unit_of_measurement: sec
step: 1.0
mode: slider
default: 30
icon:
name: Icon
description: "Enter the Icon Name or ID of the icon that you like to show."
selector:
text: {}
default: 54077
mode: restart
variables:
device_id: !input awtrix
awtrix_light: "{{ iif( device_attr(device_id, 'name_by_user') != none, device_attr(device_id, 'name_by_user'), device_attr(device_id, 'name') ) }}"
nordpool: !input nordpool
hourly_attribute: !input hourly_attribute
unit: !input unit
unit_multiplier: !input unit_multiplier
color_matrix_json: !input color_matrix_json
message_duration: !input message_duration
icon: !input icon
nordpool_prices: '{{state_attr(nordpool,hourly_attribute)}}'
current_price: '{{states(nordpool) | float}}'
multiplied_price: '{{current_price | float * unit_multiplier }}'
price_text: '{{ multiplied_price | round(1) ~ unit}}'
color_dict: >-
{% set b = color_matrix_json | from_json %}
{%- set ns = namespace(tuples=[]) %}
{%- for k,v in b | items -%}
{%- set key = k|float -%}
{%- set ns.tuples = ns.tuples + [(key,v)] %}
{% endfor %}
{{ dict.from_keys(ns.tuples) }}
payload: |-
{%- macro interpolate(dictionary, x) -%}
{%- set x = x * unit_multiplier -%}
{%- set sorted_keys = dictionary|dictsort -%}
{%- set above = sorted_keys|selectattr('0', 'gt', x)|map(attribute='0')|list|first-%}
{%- set below = sorted_keys|selectattr('0', 'lt', x)|map(attribute='0')|list|last -%}
{#- Key matches x exactly -#}
{%- if above is defined and dictionary[above] == x -%}
{%- set value = dictionary[above] -%}
{{ value }}
{%- elif below is defined and dictionary[below] == x -%}
{%- set value = dictionary[below]-%}
{{ value }}
{#- Interpolation between two values -#}
{%- elif below is defined and above is defined -%}
{%- set lower_value = dictionary[below] -%}
{%- set upper_value = dictionary[above] -%}
{%- set lower_rgb = lower_value[1:] -%}
{%- set upper_rgb = upper_value[1:] -%}
{%- set lower_r = lower_rgb[0:2]|int(base=16) -%}
{%- set lower_g = lower_rgb[2:4]|int(base=16)-%}
{%- set lower_b = lower_rgb[4:6]|int(base=16) -%}
{%- set upper_r = upper_rgb[0:2]|int(base=16) -%}
{%- set upper_g = upper_rgb[2:4]|int(base=16)-%}
{%- set upper_b = upper_rgb[4:6]|int(base=16) -%}
{%- set interpolation_factor = (x - below) / (above - below) -%}
{%- set interpolated_r = ((1 - interpolation_factor) * lower_r + interpolation_factor * upper_r)|int -%}
{%- set interpolated_g = ((1 - interpolation_factor) * lower_g + interpolation_factor * upper_g)|int -%}
{%- set interpolated_b = ((1 - interpolation_factor) * lower_b + interpolation_factor * upper_b)|int -%}
{%- set interpolated_hex = '#' ~ '%02X' % interpolated_r ~ '%02X' % interpolated_g ~ '%02X' % interpolated_b -%}
{{ interpolated_hex }}
{#- Only below key available -#}
{%- elif below is defined -%}
{%- set value = dictionary[below] -%}
{{ value }}
{#- Only above key available -#}
{%- elif above is defined -%}
{%- set value = dictionary[above] -%}
{{ value }}
{#- No matching keys available -#}
{%- else -%}\
No matching key found.
{%- endif -%}
{%- endmacro -%}
{#- Define a macro to draw out the price lines#}
{%- macro draw_price_lines() %}
{%- for hour in range(24) %}
{"dp": [{{8+hour}},7,"{{interpolate(color_dict, nordpool_prices[hour]) }}"]}
{%- if hour+1 != 24 %},{%endif%}
{%- endfor %}
{%- endmacro %}
{"draw":[ {{draw_price_lines()}}
],
"icon": '{{icon}}',
"duration": '{{message_duration}}',
"text": '{{price_text}}',
"textCase": 2,
"color": '{{interpolate(color_dict, current_price | float)}}',
"lifetimeMode": 1
}
trigger:
- platform: state
entity_id: !input nordpool
id: Changes
enabled: true
condition: []
action:
- service: mqtt.publish
data:
qos: 0
retain: false
topic: "{{awtrix_light}}/custom/nordpool"
payload: '{{payload}}'
-- Flow first published on January 24, 2024, last updated on January 24, 2024 at 18:45.