Pyscript - new integration for easy and powerful Python scripting

Well I moved all the plexapi calls to a function in another .py-file and imported it as a module, then running the new function with task.executor. Then it works.

Hi,

I am trying to find a somewhat over the top way of moving my blinds to follow the sun across the windows in my house. I started with a template binary_sensor, but the jinja2 required is just too much, especially given the amount of standard libraries one could use from Python to implement standard algorithms. So I would like to know if pyscript could do the following:

  • The output should be a binary sensor which will be turned on whenever the script passes a bunch of conditions.
  • The script will need to import the shapely python module, so that I can deal with a bunch of projective geometry and unions of polygons without rewriting everything from scratch
  • I’ll need to have access to a few sensors and the sun’s position from HA.
  • Ideally I would have one such script and run separate instaces for every cover in the house, with a simple config for each of them.

Is this something that pyscript can do? Essentially I want it to be a much more powerful way of writing a template sensor. Or do I need to do the whole automation inside it, rather than just having a simple binary_sensor as an output?

I seem to have managed to do what I wanted with pyscript Rather than some automation, I have used it to compile and compute some values which go into a sensor. I then have normal automations triggering on values of this.

It’s very nice to be able to just use normal python to process data instead of mucking around with jinja2.

1 Like

Hey, very interesting stuff!

May I ask how did you manage to run shapely in pyscript? I was trying myself and it seems not supported yet.

thanks!

The issue is that you need to install the geos package into the docker image that HA runs on. Not sure if there is a way to do it permanently, so I just execute a shell script with an automation on HA startup:

#!/bin/sh
apk update
apk add geos

If you then turn on the pyscript option to import any module and you add shapely to requirements.txt, you can import shapely in your script and use it.

This method means that when you upgrade HA, the first time it reboots, geos is not available for some reason, but another reboot fixes it.

Would love to know if there is a better way of doing it.

The thing is that pyscript is a custom component and not an AddOn.

It’s possible to use AppDaemon which is an addon where you can specify apk’s to install.
I’ve made an AppDaemon script that allows you to call another command. You can call an external command by calling python3.
Alternatively, you implement your script as an AppDaemon module.

Have a look at my forum reply the gist I shared there:

Any news on support for new classes? I’ve had medium success using classes for now, but it breaks as soon as I try inheritance or state_triggers within a class.

Ive just converted my old python script that scrapes for bin days and color, At the moment it outputs to log.info a text sentence like ‘Next rubbish day is Monday the 27th and is Black’

Im trying to find how to display this text in a markdown card.

Do I need to create the entity first in home assistant or can it be created at runtime in the script.

Ive tried various variations around this in my Pyscript code like:

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

just to test the setting up off entities but not getting anywhere, any help would be appreciated.

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)")