node-red-contrib-s2 0.1.2 → 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.
- package/README.md +36 -8
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/s2/schedule.d.ts +3 -2
- package/dist/lib/s2/schedule.js +8 -7
- package/dist/lib/s2/schedule.js.map +1 -1
- package/dist/lib/s2/session.d.ts +17 -22
- package/dist/lib/s2/session.js +29 -59
- package/dist/lib/s2/session.js.map +1 -1
- package/dist/nodes/s2-cem-config/index.html +10 -0
- package/dist/nodes/s2-ombc/icons/s2-logo.svg +14 -0
- package/dist/nodes/s2-ombc/index.d.ts +30 -0
- package/dist/nodes/s2-ombc/index.html +82 -0
- package/dist/nodes/s2-ombc/index.js +153 -0
- package/dist/nodes/s2-ombc/index.js.map +1 -0
- package/dist/nodes/s2-ombc-config/index.d.ts +3 -0
- package/dist/nodes/s2-ombc-config/index.html +428 -0
- package/dist/nodes/s2-ombc-config/index.js +9 -0
- package/dist/nodes/s2-ombc-config/index.js.map +1 -0
- package/dist/nodes/s2-pebc/icons/s2-logo.svg +14 -0
- package/dist/nodes/s2-pebc/index.d.ts +44 -0
- package/dist/nodes/s2-pebc/index.html +85 -0
- package/dist/nodes/s2-pebc/index.js +417 -0
- package/dist/nodes/s2-pebc/index.js.map +1 -0
- package/dist/nodes/s2-pebc-config/index.d.ts +3 -0
- package/dist/nodes/s2-pebc-config/index.html +64 -0
- package/dist/nodes/s2-pebc-config/index.js +10 -0
- package/dist/nodes/s2-pebc-config/index.js.map +1 -0
- package/dist/nodes/s2-rm/index.d.ts +21 -11
- package/dist/nodes/s2-rm/index.html +12 -88
- package/dist/nodes/s2-rm/index.js +85 -309
- package/dist/nodes/s2-rm/index.js.map +1 -1
- package/dist/nodes/s2-rm-config/index.html +34 -66
- package/dist/nodes/s2-rm-config/index.js +2 -2
- package/dist/nodes/s2-rm-config/index.js.map +1 -1
- package/dist/types/config-nodes.d.ts +20 -6
- package/package.json +10 -4
- package/resources/s2-common.js +37 -0
- package/resources/s2-styles.css +263 -0
|
@@ -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
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
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',
|
|
15
|
-
* { command: 'Message',
|
|
16
|
-
* { command: 'KeepAlive',
|
|
17
|
-
* { command: 'PowerMeasurement',
|
|
18
|
-
* { command: '
|
|
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:
|
|
12
|
+
outputs: 3,
|
|
16
13
|
icon: 's2-logo.svg',
|
|
17
|
-
outputLabels: ['to transport', 'from CEM', 'instructions'
|
|
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>
|
|
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
|
|
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
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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>
|