node-red-contrib-alarm-ultimate 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +87 -13
  2. package/docs/images/alarm-panel-mock.svg +114 -0
  3. package/docs/images/banner.svg +63 -0
  4. package/docs/images/flow-overview.svg +85 -0
  5. package/examples/README.md +32 -11
  6. package/examples/alarm-ultimate-basic.json +0 -1
  7. package/examples/alarm-ultimate-dashboard-controls.json +575 -0
  8. package/examples/alarm-ultimate-dashboard-v2.json +762 -0
  9. package/examples/alarm-ultimate-dashboard.json +3 -3
  10. package/flowfuse-node-red-dashboard-1.30.2.tgz +0 -0
  11. package/nodes/AlarmSystemUltimate.html +174 -85
  12. package/nodes/AlarmSystemUltimate.js +39 -8
  13. package/nodes/AlarmUltimateInputAdapter.html +304 -0
  14. package/nodes/AlarmUltimateInputAdapter.js +188 -0
  15. package/nodes/AlarmUltimateSiren.html +3 -3
  16. package/nodes/AlarmUltimateSiren.js +6 -2
  17. package/nodes/AlarmUltimateState.html +3 -3
  18. package/nodes/AlarmUltimateState.js +6 -2
  19. package/nodes/AlarmUltimateZone.html +11 -6
  20. package/nodes/AlarmUltimateZone.js +27 -6
  21. package/nodes/icons/alarm-ultimate-siren.svg +6 -0
  22. package/nodes/icons/alarm-ultimate-state.svg +5 -0
  23. package/nodes/icons/alarm-ultimate-zone.svg +5 -0
  24. package/nodes/icons/alarm-ultimate.svg +6 -0
  25. package/nodes/presets/input-adapter/ax-pro-hikvision-ultimate.js +34 -0
  26. package/nodes/presets/input-adapter/boolean-from-payload.js +10 -0
  27. package/nodes/presets/input-adapter/ha-on-off.js +24 -0
  28. package/nodes/presets/input-adapter/knx-ultimate.js +29 -0
  29. package/nodes/presets/input-adapter/passthrough.js +7 -0
  30. package/package.json +5 -4
  31. package/test/alarm-system.spec.js +51 -0
  32. package/test/input-adapter.spec.js +243 -0
  33. package/test/output-nodes.spec.js +3 -0
  34. package/tools/alarm-json-mapper.html +1882 -460
  35. package/tools/alarm-panel.html +630 -131
package/README.md CHANGED
@@ -1,15 +1,59 @@
1
+ <p align="center">
2
+ <img src="docs/images/banner.svg" alt="Alarm Ultimate for Node-RED" width="900">
3
+ </p>
4
+
5
+ [![NPM version][npm-version-image]][npm-url]
6
+ [![NPM downloads][npm-downloads-image]][npm-url]
7
+ [![Node-RED Flows][flows-image]][flows-url]
8
+ [![License][license-image]][license-url]
9
+ [![GitHub issues][issues-image]][issues-url]
10
+ [![Status: beta][beta-image]][repo-url]
11
+
1
12
  # node-red-contrib-alarm-ultimate
2
13
 
3
- Alarm System Ultimate node for Node-RED.
14
+ Alarm System Ultimate nodes + web panel for Node-RED.
15
+
16
+ Includes:
17
+
18
+ - `AlarmSystemUltimate` (BETA): full alarm control panel node (zones, entry/exit delays, bypass, chime, 24h/fire/tamper, siren, event log).
19
+ - `AlarmUltimateInputAdapter`: translates incoming messages into zone messages for `AlarmSystemUltimate` using built-in or user-defined presets.
20
+ - Output-only helper nodes: `AlarmUltimateState`, `AlarmUltimateZone`, `AlarmUltimateSiren`.
21
+ - Web tools: Zones JSON mapper + web Alarm Panel (embeddable in Node-RED Dashboard).
22
+
23
+ Note: `AlarmSystemUltimate` is currently **BETA**.
4
24
 
5
- This package provides:
25
+ ## Table of contents
6
26
 
7
- - `AlarmSystemUltimate`: a full alarm control panel node (zones, entry/exit delays, bypass, chime, 24h/fire/tamper, siren, event log).
8
- - Output-only helper nodes to mirror alarm state into your flows (`AlarmUltimateState`, `AlarmUltimateZone`, `AlarmUltimateSiren`).
9
- - Web tools: a Zones JSON mapper and a web Alarm Panel (also embeddable in Node-RED Dashboard).
27
+ - [Install](#install)
28
+ - [Screenshots](#screenshots)
29
+ - [Nodes](#nodes)
30
+ - [Web tools](#web-tools)
31
+ - [Examples](#examples)
32
+ - [Permissions and endpoints](#permissions-and-endpoints)
33
+ - [Development](#development)
10
34
 
11
- Note: this repository currently ships `AlarmSystemUltimate` as **BETA**.
35
+ ## Install
36
+
37
+ - Palette Manager: Menu → **Manage palette** → **Install** → search `alarm ultimate`
38
+ - NPM:
39
+
40
+ ```bash
41
+ npm i node-red-contrib-alarm-ultimate
42
+ ```
12
43
 
44
+ ## Screenshots
45
+
46
+ ### Alarm Panel (web)
47
+
48
+ <p align="center">
49
+ <img src="docs/images/alarm-panel-mock.svg" alt="Alarm Panel mock" width="900">
50
+ </p>
51
+
52
+ ### Flow overview
53
+
54
+ <p align="center">
55
+ <img src="docs/images/flow-overview.svg" alt="Typical flow overview" width="900">
56
+ </p>
13
57
 
14
58
  ## Nodes
15
59
 
@@ -30,6 +74,13 @@ These nodes have no input and emit the current Alarm state (and changes) for one
30
74
  - `Alarm Zone` (`AlarmUltimateZone`): `msg.payload = true|false` for a selected zone
31
75
  - `Alarm Siren` (`AlarmUltimateSiren`): `msg.payload = true|false` when the siren is on/off
32
76
 
77
+ ### Input Adapter
78
+
79
+ `AlarmUltimateInputAdapter` translates incoming messages (from arbitrary sources) into the format expected by the Alarm zones.
80
+
81
+ - Built-in presets are shipped with the package.
82
+ - A single user preset (custom JavaScript) can be created/edited inside the node and is stored in the node configuration.
83
+
33
84
  ## Web tools
34
85
 
35
86
  These pages are served via the Node-RED admin HTTP endpoint:
@@ -42,32 +93,55 @@ The Alarm Panel supports:
42
93
  - Preselect node: `/alarm-ultimate/alarm-panel?id=<alarmNodeId>`
43
94
  - Embed mode (for Dashboard iframes): `/alarm-ultimate/alarm-panel?embed=1&id=<alarmNodeId>`
44
95
 
96
+ The Zones JSON Mapper supports:
97
+
98
+ - Sample message mapping (e.g. KNX Ultimate): map `topic`/`payload` fields and generate a zone template.
99
+ - ETS Group Addresses export (TSV): paste the exported table and generate zones in batch (boolean datapoints only).
100
+
45
101
  ## Examples
46
102
 
47
103
  - `examples/alarm-ultimate-basic.json`: ready-to-import flow with `AlarmSystemUltimate`, injects and debug nodes.
48
104
  - `examples/alarm-ultimate-dashboard.json`: Node-RED Dashboard example embedding the Alarm Panel in a `ui_template` iframe.
105
+ - `examples/alarm-ultimate-dashboard-controls.json`: Node-RED Dashboard example with the embedded panel plus command buttons (and a small sensor simulator).
106
+ - `examples/alarm-ultimate-dashboard-v2.json`: Dashboard 2.0 example for `@flowfuse/node-red-dashboard` (Alarm Panel + basic controls + status).
49
107
 
50
108
  See `examples/README.md`.
51
109
 
110
+ ## Development
111
+
112
+ Run tests:
113
+
114
+ ```bash
115
+ npm test
116
+ ```
117
+
52
118
  ## Permissions and endpoints
53
119
 
54
120
  When Node-RED authentication is enabled, the admin endpoints use these permissions (if available):
55
121
 
56
122
  - `AlarmSystemUltimate.read`
57
123
  - `AlarmSystemUltimate.write`
124
+ - `AlarmUltimateInputAdapter.read`
58
125
 
59
126
  HTTP admin endpoints:
60
127
 
61
128
  - `GET /alarm-ultimate/alarm/nodes`
62
129
  - `GET /alarm-ultimate/alarm/:id/state`
130
+ - `GET /alarm-ultimate/input-adapter/presets`
63
131
  - `POST /alarm-ultimate/alarm/:id/command`
64
132
  - `GET /alarm-ultimate/alarm-json-mapper`
65
133
  - `GET /alarm-ultimate/alarm-panel`
66
134
 
67
- ## Development
68
-
69
- Run tests:
70
-
71
- ```bash
72
- npm test
73
- ```
135
+ <!-- Badges (reference-style links) -->
136
+
137
+ [repo-url]: https://github.com/Supergiovane/node-red-contrib-alarm-ultimate
138
+ [npm-url]: https://www.npmjs.com/package/node-red-contrib-alarm-ultimate
139
+ [flows-url]: https://flows.nodered.org/node/node-red-contrib-alarm-ultimate
140
+ [license-url]: LICENSE
141
+ [issues-url]: https://github.com/Supergiovane/node-red-contrib-alarm-ultimate/issues
142
+ [npm-version-image]: https://img.shields.io/npm/v/node-red-contrib-alarm-ultimate.svg
143
+ [npm-downloads-image]: https://img.shields.io/npm/dm/node-red-contrib-alarm-ultimate.svg
144
+ [flows-image]: https://img.shields.io/badge/Node--RED%20Flows-library-8f0000?logo=nodered&logoColor=white
145
+ [license-image]: https://img.shields.io/npm/l/node-red-contrib-alarm-ultimate.svg
146
+ [issues-image]: https://img.shields.io/github/issues/Supergiovane/node-red-contrib-alarm-ultimate.svg
147
+ [beta-image]: https://img.shields.io/badge/status-beta-orange.svg
@@ -0,0 +1,114 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1200" height="700" viewBox="0 0 1200 700" role="img" aria-label="Alarm Panel mock screenshot">
2
+ <defs>
3
+ <linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
4
+ <stop offset="0" stop-color="#0b1020"/>
5
+ <stop offset="1" stop-color="#11162a"/>
6
+ </linearGradient>
7
+ <linearGradient id="accent" x1="0" y1="0" x2="1" y2="0">
8
+ <stop offset="0" stop-color="#ff375f"/>
9
+ <stop offset="1" stop-color="#ff9f0a"/>
10
+ </linearGradient>
11
+ <filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
12
+ <feDropShadow dx="0" dy="10" stdDeviation="14" flood-color="#000" flood-opacity="0.4"/>
13
+ </filter>
14
+ <style>
15
+ .h1 { font: 700 22px ui-sans-serif, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial; fill: #fff; }
16
+ .h2 { font: 600 14px ui-sans-serif, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial; fill: rgba(255,255,255,0.78); }
17
+ .label { font: 600 13px ui-sans-serif, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial; fill: rgba(255,255,255,0.86); }
18
+ .value { font: 700 18px ui-sans-serif, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial; fill: #fff; }
19
+ .tiny { font: 600 12px ui-sans-serif, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial; fill: rgba(255,255,255,0.68); }
20
+ </style>
21
+ </defs>
22
+
23
+ <rect width="1200" height="700" fill="url(#bg)"/>
24
+ <rect x="0" y="0" width="1200" height="10" fill="url(#accent)"/>
25
+
26
+ <!-- Window -->
27
+ <g filter="url(#shadow)">
28
+ <rect x="80" y="70" width="1040" height="560" rx="18" fill="rgba(255,255,255,0.06)" stroke="rgba(255,255,255,0.14)"/>
29
+ </g>
30
+
31
+ <!-- Top bar -->
32
+ <g>
33
+ <rect x="80" y="70" width="1040" height="64" rx="18" fill="rgba(255,255,255,0.07)"/>
34
+ <circle cx="118" cy="102" r="7" fill="#ff375f"/>
35
+ <circle cx="142" cy="102" r="7" fill="#ff9f0a"/>
36
+ <circle cx="166" cy="102" r="7" fill="#34c759"/>
37
+ <text class="h1" x="210" y="110">Alarm Panel</text>
38
+ <text class="h2" x="340" y="110">demo layout</text>
39
+ </g>
40
+
41
+ <!-- Status -->
42
+ <g transform="translate(120,160)">
43
+ <rect x="0" y="0" width="420" height="110" rx="16" fill="rgba(255,255,255,0.06)" stroke="rgba(255,255,255,0.12)"/>
44
+ <text class="label" x="22" y="32">Status</text>
45
+ <text class="value" x="22" y="70">DISARMED</text>
46
+ <rect x="280" y="30" width="120" height="56" rx="14" fill="rgba(52,199,89,0.18)" stroke="rgba(52,199,89,0.55)"/>
47
+ <text class="label" x="308" y="64">Ready</text>
48
+ </g>
49
+
50
+ <!-- Actions -->
51
+ <g transform="translate(560,160)">
52
+ <rect x="0" y="0" width="520" height="110" rx="16" fill="rgba(255,255,255,0.06)" stroke="rgba(255,255,255,0.12)"/>
53
+ <text class="label" x="22" y="32">Actions</text>
54
+ <g transform="translate(22,48)">
55
+ <rect x="0" y="0" width="140" height="44" rx="12" fill="rgba(255,55,95,0.18)" stroke="rgba(255,55,95,0.6)"/>
56
+ <text class="label" x="38" y="28">Arm</text>
57
+ <rect x="160" y="0" width="160" height="44" rx="12" fill="rgba(255,159,10,0.16)" stroke="rgba(255,159,10,0.55)"/>
58
+ <text class="label" x="202" y="28">Arm stay</text>
59
+ <rect x="340" y="0" width="158" height="44" rx="12" fill="rgba(255,255,255,0.08)" stroke="rgba(255,255,255,0.18)"/>
60
+ <text class="label" x="382" y="28">Disarm</text>
61
+ </g>
62
+ </g>
63
+
64
+ <!-- Zones list -->
65
+ <g transform="translate(120,300)">
66
+ <rect x="0" y="0" width="700" height="290" rx="16" fill="rgba(255,255,255,0.06)" stroke="rgba(255,255,255,0.12)"/>
67
+ <text class="label" x="22" y="34">Zones</text>
68
+
69
+ <!-- rows -->
70
+ <g transform="translate(22,56)">
71
+ <rect x="0" y="0" width="656" height="44" rx="12" fill="rgba(255,255,255,0.07)"/>
72
+ <text class="label" x="16" y="28">01 • Front door</text>
73
+ <rect x="540" y="10" width="100" height="24" rx="10" fill="rgba(52,199,89,0.18)" stroke="rgba(52,199,89,0.55)"/>
74
+ <text class="tiny" x="570" y="27">closed</text>
75
+
76
+ <rect x="0" y="58" width="656" height="44" rx="12" fill="rgba(255,255,255,0.07)"/>
77
+ <text class="label" x="16" y="86">02 • Living room PIR</text>
78
+ <rect x="540" y="68" width="100" height="24" rx="10" fill="rgba(52,199,89,0.18)" stroke="rgba(52,199,89,0.55)"/>
79
+ <text class="tiny" x="570" y="85">idle</text>
80
+
81
+ <rect x="0" y="116" width="656" height="44" rx="12" fill="rgba(255,255,255,0.07)"/>
82
+ <text class="label" x="16" y="144">03 • Garage</text>
83
+ <rect x="540" y="126" width="100" height="24" rx="10" fill="rgba(255,55,95,0.18)" stroke="rgba(255,55,95,0.6)"/>
84
+ <text class="tiny" x="572" y="143">open</text>
85
+
86
+ <rect x="0" y="174" width="656" height="44" rx="12" fill="rgba(255,255,255,0.07)"/>
87
+ <text class="label" x="16" y="202">04 • Smoke detector</text>
88
+ <rect x="540" y="184" width="100" height="24" rx="10" fill="rgba(255,159,10,0.16)" stroke="rgba(255,159,10,0.55)"/>
89
+ <text class="tiny" x="567" y="201">24h</text>
90
+ </g>
91
+ </g>
92
+
93
+ <!-- Side panel -->
94
+ <g transform="translate(840,300)">
95
+ <rect x="0" y="0" width="240" height="290" rx="16" fill="rgba(255,255,255,0.06)" stroke="rgba(255,255,255,0.12)"/>
96
+ <text class="label" x="20" y="34">Last events</text>
97
+ <g transform="translate(20,56)">
98
+ <rect x="0" y="0" width="200" height="54" rx="12" fill="rgba(255,255,255,0.07)"/>
99
+ <text class="tiny" x="14" y="22">10:24</text>
100
+ <text class="label" x="14" y="42">Zone 03 opened</text>
101
+
102
+ <rect x="0" y="66" width="200" height="54" rx="12" fill="rgba(255,255,255,0.07)"/>
103
+ <text class="tiny" x="14" y="88">10:26</text>
104
+ <text class="label" x="14" y="108">Disarmed</text>
105
+
106
+ <rect x="0" y="132" width="200" height="54" rx="12" fill="rgba(255,255,255,0.07)"/>
107
+ <text class="tiny" x="14" y="154">10:28</text>
108
+ <text class="label" x="14" y="174">Siren off</text>
109
+ </g>
110
+ </g>
111
+
112
+ <!-- Footnote -->
113
+ <text class="tiny" x="80" y="670">Illustration only (mock). The real panel is served at /alarm-ultimate/alarm-panel</text>
114
+ </svg>
@@ -0,0 +1,63 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1200" height="320" viewBox="0 0 1200 320" role="img" aria-label="Alarm Ultimate for Node-RED banner">
2
+ <defs>
3
+ <linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
4
+ <stop offset="0" stop-color="#0b1020"/>
5
+ <stop offset="1" stop-color="#171a2a"/>
6
+ </linearGradient>
7
+ <linearGradient id="accent" x1="0" y1="0" x2="1" y2="0">
8
+ <stop offset="0" stop-color="#ff375f"/>
9
+ <stop offset="1" stop-color="#ff9f0a"/>
10
+ </linearGradient>
11
+ <filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
12
+ <feDropShadow dx="0" dy="8" stdDeviation="10" flood-color="#000" flood-opacity="0.35"/>
13
+ </filter>
14
+ <style>
15
+ .title { font: 700 54px ui-sans-serif, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial; fill: #ffffff; }
16
+ .subtitle { font: 500 22px ui-sans-serif, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial; fill: rgba(255,255,255,0.78); }
17
+ .chip { font: 600 14px ui-sans-serif, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial; fill: rgba(255,255,255,0.92); letter-spacing: 0.2px; }
18
+ .mono { font: 600 14px ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; fill: rgba(255,255,255,0.92); }
19
+ </style>
20
+ </defs>
21
+
22
+ <rect width="1200" height="320" fill="url(#bg)"/>
23
+
24
+ <!-- Accent ribbon -->
25
+ <rect x="0" y="0" width="1200" height="10" fill="url(#accent)"/>
26
+
27
+ <!-- Decorative grid -->
28
+ <g opacity="0.16">
29
+ <path d="M80 0V320M160 0V320M240 0V320M320 0V320M400 0V320M480 0V320M560 0V320M640 0V320M720 0V320M800 0V320M880 0V320M960 0V320M1040 0V320M1120 0V320" stroke="#ffffff" stroke-width="1"/>
30
+ <path d="M0 60H1200M0 120H1200M0 180H1200M0 240H1200" stroke="#ffffff" stroke-width="1"/>
31
+ </g>
32
+
33
+ <!-- Card -->
34
+ <g filter="url(#shadow)">
35
+ <rect x="70" y="70" width="1060" height="180" rx="18" fill="rgba(255,255,255,0.06)" stroke="rgba(255,255,255,0.14)"/>
36
+ </g>
37
+
38
+ <!-- Icon -->
39
+ <g transform="translate(120,115)">
40
+ <rect x="0" y="0" width="86" height="86" rx="18" fill="rgba(255,55,95,0.15)" stroke="rgba(255,55,95,0.5)"/>
41
+ <path d="M43 16c-10.5 0-19 8.5-19 19v11.3l-5.7 11.4c-1.2 2.3 0.4 5.1 3 5.1H64c2.6 0 4.2-2.8 3-5.1l-5.7-11.4V35c0-10.5-8.5-19-19-19z" fill="#ff375f"/>
42
+ <path d="M32 68c0 6.1 4.9 11 11 11s11-4.9 11-11H32z" fill="#ff9f0a"/>
43
+ </g>
44
+
45
+ <!-- Text -->
46
+ <text class="title" x="240" y="150">Alarm Ultimate</text>
47
+ <text class="subtitle" x="240" y="186">Alarm nodes + web panel for Node-RED</text>
48
+
49
+ <!-- Chips -->
50
+ <g transform="translate(240,206)">
51
+ <rect x="0" y="0" width="132" height="30" rx="10" fill="rgba(255,255,255,0.08)" stroke="rgba(255,255,255,0.14)"/>
52
+ <text class="chip" x="16" y="20">Zones</text>
53
+
54
+ <rect x="148" y="0" width="170" height="30" rx="10" fill="rgba(255,255,255,0.08)" stroke="rgba(255,255,255,0.14)"/>
55
+ <text class="chip" x="164" y="20">Siren &amp; events</text>
56
+
57
+ <rect x="334" y="0" width="232" height="30" rx="10" fill="rgba(255,255,255,0.08)" stroke="rgba(255,255,255,0.14)"/>
58
+ <text class="chip" x="350" y="20">Dashboard embed</text>
59
+
60
+ <rect x="582" y="0" width="214" height="30" rx="10" fill="rgba(255,255,255,0.08)" stroke="rgba(255,255,255,0.14)"/>
61
+ <text class="mono" x="598" y="20">/alarm-ultimate</text>
62
+ </g>
63
+ </svg>
@@ -0,0 +1,85 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1200" height="520" viewBox="0 0 1200 520" role="img" aria-label="Flow overview diagram">
2
+ <defs>
3
+ <linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
4
+ <stop offset="0" stop-color="#0b1020"/>
5
+ <stop offset="1" stop-color="#11162a"/>
6
+ </linearGradient>
7
+ <linearGradient id="accent" x1="0" y1="0" x2="1" y2="0">
8
+ <stop offset="0" stop-color="#ff375f"/>
9
+ <stop offset="1" stop-color="#ff9f0a"/>
10
+ </linearGradient>
11
+ <filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
12
+ <feDropShadow dx="0" dy="10" stdDeviation="14" flood-color="#000" flood-opacity="0.35"/>
13
+ </filter>
14
+ <style>
15
+ .title { font: 800 20px ui-sans-serif, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial; fill: #fff; }
16
+ .label { font: 650 14px ui-sans-serif, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial; fill: rgba(255,255,255,0.85); }
17
+ .tiny { font: 600 12px ui-sans-serif, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial; fill: rgba(255,255,255,0.65); }
18
+ .mono { font: 650 12px ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; fill: rgba(255,255,255,0.8); }
19
+ </style>
20
+ <marker id="arrow" viewBox="0 0 10 10" refX="9.2" refY="5" markerWidth="8" markerHeight="8" orient="auto-start-reverse">
21
+ <path d="M 0 0 L 10 5 L 0 10 z" fill="rgba(255,255,255,0.65)"/>
22
+ </marker>
23
+ </defs>
24
+
25
+ <rect width="1200" height="520" fill="url(#bg)"/>
26
+ <rect x="0" y="0" width="1200" height="10" fill="url(#accent)"/>
27
+
28
+ <text class="title" x="80" y="58">Typical Node-RED flow</text>
29
+ <text class="tiny" x="80" y="84">Sensors publish to per-zone topics; commands go to a dedicated control topic; helper nodes mirror state.</text>
30
+
31
+ <!-- Nodes -->
32
+ <g filter="url(#shadow)">
33
+ <!-- Sensors -->
34
+ <rect x="80" y="140" width="260" height="300" rx="18" fill="rgba(255,255,255,0.06)" stroke="rgba(255,255,255,0.14)"/>
35
+ <text class="label" x="110" y="176">Sensors</text>
36
+ <text class="mono" x="110" y="202">topic: house/zone/01</text>
37
+ <text class="mono" x="110" y="226">payload: true/false</text>
38
+ <text class="mono" x="110" y="262">topic: house/zone/02</text>
39
+ <text class="mono" x="110" y="286">payload: true/false</text>
40
+ <text class="mono" x="110" y="322">topic: house/zone/03</text>
41
+ <text class="mono" x="110" y="346">payload: true/false</text>
42
+ <text class="tiny" x="110" y="392">Any topic != controlTopic</text>
43
+ </g>
44
+
45
+ <g filter="url(#shadow)">
46
+ <!-- Main node -->
47
+ <rect x="420" y="200" width="360" height="180" rx="18" fill="rgba(255,55,95,0.12)" stroke="rgba(255,55,95,0.55)"/>
48
+ <text class="label" x="450" y="240">AlarmSystemUltimate</text>
49
+ <text class="tiny" x="450" y="266">Zones + delays + bypass + siren + log</text>
50
+ <rect x="450" y="292" width="300" height="56" rx="14" fill="rgba(255,255,255,0.08)" stroke="rgba(255,255,255,0.16)"/>
51
+ <text class="mono" x="468" y="326">msg.topic === controlTopic</text>
52
+ </g>
53
+
54
+ <g filter="url(#shadow)">
55
+ <!-- Commands -->
56
+ <rect x="420" y="140" width="360" height="46" rx="14" fill="rgba(255,159,10,0.14)" stroke="rgba(255,159,10,0.55)"/>
57
+ <text class="label" x="450" y="170">Commands (Inject / MQTT / UI)</text>
58
+ </g>
59
+
60
+ <g filter="url(#shadow)">
61
+ <!-- Helpers -->
62
+ <rect x="860" y="140" width="260" height="300" rx="18" fill="rgba(255,255,255,0.06)" stroke="rgba(255,255,255,0.14)"/>
63
+ <text class="label" x="890" y="176">Output-only nodes</text>
64
+
65
+ <rect x="890" y="200" width="200" height="56" rx="14" fill="rgba(255,255,255,0.07)" stroke="rgba(255,255,255,0.14)"/>
66
+ <text class="label" x="910" y="234">AlarmUltimateState</text>
67
+ <text class="tiny" x="910" y="252">payload: \"armed\" | \"disarmed\"</text>
68
+
69
+ <rect x="890" y="270" width="200" height="56" rx="14" fill="rgba(255,255,255,0.07)" stroke="rgba(255,255,255,0.14)"/>
70
+ <text class="label" x="910" y="304">AlarmUltimateZone</text>
71
+ <text class="tiny" x="910" y="322">payload: true/false (selected)</text>
72
+
73
+ <rect x="890" y="340" width="200" height="56" rx="14" fill="rgba(255,255,255,0.07)" stroke="rgba(255,255,255,0.14)"/>
74
+ <text class="label" x="910" y="374">AlarmUltimateSiren</text>
75
+ <text class="tiny" x="910" y="392">payload: true/false</text>
76
+ </g>
77
+
78
+ <!-- Arrows -->
79
+ <path d="M340 290H420" stroke="rgba(255,255,255,0.65)" stroke-width="2.2" marker-end="url(#arrow)"/>
80
+ <path d="M600 186V200" stroke="rgba(255,255,255,0.65)" stroke-width="2.2" marker-end="url(#arrow)"/>
81
+ <path d="M780 290H860" stroke="rgba(255,255,255,0.65)" stroke-width="2.2" marker-end="url(#arrow)"/>
82
+
83
+ <!-- Footer -->
84
+ <text class="tiny" x="80" y="486">Web tools: /alarm-ultimate/alarm-json-mapper • /alarm-ultimate/alarm-panel (also embeddable)</text>
85
+ </svg>
@@ -1,21 +1,42 @@
1
- ## Esempi
1
+ ## Examples
2
2
 
3
- Importa il flow da `examples/alarm-ultimate-basic.json` in Node-RED:
3
+ Import the flow from `examples/alarm-ultimate-basic.json` into Node-RED:
4
4
 
5
5
  1. Menu → **Import**
6
- 2. Incolla il contenuto del file JSON
6
+ 2. Paste the JSON file content
7
7
  3. Deploy
8
8
 
9
- Il flow include:
9
+ This flow includes:
10
10
 
11
- - 1 nodo `AlarmSystemUltimate` con 2 zone di esempio
12
- - Inject per arm/disarm, bypass, sensori open/close
13
- - I nodi output-only (`Alarm State`, `Alarm Zone`, `Alarm Siren`) collegati a debug
11
+ - 1 `AlarmSystemUltimate` node with 2 example zones
12
+ - Inject nodes for arm/disarm, bypass, sensor open/close
13
+ - Output-only nodes (`Alarm State`, `Alarm Zone`, `Alarm Siren`) connected to debug
14
+
15
+ Notes:
16
+
17
+ - The old Alarm “Translator” option has been removed. If you need to translate incoming device messages, use the `AlarmUltimateInputAdapter` node.
18
+ - Zones can be edited from the Alarm node editor via the “Manage zones” button (opens the `alarm-json-mapper` tool).
14
19
 
15
20
  ## Dashboard (node-red-dashboard)
16
21
 
17
- Importa `examples/alarm-ultimate-dashboard.json`.
22
+ Import `examples/alarm-ultimate-dashboard.json`.
23
+
24
+ - Requires `node-red-dashboard` installed (`ui_*` nodes).
25
+ - The widget uses an iframe pointing to `"/alarm-ultimate/alarm-panel?embed=1&id=<alarmNodeId>"`.
26
+ - If you changed `httpAdminRoot`, update the iframe URL accordingly (e.g. `"/red/alarm-ultimate/alarm-panel?...`).
27
+
28
+ ### Dashboard + commands (panel + controls)
29
+
30
+ Import `examples/alarm-ultimate-dashboard-controls.json`.
31
+
32
+ - Includes the panel (iframe) + Dashboard buttons for `arm`, `disarm`, `status`, `list_open_zones`, `siren_on/off`, `panic`.
33
+ - Also includes a small “sensor simulator” (buttons that send `true/false` on `sensor/frontdoor` and `sensor/living_pir`).
34
+ - The iframe uses a *relative* URL (`alarm-ultimate/...`) so it works even when Node-RED is served under a path prefix (e.g. Home Assistant Ingress).
35
+
36
+ ## Dashboard V2 (FlowFuse / @flowfuse/node-red-dashboard)
37
+
38
+ Import `examples/alarm-ultimate-dashboard-v2.json`.
18
39
 
19
- - Richiede `node-red-dashboard` installato (nodi `ui_*`).
20
- - Il widget usa un iframe verso `"/alarm-ultimate/alarm-panel?embed=1&id=<alarmNodeId>"`.
21
- - Se hai cambiato `httpAdminRoot`, aggiorna l'URL dell'iframe di conseguenza (es: `"/red/alarm-ultimate/alarm-panel?...`).
40
+ - Requires `@flowfuse/node-red-dashboard` installed (`ui-*` nodes).
41
+ - Embeds the Alarm Panel via a Dashboard 2.0 `ui-template` (Vue SFC) iframe.
42
+ - Includes basic command buttons (`arm`, `disarm`, `status`), a small sensor simulator, and two status widgets (`AlarmUltimateState`, `AlarmUltimateSiren` → `ui-text`).
@@ -23,7 +23,6 @@
23
23
  "name": "Home Alarm",
24
24
  "controlTopic": "alarm",
25
25
  "payloadPropName": "payload",
26
- "translatorConfig": "",
27
26
  "persistState": true,
28
27
  "requireCodeForArm": false,
29
28
  "requireCodeForDisarm": false,