WinCC Redundant Server State Detection in VBScript and C-Script

David Krause11 min read
SiemensTechnical ReferenceWinCC
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

WinCC Redundant Server State Detection in VBScript and C-Script

Siemens WinCC (TIA Portal and WinCC RT Professional / WinCC V7) supports a hot-standby server pair that runs in parallel so that the standby server takes over the OS client connections, alarms, and tag archive role without operator action when the master fails. The redundancy state is exposed to the runtime database as a built-in internal tag, @RedundantServerState, which can be read from any VBScript action, C-script action, or faceplate dynamic. This reference documents how to evaluate that tag, how to use it to gate one-shot actions, and how to verify the implementation on a live pair.

1. WinCC Redundancy Architecture Overview

A WinCC redundant server pair consists of two runtime servers configured with identical projects. The pairing is defined in the WinCC Explorer under Server-Server-Redundancy (WinCC V7) or Redundancy > Server Pair (WinCC Professional). The two nodes exchange state information over TCP port 80 (default) and continuously mirror project data, tag values, and alarm acknowledgements.

Component Master (active) Standby (passive)
OS client connections Primary Failover only
Tag logging archive Write enabled Mirror only
Alarm logging Write enabled Mirror only
User archive writes Primary Sync replication
Time synchronization role Master clock for clients Slave

Both servers run the project continuously. The standby is not idle; it processes tags, evaluates scripts, and maintains its own copy of the archive. The only difference from the client perspective is which server answers new picture requests and which server is authorized to write to the central archive. This is the conceptual basis for the rule: gate one-shot actions by redundancy state, not by assuming the script only runs on one node.

Important: Both servers execute scheduled and tag-triggered actions. The WinCC scheduler is duplicated on both nodes. If your action is not idempotent (for example, sending an email, opening a valve, starting a batch ID), it must be guarded by the master/standby check, otherwise it will fire twice per event.

2. Redundancy State Machine

The internal state machine exposed to the runtime is a small set of values. @RedundantServerState reports the local machine's role from the OS-client perspective.

Value State Meaning
0 Undefined / Not in redundancy Server is not part of a configured pair, or redundancy has not yet been negotiated.
1 Master Local server is currently the active server. OS clients are bound to this node for new picture requests and archive writes.
2 Standby Local server is the hot standby. Project is running, but archive and client-serving role belongs to the master.

The state transitions are driven by partner liveness, redundancy state poll, and the user-defined failover/switchover trigger. Typical transition latency from a hard master fault to standby promotion is 2-10 seconds, depending on configured Failure detection time (default 5 s) and Switchover delay settings.

3. The @RedundantServerState Internal Tag

@RedundantServerState is a system tag, automatically created by WinCC in every project that has redundancy enabled. It is a 16-bit unsigned integer (WORD) and is read-only. The tag is updated whenever the WinCC redundancy manager changes its internal state. The update is propagated to all connected OS clients and is also available to local script actions without any additional configuration.

Property Value
Tag name @RedundantServerState
Data type WORD (unsigned 16-bit)
Direction Read-only
Update mechanism Internal, on redundancy state change
Available in WinCC V7.x, WinCC RT Professional, WinCC Professional (TIA)

To use the tag in a script, reference it as you would any other internal tag. No declaration, no add-in, no OCX wrapper is required. The prefix @ marks it as a system tag and prevents name collisions with project tags.

4. Related Internal Redundancy Tags

WinCC exposes several companion tags that are useful when you need more than a single bit of state. These are read in the same way as @RedundantServerState.

Tag Type Meaning
@RedundantServerState WORD 1=Master, 2=Standby, 0=undefined
@RM_MASTER BOOL TRUE on master, FALSE on standby (legacy alias in older versions)
@RM_SERVER_NAME TEXT Computer name of the partner server
@RM_OFFLINE_STATE BOOL TRUE if local server has lost its partner
@LocalMachineName TEXT Local server computer name
Field note: Tag names with the @RM_ prefix are part of the WinCC Redundancy Manager interface and are documented in the WinCC Information System under Redundancy > System Tags. Treat the table above as the canonical set; do not invent new ones. If a tag is not visible in the tag browser after redundancy is enabled, the redundancy license or partner connection is not yet established.

5. Detecting Master/Standby in VBScript

VBScript is the standard scripting language in WinCC RT Professional and WinCC Professional. Actions are placed in the project tree under Scripts > VBS Actions and can be triggered by tag change, scheduler, or picture open. Inside the action, access the internal tag through the HMIRuntime object.

5.1 Reading the state in a cyclic VBS action

' VBScript: check redundancy state once per cycle
Dim nState
nState = HMIRuntime.Tags("@RedundantServerState").Read

Select Case nState
    Case 1
        ' Master: this is the active server
        ' Execute master-only logic here
    Case 2
        ' Standby: suppress one-shot actions
    Case Else
        ' 0 or unexpected: redundancy not yet negotiated, fail safe
        Exit Sub
End Select

The HMIRuntime.Tags(...).Read call returns a variant; cast to integer using CInt if you intend to compare it numerically with non-magic numbers. Reading the tag does not require a prior .Write because the internal tag is constantly refreshed by the redundancy manager.

5.2 Global module pattern (project-wide master check)

For a clean implementation, expose a helper function in a global module so every action calls the same gate.

' Module: modRedundancy
Public Function IsMaster() As Boolean
    Dim vState
    vState = HMIRuntime.Tags("@RedundantServerState").Read
    IsMaster = (CInt(vState) = 1)
End Function

Public Function IsStandby() As Boolean
    Dim vState
    vState = HMIRuntime.Tags("@RedundantServerState").Read
    IsStandby = (CInt(vState) = 2)
End Function

Call sites then read:

If IsMaster() Then
    HMIRuntime.Tags("MyOneShotFlag").Write 1
End If

Putting the logic in a single module makes it trivial to change the gating policy later (for example, switching to ExecuteOnlyOnMaster = false during commissioning) without touching every action.

6. Detecting Master/Standby in C-Script

C-scripts (WinCC V7 ANSI C) access internal tags through the GetTagWord family of API functions declared in apdefap.h. The state is a 16-bit value, so use GetTagWord.

6.1 Reading the state in a C-action

/* C-Script: check redundancy state */
#include "apdefap.h"

void CheckRedundancyState(void)
{
    WORD wState = 0;
    DWORD dwResult = GetTagWord("@RedundantServerState", &wState);

    if (dwResult != 0) {
        /* Tag read error - log and return */
        printf("RedundancyState read failed, code=%lu\r\n", dwResult);
        return;
    }

    switch (wState) {
        case 1:
            /* Master */
            break;
        case 2:
            /* Standby */
            break;
        default:
            /* 0 = undefined */
            break;
    }
}

For legacy projects, the same value is available as the boolean @RM_MASTER read with GetTagBit, but the WORD form is the recommended interface and is forward-compatible across all current WinCC versions.

6.2 Threshold-triggered C-action

When the action is fired by a tag change, a common pattern is to perform the master check first, then re-check after any wait or blocking call, because the role may have flipped during a long action.

#include "apdefap.h"

void OnTankLevelTrigger(void)
{
    WORD wState = 0;
    if (GetTagWord("@RedundantServerState", &wState) != 0) return;
    if (wState != 1) return;                /* Gate 1: only on master */

    /* ... do work that takes time ... */

    /* Gate 2: re-check after potentially long operation */
    if (GetTagWord("@RedundantServerState", &wState) != 0) return;
    if (wState != 1) return;

    /* Commit result */
    SetTagWord("MyResult", 0x0001);
}

The double-check pattern is important when the script duration exceeds the configured failover time, otherwise a flip that happens mid-script can cause both servers to write the same one-shot outcome.

7. Triggering Script Execution Only on Master

Three practical patterns are used in production WinCC projects. Choose based on whether the script is one-shot, idempotent, or has external side effects.

7.1 In-script gate (most common)

Run the script on both servers. At the top, read @RedundantServerState and exit if the value is not 1. This is the safest pattern for non-idempotent logic (e-mail, batch start, valve command) and is what Siemens documents in the WinCC Information System under Redundancy > Master-Standby Behaviour > Scripts.

7.2 Scheduler gate

Use a WinCC scheduler that is itself set to fire only when a calculated condition is true. Combine the schedule with a tag-prefix condition:

Condition: @RedundantServerState == 1
Event:     Daily 06:00:00

Schedulers do not natively expose the redundancy state, so the cleanest realization is to drive the schedule from a derived tag updated by a small cyclic VBS action that copies the comparison result into a BOOL tag, e.g. IsMasterTag = (@RedundantServerState == 1). The scheduler then triggers on IsMasterTag rising edge.

7.3 Picture-level dynamic

For faceplate or screen visibility, bind the Visible property of a button or a message line to a dynamic dialog that compares the internal tag value. This avoids executing a script at all when the operator must not see the control on the standby.

Field note: In all three patterns, do not rely on the script's host computer name (for example HMIRuntime.Environment.ComputerName) to decide master/standby. The redundancy state is the source of truth; the computer name is a configuration detail that does not change when a switchover occurs.

8. Edge Cases and Field-Proven Caveats

Edge case Symptom Mitigation
Partner offline, local promoted to master State transitions 2 -> 1 on the local server; @RM_OFFLINE_STATE is TRUE Do not assume the partner is reachable; gate archive writes but allow tag evaluation.
State value reads 0 at project start Redundancy handshake not finished; scripts that read 0 will skip the action Add a startup delay or subscribe to a cyclic check for non-zero value before relying on the gate.
Script runs longer than failover time Role flip mid-script causes both servers to commit Use the double-check pattern from Section 6.2.
Internal tag not in tag browser Project deployed without redundancy license activated Activate the WinCC Redundancy option in SIMATIC Management Console / Authorizations.
Tag value updates are buffered Action fires on the old value if the action is triggered by the tag change Subscribe to a separate scheduler-based timer instead of a tag-change trigger for critical gates.
C-script uses GetTagBit on the WORD tag Reads always 0 because the bit layout is implementation-specific Always use GetTagWord for @RedundantServerState.

9. Verification and Diagnostics

Before relying on the master/standby gate in production, verify the implementation end-to-end.

  1. Inspect the tag in the WinCC Tag Browser. In the running project, open Tag Management > Internal Tags and confirm @RedundantServerState is present. Right-click and select Properties to confirm the data type is WORD and the update direction is system-driven.
  2. Force a manual switchover. In WinCC Explorer, choose Server-Server-Redundancy > Force Standby on the current master. Confirm that within the configured switchover delay the value flips to 2 on the original master and 1 on the new master, and that all gated scripts behave accordingly.
  3. Power-fail the master. Pull the network on the active server. The standby should promote automatically. Monitor the Guf diagnostic channel for the redundancy event log and confirm that no script-triggered action fired twice.
  4. Trace the tag in the Tag Logging archive. Add the internal tag to a logging tag group with a 1-second acquisition cycle. The archive will show exactly when the state changed, useful for post-incident analysis.
  5. Test the helper function. Add a temporary button bound to a VBS action that calls IsMaster() and writes the boolean result to a visible internal tag. The operator screen can then show a permanent indicator of which server is currently authoritative for actions.
Safety-critical systems: If the action drives a Safety Integrated or fail-safe output, do not gate it on the WinCC redundancy tag alone. Use the F-CPU's own redundancy concept and route the enable through a hardwired AND of the F-CPU sign-of-life and a separate WinCC tag confirmed by an independent channel. Redundancy state in the SCADA layer is for supervisory and informational logic, not for primary safety interlocks.

10. Reference: WinCC Information System Paths

The following paths in the WinCC Information System (V7.5 SP2 and later) document the redundancy state tag and the supported scripting interfaces.

  • Working with WinCC > Redundancy > Configuring Redundancy - server pair configuration
  • Working with WinCC > Redundancy > System Tags - canonical list of @RedundantServerState and related tags
  • Working with WinCC > Redundancy > Master-Standby Behaviour > Scripts - master-only execution patterns
  • VBScript Reference > HMIRuntime Object > Tags Collection - tag read/write API
  • C-Script Reference > Internal Functions > Tag Functions - GetTagWord / SetTagWord signatures

FAQ

What is the exact value of @RedundantServerState on the active server?

On the master (active) server, @RedundantServerState reads the integer value 1. On the standby it reads 2. The value 0 means redundancy has not been negotiated yet, typically during the first few seconds after runtime start.

Can I write to @RedundantServerState from a script?

No. The tag is system-managed and read-only from the script's perspective. Attempting to write to it returns an error from the WinCC tag manager. The value is set exclusively by the WinCC Redundancy Manager based on the partner's liveness and switchover commands.

Does the standby server really execute all VBS and C actions?

Yes. In WinCC redundancy the standby is a hot standby: the runtime, the tag manager, and the script engine are fully active on both nodes. Scripts that must run only once per event must gate themselves on @RedundantServerState; otherwise they will fire on both servers.

How fast does the redundancy state update after a failover?

With default settings (failure detection 5 s, switchover delay 0 s), the standby promotes to master within roughly 2 to 10 seconds of the partner becoming unreachable. The internal tag is updated at the moment of promotion, so scripts that read it after the update see 1 on the new master and 2 on the new standby.

Is @RedundantServerState available in WinCC Professional (TIA Portal) as well?

Yes, the same internal tag is available in WinCC RT Professional and WinCC Professional projects that have the Redundancy option licensed and a configured server pair. The data type, values, and read APIs (HMIRuntime.Tags in VBScript, GetTagWord in C-script) are identical across the V7 and TIA families.

Back to blog