Overview
Wonderware InTouch HMI projects deployed in distributed (client/server) configurations face a recurring challenge: tag references in graphics and scripts are automatically qualified with the configured server's node name, which causes incorrect resolution of client-only local tags such as @LocalComputerName. The @local:: namespace prefix bypasses this default server prefixing and forces tagname resolution against the local client tag database, enabling per-client identification without scripting workarounds.
This article explains the @local:: namespace, its case-sensitivity requirements, the architectural distinction between distributed and standalone tag resolution, and the field-proven verification steps required to ensure reliable deployment.
Background: Distributed InTouch Architecture
InTouch distributed applications separate the tag database from the HMI visualization layer into distinct processes that communicate over the Suite Link protocol. Understanding this separation is essential for diagnosing tag resolution issues.
Core Components
-
InTouch Application Server (IAS): Hosts the master tag database, known as DBDump (Database Dump). The DBDump file (
DBDump.dbf) is the canonical source for all tag definitions and current values. The server process exposes these values to network clients via TCP port 5413 (default Suite Link port). - InTouch HMI Client (WindowViewer): The runtime HMI display engine that runs on operator workstations. WindowViewer subscribes to tag values from one or more Application Servers using configured Access Names.
- Network Application Development (NAD): A file-sharing mechanism that synchronizes project assets (graphics, scripts, tag dictionaries) across the server and client nodes. NAD uses UNC paths or DFS shares, not a network protocol.
- Suite Link / DDE / TCP/IP: Communication protocols used between WindowViewer and the Application Server. Suite Link is the preferred protocol for InTouch-to-InTouch communication and uses dedicated ports for tag read/write operations.
Tag Resolution Order
When WindowViewer encounters a tagname reference, it follows a deterministic resolution sequence:
- Local tagname dictionary: Checks the client machine's local tag database first.
- Access Name hierarchy: If the tag is not found locally, queries each configured Access Name in order until a match is found.
-
System tags: Built-in tags prefixed with
@(e.g.,@LocalComputerName,@Date,@Time) are resolved locally. - Error / blank: If no match is found at any level, the tag returns a blank value and a "tag not found" entry is written to the InTouch log.
The default behavior assumes that tag references should be resolved against the server. The @local:: prefix overrides this default and forces step 1 (local lookup) regardless of any Access Name configuration.
The Problem: Server-Prefixed Local Tags
The system tag @LocalComputerName is a built-in InTouch local tag that returns the Windows computer name of the machine where WindowViewer is running. In a distributed deployment, the resolution sequence creates a specific failure mode:
- The HMI client runs on Workstation A (e.g.,
STATION01). - The Application Server runs on Computer B (e.g.,
SERVERNODE). - The graphics contain a reference to
@LocalComputerNameorLocalComputerNamein an animation expression. - InTouch resolves the reference against the server's tag database via the configured Access Name.
- The returned value is
SERVERNODE, notSTATION01.
This breaks per-client identification logic in several common scenarios:
- Audit trails: Records that should capture which workstation performed an action instead capture the server's identity.
- Conditional graphics: Visibility or color animations that should differ per operator station all evaluate against a single server-side value.
- License enforcement: Per-workstation license counters remain tied to the server's identity rather than the active client.
- Session memory flags: Per-operator memory tags get shared across all clients connected to the same server, causing state leakage between operators.
- Operator identification: Operator name displays show the server's logged-in user rather than the actual operator.
Before the introduction of the @local:: namespace, engineers worked around this limitation with QuickScript code that read the local computer name via Windows API calls (e.g., InfoApp(), WinExec() calling hostname.exe) and assigned the value to a memory tag. The @local:: prefix eliminates this scripting overhead.
Solution: The @local:: Namespace Prefix
InTouch supports a local tag namespace that bypasses the server prefixing mechanism. The @local:: prefix forces tagname resolution against the local tag database on the client machine running WindowViewer, ensuring that the returned value reflects the client's local state, not the server's.
Syntax
The prefix follows the standard InTouch namespace notation:
@local::TagName
where TagName is the unqualified tag name to resolve against the local tag database.
Resolution Examples
| Use Case | Expression | Result on Client | Result on Server |
|---|---|---|---|
| Client computer name | @local::LocalComputerName |
Client hostname (e.g., STATION01) |
Server hostname (e.g., SERVERNODE) |
| Custom local memory tag | @local::MySessionFlag |
Client's local value | Server's local value |
| Conditional animation | IF @local::LocalComputerName == "STATION01" THEN ... |
Per-client branch logic | Per-server branch logic |
| Operator identification | @local::LocalUserName |
Client's Windows user | Server's Windows user |
| Local timestamp | @local::LocalDate |
Client's system date | Server's system date |
Case Sensitivity
@local:: prefix is case-sensitive. Use lowercase l in @local::. The form @Local:: is rejected by the InTouch name resolver and falls through to the default server-prefixed lookup, returning server-side values instead of the expected client-side values.This case-sensitivity is the most common deployment failure. Engineers who type @Local:: based on capitalization conventions from other namespace prefixes (e.g., @LocalComputerName) silently get server-side values and may not detect the issue until commissioning when conditional logic fails to branch correctly.
Where the Prefix Is Recognized
The @local:: prefix is recognized in the following contexts:
- WindowScript animation links: Visibility, color, position (X/Y), size (width/height), fill, blink, orientation, value (slider/gauge), percent fill, horizontal/vertical percent.
- QuickScript expressions: Application scripts, condition scripts, data change scripts, key scripts, mouse scripts, window scripts.
-
Indirect tagname references: Limited support; the indirect string must contain the fully qualified
@local::prefix. -
Tagname Dictionary entries: Indirect tag definitions can reference
@local::-prefixed local tags.
The prefix is not recognized in Access Name definitions (which always refer to remote nodes) or in DDE/OPC topic definitions (which are protocol-specific).
Critical Testing Requirement: Standalone Projects
@local:: prefix behavior differs between distributed and standalone InTouch project configurations. A project that functions correctly in a distributed deployment may fail, generate warnings, or produce unexpected results when deployed as a standalone project. Always test both configurations before production rollout.InTouch projects commonly exist in three deployment modes:
- Standalone: One machine hosts both WindowMaker/WindowViewer and the tag database. Common in single-station HMIs, engineering workstations, and OEM test rigs.
- Distributed with primary client: One machine serves tags to itself (acting as its own client) and to additional remote clients. Common in plant-floor server/client topologies.
- Distributed with remote clients: A dedicated server machine serves tags; clients connect remotely and may not run any local tag database. Common in large-scale SCADA deployments.
In standalone mode, all tags are inherently local to the single machine. The @local:: prefix may resolve differently or generate namespace warnings in the InTouch log (WWLogger.log) because the resolver detects that the prefix is unnecessary but not strictly invalid. Some versions of InTouch suppress the warning; others log it as a low-severity informational entry.
Test Sequence for Both Modes
-
Deploy to distributed configuration: Install on server and at least one client. Verify
@local::references return client-specific values. -
Deploy to standalone configuration: Install on a single machine with no remote Access Names configured. Verify the same
@local::references return local values. -
Check log files: Inspect
WWLogger.logon both deployments for namespace resolution warnings. - Document both results: Record test outcomes in the project validation report.
Step-by-Step: Configuring @local:: References
Prerequisites
- InTouch 2014 R2 or later (or InTouch 11.6 with applicable patches for legacy environments)
- Distributed project with at least one remote HMI client configured
- Local memory tags defined in the Tagname Dictionary, or use of built-in tags like
@LocalComputerName - Application Server configured with appropriate Access Names pointing to the server node
- Administrator access on both server and client machines for deployment and verification
- Read access to the InTouch log directory (typically
C:\Program Files\Wonderware\InTouch\Logs)
Procedure
-
Verify the local tag exists on the client. Open WindowMaker on the client machine. Select Special > Tagname Dictionary. Confirm the local tag (e.g.,
LocalComputerNameor your custom tag) is present in the local scope. Built-in tags like@LocalComputerNameare automatically available; custom tags must be added manually. -
Configure the Access Name. Open Special > Access Names. Verify the Access Name points to the correct application server node name (e.g.,
\\SERVERNODE). Do not include@local::in the Access Name definition; the prefix is for tag references only. -
Locate unqualified references in the project. Search the project for references to tags that should resolve locally (e.g.,
LocalComputerName,LocalUserName, or custom local memory tags). WindowMaker's cross-reference tool (Search > Cross-Reference) can identify all references to a specific tag. -
Replace unqualified references with qualified local references. For each animation, script, or expression, replace the bare reference:
LocalComputerName
with the qualified local reference:@local::LocalComputerName
Apply the same change to any QuickScript expressions and indirect tagname strings. - Save and deploy the project. Save the project in WindowMaker. Copy the project files to the client machine using View SCC (Source Control) or a manual file copy that preserves the directory structure. Launch WindowViewer on the client.
- Verify client resolution. Open the script debugger (Special > Script Debugger) or create a temporary display that shows the tag value in a text field animation. Confirm the value matches the client machine's hostname, not the server's.
-
Test standalone behavior. Switch the project to standalone mode by reconfiguring the Access Name to point to the local node (
\\localhostor the machine's own hostname). Launch WindowViewer. Confirm the same reference returns the expected value and check the InTouch log (WWLogger.log) for any namespace resolution warnings. -
Document the change. Record the qualified references in your project's design specification, noting both distributed and standalone test results. Update the project's tag reference matrix to indicate which tags use
@local::.
Creating Custom Local Memory Tags
Beyond the built-in system tags, you may need custom local memory tags for per-client state. To create a local memory tag that uses @local:: resolution:
Procedure
- In WindowMaker, select Special > Tagname Dictionary.
- Click New to create a new tag.
- Enter the tag name (e.g.,
OperatorSessionID). Do not include the@local::prefix in the tag definition; the prefix is only used in references. - Set the Tag Type to Memory.
- Set the Access scope to Local (not Server or Both).
- Click Save to add the tag to the local dictionary.
Once defined, reference the tag using @local::OperatorSessionID in any animation, script, or expression. The tag value is isolated to the client machine and is not propagated to the server or other clients.
QuickScript Examples
Example 1: Conditional Visibility Based on Client Identity
// Hide a button unless the current client is STATION01 or STATION02
IF (@local::LocalComputerName == "STATION01") OR (@local::LocalComputerName == "STATION02") THEN
Show "OperatorButton";
ELSE
Hide "OperatorButton";
ENDIF;
Example 2: Per-Client Audit Log Entry
// Append operator action to a local memory string tag
LOCAL STRING sLogEntry;
sLogEntry = @local::LocalDate + " " + @local::LocalTime + " - " + @local::LocalUserName + " pressed START";
@local::AuditBuffer = @local::AuditBuffer + sLogEntry + "\n";
Example 3: Local Counter Initialization on Startup
// Initialize per-client session counter in the window's On Show script
@local::SessionEventCount = 0;
@local::SessionStartTime = @local::LocalTime;
Example 4: Indirect Tagname with Local Prefix
// Read a local memory tag via indirect reference
LOCAL STRING sTagRef;
sTagRef = "@local::Temp" + StringFromIntg(@local::UnitIndex, 10);
MyDisplay.Value = @local:sTagRef; // Note: indirect indirection may require script workaround
Indirect tagname support for @local:: is limited; in many cases it is simpler to use direct references in conditional logic or switch-case constructs rather than relying on dynamic tagname construction.
Verification Checklist
| Check | Expected Result |
|---|---|
Client resolves @local::LocalComputerName
|
Returns client's hostname (e.g., STATION01) |
Server resolves @local::LocalComputerName
|
Returns server's hostname (e.g., SERVERNODE) |
Standalone resolves @local::LocalComputerName
|
Returns local hostname |
| Case sensitivity |
@local:: resolves correctly; @Local:: is rejected |
| Animation updates | Visibility, color, and position updates reflect per-client value |
| QuickScript log | No "tag not found" or namespace errors |
| Indirect tagname | Resolves when the indirect string contains @local:: prefix |
| Network interruption | Local tags remain readable when server connection drops |
| Custom memory tag | Returns client-local value, not shared across clients |
| Log file review | No namespace warnings in WWLogger.log
|
Troubleshooting Matrix
| Symptom | Likely Cause | Resolution |
|---|---|---|
@local:: returns server name |
Access Name overriding local lookup | Verify Access Name scope and Tagname Dictionary local entries |
@local:: tag not found |
Tag not defined in local scope | Add tag to local tag database on the client |
| Works on distributed, fails on standalone | Namespace resolution difference | Test standalone early; add conditional logic to handle both modes |
@Local:: (uppercase L) rejected |
Case-sensitive namespace | Use lowercase @local::
|
| Tag returns blank value | WindowViewer not running locally | Verify client component installation; confirm local tag database is loaded |
| Animation does not update | Tagname in indirect reference | Use direct reference with @local::; indirection has limited support |
| Tagname Dictionary shows red X | Tagname syntax error | Verify colon placement and case of @local::
|
| Different values across clients | Working as designed | Each client returns its own local value; this is expected |
| Server connection lost, local tags blank | Server tag confusion | Confirm references use @local::, not unqualified names |
| QuickScript returns wrong value | Script using unqualified name | Update script to use @local:: prefix |
| Indirect lookup fails | Indirect string missing prefix | Construct indirect string with full @local:: prefix |
| Tag works in WindowMaker but not WindowViewer | Development vs runtime discrepancy | Deploy updated project to client; verify file copy completed |
Common Built-In Local Tags
InTouch provides several built-in system tags that expose local machine information without requiring custom tag definitions:
| Tagname | Description | Typical Use |
|---|---|---|
@LocalComputerName |
Windows computer name of the running machine | Per-workstation identification |
@LocalUserName |
Windows user account running WindowViewer | Operator identification |
@LocalDate |
System date on the local machine | Local timestamp for audit logs |
@LocalTime |
System time on the local machine | Local timestamp for audit logs |
@LocalMs |
Millisecond counter on the local machine | High-resolution timing |
@AppExecPath |
Path to the InTouch application directory | File I/O path construction |
@WindowResolution |
WindowViewer display resolution | Adaptive graphics |
Use Cases
-
Per-client audit logging and traceability: Combine
@local::LocalComputerNameand@local::LocalUserNamewith@local::LocalDate/@local::LocalTimeto build tamper-evident audit trails. - Conditional graphics: Show different views, colors, or layouts based on operator station identity.
- License enforcement per workstation: Tie license counters to a specific hostname to prevent over-deployment.
- Session-specific memory flags: Maintain per-operator state (e.g., which screen was last viewed, current recipe selection) without server-side interference.
-
Time-stamping operator actions: Use
@local::LocalTimerather than the server's clock to capture when the operator actually triggered an action.
Related Concepts: AOI Local Tags in Logix Designer
While InTouch's @local:: prefix deals with HMI-side namespace resolution, similar scoping concepts exist in PLC programming environments. In Rockwell Automation Logix Designer, Add-On Instructions (AOIs) maintain their own local tag scope that is not directly accessible from outside the AOI by default.
According to Rockwell Automation support documentation on AOI local tag access, local tag values inside an AOI can be exposed to external consumers (including HMIs and other routines) by:
- Changing the External Access property of the local tag from "None" to "Read Only" or "Read/Write".
- Passing the value through an AOI input or output parameter.
- Creating a controller-scoped tag alias that mirrors the local value.
The conceptual parallel is direct: both platforms enforce explicit scoping of tag accessibility. InTouch uses the @local:: prefix to opt into local scope from a global reference; AOI local tags require explicit opt-out (External Access property change) to leave their default private scope. The default for AOI local tags is private; the default for InTouch tag references is server-scoped. Engineers should be aware of both defaults when designing systems that span HMI and PLC domains.
Reference: AVEVA Documentation
Per AVEVA InTouch HMI documentation on local tags, local tags enable per-session memory tags for use in Web Client and distributed HMI scenarios. The documentation describes the configuration of local memory tags as a mechanism to maintain client-specific state without requiring script-based workarounds. The same namespace rules apply for AVEVA InTouch HMI 2020 and later versions, with consistent @local:: resolution behavior across the product line.
Best Practices
-
Always use lowercase
@local::: the parser is case-sensitive and silently rejects uppercase variants, returning server-side values instead. - Test both distributed and standalone deployments: namespace resolution behavior diverges between the two modes and must be validated before production rollout.
-
Document
@local::usage in design specifications: note where per-client resolution is required so future maintainers understand the intent and do not "simplify" the references by removing the prefix. -
Avoid
@local::in shared graphics that don't need per-client resolution: only use where client-specific data is required. Overuse creates unnecessary namespace complexity. -
Use built-in local tags where possible:
@LocalComputerNameand@LocalUserNameeliminate the need to create custom local memory tags for common identification scenarios. -
Validate after every project upgrade: InTouch version upgrades (e.g., 2014 R2 to 2020) can change namespace resolution behavior. Always re-test
@local::references after a major version upgrade. -
Check the InTouch log after deployment: namespace warnings often appear in
WWLogger.logor the SMC log. Review the log to catch silent resolution issues before they manifest as field problems. -
Combine
@local::with memory tags for session state: local memory tags persist for the lifetime of the WindowViewer process, making them suitable for session-level state that should not propagate to the server. -
Cross-reference tag usage: use WindowMaker's cross-reference tool to identify all locations where a tag is referenced before renaming or replacing it. This prevents missed updates when migrating to
@local::qualified references. - Train operators on local tag semantics: when operators see per-station differences in display behavior, they should understand that this is by design and not a system fault.
Compatibility Notes
| InTouch Version |
@local:: Support |
Notes |
|---|---|---|
| InTouch 10.6 | Legacy support | Verify against specific patch level; behavior may differ from later versions |
| InTouch 11.6 | Supported | Stable namespace resolution; documented in help files |
| InTouch 2014 R2 and later | Full support | Recommended baseline for distributed deployments |
| AVEVA InTouch HMI 2020 | Supported | Consistent behavior with InTouch 2014 R2 namespace |
| AVEVA InTouch HMI 2023 | Supported | Verify against release notes for any namespace changes |
| AVEVA InTouch HMI 2024 and later | Supported | Namespace behavior unchanged; refer to current AVEVA documentation |
Migration Scenario: Converting Existing Projects
Existing projects that rely on scripting workarounds (e.g., QuickScript calling Windows API or executing hostname.exe to populate a memory tag) can be migrated to use the @local:: prefix for cleaner implementation.
Migration Steps
- Inventory existing workarounds: Use WindowMaker's cross-reference tool to identify all scripts that populate local-identification memory tags.
-
Replace script logic with
@local::references: Update animations and expressions to use@local::LocalComputerNameinstead of the script-populated tag. - Remove obsolete scripts: Delete the QuickScripts that previously populated the local memory tag, taking care not to break other logic that may depend on them.
- Test on distributed and standalone: Validate both deployment modes after migration.
- Update design documentation: Record the migration in the project change log.
FAQ
What is the difference between @local:: and @ServerName::?
@local:: forces tag resolution against the local client's tag database and returns client-specific values. @ServerName:: (e.g., @SERVERNODE::) forces resolution against the named server's tag database and returns server-side values. Use @local:: when per-client identification is required; use the server prefix when a specific server's data is needed.
Does @local:: work in standalone InTouch projects?
Yes, but behavior may differ from distributed mode. In standalone mode all tags are local, and the @local:: prefix may resolve differently or generate namespace warnings in WWLogger.log. Always test the project in both standalone and distributed configurations before deployment.
Why does @Local:: (uppercase L) fail to return client values?
The InTouch name resolver treats the namespace prefix as case-sensitive. @local:: (lowercase) is the recognized form; @Local:: is rejected and falls through to the default server-prefixed lookup, returning server-side values. Always use lowercase @local:: in tag references to ensure client-side resolution.
Can I use @local:: in QuickScript animations?
Yes. The @local:: prefix is recognized in QuickScript expressions (application, condition, data change, key, mouse, and window scripts) and in WindowScript animation links for visibility, color, position, fill, blink, and orientation. Indirect tagname support is limited; use direct references where possible.
How do I expose client-specific data to multiple operators without scripting?
Use the @local:: prefix combined with built-in local tags (@LocalComputerName, @LocalUserName) or custom local memory tags defined in the Tagname Dictionary with Local scope. Each client returns its own value without requiring script-based tagname manipulation or Windows API calls.