Wie wechselt man automatisch vom Standby-Modus in den Ruhezustand?

53

Ist es möglich, Ubuntu von Suspend in den Ruhezustand zu versetzen, auch bekannt als "Suspend Sedation"?

Ich suche
Folgendes : Wenn ich den Deckel schließe, wird der Laptop in den Standby-Modus versetzt. Wenn ich ihn dann nach einer festgelegten Zeit (auch wenn der Akku stark ist) immer noch nicht benutze, sollte er sich selbst in den Ruhezustand versetzen, um Akkustrom zu sparen.

Zum Beispiel ist mein Laptop so eingerichtet, dass er in den Standby-Modus wechselt, sobald ich den Deckel schließe. Wenn ich es dann den ganzen Tag nicht benutze, wird der Akku leer, da die Hardware auch im Suspend-Modus noch einen geringen Strom verbraucht und sich der Akku schließlich entlädt. Ich möchte, dass ich Ubuntu mitteilen kann, dass es nach einigen Stunden Inaktivität auch dann in den Ruhezustand versetzt werden muss, wenn es angehalten ist.

Windows kann das. Ubuntu kann so programmiert werden, dass es mit dem Timer in den Standby- oder Ruhezustand wechselt, aber nicht beides.

Sergey Stadnik
quelle
Bei meinen Recherchen habe ich den gleichen Linux Mint-Thread gefunden, aber "Suspend Sedation" ist kein offizieller Microsoft-Begriff für diese Funktion und wurde, soweit ich das beurteilen kann, vom Linux Mint-Forumbenutzer erfunden, der ihn erwähnt hat.
ayan4m1
Gibt es einen besseren Namen für diese Funktion?
Sergey Stadnik
Soweit ich das beurteilen kann, gibt es keinen allgemein akzeptierten Namen für das Feature. "Hybrid Suspend" wird von einigen verwendet, "Suspend Sedation" wird von diesem einen Linux Mint-Forumbenutzer verwendet, und ich habe "Hibernate and Suspend" gehört, um auf den Prozess vorher Bezug zu nehmen. Microsoft nennt es offiziell "hybrider Schlaf", zumindest für Windows 7.
ayan4m1
2
@ ayan4m1 Mir ist klar, dass dies eine alte Frage ist, aber ich denke, es ist wichtig, dies zu klären. Der Ruhezustand ist nicht dasselbe wie "Ruhezustand und Ruhezustand nach einer bestimmten Zeit". Hybridschlaf wird einfach in den Ruhezustand versetzt, wenn der Akku leer wird. Für das vom OP beschriebene Verhalten muss der Hybrid-Sleep nicht aktiviert sein.
Paul

Antworten:

20

In Ubuntu 18.04 ist es viel einfacher. In systemd gibt es einen neuen Modus Suspend-Then-Hibernate . Um diese Funktion zu verwenden, müssen Sie eine Datei /etc/systemd/sleep.conf mit dem nächsten Inhalt erstellen :

[Sleep]
HibernateDelaySec=3600

Dann können Sie es per Befehl testen:

sudo systemctl suspend-then-hibernate

Sie können bearbeiten HibernateDelaySec, um die Verzögerung des Ruhezustands zu verringern.


Wenn alles funktioniert, können Sie die Lid Close Action ändern. Dazu müssen Sie die Datei /etc/systemd/logind.conf bearbeiten

Sie müssen die Option finden HandleLidSwitch=, das Kommentarzeichen entfernen und zu wechseln HandleLidSwitch=suspend-then-hibernate. Dann müssen Sie den systemd-logind-Dienst mit dem nächsten Befehl neu starten (Warnung! Ihre Benutzersitzung wird neu gestartet):

sudo systemctl restart systemd-logind.service

Das ist alles! Jetzt können Sie diese schöne Funktion verwenden.

PRIHLOP
quelle
Das war genau richtig. Verwendung unter Pop! _OS 18.10 (auch bekannt als Ubuntu 18.10).
Eduncan911
Genial, danke! Beeinflusst sleep.conf in irgendeiner Weise auch den Ruhezustand oder wirkt es sich nur auf den Ruhezustand aus?
user2428107
@ user2428107 Weitere
Informationen zu
35

Die Lösung hierfür ist einfach. Beim Anhalten und Fortsetzen führt das Programm pm-suspend zunächst eine Reihe von Skripten in /etc/pm/sleep.dund aus /usr/lib/pm-utils/sleep.d. Meine Lösung besteht also darin, ein Skript hinzuzufügen, das Folgendes ausführt:

  1. Notieren Sie nach dem Anhalten die aktuelle Uhrzeit und registrieren Sie ein Weckereignis mit rtcwake.
  2. Überprüfen Sie nach dem Fortsetzen die aktuelle Zeit mit der von oben aufgezeichneten Zeit. Wenn genügend Zeit verstrichen ist, sind wir wahrscheinlich aufgrund des Ereignisses des RTC-Timers aufgewacht. Andernfalls sind wir aufgrund eines Benutzerereignisses (z. B. Öffnen des Laptop-Bildschirms) früh aufgewacht.
  3. Wenn wir aufgrund des RTC-Timers aufgewacht sind, geben Sie sofort den Befehl "pm-hibernate" aus, um in den Ruhezustand zu wechseln.

Hier ist ein Skript, das dies tut. Benennen Sie es 0000rtchibernateund platzieren Sie es im /etc/pm/sleep.dVerzeichnis (0000 ist wichtig, damit das Skript beim Anhalten zuerst und beim Fortsetzen zuletzt ausgeführt wird).

#!/bin/bash
# Script name: /etc/pm/sleep.d/0000rtchibernate
# Purpose: Auto hibernates after a period of sleep
# Edit the "autohibernate" variable below to set the number of seconds to sleep.
curtime=$(date +%s)
autohibernate=7200
echo "$curtime $1" >>/tmp/autohibernate.log
if [ "$1" = "suspend" ]
then
    # Suspending.  Record current time, and set a wake up timer.
    echo "$curtime" >/var/run/pm-utils/locks/rtchibernate.lock
    rtcwake -m no -s $autohibernate
fi

if [ "$1" = "resume" ]
then
    # Coming out of sleep
    sustime=$(cat /var/run/pm-utils/locks/rtchibernate.lock)
    rm /var/run/pm-utils/locks/rtchibernate.lock
    # Did we wake up due to the rtc timer above?
    if [ $(($curtime - $sustime)) -ge $autohibernate ]
    then
        # Then hibernate
        rm /var/run/pm-utils/locks/pm-suspend.lock
        /usr/sbin/pm-hibernate
    else
        # Otherwise cancel the rtc timer and wake up normally.
        rtcwake -m no -s 1
    fi
fi

Hoffentlich kommt dieser Code auf diesem Message Board durch (dies ist mein erster Beitrag hier).

Ändern Sie den Timeout-Wert autohibernate=7200oben, bis Sie nach wie vielen Sekunden in den Ruhezustand wechseln. Der aktuelle Wert oben beträgt 2 Stunden. Beachten Sie, dass Ihr Laptop zu diesem Zeitpunkt einige Sekunden lang aufwacht, während die Ruhezustandsfunktion ausgeführt wird.

Wenn Sie also vorhaben, Ihren Laptop in eine Tasche zu legen, setzen Sie ihn nicht aus, sondern schalten Sie ihn in den Ruhezustand. Andernfalls könnte Ihr Laptop in esp überhitzen. Wenn es sich in einem eng anliegenden Schuber befindet (obwohl es nur für ein paar Sekunden bis eine Minute eingeschaltet ist).

Ich habe diese Methode in den letzten Tagen angewendet, bis jetzt war sie erfolgreich (und hat mich heute Nachmittag vor einer leeren Batterie bewahrt). Genießen.

Für andere Linux-Distributionen, die systemdUbuntu und neuere Versionen verwenden, sollte dies weiterhin funktionieren, wenn Sie das Skript in /usr/lib/systemd/system-sleepstatt platzieren /etc/pm/sleep.d. Ersetzen Sie den /usr/sbin/pm-hibernateBefehl auch durch systemctl hibernate.

Derek Pressnall
quelle
Es hat hier funktioniert, aber erst nachdem ich die Datei so geändert habe, dass X zu allen hinzugefügt wird. Ich bin ein riesiger Neuling und ich habe 2 Tage gebraucht, um das herauszufinden. Sehr gutes Skript und ich hoffe, das hilft jedem, der Probleme hat. Danke.
2
Dies würde ein nützliches Ubuntu / Debian-Paket ergeben!
Petr Pudlák
Ich frage mich nur: Gilt das noch für Ubuntu 13.04? Ich brauche genau diese Lösung, aber ich möchte mich nicht mit dem Laptop meiner Frau anlegen, wenn sich herausstellt, dass es bei neueren Versionen zu Problemen kommt.
Torben Gundtofte-Bruun
Danke für das Drehbuch. Funktioniert gut für mich auf Ubuntu 14.04! Eine Verbesserung wäre, wenn der Laptop im Ruhezustand prüfen könnte, ob er an das Stromnetz angeschlossen ist. In diesem Fall möchte ich, dass es erneut angehalten wird, anstatt in den Ruhezustand zu wechseln. Das Wiederherstellen aus dem Ruhezustand dauert länger und ich brauche es nicht wirklich, um in den Ruhezustand zu
wechseln,
Ich danke dir sehr!!!! Dieses Drehbuch ist Magie, von der ich geträumt habe !!
Yanpas
12

Um in einfachen Worten zu erklären, wie dies funktioniert (ähnlich wie bei Windows): Der Computer wird nicht aus dem Standby-Modus geweckt, wenn der Akku fast leer ist, um den Status des Computers auf der Auslagerungspartition zu speichern. Er speichert alles sofort auf der Auslagerungspartition Im Standby-Modus und wenn der Akku leer ist, wird er durch Laden des Status von der Swap-Partition wiederhergestellt (wie im Ruhezustand).

AFAIK Linux wird / sollte Hybrid-Standby / Ruhezustand anstelle von "normalem" Standby verwenden, wenn es weiß, dass es für Ihre Hardware funktioniert. Es ist auch möglich, dass dies momentan wegen zu vieler Bugs oder so deaktiviert ist ...;)

Wenn Sie gerne experimentieren, können Sie vielleicht sehen, ob Sie mit pm-suspend-hybrid gute Ergebnisse erzielen .

Wenn das Folgende besagt, dass Sie Glück haben, wird der hybride Suspend theoretisch auf Ihrem System unterstützt:

pm-is-supported --suspend-hybrid && echo "you're lucky"
JanC
quelle
1
Das einzelne Apostroph in Ihrem Shell-Befehl könnte irreführend und verwirrend sein.
ayan4m1
1
Bah, das ist es, was passiert, wenn Sie eine Kommandozeile bearbeiten, die in einen anderen Text eingebettet ist, ohne daran zu denken, dass es sich um eine Kommandozeile handelt ... Danke & Behoben.
12.
Kein Problem, ja verstanden über die unterschiedlichen Headspaces für die beiden Prozesse.
ayan4m1
6

Sie könnten an s2both interessiert sein . Es wird durch das Paket uswsuspin Ubuntu 10.10 bereitgestellt . Es wird auf der Festplatte angehalten, aber anstatt das System herunterzufahren, wird es in S3 abgelegt. Dies ist der Energiemodus, der normalerweise mit der Option "Anhalten" in Ubuntu verbunden ist. pm-suspend-hybrid ist ein weiteres Tool, das das Gleiche vorgibt.

Um dies beim Schließen des Deckels zu automatisieren, lesen Sie die folgende Anleitung, in der Sie ein beliebiges Skript ausführen können, wenn ein Deckelereignis abgefangen wird:

http://ubuntuforums.org/showthread.php?t=1076486

Wenn Sie zufällig ein ThinkPad haben, tpctlverweist die Manpage für auf ein Argument --pm-sedation-hibernate-from-suspend-timer, das die gesuchte Funktion zu bieten scheint. Ich möchte Sie davor warnen, dies auf Hardware zu versuchen, die nicht von ThinkPad stammt.

Als Referenz habe ich in der Manpage nach hibernate.conf gesucht . es schien keine relevanten Optionen zu haben, könnte aber eine zweite Lesung wert sein.

ayan4m1
quelle
5

Ubuntu 16.04 - von Suspend / Sleep in den Ruhezustand nach einer festgelegten Zeit

Es scheint, dass die Dinge auf Ubuntu 16.04 ein wenig anders sind, also habe ich folgende Schritte unternommen, damit es funktioniert:

  1. Stellen Sie sicher, dass der Ruhezustand beim Ausführen wie erwartet funktioniert

    systemctl hibernate
    
  2. Kopieren Sie die Originaldatei suspend.target:

    sudo cp /lib/systemd/system/suspend.target /etc/systemd/system/suspend.target
    

    Bearbeiten Sie dann die Datei /etc/systemd/system/suspend.targetund fügen Sie die Zeile hinzu:

    Requires=delayed-hibernation.service
    

    zu dem [Unit]Abschnitt dieser Datei.

  3. Erstellen Sie die Datei /etc/systemd/system/delayed-hibernation.servicemit folgendem Inhalt:

[Einheit]
Beschreibung = Auslöser für verzögerten Ruhezustand
Vorher = suspend.target
Konflikte = hibernate.target hybrid-suspend.target
StopWhenUnneeded = true

[Bedienung]
Typ = Einschuss
RemainAfterExit = yes
ExecStart = / usr / local / bin / delayed-hibernation.sh vor dem Suspendieren
ExecStop = /usr/local/bin/delayed-hibernation.sh post suspend

[Installieren]
WantedBy = sleep.target
  1. Erstellen Sie die Konfigurationsdatei /etc/delayed-hibernation.conffür das Skript mit dem folgenden Inhalt:
# Konfigurationsdatei für das Skript 'delayed-hibernation.sh'

# Geben Sie die Zeit in Sekunden an, die Sie im Energiesparmodus verbringen möchten, bevor der Computer in den Ruhezustand wechselt
TIMEOUT = 1200 #in Sekunden, ergibt 20 Minuten
  1. Erstellen Sie das Skript, das tatsächlich die harte Arbeit erledigt.

    Erstelle eine Datei /usr/local/bin/delayed-hibernation.shmit dem Inhalt:

#! / bin / bash
# Skriptname: delayed-hibernation.sh
# Zweck: Auto-Ruhezustand nach einer bestimmten Zeit des Schlafes
# Bearbeiten Sie die Variable `TIMEOUT` in der Datei` $ hibernation_conf`, um die Anzahl der Sekunden für den Ruhezustand festzulegen.

hibernation_lock = '/ var / run / delayed-hibernation.lock'
hibernation_fail = '/ var / run / delayed-hibernation.fail'
hibernation_conf = '/ etc / delayed-hibernation.conf'

# Überprüfen der Konfigurationsdatei
wenn [ ! -f $ hibernation_conf]; dann
    echo "Fehlende Konfigurationsdatei ('$ hibernation_conf') wird abgebrochen."
    Ausfahrt 1
fi
hibernation_timeout = $ (grep "^ [^ #]" $ hibernation_conf | grep "TIMEOUT =" | awk -F '=' '{print $ 2}' | awk -F '#' '{print $ 1}' | tr -d '[[\ t]]')
if ["$ hibernation_timeout" = ""]; dann
    echo "Fehlender 'TIMEOUT'-Parameter in der Konfigurationsdatei (' $ hibernation_conf '), Abbruch."
    Ausfahrt 1
elif [[! "$ hibernation_timeout" = ~ ^ [0-9] + $]]; dann
    echo "Fehlerhafter 'TIMEOUT'-Parameter (' $ hibernation_timeout ') in Konfigurationsdatei (' $ hibernation_conf '), erwartete Anzahl von Sekunden, Abbruch."
    Ausfahrt 1
fi

# Verarbeitet die angegebenen Parameter
if ["$ 2" = "suspend"]; dann
    Kurzzeit = $ (Datum +% s)
    if ["$ 1" = "pre"]; dann
        if [-f $ hibernation_fail]; dann
            echo "Der Ruhezustand ist fehlgeschlagen. Der eingestellte RTC-Weck-Timer wird übersprungen."
        sonst
            echo "Suspend erkannt. Aufnahmezeit, RTC-Timer einstellen"
            echo "$ curtime"> $ hibernation_lock
            rtcwake -m no -s $ hibernation_timeout
        fi
    elif ["$ 1" = "post"]; dann
        if [-f $ hibernation_fail]; dann
            rm $ hibernation_fail
        fi
        if [-f $ hibernation_lock]; dann
            sustime = $ (cat $ hibernation_lock)
            rm $ hibernation_lock
            if [$ (($ curtime - $ sustime)) -ge $ hibernation_timeout]; dann
                echo "Automatisches Fortsetzen nach Suspendieren erkannt. Ruhezustand ..."
                Systemctl Ruhezustand
                wenn [$? -ne 0]; dann
                    echo "Der automatische Ruhezustand ist fehlgeschlagen. Stattdessen wurde versucht, den Vorgang anzuhalten."
                    Berühre $ hibernation_fail
                    systemctl suspend
                    wenn [$? -ne 0]; dann
                        echo "Der automatische Ruhezustand und das Suspend-Failover sind fehlgeschlagen. Es ist nichts anderes zu versuchen."
                    fi
                fi
            sonst
                echo "Manuelle Fortsetzung nach Unterbrechung erkannt. RTC-Timer löschen"
                rtcwake -m deaktivieren
            fi
        sonst
            echo "Datei '$ hibernation_lock' wurde nicht gefunden, nichts zu tun"
        fi
    sonst
        echo "Unbekannter erster Parameter: '$ 1', erwartet 'vor' oder 'nach'"
    fi
sonst
    echo "Dieses Skript soll von systemctl delayed-hibernation.service ausgeführt werden (erwarteter zweiter Parameter: 'suspend')"
fi
  1. Machen Sie das Skript ausführbar:
chmod 755 /usr/local/bin/delayed-hibernation.sh

Es hat ziemlich viel gedauert, bis ich dieses Skript basierend auf anderen Antworten in diesem Thread geschrieben habe, Dinge, die ich im Internet gefunden habe, wie https://bbs.archlinux.org/viewtopic.php?pid=1554259

Meine Version des Skripts versucht, viele Probleme zu lösen, z. B. erneut in den Standby-Modus zu wechseln, wenn der Ruhezustand nicht erfolgreich war, aber nach der festgelegten Zeit nicht immer wieder aufzuwachen.

  1. Der letzte Schritt, von dem ich annehme, ist die Ausführung

    sudo systemctl daemon-reload
    sudo systemctl enable delayed-hibernation.service 
    

    um sicherzustellen, dass neue Dienste / Konfigurationen verwendet werden.

Um das Serviceprotokoll zu überprüfen, können Sie Folgendes verwenden:

sudo systemctl status delayed-hibernation.service

oder für ein vollständiges Protokoll der Dienstnutzung:

sudo journalctl -u verzögert-Ruhezustand

Ein normales Protokoll, das ich vom laufenden Dienst erhalte, lautet:

mile @ mile-ThinkPad: ~ $ sudo systemctl status delayed-hibernation.service 
● delayed-hibernation.service - Trigger für verzögerten Ruhezustand
   Loaded: loaded (/etc/systemd/system/delayed-hibernation.service; enabled; Herstellervoreinstellung: enabled)
   Aktiv: inaktiv (tot)

Jun 09 20:35:42 mile-ThinkPad systemd [1]: Start des Triggers für verzögerten Ruhezustand ...
09. Juni 20:35:42 Meilen-ThinkPad delayed-hibernation.sh [2933]: Unterbrechung erkannt. Aufnahmezeit, RTC-Timer einstellen
Jun 09 20:35:42 mile-ThinkPad delayed-hibernation.sh [2933]: rtcwake: unter der Annahme, dass RTC UTC verwendet ...
09. Juni 20:35:42 mile-ThinkPad delayed-hibernation.sh [2933]: rtcwake: Aufwachen mit / dev / rtc0 am 9. Juni 18:55:43 2016
09. Juni 20:55:44 Meile-ThinkPad-Systemd [1]: Auslöser für verzögerten Ruhezustand gestartet.
09.06. 20:55:44 Meile-ThinkPad-Systemd [1]: Verzögerter Ruhezustand. Service: Gerät wird nicht mehr benötigt. Anhalten.
Jun 09 20:55:44 mile-ThinkPad systemd [1]: Anhalten des Triggers für verzögerten Ruhezustand ...
Jun 09 20:55:44 mile-ThinkPad delayed-hibernation.sh [3093]: Automatisches Fortsetzen nach Suspendieren erkannt. Winterschlaf halten ...
09.06. 20:55:44 Meile-ThinkPad-Systemd [1]: Auslöser für verzögerten Ruhezustand gestoppt.
Meile @ Meile-ThinkPad: ~ $ 

Das wäre es also, ich hoffe, es hilft jemandem wirklich, da ich tagelang versucht habe, die richtige Kombination von Konfigurationen und Skriptversionen zu finden, damit diese praktische Funktion funktioniert.

mihai.ile
quelle
Danke für die Antwort, das funktioniert immer noch wie ein Zauber auf Ubuntu 18.04. Ich konnte die obigen Antworten nicht zum /bin/systemctl hibernateLaufen bringen. Die Ausführung gab immer 1 zurück, wenn das systemd-Skript ausgeführt wurde, obwohl es in der Befehlszeile einwandfrei funktioniert.
Eugenhu
4

Nur für den Fall, dass etwas schief geht pm-hibernateund ich den Computer lieber in den Suspend-Modus versetzen möchte, als ihn laufen zu lassen. So können Sie verwenden:

   ...
/usr/sbin/pm-hibernate || /usr/sbin/pm-suspend
   ...
iiegn
quelle
3

Hier ist eine aktualisierte Version von Derek Pressnalls Antwort , die mit systemd funktioniert und Eliah Kagans Vorschlag enthält. Legen Sie sie einfach in /usr/lib/systemd/system-sleep/delayed_hibernation.sh ab und machen Sie sie ausführbar:

#!/bin/bash

hibernation_timeout=1800  #30 minutes

if [ "$2" = "suspend" ]; then
    curtime=$(date +%s)
    if [ "$1" = "pre" ]; then
        echo -e "[($curtime) $@]\nExecuting pre-suspend hook..." >> /tmp/delayed_hibernation.log
        echo "$curtime" > /var/run/delayed_hibernation.lock
        rtcwake -m no -s $hibernation_timeout
    elif [ "$1" = "post" ]; then
        echo -e "[($curtime) $@]\nExecuting post-suspend hook..." >> /tmp/delayed_hibernation.log
        sustime=$(cat /var/run/delayed_hibernation.lock)
        if [ $(($curtime - $sustime)) -ge $hibernation_timeout ]; then
            echo -e "Automatic resume detected, hibernating.\n" >> /tmp/delayed_hibernation.log
            systemctl hibernate || systemctl suspend
        else
            echo -e "Manual resume detected, clearing RTC alarm.\n" >> /tmp/delayed_hibernation.log
            rtcwake -m no -s 1
        fi
        rm /var/run/delayed_hibernation.lock
    fi
fi
Niccolò Maggioni
quelle
Dies funktionierte am 15.10 einige Monate lang hervorragend, aber etwas an 16.04 verhinderte, dass es in den Ruhezustand übergeht, obwohl das Skript noch ausgeführt wird.
Sean
@ Sean hast du die Problemumgehung in diesem Thread ausprobiert ?
Niccolò Maggioni
Vielen Dank, dass Sie mich in die richtige Richtung weisen. Ich habe einen systemd-Dienst (/etc/systemd/system/delayed-hibernation.service) erstellt, der auf das obige Skript verweist, und dann /etc/systemd/system/suspend.target geändert, um delayed-hibernation.service zu erfordern.
Sean
2

Hier ist mein Rezept (getestet auf zwei Notebooks Ubuntu 16.04):

Setzen Sie dieses Skript, wo immer Sie möchten (ich lege es auf root, /syspend.sh) und machen Sie es ausführbar ( chmod +x /suspend.sh)

TIMELOG=/tmp/autohibernate.log
ALARM=$(tail -n 1 $TIMELOG)
SLEEPTIME=5000 #edit this line to change timer, e.g. 2 hours "$((2*60*60))"
if [[ $1 == "resume" ]]
then
    if [[ $(date +%s) -ge $(( $ALARM + $SLEEPTIME )) ]]
    then
        echo "hibernate triggered $(date +%H:%M:%S)">>$TIMELOG
        systemctl hibernate 2>> $TIMELOG
    else
        echo "normal wakeup $(date +%H:%M:%S)">>$TIMELOG
    fi
elif [[ $1 == "suspend" ]]
then
    echo "$(date +%s)" >> $TIMELOG
    rtcwake -m no -s $SLEEPTIME
fi

Dann erstelle systemd target: # touch /etc/systemd/system/suspend-to-sleep.target Füge diesen Inhalt ein:

#/etc/systemd/system/suspend-to-hibernate.service
[Unit]
Description=Delayed hibernation trigger
Before=suspend.target
Conflicts=hibernate.target hybrid-suspend.target
StopWhenUnneeded=true

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash /suspend.sh suspend
ExecStop=/bin/bash /suspend.sh wakeup

[Install]
WantedBy=sleep.target
RequiredBy=suspend.target

Dann aktivieren Sie es # systemctl enable suspend-to-sleep.target.

Ich habe ein Problem mit Notebooks: Das Schließen des Deckels hat dieses Ziel nicht ausgelöst. Dies lag an xfce4-power-manager. Es gibt zwei Möglichkeiten, dieses Problem zu umgehen. Die erste ist , zu bearbeiten /etc/systemd/logind.confDatei und ersetzen HandleLidSwitch=ignoremit HandleLidSwitch=suspend. Da es aber systemweit sein wird, habe ich meinem Skript gerade einen Symlink hinzugefügt# ln -s /suspend.sh /etc/pm/sleep.d/0000rtchibernate

Yanpas
quelle
1

Eine weitere häufigere Problemumgehung, die Sie verwenden können hybrid-sleep(wie dies auch unter Mac OS der Fall ist). Wenn Ihr Computer den Ruhezustand unterstützt, können Sie diese Funktion verwenden:

systemctl hybrid-sleep

Dieser Befehl sollte den Computer anhalten und auf die Festplatte senden (in den Ruhezustand versetzen). Nach einiger Zeit schaltet sich der Computer aus (beim Einschalten werden die Ruhezustandsdateien zum Aufwecken verwendet).

ps: Ich weiß, dass es nicht genau das ist, was das OP gepostet hat, aber es ist ziemlich nah

morhook
quelle
0

Vergessen Sie nicht, diese Datei mit chmod + x auszuführen.

Es gibt eine andere Lösung ohne rtcwake mit wakealarm in / sys / class / rtc / rtc0. Verwenden Sie veralteten Code in pm-Funktionen (/ usr / lib / pm-utils), nachdem die Kommentare # nicht direkt vom Kernel unterstützt werden ... (weil der aktuelle Kernel (nach 3.6 etwas) dies direkt unterstützt). Setzen Sie diesen Code zurück und geben Sie do_suspend () anstelle von do_suspend_hybrid () ein.

Veralteter Code (aussetzen und in den Ruhezustand versetzen, wenn suspend_hybrid aufgerufen wird):

# since the kernel does not directly support hybrid sleep, we do
# something else -- suspend and schedule an alarm to go into
# hibernate if we have slept long enough.
# Only do this if we do not need to do any special video hackery on resume
# from hibernate, though.
if [ -z "$SUSPEND_HYBRID_MODULE" -a -w "$PM_RTC/wakealarm" ] && \
    check_suspend && check_hibernate && ! is_set $HIBERNATE_RESUME_POST_VIDEO; \
    then
    SUSPEND_HYBRID_MODULE="kernel"
    do_suspend_hybrid() {
    WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
    echo >"$PM_RTC/wakealarm"
    echo $WAKETIME > "$PM_RTC/wakealarm"
    if do_suspend; then
        NOW=$(cat "$PM_RTC/since_epoch")
        if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ]; then
        log "Woken by RTC alarm, hibernating."
        # if hibernate fails for any reason, go back to suspend.
        do_hibernate || do_suspend
        else
        echo > "$PM_RTC/wakealarm"
        fi
    else
        # if we cannot suspend, just try to hibernate.
        do_hibernate
    fi
    }
fi

Empfohlen. Noch einfacher ist es, uswsusp zu verwenden und gleichzeitig den Nutzen von s2both zu maximieren, dh s2both beim Suspendieren. Fügen Sie den wiederhergestellten Code in den Teil do_suspend () des Moduls uswsusp (/usr/lib/pm-utils/module.d) ein.

Zurückgesetzter Code (suspend_hybrid, wenn suspend aufgerufen wird):

WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
echo >"$PM_RTC/wakealarm"
echo $WAKETIME > "$PM_RTC/wakealarm"
if do_suspend_hybrid; then
    NOW=$(cat "$PM_RTC/since_epoch")
    if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ];             then
    log "Woken by RTC alarm, hibernating."
    # if hibernate fails for any reason, go back to suspend_hybrid.
    do_hibernate || do_suspend_hybrid
    else
    echo > "$PM_RTC/wakealarm"
    fi
else
    # when do_suspend is being called, convert to suspend_hybrid.
    do_suspend_hybrid
fi      

Mit uswsusp können wir den Fortschritt von Suspend / Hibernate und den umgekehrten Prozess im Text sehen, selbst wenn wir die Rücktaste drücken, um den Vorgang abzubrechen. Ohne uswsusp wird Suspend / Hibernate nur ärgerlich angezeigt bzw. ausgeblendet, insbesondere wenn Wakealarm ausgelöst wird und Hibernate ausgeführt wird (s2disk in uswsusp). Stellen Sie die Ruhezeit vor dem Ruhezustand an der üblichen Stelle in der pm-functions-Datei ein.

# variables to handle hibernate after suspend support
PM_HIBERNATE_DELAY=900  # 15 minutes
PM_RTC=/sys/class/rtc/rtc0

Hier ist der uswsusp-Mod: (Denken Sie daran, dass dieses Modul von pm-Funktionen aufgerufen wird, damit die eingefügten Variablen identisch sind.)

#!/bin/sh

# disable processing of 90chvt and 99video.
# s2ram and s2disk handle all this stuff internally.
uswsusp_hooks()
{
    disablehook 99video "disabled by uswsusp"
}

# Since we disabled 99video, we need to take responsibility for proper
# quirk handling.  s2ram handles all common video quirks internally,
# so all we have to do is translate the HAL standard options to s2ram options.
uswsusp_get_quirks()
{
    OPTS=""
    ACPI_SLEEP=0
    for opt in $PM_CMDLINE; do
        case "${opt##--quirk-}" in # just quirks, please
            dpms-on)       ;; # no-op
            dpms-suspend)      ;; # no-op
            radeon-off)        OPTS="$OPTS --radeontool" ;;
            reset-brightness)  ;; # no-op
            s3-bios)       ACPI_SLEEP=$(($ACPI_SLEEP + 1)) ;;
            s3-mode)       ACPI_SLEEP=$(($ACPI_SLEEP + 2)) ;;
            vbe-post)      OPTS="$OPTS --vbe_post" ;;
            vbemode-restore)   OPTS="$OPTS --vbe_mode" ;;
            vbestate-restore)  OPTS="$OPTS --vbe_save" ;;
            vga-mode-3)        ;; # no-op
            save-pci)          OPTS="$OPTS --pci_save" ;;
            none)          QUIRK_NONE="true" ;;
            *) continue ;;
        esac
    done
    [ $ACPI_SLEEP -ne 0 ] && OPTS="$OPTS --acpi_sleep $ACPI_SLEEP"
    # if we were told to ignore quirks, do so.
    # This is arguably not the best way to do things, but...
    [ "$QUIRK_NONE" = "true" ] && OPTS=""
}

# Since we disabled 99video, we also need to handle displaying
# help info for the quirks we handle.
uswsusp_help()
{
    echo  # first echo makes it look nicer.
    echo "s2ram video quirk handler options:"
    echo
    echo "  --quirk-radeon-off"
    echo "  --quirk-s3-bios"
    echo "  --quirk-s3-mode"
    echo "  --quirk-vbe-post"
    echo "  --quirk-vbemode-restore"
    echo "  --quirk-vbestate-restore"
    echo "  --quirk-save-pci"
    echo "  --quirk-none"
}

# This idiom is used for all sleep methods.  Only declare the actual
# do_ method if:
# 1: some other sleep module has not already done so, and
# 2: this sleep method can actually work on this system.
#
# For suspend, if SUSPEND_MODULE is set then something else has already
# implemented do_suspend.  We could just check to see of do_suspend was
# already declared using command_exists, but using a dedicated environment
# variable makes it easier to debug when we have to know what sleep module
# ended up claiming ownership of a given sleep method.
if [ -z "$SUSPEND_MODULE" ] && command_exists s2ram && \
    ( grep -q mem /sys/power/state || \
        ( [ -c /dev/pmu ] && check_suspend_pmu; ); ); then
    SUSPEND_MODULE="uswsusp"
    do_suspend()
    {
        WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
        echo >"$PM_RTC/wakealarm"
        echo $WAKETIME > "$PM_RTC/wakealarm"
        if do_suspend_hybrid; then
            NOW=$(cat "$PM_RTC/since_epoch")
            if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ];             then
            log "Woken by RTC alarm, hibernating."
            # if hibernate fails for any reason, go back to suspend_hybrid.
            do_hibernate || do_suspend_hybrid
            else
            echo > "$PM_RTC/wakealarm"
            fi
        else
            # when do_suspend is being called, convert to suspend_hybrid.
            do_suspend_hybrid
        fi      
    }
fi

if [ -z "$HIBERNATE_MODULE" ] && \
    [ -f /sys/power/disk ] && \
    grep -q disk /sys/power/state && \
    [ -c /dev/snapshot ] &&
    command_exists s2disk; then
    HIBERNATE_MODULE="uswsusp"
    do_hibernate()
    {
        s2disk
    }
fi

if [ -z "$SUSPEND_HYBRID_MODULE" ] && 
    grep -q mem /sys/power/state && \
    command_exists s2both && \
    check_hibernate; then
    SUSPEND_HYBRID_MODULE="uswsusp"
    do_suspend_hybrid()
    {   
        uswsusp_get_quirks
        s2both --force $OPTS 
    }
    if [ "$METHOD" = "suspend_hybrid" ]; then
        add_before_hooks uswsusp_hooks
        add_module_help uswsusp_help
    fi
fi  
Kennzeichen
quelle