I want to be able to publish, using MQTT the information that I can see homeassistant holds when I look in Developers Tools → States (see below) The info is being collected by an Octopus integration, and used within different integrations. I am already happily sending and receiving other info such as immersion temperature and battery SOC but I just don’t seem to be able to access this info from within an automation. (The best I can do just sends “{“platform”:null}”)
Any help (ideally a pointer to some kind of reference to help me with this kind of thing, but a simple recipe would be a help)
PS I tried things like {{ trigger.to_state.state | to_json }} or `{{ states(“event.octopus_energy…etc”) | to_json }} etc.
Figure out whether you want the state or the state object…
… then use the appropriate method:
Building Templates - States
@Didgeridrew thanks very much for those pointers.
Looking at the first I think I can deduce that the info I want to get falls under the category “entity state attributes” that the help page applies to the min_color_temp_kelvin of the light.bed_light in the example screen shot. So that means I want… a state rather than a state object?
Going to the second ref. I tried various version of automations along the lines of
- id: '1763330124678'
alias: agile_current_rates
description: ====
triggers:
- trigger: state
entity_id:
- event.octopus_energy_electricity_23abcdef98_23abcdef41513_current_day_rates
conditions: []
actions:
- action: mqtt.publish
metadata: {}
data:
qos: '0'
retain: false
topic: homeassistant/agile/current_rates
payload: '{{ state_attr("event.octopus_energy_electricity_23abcdef98_23abcdef41513_current_day_rates",
"attributes").rates | to_json }}'
evaluate_payload: false
mode: single
But, though I can sometimes transmit something like {"platform": null} I normally get things in the log along the lines of
Error while executing automation automation.agile_current_rates: Error rendering data template: UndefinedError: 'dict object' has no attribute 'to_state'
Error while executing automation automation.agile_current_rates: Error rendering data template: UndefinedError: 'dict object' has no attribute 'state'
Error while executing automation automation.agile_current_rates: Error rendering data template: UndefinedError: 'dict object' has no attribute 'attributes'
Error while executing automation automation.agile_current_rates: Error rendering data template: UndefinedError: 'str object' has no attribute 'attributes'
Error while executing automation automation.agile_current_rates: Error rendering data template: TypeError: Type is not JSON serializable: LoggingUndefined
I’m manually triggering the automation as the event only really happens once a day, would that make any difference?
Do I need to set something up in templates.yaml rather than automations?
I feel there should be a more scientific way to figure out from the Developer tools → States page what reference I need to use. The trial and error system takes a long time!
All the best
Paddy
PS after re-reading your first reference I am slightly more confused about what exactly constitutes state and state object Does state used alone refer to the attribute of the object called state? In the screen-shot in my OP, is rates: an attribute of the state or the state object?
Manually triggering will not work for testing if you are using any trigger variables in your automation, like the trigger.to_state.state used in your first post.
Based on that error and the integration’s doc
An issue is that the start and end values of each item in the rate list are datetime objects. Datetime objects are not JSON serializable, so you need to convert them to datetime strings before using to_json.
Well, if you understand that trigger.to_state represents the complete new state object of the entity and that you can access that same data with states.event.octopus_energy_electricity_23j0520798_2310654241513_current_day_rates (as described in the “Building Templates” page linked above), you can refine your templates in the Developer tools → Templates tool. The following will allow you to tinker and test your template without having to worry about the automation part:
{% set trigger = {'to_state': states.event.octopus_energy_electricity_23j0520798_2310654241513_current_day_rates} %}
{{ trigger.to_state.attributes.rates }}
There might be a way to do this without an explicit loop, but this is what came to mind:
{# The following is what would be used for payload in your mqtt action #}
{% set ns = namespace(r_list=[]) %}
{% for r in trigger.to_state.attributes.rates %}
{% set start = (r.start).isoformat() %}
{% set end = (r.end).isoformat() %}
{% set ns.r_list = ns.r_list + [{'start': start,'end': end,'rate': r.rate}] %}
{% endfor %}
{{ ns.r_list |to_json }}
The state object is a collection of properties of an entity. Both state and attributes are properties of the state object as well as others like last_changed, name, etc.
state is a string, usually representing the most important data point for that entity.
attributes is a dictionary containing it’s own collection of data… one of which is rates in this case. Most of us will just describe rates as an “attribute”.
1 Like
@Didgeridrew thanks so much for your patience. Inspired by your suggestions, I “stumbled upon” the Developers tools → Template tab. This allowed me to type stuff in and see what happened… a 1,000% increase in productivity!
I’m picking up the MQTT info in my own python script running on a Raspberry Pi (I help maintain helgeerbe/picframe but only just decided to wade into digital assistant) so I can parse stuff out at the other end. This is what I came up with, but I will study your suggestion as it’s probably better (I had looked to see if there was a way to append to a list in all the jinja mumbo jumbo!
{% set cur_rates = state_attr("event.octopus_energy_electricity_23abcdef98_23abcdef513_current_day_rates", "rates") %}
[{%- for r in cur_rates -%}
{%- if loop.index0 > 0 -%}
, {% endif -%}
{"start": "{{ r.start | string }}", "end": "{{ r.end | string }}", "value_inc_vat": {{ r.value_inc_vat }}}
{%- endfor -%}]