Flat-structure generator + Rego guards, rename Laser & Fog to DJ Booth
Closes #1. Generator (scripts/flow2json.py): - Emit all nodes at top level with z field (no wrapped tabs) - Set icon: "" on ui-button to avoid Dashboard 2.0 prependIcon TypeError - Set z field on ui-* widgets so they render in Dashboard 2.0 SPA - Use ui-text label from spec, not name Policy (policy/flow.rego) — 9 new deny rules: - deny_wrapped_tab: tab with internal nodes[] (nodered 5.0 bug) - deny_missing_wires: missing or non-array wires (Flow.js rewireNode crash) - deny_no_autoconnect: mqtt-broker must reconnect - deny_invalid_protocol: protocolVersion must be 3/4/5 - deny_unused_broker: broker declared but never referenced - Plus deny_broker_port / deny_group_ref / deny_page_ref / deny_wire_ref refinements Flow (zigbee-monitor.*): - 22-node flat flow: button-in → btn-filter → 4 parallel plug-outs - 4 ui-text widgets + ui-button for permit-join (60s) - Renamed plug: "Laser & Fog" → "DJ Booth" (matches z2m friendly_name) Repo hygiene: - justfile: fix host IP 192.168.9.147 → 192.168.81.147, /ui → /dashboard - README.md: document 8 generation invariants and rule table Verified end-to-end: publishing {"action":"single"} on zigbee2mqtt/Door Button triggers {"state":"TOGGLE"} on all four .../set topics including the renamed DJ Booth. 462/462 conftest tests pass.
This commit is contained in:
+14
-1
@@ -40,7 +40,7 @@ def make_broker_node(name, cfg):
|
||||
def make_node(nd, col, row, broker_map, group_map):
|
||||
ntype = nd["type"]
|
||||
nid = nd.get("id", new_id())
|
||||
node = {"id": nid, "z": FLOW_ID, "type": ntype, "wires": [],
|
||||
node = {"id": nid, "type": ntype, "wires": [],
|
||||
"name": nd.get("label", nd.get("name", ""))}
|
||||
node["x"] = COLUMNS[col] if col < len(COLUMNS) else col * 300 + 170
|
||||
node["y"] = row * ROW_HEIGHT + 80
|
||||
@@ -145,9 +145,22 @@ def build_flow(doc, flow_def, node_positions):
|
||||
})
|
||||
group_map[grp["name"]] = gid
|
||||
|
||||
nodes.append({
|
||||
"id": FLOW_ID,
|
||||
"type": "tab",
|
||||
"label": flow_def.get("tab", "Flow"),
|
||||
"disabled": False,
|
||||
"info": flow_def.get("description", ""),
|
||||
"env": [],
|
||||
})
|
||||
|
||||
for i, nd in enumerate(flow_def["nodes"]):
|
||||
col, row = node_positions.get(nd["id"], (0, i))
|
||||
node = make_node(nd, col, row, broker_map, group_map)
|
||||
node["z"] = FLOW_ID
|
||||
if node.get("type") == "ui-button":
|
||||
node["icon"] = ""
|
||||
node["label"] = nd.get("label", nd.get("name", ""))
|
||||
nodes.append(node)
|
||||
|
||||
wires = flow_def.get("wires", {})
|
||||
|
||||
Reference in New Issue
Block a user