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
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
namespace ZB.MOM.WW.OtOpcUa.Driver.Modbus;
|
||||
|
||||
/// <summary>
|
||||
/// The driver refused a write BEFORE anything reached the wire (wrong array length, a payload over
|
||||
/// <c>MaxRegistersPerWrite</c>, an unsupported shape). Carries the OPC UA status the write returns;
|
||||
/// it never touches driver health — nothing was sent.
|
||||
/// </summary>
|
||||
public sealed class ModbusWriteRefusedException : Exception
|
||||
{
|
||||
/// <summary>Initializes a new instance of the <see cref="ModbusWriteRefusedException"/> class.</summary>
|
||||
/// <param name="statusCode">The OPC UA status the write returns.</param>
|
||||
/// <param name="message">A human-readable description.</param>
|
||||
public ModbusWriteRefusedException(uint statusCode, string message)
|
||||
: base(message)
|
||||
{
|
||||
StatusCode = statusCode;
|
||||
}
|
||||
|
||||
/// <summary>Gets the OPC UA status the write returns.</summary>
|
||||
public uint StatusCode { get; }
|
||||
}
|
||||
Reference in New Issue
Block a user