There is a set of sensors:
- sensor.test_1
- sensor.test_2
- sensor.test_3
Each sensor has a set of attributes like:
- name: sensor.test_1:
state: ...
attributes:
attr_1: ...
attr_2: ...
attr_3: ...
Now I need to have some composite “sensor.composite_123”:
- name: sensor.composite_123:
state: ...
attributes:
comp_attr_1: ...
comp_attr_2: ...
whose state & attributes depend on states & attributes of those 3 sensors.
Assume that here is an algorithm of calculating the composite state & composite attributes:
step 1 - some calculation
comp_attr_1: ...
step 2 - some calculation
state: ...
step 3 - some calculation
comp_attr_2: ...
Here is how I can split this algorithm when defining a template sensor:
- name: sensor.composite_123:
state: >-
step 1 - some calculation
comp_attr_1: ...
step 2 - some calculation
{{ return result for the state }}
attributes:
comp_attr_1: >-
step 1 - some calculation
comp_attr_1: ...
{{ return result for the comp_attr_1 }}
comp_attr_2: >-
step 1 - some calculation
comp_attr_1: ...
step 2 - some calculation
state: ...
step 3 - some calculation
comp_attr_2: ...
{{ return result for the comp_attr_2 }}
It seems cumbersome since there is a repeating code.
Tried another option - keeping results of the whole algorithm in some namespace:
- name: sensor.composite_123:
state: >-
step 1 - some calculation
comp_attr_1: ...
step 2 - some calculation
state: ...
step 3 - some calculation
comp_attr_2: ...
set some_ns = namespace(state,attr_1,attr_2)
some_ns.state = calculated state
some_ns.attr_1 = calculated comp_attr_1
some_ns.attr_2 = calculated comp_attr_2
{{ some_ns }}
attributes:
attr_state: >-
{{ states("sensor.composite_123").state }}
comp_attr_1: >-
{{ states("sensor.composite_123").attr_1 }}
comp_attr_2: >-
{{ states("sensor.composite_123").attr_2 }}
The idea is to perform calculations once, then access results from a “composite” state.
So I created a sensor with this state:
<Namespace {'p_s': 'asuswrt', 'place': None, 'p_d': 2.0087780952453613, 'p_a': 'off', 'b_s': 'life360', 'b': '52', 'b_d': 610.0081288814545, 'b_a': 'off', 'bc_src': 'life360', 'bc': 'off', 'bc_d': 610.0081720352173, 'bc_a': 'off', 'p': 'home'}>
But - I cannot access its attributes:
I can convert this “namespace string” to a “dictionary-looking” string:
{% set ns = "<Namespace {'p_s': 'asuswrt', 'place': None, 'p_d': 2.0087780952453613, 'p_a': 'off', 'b_s': 'life360', 'b': '52', 'b_d': 610.0081288814545, 'b_a': 'off', 'bc_src': 'life360', 'bc': 'off', 'bc_d': 610.0081720352173, 'bc_a': 'off', 'p': 'home'}>"%}
{{ns}}
{% set dict = (ns|string).split("<Namespace ")[1].split(">")[0] %}
{{dict}}
But still this “dictionary-looking” string does not work as a dictionary - I cannot do any of these:
{{ dict['p'] }}
{{ dict[p] }}
{{ dict.p }}
Probably I should not use a namespace? May be I should create some kind of dictionary and return it?
Or may be there is some 3rd way?
Update:
Managed to extract an argument from that “dictionary-looking” string:
{% set dict_2 = dict.replace("'","\"") %}
dict_2 = {{dict_2}}
{{(dict_2|from_json).place}}
But these tricks seem like a hack; probably there is a better solution.