Get event data in python script

I am sending some json data to HA via http post. I use the /api/event/event_name method so that an event is triggered when the data arrives. I have used the developer tools to listen for the event and it does show up with the appropriate data. I then created an automation that uses the event as a trigger with an action that calls a python function where I intend to act on the data. My question is, how do i pass the event data to the python script?

Thanks for any help.

service: python_script.something
data_template:
  your_variable: "{{ trigger.event.data }}"

Thank you. So when it gets to the script is that a string or is it json?

String I would think.

JSON is a string. :wink:

What does the event data look like? I’m guessing, at the very least, you’ll want to use "{{ trigger.event.data.XYZ }}", replacing XYZ as appropriate.

Parsing a JSON string inside a python_script might not be too easy. (I.e., I don’t think the json package is available.) If there are multiple pieces of data in the JSON string you might want to break them out in the automation instead.

Thanks for your reply. Yes, I ended up building three templates to pull out the data I needed and send it to the script. I wasn’t too familiar with the templating engine but it’s not bad once you use it a little. The biggest obstacle was making sure I validated the data was actually in the json data before i tried to send it. These sensors send frames on a regular cadence but only some of them actually have the temperature/humidity fields populated.

FYI to get the data in the python script:

data_template:
  foo: "{{ trigger.event.data }}"

in the script

data.get('foo')

yes, as @petro suggests. let me share how I use it:

automation:

- alias: 'Last Script'
  id: 'Last Script'
  trigger:
    platform: event
    event_type: call_service
    event_data:
      domain: script
  condition: []
  action:
    - delay:
        seconds: 1
    - service: python_script.last_script
      data_template:
        event: '{{ trigger.event }}'

python script:

# Get params
event = data.get('event')
# logger.error("LAST SCRIPT: " + str(event))
# Sample: <Event call_service[L]: service_data=, service_call_id=78356624-86, service=mp_playpause, domain=script>

# Find the script name.
pos_start = event.find('service=')+8
pos_end = event.find(',', pos_start)

# Get the state object (script) from the name
entity_id = 'script.' + event[pos_start:pos_end]
state = hass.states.get(entity_id)
dt = datetime.datetime.now() #state.attributes.get('last_triggered') #
#time = '%d:%02d' % (dt.hour, dt.minute)
time = '{:d}:{:02d}'.format(dt.hour, dt.minute)
#time = '{:%-H:%M}'.format(dt)
msg = []

try:
    msg = state.name
except:
    msg = ''

if (msg is None):
    msg = ''

# Ignore some names
# msg = state.name
if (msg == 'None') or (msg.startswith('Set ')):
    msg = ''

if (msg != '') :
    # Sensor update
    hass.states.set('sensor.last_script', '{}: {}'.format(msg,time), {
        'friendly_name': 'Last script',
        'entity_picture': '/local/buttons/command.png'
    })

which give a sensor with the state of the last run script…

This is great stuff. Thanks for sharing!

Is that logger statement how you figure out what the string looks like so you can parse it?

yes, indeed it will show something like this in the home-assistant.log

020-01-09 16:24:50 ERROR (SyncWorker_19) [homeassistant.components.python_script.last_script.py] LAST CMD: <Event call_service[L]: domain=script, service=mode_full_house, service_data=>

Very cool. Thanks!

Marius, after a whole day of trying to unsuccessfully pass an argument to a python script, I’m desperate so your help would be much appreciated.

My python script is

name = data.get("nombre")
logger.warning("Hello %s", name)
hass.bus.fire(name, {"wow": "from a Python script!"})

And I’m using it as follows

type: button
entity: sensor.irrigation_icon_1
tap_action: 
  action: call-service
  service: python_script.hello_world
  data_template:
    nombre: jaime

And I’m getting the following warning

2021-06-06 02:41:13 WARNING (SyncWorker_5) [homeassistant.components.python_script.hello_world.py] Hello None

So it is clear that data_template is not working. I’ve tried everything and can’t make it work. Is there anything else I should be doing?

Thank you again anyway if you get to look at this

use:

    data:
      name: >
        {{ 'Passed name' }}

remember you can either use a real template format (like I suggest above , between {{ }} ) in which you can either use a factual template, or, like in this case, a string. You can also use:

   sequence:
    service: python_script.hello
    data:
      name: Passed name

all in all, I think you should simply change data_template to data:

used like:

script:
 hello:
   alias: Hello
   sequence:
    service: python_script.hello
    data:
      name: Passed name

and python:

name = data.get("name")
logger.error("Hello %s", name)
hass.bus.fire(name, {"wow": "from a Python script!"})

remember also that the log_level needs to be adequate for the logger to be seen. My default log_level is ‘error’, so I changed it to that level in the Python script

Marius, thank you very much for your prompt response especially since this thread is a year old! Much appreciated.

I tested all of these but they didn’t work. Fortunately, I came across another suggestion which did work … a very simple one.

type: button
entity: sensor.irrigation_icon_1
tap_action: 
  action: call-service
  service: python_script.hello_world
  service_data:
    nombre: jaime

notice how I’m using service_data instead of data_template.

I hope this proves useful to you in the future and thank you again for your help!

A yes that’s the format for the button, I wrote a core script …