Files
argon40-battery-display/pythonscript/kickstarter/argonpowerbutton_libgpiod.py
Jeff Curless 7cb53cc8f1 Add the default set python flles that Argon40 uses.
The files being uploaded are the current versions of the files from
argon40.  These files are being archived as I want to be able to
reference them from time to time.  Also I can compare the files that
were ship with the proto type.
2026-02-01 16:14:00 -05:00

207 lines
5.9 KiB
Python

# For Libreelec/Lakka, note that we need to add system paths
# import sys
# sys.path.append('/storage/.kodi/addons/virtual.rpi-tools/lib')
import gpiod
import os
import time
# Debug Logger
def argonpowerbutton_debuglog(typestr, logstr):
try:
DEBUGFILE="/dev/shm/argononegpiodebuglog.txt"
tmpstrpadding = " "
with open(DEBUGFILE, "a") as txt_file:
txt_file.write("["+time.asctime(time.localtime(time.time()))+"] "+typestr.upper()+" "+logstr.strip().replace("\n","\n"+tmpstrpadding)+"\n")
except:
pass
def argonpowerbutton_getvalue(lineobj,lineid):
if lineid is not None:
tmpval = lineobj.get_value(lineid) != gpiod.line.Value.INACTIVE
if tmpval == False:
return 0
return 1
return lineobj.get_value()
def argonpowerbutton_watchline(debugname, dataq, lineid, callback):
monitormode = True
argonpowerbutton_debuglog(debugname, "Starting")
# Pi5 mapping, 0 for older
chippath = '/dev/gpiochip4'
try:
chip = gpiod.Chip(chippath)
except Exception as gpioerr:
try:
# Old mapping
chippath = '/dev/gpiochip0'
chip = gpiod.Chip(chippath)
except Exception as gpioolderr:
chippath = ""
if len(chippath) == 0:
argonpowerbutton_debuglog(debugname+"-error", "Unable to initialize GPIO")
try:
dataq.put("ERROR")
except:
pass
return
# Monitoring starts
try:
try:
# Reference https://github.com/brgl/libgpiod/blob/master/bindings/python/examples/gpiomon.py
lineobj = chip.get_line(lineid)
if lineid == 27:
lineobj.request(consumer="argon", type=gpiod.LINE_REQ_EV_BOTH_EDGES, flags=gpiod.LINE_REQ_FLAG_BIAS_PULL_UP)
else:
lineobj.request(consumer="argon", type=gpiod.LINE_REQ_EV_BOTH_EDGES)
while monitormode == True:
hasevent = lineobj.event_wait(10)
if hasevent:
eventdata = lineobj.event_read()
monitormode = callback(eventdata.type == gpiod.LineEvent.RISING_EDGE, lineobj, dataq, None)
lineobj.release()
chip.close()
except Exception:
# https://github.com/brgl/libgpiod/blob/master/bindings/python/examples/watch_line_rising.py
configobj = {lineid: gpiod.LineSettings(direction=gpiod.line.Direction.INPUT, edge_detection=gpiod.line.Edge.BOTH)}
if lineid == 27:
configobj = {lineid: gpiod.LineSettings(direction=gpiod.line.Direction.INPUT, edge_detection=gpiod.line.Edge.BOTH, bias=gpiod.line.Bias.PULL_UP )}
with gpiod.request_lines(
chippath,
consumer="argon",
config=configobj,
) as request:
while monitormode:
# Blocks until at least one event is available
for event in request.read_edge_events():
monitormode = callback(event.event_type == event.Type.RISING_EDGE, request, dataq, event.line_offset)
except Exception as monitorerror:
try:
argonpowerbutton_debuglog(debugname+"-error", str(monitorerror))
except:
argonpowerbutton_debuglog(debugname+"-error", "Error aborting")
try:
dataq.put("ERROR")
except:
pass
# This function is the thread that monitors activity in our shutdown pin
# The pulse width is measured, and the corresponding shell command will be issued
def argonpowerbutton_getconfigval(keyname, datatype="int"):
keyname = keyname.lower()
fname = "/etc/argononeupd.conf"
try:
with open(fname, "r") as fp:
for curline in fp:
if not curline:
continue
tmpline = curline.replace(" ", "").replace("\t", "")
if not tmpline:
continue
if tmpline[0] == "#":
continue
tmppair = tmpline.split("=")
if len(tmppair) != 2:
continue
tmpvar = tmppair[0].lower()
if tmpvar != keyname:
continue
try:
if datatype == "int":
return int(tmppair[1])
elif datatype == "float":
return float(tmppair[1])
return tmppair[1]
except:
continue
except:
pass
if datatype == "int":
return -1
elif datatype == "float":
return -1
return ""
def argonpowerbutton_monitorlidevent(isrising, lineobj, writeq, lineid):
if isrising == False:
targetsecs = argonpowerbutton_getconfigval("lidshutdownsecs")
if targetsecs > 0:
argonpowerbutton_debuglog("lid-monitor", "Close Detect; Wait for :"+str(targetsecs))
else:
argonpowerbutton_debuglog("lid-monitor", "Close Detected; Do nothing")
# Time pulse data
time.sleep(1)
pulsetimesec = 1
# 0 - Lid is closed, 1 - Lid is open
while argonpowerbutton_getvalue(lineobj, lineid) == 0:
if targetsecs > 0:
if pulsetimesec >= targetsecs:
argonpowerbutton_debuglog("lid-monitor", "Target Reached, shutting down")
monitormode = False
os.system("shutdown now -h")
return False
time.sleep(1)
pulsetimesec += 1
argonpowerbutton_debuglog("lid-monitor", "Open Detected")
return True
def argonpowerbutton_monitorlid(writeq):
LINE_LIDMONITOR=27
argonpowerbutton_watchline("lid-monitor", writeq, LINE_LIDMONITOR, argonpowerbutton_monitorlidevent)
def argonpowerbutton_monitorevent(isrising, lineobj, writeq, lineid):
pulsetime = 0
if isrising == True:
# Time pulse data
while argonpowerbutton_getvalue(lineobj, lineid) == 1:
time.sleep(0.01)
pulsetime += 1
if pulsetime >=2 and pulsetime <=3:
# Testing
#writeq.put("OLEDSWITCH")
writeq.put("OLEDSTOP")
os.system("reboot")
return False
elif pulsetime >=4 and pulsetime <=5:
writeq.put("OLEDSTOP")
os.system("shutdown now -h")
return False
elif pulsetime >=6 and pulsetime <=7:
writeq.put("OLEDSWITCH")
return True
def argonpowerbutton_monitor(writeq):
LINE_SHUTDOWN=4
argonpowerbutton_watchline("button", writeq, LINE_SHUTDOWN, argonpowerbutton_monitorevent)
def argonpowerbutton_monitorswitchevent(isrising, lineobj, writeq, lineid):
pulsetime = 0
if isrising == True:
# Time pulse data
while argonpowerbutton_getvalue(lineobj, lineid) == 1:
time.sleep(0.01)
pulsetime += 1
if pulsetime >= 10:
writeq.put("OLEDSWITCH")
return True
def argonpowerbutton_monitorswitch(writeq):
LINE_SHUTDOWN=4
argonpowerbutton_watchline("button-switch", writeq, LINE_SHUTDOWN, argonpowerbutton_monitorswitchevent)
# Testing
#argonpowerbutton_monitor(None)