"Akkupflege" mit AppleScript

Moin,


um mal wieder frischen Wind in den Akkuwald zu blasen (vor allem war es aber ein Anfall langer Weile),

spiel(t)e ich mit Applescript. Also (fasst) alles mit Bordmitteln (launchd mit den plist hab ich durch Lingon erstellen lassen >> ich bin etwas faul geworden <<:

--Aufruf aller 10 min durch (launchd)
--Meldung bei Akku <20 % und >80/99 %, aller wdhzeit
--ist akkulevel 20-80, dann beendet sich App
set min to "22" --MinLadewert
set minreset to "60" --bei Entladen < Wert: Reset ladeziel auf max1
set max1 to "77" --MaxLadewert
set max2 to "99" --Vollladewert
set wdhzeit to "60" --Meldefenster Wdh.-zeit in s
set givupzeit to "20" -- Meldefenster Einblendzeit in s
set akkulevel to word 6 of paragraph 2 of (do shell script "pmset -g batt") as number --Auslesen akkulevel
set akku to word 7 of paragraph 2 of (do shell script "pmset -g batt") as string --Auslesen charging/discharging
set ladeziel to (read file "Macintosh HD:users:testerer:scripte:akkupflege_merker.txt") --Auslesen ladeziel aus Merkerdatei

--setzt ladeziel immer auf max1, wenn akkulevel wieder unter minreset
set fileID to open for access file "Macintosh HD:users:testerer:scripte:akkupflege_merker.txt" with write permission
if akkulevel < minreset then set ladeziel to max1
write ladeziel to fileID
close access fileID

--Schleife "MinMeldung", zyklische Meldung bis geladen wird
if akkulevel < min and akku = "discharging" then
	repeat until akku = "charging"
		set akku to word 7 of paragraph 2 of (do shell script "pmset -g batt") as string --Ladeerkennung
		if akku = "discharging" then --Schleife muss bleiben, sonst wird Mldg noch einmal wdh
			beep 3
			activate
			display alert "Akku " & akkulevel & " %. " & "Bitte laden." buttons {"Okay"} giving up after givupzeit
		end if
		delay wdhzeit
	end repeat
end if

--Schleife "Max1Meldung" mit Auswahl max1 (default) oder max2, zyklische Mldg. bis entladen wird
if ladeziel = max1 and akkulevel > max1 and akku ≠ "discharging" then -- /= entspricht ungleich
	repeat until akku = "discharging"
		set akku to word 7 of paragraph 2 of (do shell script "pmset -g batt") as string --Entladeerkennung
		if akku = "charging" then
			beep 3
			activate
			display alert "Akku " & akkulevel & " %. " & "Ladekabel entfernen oder weiterladen?" buttons {"Entfernen", "Weiter"} default button 1 giving up after givupzeit
			set Diogresult to result
			if button returned of result = "Entfernen" then
				set akkumax to max1
			else if button returned of result = "Weiter" then
				set akkumax to max2
			else if gave up of Diogresult is true then
				set akkumax to max1
			end if
			set fileID to open for access file "Macintosh HD:users:testerer:scripte:akkupflege_merker.txt" with write permission
			write akkumax to fileID --schreiben ladeziel neu
			close access fileID

set ladeziel to (read file "Macintosh HD:users:testerer:scripte:akkupflege_merker.txt") --Auslesen ladeziele neu- innerhalb repeat-loop

			if ladeziel = max2 then set akku to "discharging" --Schleifenausgang bei Auswahl max2
		end if
		delay wdhzeit
	end repeat
end if

--Schleife "Max2Meldung"
if ladeziel = max2 and akkulevel > max2 and akku ≠ "discharging" then
	repeat until akku = "discharging"
		set akku to word 7 of paragraph 2 of (do shell script "pmset -g batt") as string --Entladeerkennung
		if akku ≠ "discharging" then
			beep 3
			activate
			display alert "Akku voll. Bitte Ladekabel entfernen." buttons {"Okay"} default button 1 giving up after givupzeit
		end if
		delay wdhzeit
	end repeat
end if

Das Script wird als Akkupflege.app durch launchd aller 10 min aufgerufen, schaut sich den Akkuladestand an und erinnert bei einem Minimumladewert zum Laden. Beim Laden um die 80 % erinnert es "Stecker ziehen", bzw. fragt nach ob weiter (bis 99 %) laden soll.

Da, bedingt durch die Aufrufzeit mit Toleranzen gerechnet wird, sind die Prozentwerte nie genau 80/100.


Funktioniert sogar gut ;o)

Nachteil ist der externe Speicherort des Zielladewertes in eine Textdatei (77 oder 99 %).

Aber da das Script nicht dauernd läuft (laufen soll, dafür ist AS nicht ausgelegt), muss die die Variable irgendwo zwischengespeichert werden.

property und global gehen hier nicht.

Speichern über posix ins bundle wäre eine Variante (relative Pfadangaben machbar???).

Jemand Optimierungsideeen?

(Keine Akkudiskusion, Thread soll reines Scriptquatschen werden...)

MacBook Air (M1, 2020)

Gepostet am 16. März 2023 13:48

Antworten
11 Antworten

17. März 2023 07:44 als Antwort auf testerer

Hallo testerer


natürlich kenne ich noch diesen schönen Film, dann geben wir einmal etwas Input, wobei das Skript selbst keine Endlosschleife enthalten sollte, da launchd es regelmäßig ausführen wird. Um das Skript alle 10 Minuten mit launchd auszuführen, passe den StartInterval-Wert entsprechend an (600 Sekunden entsprechen 10 Minuten).


Für jeglichen Code, sollte auch weiterhin die Code-Tags </> die "Codeeinfügung" verwendet werden, dann spielt es auch keine Rolle, dass ein Teil außerhalb des Text-Editors liegt, da er dennoch existiert. Scroll einfach einmal horizontal mit der Maus (innerhalb des AppleScript) 😉


-- Optimiertes AppleScript

on checkBatteryStatus()
    -- Parameter
    set min to 22 -- MinLadewert
    set minreset to 60 -- bei Entladen < Wert: Reset ladeziel auf max1
    set max1 to 77 -- MaxLadewert
    set max2 to 99 -- Vollladewert
    set givupzeit to 20 -- Meldefenster Einblendzeit in s
    
    -- Auslesen von Akkustatus und Ladeziel
    set akkulevel to word 6 of paragraph 2 of (do shell script "pmset -g batt") as number -- Auslesen akkulevel
    set akku to word 7 of paragraph 2 of (do shell script "pmset -g batt") as string -- Auslesen charging/discharging
    set ladeziel to (read file "Macintosh HD:users:testerer:scripte:akkupflege_merker.txt") -- Auslesen ladeziel aus Merkerdatei
    
    -- setzt ladeziel immer auf max1, wenn akkulevel wieder unter minreset
    set fileID to open for access file "Macintosh HD:users:testerer:scripte:akkupflege_merker.txt" with write permission
    if akkulevel < minreset then set ladeziel to max1
    write ladeziel to fileID
    close access fileID
    
    -- MinMeldung
    if akkulevel < min and akku = "discharging" then
        beep 3
        activate
        display alert "Akku " & akkulevel & " %. " & "Bitte laden." buttons {"Okay"} giving up after givupzeit
    end if
    
    -- Max1Meldung mit Auswahl max1 (default) oder max2
    if ladeziel = max1 and akkulevel > max1 and akku ≠ "discharging" then
        beep 3
        activate
        display alert "Akku " & akkulevel & " %. " & "Ladekabel entfernen oder weiterladen?" buttons {"Entfernen", "Weiter"} default button 1 giving up after givupzeit
        set Diogresult to result
        if button returned of result = "Entfernen" then
            set akkumax to max1
        else if button returned of result = "Weiter" then
            set akkumax to max2
        else if gave up of Diogresult is true then
            set akkumax to max1
        end if
        set fileID to open for access file "Macintosh HD:users:testerer:scripte:akkupflege_merker.txt" with write permission
        write akkumax to fileID
        close access fileID
    end if

    -- Max2Meldung
    if ladeziel = max2 and akkulevel > max2 and akku ≠ "discharging" then
        beep 3
        activate
        display alert "Akku voll. Bitte Ladekabel entfernen." buttons {"Okay"} default button 1 giving up after givupzeit
    end if
end checkBatteryStatus

checkBatteryStatus()


Liebe Grüße

17. März 2023 00:57 als Antwort auf PreCognition

Moin PreCognition,


kennst Du noch "Nummer 5 lebt"?

--> Input, Input, Input...

(Kurzfassung: Kampfroboter wird nach Blitzschlag menschlich und lernt menschlicher zu sein...)


Also da wäre ich dir sehr dankbar!

Vorschlägen, Beispielen, Kritiken und so weiter, genau das ist mein Threadanliegen.

(Okay, das mit dem Akku war/ist eine Art cliffhanger 😎 für das eigentliche Thema AS).


Die plist hatte ich mir schon, mehr recht als schlecht, "zusammengebügelt". Daher der Griff zu Lingon (Zeitsteuerung wäre mit crontab/jobs extrem einfacher, wäre...).


Was mich an den kleinen Akkuscript noch stört:

Wie kann ich Variablen intern im script speichern ohne den Umweg der externen Textdatei?

Das script (in app-Form) wird ja aller 10 min immer wieder neu aufgerufen (applescript sprengt bei Dauerschleife die Aktivitätsanzeige und legt den Rechner teilweise lahm (kein Neustart mehr möglich).

Wenn ich den Akku vollladen will, wird aus ladeziel max2 (99 %), sonst max1 (77 %).

Hab schon mit global und property getestet, wird aber beim compilieren (hier neuaufruf) jedesmal wieder zurückgesetzt.


Developerforum ist die variante (da treib ich mich wegen xcode herum). Ich möchte nur gerade hier im apple-Benutzerforum das Thema applescript etwas mehr etablieren.

Automation und AS ist ein spannendes Thema UND es sind Bordmittel (20 GB plus extra Dateien mit xcode muss man mögen und auch wollen, wobei ich will...).


In diesem Sinne:

Einen schönen Freitag und sehr sonnenreiches Wochenende.


edit: mein script wird hier geteilt dargestellt und eine Zeile ist ausserhalb der "Codeeinfügung".

Muss man dazu hier etwas beachten?


17. März 2023 08:59 als Antwort auf PreCognition

Aaaaah,


erst mal vielen Dank !


Variablenwert, ohne "" (Ich hatte vorher String mit Text also, yupp).

Stimmt, "on...", da kann man es immer wieder als Scriptteil aufrufen (hier nur die Frage wozu? da eigenständiges script, und mehr soll da nicht rein).


MinMeldung würde sich anders verhalten:

das Script soll ja z.B. bei 20 % Akku und "discharging" so lange laufen bis "charging", also aller wdhzeit (delay wdhzeit) ans Laden erinnern und nicht nur aller 10 min. Und dies so lange bis eben der Ladestecker drinnen ist (charging)

Ohne repeat würde script auch immer ein Zusatzdurchlauf benötigen um Ladezustand zu erkennen.


Die If..then wählen nur den Meldungszustand (unter 20 %, > 80 % oder > 99 %) aus.

Und innerhalb der Meldeschleifen soll durch repeat ständig erinnert werden (bis entweder Ladestecker drinnen oder eben Ladestecker raus-> repeat soll dann scriptende verhindern).

Passt ja wie Faust aufs ****. Jetzt 21 % und script meckert jede Minute bis der akku geladen wird.

Jetzt wird er geldaen und das script beendet sich.

Aller 10 min schaut es nach (durch launchd) und beendet sich wenn akku zwischen 20 und 80. Bei 80 fragt es nach ob vollgeladen werden soll. wenn ja wird das Ladeziel von 80 auf 99 erhöht (und in die Textdatei als Speicher geschrieben). Nach 10 minuten schaut das script wieder nach, noch nicht voll dann Ende. Nach weiteren 10 min wieder, wenn dann Akku voll kommt die repeat schleife bis ladestecker daussen ist (ladeziel = 99 UND akkulevel größer 99 (deswegen 99 und nicht 100) UND akku wird nicht entladen).



16. März 2023 19:44 als Antwort auf testerer

Hallo testerer


Sie können "launchd" verwenden, um Ihr AppleScript im Hintergrund und zeitgesteuert auszuführen. Um dies zu tun, erstellen Sie eine "plist"-Datei (Property List) mit den entsprechenden Einstellungen und speichern Sie diese im Ordner "~/Library/LaunchAgents/". Zum Ausführen Ihres Scripts verwenden Sie "osascript".

Hier ist ein Beispiel für eine "plist"-Datei:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.example.MyAppleScript</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/bin/osascript</string>
        <string>/Pfad/zu/Ihrem/AppleScript.scpt</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>StartInterval</key>
    <integer>60</integer> <!-- Ausführung alle 60 Sekunden -->
</dict>
</plist>


Ersetzen Sie "/Pfad/zu/Ihrem/AppleScript.scpt" durch den tatsächlichen Pfad zu Ihrer AppleScript-Datei. Aktivieren Sie danach Ihren "launchd"-Agenten, indem Sie im Terminal den folgenden Befehl eingeben:


launchctl load ~/Library/LaunchAgents/com.example.MyAppleScript.plist


Beste Grüße & Viel Erfolg!

16. März 2023 22:49 als Antwort auf testerer

Hallo testerer,


vielen Dank für deinen Input. Ich hoffe, du nimmst es mir nicht übel, aber erstens kann man mit einer einfachen Automation auf dem iPhone ebenfalls eine Warnung einstellen, wenn der Akkustand zu niedrig bzw. zu hoch ist, das geht aus meiner Sicht einfacher, und zweitens bin ich der Meinung, dass dem Thema Akku einfach zu viel Aufmerksamkeit beigemessen wird, anstatt die Geräte einfach zu benutzen.


LG, Dutchman

16. März 2023 23:43 als Antwort auf testerer

Guten Morgen testerer


sollte meine erste Antwort für dein AppleScript für Dich hilfreich sein / solltest du an mehr Interesse haben, kann ich Dir gerne noch weitere Informationen / zum Beispiel meine Version / mein Vorschlag zu deinem AppleScript für macOS geben.


Danke für deine Frage, wobei wir uns eigentlich im Entwickler Forum hätten treffen müssen, liebe Grüße

17. März 2023 00:28 als Antwort auf Dutchman

Moin Dutchman,


kein Problem. Es geht um Mac/Script und nicht IOS/Kurzbefehle. Ich hätte auch etwas anderes als "...Akku..." nehmen können,

nur ist es eben zur Zeit mein kleiner Zeitvertreib mich in die Untiefen der Macdateien weiterdurchzuwühlen (z.B. pmset -g batt). Und ausserdem ist ja gerade der Reiz des nichtsoeinfachen Weges (der Weg ist hier das Ziel).

Ich nutze das privates Applegerät (ein s**g****s Appleteil!!!) einfach zum Spass. Und das macht Apple (mal mehr, mal weniger).


😎

17. März 2023 12:28 als Antwort auf testerer

Hallo testerer


Danke für die Erläuterung. In diesem Fall ist es sinnvoll, die Schleifen einzufügen, um das gewünschte Verhalten zu erreichen.


Anbei das AppleScript, welches zur besseren Lesbarkeit in drei Teile erfolgt - einfach bitte wieder zusammenfügen 😉


Teil 1:

-- Parameter
set min to 22 -- MinLadewert
set minreset to 60 -- bei Entladen < Wert: Reset ladeziel auf max1
set max1 to 77 -- MaxLadewert
set max2 to 99 -- Vollladewert
set wdhzeit to 10 -- Meldefenster Wdh.-zeit in s (alle 10 Sekunden)
set givupzeit to 20 -- Meldefenster Einblendzeit in s

-- Auslesen von Akkustatus und Ladeziel
set akkulevel to word 6 of paragraph 2 of (do shell script "pmset -g batt") as number -- Auslesen akkulevel
set akku to word 7 of paragraph 2 of (do shell script "pmset -g batt") as string -- Auslesen charging/discharging
set ladeziel to (read file "Macintosh HD:users:testerer:scripte:akkupflege_merker.txt") -- Auslesen ladeziel aus Merkerdatei


Teil 2:

-- setzt ladeziel immer auf max1, wenn akkulevel wieder unter minreset
set fileID to open for access file "Macintosh HD:users:testerer:scripte:akkupflege_merker.txt" with write permission
if akkulevel < minreset then set ladeziel to max1
write ladeziel to fileID
close access fileID

-- MinMeldung
if akkulevel < min and akku = "discharging" then
    repeat until akku = "charging"
        set akku to word 7 of paragraph 2 of (do shell script "pmset -g batt") as string -- Ladeerkennung
        if akku = "discharging" then
            beep 3
            activate
            display alert "Akku " & akkulevel & " %. " & "Bitte laden." buttons {"Okay"} giving up after givupzeit
        end if
        delay wdhzeit
    end repeat
end if


Teil 3:

-- Max1Meldung mit Auswahl max1 (default) oder max2
if ladeziel = max1 and akkulevel > max1 and akku ≠ "discharging" then
    repeat until akku = "discharging"
        set akku to word 7 of paragraph 2 of (do shell script "pmset -g batt") as string -- Entladeerkennung
        if akku = "charging" then
            beep 3
            activate
            display alert "Akku " & akkulevel & " %. " & "Ladekabel entfernen oder weiterladen?" buttons {"Entfernen", "Weiter"} default button 1 giving up after givupzeit
            set Diogresult to result
            if button returned of result = "Entfernen" then
                set akkumax to max1
            else if button returned of result = "Weiter" then
                set akkumax to max2
            else if gave up of Diogresult is true then
                set akkumax to max1
            end if
            set fileID to open for access file "Macintosh HD:users:testerer:scripte:akkupflege_merker.txt" with write permission
            write akkumax to fileID --schreiben ladeziel neu
            close access fileID
            set ladeziel to (read file "Macintosh HD:users:testerer:scripte:akkupflege_merker.txt") --Auslesen ladeziele neu- innerhalb repeat-loop
            if ladeziel = max2 then set akku to "discharging" --Schleifenausgang bei Auswahl max2
        end if
        delay wdhzeit
    end repeat
end if

-- Max2Meldung
if ladeziel = max2 and akkulevel > max2 and akku ≠ "discharging" then
    repeat until akku = "discharging"
        set akku to word 7 of paragraph 2 of (do shell script "pmset -g batt") as string --Entladeerkennung
        if akku ≠ "discharging" then
            beep 3
            activate
            display alert "Akku voll. Bitte Ladekabel entfernen." buttons {"Okay"} default button 1 giving up after givupzeit
        end if
        delay wdhzeit
    end repeat
end if


Damit endet vorerst meine Beteiligung, welche schließlich nur das Ziel hatte, in eine kurzfristige Diskussion der Möglichkeiten / Alternativen zu gehen, so dass auf dieser Basis ein Abschluss außerhalb der Community erreicht werden kann.


Ich hoffe, diese Ansicht wird wertschätzend geteilt?!


Ansonsten gilt:


Ask questions and discuss development topics with Apple engineers and other developers.

Apple Developer Forums


Liebe Grüße & viel Erfolg

Dieser Thread wurde vom System oder dem Community-Team geschlossen. Du kannst alle Beiträge positiv bewerten, die du hilfreich findest, oder in der Community nach weiteren Antworten suchen.

"Akkupflege" mit AppleScript

Willkommen in der Apple Support Community
Ein Forum, in dem Apple-Kunden sich gegenseitig mit ihren Produkten helfen. Melde dich mit deinem Apple Account an, um Mitglied zu werden.