Yep, looks good!
Hi again René
I used your example, and added the remaining sensors, and it has been working flawless ever since - Resource light, and very stable.
But after upgrading to Home Assistant 2021.6 I get an error:
- Error while processing template: Template("{% set root = state_attr(‘sensor.solar_inverter’, ‘root’) %} {% if root.Device.Measurements.Measurement[2]["@Value"] is defined %} {{ root.Device.Measurements.Measurement[2]["@Value"] | round(0)}} {% else %} 0 {% endif %}")
I think it has to do with the “REST-wannabe-answer” from the inverter, but I’m not able to pinpoint where I have to correct it.
Do you got the same problem after update?
k.r. Niels
Hi Niels,
Indeed I’m seeing the same at my installation, I didn’t notice.
I’ll get to work and find out why this doesn’t work anymore, I’ll keep you posted
Regards,
René
@petro Can you help us out here?
There’s nothing changed on the code, but still it doesn’t work and can’t figure out why. This is the converted XML to JSON coming back from the inverter and put it in the template editor. It throws the exact same error as I see in the log files:
UndefinedError: ‘None’ has no attribute 'Device’
{## Imitate available variables: ##}
{% set my_test_json = {
"root": {
"Device": {
"Measurements": {
"Measurement": [
{
"_Value": "228.8",
"_Unit": "V",
"_Type": "AC_Voltage"
},
{
"_Value": "1.832",
"_Unit": "A",
"_Type": "AC_Current"
},
{
"_Value": "403.4",
"_Unit": "W",
"_Type": "AC_Power"
},
{
"_Value": "49.977",
"_Unit": "Hz",
"_Type": "AC_Frequency"
},
{
"_Value": "415.2",
"_Unit": "V",
"_Type": "DC_Voltage"
},
{
"_Value": "0.975",
"_Unit": "A",
"_Type": "DC_Current"
},
{
"_Value": "39.1",
"_Unit": "°C",
"_Type": "Temp"
},
{
"_Unit": "V",
"_Type": "LINK_Voltage"
},
{
"_Unit": "W",
"_Type": "GridPower"
},
{
"_Unit": "W",
"_Type": "GridConsumedPower"
},
{
"_Unit": "W",
"_Type": "GridInjectedPower"
},
{
"_Unit": "W",
"_Type": "OwnConsumedPower"
},
{
"_Value": "100.0",
"_Unit": "%",
"_Type": "Derating"
}
]
},
"_Name": "StecaGrid 3600x",
"_NominalPower": "3680",
"_Type": "Inverter",
"_Serial": "xxxxx",
"_BusAddress": "1",
"_NetBiosName": "xxxxx",
"_IpAddress": "xxxxx",
"_DateTime": "2021-06-21T18:23:19"
}
}
} %}
{% set root = state_attr('my_test_json', 'root') %}
{{ (root.Device.Measurements.Measurement[2]["@Value"] | float / 1000) }}
And this is the logging from homeassistant logbook:
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 389, in async_render
render_result = _render_with_context(self.template, compiled, **kwargs)
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 1358, in _render_with_context
return template.render(**kwargs)
File "/usr/local/lib/python3.8/site-packages/jinja2/environment.py", line 1304, in render
self.environment.handle_exception()
File "/usr/local/lib/python3.8/site-packages/jinja2/environment.py", line 925, in handle_exception
raise rewrite_traceback_stack(source=source)
File "<template>", line 1, in top-level template code
File "/usr/local/lib/python3.8/site-packages/jinja2/sandbox.py", line 326, in getattr
value = getattr(obj, attribute)
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 1382, in _fail_with_undefined_error
raise ex
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 1374, in _fail_with_undefined_error
return super()._fail_with_undefined_error(*args, **kwargs)
jinja2.exceptions.UndefinedError: 'None' has no attribute 'Device'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 505, in async_render_to_info
render_info._result = self.async_render(variables, strict=strict, **kwargs)
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 391, in async_render
raise TemplateError(err) from err
homeassistant.exceptions.TemplateError: UndefinedError: 'None' has no attribute 'Device'
Not sure if it will solve the actual problem, but the template should be:
{% set root = my_test_json['root'] %}
{{ (root.Device.Measurements.Measurement[2]["_Value"] | float / 1000) }}
Exactly what I was going to observe, but you beat me to it. It looks as though the XML has changed from @Value
to _Value
which is why the original sensor isn’t working — and you cannot use state_attr
on a variable you’ve declared in the template editor, which is why you’re getting that error.
If there’s no guarantee that the measurements will be in the same order each type, you can loop through to find the correct _Type
, as I have with my printer.
If that is your template, root is None at startup. Therefore accessing anything in it will result in an error. So, make a check. There’s plenty of ways to do this:
{% set root = state_attr('sensor.solar_inverter', 'root') %}
{{ root.Device.Measurements.Measurement[2]["@Value"] | float / 1000 if root is not none else 0 }}
{% set root = state_attr('sensor.solar_inverter', 'root') %}
{% if root %}
{{ root.Device.Measurements.Measurement[2]["@Value"] | float / 1000 }}
{% else %}
0
{% endif %}
No, he changed it for testing. His error is related to startup issues with the update to 2021.5 where silent errors produced by things being ‘undefined’ in templates are no longer ignored. This results in the template sensor failing the onboarding process and a listener is never created. You basically have to safely access things from here on out, even at startup when things aren’t initialized.
See his error:
It’s referencing Device
which is a key inside root. I.E. root is set to none. That only happens at startup (Typically).
Hi Petro and Troon,
Thank you for your quick replies. As Petro suggested at the time I built this, there is already a check builtin if root was defined or not:
solar_live_output_kw:
value_template: >
{% set root = state_attr('sensor.solar_inverter', 'root') %}
{% if root.Device.Measurements.Measurement[2]["@Value"] is defined %}
{{ (root.Device.Measurements.Measurement[2]["@Value"] | float / 1000) }}
{% else %}
0
{% endif %}
device_class: power
unit_of_measurement: 'kW'
friendly_name: Live opgewekt in kW
Now, without changing anything, BUT upgrading to core-2021.6.6 the issue disappeared and showed me data again:
Same here (Also working) - Had to be a buggy implementation in early 2021.6.x releases.
With the new Energy focus in HA 2021.8 I am wondering what the criterias is for our Steca inverters to be able to be selectable as a Solar input?
I know that it is Power (Watt) that is measured, and Energy (wh) that is wanted as input - but no matter how I tweak any sensor I can not figure out how to get anything working.
Do i need to go to a ModBus solution for this to work?
Any ideers?
All thank you for this threat it helped me a lot on using REST with my inverter.
@nila nila mayby you can use the http://ip_address/yields.xml page. That should sum up the amount of energy created.
Or try all.xml for all options of your inverter.
Every day my home assistant stops responding some where in the night. It started after using the REST integration as Rene (see threat)
The error i get is:
2021-09-22 03:16:42 ERROR (MainThread) [homeassistant.components.template.template_entity] TemplateError('UndefinedError: dict object has no element 2') while processing template 'Template("{% set root = state_attr('sensor.solar_frontier', 'root') %} {% if root.Device.Measurements.Measurement[2]["@Value"] is defined %}
{{ root.Device.Measurements.Measurement[2]["@Value"] | round(0)}}
{% else %}
0
{% endif %}")' for attribute '_attr_native_value' in entity 'sensor.solar_live_output'
Below is the config i am using
# Configuration.yaml entry
sensor:
- platform: rest #Solar Frontier Inverter
resource: http://x.x.x.x/measurements.xml
json_attributes:
- root
- Measurements
name: Solar_Frontier
scan_interval: 60
timeout: 20
value_template: 'OK'
- platform: template
sensors:
solar_live_output:
value_template: >
{% set root = state_attr('sensor.solar_frontier', 'root') %}
{% if root.Device.Measurements.Measurement[2]["@Value"] is defined %}
{{ root.Device.Measurements.Measurement[2]["@Value"] | round(0) }}
{% else %}
0
{% endif %}
device_class: power
unit_of_measurement: 'W'
friendly_name: Solar Frontier Live power
The inverter has all value’s at daytime but at night some value disappear from measurements.xml (complete lines disappear at night)
<Measurement Value="239.392" Unit="V" Type="AC_Voltage"/>
<Measurement Value="12.826" Unit="A" Type="AC_Current"/>
<Measurement Value="3043.300" Unit="W" Type="AC_Power"/>
<Measurement Value="50.000" Unit="Hz" Type="AC_Frequency"/>
<Measurement Value="612.804" Unit="V" Type="DC_Voltage"/>
<Measurement Value="5.050" Unit="A" Type="DC_Current"/>
<Measurement Value="3099.480" Unit="W" Type="DC_Power"/>
<Measurement Value="37.000" Unit="°C" Type="Temp"/>
Any1 a suggestion on how to fix this?
{% set root = state_attr('sensor.solar_frontier', 'root') %}
{% if root.Device.Measurements.Measurement is defined and root.Device.Measurements.Measurement
| length > 0 %}
{{ (root.Device.Measurements.Measurement | selectattr('@Type', 'eq', 'AC_Current') | list | first)['@Value'] | default }}
{% else %}
0
{% endif %}
Petro thanks a lot it works!!
Most of the error messages have disappeared. There is only one error left every day. Is there a way to resolve this condition to?
2021-09-28 19:15:41 ERROR (MainThread) [homeassistant.components.template.template_entity] TemplateError('UndefinedError: No first item, sequence was empty.') while processing template 'Template("{% set root = state_attr('sensor.solar_frontier', 'root') %} {% if root.Device.Measurements.Measurement is defined and root.Device.Measurements.Measurement | length > 0 %}
{{ (root.Device.Measurements.Measurement | selectattr('@Type', 'eq', 'AC_Power') | list | first)['@Value'] | default }}
{% else %}
0
{% endif %}")' for attribute '_attr_native_value' in entity 'sensor.solar_live_output'
And now the complete error hoping someone can help me solve it
Logger: homeassistant.helpers.event
Source: helpers/template.py:399
First occurred: 2:00:46 AM (2 occurrences)
Last logged: 2:00:46 AM
Error while processing template: Template("{% set root = state_attr('sensor.solar_frontier', 'root') %} {% if root.Device.Measurements.Measurement is defined and root.Device.Measurements.Measurement | length > 0 %} {{ (root.Device.Measurements.Measurement | selectattr('@Type', 'eq', 'AC_Power') | list | first)['@Value'] | default }} {% else %} 0 {% endif %}")
Error while processing template: Template("{% set root = state_attr('sensor.solar_frontier', 'root') %} {% if root.Device.Measurements.Measurement is defined and root.Device.Measurements.Measurement | length > 0 %} {{ (root.Device.Measurements.Measurement | selectattr('@Type', 'eq', 'Temp') | list | first)['@Value'] | default }} {% else %} 0 {% endif %}")
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 397, in async_render
render_result = _render_with_context(self.template, compiled, **kwargs)
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 1604, in _render_with_context
return template.render(**kwargs)
File "/usr/local/lib/python3.9/site-packages/jinja2/environment.py", line 1304, in render
self.environment.handle_exception()
File "/usr/local/lib/python3.9/site-packages/jinja2/environment.py", line 925, in handle_exception
raise rewrite_traceback_stack(source=source)
File "<template>", line 2, in top-level template code
File "/usr/local/lib/python3.9/site-packages/jinja2/sandbox.py", line 303, in getitem
return obj[argument]
jinja2.exceptions.UndefinedError: No first item, sequence was empty.
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 513, in async_render_to_info
render_info._result = self.async_render(variables, strict=strict, **kwargs)
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 399, in async_render
raise TemplateError(err) from err
homeassistant.exceptions.TemplateError: UndefinedError: No first item, sequence was empty.
root.Device.Measurements.Measurement
has no @Type
= AC_Power
, apparently
I think the problem is that sometimes @Type
= AC_Power
is not available. But i dont know how to change the command to first check is it is there or not.