# HABApp: how do run.once and run.countdown work?

**URL:** <https://community.openhab.org/t/habapp-how-do-run-once-and-run-countdown-work/164936>\
**Category:** 3rd Party\
**Tags:** habapp\
**Created:** [July 13, 2025, 3:23pm UTC](https://community.openhab.org/t/habapp-how-do-run-once-and-run-countdown-work/164936 "2025-07-13T15:23:33Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![TooBee](https://community.openhab.org/user_avatar/community.openhab.org/toobee/32/79015_2.png) [@TooBee](https://community.openhab.org/u/TooBee)\
**Post date:** [July 13, 2025, 3:23pm UTC](https://community.openhab.org/t/habapp-how-do-run-once-and-run-countdown-work/164936/1 "2025-07-13T15:23:33Z")

</div>

The HABApp [documentation](https://habapp.readthedocs.io/en/latest/rule.html#scheduler) states not to use `time.sleep` but `run.once`.  
I have a rule running flawlessly that shuts down the espressomachine after 2,5 hours of idle running that uses a countdown timer.  
Now I would like to write rules to reset bindings that go offline. The Velux binding is a known example. Resetting is described [here](https://community.openhab.org/t/velux-binding-stop-working/156794/8).

The procedure involves shutting down the bridge (power supply off), disabling the bridge, wait some second, then turn power on again, wait again for eleven minutes and enable the bridge.

No complicated functions are necessary, just plain power off and on commands after several seconds, and device disable and enable.

Not sure how this would work I wrote some simple code to see if a simple print command would function after some waiting period defined by `run.once`. It does not. I get the following error:

```python
TypeError: Callable or coroutine function expected! Got "None" (type NoneType)

```

My code is as follows:

```python
import HABApp

class Test(HABApp.Rule):
    def __init__ (self):
        super(). __init__ ()

        self.run.soon(print('Counting to five:'))
        self.run.countdown(5, print('Waited five seconds.'))
    

Test()

```

So I changed it to the following code, thinking that the print function was not allowed and a call to a function was needed. That, unfortunately, did not help.

```python

        self.run.soon(print('Counting to five:'))
        self.run.once(5, self.after)
    

    def after(self):
        self.print('Waited five seconds.')

```

Nor does trying the simple form of my espresso timer script.

```python

        self.run.soon(print('Counting to five:'))
        self.cd = self.run.countdown(5, self.after)
    

    def after(self):
        self.print('Waited five seconds.')
        self.cd.stop()

```

Reading back further in the traceback it looks like the first parameter (the 5 as in five seconds countdown) is incorrect.

` File "/Users/erw/.pyenv/versions/3.11.2/envs/habapp-dev/lib/python3.11/site-packages/HABApp/rule/scheduler/job_builder.py", line 178, in soon [2025-07-13 16:35:37,053] [HABApp.Worker] ERROR | return self.once(None, callback, *args, job_id=job_id, **kwargs) [2025-07-13 16:35:37,053] [HABApp.Worker] ERROR | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [2025-07-13 16:35:37,053] [HABApp.Worker] ERROR | File "/Users/erw/.pyenv/versions/3.11.2/envs/habapp-dev/lib/python3.11/site-packages/HABApp/rule/scheduler/job_builder.py", line 130, in once [2025-07-13 16:35:37,054] [HABApp.Worker] ERROR | return run_func_from_async(self._create_once, instant, callback, *args, job_id=job_id,**kwargs) [2025-07-13 16:35:37,054] [HABApp.Worker] ERROR | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [2025-07-13 16:35:37,054] [HABApp.Worker] ERROR | File "/Users/erw/.pyenv/versions/3.11.2/envs/habapp-dev/lib/python3.11/site-packages/HABApp/core/asyncio.py", line 133, in run_func_from_async [2025-07-13 16:35:37,054] [HABApp.Worker] ERROR | return future.result() [2025-07-13 16:35:37,054] [HABApp.Worker] ERROR | ^^^^^^^^^^^^^^^ [2025-07-13 16:35:37,054] [HABApp.Worker] ERROR | File "/Users/erw/.pyenv/versions/3.11.2/lib/python3.11/concurrent/futures/_base.py", line 456, in result [2025-07-13 16:35:37,054] [HABApp.Worker] ERROR | return self.__get_result() [2025-07-13 16:35:37,054] [HABApp.Worker] ERROR | ^^^^^^^^^^^^^^^^^^^ [2025-07-13 16:35:37,054] [HABApp.Worker] ERROR | File "/Users/erw/.pyenv/versions/3.11.2/lib/python3.11/concurrent/futures/_base.py", line 401, in__get_result [2025-07-13 16:35:37,054] [HABApp.Worker] ERROR | raise self._exception [2025-07-13 16:35:37,054] [HABApp.Worker] ERROR | File "/Users/erw/.pyenv/versions/3.11.2/envs/habapp-dev/lib/python3.11/site-packages/HABApp/core/asyncio.py", line 141, in _async_execute_func [2025-07-13 16:35:37,054] [HABApp.Worker] ERROR | return func(*args, **kwargs) [2025-07-13 16:35:37,054] [HABApp.Worker] ERROR | ^^^^^^^^^^^^^^^^^^^^^ [2025-07-13 16:35:37,054] [HABApp.Worker] ERROR | File "/Users/erw/.pyenv/versions/3.11.2/envs/habapp-dev/lib/python3.11/site-packages/HABApp/rule/scheduler/job_builder.py", line 112, in _create_once [2025-07-13 16:35:37,054] [HABApp.Worker] ERROR | callback = wrap_func(callback, context=self._habapp_rule_ctx) [2025-07-13 16:35:37,054] [HABApp.Worker] ERROR | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [2025-07-13 16:35:37,054] [HABApp.Worker] ERROR | File "/Users/erw/.pyenv/versions/3.11.2/envs/habapp-dev/lib/python3.11/site-packages/HABApp/core/internals/wrapped_function/wrapper.py", line 35, in wrap_func [2025-07-13 16:35:37,054] [HABApp.Worker] ERROR | raise TypeError(msg) [2025-07-13 16:35:37,054] [HABApp.Worker] ERROR | TypeError: Callable or coroutine function expected! Got "None" (type NoneType) [2025-07-13 16:35:37,055] [HABApp.Rules] INFO | Added rule "Test" from rules/test-run_once.py`

That puzzles me greatly: I’m pretty sure that the first parameter can be given as an integer representing a number in seconds to countdown (it is in my espresso countdown rule and it works). In de docs the wording between the `run.once` and `run.countdown` functions are slightly different, and I am not sure if I am passing parameters correctly.  
How should I use `run.once`?

For completeness: I’m running on HABApp 25.06.2

---

<div class="post-metadata">

**Author:** ![Spaceman\_Spiff](https://community.openhab.org/user_avatar/community.openhab.org/spaceman_spiff/32/56883_2.png) [@Spaceman\_Spiff](https://community.openhab.org/u/Spaceman_Spiff)\
**Post date:** [July 14, 2025, 7:16am UTC](https://community.openhab.org/t/habapp-how-do-run-once-and-run-countdown-work/164936/2 "2025-07-14T07:16:56Z")

</div>

You are not passing a function to run.soon but the result of the function call.  
That’s why you get an error.

> [@TooBee](#):
>
> `self.run.soon(print('Counting to five:'))`

I would suggest you move the print out of the self.run.soon
