This is my effort to implement device sleep support for CM4. I call it quasi-sleep.
Obviously, CM4 does not support true sleep, nor does it have “efficiency” cores to fall back to as Android does, so we only have left with:
Put all processes to sleep to let CPU clock down and prevent any heavy compute while in “sleep”, effectively drawing just idle current [DONE]
Switch off screen backlight [DONE]
Shut down graphics core - I have no idea yet how to do this
Lock the keyboard - dangerous, and I have yet to find a way to do this programmatically. It may be possible to issue a lock so that it can be unlocked with fn-combo?
To implement this, I wrote a simple script called qsleep.sh
#!/bin/bash
# Check if pidstat is already running
if pgrep -x "pidstat" > /dev/null; then
echo "pidstat is already running. Exiting."
echo 2 > /sys/class/backlight/backlight@0/brightness
killall lxde-pi-shutdown-helper
killall qsleep.sh
exit 1
fi
if pgrep -x "cpulimit" > /dev/null; then
echo "resume"
killall cpulimit
echo 2 > /sys/class/backlight/backlight@0/brightness
exit 1
fi
if [ "`cat /sys/class/backlight/backlight@0/brightness`" = "0" ] ; then
echo "resume"
killall cpulimit
echo 2 > /sys/class/backlight/backlight@0/brightness
exit 1
fi
echo 0 > /sys/class/backlight/backlight@0/brightness
# Run pidstat and capture output
output=$(pidstat 1 1)
# Extract the 'Average:' lines from the output
averages=$(echo "$output" | grep '^Average:')
# Parse the output to find PIDs where %CPU > 2
pids=$(echo "$averages" | awk 'BEGIN {FS="[[:space:]]+"} $8 > 2 {print $3}')
# Print the PIDs
echo "PIDs using more than 2% CPU: $pids"
# Apply cpulimit to each PID
for pid in $pids; do
cpulimit -z -b -l 2 --pid=$pid
done
Depends on sysstat and cpulmit:
sudo apt install sysstat cpulimit
To “install” I just replace the default binary that reacts to the power button press. Assuming you saved the script to your $HOME directory as qsleep.sh,
This has the effect of “locking the smartphone” as you would see from your ordinary Android phone, and extends the battery run in my case to about 13 hours or so on a normal smartphone-y use pattern. It can extend even more if I get the cpulimit to throttle processes to 0, but I leave them at 2% CPU to still receive notifications and mail in background.
The script also does not re-check if any new heavy processes pop up, this may also help extending. I will keep developing it and see how long it could sustain on more aggressive settings.
Good work! I use my uConsole for work and normally shut it down between jobs. While battery was never a problem working that way, it wouldn’t last all day if I did leave it on. Today I just put the uConsole to “sleep” while between jobs and the battery lasted all day.
I did change it to return to brightness level 9 when coming out of “sleep” because i’m working outside or bright areas. Great addition to help battery life.
I’m wondering if this sleep support would be helpful on a Devterm as well? Specifically, I’ve had times where I used it sort of a like a server, with it on for long periods of time (days, weeks, etc.) I’ve always kept batteries in it though… I wonder if this would help with the batteries last a bit longer, or if the existing battery management stuff prevents much damage to them over time, with whatever draining and recharge cycle occurs. Or perhaps it would just reduce the power usage/cost to keep charging it, not that it’s much of a concern, as I doubt it uses much power anyway. I’m guessing the benefit would be minimal in both cases, but I also don’t really know much about battery charge cycles.
I wish they could be changed on the fly. But since I use TWM and have a 20Ah pack I don’t really chase power savings any more. (also to be fair I’m waiting for another uConsole and a cable from aliexpress to make my portable one)
But the cpulimit and turning off gpu is interesting. Maybe one could run the script when the screen saver turns off the display automatically?
If you remove the “cpupower” part of it it will definitely help with server scenario. cpupower makes it almost dead slow. As for batteries, I am sure they will deteriorate if you leave them 100% charged, so you may try to change max charge voltage to 70% charged, with latest patches it seems to be configurable, although I haven’t tried
Uhh, yeah, like just that is a good substitute. The script is specifically designed to induce a low-power mode, like the sleep mode in smartphones. Don’t mistake GNOME’s feature with what is being worked on here.
I use this script to lock & enter pseudo-sleep mode.
echo 0 | doas tee /sys/class/backlight/backlight@0/brightness
echo "powersave" | doas tee /sys/devices/system/cpu/cpufreq/policy0/scaling_governor
nmcli r all off
slock &&\
echo 1 | doas tee /sys/class/backlight/backlight@0/brightness &&\
nmcli r all on &&\
echo "performance" | doas tee /sys/devices/system/cpu/cpufreq/policy0/scaling_governor
Anyone know how to turn off the keyboard backlight? I tried xset led off but doesn’t seem to work. I also had a look around in /sys/class /dev/ but didn’t see anything for the keyboard backlight. I thought I would add that to the qsleep script.
@grandrew Thanks for the great work, my uconsole now supports sleep.
For the logout button in the start menu, I want to keep its original behavior: opening the shutdown options dialog. Do you know which config file should I change?
I haven’t figured yet a more ‘polite’ way of installing the qsleep script. Ideally it should be set as power button event hook directly, not as a replacement for the system app that shows poweroff dialog. Currently there is no way I know of to keep the behavior separate with button and menu. You may type poweroff command in terminal to power off…
Yeah, I guess I didn’t read carefully and understand that doing this would break the logout menu. I think personally I would would rather have the qlseep tied to a desktop icon that can be executed by clicking it rather than replace the logout menu. I wonder if I could wrap it in a Python TK script with a menu to choose sleep or logout? I might play with it a bit.