Group writes by device through new AbCipMultiWritePlanner; for families that support CIP request packing (ControlLogix / CompactLogix / GuardLogix) the packable writes for one device are dispatched concurrently so libplctag's native scheduler can coalesce them onto one Multi-Service Packet (0x0A). Micro800 keeps SupportsRequestPacking=false and falls back to per-tag sequential writes. BOOL-within-DINT writes are excluded from packing and continue to go through the per-parent RMW semaphore so two concurrent bit writes against the same DINT cannot lose one another's update. The libplctag .NET wrapper does not expose a Multi-Service Packet construction API at the per-Tag surface (each Tag is one CIP service), so this PR uses client-side coalescing — concurrent Task.WhenAll dispatch per device — rather than building raw CIP frames. The native libplctag scheduler does pack concurrent same-connection writes when the family allows it, which gives the round-trip reduction #228 calls for without ballooning the diff. Per-tag StatusCodes preserve caller order across success, transport failure, non-writable tags, unknown references, and unknown devices, including in mixed concurrent batches. Closes #228
12 KiB
12 KiB