From 112e7a9548aec9fec6a171e473097335f3c39707 Mon Sep 17 00:00:00 2001 From: Jeff Curless Date: Sat, 10 Jan 2026 19:04:49 -0500 Subject: [PATCH] Latest scripts and such from argon40. These scripts are used by me to determine if there is anything else I want to add to the oneUp environment. --- pythonscript/latest/argon-uninstall.sh | 10 +- pythonscript/latest/argon-versioninfo.sh | 2 +- pythonscript/latest/argonkeyboard.py | 501 +++++++++++++++-------- pythonscript/latest/argononeup.sh | 31 +- pythonscript/latest/argononeupd.py | 27 +- pythonscript/latest/argonpowerbutton.py | 250 +++++------ 6 files changed, 511 insertions(+), 310 deletions(-) diff --git a/pythonscript/latest/argon-uninstall.sh b/pythonscript/latest/argon-uninstall.sh index 2693fcb..43f0367 100644 --- a/pythonscript/latest/argon-uninstall.sh +++ b/pythonscript/latest/argon-uninstall.sh @@ -98,8 +98,14 @@ then sudo systemctl stop argonupsrtcd.service sudo systemctl disable argonupsrtcd.service - sudo systemctl --global stop argononeupsduser.service - sudo systemctl --global disable argononeupsduser.service + for tmpuser in `awk -F: '{ if ($3 >= 1000) print $1 }' /etc/passwd` + do + if [ "$tmpuser" != "nobody" ] + then + sudo -u "$tmpuser" systemctl --user stop argononeupsduser.service + sudo -u "$tmpuser" systemctl --user disable argononeupsduser.service + fi + done # Remove files sudo rm /lib/systemd/system/argononeupsd.service diff --git a/pythonscript/latest/argon-versioninfo.sh b/pythonscript/latest/argon-versioninfo.sh index 9f79080..57fc8ce 100644 --- a/pythonscript/latest/argon-versioninfo.sh +++ b/pythonscript/latest/argon-versioninfo.sh @@ -1,6 +1,6 @@ #!/bin/bash -VERSIONINFO="2509004" +VERSIONINFO="2601003" echo "Version $VERSIONINFO" if [ -z "$1" ] diff --git a/pythonscript/latest/argonkeyboard.py b/pythonscript/latest/argonkeyboard.py index b55c0bb..57ecc91 100644 --- a/pythonscript/latest/argonkeyboard.py +++ b/pythonscript/latest/argonkeyboard.py @@ -11,10 +11,8 @@ from evdev import InputDevice, categorize, ecodes, list_devices from select import select - import subprocess - import sys import os import time @@ -26,12 +24,22 @@ from queue import Queue UPS_LOGFILE="/dev/shm/upslog.txt" KEYBOARD_LOCKFILE="/dev/shm/argononeupkeyboardlock.txt" + +KEYCODE_BRIGHTNESSUP = "KEY_BRIGHTNESSUP" +KEYCODE_BRIGHTNESSDOWN = "KEY_BRIGHTNESSDOWN" +KEYCODE_VOLUMEUP = "KEY_VOLUMEUP" +KEYCODE_VOLUMEDOWN = "KEY_VOLUMEDOWN" +KEYCODE_PAUSE = "KEY_PAUSE" +KEYCODE_MUTE = "KEY_MUTE" + + ################### # Utilty Functions ################### # Debug Logger def debuglog(typestr, logstr): + #return try: DEBUGFILE="/dev/shm/argononeupkeyboarddebuglog.txt" tmpstrpadding = " " @@ -43,19 +51,19 @@ def debuglog(typestr, logstr): def runcmdlist(key, cmdlist): try: - result = subprocess.run(cmdlist, + cmdresult = subprocess.run(cmdlist, capture_output=True, text=True, check=True ) - #debuglog(key+"-result-output",str(result.stdout)) - if result.stderr: - debuglog(key+"-result-error",str(result.stderr)) - #debuglog(key+"-result-code",str(result.returncode)) + #debuglog(key+"-result-output",str(cmdresult.stdout)) + if cmdresult.stderr: + debuglog(key+"-result-error",str(cmdresult.stderr)) + #debuglog(key+"-result-code",str(cmdresult.returncode)) except subprocess.CalledProcessError as e: debuglog(key+"-error-output",str(e.stdout)) - if result.stderr: + if e.stderr: debuglog(key+"-error-error",str(e.stderr)) debuglog(key+"-error-code",str(e.returncode)) except FileNotFoundError: @@ -67,32 +75,33 @@ def runcmdlist(key, cmdlist): debuglog(key+"-error-other", "Other Error") def createlockfile(fname): - try: - if os.path.isfile(fname): - return True - except Exception as checklockerror: - try: - debuglog("keyboard-lock-error", str(checklockerror)) - except: - debuglog("keyboard-lock-error", "Error Checking Lock File") - try: - with open(fname, "w") as txt_file: - txt_file.write(time.asctime(time.localtime(time.time()))+"\n") - except Exception as lockerror: - try: - debuglog("keyboard-lock-error", str(lockerror)) - except: - debuglog("keyboard-lock-error", "Error Creating Lock File") + # try: + # if os.path.isfile(fname): + # return True + # except Exception as checklockerror: + # try: + # debuglog("keyboard-lock-error", str(checklockerror)) + # except: + # debuglog("keyboard-lock-error", "Error Checking Lock File") + # try: + # with open(fname, "w") as txt_file: + # txt_file.write(time.asctime(time.localtime(time.time()))+"\n") + # except Exception as lockerror: + # try: + # debuglog("keyboard-lock-error", str(lockerror)) + # except: + # debuglog("keyboard-lock-error", "Error Creating Lock File") return False def deletelockfile(fname): - try: - os.remove(fname) - except Exception as lockerror: - try: - debuglog("keyboard-lock-error", str(lockerror)) - except: - debuglog("keyboard-lock-error", "Error Removing Lock File") + # try: + # os.remove(fname) + # except Exception as lockerror: + # try: + # debuglog("keyboard-lock-error", str(lockerror)) + # except: + # debuglog("keyboard-lock-error", "Error Removing Lock File") + return True # System Notifcation @@ -147,9 +156,13 @@ def keyboardevent_getdevicepaths(): # Keyboard has EV_KEY (key) and EV_REP (autorepeat) if ecodes.KEY_BRIGHTNESSDOWN in keyeventlist and ecodes.KEY_BRIGHTNESSDOWN in keyeventlist: outlist.append(path) + #debuglog("keyboard-device-keys", path) + #debuglog("keyboard-device-keys", str(keyeventlist)) elif ecodes.KEY_F2 in keyeventlist and ecodes.KEY_F3 in keyeventlist: # Keyboards with FN key sometimes do not include KEY_BRIGHTNESS in declaration outlist.append(path) + #debuglog("keyboard-device-keys", path) + #debuglog("keyboard-device-keys", str(keyeventlist)) tmpdevice.close() except: pass @@ -169,11 +182,32 @@ def keyboardevent_devicechanged(curlist, newlist): pass return False -def keyboardevent_getbrigthnessinfo(defaultlevel=50): +def keyboardevent_getbrigthnesstoolid(): + toolid = 0 + try: + output = subprocess.check_output(["ddcutil", "--version"], text=True, stderr=subprocess.DEVNULL) + lines = output.splitlines() + if len(lines) > 0: + tmpline = lines[0].strip() + toolid = int(tmpline.split(" ")[1].split(".")[0]) + except Exception as einit: + try: + debuglog("keyboard-brightness-tool-error", str(einit)) + except: + debuglog("keyboard-brightness-tool-error", "Error getting tool id value") + + debuglog("keyboard-brightness-tool", toolid) + return toolid + +def keyboardevent_getbrigthnessinfo(toolid, defaultlevel=50): level = defaultlevel try: # VCP code x10(Brightness ): current value = 90, max value = 100 - output = subprocess.check_output(["ddcutil", "getvcp", "10"], text=True, stderr=subprocess.DEVNULL) + if toolid > 1: + # Disabled dynamic sleep "--disable-dynamic-sleep", "--sleep-multiplier", "0.1" + output = subprocess.check_output(["ddcutil", "--disable-dynamic-sleep", "--sleep-multiplier", "0.1", "getvcp", "10"], text=True, stderr=subprocess.DEVNULL) + else: + output = subprocess.check_output(["ddcutil", "--sleep-multiplier", "0.1", "getvcp", "10"], text=True, stderr=subprocess.DEVNULL) debuglog("keyboard-brightness-info", output) level = int(output.split(":")[-1].split(",")[0].split("=")[-1].strip()) except Exception as einit: @@ -188,24 +222,29 @@ def keyboardevent_getbrigthnessinfo(defaultlevel=50): } -def keyboardevent_adjustbrigthness(baselevel, adjustval=5): +def keyboardevent_adjustbrigthness(toolid, baselevel, adjustval=5): curlevel = baselevel if adjustval == 0: return { "level": baselevel } - try: - tmpobj = keyboardevent_getbrigthnessinfo(curlevel) - curlevel = tmpobj["level"] - except Exception: - pass + # Moved reading because ddcutil has delay + # try: + # tmpobj = keyboardevent_getbrigthnessinfo(toolid, curlevel) + # curlevel = tmpobj["level"] + # except Exception: + # pass tmpval = max(10, min(100, curlevel + adjustval)) if tmpval != curlevel: try: debuglog("keyboard-brightness", str(curlevel)+"% to "+str(tmpval)+"%") - runcmdlist("brightness", ["ddcutil", "setvcp", "10", str(tmpval)]) + if toolid > 1: + # Disabled dynamic sleep "--disable-dynamic-sleep", "--sleep-multiplier", "0.1" + runcmdlist("brightness", ["ddcutil", "--disable-dynamic-sleep", "--sleep-multiplier", "0.1", "setvcp", "10", str(tmpval)]) + else: + runcmdlist("brightness", ["ddcutil", "--sleep-multiplier", "0.1", "setvcp", "10", str(tmpval)]) notifymessage("Brightness: "+str(tmpval)+"%", False) except Exception as adjusterr: try: @@ -217,7 +256,7 @@ def keyboardevent_adjustbrigthness(baselevel, adjustval=5): } # DEBUG: Checking - #keyboardevent_getbrigthnessinfo(tmpval) + #keyboardevent_getbrigthnessinfo(toolid, tmpval) return { "level": tmpval } @@ -351,12 +390,12 @@ def keyboardevent_adjustvolume(baselevel, basemuted, adjustval=5): "muted": basemuted } - try: - tmpobj = keyboardevent_getvolumeinfo(deviceidstr, curlevel, curmuted) - curlevel = tmpobj["level"] - curmuted = tmpobj["muted"] - except Exception: - pass + # try: + # tmpobj = keyboardevent_getvolumeinfo(deviceidstr, curlevel, curmuted) + # curlevel = tmpobj["level"] + # curmuted = tmpobj["muted"] + # except Exception: + # pass tmpmuted = curmuted if adjustval == 0: @@ -413,21 +452,197 @@ def keyboardevent_adjustvolume(baselevel, basemuted, adjustval=5): "muted": tmpmuted } +def keyboard_getlayoutfieldvalue(tmpval): + debuglog("keyboard-layout-lang", tmpval) + if "us" in tmpval: + debuglog("keyboard-layout-langout", "us") + return "us" + debuglog("keyboard-layout-langout", "gb") + return "gb" # uk, gb, etc + #return tmpval +def keyboard_getdevicefw(kbdevice): + # info: vendor 0x6080=24704, product 0x8062=32866 + try: + if kbdevice.info.vendor == 24704 and kbdevice.info.product == 32866: + # Special HID + return "314" + except Exception as infoerr: + pass + + return "" -def keyboardevent_check(readq): +def keyboardevemt_keyhandler(readq): + ADJUSTTYPE_NONE=0 ADJUSTTYPE_BRIGHTNESS=1 ADJUSTTYPE_VOLUME=2 ADJUSTTYPE_MUTE=3 ADJUSTTYPE_BATTERYINFO=4 + DATAREFRESHINTERVALSEC = 10 + + PRESSWAITINTERVALSEC = 0.5 + FIRSTHOLDINTERVALSEC = 0.5 + HOLDWAITINTERVALSEC = 0.5 + + + # Get current levels + volumetime = time.time() + curvolumemuted = 0 + curvolume = 50 + + brightnesstime = volumetime + curbrightness = 50 + brightnesstoolid = 0 + + try: + brightnesstoolid = keyboardevent_getbrigthnesstoolid() + except Exception: + brightnesstoolid = 0 + pass + + try: + tmpobj = keyboardevent_getbrigthnessinfo(brightnesstoolid) + curbrightness = tmpobj["level"] + except Exception: + pass + + try: + tmpobj = keyboardevent_getvolumeinfo() + curvolumemuted = tmpobj["muted"] + curvolume = tmpobj["level"] + except Exception: + pass + + while True: + try: + tmpkeymode = 0 + tmpkeycode = "" + adjustval = 0 + adjusttype = ADJUSTTYPE_NONE + + tmpcode = readq.get() # Blocking + try: + codeelements = tmpcode.split("+") + if len(codeelements) == 2: + if codeelements[0] == "PRESS": + tmpkeymode = 1 + else: + tmpkeymode = 2 + tmpkeycode = codeelements[1] + elif tmpcode == "EXIT": + readq.task_done() + return + + except Exception: + tmpkeycode = "" + tmpkeymode = 0 + pass + tmptime = time.time() + if tmpkeycode in [KEYCODE_BRIGHTNESSDOWN, KEYCODE_BRIGHTNESSUP]: + if tmpkeymode == 1 and tmptime - brightnesstime > DATAREFRESHINTERVALSEC: + # Do not update value during hold + try: + tmpobj = keyboardevent_getbrigthnessinfo(brightnesstoolid) + curbrightness = tmpobj["level"] + except Exception: + pass + + adjusttype = ADJUSTTYPE_BRIGHTNESS + if tmpkeycode == KEYCODE_BRIGHTNESSDOWN: + adjustval = -5*tmpkeymode + else: + adjustval = 5*tmpkeymode + brightnesstime = tmptime + elif tmpkeycode in [KEYCODE_MUTE, KEYCODE_VOLUMEDOWN, KEYCODE_VOLUMEUP]: + if tmpkeymode == 1 and tmptime - volumetime > DATAREFRESHINTERVALSEC and tmpkeymode == 1: + # Do not update value during hold + try: + tmpobj = keyboardevent_getvolumeinfo() + curvolumemuted = tmpobj["muted"] + curvolume = tmpobj["level"] + except Exception: + pass + + if tmpkeycode == KEYCODE_MUTE: + adjusttype = ADJUSTTYPE_MUTE + adjustval = 0 + else: + adjusttype = ADJUSTTYPE_VOLUME + if tmpkeycode == KEYCODE_VOLUMEDOWN: + adjustval = -5*tmpkeymode + else: + adjustval = 5*tmpkeymode + volumetime = tmptime + + elif tmpkeycode == KEYCODE_PAUSE: + adjusttype = ADJUSTTYPE_BATTERYINFO + else: + readq.task_done() + continue + + try: + tmplockfilea = KEYBOARD_LOCKFILE+".a" + if createlockfile(tmplockfilea) == False: + # Debug ONLY + # if tmpkeymode == 1: + # debuglog("keyboard-event", "Press Key Code: "+str(tmpkeycode)) + # else: + # debuglog("keyboard-event", "Hold Key Code: "+str(tmpkeycode)) + + if adjusttype == ADJUSTTYPE_BRIGHTNESS: + try: + tmpobj = keyboardevent_adjustbrigthness(brightnesstoolid, curbrightness, adjustval) + curbrightness = tmpobj["level"] + except Exception as brightnesserr: + try: + debuglog("keyboard-brightnessother-error", str(brightnesserr)) + except: + debuglog("keyboard-brightnessother-error", "Error adjusting value") + pass + elif adjusttype == ADJUSTTYPE_VOLUME or adjusttype == ADJUSTTYPE_MUTE: + try: + tmpobj = keyboardevent_adjustvolume(curvolume, curvolumemuted, adjustval) + curvolumemuted = tmpobj["muted"] + curvolume = tmpobj["level"] + except Exception as volumeerr: + try: + debuglog("keyboard-volumeother-error", str(volumeerr)) + except: + debuglog("keyboard-volumeother-error", "Error adjusting value") + pass + elif adjusttype == ADJUSTTYPE_BATTERYINFO: + outobj = battery_loadlogdata() + try: + notifymessage(outobj["power"], False) + except: + pass + deletelockfile(tmplockfilea) + + + except Exception as keyhandlererr: + try: + debuglog("keyboard-handlererror", str(keyhandleerr)) + except: + debuglog("keyboard-handlererror", "Error") + + readq.task_done() + + except Exception as mainerr: + time.sleep(10) + # While True + + +def keyboardevent_monitor(writeq): + READTIMEOUTSECS = 1.0 - PRESSWAITINTERVALSEC = 2 - HOLDWAITINTERVALSEC = 1 + FIRSTHOLDINTERVALSEC = 0.5 + HOLDWAITINTERVALSEC = 0.5 + while True: try: keypresstimestamp = {} @@ -436,6 +651,7 @@ def keyboardevent_check(readq): devicelist = [] devicefdlist = [] devicepathlist = keyboardevent_getdevicepaths() + devicefwlist = [] deviceidx = 0 while deviceidx < len(devicepathlist): @@ -443,33 +659,16 @@ def keyboardevent_check(readq): tmpdevice = InputDevice(devicepathlist[deviceidx]) devicelist.append(tmpdevice) devicefdlist.append(tmpdevice.fd) + devicefwlist.append(keyboard_getdevicefw(tmpdevice)) + #debuglog("keyboard-device-info", devicepathlist[deviceidx]) + #debuglog("keyboard-device-info", str(tmpdevice.info)) except Exception as deverr: try: - debuglog("keyboard-deviceerror-", str(deverr)+ " "+ devicepathlist[deviceidx]) + debuglog("keyboard-deviceerror", str(deverr)+ " "+ devicepathlist[deviceidx]) except: debuglog("keyboard-deviceerror", "Error "+devicepathlist[deviceidx]) deviceidx = deviceidx + 1 - - # Get current levels - curvolumemuted = 0 - curvolume = 50 - - curbrightness = 50 - - try: - tmpobj = keyboardevent_getbrigthnessinfo() - curbrightness = tmpobj["level"] - except Exception: - pass - - try: - tmpobj = keyboardevent_getvolumeinfo() - curvolumemuted = tmpobj["muted"] - curvolume = tmpobj["level"] - except Exception: - pass - try: debuglog("keyboard-update", str(len(devicefdlist))+" Devices") while len(devicefdlist) > 0: @@ -478,9 +677,11 @@ def keyboardevent_check(readq): r, w, x = select(devicefdlist, [], [], READTIMEOUTSECS) for fd in r: found = False + curdevicefw = "" deviceidx = 0 while deviceidx < len(devicefdlist): if devicefdlist[deviceidx] == fd: + curdevicefw = devicefwlist[deviceidx] found = True break deviceidx = deviceidx + 1 @@ -493,131 +694,69 @@ def keyboardevent_check(readq): if event.type == ecodes.EV_KEY: key_event = categorize(event) keycodelist = [] - if event.value == 1 or event.value == 0: - #debuglog("keyboard-event", "Mode:"+str(event.value)+" Key Code: "+str(key_event.keycode)) + # 2 hold, 0 release, 1 press + if event.value == 2 or event.value == 1: + debuglog("keyboard-event", "Mode:"+str(event.value)+" Key Code: "+str(key_event.keycode)) if isinstance(key_event.keycode, str): keycodelist = [key_event.keycode] else: keycodelist = key_event.keycode + else: + continue keycodelistidx = 0 while keycodelistidx < len(keycodelist): tmpkeycode = keycodelist[keycodelistidx] + if tmpkeycode == "KEY_SYSRQ": + # This gets fired for some devices + tmpkeycode = KEYCODE_PAUSE + elif curdevicefw == "314": + # Remap printscreen event as pause and vice versa for special handling + if tmpkeycode == "KEY_PRINTSCREEN": + tmpkeycode = KEYCODE_PAUSE + elif tmpkeycode == KEYCODE_PAUSE: + # Some other key so it will not fire + tmpkeycode = "KEY_PRINTSCREEN" + debuglog("keyboard-event", "FW:" + curdevicefw+ " Key Code: "+tmpkeycode + " Press:"+keycodelist[keycodelistidx]) + + keycodelistidx = keycodelistidx + 1 - if tmpkeycode not in ["KEY_BRIGHTNESSDOWN", "KEY_BRIGHTNESSUP", "KEY_VOLUMEDOWN", "KEY_VOLUMEUP"]: - if event.value == 0: - # Hold for unhandled keys + if tmpkeycode not in [KEYCODE_BRIGHTNESSDOWN, KEYCODE_BRIGHTNESSUP, KEYCODE_VOLUMEDOWN, KEYCODE_VOLUMEUP]: + if event.value == 2: + # Skip hold for unhandled keys continue - elif tmpkeycode not in ["KEY_PAUSE", "KEY_MUTE"]: - # Press for unhandled keys + elif tmpkeycode not in [KEYCODE_PAUSE, KEYCODE_MUTE]: + # Skip press for unhandled keys continue - adjustval = 0 - adjusttype = ADJUSTTYPE_NONE - - if event.value == 1: - # Press - debuglog("keyboard-event", "Press Key Code: "+str(tmpkeycode)) - - tmptime = time.time() - # Guard time for press - if tmpkeycode not in ["KEY_MUTE"]: - # Buttons w/o guard time - keypresstimestamp[tmpkeycode] = tmptime - elif tmpkeycode in keypresstimestamp: - if (tmptime - keypresstimestamp[tmpkeycode]) >= PRESSWAITINTERVALSEC: - keypresstimestamp[tmpkeycode] = tmptime - else: - continue - else: - # First Press - keypresstimestamp[tmpkeycode] = tmptime - - if tmpkeycode == "KEY_BRIGHTNESSDOWN" or tmpkeycode == "KEY_BRIGHTNESSUP": - adjusttype = ADJUSTTYPE_BRIGHTNESS - if tmpkeycode == "KEY_BRIGHTNESSDOWN": - adjustval = -5 - else: - adjustval = 5 - elif tmpkeycode == "KEY_VOLUMEDOWN" or tmpkeycode == "KEY_VOLUMEUP": - adjusttype = ADJUSTTYPE_VOLUME - if tmpkeycode == "KEY_VOLUMEDOWN": - adjustval = -5 - else: - adjustval = 5 - elif tmpkeycode == "KEY_PAUSE": - adjusttype = ADJUSTTYPE_BATTERYINFO - elif tmpkeycode == "KEY_MUTE": - adjusttype = ADJUSTTYPE_MUTE - adjustval = 0 - - elif event.value == 0: - # Hold - debuglog("keyboard-event", "Hold Key Code: "+str(tmpkeycode)) - - tmptime = time.time() + tmptime = time.time() + finalmode = event.value + if event.value == 2: + # Hold needs checking if tmpkeycode in keypresstimestamp: # Guard time before first for hold - if (tmptime - keypresstimestamp[tmpkeycode]) >= PRESSWAITINTERVALSEC: + if (tmptime - keypresstimestamp[tmpkeycode]) >= FIRSTHOLDINTERVALSEC: # Guard time for hold if tmpkeycode in keyholdtimestamp: - if (tmptime - keyholdtimestamp[tmpkeycode]) >= HOLDWAITINTERVALSEC: - keyholdtimestamp[tmpkeycode] = tmptime - else: + if (tmptime - keyholdtimestamp[tmpkeycode]) < HOLDWAITINTERVALSEC: + #debuglog("keyboard-event", "Hold Key Code: "+str(tmpkeycode)+" - Skip") continue - else: - # First Hold event - keyholdtimestamp[tmpkeycode] = tmptime else: + #debuglog("keyboard-event", "Hold Key Code: "+str(tmpkeycode)+" - Skip") continue else: # Should not happen, but treat as if first press - keypresstimestamp[tmpkeycode] = tmptime + finalmode = 1 - if tmpkeycode == "KEY_BRIGHTNESSDOWN" or tmpkeycode == "KEY_BRIGHTNESSUP": - adjusttype = ADJUSTTYPE_BRIGHTNESS - if tmpkeycode == "KEY_BRIGHTNESSDOWN": - adjustval = -10 - else: - adjustval = 10 - elif tmpkeycode == "KEY_VOLUMEDOWN" or tmpkeycode == "KEY_VOLUMEUP": - adjusttype = ADJUSTTYPE_VOLUME - if tmpkeycode == "KEY_VOLUMEDOWN": - adjustval = -10 - else: - adjustval = 10 + #debuglog("keyboard-event", "Mode:"+str(event.value) + " Final:"+str(finalmode)+" " +str(tmpkeycode)) - - - tmplockfilea = KEYBOARD_LOCKFILE+".a" - if createlockfile(tmplockfilea) == False: - # Debug ONLY - if event.value == 1: - debuglog("keyboard-event", "Press Key Code: "+str(tmpkeycode)+ " => "+str(adjusttype)) - else: - debuglog("keyboard-event", "Hold Key Code: "+str(tmpkeycode)+ " => "+str(adjusttype)) - - if adjusttype == ADJUSTTYPE_BRIGHTNESS: - try: - tmpobj = keyboardevent_adjustbrigthness(curbrightness, adjustval) - curbrightness = tmpobj["level"] - except Exception: - pass - elif adjusttype == ADJUSTTYPE_VOLUME or adjusttype == ADJUSTTYPE_MUTE: - try: - tmpobj = keyboardevent_adjustvolume(curvolume, curvolumemuted, adjustval) - curvolumemuted = tmpobj["muted"] - curvolume = tmpobj["level"] - except Exception: - pass - elif adjusttype == ADJUSTTYPE_BATTERYINFO: - outobj = battery_loadlogdata() - try: - notifymessage(outobj["power"], False) - except: - pass - deletelockfile(tmplockfilea) + if finalmode == 1: + keypresstimestamp[tmpkeycode] = tmptime + writeq.put("PRESS+"+tmpkeycode) + else: + keyholdtimestamp[tmpkeycode] = tmptime + writeq.put("HOLD+"+tmpkeycode) except Exception as keyhandleerr: try: @@ -625,9 +764,6 @@ def keyboardevent_check(readq): except: debuglog("keyboard-keyerror", "Error") - else: - # No events received within the timeout - pass newpathlist = keyboardevent_getdevicepaths() if keyboardevent_devicechanged(devicepathlist, newpathlist): debuglog("keyboard-update", "Device list changed") @@ -650,6 +786,10 @@ def keyboardevent_check(readq): except Exception as mainerr: time.sleep(10) # While True + try: + writeq.put("EXIT") + except Exception: + pass if len(sys.argv) > 1: @@ -660,11 +800,18 @@ if len(sys.argv) > 1: else: try: debuglog("keyboard-service", "Service Starting") - keyboardevent_check("") + ipcq = Queue() + t1 = Thread(target = keyboardevemt_keyhandler, args =(ipcq, )) + t2 = Thread(target = keyboardevent_monitor, args =(ipcq, )) + t1.start() + t2.start() + + ipcq.join() + except Exception as einit: try: debuglog("keyboard-service-error", str(einit)) except: debuglog("keyboard-service-error", "Error") - checklockerror(KEYBOARD_LOCKFILE) debuglog("keyboard-service", "Service Stopped") + deletelockfile(KEYBOARD_LOCKFILE) diff --git a/pythonscript/latest/argononeup.sh b/pythonscript/latest/argononeup.sh index 1e65934..ac8791f 100644 --- a/pythonscript/latest/argononeup.sh +++ b/pythonscript/latest/argononeup.sh @@ -185,6 +185,14 @@ daemonconfigfile=/etc/$daemonname.conf lidconfigscript=$INSTALLATIONFOLDER/${basename}-lidconfig.sh + +for TMPDIRECTORY in "/lib/systemd/system" +do + sudo mkdir -p "$TMPDIRECTORY" + sudo chmod 755 $TMPDIRECTORY + sudo chown root:root "$TMPDIRECTORY" +done + echo "Installing/Updating scripts and services ..." if [ ! -f $daemonconfigfile ]; then @@ -402,18 +410,27 @@ then sudo systemctl daemon-reload sudo systemctl enable argononeupd.service sudo systemctl start argononeupd.service - - # Enable and Start User Service(s) - sudo systemctl --global enable argononeupduser.service - sudo systemctl --global start argononeupduser.service - else sudo systemctl daemon-reload sudo systemctl restart argononeupd.service - - sudo systemctl --global restart argononeupduser.service fi +# Enable and Start User Service(s) +for tmpuser in `awk -F: '{ if ($3 >= 1000) print $1 }' /etc/passwd` +do + if [ "$tmpuser" != "nobody" ] + then + if [ "$setupmode" = "Setup" ] + then + sudo -u "$tmpuser" systemctl --user enable argononeupduser.service + sudo -u "$tmpuser" systemctl --user start argononeupduser.service + + else + sudo -u "$tmpuser" systemctl --user restart argononeupduser.service + fi + fi +done + if [ "$CHECKPLATFORM" = "Raspbian" ] then if [ -f "$eepromrpiscript" ] diff --git a/pythonscript/latest/argononeupd.py b/pythonscript/latest/argononeupd.py index 4314e2c..8ea1f0e 100644 --- a/pythonscript/latest/argononeupd.py +++ b/pythonscript/latest/argononeupd.py @@ -131,7 +131,7 @@ def battery_checkupdateprofile(): try: REG_GPIOCONFIG = 0x0A - PROFILE_DATALIST = [0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xAA,0xBE,0xC6,0xB8,0xAE,0xC2,0x98,0x82,0xFF,0xFF,0xCA,0x98,0x75,0x63,0x55,0x4E,0x4C,0x49,0x98,0x88,0xDC,0x34,0xDB,0xD3,0xD4,0xD3,0xD0,0xCE,0xCB,0xBB,0xE7,0xA2,0xC2,0xC4,0xAE,0x96,0x89,0x80,0x74,0x67,0x63,0x71,0x8E,0x9F,0x85,0x6F,0x3B,0x20,0x00,0xAB,0x10,0x00,0xB0,0x73,0x00,0x00,0x00,0x64,0x08,0xD3,0x77,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAC] + PROFILE_DATALIST = [0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xAA,0xBE,0xC6,0xB8,0xAE,0xC2,0x98,0x82,0xFF,0xFF,0xCA,0x98,0x75,0x63,0x55,0x4E,0x4C,0x49,0x98,0x88,0xDC,0x34,0xDB,0xD3,0xD4,0xD3,0xD0,0xCE,0xCB,0xBB,0xE7,0xA2,0xC2,0xC4,0xAE,0x96,0x89,0x80,0x74,0x67,0x63,0x71,0x8E,0x9F,0x85,0x6F,0x3B,0x20,0x00,0xAB,0x10,0xFF,0xB0,0x73,0x00,0x00,0x00,0x64,0x08,0xD3,0x77,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFA] PROFILE_LEN = len(PROFILE_DATALIST) @@ -351,10 +351,17 @@ def battery_check(readq): curnotifycritical = False if device_charging == 0: - if device_battery>99: - statusstr = "Charged" - else: - statusstr = "Charging" + if "Shutting Down" in prevnotifymsg: + os.system("shutdown -c ""Charging, shutdown cancelled.""") + debuglog("battery-shutdown", "Abort") + + if device_battery>99: + # Prevents switching issue + statusstr = "Charged" + curnotifymsg = statusstr + tmpiconfile = tmpiconfile+"charge_"+str(device_battery) + elif device_charging == 0: + statusstr = "Charging" curnotifymsg = statusstr tmpiconfile = tmpiconfile+"charge_"+str(device_battery) else: @@ -367,8 +374,12 @@ def battery_check(readq): curnotifymsg="50%% Battery" elif device_battery > 10: curnotifymsg="20%% Battery" + elif device_battery > 5: + #curnotifymsg="Low Battery" + curnotifymsg="Low Battery: The device may power off automatically soon." + curnotifycritical=True else: - curnotifymsg="Low Battery" + curnotifymsg="CRITICAL BATTERY: Shutting Down in 1 minute" curnotifycritical=True tmpiconfile = tmpiconfile + ".png" @@ -382,7 +393,9 @@ def battery_check(readq): # Send notification if necessary if prevnotifymsg != curnotifymsg: notifymessage(curnotifymsg, curnotifycritical) - + if device_battery <= 5 and device_charging != 0: + os.system("shutdown +1 """+curnotifymsg+".""") + debuglog("battery-shutdown", "Shutdown in 1 minute") prevnotifymsg = curnotifymsg diff --git a/pythonscript/latest/argonpowerbutton.py b/pythonscript/latest/argonpowerbutton.py index 0c19433..484e00c 100644 --- a/pythonscript/latest/argonpowerbutton.py +++ b/pythonscript/latest/argonpowerbutton.py @@ -17,6 +17,79 @@ def argonpowerbutton_debuglog(typestr, logstr): 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 @@ -58,131 +131,76 @@ def argonpowerbutton_getconfigval(keyname, datatype="int"): return -1 return "" -def argonpowerbutton_monitorlid(writeq): - try: - argonpowerbutton_debuglog("lid-monitor", "Starting") - monitormode = True +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 - # Pin Assignments - LINE_LIDMONITOR=27 - try: - # Pi5 mapping - chip = gpiod.Chip('4') - except Exception as gpioerr: - # Old mapping - chip = gpiod.Chip('0') + 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 - lineobj = chip.get_line(LINE_LIDMONITOR) - lineobj.request(consumer="argon", type=gpiod.LINE_REQ_EV_BOTH_EDGES, flags=gpiod.LINE_REQ_FLAG_BIAS_PULL_UP) - while monitormode == True: - hasevent = lineobj.event_wait(10) - if hasevent: - eventdata = lineobj.event_read() - if eventdata.type == gpiod.LineEvent.FALLING_EDGE: - 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 - while lineobj.get_value() == 0: - if targetsecs > 0: - if pulsetimesec >= targetsecs: - argonpowerbutton_debuglog("lid-monitor", "Target Reached, shutting down") - monitormode = False - os.system("shutdown now -h") - break + time.sleep(1) + pulsetimesec += 1 + argonpowerbutton_debuglog("lid-monitor", "Open Detected") + return True - time.sleep(1) - pulsetimesec += 1 - argonpowerbutton_debuglog("lid-monitor", "Open Detected") +def argonpowerbutton_monitorlid(writeq): + LINE_LIDMONITOR=27 + argonpowerbutton_watchline("lid-monitor", writeq, LINE_LIDMONITOR, argonpowerbutton_monitorlidevent) - lineobj.release() - chip.close() - except Exception as liderror: - try: - argonpowerbutton_debuglog("lid-monitor-error", str(liderror)) - except: - argonpowerbutton_debuglog("lid-monitor-error", "Error aborting") - #pass +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) - try: - # Reference https://github.com/brgl/libgpiod/blob/master/bindings/python/examples/gpiomon.py - # Pin Assignments - LINE_SHUTDOWN=4 - try: - # Pi5 mapping - chip = gpiod.Chip('4') - except Exception as gpioerr: - # Old mapping - chip = gpiod.Chip('0') - - lineobj = chip.get_line(LINE_SHUTDOWN) - lineobj.request(consumer="argon", type=gpiod.LINE_REQ_EV_BOTH_EDGES) - while True: - hasevent = lineobj.event_wait(10) - if hasevent: - pulsetime = 0 - eventdata = lineobj.event_read() - if eventdata.type == gpiod.LineEvent.RISING_EDGE: - # Time pulse data - while lineobj.get_value() == 1: - time.sleep(0.01) - pulsetime += 1 - - if pulsetime >=2 and pulsetime <=3: - # Testing - #writeq.put("OLEDSWITCH") - writeq.put("OLEDSTOP") - os.system("reboot") - break - elif pulsetime >=4 and pulsetime <=5: - writeq.put("OLEDSTOP") - os.system("shutdown now -h") - break - elif pulsetime >=6 and pulsetime <=7: - writeq.put("OLEDSWITCH") - lineobj.release() - chip.close() - except Exception: - writeq.put("ERROR") +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) - try: - # Reference https://github.com/brgl/libgpiod/blob/master/bindings/python/examples/gpiomon.py - - # Pin Assignments - LINE_SHUTDOWN=4 - try: - # Pi5 mapping - chip = gpiod.Chip('4') - except Exception as gpioerr: - # Old mapping - chip = gpiod.Chip('0') - - lineobj = chip.get_line(LINE_SHUTDOWN) - lineobj.request(consumer="argon", type=gpiod.LINE_REQ_EV_BOTH_EDGES) - while True: - hasevent = lineobj.event_wait(10) - if hasevent: - pulsetime = 0 - eventdata = lineobj.event_read() - if eventdata.type == gpiod.LineEvent.RISING_EDGE: - # Time pulse data - while lineobj.get_value() == 1: - time.sleep(0.01) - pulsetime += 1 - - if pulsetime >= 10: - writeq.put("OLEDSWITCH") - lineobj.release() - chip.close() - except Exception: - writeq.put("ERROR") +# Testing +#argonpowerbutton_monitor(None)