Ok cool, I hear you, so lets see what we can do…
I’m going to assume your PV sensor is called sensor.pv_power
.
We’re going to create a template sensor which has the same value, but with an attribute for colour. The attribute will be a piece of text containing a CSS colour.
I’m going to use the new style template sensor format. I’m not testing any of this though, so keep that in mind.
Note that the macro in the template is like an (inline) function – mostly for readability. It’s the line before the endmacro
directive that “returns” the value – e.g. rgb(255, 0, 0)
which is red or #ff0000
. I’m renaming the references from my original post from temp
to value
to make it more generic.
This line is where we reference the sensor value from your PVs:
{%- set value = states('sensor.pv_power') | float(0) -%}
This is (one option for) a new map of colours:
{%- set value_map = {
50: "3498db",
125: "70a03c",
200: "ff9800",
275: "e74c3c"
} -%}
The keys are the watt values, so 50 will map to #3498db
. Values below that will be the same colour, because this is the lowest value. Between 50 and 125, the colour will be a gradient between #3498db
and #70a03c
. When you hit the highest value (275) or higher (300), the colour will be #e74c3c
.
Here is the full sensor definition:
- sensor:
- name: PV With Color
state: "{{ states('sensor.pv_power') }}"
attributes:
color: >-
{%- macro interpolate(value, start, stop) -%}
{%- set (start_value, start_color) = start -%}
{%- set (stop_value, stop_color) = stop -%}
{%- set (start_r, start_g, start_b) = (int(start_color[0:2], base=16), int(start_color[2:4], base=16), int(start_color[4:6], base=16)) -%}
{%- set (stop_r, stop_g, stop_b) = (int(stop_color[0:2], base=16), int(stop_color[2:4], base=16), int(stop_color[4:6], base=16)) -%}
{%- set s = ((value - start_value)/(stop_value - start_value)) -%}
{# some channels might be negative; most browsers are probably tolerant, but in case not #}
{%- set r = max(int(start_r + s*(stop_r - start_r)), 0) -%}
{%- set g = max(int(start_g + s*(stop_g - start_g)), 0) -%}
{%- set b = max(int(start_b + s*(stop_b - start_b)), 0) -%}
rgb({{ r }}, {{ g }}, {{ b }});
{%- endmacro -%}
{%- set value = states('sensor.pv_power') | float(0) -%}
{%- set value_map = {
50: "3498db",
125: "70a03c",
200: "ff9800",
275: "e74c3c"
} -%}
{%- set keys = value_map | sort -%}
{%- set index = keys | select("lt", value) | list | length -%}
{%- if index == 0 -%}
#{{ value_map[keys | first] }}
{%- elif index == keys | length -%}
#{{ value_map[keys | last] }}
{%- else -%}
{%- set start = (keys[index - 1], value_map[keys[index - 1]]) -%}
{%- set stop = (keys[index], value_map[keys[index]]) -%}
{{ interpolate(value, start, stop) }}
{%- endif -%}
Next, if you tell me which card you’re going to use to visualise this, we can look at how to apply that colour, but that might be a topic for a card-mod thread. Either way, you should see the new sensor with it’s attribute in your dev tools or by using a template such as {{ state_attr('sensor.pv_with_color', 'color') }}
.