mbproxy: fix dashboard review findings, add named BCD tags + fleet config
Reviewed the new SignalR dashboard and fixed its two top findings: a stored XSS on the connection-detail page (unescaped tag name / direction / timestamp rendered into innerHTML) and FC03/FC04 cache hits bypassing the debug-view capture, which left cached tags frozen while their age climbed. Also adds an optional human-friendly Name to BCD tags surfaced on the debug view, and loads the real fleet config from tags.txt (12 named BCD tags, PLC Z28061) so the published appsettings.json is deploy-ready. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -29,21 +29,33 @@
|
||||
// Remove — removes specific addresses from the effective set for that PLC.
|
||||
// Effective set = (Global ∪ Add) − Remove, resolved per PDU.
|
||||
"BcdTags": {
|
||||
// Fleet-wide BCD tag list from tags.txt — applies to every PLC.
|
||||
// Address = Modbus PDU-decimal = (4xxxx Modbus address − 40001), which also
|
||||
// equals the DirectLOGIC V-memory address converted octal → decimal
|
||||
// (e.g. 41549 / V3014 → 41549 − 40001 = 1548 ; octal 3014 = 1548).
|
||||
// A 32-bit tag is ONE entry at its low/base address; it covers Address &
|
||||
// Address+1 (CDAB: low word at Address, high word at Address+1).
|
||||
// Name (optional) is a human-friendly label shown on the connection-detail
|
||||
// debug view; it has no effect on rewriting. tags.txt's "Data Direction" is
|
||||
// informational — the proxy rewrites BCD on whichever FC touches the address.
|
||||
// CacheTtlMs (optional, per entry) opts a tag into the Phase-11 response cache;
|
||||
// omitted / 0 = uncached (the default for every tag).
|
||||
"Global": [
|
||||
// V2000 (octal) = decimal address 1024. 16-bit BCD counter.
|
||||
{ "Address": 1024, "Width": 16 },
|
||||
// ── 16-bit setpoints — BCD16, HMI-written ────────────────────────────
|
||||
{ "Address": 1536, "Width": 16, "Name": "Left ArgonSP" }, // 41537
|
||||
{ "Address": 1539, "Width": 16, "Name": "Right ArgonSP" }, // 41540
|
||||
{ "Address": 1544, "Width": 16, "Name": "Left ChlorineSP" }, // 41545 · V3010
|
||||
{ "Address": 1545, "Width": 16, "Name": "Right ChlorineSP" }, // 41546 · V3011
|
||||
{ "Address": 1546, "Width": 16, "Name": "Left HydrogenSP" }, // 41547 · V3012
|
||||
{ "Address": 1547, "Width": 16, "Name": "Right HydrogenSP" }, // 41548 · V3013
|
||||
{ "Address": 1548, "Width": 16, "Name": "Left AirSP" }, // 41549 · V3014
|
||||
{ "Address": 1549, "Width": 16, "Name": "Right AirSP" }, // 41550 · V3015
|
||||
|
||||
// V2040 (octal) = decimal address 1056. 32-bit BCD total at 1056/1057.
|
||||
{ "Address": 1056, "Width": 32 },
|
||||
|
||||
// V2100 (octal) = decimal address 1088. 16-bit BCD setpoint.
|
||||
//
|
||||
// Phase 11: CacheTtlMs (optional) opts this tag into the response cache. With
|
||||
// CacheTtlMs > 0 set, upstream clients reading this register will see values up
|
||||
// to CacheTtlMs MILLISECONDS OLD — explicit acknowledgement of the staleness
|
||||
// window is required by enabling it. Default (omitted or 0) = cache disabled
|
||||
// for this tag. The cache is OFF by default for every tag.
|
||||
{ "Address": 1088, "Width": 16 /* , "CacheTtlMs": 1000 */ }
|
||||
// ── 32-bit runtimes — BCD32, read; CDAB pair spans Address & Address+1 ─
|
||||
{ "Address": 4616, "Width": 32, "Name": "MTA Runtime Left (min)" }, // 44617/44618 · V11010
|
||||
{ "Address": 4618, "Width": 32, "Name": "MTA Runtime Right (min)" }, // 44619/44620 · V11012
|
||||
{ "Address": 4626, "Width": 32, "Name": "FRR Runtime Left (min)" }, // 44627/44628 · V11022
|
||||
{ "Address": 4628, "Width": 32, "Name": "FRR Runtime Right (min)" } // 44629/44630 · V11024
|
||||
]
|
||||
},
|
||||
|
||||
@@ -56,26 +68,12 @@
|
||||
// port will cause a backend connect failure and an immediate upstream disconnect.
|
||||
"Plcs": [
|
||||
{
|
||||
"Name": "Line1-Mixer", // Human-readable name (shown on status page and in logs)
|
||||
"ListenPort": 5020, // Port the proxy listens on (upstream clients connect here)
|
||||
"Host": "10.0.1.1", // PLC IP address or hostname
|
||||
"Port": 502, // PLC Modbus TCP port (almost always 502)
|
||||
"BcdTags": {
|
||||
// Additional 32-bit tag specific to this PLC only.
|
||||
"Add": [
|
||||
{ "Address": 1200, "Width": 32 }
|
||||
],
|
||||
// Remove address 1056 from the Global list for this PLC
|
||||
// (this mixer doesn't use the 32-bit BCD total).
|
||||
"Remove": [ 1056 ]
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "Line1-Conveyor",
|
||||
"ListenPort": 5021,
|
||||
"Host": "10.0.1.2",
|
||||
"Port": 502
|
||||
// No BcdTags override — uses the Global set as-is.
|
||||
"Name": "Z28061", // Human-readable name (shown on status page and in logs)
|
||||
"ListenPort": 5020, // Port the proxy listens on (upstream clients connect here)
|
||||
"Host": "10.210.192.5", // PLC IP address or hostname
|
||||
"Port": 502 // PLC Modbus TCP port (almost always 502)
|
||||
// No BcdTags override — uses the Global set as-is. Per-PLC overrides are
|
||||
// available: "BcdTags": { "Add": [ ... ], "Remove": [ ... ] }.
|
||||
}
|
||||
// Add one entry per PLC. Ports must be unique per host. Typical fleet: 54 PLCs.
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user