Commit Graph

4 Commits

Author SHA1 Message Date
Joseph Doherty 620ecc41dd fix(modbus): refusals are per-tag Bad, batch health, generation-stamped lifecycle, write status mapping
H4: exception 01/02/03 (and undecodable data) are device refusals - per-tag
Bad with a once-per-tag Warning, no Degraded, and they advance
LastSuccessfulRead (the device answered), so an all-refused driver no longer
trips the 90 s watchdog. 04/05/06 still degrade (answered); 0A/0B degrade
without advancing. Health is one worst-wins write per batch instead of
last-writer-wins per tag. A comms failure on one unit fails the rest of
that unit's batch fast; an unreachable endpoint fails the whole batch fast.
H7: write transport failures map to BadCommunicationError, value overflow and
array length mismatch to BadOutOfRange, conversion failures to
BadTypeMismatch; writes report write-side health (a good write or a refusal
clears a write-side Degraded; a good read does not).
Lifecycle: every health write and the transport/table publish carry a
generation; a superseded init releases its transport and publishes nothing,
a read straddling a re-init cannot degrade the new transport, and the
shutdown's final write cannot clobber a newer init. The tag table is
build-and-swapped (re-init no longer merges into the old table). Teardown
joins the probe/re-probe loops (bounded); a probe answer advances
LastSuccessfulRead and an exception PDU from the device counts as Running.
Transports latch dispose atomically and never reconnect after it.

Refs #741
Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
2026-10-22 15:15:20 -04:00
Joseph Doherty aafb9d4929 v3(b1-modbus): RawPath identity seam — RawTagEntry-driven Modbus driver
Wave-B EXEMPLAR. Retire the pre-declared/blob-parse tag model; the driver now
builds its RawPath -> definition table from the artifact's RawTagEntry set via a
pure mapper.

- Contracts: rename ModbusEquipmentTagParser -> ModbusTagDefinitionFactory;
  TryParse(reference) -> FromTagConfig(tagConfig, rawPath) (def.Name = rawPath,
  no leading-brace heuristic); add inverse ToTagConfig(def) serializer; keep all
  strict-enum reads + guards; also read stringByteOrder/deadband/coalesceProhibited
  so a RawTagEntry round-trips the full authored def. Inspect() unchanged.
- Options: Tags(IReadOnlyList<ModbusTagDefinition>) -> RawTags(IReadOnlyList<RawTagEntry>).
- Driver: _tagsByName -> _tagsByRawPath (Ordinal); resolver byRawPath-only; build
  the table from RawTags at Initialize threading entry.WriteIdempotent onto each def;
  Discover/Teardown updated.
- Factory: remove ModbusTagDto/BuildTag/ValidateStringLength + ConfigDto.Tags; bind
  RawTags from driver-config JSON.
- CLI ModbusCommandBase.BuildOptions: serialise typed defs -> RawTagEntry via ToTagConfig.
- Tests: migrate Tags= -> RawTags via ModbusRawTags.Entries helper; parser tests ->
  FromTagConfig(rawPath); factory String-length/enum tests re-seated on the mapper seam.
- Propagated rename to ControlPlane EquipmentTagConfigInspector (outside Modbus projects).

Modbus.Tests 315/315, Addressing.Tests 161/161, Cli.Tests 72/72 green.
Docker-gated Driver.Modbus.IntegrationTests left untouched (won't compile against
the new API; expected).
2026-07-15 19:50:10 -04:00
Joseph Doherty 64e3fbe035 docs: backfill XML documentation across 756 files
v2-ci / build (push) Failing after 1m43s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
Adds <summary>, <param>, <typeparam>, and <inheritdoc/> tags to public
members surfaced by commentchecker — resolves 5,847 of 5,869 issues
(99.6%) across three /fixdocs passes.
2026-05-28 08:10:17 -04:00
Joseph Doherty a25593a9c6 chore: organize solution into module folders (Core/Server/Drivers/Client/Tooling)
Group all 69 projects into category subfolders under src/ and tests/ so the
Rider Solution Explorer mirrors the module structure. Folders: Core, Server,
Drivers (with a nested Driver CLIs subfolder), Client, Tooling.

- Move every project folder on disk with git mv (history preserved as renames).
- Recompute relative paths in 57 .csproj files: cross-category ProjectReferences,
  the lib/ HintPath+None refs in Driver.Historian.Wonderware, and the external
  mxaccessgw refs in Driver.Galaxy and its test project.
- Rebuild ZB.MOM.WW.OtOpcUa.slnx with nested solution folders.
- Re-prefix project paths in functional scripts (e2e, compliance, smoke SQL,
  integration, install).

Build green (0 errors); unit tests pass. Docs left for a separate pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 01:55:28 -04:00