cPing - WHS Ruhezustand durch letztes Netzwerkgerät

  • Ich hab mir ein kleines Skript geschrieben, mit dem ich meinen WHS (Windows Home Server) in den Ruhezustand versetzten kann, wenn alle Netzwerkgeräte ausgeschaltet sind!

    Funktion:
    - WHS fährt jede Früh automatisch aus dem Ruhezustand hoch
    - mein Programm läuft im Hintergrund
    - wenn eine Gewisse Zeit überschritten wird (22Uhr), vor der es gar nichts macht
    - es testet ob schon ein Netzwerkgerät erreichbar ist (mittels Ping()), damit es nicht herunterfahrt, weil es meint, dass alle Geräte schon aus sind (obwohl noch keine gestartet sind)
    - wenn min. ein Gerät anpingbar ist, pingt es weiter und testet so lange bis keine Geräte mehr erreichbar sind
    - falls das der Fall ist, gibt es eine MsgBox aus in der man noch 30s verhindern kann, dass der WHS in den Ruhezustand fährt
    - dann wieder holt sich alles von Vorne

    Programmablaufplan
    Quellcode

    ### Pastebin Link ###

    [autoit]

    ; Include Dateien
    #include-once
    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    ; TrayIcon
    ;#NoTrayIcon ; TryIcon ausblenden
    Opt("TrayAutoPause", 0) ; Keine Pause, bei Klick
    Opt("TrayIconDebug", 1) ; zeige Debug

    [/autoit] [autoit][/autoit] [autoit]

    ; Variablen
    $zeit_ping = 60 * 1000 ; Abstände der Pings | in ms
    $zeit_aus = 30 ; Wann der WHS dann herunterfährt, nach dem letzten Ping | in s
    $zeit_start = 5 * 60* 1000 ; Wie lange das Programm, nach dem herunterfahren wartet, bis es das erste mal pingt | in ms
    $zeit_uhrzeit = 22 ; Früheste Zeit zum herunterfahren | in h

    [/autoit] [autoit][/autoit] [autoit]

    dim $ping[2]
    dim $host[UBound($ping)]
    $host[0] = "client1"
    $host[1] = "192.168.1.123"

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    ; Warten bis Uhrzeit erreicht ist
    While 1
    if @HOUR >= $zeit_uhrzeit then exitloop
    sleep($zeit_ping)
    Wend
    ;MsgBox(0, "", "Min. ein Gerät ist an!", 3)

    ; Warten bis min. ein Gerät gestartet ist
    While 1
    for $n=0 to UBound($host)-1
    $ping[$n] = Ping($host[$n], 4000)
    ;$error = @error
    ;MsgBox(0, "Test:", $host[$n])
    next

    if _ArrayToString($ping, '') <> 0 then exitloop
    sleep($zeit_ping)
    Wend
    ;MsgBox(0, "", "Min. ein Gerät ist an!", 3)

    ; Warten, bis alle Geräte ausgeschalten sind
    While 1
    for $n=0 to UBound($host)-1
    $ping[$n] = Ping($host[$n], 4000)
    ;$error = @error
    ;MsgBox(0, "Test:", $host[$n])
    next

    if _ArrayToString($ping, '') = 0 then exitloop
    sleep($zeit_ping)
    Wend
    ;MsgBox(0, "", "Alle Geräte sind aus!", 3)

    ; WHS wird in den Ruhezustand versetzt
    $msg = MsgBox(4, "", "Alle Geräte sind aus, der WHS wird in den Ruhezustand versetzt!", $zeit_aus)
    if $msg <> 7 then
    Shutdown(64, "Durch cPing!") ; Ruhezustand
    ;MsgBox(0, "", "WHS ist jetzt aus!", 10)
    endif
    sleep($zeit_start)
    Wend

    [/autoit]

    Das mit der ini-Abfrage und die Start-GUI sind noch nicht fertig, der Rest funktioniert mit den festen Werten!

    Das mit den vielen sleeps gefällt mir nicht so ganz, dass kann man doch sicher besser machen?
    Das der zumindest bei der Uhrzeit-Abfrage so lange wartet, bis die Zeit erreicht ist ... ohne sleep und while-Schlife!?
    Aber die System-Auslastung ist eh bisher minimal ...

    Ich würde auch gerne noch einbauen, dass man damit die Uhrzeit einstellen kann, wann der WHS wieder hochfährt.
    Bisher mache ich das über ein extra Programm ...

    Was kann ich noch verbessern?

  • Meine Vorschläge dazu:
    - Windowstaskplaner/Aufgabenplaner (Crontab) das Programm erst um 22Uhr starten
    - Die IP-Adressen aus dem ARP-Cache auslesen (wenns dein Server ist, werden sich alle Rechner eh einmal bei diesem melden)
    - Im Programm alle 60 Sek per AdLib einen "Interrupt" ausführen= minimalste CPU-Last

  • - Windowstaskplaner/Aufgabenplaner (Crontab) das Programm erst um 22Uhr starten

    Könnte ich machen, nur ...
    ... ist es um umständlicher den Task über "Geplante Tasks" hinzufügen/ändern. Kann man mit AutoIt direkt dort einen Task hinzufügen/ändern?
    ... wenn der WHS um 22Uhr nicht an ist passiert nichts, weil der Task nicht startet (schon getestet)!
    ... ich möchte mit meinem Programm dokumentieren, wann der WHS startet und herunterfährt. Wenn ich das über "Geplante Tasks" starten lasse brauche ich noch ein extra Programm, dass da dokumentiert, dass dann aber auch immer laufen muss.

    - Die IP-Adressen aus dem ARP-Cache auslesen (wenns dein Server ist, werden sich alle Rechner eh einmal bei diesem melden)

    Das ist nicht direkt ein Server, er läuft wie jeder andere PC in meinem Netzwerk ... ist kein DHCP-Server ist sonst was, nur ein Datengrab.
    Was mache ich mit IP-Adresse dann?
    Ich möchte ja nicht alle Geräte im Netzwerk überwachen, sondern nur ein paar. Bei mit konkret der PC und die MediaStation. Ob der PC von meiner Mutter an ist, ist irrelevant ;)
    Deshalb soll er nur eine selbst definierbare Liste von Clientnamen oder IP-Adresse abfragen.

    - Im Programm alle 60 Sek per AdLib einen "Interrupt" ausführen= minimalste CPU-Last

    Was meinst du damit?
    Kann damit gerade gar nichts anfangen.

  • - Dein Script kann auch nicht funktionieren, wenn per Taskplaner gestartet, da unbedingt ein Rechner laufen muss um in die nächste Stufe zu gelangen -> ändern
    Taskplaner unter Windows mit AutoIT: Automatisches Ausführen '] Automatisches Ausführen[/url]
    Die Startzeit deines WHS steht doch eh schon in den Windowslogfiles, warum willst du sie dann noch extra haben?

    - Dann Funktioniert das mit dem ARP-Cache ja trotzdem, da sich dann ja nur die Maschinen auf dem "Datengrab" anmelden, die eh was vom WHS wollen
    Mach ma ne Komandozeile auf und tipp da mal

    Code
    ARP -a

    ein. Das kannste auslesen in AutoIT

    - Adlib: http://translation.autoit.de/onlinehilfe/fu…libRegister.htm

    P.S.: Schaff dir ne Linuxmaschine an, da geht sowas per Crontab & Bash :rock: