Python-Script für PowerMangament - bitte um Kritik

Meta.Morph

Lt. Junior Grade
Registriert
März 2022
Beiträge
364
Servus,
ich bin im Bash/Python Scripting noch komplett unerfahren.

Folgendes: ich nutze Qtile als WM. Hier müsste ich ein Tool fürs Power Managment Installieren. Aber hey, warum nicht das wissen anwenden und in etwas Nützliches gießen (auch wenn das Projekt wirklich Mini ist...).

Ging auch relativ Fix:
Python:
import os
from time import sleep
def getBatteryStatus():
    status = int(os.popen("acpi -b | cut -d ',' -f2 | sed s/%//").read().strip())
    return status
def getChargeStatus():
    status = os.popen("acpi -b | cut -d ' ' -f3 | cut -c 1-11").read().strip()
    return status
def energySave():
    os.system("rfkill block bluetooth wlan")
    os.system("brightnessctl set 10%")
    while getBatteryStatus() < 33 and getBatteryStatus() > 10 and getChargeStatus() == "Discharging":
        os.system("xset dpms force off")
        sleep(30)
def energyEmergency():
    os.system("systemctl suspend")
while True:
    # if charging every 5 minutes
    if getChargeStatus() == "Discharging":
        while getChargeStatus() == "Discharging":
            # until discharging, make this - chack every 2 minutes
            # when battery is 33% and over 10%, energy save
            if getBatteryStatus() < 33 and getBatteryStatus() > 10:
                energySave()
            # when battery is 10% and under and discharge, emergency
            elif getBatteryStatus() < 10 and getChargeStatus() == "Discharging":
                energyEmergency()
            sleep(120)
    sleep(300)

Funktionieren tut das ganze. Toll.
Aber ich kann mir auch gut Vorstellen, das solch ein Script vor 20 Jahren vielleicht noch cool war - heute aber nicht mehr... der schlaueste Weg ist.

Welche Möglichkeiten gibt es, ein besseres Script zu schreiben?
Mit welchen Python Bibliotheken müsste ich mich beschäftigen?

EDIT:

Als kleines Update nach dem Urlaub:
Python:
#!/usr/bin/env python
import os
from time import sleep
batStatus = 0
lowBat = 25
emergencyBat = 10
batteryTimerNormal = 300
batteryTimerLow = 120
batteryTimerEmergency = 30
def getBatteryStatus():
    status = int(os.popen("acpi -b | cut -d ',' -f2 | sed s/%//").read().strip())
    return status
def getChargeStatus():
    status = os.popen("acpi -b | cut -d ' ' -f3 | cut -c 1-11").read().strip()
    return status
def energySave():
    os.system("rfkill block bluetooth wlan")
    os.system("brightnessctl set 10%")
    while batStatus < lowBat and batStatus > emergencyBat and getChargeStatus() == "Discharging":
        os.system("xset dpms force off")
        batStatus = getBatteryStatus()
        sleep(batteryTimerEmergency)
def energyEmergency():
    os.system("brightnessctl set 10%")
    os.system("systemctl suspend")
if getChargeStatus() != "Discharging":
    os.system("brightnessctl set 50%")
else:
    os.system("brightnessctl set 30%")
while True:
    if getChargeStatus() == "Discharging":
        while getChargeStatus() == "Discharging":
            batStatus = getBatteryStatus()
            if batStatus < lowBat and batStatus > emergencyBat:
                energySave()
            elif batStatus < emergencyBat:
                energyEmergency()
            sleep(batteryTimerLow)
    sleep(batteryTimerNormal)

... das sollte alle Unnötigen abfragen auf das nötigste reduzieren - ohne den Code im wesentlichen zu verändern.
 
Zuletzt bearbeitet:
_anonymous0815_ schrieb:
Wusste gar nicht, dass os auch Funktionen mitbringt, um den Ladezustand auszulesen,
Mit os schicke bzw lese ich ja nur einen (Konsolen-)Befehl aus. Mag sein, das man mit Sys ein besseres/eleganteres Ergebnis erreicht.
 
Achja: Ansonsten da ich Python aktuell auch noch lerne:

Python:
#from ganzes_modul import einzelne_methode

from time import sleep

Hat den Vorteil, dass Du direkt sleep(60) schreiben kannst, anstatt time.sleep(60) und importiert halt nur diese einzelne Funktion/ Methode. Wenn Du mit pyinstaller eine Executable machen wollen würdest, reduziert das den Speicherplatz etwas. Alles Weitere müssen Dir die Cracks verraten. :D
 
Deine while-true Schleife sieht gruselig aus. Warum die verschachtelten While-Schleifen?
Für was die for-schleife in energySafe() ? Und die While-Schleife da drin ist auch komisch. Warum möchtest du den os Befehl denn mehrfach absetzen?

Ich mein wenn es funktioniert wie du dir das vorstellst, prima, aber das sieht auf den ersten Blick ein bischen wild aus.
 
Falc410 schrieb:
Warum die verschachtelten While-Schleifen?
Die Idee ist, wenn das Notebook am Strom hängt, muss das Script nicht ständig irgendwelche abfragen an das System schicken.
Aber eine Schleife hab ich entfernt, die sollte tatsächlich unnötig sein. Wie gesagt, das ist erst einmal nur ein grober Plan. Pseudocode - der dank Python funktioniert 😂 .

Schöner geht das sicher.

Die eigentliche Frage ist ja: ist das Valider Code? Oder belegt dieses Script unnötig ressourcen?

Falc410 schrieb:
Für was die for-schleife in energySafe() ? Und die While-Schleife da drin ist auch komisch.
Mit der For-Schleife wollte ich sicherstellen, das er mir nur einmal diese Befehle ausführt. Aber ja, ist tatsächlich unnötig - denn mit der Whil-Schleife soll das Script den Bildschirm alle 30 Sec ausschalten

Und sobald der Akku unter 10% ist, soll das Notebook eh schlafen geschickt werden.
 
Zuletzt bearbeitet:
Deine äusser While schleife wird alle 300 sekunden getChargeStatus aufrufen.
Fall "Discharging" rufst du alle 120 sekunden wieder diese funktion auf.
Wenn die Batterie dann zwischen 10 und 33% gehst du in energySave() und bleibst dort solange drin, bis
du entweder am Strom hängst oder die Batterie unter 10 gefallen ist. Die Abfrage mit 33% bräuchtest du dort eigentlich gar nicht. Und alle 30 Sekunden führst du dann ein xset dpms force off aus, was macht das?
D.h. du rufst auch alle 30 Sekunden die bei get-Funktionen auf (nur als Info, der Overhead ist harmlos).
Wenn der Zustand also unter 10% fällt kommst du wieder zurück in deine While-True Schleife. Für das elif brauchst du keine Abfrage für "Discharging" weil du ja eh nicht ohne an die Stelle kommen würdest.
 
Falc410 schrieb:
Für das elif brauchst du keine Abfrage für "Discharging" weil du ja eh nicht ohne an die Stelle kommen würdest
Hm...
Theoretisch könnte doch der Fall eintreten, das ich mit unter 10% aus dem energy Save komme - aber mit dem Status Charging. Wenn ich dann aber wieder am Strom hänge, muss das Notebook nicht mehr in den Emergency Mode (was er aber tun würde, die Prüfung, ob das Notebook geladen wird, kommt erst noch mit dem nächsten Schleifen-Beginn).

Falc410 schrieb:
xset dpms force off aus, was macht das?
Bildschirm Ausschalten.
 
Und warum musst du alle 30 Sekunden Bildschirm erneut ausschalten?
Meta.Morph schrieb:
Theoretisch könnte doch der Fall eintreten, das ich mit unter 10% aus dem energy Save komme - aber mit dem Status Charging.
Und was ist deine erste if-Abfrage in deiner True-While Schleife? ;)
Wenn du aus energeySave() zurück kommst, wird nicht in den elif Teil gegangen, die If Abfrage hast du ja schon hinter dir. er wird dann sleep(120) ausführen und danach wieder auf Discharging prüfen
 
  • Gefällt mir
Reaktionen: Meta.Morph
Falc410 schrieb:
wird nicht in den elif Teil gegangen, die If Abfrage hast du ja schon hinter dir. er wird dann sleep(120) ausführen und danach wieder auf Discharging prüfen
Und das ist dann auch der entscheidende Unterschied zwischen elif und if. Man lernt so vieles, man sollte sich das tatsächlich mal merken 😂.
 
Zurück
Oben