fix(twincat): map TwinCAT 2 ADS base-type names in symbol browse
A TC2 PLC reports top-level integer globals as INT16/UINT16 (354 symbols on
the Elma cleaner Z33856) and the Beckhoff type system keeps that spelling as
a built-in primitive, so MapSymbolTypeName returned null and discovery dropped
them silently. INT16/UINT16/INT32/UINT32/UINT8/FLOAT/DOUBLE now map like their
IEC twins; padded member names ("REAL ") are trimmed; a parenthesised
non-string form ("INT (VAR_IN_OUT)", a reference) stays unsupported.
This commit is contained in:
@@ -376,27 +376,36 @@ internal sealed class AdsTwinCATClient : ITwinCATClient
|
||||
return (MapSymbolTypeName(dataType.Name), null);
|
||||
}
|
||||
|
||||
private static TwinCATDataType? MapSymbolTypeName(string? typeName)
|
||||
internal static TwinCATDataType? MapSymbolTypeName(string? typeName)
|
||||
{
|
||||
if (typeName is null) return null;
|
||||
// A TwinCAT 2 data-type upload pads some member type names with a trailing blank
|
||||
// ("REAL ", "DINT " on a TC 2.11 CX) — trim before matching.
|
||||
var name = typeName.Trim();
|
||||
// SymbolLoader emits STRING(80) / WSTRING(80) with the declared bound baked into
|
||||
// the type name — strip the "(...)" suffix so sized strings map onto the bare
|
||||
// String/WString atom the driver speaks.
|
||||
var paren = typeName.IndexOf('(');
|
||||
var bare = paren > 0 ? typeName[..paren] : typeName;
|
||||
// String/WString atom the driver speaks. Only for the string kinds: any other
|
||||
// parenthesised form ("INT (VAR_IN_OUT)" — a 4-byte reference on TC2) is not the
|
||||
// scalar its prefix names and stays unsupported.
|
||||
var paren = name.IndexOf('(');
|
||||
var bare = paren > 0 ? name[..paren] : name;
|
||||
if (paren > 0 && bare is not ("STRING" or "WSTRING")) return null;
|
||||
return bare switch
|
||||
{
|
||||
"BOOL" or "BIT" => TwinCATDataType.Bool,
|
||||
"SINT" or "BYTE" => TwinCATDataType.SInt,
|
||||
"USINT" => TwinCATDataType.USInt,
|
||||
"INT" or "WORD" => TwinCATDataType.Int,
|
||||
"UINT" => TwinCATDataType.UInt,
|
||||
"DINT" or "DWORD" => TwinCATDataType.DInt,
|
||||
"UDINT" => TwinCATDataType.UDInt,
|
||||
// TwinCAT 2 reports top-level globals by their ADS base-type name (INT16 / UINT16 / …),
|
||||
// and the Beckhoff type system keeps that spelling as a built-in primitive
|
||||
// (AdsSymbolProvider.CreateBuildInTypes) — map each like its IEC twin.
|
||||
"USINT" or "UINT8" => TwinCATDataType.USInt,
|
||||
"INT" or "WORD" or "INT16" => TwinCATDataType.Int,
|
||||
"UINT" or "UINT16" => TwinCATDataType.UInt,
|
||||
"DINT" or "DWORD" or "INT32" => TwinCATDataType.DInt,
|
||||
"UDINT" or "UINT32" => TwinCATDataType.UDInt,
|
||||
"LINT" or "LWORD" => TwinCATDataType.LInt,
|
||||
"ULINT" => TwinCATDataType.ULInt,
|
||||
"REAL" => TwinCATDataType.Real,
|
||||
"LREAL" => TwinCATDataType.LReal,
|
||||
"REAL" or "FLOAT" => TwinCATDataType.Real,
|
||||
"LREAL" or "DOUBLE" => TwinCATDataType.LReal,
|
||||
"STRING" => TwinCATDataType.String,
|
||||
"WSTRING" => TwinCATDataType.WString,
|
||||
"TIME" => TwinCATDataType.Time,
|
||||
|
||||
Reference in New Issue
Block a user