node-red-contrib-s2 0.1.3 → 0.2.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.
Files changed (37) hide show
  1. package/README.md +36 -8
  2. package/dist/lib/index.d.ts +1 -1
  3. package/dist/lib/s2/schedule.d.ts +3 -2
  4. package/dist/lib/s2/schedule.js +8 -7
  5. package/dist/lib/s2/schedule.js.map +1 -1
  6. package/dist/lib/s2/session.d.ts +17 -22
  7. package/dist/lib/s2/session.js +29 -59
  8. package/dist/lib/s2/session.js.map +1 -1
  9. package/dist/nodes/s2-cem-config/index.html +10 -0
  10. package/dist/nodes/s2-ombc/icons/s2-logo.svg +14 -0
  11. package/dist/nodes/s2-ombc/index.d.ts +30 -0
  12. package/dist/nodes/s2-ombc/index.html +82 -0
  13. package/dist/nodes/s2-ombc/index.js +153 -0
  14. package/dist/nodes/s2-ombc/index.js.map +1 -0
  15. package/dist/nodes/s2-ombc-config/index.d.ts +3 -0
  16. package/dist/nodes/s2-ombc-config/index.html +428 -0
  17. package/dist/nodes/s2-ombc-config/index.js +9 -0
  18. package/dist/nodes/s2-ombc-config/index.js.map +1 -0
  19. package/dist/nodes/s2-pebc/icons/s2-logo.svg +14 -0
  20. package/dist/nodes/s2-pebc/index.d.ts +44 -0
  21. package/dist/nodes/s2-pebc/index.html +85 -0
  22. package/dist/nodes/s2-pebc/index.js +417 -0
  23. package/dist/nodes/s2-pebc/index.js.map +1 -0
  24. package/dist/nodes/s2-pebc-config/index.d.ts +3 -0
  25. package/dist/nodes/s2-pebc-config/index.html +64 -0
  26. package/dist/nodes/s2-pebc-config/index.js +10 -0
  27. package/dist/nodes/s2-pebc-config/index.js.map +1 -0
  28. package/dist/nodes/s2-rm/index.d.ts +21 -11
  29. package/dist/nodes/s2-rm/index.html +12 -88
  30. package/dist/nodes/s2-rm/index.js +85 -309
  31. package/dist/nodes/s2-rm/index.js.map +1 -1
  32. package/dist/nodes/s2-rm-config/index.html +34 -66
  33. package/dist/nodes/s2-rm-config/index.js +2 -2
  34. package/dist/nodes/s2-rm-config/index.js.map +1 -1
  35. package/dist/types/config-nodes.d.ts +20 -6
  36. package/package.json +6 -2
  37. package/resources/s2-styles.css +101 -2
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ module.exports = function (RED) {
3
+ function S2PebcConfigNodeConstructor(config) {
4
+ RED.nodes.createNode(this, config);
5
+ this.gridConnection = config.gridConnection;
6
+ this.customMaxPowerW = config.customMaxPowerW != null ? Number(config.customMaxPowerW) : undefined;
7
+ }
8
+ RED.nodes.registerType('s2-pebc-config', S2PebcConfigNodeConstructor);
9
+ };
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/nodes/s2-pebc-config/index.ts"],"names":[],"mappings":";AAGA,iBAAS,UAAU,GAAe;IAChC,SAAS,2BAA2B,CAA0B,MAAkB;QAC9E,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QAClC,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,cAAwB,CAAA;QACrD,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACpG,CAAC;IAED,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,gBAAgB,EAAE,2BAA2B,CAAC,CAAA;AACvE,CAAC,CAAA"}
@@ -2,20 +2,29 @@ import { NodeRedApp } from '../../types/node-red';
2
2
  /**
3
3
  * s2-rm node (S2 Resource Manager)
4
4
  *
5
- * Manages S2 protocol sessions for all connected CEMs. Sits between
6
- * the transport node (victron-virtual acload, s2-websocket, etc.) and the
7
- * rest of the flow.
5
+ * Generic S2 protocol state machine: handshake, control-type selection,
6
+ * generic instruction ack/routing. Control-type-specific behavior (OMBC mode
7
+ * resolution, PEBC schedule dispatch, etc.) lives in dedicated nodes
8
+ * (s2-ombc, s2-pebc, ...) wired downstream/alongside this node.
8
9
  *
9
10
  * Wiring:
10
11
  * [transport port 2] -> [s2-rm input]
11
12
  * [s2-rm port 1] -> [transport input]
13
+ * [s2-rm port 2] -> [control-type node input] (so it can observe SelectControlType/RevokeObject/etc.)
14
+ * [s2-rm port 3] -> [control-type node input] (enriched instructions)
15
+ * [control-type node command output] -> [s2-rm input] (UpdateStatus/SystemDescription/PowerConstraints/InstructionStatus)
12
16
  *
13
- * Input msg.payload from transport:
14
- * { command: 'Connect', cemId, keepAliveInterval }
15
- * { command: 'Message', cemId, message } <- message is a raw S2 JSON string
16
- * { command: 'KeepAlive', cemId }
17
- * { command: 'PowerMeasurement', cemId, values }
18
- * { command: 'Disconnect', cemId }
17
+ * Input msg.payload from transport or a control-type node:
18
+ * { command: 'Connect', cemId, keepAliveInterval }
19
+ * { command: 'Message', cemId, message } <- message is a raw S2 JSON string
20
+ * { command: 'KeepAlive', cemId }
21
+ * { command: 'PowerMeasurement', cemId, values }
22
+ * { command: 'PowerConstraints', constraints }
23
+ * { command: 'Forecast', cemId, forecast }
24
+ * { command: 'Disconnect', cemId }
25
+ * { command: 'InstructionStatus', cemId, instructionId, status }
26
+ * { command: 'UpdateStatus', cemId, controlType, <namespaced status payload, e.g. ombc: {...}> }
27
+ * { command: 'SystemDescription', cemId, controlType, <namespaced system description payload, e.g. ombc: {...}> }
19
28
  *
20
29
  * Output port 1 - messages to send to the CEM (via transport input):
21
30
  * { payload: { s2Signal: 'Message', message: <S2 message object> }, cemId }
@@ -27,8 +36,9 @@ import { NodeRedApp } from '../../types/node-red';
27
36
  * { topic: 'Connected', cemId: <string> }
28
37
  * { topic: 'Disconnected', cemId: <string>, reason: 'cem_initiated' | 'keepalive_timeout' }
29
38
  *
30
- * Output port 3 - S2 instructions from CEM:
31
- * { payload: <S2 instruction object>, cemId: <string> }
39
+ * Output port 3 - S2 instructions from CEM, enriched with the resolved control type:
40
+ * { payload: <S2 instruction object>, cemId: <string>, controlType: <string>, <namespace key>: <S2 instruction object> }
41
+ * e.g. for an OMBC.Instruction: { payload: {...}, cemId, controlType: 'OPERATION_MODE_BASED_CONTROL', ombc: {...} }
32
42
  */
33
43
  declare const _default: (RED: NodeRedApp) => void;
34
44
  export = _default;
@@ -6,16 +6,13 @@
6
6
  defaults: {
7
7
  name: { value: '' },
8
8
  rmConfig: { value: '', type: 's2-rm-config', required: true },
9
- cem: { value: '', type: 's2-cem-config', required: false },
10
- controlTypeConfig: { value: '' },
11
- providesPowerMeasurement: { value: '3_PHASE_SYMMETRIC' },
12
- providesForecast: { value: false }
9
+ cem: { value: '', type: 's2-cem-config', required: false }
13
10
  },
14
11
  inputs: 1,
15
- outputs: 4,
12
+ outputs: 3,
16
13
  icon: 's2-logo.svg',
17
- outputLabels: ['to transport', 'from CEM', 'instructions', 'schedule'],
18
- inputLabels: ['from transport'],
14
+ outputLabels: ['to transport', 'from CEM', 'instructions'],
15
+ inputLabels: ['from transport / control-type nodes'],
19
16
  label: function () {
20
17
  return this.name || 'S2 Resource Manager'
21
18
  },
@@ -23,53 +20,7 @@
23
20
  return this.name ? 'node_label_italic' : ''
24
21
  },
25
22
  oneditprepare: function () {
26
- // Migrate legacy boolean to string value
27
- if (this.providesPowerMeasurement === true) {
28
- this.providesPowerMeasurement = '3_PHASE_SYMMETRIC'
29
- $('#node-input-providesPowerMeasurement').val('3_PHASE_SYMMETRIC')
30
- } else if (this.providesPowerMeasurement === false) {
31
- this.providesPowerMeasurement = ''
32
- $('#node-input-providesPowerMeasurement').val('')
33
- }
34
-
35
- $('#node-input-controlTypeConfig').typedInput({ types: ['json'] })
36
-
37
23
  window.__s2Common.initializeTooltips()
38
-
39
- if (!this.controlTypeConfig) {
40
- var modeId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
41
- var r = Math.random() * 16 | 0
42
- return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16)
43
- })
44
- var defaultConfig = {
45
- OMBC: {
46
- systemDescription: {
47
- operationModes: [
48
- {
49
- id: modeId,
50
- diagnostic_label: 'Normal operation',
51
- power_ranges: [
52
- {
53
- commodity_quantity: 'ELECTRIC.POWER.3_PHASE_SYMMETRIC',
54
- start_of_range: 0,
55
- end_of_range: 2500
56
- }
57
- ],
58
- abnormal_condition_only: false
59
- }
60
- ],
61
- transitions: [],
62
- timers: []
63
- },
64
- status: {
65
- activeOperationModeId: modeId,
66
- operationModeFactor: 1
67
- }
68
- }
69
- }
70
- $('#node-input-controlTypeConfig').typedInput('value', JSON.stringify(defaultConfig, null, 2))
71
- }
72
-
73
24
  }
74
25
  })
75
26
  </script>
@@ -94,40 +45,19 @@
94
45
  <input type="text" id="node-input-cem">
95
46
  </div>
96
47
 
97
- <div class="form-row">
98
- <label for="node-input-controlTypeConfig"><i class="fa fa-code"></i> Control Type<i class="fa fa-info-circle tooltip-icon" data-tooltip="JSON configuration per control type. For OMBC: operation modes, power ranges, transitions and timers. Keys: OMBC.systemDescription.operationModes, OMBC.status.activeOperationModeId"></i></label>
99
- <input type="text" id="node-input-controlTypeConfig">
100
- </div>
101
-
102
- <div class="form-row">
103
- <label for="node-input-providesPowerMeasurement"><i class="fa fa-bolt"></i> Power Meas.<i class="fa fa-info-circle tooltip-icon" data-tooltip="Commodity quantities for power measurement. Advertised to the CEM in ResourceManagerDetails."></i></label>
104
- <select id="node-input-providesPowerMeasurement" style="width: 70%;">
105
- <option value="">None</option>
106
- <option value="3_PHASE_SYMMETRIC">3-phase symmetric</option>
107
- <option value="L1_L2_L3">Per phase (L1, L2, L3)</option>
108
- </select>
109
- </div>
110
-
111
- <div class="form-row">
112
- <label for="node-input-providesForecast">
113
- <i class="fa fa-line-chart"></i> Forecast
114
- </label>
115
- <input type="checkbox" id="node-input-providesForecast" style="width: auto; margin-top: 6px;">
116
- <span style="margin-left: 6px;">Provides power forecast</span>
117
- </div>
118
-
119
48
  </div>
120
49
  </script>
121
50
 
122
51
  <link rel="stylesheet" href="resources/node-red-contrib-s2/s2-styles.css">
123
52
 
124
53
  <script type="text/html" data-help-name="s2-rm">
125
- <p>Manages S2 protocol sessions for connected CEMs. Handles the S2 handshake, sends ResourceManagerDetails, and responds to SelectControlType.</p>
54
+ <p>Generic S2 protocol state machine for connected CEMs. Handles the S2 handshake, sends ResourceManagerDetails, and acknowledges/routes instructions - independent of any specific control type's semantics.</p>
126
55
  <p>RM identity (resource ID, name, control types) is configured in the linked <b>s2-rm-config</b> node, shared with the transport node.</p>
56
+ <p>Control-type-specific behavior (OMBC mode resolution, PEBC schedule dispatch, etc.) lives in dedicated nodes - <b>s2-ombc</b>, <b>s2-pebc</b> - wired to this node's "from CEM" and "instructions" outputs, with their command output wired back to this node's input.</p>
127
57
  <h3>Input</h3>
128
58
  <dl class="message-properties">
129
59
  <dt>payload <span class="property-type">object</span></dt>
130
- <dd>Command from transport: <code>{ command, cemId, ... }</code></dd>
60
+ <dd>Command from transport or a control-type node: <code>{ command, cemId, ... }</code>. Commands: <code>Connect</code>, <code>Message</code>, <code>KeepAlive</code>, <code>PowerMeasurement</code>, <code>PowerConstraints</code>, <code>Forecast</code>, <code>Disconnect</code>, <code>InstructionStatus</code>, <code>UpdateStatus</code>, <code>SystemDescription</code>.</dd>
131
61
  </dl>
132
62
  <h3>Outputs</h3>
133
63
  <ol class="node-ports">
@@ -140,7 +70,7 @@
140
70
  <li>From CEM
141
71
  <dl class="message-properties">
142
72
  <dt>payload <span class="property-type">object</span></dt>
143
- <dd>S2 messages received from the CEM (HandshakeResponse, SelectControlType, ReceptionStatus, etc.).</dd>
73
+ <dd>S2 messages received from the CEM (HandshakeResponse, SelectControlType, ReceptionStatus, RevokeObject, etc.). Wire this to control-type nodes so they can observe control-type selection and revocations.</dd>
144
74
  <dt>cemId <span class="property-type">string</span></dt>
145
75
  <dd>ID of the CEM that sent the message.</dd>
146
76
  </dl>
@@ -151,16 +81,10 @@
151
81
  <dd>Control instructions from the CEM (OMBC.Instruction, PEBC.Instruction, etc.).</dd>
152
82
  <dt>cemId <span class="property-type">string</span></dt>
153
83
  <dd>ID of the CEM that sent the instruction.</dd>
154
- </dl>
155
- </li>
156
- <li>Schedule
157
- <dl class="message-properties">
158
- <dt>payload.commodityQuantity <span class="property-type">string</span></dt>
159
- <dd>Commodity quantity for all elements (e.g. <code>ELECTRIC.POWER.3_PHASE_SYMMETRIC</code>).</dd>
160
- <dt>payload.elements <span class="property-type">array</span></dt>
161
- <dd>Full accumulated PEBC schedule as an array of <code>{ startTime, endTime, durationSec, lowerBound, upperBound }</code>. Emitted each time the schedule is updated. Use this to program DESS schedule slots or similar downstream consumers.</dd>
162
- <dt>cemId <span class="property-type">string</span></dt>
163
- <dd>ID of the CEM that issued the schedule.</dd>
84
+ <dt>controlType <span class="property-type">string</span></dt>
85
+ <dd>Resolved S2 control type of the instruction, e.g. <code>OPERATION_MODE_BASED_CONTROL</code>.</dd>
86
+ <dt>ombc / pebc / frbc / ddbc / ppbc <span class="property-type">object</span></dt>
87
+ <dd>The instruction payload, namespaced under the key matching <code>controlType</code>, for easy Switch-node routing to the matching control-type node.</dd>
164
88
  </dl>
165
89
  </li>
166
90
  </ol>