question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Feature Request: service call contexts

See original GitHub issue

Right now, when a pyscript performs a service call, the LogBook has an entry like this:

HallDown Occupied turned off by service input_boolean.turn_off

However, when Home Assistant Automations perform an action, the LogBook looks like this:

 halldown_overhead turned off by halldown_occupied_off 

It does this through a context object:

        service_task = self._hass.async_create_task(
            self._hass.services.async_call(
                domain,
                service,
                service_data,
                blocking=True,
                context=self._context,
                limit=limit,
            )
        )

pyscript can create one of these with something like:

from homeassistant.core import Context

# context comes from the state_trigger, time_trigger, etc
parent_id = None if context is None else context.id
new_context = Context(parent_id=parent_id)

I can’t find a lot of documentation on how to create context and name the pieces so they show up well in LogBook, but I think this is a start anyway. I think even this small bit of code would make the logbook show that, for instance, the “binary_sensor.dark” in my @state_trigger is what called input_boolean.turn_on. And, even this, is better than what we have now.

The final bit would be to get LogBook to show that binary_sensor.dark activated my pyscript called “halldown_at_dark”, and that “halldown_at_dark” is what called input_boolean.turn_on.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:13 (11 by maintainers)

github_iconTop GitHub Comments

2reactions
craigbarrattcommented, Oct 28, 2020

I just pushed d0745ea which provides context to state, service and event trigger functions (minimal testing). It also adds context as an optional argument for outbound service calls (untested). context contains user_id, parent_id and id. This is the first step in having what will be the parent context for the context we sent to logbook.

Use the master version if you want to test this.

1reaction
dlashuacommented, Oct 27, 2020

Here’s what I’ve learned.

The scenario: User turns on input_boolean.a. pyscript sees this and turns on input_boolean.b.

Here’s what we need to do.

When User turns on “A”, HASS sends a state changed event that has a context with a unique id (1), and a user id. This happens already.

Before running the trigger function, Pyscript should then send an event (pyscript_running or whatever) that looks like event_notify_trigger in my example. When it sends that event it should include a context with a new unique id (2). This is generated by HASS. However, when the context is created, parent_id should be set to 1. I should also note that the context doesn’t get sent as part of the “event_data”. Instead, it looks like this:

# function.py
    @classmethod
    async def event_fire(cls, event_type, **kwargs):
        """Implement event.fire()."""

        if "context" in kwargs:
            context = kwargs['context']
            del kwargs['context']
        else:
            context = Context()

        cls.hass.bus.async_fire(event_type, kwargs, context=context)

Then the pyscript runs and it turns on “B”. When it issues the service call to turn this on, it should include the SAME context that was included in async_fire. Alternately, it can send a different context, however, the parent_id must be the same as the one from the original state changed event.

The final piece of the puzzle is how to make the logbook show that data. When the log book loads, if it sees an event that has been registered, it calls a function to help display the event. To do that, inside of custom_components/pyscript along side __init__.py and function.py, we have to include a file that looks like this:

"""Describe logbook events."""
from homeassistant.core import callback

from .const import DOMAIN

import logging

_LOGGER = logging.getLogger(__name__)

@callback
def async_describe_events(hass, async_describe_event):  # type: ignore
    """Describe logbook events."""

    @callback
    def async_describe_logbook_event(event):  # type: ignore
        """Describe a logbook event."""
        data = event.data
        message = "has been triggered"
        if "source" in data:
            message = f'{message} by {data["source"]}'
        return {
            "name": data.get('name'),
            "message": message,
            "source": data.get('source'),
            "entity_id": data.get('entity_id'),
        }

    async_describe_event(DOMAIN, "pyscript_running", async_describe_logbook_event)

So while there are a few ways to do it. I think the best way is that when pyscript is about to call a pyscript function it should generate a new context with parent_id of the incoming context (except time triggers, they won’t have a parent). Then it should hold on to that context and send the same one with every other service call, event fire, or state set during that particular call to the function.

In the return data for async_describe_logbook_event, it seems that source is thrown away (or, at least not displayed). entity_id has to LOOK like an entity id (domain.name) however, it doesn’t have to be a real entity. message is what is displayed in the logbook. Without an entity_id, the subsequent service calls and event fires won’t appear tied to this event in the logbook. So it has to be included even though we don’t have a REAL entity for every pyscript function.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Feature request response email templates - LiveAgent
While there isn't a perfect way to reply to all customer feature requests as it largely depends on the context, here are 7...
Read more >
10 Tips for Responding Graciously to Customer Feature ...
Picture this scenario: A customer requests a feature. Support politely tells them that it can't be done while still providing top quality service....
Read more >
Feature Request Handling: How a SaaS Company Obsessed ...
A feature request is a specific type of product feedback that SaaS product ... BTW: if you need a little more context, we've...
Read more >
How to say no to product feature requests - Canny Blog
Here's how to say no to feature requests the right way. ... It's perfectly fine to share the real context behind why you...
Read more >
Feature Request Management Software | Hellonext
Give your users a single place to submit new feature requests. Keep them updated about the development of these features with context. →...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found