ubuntuusers.de

Schlaflabor

Dieser Artikel wurde für die folgenden Ubuntu-Versionen getestet:

Dieser Artikel ist größtenteils für alle Ubuntu-Versionen gültig.

Dieser Artikel konkretisiert die Übersicht „Schlafender Rechner“[1] und ergänzt die Artikel Bereitschaft[2] und systemd-sleep[3] durch Vorstellung eines Skripts für die Shell[5][6] Bash, welches eine Zeitreihe für die Entladung des Akkus im Schlaf bequem (d.h. z.B. über Nacht) ermittelt.

Der Titel „Schlaflabor“ für dieses Skript soll andeuten, dass damit ein rudimentäres Schlaflabor für Rechner realisiert wird, er hat aber nichts zu tun mit einem Schlaflabor für Menschen.

Dieses Skript ist außerdem ein Anwendungsbeispiel für den Wecker in der Firmware des Rechners und wie dieser mit rtcwake[4] benutzt werden kann.

Das Skript verwendet Befehle an Komponenten wie UPower, systemd-sleep, rtcwake, grep, date und bc, die bei jedem Ubuntu-System üblicherweise zur Grundinstallation gehören und in den genannten Artikeln beschrieben sind.

Installation

Das Skript als Textdatei kopieren, an einer beliebigen Stelle ablegen, welche die Ausführung von Programmen erlaubt und die Datei ausführbar machen. Die Datei sollte einem normalen Benutzer und dessen primären Gruppe gehören, und als Dateirechte werden 755 vorgeschlagen.

Zur Deinstallation diese Datei einfach löschen.

Funktionsweise

Das Skript ermittelt den aktuellen Ladezustand des Akkus durch Abfrage beim Energiemanager UPower und den aktuellen Zeitpunkt mit date und gibt diese beiden Informationen aus. Danach geht das System für einen begrenzten Zeitraum in den Modus Bereitschaft[2].

Die vorstehende Grundfunktion wird gestartet, sobald der Ladezustand größer als „voll“ gemeldet wird und wird repetiert ausgeführt, solange als Ladezustand größer als „leer“ gemeldet wird. Als Kriterium für „voll“ und „leer“ werden die für UPower definierten Schwellen "Low" (Standard: 20%) und "Critical" (Standard: 5%) abgefragt, die in der Konfigurationsdatei von UPower änderbar sind. Alternativ sind die Schwellen auch als Umgebungsvariablen vorgebbar. Eine weitere Bedingung für die Abarbeitung der Schleife ist natürlich die laufende Entladung des Akkus, die ja gemessen werden soll; sobald diese Bedingung nicht mehr erfüllt ist, wird das Programm beendet.

Bei jedem Schleifendurchlauf wird außerdem mittels rtcwake[4] der Wecker des Rechners gestellt und mittels systemd-sleep[3] die Bereitschaft[2] angefordert. Hierbei wird ein Zähler der Aufwachvorgänge abgefragt um zu verhindern, dass mehrfach der Schlafzustand angefordert wird – leider funktioniert das nicht 100%-ig. Als Zeitpunkt für den Wecker wird der Wert aus der Umgebungsvariable Period oder als Vorgabe 3600 Sekunden nach dem aktuellen Zeitpunkt verwendet.

Bedienung

Man startet das Programm[5] auf der Kommandozeile in einem Terminal[6]. Der Benutzer muss ein Administrator oder root sein. Da einige der im Skript verwendeten Befehle erweiterte Rechte[7] benötigen, prüft das Skript zuerst, ob es als root läuft und wenn dies nicht der Fall ist, startet es sich selber neu als root. Selbstverständlich wird dafür nötigenfalls ein Passwort abgefragt.

Das Programm erfragt vom Kernel aus der Datei /sys/power/mem_sleep die für Bereitschaft[1] möglichen Zustände und erfragt vom Bediener, welcher davon benutzt werden soll. Dieser wird eingestellt.

Das Programm prüft dann, ob die Startbedingungen erfüllt sind:

  • Der Ladezustand muss (im oben beschriebenen Sinne) „voll“ sein und der Betriebszustand muss „entladend“ sein. Wenn die Bedingungen nicht erfüllt sind, ergehen Aufforderungen an den Bediener, die Netzstromversorgung herzustellen bzw. zu trennen.

  • Wenn die Startbedingungen erfüllt sind, startet nach einer weiteren Eingabe die oben beschriebene Prüfschleife.

Zur Beendigung des Programms muss der Bediener

  1. die Netzstromversorgung herstellen und ggf.

  2. den Schlaf des Rechners durch kurzes Drücken des Einschalttasters abbrechen.

Zuletzt wird noch ein Wert für die Entladerate berechnet und ausgegeben. Die Berechnung ist nur richtig für Zeiträume unter 24 h.

Beispiellauf:

$ voll=90 leer=30 Period=900 /tmp/Schlaflabor 
[sudo] Passwort für kB: 
Schlaflabor – Zeitreihe Akku-Entladung im Schlaf aufnehmen.
1) s2idle
2) deep
Welche Methode für Schlaf verwenden? 1
Method=s2idle, Period=900s, voll=90%, leer=30%.
09:15:32: Ladung 98%, fully-charged.
Trenne die Netzstromversorgung!
09:15:37: Ladung 98%, discharging.
Test startet nach Eingabetaste!
09:15:39: Ladung 97%, discharging.
09:30:43: Ladung 97%, discharging.
09:45:44: Ladung 96%, discharging.
…
11:16:25: Ladung 91%, discharging.
11:16:50: Ladung 90%, charging.
Für s2idle: dlnE/dt = 3.4 %/h

Das Skript

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#! /bin/bash -e
# Copyright (c) 2025 kB @ UbuntuUsers.de
# SPDX-License-Identifier: GPL-2.0-or-later

test $UID = 0 || exec sudo env Period=${Period:=3600} voll=$voll leer=$leer $0
echo Schlaflabor  Zeitreihe Akku-Entladung im Schlaf aufnehmen.	>&2

PS3='Welche Methode für Schlaf verwenden? '
select Method in $( sed 'y/[]/  /' /sys/power/mem_sleep )
  do test -n "$Method" && break ; done
test -z "$Method" || echo $Method > /sys/power/mem_sleep

shopt -s lastpipe
grep  ^Percentage /etc/UPower/UPower.conf	|
  while read
  do	case $REPLY
  	  in (*Low*)		: ${voll:=${REPLY#*=}}
  	  ;; (*Critical*)	: ${leer:=${REPLY#*=}}
  	esac
done

echo Method=$Method, Period=${Period}s, voll=$voll%, leer=$leer%.	>&2

getBatState()
{ upower -i /org/freedesktop/UPower/devices/battery_BAT0 | grep -e percentage -e state	|
    while read Name Wert ; do printf -v ${Name%:} '%s' ${Wert%'%'} ; done
  date "+%T: Ladung $percentage%%, $state."
}

until	getBatState
	(( voll < percentage )) && test $state = discharging	# voll geladen und entladend
do	if	(( voll < percentage ))
	then	test   $state = discharging	|| echo Trenne die Netzstromversorgung!
	else	echo Warte auf über $voll%.
		! test $state = discharging	|| echo Schliesse Netzstromversorgung an!
	fi
	sleep 5
done

Minutes()
{ local NOW=$( date +%T )
  echo $(( ( 1440 + 60 * 10#${NOW::2} + 10#${NOW:3:2} - ${1:-0} ) % 1440 ))
}

read -p 'Test startet nach Eingabetaste! '
N_last=-1
rtcwake -m disable	>/dev/null
while	getBatState
	(( leer < percentage )) && test $state = discharging	# noch geladen und entladend
do	read N </sys/power/suspend_stats/success
	if	(( N_last < 0 ))
	then	Rate=$percentage ; dt=$( Minutes )
	fi
	if	(( N_last < N ))
	then	rtcwake -m no -s $Period && systemctl suspend -i && N_last=$N || true
	fi		1>/dev/null 2>/dev/null
	sleep 5
done
bc <<< "scale = 1 ; ( $Rate - $percentage ) * 60 / $( Minutes $dt )" | read Rate
echo "Für $Method: dlnE/dt = $Rate %/h"

Diese Revision wurde am 1. März 2025 09:02 von kB erstellt.
Die folgenden Schlagworte wurden dem Artikel zugewiesen: System, Hardware, Bereitschaft, Suspend