Each script is run inside the thread worker pool that also handles all synchronous work for Home Assistant components.
Ouch, so sleeping or delaying in a script would impact HA ( at least that thread ). Not just be limited to the python_scripts that might be running…
Correct, and that’s why we don’t support sleep. You could create a script that implements a delay if you want to call actions in the future.
Please add datetime! That was one of the first things I tried to do. I can think of quite a few things I’d do in python vs the current yaml.
The re (regexp) module would be nice as well.
I’m quite busy, so probably don’t have time to address certain features anytime soon. Pull requests are welcome
Import module and expose as local:
https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/python_script.py#L98-L102
Then add a test to verifiy that it works:
https://github.com/home-assistant/home-assistant/blob/dev/tests/components/test_python_script.py#L154-L166
I understand why you would want to limit sleep calls, but I feel that some way to introduce short delays in a script is very important. I also realize that you are not trying to recreate AppDaemon or replace the purpose of custom components. The python scripting functionality is an excellent feature between yaml scripting and either of those–the ability to create scripts that are slightly more complex that could otherwise be easily done in yaml, without having to go all the way to AppDaemon or custom components is a huge step in the right direction. But ideally, what is possible in a python script should not be a subset of what is possible in a yaml script, and with the absence of a delay function in python script, it turns out that way.
An idea: If you don’t want to allow sleep calls, what about exposing a delay service, so that a blocking call could be made to effect a short delay? Calling a blocking delay service wouldn’t be significantly different than calling any other blocking service, in that either way the script is waiting until the call completes.
Such constructions as you describe are only possible with async and we chose to keep all scripts sync.
OK. I guess it’s time to learn AppDaemon.
How do we change the logger level for python_script
to info
so that we can use logger.info() for debugging? I tried:
logger:
homeassistant.components.python_script: warning
But that is not working, I get:
2017-07-08 17:01:34 ERROR (MainThread) [homeassistant.config] Invalid config for [logger]: [homeassistant.components.python_script] is an invalid option for [logger]. Check: logger->logger->homeassistant.components.python_script. (See /config/configuration.yaml, line 99). Please check the docs at https://home-assistant.io/components/logger/
2017-07-08 17:01:34 ERROR (MainThread) [homeassistant.setup] Setup failed for logger: Invalid config.
When I run the script, I see the following:
2017-07-08 16:57:25 INFO (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: domain=python_script, service=light_counter, service_data=, service_call_id=1984197328-15>
2017-07-08 16:57:25 INFO (SyncWorker_10) [homeassistant.components.python_script] Executing light_counter.py: {}
2017-07-08 16:57:25 INFO (MainThread) [homeassistant.core] Bus:Handling <Event service_executed[L]: service_call_id=1984197328-15>
Sounds like homeassistant.components.python_script
should work, but it is not
Check the logger documentation for the correct format
Oops missed the logs
. Here’s the right way for those who are looking:
logger:
default: error
logs:
homeassistant.components.python_script: info
For non-trivial conversions between data access to the math library (math.*) is needed.
How about calling a service that starts a script that has a delay in it. Then one the scripts delay has been satisfied, it would start the next part of the python automation. It’ sa hac, but it’s something.
@turboc: Thanks for the idea. I had thought of something along those lines, but it was too much of a hack. I had hoped to make this work without needing to add AppDaemon, but that’s what I did and it works fine (at the “expense” of needing to have a separate process to take care of).
Understood. If you need any help with AD, just let us know. Even there you are doing the same thing, you are just using a run_in or run_at command to do your delay. Don’t use a sleep over there either.
@turboc: Yes, I’m using run_in for long (up to 12-second) delays, but I also have a sequence that needs very short (up to 1-second) delays between sending commands to various devices, and for those I am using sleep(). I understand the potential risk, but this process runs rarely and never more than one instance. It’s working well.
I would love to see support for datetime
so I can use timestamps in my python_script
.
I’ve changed my mind. If people want to implement sleep, they can. We should just make sure we add a warning in the docs that you are blocking a limited amount of workers.
A pull request to expose both the datetime and time modules is welcome.
How about dicts?