[RPi4, LE12.0.1] Autostart.sh with python script for fan control won't work

  • Hey everyone ! Hope you are well !^^

    I am trying to have a fan control script working at startup. I have a Pi 4 with Libreelec 12.0.1 freshly installed with RPi tools addon. Fan is controlled by PWM on PIN 18.

    The control script runs well when I use the command: python /storage/fan_control.py

    I have created an autostart.sh file and it also works (fan is controlled) when I execute sh /storage/.config/autostart.sh

    When I boot the Raspberry, the fan is always running at full speed which means the python script isn't launched.

    Here is the result of systemctl status kodi-autostart.service:

    I have tried to increase the sleep delay in autostart.sh to 60 and 120 but it does not make any difference.

    Any idea ? :blush:

  • It works !!!! Thank you so much HarryH :D


    For those who wants details, here is the content of fan_control.py:


    Here is the content of autostart.sh:

    Bash
    #!/bin/bash
    (
    sleep 180
    sh /storage/.config/fan_control.sh start
    )&


    Here is the content of fan_control.sh:

  • Hello all,

    I have written a service addon that covers partial code from here. The idea behind the development of a service addon is that it is easy to use, no further scripts are required and it runs ootB. The addon is now part of the Kodinerds repo, the source code you'll find on github: https://github.com/b-jesch/service.joy-it.fancontrol. The addon is primary written for the Joy-IT Multimedia case but runs with other cases and integrated fans connected to GPIO17 too.

    Anyway: While this service addon runs perfect in normal circumstances, it throws an exception when the addon is disabled and enabled again by the user in addon settings.

    Why it's throwing "GPIO busy"? Normally all GPIO should be unlocked (closed) by gpiozero when the service finished - and it does so.

  • Code
    2024-10-06 15:32:15.351 T:1041    debug <general>: CPythonInvoker(1, /storage/.kodi/addons/service.joy-it.fancontrol/fan.py): trigger Monitor abort request
    2024-10-06 15:32:15.352 T:939      info <general>: [Joy-IT Fan Controller 1.0.9] Joy-IT fan control service finished
    2024-10-06 15:32:15.352 T:939     debug <general>: CPythonInvoker(1, /storage/.kodi/addons/service.joy-it.fancontrol/fan.py): script successfully run
    2024-10-06 15:32:15.352 T:939      info <general>: CPythonInvoker(1, /storage/.kodi/addons/service.joy-it.fancontrol/fan.py): waiting on thread 1496097344
    2024-10-06 15:32:20.359 T:1041    error <general>: CPythonInvoker(1, /storage/.kodi/addons/service.joy-it.fancontrol/fan.py): script didn't stop in 5 seconds - let's kill it

    _PvD Guess without any knowledge about gpiozero: GPIO "resource" is not freed because thread is killed instead of terminated gracefully.

  • A new version of the service addon is using lgpio instead gpiozero. This avoids the 'GPIO busy' exception now. Thank you for pointing me in the right direction.

  • Thank you Nathan for the code! Yes, this thread is old but considering what you did, and what I am trying to do, this is the freshest attempt I have seen after a whole day of researching.

    Your code did not work for me. The fan just keeps running. But your nicely written code opened up a lot for me and I appreciate that! I am also using a Noctua Fan, a 5vdc PWM 40mm. To be honest, I am addicted to the Noctua line. I was able to control my fan just fine from the interactive python so I know I have everything hooked up correctly. But for some reason, using your code, the fan just stays on.

    I have not gone after making the speed reporting line from the fan safe for RPI input yet. The specs say the interface works at 5vdc but is tolerant of 3.3vdc on the PWM line. But considering the speed reporting line will still throw 5vdc, I need to either place a level shifter on it, or at least a 3.3vdc zenier diode. Anyway, with that speed line, on maybe GPIO 23 or 24, or 4 maybe? I will be able to see the RPM's. Funny thing, this fan is REAL HARD to tell if it is at 1% or 100% speed without a completely quite room or putting my ear to it. lol

    My only change is that I placed the fan_control.py in a subfolder of storage so it is at ~/scripts/fan_control.py and I updated any references I could find. I probably missed something.

    When I boot, this is what my systemctl status kodi-autostart.service: shows...

    Thanks again for the great offering! I appreciate it!

  • Because it relies on gpiozero you could be affected by this (RPi gpiozero): https://libreelec.tv/2025/01/22/libreelec-nexus-12-0-2/

    To find out where the problem comes from, what is the output of python3 /storage/scripts/fan_control.py ? Are there any exceptions/error messages? Or is this what you mean by?

    Quote

    I was able to control my fan just fine from the interactive python so I know I have everything hooked up correctly.

    If this works, the next step should be to test the wrapper script:
    sh /storage/scripts/fan_control.sh start and sh /storage/scripts/fan_control.sh stop

  • To find out where the problem comes from, what is the output of python3 /storage/scripts/fan_control.py ? Are there any exceptions/error messages? Or is this what you mean by?

    The script works or at least it does not exit with any exceptions. I modified the temperature function slightly in order to output the current temp while running. When I said I was able to control my fan just fine, I meant at the most direct level. From the Python interactive environment, PWMOutputDevice(GPIO18, 25kHz), and changing the value of the resulting object by .01-1. I was actually surprised to see the fan spin at .01 but it IS a Noctua. My guess is the fan's controller has a floor limit for PWM duty cycle but without speed reporting, it's hard to test because the fan is so quite.

    I will check the wrapper script next. Thank you for your help with this! I appreciate it.

  • If this works, the next step should be to test the wrapper script:
    sh /storage/scripts/fan_control.sh start and sh /storage/scripts/fan_control.sh stop

    I sorted it out. I had to set the execute flag on fan_control.py

    Code
     # chmod +x fan_control.py

    And the fan_control.sh is in /storage/.config/ by the way because that appears to be where the OP has it. I don't see that it matters so long as autostart.sh knows where it is. fan_control.sh works fine also and then I was greeted by my system temp every 2 seconds (ooops) so after careful timing of pasting sh /storage/.config/fan_control.sh stop and a quick press of ENTER and the temp reporting stopped. I went back in to fan_control.py and commented out my print statement, came back and did

    sh /storage/.config/fan_control.sh start and it is working. At least the scripts are. Not sure about the fan speed yet. Now I just need to reboot and check for the process with htop.

    Thanks HarryH!

  • You are welcome. It was just a guess on my part that you also moved the fan_control.sh shell script to the subfolder called ‘scripts’. You are right that it makes no difference where it is located as long as the path in the autostart.sh script matches.

    If you set FAN_OFF = 0, the fan should be stopped until the CPU temp value cross the threshold of MIN_TEMP. So you could lower the value MIN_TEMP near to the idle temperature for testing purposes, to trigger ON/OFF earlier and check the functionality of the script.

  • You are welcome. It was just a guess on my part that you also moved the fan_control.sh shell script to the subfolder called ‘scripts’. You are right that it makes no difference where it is located as long as the path in the autostart.sh script matches.

    If you set FAN_OFF = 0, the fan should be stopped until the CPU temp value cross the threshold of MIN_TEMP. So you could lower the value MIN_TEMP near to the idle temperature for testing purposes, to trigger ON/OFF earlier and check the functionality of the script.

    Hey Harry, is there a document or guide out there that could take me through the intricacies of running background Python processes (autostart), how to include modules without PIP, how to write an addon (that accomplishes bringing in modules), how to bake in what I usually need, how to avoid using docker if possible, and the do's and don'ts of LibreElec?

    It's VERY frustrating but I do not complain because I totally get why LibreElec is the way it is. I have had Kodi installed in an OS like Ubuntu, Raspbian, and have had amazing issues. Most of those were years ago, but that is because once I found LibreElec, I just haven't had reason to go back to my previous strategy for a few years.

    But now I have progressed considerably with embedded systems, microcontrollers, hardware (and systems) design, and hungry to add interfaces with a core system. This adventure (this thread) about how to add an aftermarket PWM fan for cooling was just the surface. I want displays, IR, Radio control, power management, HEVC, etc. It's for me, not the public, but I learned today I need to know the inside-info about all of it in order to do it right.

    I apologize if this info is already available and advertised. Just not sure where to look.

    Thanks again!!!

  • Please keep in mind that LE is reduced to just the required components for KODI and hosted in a readonly root filesystem. All additional things (more than a simple script), which are not already available in the base image or as add-on, you want to install should be a package. This can be an add-on package or directly included in a self build image. Many things are documented in the Wiki, at GitHub and also in the code itself.

    As for your example with the Python background process, you can set it up manually as you have already done, or create an KODI add-on (script or service) that does the same. Adding new additional Python libraries can be significantly more difficult and depends heavily on how experienced you already are with compiling and packaging Linux packages.
    Maybe I'm just misunderstanding you. But your wishes/goals sound very ambitious and require a good understanding of hardware/specialised knowledge in some areas. There is no such thing as a simple all-in-one guide. You should also not ignore the fact that not everything can be realised or is necessary on every hardware platform.

    Some starting points: