fix(s7): Counter raw-word note + reject Writable Timer/Counter + Timer time-base tests (bundle review)
This commit is contained in:
@@ -369,6 +369,15 @@ public sealed class S7Driver
|
||||
$"S7 tag '{t.Name}' is a Counter address ('{t.Address}') but is typed {t.DataType}. " +
|
||||
"Counter tags must be DataType=Int32 (decoded to count, read-only).");
|
||||
}
|
||||
|
||||
// (d) Timer/Counter declared Writable — writes are read-only this phase; without this
|
||||
// a node is discovered as Operate-writable but every write returns BadNotSupported.
|
||||
if (parsed.Area is S7Area.Timer or S7Area.Counter && t.Writable)
|
||||
{
|
||||
throw new NotSupportedException(
|
||||
$"S7 tag '{t.Name}' is a Timer/Counter ('{t.Address}') declared Writable — " +
|
||||
"Timer/Counter are read-only this phase; set Writable=false.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -647,7 +656,14 @@ public sealed class S7Driver
|
||||
if (addr.Area is S7Area.Timer)
|
||||
return (object)global::S7.Net.Types.Timer.FromByteArray(block);
|
||||
if (addr.Area is S7Area.Counter)
|
||||
{
|
||||
// NOTE: S7.Net Counter.FromByteArray returns the RAW big-endian word ((bytes[0]<<8)|bytes[1]),
|
||||
// NOT a BCD decode. On classic S7-300/400 the C-area word is BCD (0-999), so on that hardware
|
||||
// this raw value can differ from the displayed count; S7-1200/1500 use IEC/DB counters (plain
|
||||
// ints), where it is correct. Surfacing S7.Net's value verbatim is the faithful choice; BCD
|
||||
// reinterpretation for legacy C-area counters is a live-hardware-gated follow-up.
|
||||
return (object)(int)global::S7.Net.Types.Counter.FromByteArray(block);
|
||||
}
|
||||
|
||||
// Each numeric arm is boxed to object explicitly: a bare switch expression would unify
|
||||
// long/ulong/double to their common type (double) and box THAT, mis-typing Int64/UInt64.
|
||||
|
||||
Reference in New Issue
Block a user