@craigb thanks. the recent lambda change seems to help a lot.
However, I’m struggling a bit to get things rolling since it seems that I’m the jupyter kernel is quite suspectible to crashes when using lambdas.
For instance, this following (invalid) snippet causes pyscript kernel to crash. In Python 3 kernel it correctly displays the error. If I use @pyscript_compile decorated lambda, the error is also visible in pyscript kernel.
from functional import seq
seq([1,2,3]).fold_left([], lambda acc, curr: (acc.append(curr))).to_list()
Pyscript kernel (nothing in the UI but this in the terminal):
[I 13:59:59.390 NotebookApp] Saving file at /Untitled4.ipynb
hass_pyscript_kernel: iopub_port k2c: read EOF; shutdown with exit_status=1
hass_pyscript_kernel: iopub_port k2c: read EOF; shutdown with exit_status=1
Python 3 kernel:
1 from functional import seq
----> 2 seq([1,2,3]).fold_left([], lambda acc, curr: (acc.append(curr))).to_list()
AttributeError: 'NoneType' object has no attribute 'append'
I already know my error and understand why the code fails, so it’s not that what I’m worried about. My main point is to report that certain errors, that seem to be related to lambdas, seem to crash pyscript kernel.
I tried installing functional but I get the following error in both regular python and pyscript:
ImportError: cannot import name 'seq' from 'functional'
Strangely, pip installs functional-0.4 but that latest version on PyPi is 0.7.0. It also notes that it is available in both C and python flavors (maybe the issue you have is specific to the C version - have you tried the native python version?). So I can’t replicate the problem without knowing how to install the correct version of the package.
I tried some examples that deliberately fail inside the lambda by calling a method on None, and I get the expected error. For example:
Exception in <jupyter_0> line 1:
list(map(lambda x: x.count("a"), ["a", "aa", "aaa", None]))
^
AttributeError: 'NoneType' object has no attribute 'count'
@craigb Sorry for missing your reply. Didn’t have alerts on…
Anyhow, apologies for omitting important information. The package is called pyfunctional even though it’s imported as functional.
I’ve installed it to the host machine using requirements.txt file in pyscript folder as follows, but since Jupyter is running on my dev laptop, it’s probably not the host machine library that is used in Jupyter.
requirements.txt
pyfunctional
So, I’m running Jupyter on different host than Home Assistant where pyscript runs. Jupyter host’s manually installed version of pyfunctional is in version 1.4.3. I’ve installed it using pip3. The python interpreter I’m using is Python 3.9.1.
I see that pyscript.some_name is easily accessible in lovelace so no need to set a sensor.some_name in addition to pyscript.some_name.
The code I ended up with is shown below and is a bit shorter than the appdaemon code. Mainly because of the timer handling in appdaemon, but also because it is easier to maintain state in pyscript, it seems.
I am new to pyscript and currently testing it out. I can’t get the script below to trig, but the appdaemon code at the bottom works. Does someone see what is wrong with the pyscript code?
This is bug. Good catch! In addition to your workaround, you could mention sensor.passat_status in the trigger expression too, although it’s not intuitive:
@state_trigger("sensor.passat_status.old == 'charging' or sensor.passat_status == 'no such value'")
I just committed a fix, which you can try by using the master version:
Not quite, since sensor.passat_status could be an empty string, or “0”, which will evaluate to False. It would work if you know for sure that sensor.passat_status can’t have those values. To avoid the bug you need to mention sensor.passat_status in the expression, which is why I proposed adding an or clause which would always be False.
Just using a state variable (entity) name on its own has a special meaning - trigger on any change. In that case there is no expression to evaluate, so no True/False test.
One more question: Do the app configuration have to be in configuration.yaml or can I, like its done in appdaemon, have several yaml files in the pyscript directory, one yaml for each app?
I’d imagine that you could use one of the !include_dir_merge_list or !include_dir_merged_namedconstruct in the YAML configuration to implement that. Though I don’t know if the automagic reload when changed thing would still work?
Auto-reload detects changes to any yaml files below the pyscript directory (in addition to .py files). You could put all the configuration in pyscript/config.yaml by doing this in the main config file:
pyscript: !include pyscript/config.yaml
Within that file you could also have additional includes for each app, if you prefer to break them out.
When you change any yaml file below the pyscript directory, the entire yaml configuration will be automatically reloaded, and any config changes to each app’s config will then cause that app to be reloaded. Apps whose config is unchanged will not be reloaded.