EnumStrings can represent an enumeration in multiple languages, but each LocalizedText returned to a client contains only one selected text and its locale. Store the translations in the server using its server-specific configuration, let each client Session request preferred locales, and always use the enumeration's numeric value for control logic. Do not pack several translations into one text string.
Separate the server translation set from the client value
The key distinction is between how a server stores translations and what it transmits to one client. Internally, the server may maintain several translations for each enumeration entry. Its storage may use configuration files, engineering-tool resources, databases, code, or another implementation-specific mechanism.
For a particular Session, the server selects a suitable translation from that internal set. The client receives a LocalizedText containing one text-locale pair. The type therefore does not need to carry every translation simultaneously.
Locale selection changes presentation, not process state. If the enumeration has numeric value 1, it remains 1 whether the client displays “Off” or its configured German translation. PLC logic, alarms, scripts, historians, and client applications must compare the numeric value rather than localized text.
How Session locale negotiation controls EnumStrings
A client supplies its preferred locales when it creates a Session. The server uses those preferences when returning localized attributes and values, including the entries exposed through EnumStrings. Locale selection is therefore per Session rather than a single server-wide “current locale.” Two clients connected at the same time can receive different text for the same numeric enumeration value.
For the example enumeration, the logical mapping is:
| Numeric value | English display | German display |
|---|---|---|
0 |
On | Ein |
1 |
Off | Aus |
2 |
Starting | Startet |
An English Session reads the selected English LocalizedText entries. A German Session reads the German entries when the server has those translations. The client should inspect the locale returned with each text because an unavailable preference can result in a server-selected fallback or invariant text.
The proposed encoding en|Off;de|Aus is not a translation container. It is one ordinary text value containing separators. A conforming client would display or parse it as application-defined text, and the server would have no standard basis for selecting one embedded segment.
Choose EnumStrings or EnumValues by numeric mapping
| Representation | Numeric association | Best fit | Localization behavior |
|---|---|---|---|
EnumStrings |
The array position corresponds to the numeric enumeration value. | Compact, consecutive values that map cleanly to array indexes. | Each returned array element is a locale-selected LocalizedText. |
EnumValues |
Each entry explicitly associates metadata with a numeric value. | Nonconsecutive, negative, sparse, or otherwise explicitly assigned numeric values. | Its localized metadata is selected using the same Session locale principle. |
Use EnumValues when the numeric assignments cannot safely be inferred from an array index. Changing from EnumStrings to EnumValues does not create a multi-translation payload; it changes how numeric values are associated with their descriptive metadata. The server still retains the translation resources and returns the language selected for the Session.
Never derive control decisions by comparing either representation's displayed text. Text can vary by locale, translation revision, capitalization, or fallback selection while the numeric state remains unchanged.
Diagnose an enumeration that always appears in one language
- Read the variable's numeric value and confirm that it selects the expected enumeration entry. For
EnumStrings, check the array-index relationship. ForEnumValues, check the explicit numeric association. - Inspect the client's preferred locale list at Session creation. Changing an operating-system or HMI language setting does nothing unless the client passes the corresponding preference to the OPC UA Session.
- Read the returned locale as well as the returned text. This distinguishes a requested translation from a default, fallback, or invariant result.
- Open two separate Sessions with different preferences, such as English and German, then read the same enumeration definition from both. Different localized text with the same numeric value proves that Session selection is working.
- Check the server's localization configuration for every enumeration entry. A translated label for one state does not supply translations for the remaining states.
- Review server diagnostics if a locale cannot be configured or written. A syntactically invalid or unsupported locale write can return
Bad_LocaleNotSupported.
If both Sessions return the same locale, focus on client locale negotiation and server translation resources. If they return different locale identifiers but identical text, inspect the configured translation content. If the numeric association is wrong, correct the enumeration model before investigating localization.
Configure and update the translations
- Define stable numeric values first. Treat them as the machine-readable contract between the server and every client.
- Select
EnumStringsfor index-based consecutive mappings orEnumValueswhen values require explicit association. - Enter one translation per supported locale for each enumeration state using the server's localization mechanism. Do not concatenate languages into a single field.
- Configure clients to request locales in their intended preference order when creating Sessions.
- Reconnect or recreate each Session after changing its locale preferences so the server performs selection for the new Session context.
- Read the enumeration metadata and variable value together, then render the selected label while retaining the numeric value for application logic.
Where the server permits writes to attributes with the LocalizedText data type, a client can add or overwrite a translation by writing text with its associated LocaleId. Writing a null text for a locale deletes that locale's text. Writing a null locale with non-null text sets invariant text, while writing both locale and text as null deletes all locale entries. Support for writing a Value whose data type is LocalizedText is server-specific, so validate the target server's behavior before using writes as a translation-management method.
Verify behavior and avoid recurring failures
Complete verification requires at least two Sessions and every defined numeric state. For each state, record the numeric value, requested locale order, returned locale, and displayed text. Confirm that only the presentation changes between Sessions and that all logic continues to use the numeric value.
| Failure | Result | Correction |
|---|---|---|
| Embedding several languages in one string | Clients receive one composite label and cannot perform standard locale selection. | Configure separate server-side translations. |
| Comparing localized labels in code | Logic breaks after a locale or wording change. | Compare the numeric enumeration value. |
| Assuming locale is global | Tests overlook different results across simultaneous clients. | Test locale preferences independently in each Session. |
| Using array indexes for sparse values | The displayed state can be associated with the wrong number. | Use EnumValues with explicit numeric associations. |
| Ignoring the returned locale | Fallback text is mistaken for the requested translation. | Validate both members of every returned LocalizedText. |
FAQ
Can OPC UA EnumStrings contain multiple languages?
The server can maintain multiple translations for every entry, but each LocalizedText returned to one Session contains one selected locale and text. Configure translations separately in the server.
Why does my OPC UA enum always display English?
Check the preferred locales supplied when the client creates its Session, then inspect the locale returned with the text. Also verify that the server has a translation for every enumeration entry.
Should an OPC UA client compare EnumStrings text?
No. Compare the numeric enumeration value; localized labels are presentation data and can change with Session locale or translation revisions.
Does EnumValues support locale selection?
Yes. Its localized metadata follows the same Session locale-selection model, while its explicit numeric association makes it preferable for sparse or nonconsecutive values.
What causes Bad_LocaleNotSupported in OPC UA?
Bad_LocaleNotSupported can result when a client attempts to write a locale that is syntactically invalid or unsupported by the server. Check the written LocaleId and the server's configured locale support.