Files
lmxopcua/docs/DataTypeMapping.md
Joseph Doherty 965e430f48 Add component-level documentation for all 14 server subsystems
Provides technical documentation covering OPC UA server, address space,
Galaxy repository, MXAccess bridge, data types, read/write, subscriptions,
alarms, historian, incremental sync, configuration, dashboard, service
hosting, and CLI tool. Updates README with component documentation table.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 15:47:59 -04:00

4.4 KiB

Data Type Mapping

MxDataTypeMapper and SecurityClassificationMapper translate Galaxy attribute metadata into OPC UA variable node properties. These mappings determine how Galaxy runtime values are represented to OPC UA clients and whether clients can write to them.

mx_data_type to OPC UA Type Mapping

Each Galaxy attribute carries an mx_data_type integer that identifies its data type. MxDataTypeMapper.MapToOpcUaDataType maps these to OPC UA built-in type NodeIds:

mx_data_type Galaxy type OPC UA type NodeId CLR type
1 Boolean Boolean i=1 bool
2 Integer Int32 i=6 int
3 Float Float i=10 float
4 Double Double i=11 double
5 String String i=12 string
6 Time DateTime i=13 DateTime
7 ElapsedTime Double i=11 double
8 Reference String i=12 string
13 Enumeration Int32 i=6 int
14 Custom String i=12 string
15 InternationalizedString LocalizedText i=21 string
16 Custom String i=12 string
other Unknown String i=12 string

Unknown types default to String. This is a safe fallback because MXAccess delivers values as COM VARIANT objects, and string serialization preserves any value that does not have a direct OPC UA counterpart.

Why ElapsedTime maps to Double

Galaxy ElapsedTime (mx_data_type 7) represents a duration/timespan. OPC UA has no native TimeSpan type. The OPC UA specification defines a Duration type alias (NodeId i=290) that is semantically a Double representing milliseconds, but the simpler approach is to map directly to Double (i=11) representing seconds. This avoids ambiguity about whether the value is in seconds or milliseconds and matches how the Galaxy runtime exposes elapsed time values through MXAccess.

Array Handling

Galaxy attributes with is_array = 1 in the repository are exposed as one-dimensional OPC UA array variables.

ValueRank

The ValueRank property on the OPC UA variable node indicates the array dimensionality:

is_array ValueRank Constant
0 -1 ValueRanks.Scalar
1 1 ValueRanks.OneDimension

ArrayDimensions

When ValueRank = 1, the ArrayDimensions property is set to a single-element ReadOnlyList<uint> containing the declared array length from array_dimension:

if (attr.IsArray && attr.ArrayDimension.HasValue)
{
    variable.ArrayDimensions = new ReadOnlyList<uint>(
        new List<uint> { (uint)attr.ArrayDimension.Value });
}

The array_dimension value is extracted from the mx_value binary column in the Galaxy database (bytes 13-16, little-endian int32).

NodeId for array variables

Array variables use a NodeId without the [] suffix. The full_tag_reference stored internally for MXAccess addressing retains the [] (e.g., MESReceiver_001.MoveInPartNumbers[]), but the OPC UA NodeId strips it to ns=1;s=MESReceiver_001.MoveInPartNumbers.

Security Classification to AccessLevel Mapping

Galaxy attributes carry a security_classification value that controls write permissions. SecurityClassificationMapper.IsWritable determines the OPC UA AccessLevel:

security_classification Galaxy level OPC UA AccessLevel Writable
0 FreeAccess CurrentReadOrWrite Yes
1 Operate CurrentReadOrWrite Yes
2 SecuredWrite CurrentRead No
3 VerifiedWrite CurrentRead No
4 Tune CurrentReadOrWrite Yes
5 Configure CurrentReadOrWrite Yes
6 ViewOnly CurrentRead No

Most attributes default to Operate (1). The mapper treats SecuredWrite, VerifiedWrite, and ViewOnly as read-only because the OPC UA server does not implement the Galaxy's multi-level authentication model. Allowing writes to SecuredWrite or VerifiedWrite attributes without proper verification would bypass Galaxy security.

For historized attributes, AccessLevels.HistoryRead is added to the access level via bitwise OR, enabling OPC UA history read requests when a HistorianDataSource is configured.

Key source files

  • src/ZB.MOM.WW.LmxOpcUa.Host/Domain/MxDataTypeMapper.cs -- Type and CLR mapping
  • src/ZB.MOM.WW.LmxOpcUa.Host/Domain/SecurityClassificationMapper.cs -- Write access mapping
  • gr/data_type_mapping.md -- Reference documentation for the full mapping table