Can Conditional Function loops use Python asyncio to reduce CPU load?

I think the code I’m using in my conditional functions is causing high CPU loads due to the short Period time I need to set in order for the Function to behave like I need it to… basically I need it to check a measurement every 3 seconds, so the loop is pretty much constantly running, and while that is happening, nothing else is getting the CPU time it needs, and the whole system becomes unstable.
Whenever I have these Conditional Functions activated I end up having problems with Mycodo dropping measurements and the database locking… which inevitably leads to a total system crash.
This undesirable behavior tends to happen more often on slower model Pis like the Pi 3B+ and less on faster models like the Pi 4… which leads me to believe that the Conditional code I’m currently using is really hammering the CPU.
While I believe part of the issue is Python itself, or more to the point Python’s interpreter using more resources compared to a language like C++… I have been reading about using asynchronous coding to possibly reduce CPU loads that can be caused by loops.

Here is an example of one of my Conditional Functions that is causing high CPU loads due to the need to have it constantly checking for the condition every 3 seconds…

from time import sleep
from datetime import datetime
self.loop_count = 0
blinks=8
measurement = self.condition("1c8c49f3") #VPD [Function24] Status LED Conditional
if measurement is not None:  # If a measurement exists
    if measurement < 0.8:  # led is dark blue
        self.run_action("1a811689", value={"payload": "0,0,2"})
    elif measurement >= 0.8 and measurement < 1.3:  # led is green
        self.run_action("1a811689", value={"payload": "0,1,0"})
    elif measurement >= 1.3 and measurement < 1.45:  # led is yellow
        self.run_action("1a811689", value={"payload": "1,1,0"})
    elif measurement >= 1.45:  # led is bright red
        self.run_action("1a811689", value={"payload": "2,0,0"})
else:  # If no measurement exists led is flashing bright blue
    for _ in range(blinks):
        self.run_action("1a811689", value={"payload": "0,0,10"})
        sleep(.75)
        self.run_action("1a811689", value={"payload": "0,0,0"})
        sleep(.75)

I would like to figure out if it would be possible to use asynchronous code (using asyncio and await) to create “pauses” where appropriate in the loop so that other processes can get their fair share of CPU time and prevent the Conditional from hogging the CPU.

Unfortunately I am not really a programmer… I don’t know if I should be placing the “asyncio” and “await” commands in the for loop, or the if-elif loop, or both? Or if I simply need to add some “sleep” timers or “end” or “exit” the loop after each iteration to allow other tasks to have more CPU time?

If anyone with more coding experience has any suggestions or can point me to any relevant code examples on how I can better streamline this code to make it less CPU intensive I’m all ears. I would really like to get these conditionals fixed and working without causing crashes… if I can make that happen I’d like to post a How-To on building a really useful WiFi NeoPixel LED status board that runs on an ESP32 with Tasmota and mimics the Output indicators and gauges in the Mycodo Dashboard… without having to open a browser and load a Dashboard :wink:
Thank you in advance.

Enclose your code in backticks to preserve indentations, so it can be read. Also, I would remove the line numbers, since if anyone wants to copy your code, they will then have to manually remove every line number before it can be executed. Line numbers also interfere with the forum’s ability to properly syntax hilight.

1 Like