+ Per-tag addressing for Modbus drivers isn't part of equipment import —
+ tags are configured at the driver-instance level via the
+ Drivers tab. Use the
+ address-preview tool to sanity-check
+ grammar strings (40001:F:CDAB, HR1:I, V2000 for
+ DL205 family, etc.) before pasting them into the driver config.
+
+
diff --git a/src/ZB.MOM.WW.OtOpcUa.Admin/Components/Pages/Modbus/ModbusAddressPreview.razor b/src/ZB.MOM.WW.OtOpcUa.Admin/Components/Pages/Modbus/ModbusAddressPreview.razor
new file mode 100644
index 0000000..f6c35d9
--- /dev/null
+++ b/src/ZB.MOM.WW.OtOpcUa.Admin/Components/Pages/Modbus/ModbusAddressPreview.razor
@@ -0,0 +1,85 @@
+@page "/modbus/address-preview"
+@using ZB.MOM.WW.OtOpcUa.Driver.Modbus
+
+@*
+ #149 — standalone preview / sanity-check tool for Modbus address strings. The Admin UI
+ doesn't yet have a per-tag CRUD surface (tags are seeded via SQL or arrive at runtime
+ through ITagDiscovery), so the ModbusAddressEditor component shipped in #145 needs a
+ page where operators can paste an address string and confirm it parses to what they
+ expect before committing it to a config row.
+
+ Doubles as a "did the parser ship correctly" smoke target for QA + a copy-pasteable
+ grammar reference for users skimming the docs.
+*@
+
+Modbus address preview
+
+
+
Modbus address preview
+
+ Paste an address string and watch the parser break it down field by field. Useful for
+ sanity-checking a tag spreadsheet row before adding it to a driver's DriverConfig.
+ Full grammar: docs/v2/modbus-addressing.md.
+
+
+
+
+
+
+
+ @if (_family == ModbusFamily.MELSEC)
+ {
+
+
+
+
+ }
+
+
+
+
+
+
+
Quick-reference grammar
+
@_grammarReference
+
+
+@code {
+ private string? _address;
+ private ModbusFamily _family = ModbusFamily.Generic;
+ private MelsecFamily _melsecSubFamily = MelsecFamily.Q_L_iQR;
+
+ // Held as a const string rather than inline markup so the Razor parser doesn't try to
+ // interpret the angle-bracket grammar tokens as element open/close.
+ private const string _grammarReference = @"[.][:[]][:][:]
+
+Examples (post-#146 type codes):
+ 40001 HoldingRegisters[0], Int16
+ 400001 same, 6-digit form
+ 40001:F Float32 (HR[0..1])
+ 40001:F:CDAB Float32 word-swapped
+ 40001:STR20 20-char ASCII string
+ 40001:S:5 Int16[5] array (3-field shorthand)
+ 40001:I:CDAB:10 Int32[10] word-swapped (4-field strict)
+ 40001.5 bit 5 of HR[0]
+ HR1:I Int32 via mnemonic region (matches Wonderware)
+ C100 Coil 100 (mnemonic, 1-based)
+ V2000:F:CDAB DL205 V-memory at PDU 1024 (Family=DL205)
+ D100:I MELSEC D-register 100, Int32 (Family=MELSEC)
+
+Type codes: BOOL, S (Int16), US (UInt16), I (Int32), UI (UInt32),
+ I_64 (Int64), UI_64 (UInt64), F, D, BCD, BCD_32, STR
+Byte order: ABCD (BE default), CDAB (word-swap), BADC (byte-swap), DCBA (full reverse)";
+}