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.
1 Like

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")

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).

1 Like

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: