feat(modbus): resolve equipment-tag refs (read + write) via EquipmentTagRefResolver
This commit is contained in:
@@ -34,6 +34,11 @@ public sealed class ModbusDriver
|
||||
|
||||
private readonly Dictionary<string, ModbusTagDefinition> _tagsByName = new(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
// Resolves a read/write/subscribe fullReference to a tag definition, bridging the two
|
||||
// authoring models: an authored tag-table entry (by name) OR an equipment tag whose
|
||||
// reference is its raw TagConfig JSON (parsed once via ModbusEquipmentTagParser, cached).
|
||||
private readonly EquipmentTagRefResolver<ModbusTagDefinition> _resolver;
|
||||
|
||||
// Last-published value per tag, keyed by FullReference. Used by ShouldPublish to apply
|
||||
// the deadband filter. Stored as object so all numeric types share one map; the comparison
|
||||
// does a typed cast inside.
|
||||
@@ -111,6 +116,9 @@ public sealed class ModbusDriver
|
||||
_options = options;
|
||||
_driverInstanceId = driverInstanceId;
|
||||
_logger = logger ?? NullLogger<ModbusDriver>.Instance;
|
||||
_resolver = new EquipmentTagRefResolver<ModbusTagDefinition>(
|
||||
r => _tagsByName.TryGetValue(r, out var t) ? t : null,
|
||||
r => ModbusEquipmentTagParser.TryParse(r, out var d) ? d : null);
|
||||
_transportFactory = transportFactory
|
||||
?? (o => new ModbusTcpTransport(
|
||||
o.Host, o.Port, o.Timeout, o.AutoReconnect,
|
||||
@@ -148,7 +156,7 @@ public sealed class ModbusDriver
|
||||
|
||||
private bool ShouldPublish(string tagRef, DataValueSnapshot snapshot)
|
||||
{
|
||||
if (!_tagsByName.TryGetValue(tagRef, out var tag) || tag.Deadband is null) return true;
|
||||
if (!_resolver.TryResolve(tagRef, out var tag) || tag.Deadband is null) return true;
|
||||
if (snapshot.Value is null) return true;
|
||||
// Deadband only applies to numeric scalar types — array / Bool / String publishes
|
||||
// unconditionally. Easier to special-case skip than to enumerate the supported types.
|
||||
@@ -297,7 +305,7 @@ public sealed class ModbusDriver
|
||||
for (var i = 0; i < fullReferences.Count; i++)
|
||||
{
|
||||
if (coalesced.Contains(i)) continue;
|
||||
if (!_tagsByName.TryGetValue(fullReferences[i], out var tag))
|
||||
if (!_resolver.TryResolve(fullReferences[i], out var tag))
|
||||
{
|
||||
results[i] = new DataValueSnapshot(null, StatusBadNodeIdUnknown, null, now);
|
||||
continue;
|
||||
@@ -711,7 +719,7 @@ public sealed class ModbusDriver
|
||||
var eligible = new List<(int Index, string Ref, ModbusTagDefinition Tag)>();
|
||||
for (var i = 0; i < fullReferences.Count; i++)
|
||||
{
|
||||
if (!_tagsByName.TryGetValue(fullReferences[i], out var tag)) continue;
|
||||
if (!_resolver.TryResolve(fullReferences[i], out var tag)) continue;
|
||||
if (tag.CoalesceProhibited) continue;
|
||||
if (tag.ArrayCount.HasValue) continue;
|
||||
if (tag.Region is not (ModbusRegion.HoldingRegisters or ModbusRegion.InputRegisters)) continue;
|
||||
@@ -931,7 +939,7 @@ public sealed class ModbusDriver
|
||||
for (var i = 0; i < writes.Count; i++)
|
||||
{
|
||||
var w = writes[i];
|
||||
if (!_tagsByName.TryGetValue(w.FullReference, out var tag))
|
||||
if (!_resolver.TryResolve(w.FullReference, out var tag))
|
||||
{
|
||||
results[i] = new WriteResult(StatusBadNodeIdUnknown);
|
||||
continue;
|
||||
@@ -1617,6 +1625,7 @@ public sealed class ModbusDriver
|
||||
_reprobeCts = null;
|
||||
|
||||
_tagsByName.Clear();
|
||||
_resolver.Clear(); // drop transient equipment-tag parses so a config change re-parses
|
||||
_lastPublishedByRef.Clear();
|
||||
lock (_lastWrittenLock) _lastWrittenByRef.Clear();
|
||||
lock (_autoProhibitedLock) _autoProhibited.Clear();
|
||||
|
||||
Reference in New Issue
Block a user