sxmo_suspend.sh: port to Python
This commit is contained in:
parent
3e8ad5b899
commit
88ea557cd5
|
@ -93,9 +93,9 @@ let
|
||||||
pkgs = [ "systemd" "xdg-user-dirs" ];
|
pkgs = [ "systemd" "xdg-user-dirs" ];
|
||||||
src = ./hooks;
|
src = ./hooks;
|
||||||
};
|
};
|
||||||
suspend = pkgs.static-nix-shell.mkBash {
|
suspend = pkgs.static-nix-shell.mkPython3Bin {
|
||||||
pname = "sxmo_suspend.sh";
|
pname = "sxmo_suspend.sh";
|
||||||
pkgs = [ "coreutils" "findutils" "gnugrep" "rtl8723cs-wowlan" "time" "util-linux" ];
|
pkgs = [ "rtl8723cs-wowlan" "util-linux" ];
|
||||||
src = ./hooks;
|
src = ./hooks;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/env nix-shell
|
#!/usr/bin/env nix-shell
|
||||||
#!nix-shell -i bash -p coreutils -p findutils -p gnugrep -p rtl8723cs-wowlan -p time -p util-linux
|
#!nix-shell -i python3 -p "python3.withPackages (ps: [ ])" -p rtl8723cs-wowlan -p util-linux
|
||||||
|
|
||||||
# yeah, this isn't technically a hook, but the hook infrastructure isn't actually
|
# yeah, this isn't technically a hook, but the hook infrastructure isn't actually
|
||||||
# restricted to stuff that starts with sxmo_hook_ ...
|
# restricted to stuff that starts with sxmo_hook_ ...
|
||||||
|
@ -20,40 +20,80 @@
|
||||||
# common sources of wakelocks (which one may wish to reduce) include:
|
# common sources of wakelocks (which one may wish to reduce) include:
|
||||||
# - `sxmo_led.sh blink` (every 2s, by default)
|
# - `sxmo_led.sh blink` (every 2s, by default)
|
||||||
|
|
||||||
suspend_time=300
|
import argparse
|
||||||
|
import logging
|
||||||
|
import subprocess
|
||||||
|
import time
|
||||||
|
|
||||||
# TODO: don't do this wowlan stuff every single time.
|
logger = logging.getLogger(__name__)
|
||||||
# - it's costly (can take like 1sec)
|
|
||||||
# - it seems to actually block suspension quite often
|
|
||||||
# - possibly rtl8723cs takes time to apply wowlan changes during which suspension is impossible
|
|
||||||
# alternative is to introduce some layer of cache:
|
|
||||||
# - do so in a way such that WiFi connection state changes invalidate the cache
|
|
||||||
# - because wowlan enable w/o connection may well behave differently than w/ connection
|
|
||||||
# - calculating IP addr from link, and then caching on the args we call our helper with may well suffice
|
|
||||||
doas rtl8723cs-wowlan enable-clean
|
|
||||||
# wake on ssh
|
|
||||||
doas rtl8723cs-wowlan tcp --dest-port 22 --dest-ip SELF
|
|
||||||
# wake on notification (ntfy/Universal Push)
|
|
||||||
doas rtl8723cs-wowlan tcp --source-port 2587 --dest-ip SELF
|
|
||||||
# wake if someone doesn't know how to route to us, because that could obstruct the above
|
|
||||||
# doas rtl8723cs-wowlan arp --dest-ip SELF
|
|
||||||
# specifically wake upon ARP request via the broadcast address.
|
|
||||||
# should in theory by covered by the above (TODO: remove this!), but for now hopefully helps wake-on-lan be more reliable?
|
|
||||||
doas rtl8723cs-wowlan arp --dest-ip SELF --dest-mac ff:ff:ff:ff:ff:ff
|
|
||||||
|
|
||||||
# TODO: wake for Dino (call) traffic
|
SUSPEND_TIME=300
|
||||||
|
|
||||||
echo "calling suspend for duration: $suspend_time"
|
class Executor:
|
||||||
|
def __init__(self, dry_run: bool = False):
|
||||||
|
self.dry_run = dry_run
|
||||||
|
|
||||||
time_start="$(date "+%s")"
|
def exec(self, cmd: list[str], sudo: bool = False, check: bool = True):
|
||||||
irq_start="$(cat /proc/interrupts | grep 'rtw_wifi_gpio_wakeup' | tr -s ' ' | xargs echo | cut -d' ' -f 2)"
|
if sudo:
|
||||||
|
cmd = [ 'doas' ] + cmd
|
||||||
|
|
||||||
rtcwake -m mem -s "$suspend_time" || exit 1
|
logger.debug(" ".join(cmd))
|
||||||
|
if self.dry_run:
|
||||||
|
return
|
||||||
|
|
||||||
irq_end="$(cat /proc/interrupts | grep 'rtw_wifi_gpio_wakeup' | tr -s ' ' | xargs echo | cut -d' ' -f 2)"
|
res = subprocess.run(cmd, capture_output=True)
|
||||||
time_spent="$(( $(date "+%s") - time_start ))"
|
logger.debug(res.stdout)
|
||||||
|
if res.stderr:
|
||||||
|
logger.warning(res.stderr)
|
||||||
|
if check:
|
||||||
|
res.check_returncode()
|
||||||
|
|
||||||
echo "suspended for $time_spent seconds. wifi IRQ count: ${irq_start} -> ${irq_end}"
|
def main():
|
||||||
|
logging.basicConfig()
|
||||||
|
logging.getLogger().setLevel(logging.INFO)
|
||||||
|
|
||||||
sxmo_hook_postwake.sh
|
parser = argparse.ArgumentParser(description="suspend the pinephone to RAM, and configure wake triggers to make that appear more transparent")
|
||||||
|
parser.add_argument("--dry-run", action='store_true', help="print commands instead of executing them")
|
||||||
|
parser.add_argument("--verbose", action='store_true', help="log each command before executing")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.verbose:
|
||||||
|
logging.getLogger().setLevel(logging.DEBUG)
|
||||||
|
|
||||||
|
|
||||||
|
executor = Executor(dry_run=args.dry_run)
|
||||||
|
# TODO: don't do this wowlan stuff every single time.
|
||||||
|
# - it's costly (can take like 1sec)
|
||||||
|
# alternative is to introduce some layer of cache:
|
||||||
|
# - do so in a way such that WiFi connection state changes invalidate the cache
|
||||||
|
# - because wowlan enable w/o connection may well behave differently than w/ connection
|
||||||
|
# - calculating IP addr from link, and then caching on the args we call our helper with may well suffice
|
||||||
|
# and no need to invoke a subprocess here, when it's just python code calling other python code!
|
||||||
|
executor.exec(['rtl8723cs-wowlan', 'enable-clean'], sudo=True)
|
||||||
|
# wake on ssh
|
||||||
|
executor.exec(['rtl8723cs-wowlan', 'tcp', '--dest-port', '22', '--dest-ip', 'SELF'], sudo=True)
|
||||||
|
# wake on notification (ntfy/Universal Push)
|
||||||
|
# executor.exec(['rtl8723cs-wowlan', 'tcp', '--source-port', '2587', '--dest-ip', 'SELF'], sudo=True)
|
||||||
|
# wake if someone doesn't know how to route to us, because that could obstruct the above
|
||||||
|
# executor.exec(['rtl8723cs-wowlan', 'arp', '--dest-ip', 'SELF'], sudo=True)
|
||||||
|
# specifically wake upon ARP request via the broadcast address.
|
||||||
|
# should in theory by covered by the above (TODO: remove this!), but for now hopefully helps wake-on-lan be more reliable?
|
||||||
|
executor.exec(['rtl8723cs-wowlan', 'arp', '--dest-ip', 'SELF', '--dest-mac', 'ff:ff:ff:ff:ff:ff'], sudo=True)
|
||||||
|
|
||||||
|
logger.info(f"calling suspend for duration: {SUSPEND_TIME}")
|
||||||
|
|
||||||
|
time_start = time.time()
|
||||||
|
# irq_start="$(cat /proc/interrupts | grep 'rtw_wifi_gpio_wakeup' | tr -s ' ' | xargs echo | cut -d' ' -f 2)"
|
||||||
|
#
|
||||||
|
executor.exec(['rtcwake', '-m', 'mem', '-s', str(SUSPEND_TIME)], check=False)
|
||||||
|
|
||||||
|
# irq_end="$(cat /proc/interrupts | grep 'rtw_wifi_gpio_wakeup' | tr -s ' ' | xargs echo | cut -d' ' -f 2)"
|
||||||
|
time_spent = time.time() - time_start
|
||||||
|
|
||||||
|
logger.info(f"suspended for {time_spent:.0f} seconds")
|
||||||
|
|
||||||
|
executor.exec(['sxmo_hook_postwake.sh'], check=False)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user