Hi guys, my a little heads-up about using pyscript in the docker version of HA.
I use my simple pyscript with selenium dependency defined in the requirements.txt and I observe strange behaviour about importing some classes and functions from the whole selenium library.
Sometimes I get object has no attribute ... for some specific import but the other stuff from the same library works fine. I figured out it’s needed to stop and rerun the whole docker, not just restart the HA instance in the docker.
Now I moved the piece of code with selenium import to pyscript_modules and the behaviour seems to be better.
Does anyone have a working example using !secret in the config? The help documentation refers to it working, but doesn’t show how the actual script would use it. I have the following in configuration.yaml:
Those secrets exist and I’m using them in another section of my config. Then in the pyscript directory, I have a file named get_linked_image.py, which I dumbed down to see why it wasn’t working:
When I run this from the services tab, I see this in my log:
This error originated from a custom integration.
Logger: custom_components.pyscript.file.get_linked_image.get_linked_image
Source: custom_components/pyscript/eval.py:493
Integration: Pyscript Python scripting (documentation, issues)
First occurred: 3:31:44 PM (1 occurrences)
Last logged: 3:31:44 PM
Exception in <file.get_linked_image.get_linked_image > line 3: log.error("in a script! (" + username + ")") ^ NameError: name 'username' is not defined
How do I refer to these variables within my script, if not like this? I rebooted HA after adding them to the configuration.yaml.
x != 5 is True so the expression x != 5 or x != 6 evaluates to True. Because of short circuiting, x != 6 is not even evaluated, since its value doesn’t matter when the first expression is already True.
Does anyone know if it is possible to evaluate a template is pyscript? Either with pyscript, a service call or an another custom integration.
I have a configuration for an app written in pyscript like shown below. Instead of defining state and sensor, I would rather use a template so that I can use ‘{{ states(‘sensor.effekt’) > ‘300’ }}’ in the configuration of the app and evaluate this template in code. It will be more flexible that way and I don’t have to define several helper binary sensors.
Can you share the pyscript code as well? It isn’t clear to me where you’d want to have the template evaluated right now.
At first glance, you can always just get the state from sensor.effekt in pyscript and check if it’s larger than 300 (you may need to convert the state from a string to a float/integer though).
No, I don’ want to use sensor.effekt in code. Then it is hardcoded and doesn’t work well in an app where it should be configurable.
As the code works now, I can only test for identities that has two states, normally on and off. I wan’t to extend that with templates, but doubt it is possible. But wanted to hear if someone know of a solution.
The trigger for the sensor is set up in this code section:
if "scenes" in self.cfg:
for tr in self.cfg['scenes']:
if "sensor" in self.cfg['scenes'][tr]:
@state_trigger(f"{self.cfg['scenes'][tr]['sensor']} != 'unavailable'", state_hold = 1)
def statechanged_trig(var_name=None):
task.unique(f"scenestyringstatechg_{self.cfg['id']}_{var_name}")
self.set_sceneparams()
self.statechanged()
registered_triggers.append(statechanged_trig)
and state is checked in this section:
if ("sensor" in self.cfg['scenes'][tr]
and "state" in self.cfg['scenes'][tr]
and state.get(f"{self.cfg['scenes'][tr]['sensor']}") == self.cfg['scenes'][tr]['state']):
if "name" in self.cfg['scenes'][tr]:
s = self.cfg['scenes'][tr]['name']
My best guess in that case would be using an eval() python function, and I guess putting in the template in a python format instead of jinja2? I.e. sensor.effekt > 300 in the configuration. However I’m not sure still if that is fully the goal you want to reach.
I also don’t have experience using eval(), so I can’t promise it well work. Got the answer from here:
Trying out PyScript for some automations, and keep running into an odd issue, hoping someone here can point me in the right direction.
Basically trying to compare times in a function. But i keep getting an error :
if (dt.now() - last_flash).total_seconds > 300:
^
TypeError: unsupported operand type(s) for -: 'datetime.datetime' and 'StateVal'
Code snippet is below. I added a print to confirm that “last_flash” was truly a datetime object and it seems to be (i’m reading it directly from an input_datetime object). So where is pyscript getting the “StateVal” type from? I also tried comparing directly (dt.now() - input_datetime.last_office_flash) with the same result, this format was just an attempt to add more visibility for debug.
I would try doing something like below. Basically, you need to convert the string value to a date value. I don’t remember off the top of my head what the date format is that HA uses, but you can output that and then use the format strings (datetime — Basic date and time types — Python 3.12.2 documentation) to get it to parse correctly. This should at least get you going in the right direction.
2024-04-02 08:48:30.235 DEBUG (MainThread) [custom_components.pyscript.trigger] trigger file.kontor.kontor_bordsfjarr: watching vars {'sensor.kontor_bordsfjarr_action'}
2024-04-02 08:48:30.235 DEBUG (MainThread) [custom_components.pyscript.trigger] trigger file.kontor.kontor_bordsfjarr waiting for state change or event
And I can see the sensor entity change in Developer Tools, but pyscript is not reacting to it. My pyscript apps execute like normal upon startup (some of them have an empty @time_trigger decorator and I can see the results).
Anyone has any tips on how I can troubleshoot this?