iobroker.statechart 0.2.0 → 0.3.0
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.
- package/LICENSE +21 -21
- package/README.md +42 -530
- package/admin/build/tab.js +118 -117
- package/admin/statechart.png +0 -0
- package/admin/{style.css → tab.css} +0 -2
- package/admin/tab_m.html +1 -1
- package/build/lib/chart-analysis.js +367 -0
- package/build/lib/chart-analysis.js.map +7 -0
- package/build/lib/chart-codegen.js +82 -15
- package/build/lib/chart-codegen.js.map +3 -3
- package/build/lib/chart-helpers.js +12 -0
- package/build/lib/chart-helpers.js.map +2 -2
- package/build/lib/chart-model.js +138 -14
- package/build/lib/chart-model.js.map +2 -2
- package/build/lib/chart-runtime.js +732 -87
- package/build/lib/chart-runtime.js.map +3 -3
- package/build/lib/chart-structure.js +73 -2
- package/build/lib/chart-structure.js.map +2 -2
- package/build/lib/chart-validation.js +86 -17
- package/build/lib/chart-validation.js.map +3 -3
- package/build/main.js +330 -34
- package/build/main.js.map +2 -2
- package/io-package.json +18 -34
- package/package.json +2 -1
- package/admin/i18n/de.json +0 -4
- package/admin/i18n/en.json +0 -4
- package/admin/i18n/es.json +0 -4
- package/admin/i18n/fr.json +0 -4
- package/admin/i18n/it.json +0 -4
- package/admin/i18n/nl.json +0 -4
- package/admin/i18n/pl.json +0 -4
- package/admin/i18n/pt.json +0 -4
- package/admin/i18n/ru.json +0 -4
- package/admin/i18n/uk.json +0 -4
- package/admin/i18n/zh-cn.json +0 -4
- package/admin/jsonConfig.json +0 -19
- package/admin/statechart.svg +0 -38
package/README.md
CHANGED
|
@@ -10,11 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
**Tests:** 
|
|
12
12
|
|
|
13
|
-
**
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
<a id="english"></a>
|
|
13
|
+
**English** | [Deutsch](docs/de/README.md)
|
|
18
14
|
|
|
19
15
|
## State machine adapter for ioBroker
|
|
20
16
|
|
|
@@ -22,23 +18,33 @@ Model your automations as **state machines** (statecharts) in a graphical editor
|
|
|
22
18
|
chart editors known from model based development. States, transitions with events, conditions and
|
|
23
19
|
actions, timers and function blocks are drawn in the ioBroker admin and executed by the adapter.
|
|
24
20
|
|
|
21
|
+

|
|
22
|
+
|
|
23
|
+
*An alarm system as example: exit and entry delay, alarm with siren and notification in parallel, the live values
|
|
24
|
+
of the running chart on the top left, the variables on the right.*
|
|
25
|
+
|
|
25
26
|
### Features
|
|
26
27
|
|
|
27
28
|
- Graphical editor as its own entry in the admin side bar
|
|
28
|
-
- States with `entry`, `during` and `exit` actions
|
|
29
|
+
- States with `entry`, `during` and `exit` actions, nested and parallel states (AND), history junction
|
|
29
30
|
- Transitions with labels in the well-known syntax `event[condition]{action}`
|
|
30
|
-
-
|
|
31
|
+
- Temporal logic like in Stateflow: `after(5, sec)`, `before`, `at`, `every`, counting inputs, `after(5, min, condition)`, `elapsed()`, `duration()`, and every day at a time or an astro event: `at("sunset", -30)`
|
|
31
32
|
- Function blocks with your own JavaScript functions, usable in all conditions and actions
|
|
32
33
|
- Inputs and outputs mapped to any ioBroker states
|
|
33
34
|
- Live view: the active state is highlighted in the editor, the current values of the variables are shown, taken
|
|
34
35
|
transitions light up, and a history shows when which transition was taken and why
|
|
36
|
+
- Simulation: run the chart from the editor without switching anything, set the inputs by hand, advance the time,
|
|
37
|
+
breakpoints and single steps
|
|
35
38
|
- Code editor with syntax highlighting, error checking (e.g. unknown variables) and completion
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
+
- Static check of the chart: states which never become active, transitions which are never taken, unused variables
|
|
40
|
+
- Several independent charts per instance, which can be paused, reset and woken up by states (e.g. from vis)
|
|
41
|
+
- Import and export of charts as JSON files, export of the whole chart as PNG image (e.g. for the forum)
|
|
42
|
+
- Comments on states, transitions and function blocks, notes on the canvas, and a color per state
|
|
39
43
|
- Per input: wake up on every update or only on changes, filter by ack, debounce
|
|
40
|
-
- Helper functions: setState, setStateDelayed, sendTo, isTimeBetween, isDaytime, astroTime, change detection (hasChanged...)
|
|
41
|
-
-
|
|
44
|
+
- Helper functions: getState (any state), setState, setStateDelayed, sendTo, isTimeBetween, isDaytime, astroTime, change detection (hasChanged...)
|
|
45
|
+
- Align and distribute the selected elements, snap to the grid (can be switched off)
|
|
46
|
+
- The list of charts and the properties panel can be resized and collapsed, for more space for the chart
|
|
47
|
+
- Undo/redo (Ctrl+Z, Ctrl+Y), cut/copy/paste/delete of states, function blocks and notes (Ctrl+X, Ctrl+C, Ctrl+V, Del), also between charts, and a warning about unsaved changes
|
|
42
48
|
- **Show code**: the JavaScript generated from the chart, showing exactly how the adapter executes it
|
|
43
49
|
|
|
44
50
|
### Installation
|
|
@@ -55,13 +61,14 @@ The adapter is not in the ioBroker repositories yet, but can be installed direct
|
|
|
55
61
|
Then add an instance of **State Machine**. This installs the current development version, which may
|
|
56
62
|
still change incompatibly.
|
|
57
63
|
|
|
58
|
-
Requirements: Node.js 22 or newer, js-controller 6.0.11 or newer, admin 7.6.
|
|
64
|
+
Requirements: Node.js 22 or newer, js-controller 6.0.11 or newer, admin 7.6.20 or newer.
|
|
59
65
|
|
|
60
66
|
### Getting started
|
|
61
67
|
|
|
62
68
|
1. Open **State Machine** in the admin side bar.
|
|
63
69
|
2. Create a chart with **+** in the list on the left.
|
|
64
|
-
3. Define the variables in the tab **Variables** on the right
|
|
70
|
+
3. Define the variables in the tab **Variables** on the right, with **+** next to their group. The variables are
|
|
71
|
+
grouped by kind, each one is a line with its state and current value, a click on it shows its settings:
|
|
65
72
|
- **Input**: read from an ioBroker state, every change wakes up the chart
|
|
66
73
|
- **Output**: written to an ioBroker state when an action changes it
|
|
67
74
|
- **Local**: only exists inside the chart, with an initial value
|
|
@@ -71,6 +78,7 @@ Requirements: Node.js 22 or newer, js-controller 6.0.11 or newer, admin 7.6.17 o
|
|
|
71
78
|
end where the states face each other and follow them when they are moved. To fix an end at another place,
|
|
72
79
|
select the transition and drag the round grip at the end along the border (double click: automatic again). To
|
|
73
80
|
move a transition to another state, drop the grip on that state: its label and all other properties are kept.
|
|
81
|
+
Drag a label to move it, e.g. if it covers another one; a moved label stays connected to its arrow by a thin line.
|
|
74
82
|
6. Select a state or transition (or double click it) to edit its actions or label on the right.
|
|
75
83
|
7. Click **Save**. New charts are paused: start the chart with ▶ in the chart list. After saving, the adapter
|
|
76
84
|
restarts a running chart immediately.
|
|
@@ -90,525 +98,17 @@ Requirements: Node.js 22 or newer, js-controller 6.0.11 or newer, admin 7.6.17 o
|
|
|
90
98
|
| Transition | Label |
|
|
91
99
|
|---|---|
|
|
92
100
|
| Off → On | `motion[motion == true]` |
|
|
93
|
-
| On → Off | `after(2, min
|
|
94
|
-
|
|
95
|
-
### Transition labels
|
|
96
|
-
|
|
97
|
-
```
|
|
98
|
-
event[condition]{action}
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
All parts are optional and may span several lines.
|
|
102
|
-
|
|
103
|
-
| Part | Meaning | Example |
|
|
104
|
-
|---|---|---|
|
|
105
|
-
| `event` | Name of an input: the transition is only checked when this input changes | `motion` |
|
|
106
|
-
| `after(n, unit)` | Instead of an event: valid from *n* units after entering the state on. Then a timer wakes up the chart, and the condition is checked again on every following wakeup. Units: `msec`, `sec`, `min` | `after(30, sec)` |
|
|
107
|
-
| `[condition]` | JavaScript expression, the transition is only taken if it is true | `[temp > 21 && !window]` |
|
|
108
|
-
| `{action}` | JavaScript, executed when the transition is taken | `{count++; light = true;}` |
|
|
109
|
-
|
|
110
|
-
Without event, a transition is checked whenever any input changes. If a state has several outgoing
|
|
111
|
-
transitions, they are checked in the order of their **priority** (shown at the arrow).
|
|
112
|
-
|
|
113
|
-
### When inputs wake up the chart
|
|
114
|
-
|
|
115
|
-
Every input has three settings in the tab **Variables**:
|
|
116
|
-
|
|
117
|
-
| Setting | Values | Default |
|
|
118
|
-
|---|---|---|
|
|
119
|
-
| **Wake up on** | every update / value changes only | every update |
|
|
120
|
-
| **Acknowledged (ack)** | any / confirmed values only (`ack=true`) / commands only (`ack=false`) | any |
|
|
121
|
-
| **Debounce (ms)** | the chart wakes up only after the input had no update for this time, with its last value | 0 (off) |
|
|
122
|
-
|
|
123
|
-
Updates filtered out by ack do not change the variable, so it e.g. only contains confirmed values.
|
|
124
|
-
|
|
125
|
-
### Actions
|
|
126
|
-
|
|
127
|
-
Actions and conditions are JavaScript. All variables of the chart can be used directly by their name,
|
|
128
|
-
plus `Math`, `Date`, `JSON` etc. and `log("text")` to write to the ioBroker log.
|
|
129
|
-
|
|
130
|
-
| Action | Executed |
|
|
131
|
-
|---|---|
|
|
132
|
-
| `entry` | when the state is entered |
|
|
133
|
-
| `during` | on every wakeup of the chart while the state is active and none of its outgoing transitions is taken |
|
|
134
|
-
| `exit` | when the state is left |
|
|
135
|
-
|
|
136
|
-
### Nested states
|
|
137
|
-
|
|
138
|
-
Drop a state into another state to make it a **sub state**, drag it out again to undo it. While dragging,
|
|
139
|
-
the state it would be moved into is highlighted. Every level has its own initial state (dot with arrow).
|
|
140
|
-
|
|
141
|
-
- Entering a super state also enters its initial sub state (or the sub state the transition points to).
|
|
142
|
-
Leaving it leaves the active sub state first.
|
|
143
|
-
- On every wakeup, each active state is processed in this order, starting with the outermost one:
|
|
144
|
-
1. transitions leaving the state, 2. its `during` action, 3. its **inner transitions**, 4. its active sub state.
|
|
145
|
-
So the transitions of a super state have priority over those of its sub states.
|
|
146
|
-
- A transition from a state to one of its own sub states is an **inner transition** (dot at its start):
|
|
147
|
-
the state stays active, only its active sub state is left, its own `entry`/`exit` are not executed.
|
|
148
|
-
With the option **Leave and enter the parent state again**, it is left and entered again instead.
|
|
149
|
-
|
|
150
|
-
### Helper functions
|
|
151
|
-
|
|
152
|
-
In conditions, actions and function blocks:
|
|
153
|
-
|
|
154
|
-
| Function | Purpose |
|
|
155
|
-
|---|---|
|
|
156
|
-
| `log(message, level)` | writes to the ioBroker log, level `"debug"`, `"info"` (default), `"warn"` or `"error"` |
|
|
157
|
-
| `setState(id, value, ack)` | writes any ioBroker state, `ack` is `false` by default |
|
|
158
|
-
| `setStateDelayed(id, value, delayMs, ack)` | writes after a delay, cancelled when the chart stops |
|
|
159
|
-
| `sendTo(instance, command, message)` | sends a message to an adapter, e.g. `sendTo("telegram.0", "send", { text: "Window open" })` |
|
|
160
|
-
| `isTimeBetween("22:00", "06:00")` | true if the current time is in the range, also over midnight |
|
|
161
|
-
| `isDaytime()` | true between sunrise and sunset |
|
|
162
|
-
| `astroTime("sunset", offsetMinutes)` | time of an astro event today as `Date`: `sunrise`, `sunset`, `dawn`, `dusk`, `solarNoon`, ... |
|
|
163
|
-
| `hasChanged(variable)` | true if the variable has changed, see below |
|
|
164
|
-
| `hasChangedFrom(variable, value)` | true if the variable has changed and its previous value was `value` |
|
|
165
|
-
| `hasChangedTo(variable, value)` | true if the variable has changed to `value`, e.g. `hasChangedTo(button, true)` for a rising edge |
|
|
101
|
+
| On → Off | `after(2, min, !motion)` |
|
|
166
102
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
the chart by themselves, they are evaluated when it wakes up.
|
|
103
|
+
The light goes on with motion and off after 2 minutes without motion: `after(2, min, !motion)` waits until
|
|
104
|
+
`motion` has been false for 2 minutes, every new motion starts the time again.
|
|
170
105
|
|
|
171
|
-
|
|
172
|
-
wakeup with its value at the start of the previous wakeup. Inputs, outputs and locals can be checked. An update
|
|
173
|
-
with the same value is no change, neither is a wakeup by another input or a timer, so `[hasChangedTo(button, true)]`
|
|
174
|
-
is only true once per press of the button. On the wakeup after the start nothing has changed yet. A change of a
|
|
175
|
-
local by an action is seen on the next wakeup, also in a super step. Objects and arrays are compared by their
|
|
176
|
-
contents.
|
|
106
|
+
### Documentation
|
|
177
107
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
```js
|
|
184
|
-
const LIMIT = 22;
|
|
185
|
-
|
|
186
|
-
function tooWarm(temp) {
|
|
187
|
-
return temp > LIMIT;
|
|
188
|
-
}
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
Transition label: `[tooWarm(temperature)]{heating = false;}`
|
|
192
|
-
|
|
193
|
-
### Comments and notes
|
|
194
|
-
|
|
195
|
-
- **Comment:** states, transitions, function blocks and the chart itself have a field **Comment** in their properties.
|
|
196
|
-
A speech bubble on the canvas shows that there is a comment, the comment is shown as tooltip.
|
|
197
|
-
- **Notes** (icon **Add note** in the toolbar) are free texts on the canvas, like sticky notes. Drop a note into a
|
|
198
|
-
state, so it moves together with it.
|
|
199
|
-
|
|
200
|
-
Comments and notes have no influence on the execution. They are included in the generated code and in exported
|
|
201
|
-
files, and changing them does not prevent restoring the state after a restart.
|
|
202
|
-
|
|
203
|
-
### Watching a running chart
|
|
204
|
-
|
|
205
|
-
While a chart runs, the editor shows what it does:
|
|
206
|
-
|
|
207
|
-
- The **active states** have a green border.
|
|
208
|
-
- **Live values** (panel at the top left of the canvas, switched on and off with the last icon in the toolbar):
|
|
209
|
-
the current values of all variables. They are also shown below each variable in the tab **Variables**.
|
|
210
|
-
- A **transition lights up** for a moment when the chart takes it.
|
|
211
|
-
- The tab **History** lists the starts of the chart and the transitions taken, newest first: when, from which state
|
|
212
|
-
to which, triggered by which input or by a timer (`after`), and which states were active afterwards. Click a
|
|
213
|
-
transition to select it in the chart. The adapter keeps the last 200 events, also when the editor is closed and
|
|
214
|
-
after a restart. **Clear history** removes them.
|
|
215
|
-
|
|
216
|
-
The live values and the history come from the running chart, so they refer to the saved chart, not to unsaved
|
|
217
|
-
changes in the editor.
|
|
218
|
-
|
|
219
|
-
### Import and export
|
|
220
|
-
|
|
221
|
-
- **Export chart** (last icon in the toolbar of the editor) saves the chart as JSON file, including unsaved changes.
|
|
222
|
-
- **Export all charts** (icon above the chart list) saves all saved charts in one file.
|
|
223
|
-
- **Import charts** (icon above the chart list) adds the charts of such a file as new charts, existing charts are not
|
|
224
|
-
changed. The file is checked before (structure, IDs, references between states and transitions).
|
|
225
|
-
|
|
226
|
-
Imported charts are **paused**: their variables may refer to states of another system. Check them in the tab
|
|
227
|
-
**Variables**, then start the chart with the button in the chart list.
|
|
228
|
-
|
|
229
|
-
### States created by the adapter
|
|
230
|
-
|
|
231
|
-
For every chart, the adapter creates below `statechart.<instance>.charts.<chart>`:
|
|
232
|
-
|
|
233
|
-
| State | Content |
|
|
234
|
-
|---|---|
|
|
235
|
-
| `activeState` | Name of the active state, nested states as `Parent.Child` |
|
|
236
|
-
| `activeStateIds` | IDs of all active states as JSON |
|
|
237
|
-
| `snapshot` | Stored state of the chart (active states, when they were entered, locals), see below |
|
|
238
|
-
| `values` | Current values of all variables as JSON, `{}` if the chart does not run |
|
|
239
|
-
| `history` | The last 200 events (starts and transitions taken) as JSON. Writing it without ack clears it |
|
|
240
|
-
|
|
241
|
-
The chart itself is stored in the object `statechart.<instance>.charts.<chart>`.
|
|
242
|
-
|
|
243
|
-
### Restart of the adapter
|
|
244
|
-
|
|
245
|
-
After a restart of the adapter or of ioBroker, every chart continues in the states which were active
|
|
246
|
-
before, with its local variables. The entry actions are not executed again, and timers continue with
|
|
247
|
-
their remaining time. A timer which expired while the adapter was stopped is taken right after the start.
|
|
248
|
-
Like after every start, the chart then wakes up once, so changes of the inputs during the stop are
|
|
249
|
-
noticed.
|
|
250
|
-
|
|
251
|
-
The chart starts in its initial state instead if it was changed meanwhile (positions in the editor do not
|
|
252
|
-
count), after saving it in the editor, after pausing it, and if the option **Restore the state after a
|
|
253
|
-
restart** in the chart properties is switched off. Variables declared in function blocks are not restored.
|
|
254
|
-
|
|
255
|
-
### Execution model and differences to other statechart tools
|
|
256
|
-
|
|
257
|
-
- The adapter uses [XState](https://stately.ai/docs/xstate) to execute the charts.
|
|
258
|
-
- Every change of an input wakes up the chart once, as well as an expiring `after(...)` and the start of the chart
|
|
259
|
-
(also after restoring it). Transitions without event, e.g. without label, are checked on every wakeup, so they
|
|
260
|
-
are taken right after the start if their condition is true.
|
|
261
|
-
- By default, only one transition is taken per wakeup, a following one waits for the next wakeup. With the
|
|
262
|
-
chart option **Take transitions until none is valid (super step)**, the chart is checked again right after a
|
|
263
|
-
transition, until no transition is valid anymore, like the super step semantics of Stateflow. The event of an
|
|
264
|
-
input only counts for the first transition of a wakeup, during actions may run several times. To protect against
|
|
265
|
-
loops, at most 100 transitions are taken per wakeup, then a warning is logged.
|
|
266
|
-
- `{action}` is executed while the transition is taken, i.e. after `exit` of the old and before `entry` of
|
|
267
|
-
the new state. A separate condition action and `/action` are not supported (yet).
|
|
268
|
-
- Transitions are selected like in Stateflow (outer before inner, see above), XState only executes them.
|
|
269
|
-
Pure XState would check the transitions of sub states first.
|
|
270
|
-
- Temporal logic is limited to `after(n, msec|sec|min)`, measured in real time.
|
|
271
|
-
- Conditions and actions use JavaScript, not MATLAB/C syntax.
|
|
272
|
-
|
|
273
|
-
### Limitations
|
|
274
|
-
|
|
275
|
-
- Parallel states (AND), history junctions and connective junctions are not supported yet.
|
|
276
|
-
- Deleting a super state also deletes its sub states.
|
|
277
|
-
- Unsaved changes are lost when you select another chart.
|
|
278
|
-
- Conditions and actions run in a separate JavaScript context with a time limit of 1 second, but this
|
|
279
|
-
is **no security sandbox**: everyone who may edit charts can execute any code in the adapter,
|
|
280
|
-
just like with the JavaScript adapter.
|
|
281
|
-
|
|
282
|
-
---
|
|
283
|
-
|
|
284
|
-
<a id="deutsch"></a>
|
|
285
|
-
|
|
286
|
-
## Zustandsautomaten-Adapter für ioBroker
|
|
287
|
-
|
|
288
|
-
Bilde deine Automatisierungen als **Zustandsautomaten** (Statecharts) in einem grafischen Editor ab,
|
|
289
|
-
ähnlich den Chart-Editoren aus der modellbasierten Entwicklung. Zustände, Übergänge mit Events,
|
|
290
|
-
Bedingungen und Aktionen, Timer und Funktionsblöcke werden im ioBroker-Admin gezeichnet und vom
|
|
291
|
-
Adapter ausgeführt.
|
|
292
|
-
|
|
293
|
-
### Funktionen
|
|
294
|
-
|
|
295
|
-
- Grafischer Editor als eigener Eintrag in der Seitenleiste des Admins
|
|
296
|
-
- Zustände mit `entry`-, `during`- und `exit`-Aktionen
|
|
297
|
-
- Übergänge mit Beschriftungen in der bekannten Syntax `event[bedingung]{aktion}`
|
|
298
|
-
- Timer: `after(5, sec)`
|
|
299
|
-
- Funktionsblöcke mit eigenen JavaScript-Funktionen, nutzbar in allen Bedingungen und Aktionen
|
|
300
|
-
- Eingänge und Ausgänge, die mit beliebigen ioBroker-Datenpunkten verbunden sind
|
|
301
|
-
- Live-Ansicht: Der aktive Zustand wird im Editor hervorgehoben, die aktuellen Werte der Variablen werden angezeigt,
|
|
302
|
-
genommene Übergänge leuchten auf, und ein Verlauf zeigt, wann welcher Übergang genommen wurde und warum
|
|
303
|
-
- Code-Editor mit Syntax-Hervorhebung, Fehlerprüfung (z.B. unbekannte Variablen) und Autovervollständigung
|
|
304
|
-
- Mehrere unabhängige Charts pro Instanz
|
|
305
|
-
- Import und Export von Charts als JSON-Dateien
|
|
306
|
-
- Kommentare zu Zuständen, Übergängen und Funktionsblöcken sowie Notizen auf der Zeichenfläche
|
|
307
|
-
- Pro Eingang: Aufwecken bei jeder Aktualisierung oder nur bei Änderung, Filter nach ack, Entprellen
|
|
308
|
-
- Hilfsfunktionen: setState, setStateDelayed, sendTo, isTimeBetween, isDaytime, astroTime, Änderungserkennung (hasChanged...)
|
|
309
|
-
- Rückgängig/Wiederholen (Strg+Z, Strg+Y), Kopieren/Ausschneiden/Einfügen von Zuständen und Funktionsblöcken (Strg+C, Strg+X, Strg+V), auch zwischen Charts, und eine Warnung bei ungespeicherten Änderungen
|
|
310
|
-
- **Code anzeigen**: das aus dem Chart generierte JavaScript, das genau zeigt, wie der Adapter es ausführt
|
|
311
|
-
|
|
312
|
-
### Installation
|
|
313
|
-
|
|
314
|
-
Der Adapter ist noch nicht in den ioBroker-Repositories, lässt sich aber direkt von GitHub installieren:
|
|
315
|
-
|
|
316
|
-
- **Admin:** Reiter **Adapter** → Symbol **Aus eigener URL installieren** (GitHub-Katze) → Reiter
|
|
317
|
-
**Benutzerdefiniert** → URL `https://github.com/IggePop/ioBroker.statechart` → **Installieren**
|
|
318
|
-
- **oder auf der Konsole** des ioBroker-Systems:
|
|
319
|
-
```bash
|
|
320
|
-
iobroker url https://github.com/IggePop/ioBroker.statechart
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
Danach eine Instanz von **Zustandsmaschine** hinzufügen. Installiert wird der aktuelle
|
|
324
|
-
Entwicklungsstand, der sich noch inkompatibel ändern kann.
|
|
325
|
-
|
|
326
|
-
Voraussetzungen: Node.js 22 oder neuer, js-controller 6.0.11 oder neuer, Admin 7.6.17 oder neuer.
|
|
327
|
-
|
|
328
|
-
### Erste Schritte
|
|
329
|
-
|
|
330
|
-
1. In der Seitenleiste des Admins **Zustandsmaschine** öffnen.
|
|
331
|
-
2. Links in der Liste mit **+** ein Chart anlegen.
|
|
332
|
-
3. Rechts im Reiter **Variablen** die Variablen festlegen:
|
|
333
|
-
- **Eingang**: wird aus einem ioBroker-Datenpunkt gelesen, jede Änderung weckt das Chart auf
|
|
334
|
-
- **Ausgang**: wird in einen ioBroker-Datenpunkt geschrieben, wenn eine Aktion ihn ändert
|
|
335
|
-
- **Lokal**: gibt es nur im Chart, mit einem Startwert
|
|
336
|
-
4. Mit **Zustand hinzufügen** Zustände anlegen. Der Zustand mit Punkt und Pfeil ist der Startzustand
|
|
337
|
-
(änderbar in den Eigenschaften eines Zustands).
|
|
338
|
-
5. Übergänge zeichnen: vom Rand eines Zustands zu einem anderen Zustand (oder zu sich selbst) ziehen. Die Pfeile
|
|
339
|
-
beginnen und enden dort, wo sich die Zustände gegenüberliegen, und folgen ihnen beim Verschieben. Um ein Ende
|
|
340
|
-
an einer anderen Stelle festzulegen, den Übergang auswählen und den runden Griff am Ende am Rand entlang ziehen
|
|
341
|
-
(Doppelklick: wieder automatisch). Um einen Übergang an einen anderen Zustand umzuhängen, den Griff auf diesen
|
|
342
|
-
Zustand ziehen: Beschriftung und alle anderen Eigenschaften bleiben erhalten.
|
|
343
|
-
6. Einen Zustand oder Übergang anklicken (oder doppelklicken), um rechts seine Aktionen bzw. seine
|
|
344
|
-
Beschriftung zu bearbeiten.
|
|
345
|
-
7. **Speichern** klicken. Neue Charts sind angehalten: Starte das Chart mit ▶ in der Chart-Liste. Nach dem
|
|
346
|
-
Speichern startet der Adapter ein laufendes Chart sofort neu.
|
|
347
|
-
|
|
348
|
-
### Beispiel: Licht mit Bewegungsmelder
|
|
349
|
-
|
|
350
|
-
| Variable | Art | Datenpunkt |
|
|
351
|
-
|---|---|---|
|
|
352
|
-
| `motion` | Eingang | z.B. `hm-rpc.0.ABC123.1.MOTION` |
|
|
353
|
-
| `light` | Ausgang | z.B. `hue.0.flur.on` |
|
|
354
|
-
|
|
355
|
-
| Zustand | entry |
|
|
356
|
-
|---|---|
|
|
357
|
-
| Aus (Startzustand) | `light = false;` |
|
|
358
|
-
| An | `light = true;` |
|
|
359
|
-
|
|
360
|
-
| Übergang | Beschriftung |
|
|
361
|
-
|---|---|
|
|
362
|
-
| Aus → An | `motion[motion == true]` |
|
|
363
|
-
| An → Aus | `after(2, min)[!motion]` |
|
|
364
|
-
|
|
365
|
-
### Beschriftung von Übergängen
|
|
366
|
-
|
|
367
|
-
```
|
|
368
|
-
event[bedingung]{aktion}
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
Alle Teile sind optional und dürfen über mehrere Zeilen gehen.
|
|
372
|
-
|
|
373
|
-
| Teil | Bedeutung | Beispiel |
|
|
374
|
-
|---|---|---|
|
|
375
|
-
| `event` | Name eines Eingangs: Der Übergang wird nur geprüft, wenn sich dieser Eingang ändert | `motion` |
|
|
376
|
-
| `after(n, einheit)` | Statt eines Events: gültig ab *n* Einheiten nach Betreten des Zustands. Dann weckt ein Timer das Chart, und die Bedingung wird bei jedem weiteren Aufwecken erneut geprüft. Einheiten: `msec`, `sec`, `min` | `after(30, sec)` |
|
|
377
|
-
| `[bedingung]` | JavaScript-Ausdruck, der Übergang wird nur genommen, wenn er wahr ist | `[temp > 21 && !fenster]` |
|
|
378
|
-
| `{aktion}` | JavaScript, wird ausgeführt, wenn der Übergang genommen wird | `{zaehler++; licht = true;}` |
|
|
379
|
-
|
|
380
|
-
Ohne Event wird ein Übergang bei jeder Änderung eines beliebigen Eingangs geprüft. Hat ein Zustand
|
|
381
|
-
mehrere ausgehende Übergänge, werden sie in der Reihenfolge ihrer **Priorität** geprüft (steht am Pfeil).
|
|
382
|
-
|
|
383
|
-
### Wann Eingänge das Chart aufwecken
|
|
384
|
-
|
|
385
|
-
Jeder Eingang hat im Reiter **Variablen** drei Einstellungen:
|
|
386
|
-
|
|
387
|
-
| Einstellung | Werte | Standard |
|
|
388
|
-
|---|---|---|
|
|
389
|
-
| **Aufwecken bei** | jeder Aktualisierung / nur bei Wertänderung | jeder Aktualisierung |
|
|
390
|
-
| **Bestätigt (ack)** | egal / nur bestätigte Werte (`ack=true`) / nur Befehle (`ack=false`) | egal |
|
|
391
|
-
| **Entprellen (ms)** | das Chart wird erst geweckt, wenn der Eingang so lange keine Aktualisierung bekommen hat, mit dem letzten Wert | 0 (aus) |
|
|
392
|
-
|
|
393
|
-
Aktualisierungen, die wegen ack aussortiert werden, ändern die Variable nicht. Sie enthält dann z.B. nur bestätigte Werte.
|
|
394
|
-
|
|
395
|
-
### Aktionen
|
|
396
|
-
|
|
397
|
-
Aktionen und Bedingungen sind JavaScript. Alle Variablen des Charts sind direkt über ihren Namen
|
|
398
|
-
verfügbar, dazu `Math`, `Date`, `JSON` usw. sowie `log("Text")` zum Schreiben ins ioBroker-Log.
|
|
399
|
-
|
|
400
|
-
| Aktion | Wird ausgeführt |
|
|
401
|
-
|---|---|
|
|
402
|
-
| `entry` | beim Betreten des Zustands |
|
|
403
|
-
| `during` | bei jedem Aufwecken des Charts, solange der Zustand aktiv ist und keiner seiner ausgehenden Übergänge genommen wird |
|
|
404
|
-
| `exit` | beim Verlassen des Zustands |
|
|
405
|
-
|
|
406
|
-
### Verschachtelte Zustände
|
|
407
|
-
|
|
408
|
-
Lass einen Zustand über einem anderen los, um ihn zum **Unterzustand** zu machen, und zieh ihn wieder
|
|
409
|
-
heraus, um das rückgängig zu machen. Beim Ziehen wird der Zustand hervorgehoben, in den er verschoben
|
|
410
|
-
würde. Jede Ebene hat ihren eigenen Startzustand (Punkt mit Pfeil).
|
|
411
|
-
|
|
412
|
-
- Beim Betreten eines Superstates wird auch sein Start-Unterzustand betreten (oder der Unterzustand,
|
|
413
|
-
auf den der Übergang zeigt). Beim Verlassen wird zuerst der aktive Unterzustand verlassen.
|
|
414
|
-
- Bei jedem Aufwecken wird jeder aktive Zustand in dieser Reihenfolge bearbeitet, beginnend mit dem äußersten:
|
|
415
|
-
1. Übergänge, die den Zustand verlassen, 2. seine `during`-Aktion, 3. seine **inneren Übergänge**,
|
|
416
|
-
4. sein aktiver Unterzustand. Die Übergänge eines Superstates haben also Vorrang vor denen seiner Unterzustände.
|
|
417
|
-
- Ein Übergang von einem Zustand zu einem seiner eigenen Unterzustände ist ein **innerer Übergang**
|
|
418
|
-
(Punkt am Anfang): Der Zustand bleibt aktiv, nur sein aktiver Unterzustand wird verlassen, seine
|
|
419
|
-
eigenen `entry`/`exit` laufen nicht. Mit der Option **Elternzustand verlassen und neu betreten** wird
|
|
420
|
-
er stattdessen verlassen und neu betreten.
|
|
421
|
-
|
|
422
|
-
### Hilfsfunktionen
|
|
423
|
-
|
|
424
|
-
In Bedingungen, Aktionen und Funktionsblöcken:
|
|
425
|
-
|
|
426
|
-
| Funktion | Zweck |
|
|
427
|
-
|---|---|
|
|
428
|
-
| `log(text, stufe)` | schreibt ins ioBroker-Log, Stufe `"debug"`, `"info"` (Standard), `"warn"` oder `"error"` |
|
|
429
|
-
| `setState(id, wert, ack)` | schreibt einen beliebigen Datenpunkt, `ack` ist standardmäßig `false` |
|
|
430
|
-
| `setStateDelayed(id, wert, ms, ack)` | schreibt verzögert, wird beim Anhalten des Charts verworfen |
|
|
431
|
-
| `sendTo(instanz, befehl, nachricht)` | sendet eine Nachricht an einen Adapter, z.B. `sendTo("telegram.0", "send", { text: "Fenster offen" })` |
|
|
432
|
-
| `isTimeBetween("22:00", "06:00")` | wahr, wenn die aktuelle Uhrzeit im Bereich liegt, auch über Mitternacht |
|
|
433
|
-
| `isDaytime()` | wahr zwischen Sonnenaufgang und Sonnenuntergang |
|
|
434
|
-
| `astroTime("sunset", minuten)` | Zeitpunkt eines Astro-Ereignisses heute als `Date`: `sunrise`, `sunset`, `dawn`, `dusk`, `solarNoon`, ... |
|
|
435
|
-
| `hasChanged(variable)` | wahr, wenn sich die Variable geändert hat, siehe unten |
|
|
436
|
-
| `hasChangedFrom(variable, wert)` | wahr, wenn sich die Variable geändert hat und vorher `wert` war |
|
|
437
|
-
| `hasChangedTo(variable, wert)` | wahr, wenn sich die Variable auf `wert` geändert hat, z.B. `hasChangedTo(taster, true)` für eine steigende Flanke |
|
|
438
|
-
|
|
439
|
-
`isDaytime()` und `astroTime()` nutzen den Standort aus den ioBroker-Systemeinstellungen. Andere Datenpunkte liest
|
|
440
|
-
man über Eingänge: Ihre Variablen sind immer aktuell und wecken das Chart. Zeitabhängige Funktionen wecken das
|
|
441
|
-
Chart nicht von selbst, sie werden beim Aufwecken ausgewertet.
|
|
442
|
-
|
|
443
|
-
Die **Änderungserkennung** funktioniert wie in Stateflow: Sie vergleicht den Wert der Variablen zu Beginn des
|
|
444
|
-
aktuellen Aufweckens mit ihrem Wert zu Beginn des vorherigen. Eingänge, Ausgänge und lokale Variablen lassen sich
|
|
445
|
-
prüfen. Eine Aktualisierung mit demselben Wert ist keine Änderung, ebenso wenig ein Aufwecken durch einen anderen
|
|
446
|
-
Eingang oder einen Timer. `[hasChangedTo(taster, true)]` ist also nur einmal pro Tastendruck wahr. Beim Aufwecken
|
|
447
|
-
nach dem Start hat sich noch nichts geändert. Ändert eine Aktion eine lokale Variable, sieht man das erst beim
|
|
448
|
-
nächsten Aufwecken, auch im Super-Step. Objekte und Arrays werden nach ihrem Inhalt verglichen.
|
|
449
|
-
|
|
450
|
-
### Funktionsblöcke
|
|
451
|
-
|
|
452
|
-
**Funktion hinzufügen** legt einen Block für eigenes JavaScript an. Er wird beim Start des Charts
|
|
453
|
-
einmal ausgeführt. Alle darin deklarierten Funktionen und Konstanten können in jeder Bedingung und
|
|
454
|
-
Aktion des Charts verwendet werden:
|
|
455
|
-
|
|
456
|
-
```js
|
|
457
|
-
const LIMIT = 22;
|
|
458
|
-
|
|
459
|
-
function zuWarm(temp) {
|
|
460
|
-
return temp > LIMIT;
|
|
461
|
-
}
|
|
462
|
-
```
|
|
463
|
-
|
|
464
|
-
Beschriftung eines Übergangs: `[zuWarm(temperatur)]{heizung = false;}`
|
|
465
|
-
|
|
466
|
-
### Kommentare und Notizen
|
|
467
|
-
|
|
468
|
-
- **Kommentar:** Zustände, Übergänge, Funktionsblöcke und das Chart selbst haben in ihren Eigenschaften ein Feld
|
|
469
|
-
**Kommentar**. Eine Sprechblase auf der Zeichenfläche zeigt, dass es einen Kommentar gibt, der Kommentar erscheint
|
|
470
|
-
als Tooltip.
|
|
471
|
-
- **Notizen** (Symbol **Notiz hinzufügen** in der Werkzeugleiste) sind freie Texte auf der Zeichenfläche, wie
|
|
472
|
-
Haftzettel. Lass eine Notiz über einem Zustand los, dann bewegt sie sich mit ihm.
|
|
473
|
-
|
|
474
|
-
Kommentare und Notizen haben keinen Einfluss auf die Ausführung. Sie stehen im generierten Code und in exportierten
|
|
475
|
-
Dateien, und wenn sie sich ändern, wird der Zustand nach einem Neustart trotzdem wiederhergestellt.
|
|
476
|
-
|
|
477
|
-
### Ein laufendes Chart beobachten
|
|
478
|
-
|
|
479
|
-
Während ein Chart läuft, zeigt der Editor, was es tut:
|
|
480
|
-
|
|
481
|
-
- Die **aktiven Zustände** haben einen grünen Rahmen.
|
|
482
|
-
- **Live-Werte** (Tafel oben links auf der Zeichenfläche, ein- und ausgeschaltet mit dem letzten Symbol der
|
|
483
|
-
Werkzeugleiste): die aktuellen Werte aller Variablen. Sie stehen auch unter jeder Variable im Reiter **Variablen**.
|
|
484
|
-
- Ein **Übergang leuchtet kurz auf**, wenn das Chart ihn nimmt.
|
|
485
|
-
- Der Reiter **Verlauf** listet die Starts des Charts und die genommenen Übergänge, der neueste zuerst: wann, von
|
|
486
|
-
welchem Zustand zu welchem, ausgelöst durch welchen Eingang oder einen Timer (`after`), und welche Zustände danach
|
|
487
|
-
aktiv waren. Ein Klick auf einen Übergang wählt ihn im Chart aus. Der Adapter behält die letzten 200 Ereignisse,
|
|
488
|
-
auch bei geschlossenem Editor und über einen Neustart hinweg. **Verlauf leeren** löscht sie.
|
|
489
|
-
|
|
490
|
-
Live-Werte und Verlauf kommen vom laufenden Chart. Sie beziehen sich also auf das gespeicherte Chart, nicht auf
|
|
491
|
-
ungespeicherte Änderungen im Editor.
|
|
492
|
-
|
|
493
|
-
### Import und Export
|
|
494
|
-
|
|
495
|
-
- **Chart exportieren** (letztes Symbol in der Werkzeugleiste des Editors) speichert das Chart als JSON-Datei, mit
|
|
496
|
-
ungespeicherten Änderungen.
|
|
497
|
-
- **Alle Charts exportieren** (Symbol über der Chart-Liste) speichert alle gespeicherten Charts in einer Datei.
|
|
498
|
-
- **Charts importieren** (Symbol über der Chart-Liste) fügt die Charts einer solchen Datei als neue Charts hinzu,
|
|
499
|
-
vorhandene Charts werden nicht verändert. Die Datei wird vorher geprüft (Aufbau, IDs, Verweise zwischen Zuständen
|
|
500
|
-
und Übergängen).
|
|
501
|
-
|
|
502
|
-
Importierte Charts sind **angehalten**: Ihre Variablen können auf Datenpunkte eines anderen Systems verweisen. Prüfe sie
|
|
503
|
-
im Reiter **Variablen** und starte das Chart dann mit dem Knopf in der Chart-Liste.
|
|
504
|
-
|
|
505
|
-
### Vom Adapter angelegte Datenpunkte
|
|
506
|
-
|
|
507
|
-
Für jedes Chart legt der Adapter unter `statechart.<instanz>.charts.<chart>` an:
|
|
508
|
-
|
|
509
|
-
| Datenpunkt | Inhalt |
|
|
510
|
-
|---|---|
|
|
511
|
-
| `activeState` | Name des aktiven Zustands, verschachtelte Zustände als `Eltern.Kind` |
|
|
512
|
-
| `activeStateIds` | IDs aller aktiven Zustände als JSON |
|
|
513
|
-
| `snapshot` | Gespeicherter Zustand des Charts (aktive Zustände, wann sie betreten wurden, lokale Variablen), siehe unten |
|
|
514
|
-
| `values` | Aktuelle Werte aller Variablen als JSON, `{}` wenn das Chart nicht läuft |
|
|
515
|
-
| `history` | Die letzten 200 Ereignisse (Starts und genommene Übergänge) als JSON. Schreiben ohne ack leert ihn |
|
|
516
|
-
|
|
517
|
-
Das Chart selbst ist im Objekt `statechart.<instanz>.charts.<chart>` gespeichert.
|
|
518
|
-
|
|
519
|
-
### Neustart des Adapters
|
|
520
|
-
|
|
521
|
-
Nach einem Neustart des Adapters oder von ioBroker macht jedes Chart in den Zuständen weiter, die
|
|
522
|
-
vorher aktiv waren, mit seinen lokalen Variablen. Die entry-Aktionen laufen nicht noch einmal, und Timer
|
|
523
|
-
laufen mit ihrer Restzeit weiter. Ein Timer, der abgelaufen ist, während der Adapter gestoppt war, greift
|
|
524
|
-
gleich nach dem Start. Wie nach jedem Start wacht das Chart dann einmal auf, so werden Änderungen der
|
|
525
|
-
Eingänge während des Stopps bemerkt.
|
|
526
|
-
|
|
527
|
-
Im Startzustand beginnt das Chart stattdessen, wenn es zwischendurch geändert wurde (Positionen im
|
|
528
|
-
Editor zählen nicht), nach dem Speichern im Editor, nach dem Anhalten und wenn die Option **Zustand nach
|
|
529
|
-
Neustart wiederherstellen** in den Chart-Eigenschaften ausgeschaltet ist. Variablen, die in
|
|
530
|
-
Funktionsblöcken deklariert sind, werden nicht wiederhergestellt.
|
|
531
|
-
|
|
532
|
-
### Ausführung und Unterschiede zu anderen Statechart-Werkzeugen
|
|
533
|
-
|
|
534
|
-
- Der Adapter führt die Charts mit [XState](https://stately.ai/docs/xstate) aus.
|
|
535
|
-
- Jede Änderung eines Eingangs weckt das Chart einmal auf, ebenso ein ablaufendes `after(...)` und der Start des
|
|
536
|
-
Charts (auch nach dem Wiederherstellen). Übergänge ohne Event, z.B. ohne Beschriftung, werden bei jedem Aufwecken
|
|
537
|
-
geprüft und greifen deshalb direkt nach dem Start, wenn ihre Bedingung wahr ist.
|
|
538
|
-
- Standardmäßig wird pro Aufwecken nur ein Übergang genommen, ein folgender wartet auf das nächste Aufwecken. Mit der
|
|
539
|
-
Chart-Option **Weiterschalten, bis kein Übergang mehr gilt (Super-Step)** wird das Chart nach einem Übergang sofort
|
|
540
|
-
erneut geprüft, bis kein Übergang mehr gilt, wie bei der Super-Step-Semantik von Stateflow. Das Event eines
|
|
541
|
-
Eingangs zählt nur für den ersten Übergang eines Aufweckens, during-Aktionen können mehrmals laufen. Zum Schutz vor
|
|
542
|
-
Schleifen werden pro Aufwecken höchstens 100 Übergänge genommen, danach wird eine Warnung geloggt.
|
|
543
|
-
- `{aktion}` wird während des Übergangs ausgeführt, also nach `exit` des alten und vor `entry` des
|
|
544
|
-
neuen Zustands. Eine eigene Condition Action und `/aktion` werden (noch) nicht unterstützt.
|
|
545
|
-
- Übergänge werden wie bei Stateflow ausgewählt (außen vor innen, siehe oben), XState führt sie nur aus.
|
|
546
|
-
Reines XState würde die Übergänge der Unterzustände zuerst prüfen.
|
|
547
|
-
- Zeitlogik gibt es nur als `after(n, msec|sec|min)`, gemessen in Echtzeit.
|
|
548
|
-
- Bedingungen und Aktionen sind JavaScript, nicht MATLAB- oder C-Syntax.
|
|
549
|
-
|
|
550
|
-
### Einschränkungen
|
|
551
|
-
|
|
552
|
-
- Parallele Zustände (AND), History- und Verbindungspunkte werden noch nicht unterstützt.
|
|
553
|
-
- Beim Löschen eines Superstates werden auch seine Unterzustände gelöscht.
|
|
554
|
-
- Ungespeicherte Änderungen gehen verloren, wenn ein anderes Chart ausgewählt wird.
|
|
555
|
-
- Bedingungen und Aktionen laufen in einem eigenen JavaScript-Kontext mit 1 Sekunde Zeitlimit, das
|
|
556
|
-
ist aber **keine Sicherheits-Sandbox**: Wer Charts bearbeiten darf, kann im Adapter beliebigen Code
|
|
557
|
-
ausführen, wie beim JavaScript-Adapter auch.
|
|
558
|
-
|
|
559
|
-
---
|
|
560
|
-
|
|
561
|
-
## Development / Entwicklung
|
|
562
|
-
|
|
563
|
-
```bash
|
|
564
|
-
npm install
|
|
565
|
-
npm run build # build the adapter (src/ to build/) and the admin tab
|
|
566
|
-
npm run dev-server setup # once: local ioBroker test instance in .dev-server/
|
|
567
|
-
npm run dev-server watch # run it, admin on http://127.0.0.1:8081/, rebuilds the adapter on changes
|
|
568
|
-
npm run upload:tab # in a second terminal: upload the tab into the test instance
|
|
569
|
-
```
|
|
570
|
-
|
|
571
|
-
The adapter and the editor are written in TypeScript. The editor imports the chart model, the validation
|
|
572
|
-
and the code generator directly from `src/lib/`, so they are shared by both.
|
|
573
|
-
|
|
574
|
-
| Script | Description |
|
|
575
|
-
|---|---|
|
|
576
|
-
| `dev-server` | Runs [`dev-server`](https://github.com/ioBroker/dev-server) with the given command. Before, it applies the patches in `patches/`: the dev-server uses `wmic.exe` to find the adapter process, which no longer exists in Windows 11 25H2 |
|
|
577
|
-
| `build` / `watch` | Build the adapter (`src` to `build`) and the tab (`admin/src` to `admin/build`), with type check |
|
|
578
|
-
| `build:ts` / `watch:ts` | Build only the adapter |
|
|
579
|
-
| `build:react` / `watch:react` | Build only the tab |
|
|
580
|
-
| `upload:tab` | Build the tab and write the admin files into the running dev-server instance (works while `dev-server watch` runs) |
|
|
581
|
-
| `test` | Unit tests (`src/**/*.test.ts`) and package tests |
|
|
582
|
-
| `check` | Type check of the adapter and the tab |
|
|
583
|
-
| `lint` | ESLint |
|
|
584
|
-
| `translate` | Translate the texts of the adapter |
|
|
585
|
-
| `release` | Create a new release |
|
|
586
|
-
|
|
587
|
-
After changes of `io-package.json`, run `npm run dev-server upload` and restart `npm run dev-server watch`.
|
|
588
|
-
|
|
589
|
-
**The built adapter (`build`) and tab (`admin/build`) are committed**, because installations from GitHub do
|
|
590
|
-
not run a build. After changes in `src` or `admin/src`, run `npm run build` and commit `build` and
|
|
591
|
-
`admin/build` as well. The workflow job `check-build` fails if they are outdated. The source maps are not
|
|
592
|
-
committed.
|
|
593
|
-
|
|
594
|
-
**Dependabot** proposes updates monthly. Patch updates (and minor updates of development dependencies) are
|
|
595
|
-
merged automatically when the checks pass, which are required for `main`. Dependabot cannot rebuild the
|
|
596
|
-
committed build, so `check-build` does not compare it in Dependabot pull requests. Instead, after every push to
|
|
597
|
-
`main`, it rebuilds `build` and `admin/build` and commits them if they changed. The workflows need the secret
|
|
598
|
-
`AUTO_MERGE_TOKEN`, a fine-grained personal access token for this repository with the permissions
|
|
599
|
-
"Contents" and "Pull requests" (read and write). Major updates of MUI, React and
|
|
600
|
-
`@types/node` are ignored: `@iobroker/adapter-react-v5` requires MUI 6 and React 18, and the adapter supports
|
|
601
|
-
Node.js 22.
|
|
602
|
-
|
|
603
|
-
| Path | Content |
|
|
604
|
-
|---|---|
|
|
605
|
-
| `src/main.ts` | Adapter: loads the charts, subscribes the inputs, restarts a chart when it is saved |
|
|
606
|
-
| `src/lib/chart-model.ts` | Chart model (shared by adapter and editor) and parser of the transition labels |
|
|
607
|
-
| `src/lib/chart-runtime.ts` | Execution of a chart with XState |
|
|
608
|
-
| `src/lib/chart-validation.ts` | Checks of conditions, actions and function blocks |
|
|
609
|
-
| `src/lib/chart-codegen.ts` | Code shown by "Show code" in the editor |
|
|
610
|
-
| `admin/src/` | Editor (React, React Flow, CodeMirror) |
|
|
611
|
-
| `admin/jsonConfig.json` | Instance settings |
|
|
108
|
+
- [Reference](docs/en/reference.md): the editor and its toolbar, transition labels and temporal logic, when inputs wake up the chart, actions,
|
|
109
|
+
nested and parallel states, helper functions, function blocks, watching a running chart, simulation, import and
|
|
110
|
+
export, states created by the adapter, restart, execution model and limitations
|
|
111
|
+
- [Development](docs/development.md): build, dev-server, tests and the structure of the project
|
|
612
112
|
|
|
613
113
|
## Disclaimer
|
|
614
114
|
|
|
@@ -620,6 +120,18 @@ with, endorsed or sponsored by The MathWorks, Inc.
|
|
|
620
120
|
Placeholder for the next version (at the beginning of the line):
|
|
621
121
|
### **WORK IN PROGRESS**
|
|
622
122
|
-->
|
|
123
|
+
### 0.3.0 (2026-11-14)
|
|
124
|
+
* (Igge) simulation: the chart runs in the editor without switching anything, the inputs are set by hand, advance the time, pause, single steps and breakpoints on states and transitions
|
|
125
|
+
* (Igge) parallel states (AND) with an execution order, and history junctions: entering a state returns to its last active sub state
|
|
126
|
+
* (Igge) more temporal logic: `before`, `at`, `every`, counting the wakeups by an input (`after(3, button)`), `after(5, min, condition)`, `elapsed()`, `duration()`, and every day at a time or astro event (`at("22:30")`, `at("sunset", -30)`)
|
|
127
|
+
* (Igge) `getState("id")` reads any state in conditions and actions, control states per chart: `enabled`, `reset` and `event`
|
|
128
|
+
* (Igge) static check of the chart: states which never become active or are never left, transitions which are never taken, conditions which are never true, unused variables
|
|
129
|
+
* (Igge) editor: color of each state (every second level of nested states darker), right-angled transitions as option, snap to the grid, align and distribute, labels of transitions can be moved
|
|
130
|
+
* (Igge) editor: toolbar grouped by tasks with new buttons to cut and delete, collapsible side panels, colors and icons for each kind of element, variables grouped by kind with a search
|
|
131
|
+
* (Igge) editor: transitions are black, their labels have no background
|
|
132
|
+
* (Igge) export of the whole chart as PNG image
|
|
133
|
+
* (Igge) fixed: labels of transitions inside a superstate were hidden, labels of several transitions between the same states and the line to a moved label covered text, self transitions on the top or right side were drawn twisted
|
|
134
|
+
|
|
623
135
|
### 0.2.0 (2026-11-01)
|
|
624
136
|
* (Igge) the adapter and the editor are written in TypeScript now, no changes of the behavior
|
|
625
137
|
* (Igge) live values of the variables in the editor
|