Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't call domain services using domain.entity.service() pattern #173

Closed
Nxt3 opened this issue Feb 26, 2021 · 13 comments
Closed

Can't call domain services using domain.entity.service() pattern #173

Nxt3 opened this issue Feb 26, 2021 · 13 comments

Comments

@Nxt3
Copy link

Nxt3 commented Feb 26, 2021

I used to be able to do:

light.master_bedroom.turn_on(brightness=254, color_temp=275)

but now I get errors:

AttributeError: 'StateVal' object has no attribute 'turn_on'
2021-02-26 16:06:29 ERROR (MainThread) [custom_components.pyscript.file.daytime.turnOnDayLights] Exception in <file.daytime.turnOnDayLights> line 9:
            light.master_bedroom.turn_on(brightness=254, color_temp=275)
            ^
AttributeError: 'StateVal' object has no attribute 'turn_on'

I recently upgraded my core version to core-2021.3.0b1; might have something to do with this?

@craigbarratt
Copy link
Member

craigbarratt commented Feb 27, 2021

On startup, pyscript calls async_get_all_descriptions() to get all the service descriptions, and it populates the dictionary State.service2args with all the services that have an entity_id keyword argument. Assuming you have allow_all_imports and hass_is_global both set, you can check which services it knows about:

from custom_components.pyscript.state import State
State.service2args["light"]

Does that include an entry State.service2args["light"] and State.service2args["light"]["turn_on"]?

If not, you can call async_get_all_descriptions() to see what it returns for "light":

from homeassistant.helpers.service import async_get_all_descriptions
async_get_all_descriptions(hass)["light"]

@raman325
Copy link
Contributor

raman325 commented Feb 27, 2021

I'm having the same issue, and I suspect it was the last pyscript release but haven't been able to dig in yet. Will run some tests based on your comment and will report back what I find.

EDIT: I downgraded pyscript and am still facing the issue, so it must be related to the new release beta (I am also on beta)

EDIT2: disregard above, downgrading restored the ability to call services as domain.entity.service

@craigbarratt
Copy link
Member

I created an input_number:

input_number:
  x1:
    initial: 100
    min: 0
    max: 1000

and I confirmed that things like input_number.x1.increment() and input_number.x1.set_value(50) work ok.

Perhaps there is now some race condition where the lights.turn_on service is not registered before pyscript calls async_get_all_descriptions()? It should be called when the EVENT_HOMEASSISTANT_STARTED is fired, but perhaps something is broken now. It is also called on pyscript.reload.

You could also call it manually from Jupyter with:

from custom_components.pyscript.state import State
State.get_service_params()

Does it now work after you do that?

Also, in looking at the code I noticed that pyscript fails to update State.service2args when a new service is defined with an entity_id parameter, so pyscript services don't support these virtual methods. I need to fix that.

@raman325
Copy link
Contributor

I misspoke about it being tied to 1.3.0. When I downgraded, I saw my pyscript services in Dev Tools so I assumed everything was ok. But the next time an automation ran that called one of those services, it failed, so I'm guessing there was a change that's coming in the next release that's causing this behavior as I am still running on 2021.3.0beta2.

Running that command in Jupyter did not resolve the issue:
Exception in <file.climate.set_temperature> line 47: climate.thermostat.set_temperature(temperature=float(temp)) ^ AttributeError: 'StateVal' object has no attribute 'set_temperature'

@craigbarratt
Copy link
Member

@raman325 - does the simple input_number test work or fail for you?

Unfortunately I don't have good internet access for the next day (or potentially 3 days). I don't think I can upgrade to 2021.3.0beta2 until I have better internet.

@craigbarratt
Copy link
Member

I successfully upgraded hass; the input_number test fails for me now. Onto debugging...

@craigbarratt
Copy link
Member

craigbarratt commented Feb 27, 2021

Hmmm, the return value of async_get_all_descriptions() does not include any entity_id fields, so pyscript doesn't consider them a valid virtual method.

@raman325
Copy link
Contributor

raman325 commented Feb 27, 2021

ah, I know what's going on. The latest release introduces a new key to service calls called target. Now, in addition to specifying the entity_id in the service data dictionary, you can specify it under target instead. This has resulted in service schemas changing (entity_id was removed as a field from many services and replaced with the target parameter, example here: https://github.com/home-assistant/core/blob/dev/homeassistant/components/zwave_js/services.yaml), which is probably why the logic to resolve entity services is failing.

Here are some references:

EDIT: sorry missed your note about internet access. I can look at this further on Sunday and see if I can resolve it if you'll be without access for now. Ideally we find a fix by Wednesday when this new release is GA

@craigbarratt
Copy link
Member

craigbarratt commented Feb 27, 2021

Yes, your explanation sounds exactly right. It looks like entity services are now a real and different thing, so we need to figure out how to enumerate them (or ideally just check a single one on demand, which would be better than caching them all at startup).

@raman325
Copy link
Contributor

Wow you are fast, I logged in this morning to try to figure this out and wondered how you had already had a check for the target key. Confirmed that the latest commit resolves it!

One thing that came to mind is that it would be nice if we could use target (when this is included, there is a nicer UI available to pick entities) and selector (also enhances the UI) in service descriptions. It looks like it should just work if the docstring is yaml, but something to think about if you want to support it using non YAML docstrings.

@raman325
Copy link
Contributor

Here's what it looks like in Dev Tools when you specify selectors in the service description btw:
image

@craigbarratt
Copy link
Member

craigbarratt commented Mar 4, 2021

Released 1.3.1 with this fix.

@Nxt3
Copy link
Author

Nxt3 commented Mar 4, 2021

Thank you for your work on this amazing project! Really makes automating fun.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants