PC und WinCC durch USV herunterfahren

Wenn ein PC mit WinCC bei Stromausfall durch eine unterbrechungsfreie Stromversorgung (USV) heruntergefahren werden soll, ergibt sich das Problem, dass dies mit den Boardmitteln von Windows nicht möglich ist, da die aktive Runtime von WinCC das Herunterfahren blockiert.

Siemens bietet dafür das kostenpflichtige Tool „UPS-Shutdown“ an, welches das WinCC beenden kann und den PC herunterfährt. Das Tool ist mit einem Listenpreis von über 400 € für so eine simple Funktion relativ teuer und erfordert, dass zu der USV ein Tool gehört, welches bei Stromausfall eine Datei in einen Ordner schreiben kann.

Ich präsentiere hier eine (kostenlose!) Lösung, die direkt im WinCC läuft und kein extra Tool der USV erfordert (eine Spende ist gerne gesehen: https://www.buymeacoffee.com/vanseforge).

Ein VB-Script (WinCC-Aktion) liest den in Windows angezeigten Akkustand und, ob der Akku geladen wird. Die USV muss somit nur per USB-Kabel mit dem PC verbunden werden.

Ein weiteres Script (WinCC-Aktion), diesmal in C geschrieben, wartet auf die Rückmeldung des VB-Scriptes und fährt dann den PC herunter.

Der Grund, warum dies mit VBS und C gemacht wird, ist, dass das Auslesen des Akkustandes in VBS deutlich einfacher ist und WinCC in C schon eine Funktion zum Herunterfahren bietet.

Für die Kommunikation der Scripte muss die interne WinCC-Variable (Bit) „PC_herunterfahren“ angelegt werden.

Die Scripte können natürlich beliebig erweitert werden, wenn z.B. eine Log-Datei geschrieben werden soll, wenn Stromausfall ist und der PC herunterfährt oder der Akkustand in eine Variable geschrieben werden, wenn dieser visualisiert werden soll.

Das VB-Script zum Prüfen des Akku-/Ladestandes:

On Error Resume Next

' WINCC:SCREENNAME_SECTION_START
' Const ScreenNameInAction = "ScreenName"
' WINCC:SCREENNAME_SECTION_END
' WINCC:TAGNAME_SECTION_START
' Const TagNameInAction = "TagName"
Const PCHerunterfahren = "PC_herunterfahren"
' WINCC:TAGNAME_SECTION_END

Dim BatteryStatus, EstimatedChargeRemaining, objWMIService, colItems, objItem

' Akkudaten ermitteln
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_Battery",,48)
For Each objItem In colItems
    
    BatteryStatus = objItem.BatteryStatus
    EstimatedChargeRemaining = objItem.EstimatedChargeRemaining
   
Next

If BatteryStatus = "" Then
	Exit Function
End If

' Bit setzen, wenn der Akku nicht geladen wird und Akkustand niedrig ist.
' BatteryStatus = 1 heißt, dass der Akku nicht geladen wird
If BatteryStatus = 1 And EstimatedChargeRemaining < 30 Then
		HMIRuntime.Tags(PCHerunterfahren).Write 1
End If

Das Script muss bei den WinCC-VBS-Aktionen eingefügt werden. Die Aktion muss zyklisch getriggert werden, die Wahl des Zyklus bestimmt, wie schnell auf den Netzausfall reagiert wird.

In Zeile 29 kann der Akkustand, bei dem reagiert werden soll, angepasst werden.

Das C-Script zum Herunterfahren des WinCCs und des PCs:

#include "apdefap.h"
int gscAction( void )
{

/ WINCC:TAGNAME_SECTION_START
// syntax: #define TagNameInAction "DMTagName"
// next TagID : 2
#define PCHERUNTERFAHREN "PC_herunterfahren"
// WINCC:TAGNAME_SECTION_END

// WINCC:PICNAME_SECTION_START
// syntax: #define PicNameInAction "PictureName"
// next PicID : 1
// WINCC:PICNAME_SECTION_END

// Bit vom VBScript zum Herunterfahren des PCs
if(GetTagBitWait(PCHERUNTERFAHREN))
{
	// WinCC beenden und PC herunterfahren
	DMExitWinCCEx (DM_SDMODE_FORCE_POWEROFF); 
}

return 0; 
}

Das Script muss bei den WinCC-C-Aktionen eingefügt werden. Die Aktion muss durch die Variable „PC_herunterfahren“ getriggert werden.

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert