Port of the ignitionoee TwinCAT string + type-reconciliation fixes onto the
Beckhoff-library client:
- STRING/WSTRING subscriptions never worked: AddDeviceNotificationExAsync was
called with typeof(string) and no length, and the Beckhoff any-type
marshaller throws ArgumentNullException for a string without one, so one
string tag tore down its whole subscribe call. A string now registers the
PLC's own byte width as raw bytes (0.19.2: STRING(n) of any n).
- Strings are read as raw bytes and decoded by TwinCATStringCodec. The
Beckhoff marshaller already cut a read at the first NUL (0.19.3 / TwinCAT-007
were not defects on the read path); the codec keeps that rule for both STRING
and WSTRING and extends it to the new notification path. A STRING now decodes
as Windows-1252 (TwinCAT-010) - or UTF-8 when the target reports UTF-8
strings - instead of the host culture's ANSI code page the Beckhoff
marshaller falls back to (1250 on a Polish host, 1251 Cyrillic, ...).
- TwinCATTypeGuard (TwinCAT-002/-008): a read refuses a numeric tag over a PLC
string (and vice versa / STRING vs WSTRING / string over a container) with
BadTypeMismatch instead of handing back a string object at Good; a
notification - raw bytes decoded as the DECLARED type - additionally refuses
width and float/integer mismatches (DINT over REAL reinterpreted the bits).
- A refused notification is isolated: that tag publishes BadTypeMismatch with
one WARN, keeps a dead intent for the probe-tick retry, and the rest of the
subscription registers.