signalk-automation-plugin 0.0.4 → 0.0.5
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/README.md +8 -8
- package/examples/automations.yaml +39 -37
- package/package.json +1 -1
- package/plugin/index.js +56 -9
package/README.md
CHANGED
|
@@ -36,34 +36,34 @@ Do not paste automations into the admin form. Runtime state is `~/.signalk/plugi
|
|
|
36
36
|
|
|
37
37
|
## Example
|
|
38
38
|
|
|
39
|
-
See `examples/automations.yaml
|
|
39
|
+
See `examples/automations.yaml` (fictional sample). Live YAML is whatever directory you set as `automationsDir` — usually a separate git. On/off and Verbose are plugin-data switches, not YAML keys.
|
|
40
40
|
|
|
41
41
|
```yaml
|
|
42
42
|
helpers:
|
|
43
|
-
|
|
43
|
+
dish_manual:
|
|
44
44
|
type: boolean
|
|
45
45
|
default: false
|
|
46
46
|
on_start: restore # survive reboot
|
|
47
|
-
latch_on_external_put: electrical.switches.
|
|
47
|
+
latch_on_external_put: electrical.switches.dish.state
|
|
48
48
|
|
|
49
49
|
automations:
|
|
50
|
-
- id:
|
|
50
|
+
- id: dish_standby
|
|
51
51
|
trigger:
|
|
52
52
|
- schedule: "0 4 * * *"
|
|
53
53
|
condition:
|
|
54
54
|
- zone: home_harbour
|
|
55
|
-
- helper:
|
|
55
|
+
- helper: dish_manual
|
|
56
56
|
is: false
|
|
57
57
|
action:
|
|
58
|
-
- put: electrical.switches.
|
|
58
|
+
- put: electrical.switches.dish.state
|
|
59
59
|
value: true
|
|
60
60
|
- delay: 15m
|
|
61
|
-
- put: electrical.switches.
|
|
61
|
+
- put: electrical.switches.dish.state
|
|
62
62
|
value: false
|
|
63
63
|
```
|
|
64
64
|
|
|
65
65
|
```yaml
|
|
66
|
-
- path: electrical.switches.
|
|
66
|
+
- path: electrical.switches.charger.voltage
|
|
67
67
|
round: 1 # nearest volt; 230.1 and 230.4 do not both fire
|
|
68
68
|
```
|
|
69
69
|
|
|
@@ -1,103 +1,105 @@
|
|
|
1
|
+
# Bundled sample only. Site YAML belongs in the git you set as automationsDir,
|
|
2
|
+
# not in this plugin.
|
|
3
|
+
|
|
1
4
|
helpers:
|
|
2
|
-
|
|
5
|
+
dish_manual:
|
|
3
6
|
type: boolean
|
|
4
|
-
name:
|
|
7
|
+
name: Dish manual
|
|
5
8
|
default: false
|
|
6
9
|
on_start: restore
|
|
7
|
-
latch_on_external_put: electrical.switches.
|
|
8
|
-
|
|
10
|
+
latch_on_external_put: electrical.switches.dish.state
|
|
11
|
+
trip_prep:
|
|
9
12
|
type: boolean
|
|
10
|
-
name:
|
|
13
|
+
name: Prepare to leave
|
|
11
14
|
default: false
|
|
12
15
|
on_start: restore
|
|
13
16
|
|
|
14
17
|
automations:
|
|
15
18
|
- id: shore_charge
|
|
16
|
-
alias:
|
|
19
|
+
alias: Shore charge
|
|
17
20
|
zones:
|
|
18
21
|
home_harbour:
|
|
19
|
-
name:
|
|
20
|
-
lat: 52.
|
|
21
|
-
lon:
|
|
22
|
+
name: Home harbour
|
|
23
|
+
lat: 52.1
|
|
24
|
+
lon: 4.9
|
|
22
25
|
radius: 150
|
|
23
26
|
trigger:
|
|
24
|
-
- path: sensors.presence.
|
|
27
|
+
- path: sensors.presence.shore
|
|
25
28
|
- path: electrical.batteries.house.capacity.stateOfCharge
|
|
26
29
|
round: 0.01
|
|
27
|
-
- helper:
|
|
30
|
+
- helper: trip_prep
|
|
28
31
|
choose:
|
|
29
|
-
- alias:
|
|
32
|
+
- alias: charge underway
|
|
30
33
|
conditions:
|
|
31
|
-
- path: sensors.presence.
|
|
34
|
+
- path: sensors.presence.shore
|
|
32
35
|
is: true
|
|
33
36
|
- not:
|
|
34
37
|
zone: home_harbour
|
|
35
38
|
action:
|
|
36
|
-
- put: electrical.switches.
|
|
39
|
+
- put: electrical.switches.charger.state
|
|
37
40
|
value: 1
|
|
38
|
-
- alias:
|
|
41
|
+
- alias: charge to leave
|
|
39
42
|
conditions:
|
|
40
|
-
- path: sensors.presence.
|
|
43
|
+
- path: sensors.presence.shore
|
|
41
44
|
is: true
|
|
42
45
|
- zone: home_harbour
|
|
43
|
-
- helper:
|
|
46
|
+
- helper: trip_prep
|
|
44
47
|
is: true
|
|
45
48
|
- path: electrical.batteries.house.capacity.stateOfCharge
|
|
46
49
|
below: 0.98
|
|
47
50
|
action:
|
|
48
|
-
- put: electrical.switches.
|
|
51
|
+
- put: electrical.switches.charger.state
|
|
49
52
|
value: 1
|
|
50
|
-
- alias:
|
|
53
|
+
- alias: leave charged
|
|
51
54
|
conditions:
|
|
52
|
-
- path: sensors.presence.
|
|
55
|
+
- path: sensors.presence.shore
|
|
53
56
|
is: true
|
|
54
57
|
- zone: home_harbour
|
|
55
|
-
- helper:
|
|
58
|
+
- helper: trip_prep
|
|
56
59
|
is: true
|
|
57
60
|
- path: electrical.batteries.house.capacity.stateOfCharge
|
|
58
61
|
above: 0.97
|
|
59
62
|
action:
|
|
60
|
-
- put: electrical.switches.
|
|
63
|
+
- put: electrical.switches.charger.state
|
|
61
64
|
value: 0
|
|
62
|
-
- helper:
|
|
65
|
+
- helper: trip_prep
|
|
63
66
|
value: false
|
|
64
|
-
- alias:
|
|
67
|
+
- alias: home below 60%
|
|
65
68
|
conditions:
|
|
66
|
-
- path: sensors.presence.
|
|
69
|
+
- path: sensors.presence.shore
|
|
67
70
|
is: true
|
|
68
71
|
- zone: home_harbour
|
|
69
|
-
- helper:
|
|
72
|
+
- helper: trip_prep
|
|
70
73
|
is: false
|
|
71
74
|
- path: electrical.batteries.house.capacity.stateOfCharge
|
|
72
75
|
below: 0.6
|
|
73
76
|
action:
|
|
74
|
-
- put: electrical.switches.
|
|
77
|
+
- put: electrical.switches.charger.state
|
|
75
78
|
value: 1
|
|
76
|
-
- alias:
|
|
79
|
+
- alias: home above 80%
|
|
77
80
|
conditions:
|
|
78
|
-
- path: sensors.presence.
|
|
81
|
+
- path: sensors.presence.shore
|
|
79
82
|
is: true
|
|
80
83
|
- zone: home_harbour
|
|
81
|
-
- helper:
|
|
84
|
+
- helper: trip_prep
|
|
82
85
|
is: false
|
|
83
86
|
- path: electrical.batteries.house.capacity.stateOfCharge
|
|
84
87
|
above: 0.8
|
|
85
88
|
action:
|
|
86
|
-
- put: electrical.switches.
|
|
89
|
+
- put: electrical.switches.charger.state
|
|
87
90
|
value: 0
|
|
88
91
|
|
|
89
|
-
- id:
|
|
90
|
-
alias:
|
|
92
|
+
- id: dish_standby
|
|
93
|
+
alias: Dish standby update
|
|
91
94
|
trigger:
|
|
92
95
|
- schedule: "0 4 * * *"
|
|
93
96
|
condition:
|
|
94
|
-
# home_harbour is defined on shore_charge (Walstroom laadbeleid).
|
|
95
97
|
- zone: home_harbour
|
|
96
|
-
- helper:
|
|
98
|
+
- helper: dish_manual
|
|
97
99
|
is: false
|
|
98
100
|
action:
|
|
99
|
-
- put: electrical.switches.
|
|
101
|
+
- put: electrical.switches.dish.state
|
|
100
102
|
value: true
|
|
101
103
|
- delay: 15m
|
|
102
|
-
- put: electrical.switches.
|
|
104
|
+
- put: electrical.switches.dish.state
|
|
103
105
|
value: false
|
package/package.json
CHANGED
package/plugin/index.js
CHANGED
|
@@ -305,15 +305,36 @@ module.exports = function (app) {
|
|
|
305
305
|
})
|
|
306
306
|
}
|
|
307
307
|
|
|
308
|
-
function
|
|
309
|
-
return
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
308
|
+
function isMultipleSources (err) {
|
|
309
|
+
return /multiple sources for the given path/i.test(String((err && err.message) || err || ''))
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function putSources (p) {
|
|
313
|
+
const out = []
|
|
314
|
+
const seen = Object.create(null)
|
|
315
|
+
const add = (s) => {
|
|
316
|
+
if (!s) return
|
|
317
|
+
const id = String(s)
|
|
318
|
+
if (seen[id] || id.includes(PLUGIN_ID)) return
|
|
319
|
+
seen[id] = true
|
|
320
|
+
out.push(id)
|
|
321
|
+
}
|
|
322
|
+
const node = typeof app.getSelfPath === 'function' ? app.getSelfPath(p) : null
|
|
323
|
+
if (node && typeof node === 'object' && !Array.isArray(node)) {
|
|
324
|
+
add(node.$source)
|
|
325
|
+
const vals = node.values
|
|
326
|
+
if (vals && typeof vals === 'object') {
|
|
327
|
+
Object.keys(vals)
|
|
328
|
+
.sort((a, b) => Number(/^mqtt\b/i.test(b)) - Number(/^mqtt\b/i.test(a)))
|
|
329
|
+
.forEach(add)
|
|
316
330
|
}
|
|
331
|
+
}
|
|
332
|
+
if (runtime && runtime.values) add(runtime.values[p + '.$source'])
|
|
333
|
+
return out
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function callPutSelf (p, value, source) {
|
|
337
|
+
return new Promise((resolve, reject) => {
|
|
317
338
|
let settled = false
|
|
318
339
|
const finish = (err) => {
|
|
319
340
|
if (settled) return
|
|
@@ -332,7 +353,9 @@ module.exports = function (app) {
|
|
|
332
353
|
finish(null)
|
|
333
354
|
}
|
|
334
355
|
try {
|
|
335
|
-
const ret =
|
|
356
|
+
const ret = source
|
|
357
|
+
? app.putSelfPath(p, value, fromReply, source)
|
|
358
|
+
: app.putSelfPath(p, value, fromReply)
|
|
336
359
|
if (ret && typeof ret.then === 'function') {
|
|
337
360
|
ret.then(fromReply, finish)
|
|
338
361
|
}
|
|
@@ -342,6 +365,30 @@ module.exports = function (app) {
|
|
|
342
365
|
})
|
|
343
366
|
}
|
|
344
367
|
|
|
368
|
+
async function putPath (p, value) {
|
|
369
|
+
if (typeof app.putSelfPath !== 'function') {
|
|
370
|
+
app.handleMessage(PLUGIN_ID, {
|
|
371
|
+
updates: [{ values: [{ path: p, value }] }]
|
|
372
|
+
})
|
|
373
|
+
return
|
|
374
|
+
}
|
|
375
|
+
try {
|
|
376
|
+
await callPutSelf(p, value)
|
|
377
|
+
} catch (err) {
|
|
378
|
+
if (!isMultipleSources(err)) throw err
|
|
379
|
+
let last = err
|
|
380
|
+
for (const source of putSources(p)) {
|
|
381
|
+
try {
|
|
382
|
+
await callPutSelf(p, value, source)
|
|
383
|
+
return
|
|
384
|
+
} catch (e) {
|
|
385
|
+
last = e
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
throw last
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
345
392
|
function notify (p, state, message) {
|
|
346
393
|
const npath = String(p).startsWith('notifications.') ? p : 'notifications.' + p
|
|
347
394
|
app.handleMessage(PLUGIN_ID, {
|