Resolving Duplicate Alarm Entries in WinCC V7.3 Update 8
WinCC V7.3 Update 8 runtime environments frequently surface a recurring anomaly where a single alarm appears as three visually identical rows in the Alarm Control. The rows share an identical second-resolution timestamp, leading operators to assume the alarm was raised three times. In the vast majority of cases the system is functioning correctly and the apparent duplicate is the standard Came In, Went Out, and Acknowledged state transition of one logical message compressed into a one-second window. A second, separate failure mode involves C-scripts returning inconsistent string values or generating no value at all when invoked from multiple buttons that target different tags. Both problems can be diagnosed and eliminated without reinstalling WinCC or rebuilding the project.
1. Problem Overview
WinCC V7.3 stores every alarm transition as a discrete message event in the message archive. Each event carries a state identifier, a 32-bit message number, the configured user text blocks, and a system block set that includes date, time, milliseconds, computer name, user name, priority, and state. The default column set visible in the WinCC Alarm Control Alarm Logging Control shows only Date, Time, Number, and Message text. The millisecond component and the state are omitted by default, so three events that occurred 320 ms apart but within the same calendar second render as three rows with identical timestamps and identical message text. Operators who depend on the on-screen text alone see this as a duplicate alarm bug; engineers reading the archive see it as a missing-column bug.
A secondary failure mode observed in the same Update 8 build involves C-scripts that read or write string tags via GetTagChar and SetTagChar. The GetTagChar function returns an LPCTSTR that points into the WinCC tag image. The pointer can become invalid between the call and the read access if the tag is overwritten by another subscriber, if the connection to the AS drops and the tag enters a substituted quality, or if the script is invoked from a hot-key path during a graphics runtime startup race. The invalid pointer dereference produces either a stale string, an empty string, or a WinCC runtime exception that silently aborts the script without raising a visible diagnostic. Adding the APDiag output channel resolves the visibility gap.
2. Root Cause: Three Message States in One Second
Each WinCC alarm carries one of nine defined message states defined in the WinCC Information System under System blocks > State:
| State ID (decimal) | State ID (hex) | State Name | Visible in Alarm Control? |
|---|---|---|---|
| 1 | 0x0001 | Came In | Yes (default) |
| 2 | 0x0002 | Went Out | Yes (default) |
| 3 | 0x0003 | Acknowledged | Yes (default) |
| 4 | 0x0004 | Locked | Yes |
| 5 | 0x0005 | Unlocked | Yes |
| 6 | 0x0006 | Reset | Optional |
| 7 | 0x0007 | Comment added | No (comment dialog) |
| 8 | 0x0008 | Comment deleted | No |
| 9 | 0x0009 | Loop In Alarm | Configurable |
A process variable that triggers an alarm, returns to normal within 250 ms, and is acknowledged by the operator 70 ms later produces three archive entries in the same second. The default WinCC Alarm Control Selection filter excludes the State system block from the projection, so all three rows are visually identical. Operators cannot tell whether they are looking at three separate alarms, one alarm with state transitions, or a graphics-runtime repaint artifact. The fix is never to suppress the rows; it is to expose the millisecond timestamp and the State system block so the events can be distinguished.
3. Enabling Millisecond Timestamps in the Alarm Control
The Alarm Control column selection is configured per picture and per process picture template. Open the picture containing the WinCC Alarm Control in Graphics Designer, double-click the control, and switch to the Columns tab. Add the system block Millisecond from the available columns and position it directly to the right of the Time column. Apply, rebuild the picture, and reload the runtime. Repeat for every picture that hosts an Alarm Control, including the message overview, the short-term archive view, and the long-term archive view.
For projects that use the modern WinCC AlarmControl OCX in process pictures or in the global template, the column set is propagated through the AlarmControl.Configuration properties. The relevant property is ColumnConfig; populate the array with the column order required for the plant. A typical configuration for a continuous process plant where state transitions must be visible is:
| Column Index | Column Name | Width (px) | Alignment |
|---|---|---|---|
| 0 | Date | 90 | Left |
| 1 | Time | 70 | Left |
| 2 | Millisecond | 60 | Right |
| 3 | State | 110 | Left |
| 4 | Priority | 60 | Center |
| 5 | Number | 70 | Right |
| 6 | Message text | 380 | Left |
| 7 | Point of error | 140 | Left |
Once the Millisecond column is active, three events that share a one-second timestamp will show values such as 14:07:23.118, 14:07:23.214, and 14:07:23.392. The 96 ms and 178 ms gaps immediately demonstrate that the rows are not duplicates.
4. Adding the State Column to Distinguish Events
The State system block returns the numeric state ID described in the table above. Operators read numeric IDs poorly, so configure a status text via Text Library in the WinCC Explorer. Open Text and Graphic Lists > Text Library, create a new list named AlarmState, and assign the following entries under IDs 1 through 9:
| List Index | Display Text |
|---|---|
| 1 | Came In |
| 2 | Went Out |
| 3 | Acknowledged |
| 4 | Locked |
| 5 | Unlocked |
| 6 | Reset |
| 7 | Comment added |
| 8 | Comment deleted |
| 9 | Loop In Alarm |
Wire the State column to AlarmState in the column configuration. Operators now see Came In / Went Out / Acknowledged in the same row group and understand the transition without ambiguity. For reports that consume the archive database directly through WinCC_OLEDB, the same state IDs are returned by the EVSTATE column of the ALView view.
5. Diagnosing C-Script Failures with APDiag
The APDiag tool is shipped as part of the WinCC V7.3 installation media under WinCC\Tools\APDiag. It hooks the WinCC scripting runtime and prints every GetTag*, SetTag*, GetProperty*, and SetProperty* call to either the diagnostic console or a log file. APDiag is the canonical way to determine whether a script is even executing, whether the tag value is what the script expects, and whether the return code indicates a quality problem or a connection drop.
The standard commissioning workflow is:
- Launch
APDiag.exefrom the project directory<Project>\<ComputerName>\APDiagor from Start > Siemens Automation > WinCC V7.3 > Tools. The binary requires that the WinCC runtime is active so that it can attach to the shared memory tag image. - Click Settings > Output to file and select a target such as
C:\WinCC_Diag\apdiag_<timestamp>.log. Logging to file is required for offline post-mortem analysis because the runtime screen real estate is too small to capture long sessions. The official procedure is documented in the Siemens support article How do you write outputs from the "APDiag" diagnostic tool to a file? - Filter the channel list to the tags used by the failing script. APDiag supports wildcard filtering; for example, enter
Plant42_Pump_*to capture every tag whose name begins withPlant42_Pump_. - Trigger the button that fails in the runtime. APDiag prints the
GetTagCharcall, the return code, the value returned, theSetTagCharcall, and the return code in real time. - Compare the result for the working button with the result for the failing button. If the failing button never produces an
APDiagentry, the script is not being invoked at all; the problem is event wiring, not the script logic. If the failing button produces an entry with return code-1or0xFFFF, the tag is not in the runtime tag image or has a quality of Bad.
The two Siemens support articles that document the launch procedure and the diagnostic primitives are How do you start the "APDiag" script diagnostics tool? and How do you use the diagnostic tool "APDiag" to debug C scripts?. Follow them in order; the launch article documents the registry entries that APDiag creates on first start.
6. String Pointer Validity in WinCC C-Scripts
The GetTagChar function signature is:
LPCTSTR GetTagChar(LPCTSTR lpszTagName);
The returned pointer references the string that WinCC stores in its internal tag image. The pointer is only valid until the next GetTagChar call returns, until the tag value is overwritten by the data manager, or until the connection to the AS enters a substitution state. The Siemens FAQ "What should you watch out for when processing strings in scripts?" (entry 7929092) requires every consumer of GetTagChar to copy the string immediately and to validate the pointer before dereferencing it.
The recommended pattern is:
// Safe pattern for reading a WinCC string tag in a C-script
#include "apdefap.h"
void OnLButtonDown(char* lpszPictureName, char* lpszObjectName,
char* lpszPropertyName, UINT nFlags, long x, long y)
{
LPCTSTR pszRaw = GetTagChar("Plant42_TagName");
if (pszRaw == NULL) {
// Tag not present or quality Bad - abort cleanly
printf("GetTagChar returned NULL for Plant42_TagName\r\n");
return;
}
// Copy the string immediately into a local buffer
char szCopy[256];
strncpy(szCopy, pszRaw, sizeof(szCopy) - 1);
szCopy[sizeof(szCopy) - 1] = '\0';
// Now use szCopy for all downstream processing
SetTagChar("Plant42_Derived", szCopy);
}
The naive pattern that copies directly from pszRaw into a downstream API call without the intermediate local buffer is the most common source of intermittent string corruption in WinCC V7.3. The race window is small but reproducible on systems with more than 8,000 tags, on systems running WinCC WebNavigator clients, and on virtual machines with shared memory compression.
7. Why One Button Works and the Other Fails
When two buttons invoke scripts that differ only in tag names, the root cause is almost always one of the following:
| Failure Mode | Symptom | Diagnostic Step | Fix |
|---|---|---|---|
| Tag missing from project | Second button silently does nothing | Check WinCC Explorer > Tag Management; verify the tag exists on the same channel/unit | Add the tag, redeploy, restart runtime |
| Tag in different channel | APDiag returns -1 | Inspect tag properties > Channel Unit; compare with working tag | Recreate tag under correct channel |
| String pointer invalid | Empty string written downstream | Enable APDiag file output, reproduce | Apply the safe copy pattern from section 6 |
| Button event wired to wrong script | APDiag shows script never called | Right-click button > Properties > Events > Mouse > Press; confirm script name | Reassign event to correct script |
| Update cycle too slow | Stale value returned | WinCC Explorer > Tag Management > Properties > Update | Lower the update cycle to 500 ms or use Acquisition cycle = 1 s for steady tags, 100 ms for control tags |
| Hot-key collision | Second script aborted by first | Check button Properties > Miscellaneous > Hotkey | Assign distinct hotkeys or remove hotkeys |
8. Tuning the Tag Update Cycle
The tag update cycle controls how often the WinCC data manager samples the AS for a new value. The cycle applies per channel; setting it to 500 ms globally floods the S7 connection with requests and can starve WebNavigator clients. The recommended practice is to classify tags into acquisition classes:
| Acquisition Class | Use Case | Recommended Cycle |
|---|---|---|
| 1 (Default) | Operator-display tags, slow process variables | 1000 ms |
| 2 (Fast) | Control-loop PVs, interlocks | 500 ms |
| 3 (Very Fast) | Drive status words, safety I/O | 250 ms |
| 4 (Event-driven) | Alarms, acknowledgements | On change |
| 5 (Manual) | Setpoints changed by operator | On demand |