Problem Overview
A WinCC Unified V17 faceplate is configured with two interface tags: a process tag (UDT type) and a color tag used for the plate background. From a button on the same screen, a script attempts to dynamically re-target the UDT interface tag so a single faceplate instance can represent different valves. The script runs without raising a runtime error, but the faceplate continues reading the original tag binding. The same script that changes the color interface works correctly, which isolates the failure to the tag-typed interface.
This behavior is observed when the script is attached to a control on the host screen. It is also observed when the script runs from a screen window (swContent) that hosts a different screen. In both cases, calls through the global HMIRuntime object fail to mutate the tag binding on the faceplate instance.
Affected Versions and Build Levels
| Component | Version | Behavior |
|---|---|---|
| TIA Portal | V17 Update 4 and earlier | SetPropertyValue silently fails on Tag interfaces |
| WinCC Unified Runtime | V17.0.x | Screen.Items method works on the active screen only |
| WinCC Unified Runtime | V18+ | API extensions documented; verify against release notes |
Always confirm the runtime image version on the panel or PC runtime. The Unified HMI screen object model has changed between V17 and V19, and method signatures on the HMIRuntime object are not always backward-compatible.
Symptom Details
The original failing script attempts one of the following patterns against a faceplate instance named FpContainer with an interface property ValveTag:
// Pattern A — direct HMIRuntime call (does not bind the tag interface)
HMIRuntime.SetPropertyValue("FpContainer", "ValveTag", "HMI_Tag_02");
// Pattern B — qualified path through the faceplate property
HMIRuntime.UI.Screen("MainScreen").ScreenItems("FpContainer").Properties.ValveTag = "HMI_Tag_02";
// Pattern C — assignment through the Properties collection on the runtime object
HMIRuntime.Properties.ValveTag.Tag = "HMI_Tag_02";
None of these patterns rebind the faceplate to HMI_Tag_02. The faceplate continues reading the tag configured at design time. No error is raised in the script trace, no exception is logged, and the panel's diagnostic buffer is silent. This is the diagnostic signature that distinguishes a Tag-binding failure from a property-value failure: silent pass-through with no UI effect.
Comparison with a working call
The same author confirmed that changing a Color interface works on the same faceplate using HMIRuntime:
HMIRuntime.SetPropertyValue("FpContainer", "BgColor", 0xFF8000FF); // ARGB, opaque purple
This succeeds because BgColor is an in-memory value property; SetPropertyValue writes the value and the faceplate repaints. ValveTag is a Tag-binding property, not a value, so SetPropertyValue does not have a defined meaning for it.
Root Cause Analysis
The Unified scripting API distinguishes two categories of faceplate interface properties:
| Interface Type | Storage | SetPropertyValue Semantics | Tag Reassignment |
|---|---|---|---|
| Value (Color, Boolean, Integer, String, Float, UDT instance value) | Local property in faceplate container | Writes the value into the property cell | Not applicable |
| Tag (HMI tag binding) | Symbolic name of the bound tag | No defined semantics; call is ignored or treated as a value write that the faceplate cannot apply | Must use the object-model Properties.<Name>.Tag accessor |
| Resource List | Resource reference | Per-element write only | Must reassign the resource list name |
The HMIRuntime.SetPropertyValue method is designed for value-typed faceplate properties. When the target property is a Tag interface, the runtime has no documented behavior to rebind the symbolic name; the call either writes the literal string into the property (which the faceplate does not interpret as a tag) or no-ops silently. In both cases the faceplate's underlying tag subscription is not altered.
Why the workaround works
The workaround exposed by the source uses the screen-scoped object model directly:
Screen.Items("FpContainer").Properties.ValveTag.Tag = "HMI_Tag_02";
This path navigates the screen item tree, locates the faceplate container, descends into the Properties collection, and assigns the symbolic tag name to the .Tag sub-property of the interface. Because the assignment is performed against the actual runtime container object, the faceplate's tag subscription is reissued and the UDT instance values update on the next acquisition cycle.
Verification: Confirming the Failure Mode
- Create a test screen with one faceplate instance (
FpContainer) and one button (BtnSwitch). - Configure two HMI tags of the same UDT type:
HMI_Valve_01andHMI_Valve_02. - Bind the faceplate's
ValveTaginterface toHMI_Valve_01at design time. - Attach a script to
BtnSwitchthat performs the failing pattern (Pattern A). - Force a value change in
HMI_Valve_02from the PLC (e.g., write to a member of the UDT). - Click the button and observe the faceplate.
-
Expected (failing) behavior: The faceplate does not update because the binding is still
HMI_Valve_01. - Replace the script with the workaround path and repeat step 6.
-
Expected (passing) behavior: The faceplate now reflects values from
HMI_Valve_02.
Working Workaround: Screen.Items Property Assignment
The pattern below is the documented runtime object-model path for reassigning a Tag interface on a faceplate that is hosted on the currently active screen:
// Re-bind a Tag interface on a faceplate instance on the active screen
Screen.Items("FpContainer").Properties.ValveTag.Tag = "HMI_Tag_02";
For interfaces that are not of type Tag (e.g., the color interface), use the value write directly:
// Color interface — value write, no .Tag suffix
Screen.Items("FpContainer").Properties.BgColor = 0xFF8000FF;
Generic helper function:
// BindFaceplateTag(activeScreen, faceplateName, interfaceName, hmiTagName)
// Returns true on success, false if any node in the path is missing.
function BindFaceplateTag(activeScreen, faceplateName, interfaceName, hmiTagName) {
var item = activeScreen.Items(faceplateName);
if (item === null || item === undefined) return false;
var props = item.Properties;
if (props === null || props === undefined) return false;
var iface = props(interfaceName);
if (iface === null || iface === undefined) return false;
iface.Tag = hmiTagName;
return true;
}
// Usage from a button click on the same screen
BindFaceplateTag(Screen, "FpContainer", "ValveTag", "HMI_Tag_02");
The function is null-safe against three failure points: missing faceplate name, missing Properties collection, and missing interface name. This is the recommended defensive pattern for production panels.
Workaround Scope Limitation: Screen Window Boundary
The Screen.Items collection only enumerates items on the screen object passed as the receiver. Items hosted in a screen window (swContent) are not children of the host screen in the Unified object model — they belong to the screen that the window points to. Consequently, the workaround cannot directly reach a faceplate that lives inside another screen window:
// This does NOT find a faceplate inside swContent pointing to "DetailScreen"
Screen.Items("FpContainer"); // returns null
This is the documented limitation: the property assignment path is bound to the screen whose object model you are holding. Cross-screen-window access requires one of the indirection patterns below.
Pattern 1: Indirect through a shared tag
Pass the target faceplate's desired binding via a string HMI tag. On the screen that hosts the faceplate, attach a screen-loaded event that reads the string tag and applies the binding locally:
// On the host screen (DetailScreen), in the "Loaded" event of the screen:
var target = Tags("RequestedBinding").Read();
if (target !== "") {
Screen.Items("FpContainer").Properties.ValveTag.Tag = target;
}
The originating screen writes the binding name to RequestedBinding and then navigates to DetailScreen. On load, the destination screen rebinds the faceplate to the requested tag.
Pattern 2: Cross-screen navigation through Screen object lookup
Use the HMIRuntime.UI tree to obtain a handle on the screen window's target screen, then call Items on that screen object:
// Navigate: HMIRuntime > UI > ScreenWindow > TargetScreen > Items
var sw = HMIRuntime.UI.Screen("MainScreen").ScreenItems("DetailWindow");
var detailScreen = sw.Screen; // the screen currently hosted in the window
if (detailScreen !== null) {
detailScreen.Items("FpContainer").Properties.ValveTag.Tag = "HMI_Tag_02";
}
This pattern bypasses the Screen global and goes directly through the screen window's current screen reference. It is the only documented path that allows a faceplate inside another screen window to be re-targeted without a screen-load event.
Pattern 3: Per-screen local script with shared state
For high-traffic panels, push the binding name through a tag and let each screen handle its own faceplates via a scheduled task. This avoids tight coupling between screens and keeps the cross-screen script footprint small.
Alternative: Re-target via PLC-driven Tag Multiplexing
Where the faceplate selection logic lives in the PLC, the cleanest pattern is to keep the faceplate bound to a single multiplexed tag and have the PLC move the desired source into it. The faceplate interface remains statically bound; the PLC owns the routing:
// SCL sketch (S7-1500 / ET 200SP)
IF b_SelectValve1 THEN
"HMI_ActiveValve" := "DataBlock".Valve[1];
else
"HMI_ActiveValve" := "DataBlock".Valve[2];
END_IF;
The faceplate remains statically bound to HMI_ActiveValve; only the data behind that tag changes. This eliminates the runtime rebinding problem entirely and is preferred for safety-relevant HMIs.
Parameter Mapping Reference
| Interface Property Type | Runtime Path | Assignment | Result |
|---|---|---|---|
| Color (value) | Screen.Items("FpContainer").Properties.BgColor |
Direct value | Repaint |
| Boolean (value) | Screen.Items("FpContainer").Properties.IsOpen |
Direct value | State change |
| Integer (value) | Screen.Items("FpContainer").Properties.Setpoint |
Direct value | Numeric write |
| UDT instance (value) | Screen.Items("FpContainer").Properties.ValveData |
Direct value | Struct write |
| Tag (binding) | Screen.Items("FpContainer").Properties.ValveTag.Tag |
String (HMI tag name) | Re-bind tag subscription |
| Resource List | Screen.Items("FpContainer").Properties.AlarmList.ResourceList |
String (resource list name) | Re-bind resource list |
Engineering Recommendations
- Prefer static binding with PLC multiplexing for safety-related displays. Runtime rebinding adds a layer that the PLC does not see and that operators cannot trace.
-
Wrap assignment in a null-check helper (see
BindFaceplateTagabove). Silent failures in HMI scripts are the leading cause of "it works on my desk" defects. -
Use the screen-load event pattern for faceplates that live inside screen windows. The cross-window
HMIRuntime.UI.Screen(...).ScreenItems(...).Screenpath works but is fragile across firmware versions. -
Avoid mixing
HMIRuntime.SetPropertyValuewithScreen.Items(...).Propertieson the same faceplate instance in the same script cycle. The Unified runtime may evaluate the two writes in either order, producing transient flicker. -
Validate the tag name before assignment. The
.Tagassignment does not validate that the string corresponds to an existing HMI tag; a typo silently binds to a non-existent tag and the faceplate reads defaults. - Test on the target runtime image, not just in the ES (engineering station) simulator. Object model behavior has historically diverged between the PLCSIM/PLCSIM Advanced runtime and a physical Unified Comfort Panel.
Troubleshooting Matrix
| Symptom | Likely Cause | Remediation |
|---|---|---|
| Faceplate does not update after script runs | SetPropertyValue called on Tag interface | Switch to Screen.Items(...).Properties.<Name>.Tag = "..."
|
| Script throws "Object doesn't support this property or method" | Interface name typo or faceplate name typo | Verify against the faceplate's Properties collection in the ES |
| Faceplate updates on simulator but not on physical panel | Runtime image version mismatch | Update the panel firmware to match the ES |
| Faceplate in screen window does not update | Screen.Items is bound to wrong screen | Use the screen window's .Screen reference or screen-load event pattern |
| Tag binding reverts after navigation | Faceplate is recreated on screen load | Apply the binding in the screen-loaded event of the destination screen |
| Color interface works but Tag interface does not | Mixed value/binding semantics | Use the .Tag sub-property only for Tag interfaces |
FAQ
Why does HMIRuntime.SetPropertyValue work for a Color interface but not for a Tag interface on the same faceplate?
Color is a value-typed interface property; SetPropertyValue writes the value into the property cell and the faceplate repaints. Tag is a binding-typed interface property; SetPropertyValue has no defined semantics for rebinding the symbolic tag name and the call is effectively ignored. Use Screen.Items("FpContainer").Properties.<InterfaceName>.Tag = "HMI_TagName" for tag interfaces.
Can I change a faceplate's interface tag when the faceplate is inside another screen window (swContent)?
Not directly via the Screen global — Screen.Items only enumerates items on the active screen. Use the screen window's Screen reference: HMIRuntime.UI.Screen("Host").ScreenItems("DetailWindow").Screen.Items("FpContainer").Properties.<Name>.Tag = "...", or pass the desired binding through an HMI tag and apply it in the destination screen's Loaded event.
Which TIA Portal / WinCC Unified versions are affected by this limitation?
Confirmed against TIA Portal V17 Update 4 and earlier. V18 expanded the scripting API surface for cross-screen-window access; verify against the WinCC Unified Scripting manual for the specific runtime image installed on your panel.
Does the .Tag assignment validate that the HMI tag exists?
No. The runtime accepts any string and silently binds to a non-existent tag if the name does not resolve. Validate the name with a Tags().Item(name) lookup before assigning, and reject empty or whitespace strings.
What is the recommended pattern when a single faceplate must represent multiple physical devices?
For safety-relevant HMIs, bind the faceplate to one multiplexed tag and let the PLC move data into it; this keeps the binding static. For non-safety HMIs where runtime re-selection is required, use the Screen.Items property-assignment pattern with a null-safe helper and apply it in the destination screen's Loaded event when crossing screen windows.