It is a common requirement in Companion Specifications to define discrete values which have a string representation. A typical approach (independent of OPC UA) is to use enumeration data types, defining specific strings for internally used numeric values. The drawback on standardizing such Enumeration DataTypes in OPC UA is, that they are restricted exactly to those values. It is not allowed for a vendor to extend and even not in a new version of the specification (see 3.2.4).
There are different workarounds for this issue.
In order to allow other values, a special Enumeration “Other” can be defined. If this is selected, it is clear, that none of the regular enumerations apply. However, the drawback is that there is also no hint where to find what other value is applied. Therefore, it is not recommended to use this approach.
The MultiStateDiscreteType and MultiStateValueDisctreType work similar to an enumeration but allow different enumeration values per instance. Many Companion Specifications use this approach allowing future versions and vendors to extend the allowed enumeration values. The drawback of this approach is, that potentially (from the pure model) vendors may use completely different enumerations, not the once defined in the specification. Therefore, they need to explicitly state (by written text) in the specification, that some predefined values are to be used. This approach forces clients into looking at the instance into the enumeration values and therefore forces them into considering the extensibility and is therefore an adequate approach when extensibility is expected.
Another approach, used for example in the ConditionClass of Alarms (and with version 1.05.02 also in normal Events). The ConditionClassId Variable and also the ConditionSubClassId Variable are of DataType NodeId and point to specific ObjectTypes (either BaseConditionClassType or a subtype). This approach is actually more than an enumeration, as it allows the specialization of enumeration values in the ObjectType hierarchy. If such a specialization is required, it is recommended to use this approach.
StateMachines do provide a set of States that can be reached and therefore define kind of an enumeration with additional information like the allowed transitions and potentially causes and effects. A StateMachine itself is fix and no new States can be added, but SubStateMachines for individual States allowing to refine those. This is a more complex approach that should only be used when additional functionality of a StateMachine is needed or may be needed when refined, like defining effects or Methods that trigger the transition by a Client.