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 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`. Boatnet live YAML is `git@github.com:htool/boatnet_automations.git` (`automationsDir` on the Pi). On/off and Verbose are plugin-data switches, not YAML keys.
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
- starlink_manual:
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.starlink.state
47
+ latch_on_external_put: electrical.switches.dish.state
48
48
 
49
49
  automations:
50
- - id: starlink_standby
50
+ - id: dish_standby
51
51
  trigger:
52
52
  - schedule: "0 4 * * *"
53
53
  condition:
54
54
  - zone: home_harbour
55
- - helper: starlink_manual
55
+ - helper: dish_manual
56
56
  is: false
57
57
  action:
58
- - put: electrical.switches.starlink.state
58
+ - put: electrical.switches.dish.state
59
59
  value: true
60
60
  - delay: 15m
61
- - put: electrical.switches.starlink.state
61
+ - put: electrical.switches.dish.state
62
62
  value: false
63
63
  ```
64
64
 
65
65
  ```yaml
66
- - path: electrical.switches.dolphinCharger.voltage
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
- starlink_manual:
5
+ dish_manual:
3
6
  type: boolean
4
- name: Starlink handmatig
7
+ name: Dish manual
5
8
  default: false
6
9
  on_start: restore
7
- latch_on_external_put: electrical.switches.starlink.state
8
- depart_prep:
10
+ latch_on_external_put: electrical.switches.dish.state
11
+ trip_prep:
9
12
  type: boolean
10
- name: Maak klaar voor vertrek
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: Walstroom laadbeleid
19
+ alias: Shore charge
17
20
  zones:
18
21
  home_harbour:
19
- name: Thuishaven
20
- lat: 52.37
21
- lon: 5.22
22
+ name: Home harbour
23
+ lat: 52.1
24
+ lon: 4.9
22
25
  radius: 150
23
26
  trigger:
24
- - path: sensors.presence.dolphinshelly
27
+ - path: sensors.presence.shore
25
28
  - path: electrical.batteries.house.capacity.stateOfCharge
26
29
  round: 0.01
27
- - helper: depart_prep
30
+ - helper: trip_prep
28
31
  choose:
29
- - alias: onderweg volladen
32
+ - alias: charge underway
30
33
  conditions:
31
- - path: sensors.presence.dolphinshelly
34
+ - path: sensors.presence.shore
32
35
  is: true
33
36
  - not:
34
37
  zone: home_harbour
35
38
  action:
36
- - put: electrical.switches.dolphinCharger.state
39
+ - put: electrical.switches.charger.state
37
40
  value: 1
38
- - alias: klaar voor vertrek laden
41
+ - alias: charge to leave
39
42
  conditions:
40
- - path: sensors.presence.dolphinshelly
43
+ - path: sensors.presence.shore
41
44
  is: true
42
45
  - zone: home_harbour
43
- - helper: depart_prep
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.dolphinCharger.state
51
+ - put: electrical.switches.charger.state
49
52
  value: 1
50
- - alias: klaar voor vertrek vol
53
+ - alias: leave charged
51
54
  conditions:
52
- - path: sensors.presence.dolphinshelly
55
+ - path: sensors.presence.shore
53
56
  is: true
54
57
  - zone: home_harbour
55
- - helper: depart_prep
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.dolphinCharger.state
63
+ - put: electrical.switches.charger.state
61
64
  value: 0
62
- - helper: depart_prep
65
+ - helper: trip_prep
63
66
  value: false
64
- - alias: thuis onder 60%
67
+ - alias: home below 60%
65
68
  conditions:
66
- - path: sensors.presence.dolphinshelly
69
+ - path: sensors.presence.shore
67
70
  is: true
68
71
  - zone: home_harbour
69
- - helper: depart_prep
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.dolphinCharger.state
77
+ - put: electrical.switches.charger.state
75
78
  value: 1
76
- - alias: thuis boven 80%
79
+ - alias: home above 80%
77
80
  conditions:
78
- - path: sensors.presence.dolphinshelly
81
+ - path: sensors.presence.shore
79
82
  is: true
80
83
  - zone: home_harbour
81
- - helper: depart_prep
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.dolphinCharger.state
89
+ - put: electrical.switches.charger.state
87
90
  value: 0
88
91
 
89
- - id: starlink_standby
90
- alias: Starlink standby-update
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: starlink_manual
98
+ - helper: dish_manual
97
99
  is: false
98
100
  action:
99
- - put: electrical.switches.starlink.state
101
+ - put: electrical.switches.dish.state
100
102
  value: true
101
103
  - delay: 15m
102
- - put: electrical.switches.starlink.state
104
+ - put: electrical.switches.dish.state
103
105
  value: false
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "signalk-automation-plugin",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "Home Assistant-like YAML automations for Signal K",
5
5
  "main": "plugin/index.js",
6
6
  "keywords": [
package/plugin/index.js CHANGED
@@ -305,15 +305,36 @@ module.exports = function (app) {
305
305
  })
306
306
  }
307
307
 
308
- function putPath (p, value) {
309
- return new Promise((resolve, reject) => {
310
- if (typeof app.putSelfPath !== 'function') {
311
- app.handleMessage(PLUGIN_ID, {
312
- updates: [{ values: [{ path: p, value }] }]
313
- })
314
- resolve()
315
- return
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 = app.putSelfPath(p, value, fromReply)
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, {