Hi I want to use the platform template to store in a template sensor a simple string with a list of urls just separated by spaces. The sensor I created displays ‘unknown’ as its value.
However, my template works fine in the template editor, I mean the output of the editor is exactly what I want to keep. However, my value_template code is not a kind of conditional option as usual it is a bit more complex with a for loop, it is something like this:
- platform: template
sensors:
osbee_programs_to_disable:
friendly_name: 'osbee_programs_to_disable'
value_template: >-
{% set current_dkey = 'dkey=xxxx' %}
{% set amp = '&' %}
{% set url = 'http://xxxxx.org:8124/cp?' %}
{%- for eachProgram in states.sensor.programas_osbee.attributes.progs -%}
{% set current_pid = loop.index -1 %}
{%- set current_config = eachProgram.config -%}
{%- if current_config % 2 != 0 -%}
{%- set current_config = current_config - 1 -%}
{%- endif -%}
{%- set current_name = eachProgram.name -%}
{%- set current_sts = eachProgram.sts -%}
{%- set current_nt = eachProgram.nt -%}
{%- set current_pt = eachProgram.pt -%}
{%- set changeProgramString = (url~amp~current_dkey~amp~'pid='~current_pid ~amp~'config='~current_config~amp~'nt='~current_nt~amp~'sts='~current_sts~amp~'pt='~current_pt~amp~'name='~current_name |string).replace(" ","") -%}
{{ changeProgramString }}{{' '}}
{%- endfor -%}
This sensor will be perfect to use as the URLs for a curl shell command. But, Can a sensor template store the same as the editor output or should I try another kind of approach. Thanks!!
Absolutely makes sense. I’d never worked with jinja templates before and thought I had to refer to the editor output. But in any case, shouldn’t it, at least, store the value of the last iteration??. Anyway, I’ll try it (and learn how to append) and report back. Thanks a lot!
Be advised that a variable used within a for-loop is only defined within the loop (i.e. its scope is limited to the loop). If you want to use a variable within a loop that retains its value outside the loop, you have to use namespace.
Hi, I’ve considered both of your indications and this is the result:
- platform: template
sensors:
osbee_programs_to_disable:
friendly_name: 'osbee_programs_to_disable'
value_template: >-
{% set current_dkey = 'dkey=xxxxx' %}
{% set amp = '&' %}
{% set url = 'http://xxxxxx.org:8124/cp?' %}
{% set ns = namespace(changeProgString='') %}
{%- for eachProgram in states.sensor.programas_osbee.attributes.progs -%}
{% set current_pid = loop.index -1 %}
{%- set current_config = eachProgram.config -%}
{%- if current_config % 2 != 0 -%}
{%- set current_config = current_config - 1 -%}
{%- endif -%}
{%- set current_name = eachProgram.name -%}
{%- set current_sts = eachProgram.sts -%}
{%- set current_nt = eachProgram.nt -%}
{%- set current_pt = eachProgram.pt -%}
{%- set ns.changeProgString = ns.changeProgString~' '~(url~amp~current_dkey~amp~'pid='~current_pid ~amp~'config='~current_config~amp~'nt='~current_nt~amp~'sts='~current_sts~amp~'pt='~current_pt~amp~'name='~current_name |string).replace(" ","") -%}
{%- endfor -%}
{{ ns.changeProgString }}
Now, I have appended the string and have made the string variable global with namespace() (didn’t know the limited scope to just the loop, thanks again!)
However, even if inside the template editor the result seems fine:
For a template sensor, Home Assistant inspects the contents of value_template and attempts to identify the entities that it must monitor for state-changes. When one of these entities changes its state, that triggers Home Assistant to evaluate the template sensor.
When it cannot automatically find entities to monitor, it will only evaluate the template sensor once, at startup.
To help Home Assistant find the entities it should be monitoring, use the template sensor’s entity_id option. Specify one or more entities that should be monitored. When they change state, the template sensor’s value_template will be evaluated.
So if Home Assistant should be monitoring sensor.programas_osbee then add this line to the template sensor’s configuration:
entity_id: sensor.programas_osbee
Changes to the sensor’s state or its attributes will trigger an evaluation of value_template.
Thank you Taras!. Indeed, this code is much cleaner and shorter than mine. I’ve changed my code but even with yours and with an entity_id, I’m only getting ‘unknown’ as the state of this template.
We’re getting close, I’ll try again this afternoon. Just in case, Could it be something related to the maximum size of a string variable?
BTW, maybe it is useful for someone else: what I am trying to do is this:
I get from a REST sensor, ‘sensor.programas_osbee’, (already working fine) the data from an Open Sprinkler Bee . This is the cheap one that does not support any kind of rain control in its firmware, but it has a rest api to communicate with. I just want to control from HA that, whenever it rains, disable all active irrigation programs in the OpenSprinkler Bee. It will be triggered from an automation whenever it rains.
To disable the programs, you just have to make 0 the last bit of each program ‘config’ parameter (a 3 byte long integer), this is easy, as a decimal: if it’s even, the program will already be off; if it’s odd, it’s enable, so just do ‘config-1’.
Thus, eventually the variable ns.urls will have ready, all the URLs to change the programs to disable irrigation. Once this is working , it should be as simple as using a Shell Command with cURL and sending these URLs to the Opensprinkler Bee.
Then I’ll trigger another automation once per day (at 0h, for example) to reset to ‘enable’ all my irrigation programs.
When finished, maybe this is useful for someone else.
That’s a good question because there is a maximum size for an entity’s state and that’s 255 characters. So if the total length of the string in ns.urls exceeds 255, it won’t work.
An entity’s attribute can store more than 255 characters.
That was the problem!!. I’ve removed an irrigation program and now, with only 1, it’s working fine.
You’ve told me that an entity’s attribute can store more than 255 characters but, now the problem is that as far as I know there is not attribute option for template sensors, is there?
How could I store then my URLs to be able to use them?? I’m thinking of creating a sensor from JSON data in the same JSON format to allow more than 255 characters, but now I’m not sure how to do that. I’ll keep thinking about it.
I have managed to solve my issue, although I still have to solve how to send the result via cURL.
Here it is my code(even shorter now) for the template: it seems that keeping the result as an array of JSON, it is no longer limited to 255, as it works for several programs:
{% set ns = namespace (progstochange=[]) %}
{%- for p in states.sensor.programas_osbee.attributes.progs -%}
{% set ns.progstochange = ns.progstochange+[{'name': p.name, 'pt': p.pt, 'sts': p.sts, 'nt': p.nt, 'config': (p.config - 1 if p.config % 2 != 0 else p.config)}] %}
{%- endfor -%}
{{ns.progstochange}}
I don’t know if it’s unlikely or not, but I have had it recorded as an array, maybe as an array of strings and that is why I’m not having the 255 issue, take a look at it, you can see it in states as [sensor.osbee_programs_to_disable]
Now, this is a list, as you can see it gets access to each item with its index, what I didn’t check was the current length of it. I’m going to try to add more irrigation programs to my OSBee, I’ll keep you posted.
Ok, you were absolutely right about the length: I have just checked it with one more program. Then the problem doesn’t start in my template sensor but in my restful sensor, it doesn’t even load the get request and thus it’s not appearing as a sensor, and checking the ha log it says:
“File “/srv/homeassistant/lib/python3.5/site-packages/homeassistant/core.py”, line 696, in init
“State max length is 255 characters.”).format(entity_id))”
In theory I’m not needing more than 2 programs for my little garden but, it’s a pity not been able to extend it currently to any amount of programs. Any more ideas will be appreciated. Thanks again.
That’s a list in the Template Editor. The output of that template, when stored in an entity’s state, is converted to a string (as described in the developer documentation) whose length is limited to 255 characters.
Why are you trying to store many URLs in one sensor’s state?
Can you move the values from the restful sensor to attributes, e.g. with json_attributes? Then do you need the full URLs as a state or can you just build them up when you need to send the command?