Pyscript - new integration for easy and powerful Python scripting

The documentations says:

state.set(name, value=None, new_attributes=None, **kwargs)

so doing the same with:

state.set("sensor.rubbish", value="test", new_attributes=None)

should work :slight_smile:

4 Likes

Is it possible to access historical data through pyscript? I would like to do some statistics on HA sensor values, without having to define them first in HA itself.

To be concrete, I would like to get the standard deviation for the sensor value for the last 30 minutes. Is that possible?

Could you please share how exactly you solved the “selenium has no attribute webdriver” problem? Thanks!

In no particular order, you have at least some options:

  1. Do it yourself: Collect the statistics (first and second moments) in some persistent state, and update them using a buffer (also persistent) of the last 30 minutes of sensor values.

  2. Query the HA database.

  3. Use something like InfluxDB, where the std(last 30 min) should be a relatively straightforward query.

Hi,

Sorry for the slow reply.

To solve it, I had to specifically import the webdriver as well and not just Selenium, like below:

import selenium
from selenium import webdriver

Thanks

I’m fairly new to pyscript, I actually got it strictly for this project, but I have run into a roadblock.

I am trying to translate some text from a voice assistant to another language, using a python library.

So far, I have this service, which, to my understanding and testing, should work as pure python.

@service

def translate_function_new(text, destlang):
    from google_trans_fixed import google_translator
    translator = google_translator()
    translate_text = translator.translate(str(text), lang_tgt=destlang)
    log.info(translation)

However, I get an error whenever I try to run the service with:

text: test
destlang: es

as my service data. The error(s) (and log info) I get are:

2022-07-23 03:40:13 INFO (MainThread) [homeassistant.helpers.script.websocket_api_script] websocket_api script: Running websocket_api script
2022-07-23 03:40:13 INFO (MainThread) [homeassistant.helpers.script.websocket_api_script] websocket_api script: Executing step call service
2022-07-23 03:40:13 WARNING (MainThread) [homeassistant.util.async_] Detected blocking call to putrequest inside the event loop. This is causing stability issues. Please report issue to the custom component author for pyscript doing blocking calls at custom_components/pyscript/eval.py, line 1906: return func(*args, **kwargs)
2022-07-23 03:40:13 ERROR (MainThread) [custom_components.pyscript.file.translate_new.translate_function_new] Exception in <file.translate_new.translate_function_new> line 146:
timeout=self.timeout)
^
RuntimeError: Blocking calls must be done in the executor or a separate thread; Use `await hass.async_add_executor_job()`; at custom_components/pyscript/eval.py, line 1906: return func(*args, **kwargs)

I have tried using task.executor, like:

@service

def translate_function_new(text, destlang):
    from google_trans_fixed import google_translator
    translator = google_translator()
    translate_text = task.executor(translator.translate, text, destlang)
    log.info(translation)

but I get (with the same service data)

2022-07-23 03:42:02 INFO (MainThread) [homeassistant.helpers.script.websocket_api_script] websocket_api script: Running websocket_api script
2022-07-23 03:42:02 INFO (MainThread) [homeassistant.helpers.script.websocket_api_script] websocket_api script: Executing step call service
2022-07-23 03:42:02 ERROR (MainThread) [custom_components.pyscript.file.translate_new.translate_function_new] Exception in <file.translate_new.translate_function_new> line 7:
translate_text = task.executor(translator.translate, text, destlang)
^
TypeError: pyscript functions can't be called from task.executor - must be a regular python function

Any help would be much appreciated!

I wonder if this is what you need: Reference — hacs-pyscript 1.5.0 documentation

One use for @pyscript_compile is to encapsulate functions that block (eg, doing I/O), so they can be called from task.executor 


Your second error message (“pyscript functions can’t be called from task.executor”) might be solved by this.

I created my first (Python) script in pyscript to do some advanced web scraping. Therefore I use Playwright and BeautifulSoup. In my script, I do the import:

    from bs4 import BeautifulSoup
    from playwright.sync_api import sync_playwright

But the logs give the following error:
from playwright.sync_api import sync_playwright ^ ModuleNotFoundError: No module named ‘playwright’
How can I install Playwright into HA ? I run HA in docker on a RaspberryPi4.

Can I create a new entity in HA through pyscript? Is this possible? I want to create a number entity through pyscript.

Is it possible to set the brightness of a dimmer switch as an attribute, and then update the switch to reflect that new value, rather than explicitly calling turn_on() with a brightness value specified? I was experimenting with setting brightness values via state.setattr() and state.set() (the latter with attribute keywords) and nothing seemed to be sticking or updating for me.

Thanks!

Yes, this can be done simply by setting a state for a new entity. I don’t think it will survive a reboot, but one can simply run the same code after startup.

1 Like

is there any way to have two time ranges for @time_active? this doesnt work

@time_active("range(05:30, sunrise + 1h) or range(sunset - 1h, 22:30)")

time_active can take multiple string arguments that are logically "or"ed together. The trigger will succeed if any of the time ranges match. See the docs. So:

@time_active("range(05:30, sunrise + 1h)",  "range(sunset - 1h, 22:30)")
1 Like

thanks @craigb, I had an or in there as you see, thought that would do it but thanks! I’ll try that :slight_smile:

I have installed Pyscript to Home Assistant (it runs on ubuntu server).
On my Windows machine I installed HASS Pyscript kernel shim for Jupyter and configured it (including hass_token).
Here is output of jupyter kernelspec list console command:

Available kernels:
python3     C:\Users\trofi\AppData\Roaming\Python\share\jupyter\kernels\python3
pyscript    C:\ProgramData\jupyter\kernels\pyscript

Then I run Jupyter server using python -m notebook command:


It opens local Jupyter web page in my browser. I create new notebook using hass pyscript kernel:

In Home Assistant logs I see the following errors:

Who is to blame? PyScript HA integration or HASS Pyscript kernel shim for Jupyter on my Windows machine? Or what am I doing wrong?

Thanks for creating such a brilliant integration. As someone who does not use jinja and only very occasionally uses python and not in the software industry. I found Pyscript is much easier to learn comparing to App deamon. I managed to implement certain functions that I probably would never attempt with jinja. I am trying to find a way to buy you a coffee but could not find any links for donation. Please do let us know when you start to create donation links.

How does using selenium in pyscript work since the home assistant doesn’t have a browser?

I have started using pyscript, and am really impressed how easy it is to use. Exploring a number of fun things, like interfacing with node-red via events as well as finally getting the jupyter notebook up and running (completely worth it!). I am wondering what approaches others have taken to have automations trigger when an entity has been in a state for a certain period.

I have tried the below, but obviously it isn’t going to work. An alternative is a mixture of yaml based automation, calling an event in pyscript. What technique do others use?

@state_trigger("(datetime.now(timezone.utc) - light.kitchen_lamp.last_changed).total_seconds() > 10")
def test():
    log.info("state trigger test function fired")

Use state_hold :slight_smile:

@state_trigger("binary_sensor.garasjeport == 'on' and binary_sensor.garasjeport.old == 'off'", state_hold=300)
def garagedoorleftopen():
    notify.mobile_app_sm_g715fn(message = "Lukke garasjeport?", title = "Garasje", data = {'actions': [{'action': 'nothing', 'title': 'Nei'}, {'action': 'CLOSE_GARAGE', 'title': 'Ja'}]})
    script.talemelding.turn_on(variables = {'message': 'Garasjeporten stÄr Äpen.'})
1 Like

Brilliant - thanks - I’m obviously still learning my way round the documentation.
I love how concise pyscript is (obviously once I know what I am doing) :smile:

# Turn backdoor light off after 30 minutes
@state_trigger("light.backdoor == 'on'", state_hold=1800)
def backdoor_light_timer_off():
    light.turn_off(entity_id="light.backdoor")