Making a script like argononed.py for Debian bullseye, why is their time.sleep only 0.01 seconds?

Hi,
I tried to install the Argon ONE software functionally running on my Pi4(4GB) with Debian bullseye on an SSD.
It did not work at all, but after some investigation I discovered some differences between my configuration and the one that is probably expected bij the Authors of AgoneOne’s script.

I think I got the adjustments sorted out, summarised under my question, but based on it, I wondered why the time.sleep()s in the def shutdown_check(): in Argone ONE’s script (argononed.py) have a duration of 0.01(seconds) and not 1.0 seconds (before the pulsetime +=)?
(I havent been able to get their code running, so I am just interpreting the code as I can read it)

  1. Using ‘i2cdetect -y i’ (for i in [0,1,2,3, …]) I found out that my Debian set up 4 I2C bus masters with the Case one being the fourth, so with number 3. Hence I had to change the bus initialisation to bus = smbus.SMBus(3)
  2. I guess the new gpiod-subsystem with char-devices is locking the gpio properly and the RPi.GPIO module cannot get acces to it the way it expects. Therefore, in my own script I am using the python3-libgpio module ( import gpiod etc.) which uses the event buffer that became available with it: the events are provided with timestamps, so this might be usefull for distinguishing between the two short presses (=>reboot) press of 3-5 seconds (halt) and more than 5 seconds (Hard shutdown).
    While trying to decide over the exact logic to establish it, I took a look at the logic in ArgonOne’s python script and my question rose.
2 Likes

Probably helps to add the code itself:

def shutdown_check():
  while True:
      pulsetime = 1 
      GPIO.wait_for_edge(shutdown_pin, GPIO.RISING)
      time.sleep(0.01)
      while GPIO.input(shutdown_pin) == GPIO.HIGH:
          time.sleep(0.01)
          pulsetime += 1
      if pulsetime >=2 and pulsetime <=3:
          os.system("reboot")
      elif pulsetime >=4 and pulsetime <=5:
          os.system("shutdown now -h")
1 Like

Hi Hansdej. Hope this finds you well. Were you able to have the script working on your installation? Would you mind sharing it? Having the fan working is what preventing me to move my Home Assistant installation to Debian on Raspberry Pi…

Thanks in advance,
Marcelo

This is definitely odd.

I’m running the Raspberry Pi OS version of Debian Bullseye on several of my raspberry pi 4b devices, and the script installed and runs fine.

They must have made some adjustments to Debian for the GPIO.

I am not using the Pi OS, but a native Debian installation:
https://wiki.debian.org/RaspberryPi

That’ s because I want it to host HomeAssistant(HA) on it, The ppl from HA advise their own OS or if you feel experienced enough a native Debian. (I guess 23 years of using Debian would not classify me as a novice). I guess Marcelo’ s motiviation is similar.

The native Debian is probably a bit different configured than Pi OS which is especially tweaked for the Pi: for one thing the vcgencmd is not available out-of-the-box. I also suspect that a different selection of installed packages can make a difference in configuration.

I did a couple of things before I got my fan working:

  1. Added iomem=relaxed tot the file /boot/firmware/commandline.txt
    as suggested on https://wiki.debian.org/RaspberryPi4.
  2. As root I ran i2cdetect -y 3 (and -y 0 and -y 1 and -y 2 ) and suspected from the presence 1a that that was the correct master.
root@host4ha]/root>i2cdetect -y 3
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- 1a -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --    
  1. As a test: the command (as root or sudo) i2cset -y 3 0x01a 0x00 indeed switched off the fan, and the fan and powerdown started to behave as intended after I changed the smbus initialisation to:bus = smbus.SMBus(3) in:
  • /usr/bin/argononed.py
  • /lib/systemd/system-shutdown/argononed-poweroff.py

Next thing is getting the power button working which is wat my actual question about.

The Argon one’ s power button is connected to GPIO pin 4. In my system’ s logs I observed messages indicating that the powerbutton thread in the /usr/bin/argoneoned.py cannot get access to it via the RPi.GPIO library so I started investigating that with a somewhat simpler push-button setup (on GPIO 18).

RPi.GPIO did not work on that either, but with libgpiod progress started (install python3-libgpiod )
and I am trying to recode the power button part to work with libgpiod instead: This seems to be easier done by using the events from gpiod but when I tried to understand the original code, I got confused by the time.sleep(0.01): looks as if they configure a normal shutdown after 3x0.01 seconds and the hard-one after only 0.05 seconds (instead of 3 seconds and 5 seconds)

I suspect the reason is that the new gpiod driver with more proper char devices /dev/gpiochip0 only allow access to the one process that has claimed it and hence blocks all access for other mechanisms like RPi.GPIO (via the depricated sysfs interface).

2 Likes

Thanks for your response. I will go over it attentively later. Yes, my motivation is the same, except for the fact that I’m really a novice in here… :slight_smile:

Did you have the chance to check which tweaks a guy named Richard did in GitHub - tirtadji-com/Argon-One-Scripts-for-Raspi-running-Debian: Argon One case scripts for Raspberry running Debian 10 for Debian 10?

Thanks again!
Marcelo

Yes, I also found his repo: tried it but it did not get my fan running as I got it with my adjusted I2C master indicator.

He seems to have forked it from a script for an Ubuntu-version and tailored it more to Debian. However it still uses RPi.GPIO which (probably) still is sysfs based and if my suspicion about the kernel’s gpiod driver locking the gpio-pin for others processes is correct the sysfs mechanism could be non-functional.

And because of the the way Debian Bullseye configured my system - with Argon One’s I2C residing at I2C master 3 - the bus=smbus.SMBus(1) still needs to be adjusted.

  • Considering the I2C-bus initialisation code: Personally I would have coded that a little bit different to separate the proper selection of which busmaster from the initialisation of that (selected) master. But that might be just a bit of Pythonic nitpicking:
i2c_master = 1 if rev in [2,3] else 0
i2c_master = 3  # Manual override from original source
bus = smbus.SMBus(i2c_master) 

Looking at his adjustments to the script did help me to find the right debian package names but then I still bumped into the quircks of the evolution from sysfs to gpiod.

FYI: Spiros Papadimitriou released code that builds a proper debian package I tried it unsuccesfully even longer ago, could be useful to look into that again (after further developed insights). He uses a lot of extra imports and I his coding style looked a too bit ‘busy’ with respect to what I am used to read.

Ahh, gotcha.

I run HA, Mosquitto, and Node-Red on the EON in containers running within OMV.

Hi Hans, hope this finds you well. Sorry to revive this but, have you been successful on making the argonone scripts running fine on Debian 11 on RPi?

Thanks in advance,
Marcelo

Hi Marcelo,

I got a test-circuit with a pull-up toggle switch on gpio18 somewhat operational with the gpiod driver: I got gpiod.LineEvent.FALLING_EDGE events upon releasing it. However, while testing it, I observed some extra gpio.LineEvent.RISING_EDGE events with very short intermediate times, probably the switch was a bit whacky or something, but at least I achieved some interacting code.

import gpiod
with gpiod.Chip('gpiochip0') as chip:
    line = chip.get_line(18) # I guessed pwr =>4 
    # Claim the gpio.
    line.request(consumer='togglebutton', type=gpiod.LINE_REQ_EV_BOTH_EDGES)
    #Then some irrelevant code is left out
     while True:
            events = line.event_read_multiple()[::-1]
             # Left out further event handling.

I then tried to see whether I could capture events of the power button of the argon case, however that failed, I am not even sure any more whether gpio 4 is the right one. Maybe I could boot it with a regular Raspbian image to see if that gives something.

On the other hand: Fancontrol is okay, and maybe the power button is not a very necessary feature on a HA-system that is always on. And there still seems to be some hard wiring that powers the case of at a lengthy press of the power button.

Hi Hans, good morning!

I already migrated my HA to Debian 11. Until now it is working ok as the temperatures are kind of mild. But I’m worried because they tend to get higher soon and the system will start to hang once in a while with higher temperatures…

Do you mind sharing the script you used to install the scripts and/or control the fan? Many thanks in advance.

Marcelo

Hi Marcelo,

I have not used my pi4 continuously in the Argon One housing yet. So I have not observed long term thermal performance yet and focussed on understanding the reboot gpio mechanism with some research & debugging investigation scripts first.

In my Post of November I indicated that I had to change the number of i2c_master in the installed /usr/bin/argoneoned.py script (and restart it).

i2c_master = 3  # Manual override from original source
bus = smbus.SMBus(i2c_master) 

Not sure if the temperature feedback works in that script, you mention your system heats up a lot (too much): Does that happen because the ventilatoris not switched on as argononed.py temp_check should do?

With respect to my confusion about the power button, thinkI understand it:
Initial cofusion: I assumed the button was connected directly to gpio4.

Conclusion, insight: After some pressing and event monitoring however I realised that there must be some intermediate electronics that smoothens (button debounching etc.) and translates power button (PWR) events to pulses of different lengths on the Pi’ s GPIO4:
So gpiod.LineEvent.RISING_EDGE and gpiod.LineEvent.FALLING_EDGE events

  • (PWR) two-press: with a distance of 0.02 s on gpio4 ( => reboot )
  • (PWR) hold: longer than 3 s AND shorter than 5s: length of 0.04 s ( => soft shutdown, possibly also with a hardware powerdown timeout)
  • (PWR) hold longer than 5s: No clear observation: possibly a hard power cutby the case’s own electronics.

Is there a place with documentation where I could have read this without my experimental finding out?

Hi Hans, the user manual has a reference to this:

There is also a pin setting that can make power flow directly:


1 Like

Yes:
that user manual is a description at user level, the pulse-lengths difference is an implementation detail of a more technical, electronical level, a bit hiddenin the details of the original script.

Now I am busy with (life & work, but also with) a (re)write of the python3-code that will work on OS-es that use the new gpiod-driver for the power button functionality.

Also investigating the logic of the fan-control. At present my not-so-heavy loaded system seems to stay at a safe temperature of around 45 degC.
With most of the original code intact and a config file that should switch on the fan (somewhat) at those temperatures I see that it does not, so that needs attention/fixing.

Unfortunately, I wasn’t able to make the fan work, even with your tips… I just had my Pi4 hung again because of high temperatures… around 63 Celsius… :frowning: Thinking of abandoning this case because of the lack of support… I’ve been searching this forum but I didn’t notice their team engaged in any conversation… Seems they don’t give much support.

Few steps to test if you ended up in a similar configuration as me:
First thing to answer: is can you get manual control?

  1. Make sure the i2cset & i2cdetect commands are available to the root user: ensure i2c-tools installed.

  2. Investigate how many i2c-host are in your system & which one controls the argon HW:
    Run as root (or sudo /usr/sbin/i2c... )

    • i2cdetect -y 0
    • i2cdetect -y 1
    • i2cdetect -y 2 (if it fails you probably do not need to try further)
    • i2cdetect -y 3
    • (Try if -y4 and further fail?)
      On my system host 3 displays a marked 1a position related to fan control:
      root@host4ha]/root>i2cdetect -y 3
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
      00:                         -- -- -- -- -- -- -- -- 
      10: -- -- -- -- -- -- -- -- -- -- 1a -- -- -- -- -- 
      20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  
      30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
      40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
      50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  
      60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
      70: -- -- -- -- -- -- -- --    
      
  3. Run as root or sudo (with your detected host number after -y):
    i2cset -y 3 0x01a 0x11
    and listen whether your fan switches on: the last hex number is the fan percentage.
    you can use i2cset -y 3 0x01a 0x00 to silence it again.

This way I discovered that the hardcoded hostnumber 0 or 1 in the first lines of argon’s installed script /usr/bin/argoneoned.py does not apply to my setup and I just replaced the case in the first lines with:

 10 if rev == 2 or rev == 3: 
 11     i2c_host = 3
 12 else: 
 13    i2c_host = 0
 14 bus = smbus.SMBus(i2c_host)

You can even take the i2c_host=3 (or other host number) out of the if - else stament if you won’t copy this file to other systems.

And this customisation has to be reapplied every time after a fresh installation from the present Argon1 install script.

Hope this helps you to understand it better.

1 Like

I don’t know what I did wrong the last time… I edited the argononed.py directly and rebooted but didn’t work…
My configuration is just like yours and now I issued the command sudo i2cset -y 3 0x01a 0x11 and it started the fan! :slight_smile: Thanks…

The avg temperature dropped 6 degrees in 25 minutes… I now edited the argononed.py and will boot to see if it turns on the fan automatically.

The blue line is showing how the avg temp has dropped so far and the red line showed when my Pi hung yesterday due to the high temp.

Thanks again!! Best regards!!

1 Like

Actually I found the reason why it didn’t work first time… The argononed service is not starting…So it never triggers the fan…

First time I simply edited the argononed.py and rebooted thinking it would work. I was able to work around it by creating and automation to trigger i2cset every time HA starts

Anyways, this is a different problem! :slight_smile:

Could be you are also suffering from the crashing power button thread, due to Debian’ s use of the new gpiod driver.

Looking at my installed file /usr/bin/argononed.py again, I noticed that I must have switched the sequence of the starts of the shutdown_check (t1) and the temp_check (t2) sometime in the past:

103 try:
104 	t1 = Thread(target = shutdown_check)
105 	t2 = Thread(target = temp_check)
106 	t2.start()
107 	t1.start()
108 except:
109 	t1.stop()
110  	t2.stop()
111  	GPIO.cleanup()

That way the fan control is started up before the script crashes on the gpio, power button related errors.
I suppose commenting out the shutdown_check (t1) stuff (and the GPIO.cleanup() completely would be a correcter workaround.
:rofl: Could be an additional crash on t1.stop() in the except: block prevents the t2.stop() to be reached and (accidentally) leaves the fan-thread running nicely on my system.