@thingwala/node-red-contrib-geyserwala-connect 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/CHANGELOG.md +26 -0
- package/examples/Victron_OS_Large_BMS_SoC.json +220 -0
- package/package.json +1 -1
- package/src/nodes/geyserwala-api.html +1 -1
- package/src/nodes/geyserwala-nodes.html +45 -16
- package/src/nodes/geyserwala-nodes.js +32 -23
- package/CHANGELOG +0 -19
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Change Log - Geyserwala Connect - Node-RED Plugin
|
|
2
|
+
|
|
3
|
+
## [0.0.5] - 2023-12-20
|
|
4
|
+
|
|
5
|
+
Allow for custom signals
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- Custom node.
|
|
9
|
+
|
|
10
|
+
## [0.0.4] - 2023-12-05
|
|
11
|
+
|
|
12
|
+
Migrate to persistent latch signals, with programmable hold time
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
- `external-disable` signal, accepts integer of number or seconds to latch, or true (defaults to 24 hours). Zero/false will clear.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- naming to geyserwala-connect-...
|
|
19
|
+
- `external-demand` signal: accepts integer of number of seconds to latch, or true (defaults to 24 hours). Zero/false will clear.
|
|
20
|
+
|
|
21
|
+
### Removed
|
|
22
|
+
- `lowpower-enable`: replaced by `external-disable`.
|
|
23
|
+
|
|
24
|
+
## [0.0.3] - 2023-09-01
|
|
25
|
+
|
|
26
|
+
Initial development
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "ca3352fdbb2d931a",
|
|
4
|
+
"type": "tab",
|
|
5
|
+
"label": "Geyserwala - BMS SoC",
|
|
6
|
+
"disabled": false,
|
|
7
|
+
"info": "",
|
|
8
|
+
"env": []
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"id": "29a73b429a4838ca",
|
|
12
|
+
"type": "victron-input-battery",
|
|
13
|
+
"z": "ca3352fdbb2d931a",
|
|
14
|
+
"service": "com.victronenergy.battery/512",
|
|
15
|
+
"path": "/Soc",
|
|
16
|
+
"serviceObj": {
|
|
17
|
+
"service": "com.victronenergy.battery/512",
|
|
18
|
+
"name": "SS4143 BMS-EX"
|
|
19
|
+
},
|
|
20
|
+
"pathObj": {
|
|
21
|
+
"path": "/Soc",
|
|
22
|
+
"type": "float",
|
|
23
|
+
"name": "State of charge (%)"
|
|
24
|
+
},
|
|
25
|
+
"name": "",
|
|
26
|
+
"onlyChanges": false,
|
|
27
|
+
"x": 190,
|
|
28
|
+
"y": 160,
|
|
29
|
+
"wires": [
|
|
30
|
+
[
|
|
31
|
+
"0399d69c01f87a48"
|
|
32
|
+
]
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"id": "3d2a53f1b12d9675",
|
|
37
|
+
"type": "geyserwala-connect-external-disable",
|
|
38
|
+
"z": "ca3352fdbb2d931a",
|
|
39
|
+
"name": "External Disable",
|
|
40
|
+
"geyserwalaApi": "20dd980fafe6ca2e",
|
|
41
|
+
"x": 580,
|
|
42
|
+
"y": 240,
|
|
43
|
+
"wires": [
|
|
44
|
+
[]
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"id": "562e3bc5f100a612",
|
|
49
|
+
"type": "switch",
|
|
50
|
+
"z": "ca3352fdbb2d931a",
|
|
51
|
+
"name": "90%",
|
|
52
|
+
"property": "payload",
|
|
53
|
+
"propertyType": "msg",
|
|
54
|
+
"rules": [
|
|
55
|
+
{
|
|
56
|
+
"t": "gte",
|
|
57
|
+
"v": "90",
|
|
58
|
+
"vt": "str"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"t": "lt",
|
|
62
|
+
"v": "90",
|
|
63
|
+
"vt": "str"
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
"checkall": "true",
|
|
67
|
+
"repair": false,
|
|
68
|
+
"outputs": 2,
|
|
69
|
+
"x": 270,
|
|
70
|
+
"y": 240,
|
|
71
|
+
"wires": [
|
|
72
|
+
[
|
|
73
|
+
"d5a7a12a701ab13c"
|
|
74
|
+
],
|
|
75
|
+
[
|
|
76
|
+
"d31b6ddda17ef2fc"
|
|
77
|
+
]
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"id": "d31b6ddda17ef2fc",
|
|
82
|
+
"type": "change",
|
|
83
|
+
"z": "ca3352fdbb2d931a",
|
|
84
|
+
"name": "true",
|
|
85
|
+
"rules": [
|
|
86
|
+
{
|
|
87
|
+
"t": "set",
|
|
88
|
+
"p": "payload",
|
|
89
|
+
"pt": "msg",
|
|
90
|
+
"to": "true",
|
|
91
|
+
"tot": "bool"
|
|
92
|
+
}
|
|
93
|
+
],
|
|
94
|
+
"action": "",
|
|
95
|
+
"property": "",
|
|
96
|
+
"from": "",
|
|
97
|
+
"to": "",
|
|
98
|
+
"reg": false,
|
|
99
|
+
"x": 410,
|
|
100
|
+
"y": 260,
|
|
101
|
+
"wires": [
|
|
102
|
+
[
|
|
103
|
+
"3d2a53f1b12d9675"
|
|
104
|
+
]
|
|
105
|
+
]
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"id": "d5a7a12a701ab13c",
|
|
109
|
+
"type": "change",
|
|
110
|
+
"z": "ca3352fdbb2d931a",
|
|
111
|
+
"name": "false",
|
|
112
|
+
"rules": [
|
|
113
|
+
{
|
|
114
|
+
"t": "set",
|
|
115
|
+
"p": "payload",
|
|
116
|
+
"pt": "msg",
|
|
117
|
+
"to": "false",
|
|
118
|
+
"tot": "bool"
|
|
119
|
+
}
|
|
120
|
+
],
|
|
121
|
+
"action": "",
|
|
122
|
+
"property": "",
|
|
123
|
+
"from": "",
|
|
124
|
+
"to": "",
|
|
125
|
+
"reg": false,
|
|
126
|
+
"x": 410,
|
|
127
|
+
"y": 220,
|
|
128
|
+
"wires": [
|
|
129
|
+
[
|
|
130
|
+
"3d2a53f1b12d9675"
|
|
131
|
+
]
|
|
132
|
+
]
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"id": "0399d69c01f87a48",
|
|
136
|
+
"type": "rbe",
|
|
137
|
+
"z": "ca3352fdbb2d931a",
|
|
138
|
+
"name": "",
|
|
139
|
+
"func": "rbe",
|
|
140
|
+
"gap": "",
|
|
141
|
+
"start": "",
|
|
142
|
+
"inout": "out",
|
|
143
|
+
"septopics": true,
|
|
144
|
+
"property": "payload",
|
|
145
|
+
"topi": "topic",
|
|
146
|
+
"x": 150,
|
|
147
|
+
"y": 240,
|
|
148
|
+
"wires": [
|
|
149
|
+
[
|
|
150
|
+
"562e3bc5f100a612"
|
|
151
|
+
]
|
|
152
|
+
]
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"id": "f1e662c9433dcab2",
|
|
156
|
+
"type": "inject",
|
|
157
|
+
"z": "ca3352fdbb2d931a",
|
|
158
|
+
"name": "true",
|
|
159
|
+
"props": [
|
|
160
|
+
{
|
|
161
|
+
"p": "payload"
|
|
162
|
+
}
|
|
163
|
+
],
|
|
164
|
+
"repeat": "",
|
|
165
|
+
"crontab": "",
|
|
166
|
+
"once": false,
|
|
167
|
+
"onceDelay": 0.1,
|
|
168
|
+
"topic": "",
|
|
169
|
+
"payload": "true",
|
|
170
|
+
"payloadType": "bool",
|
|
171
|
+
"x": 410,
|
|
172
|
+
"y": 320,
|
|
173
|
+
"wires": [
|
|
174
|
+
[
|
|
175
|
+
"3d2a53f1b12d9675"
|
|
176
|
+
]
|
|
177
|
+
]
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"id": "e9867b4f5d12423a",
|
|
181
|
+
"type": "inject",
|
|
182
|
+
"z": "ca3352fdbb2d931a",
|
|
183
|
+
"name": "false",
|
|
184
|
+
"props": [
|
|
185
|
+
{
|
|
186
|
+
"p": "payload"
|
|
187
|
+
}
|
|
188
|
+
],
|
|
189
|
+
"repeat": "",
|
|
190
|
+
"crontab": "",
|
|
191
|
+
"once": false,
|
|
192
|
+
"onceDelay": 0.1,
|
|
193
|
+
"topic": "",
|
|
194
|
+
"payload": "false",
|
|
195
|
+
"payloadType": "bool",
|
|
196
|
+
"x": 410,
|
|
197
|
+
"y": 360,
|
|
198
|
+
"wires": [
|
|
199
|
+
[
|
|
200
|
+
"3d2a53f1b12d9675"
|
|
201
|
+
]
|
|
202
|
+
]
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"id": "20dd980fafe6ca2e",
|
|
206
|
+
"type": "geyserwala-connect-api",
|
|
207
|
+
"name": "Geyserwala",
|
|
208
|
+
"api": "REST",
|
|
209
|
+
"mqttBroker": "",
|
|
210
|
+
"mqttTopicTemplate": "geyserwala/%prefix%/%mac%",
|
|
211
|
+
"mqttTopicMac": "",
|
|
212
|
+
"mqttTopicIp": "",
|
|
213
|
+
"mqttTopicHostname": "",
|
|
214
|
+
"restHost": "10.0.0.51",
|
|
215
|
+
"restPort": "80",
|
|
216
|
+
"restUser": "admin",
|
|
217
|
+
"restPassword": "",
|
|
218
|
+
"restPollInterval": "10"
|
|
219
|
+
}
|
|
220
|
+
]
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
api: { value: "MQTT", requred: true },
|
|
9
9
|
|
|
10
|
-
mqttBroker: { type: "mqtt-broker" },
|
|
10
|
+
mqttBroker: { type: "mqtt-broker", required: false },
|
|
11
11
|
mqttPubQos: { value: 0 },
|
|
12
12
|
mqttRetain: { value: false },
|
|
13
13
|
mqttTopicTemplate: { value: "geyserwala/%prefix%/%mac%" },
|
|
@@ -12,24 +12,52 @@
|
|
|
12
12
|
</div>
|
|
13
13
|
</script>
|
|
14
14
|
|
|
15
|
+
<script type="text/template" id="node-input-value-template">
|
|
16
|
+
<fieldset id="node-input-value">
|
|
17
|
+
<legend>Value</legend>
|
|
18
|
+
<div class="form-row">
|
|
19
|
+
<label for="node-input-valueType"><i class="fa fa-cube"></i> Type</label>
|
|
20
|
+
<select id="node-input-valueType" style="width:25%;">
|
|
21
|
+
<option value="">Undefined</option>
|
|
22
|
+
<option value="Boolean">Boolean</option>
|
|
23
|
+
<option value="Number">Number</option>
|
|
24
|
+
<option value="String">String</option>
|
|
25
|
+
</select>
|
|
26
|
+
</div>
|
|
27
|
+
<div class="form-row">
|
|
28
|
+
<label for="node-input-valueKey"><i class="fa fa-hashtag"></i> Key</label>
|
|
29
|
+
<input type="text" id="node-input-valueKey" placeholder="Key">
|
|
30
|
+
</div>
|
|
31
|
+
</fieldset>
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
|
|
15
35
|
<script type="text/javascript">
|
|
16
|
-
function addInputDialog(
|
|
36
|
+
function addInputDialog(nodeKey, nodeLabel, valueType) {
|
|
17
37
|
var nodeInput = $("#node-input-template").clone().html();
|
|
18
38
|
|
|
19
|
-
|
|
39
|
+
if (nodeKey.startsWith('custom-')) {
|
|
40
|
+
var nodeInputValue = $("#node-input-value-template").clone().html();
|
|
41
|
+
console.log(typeof nodeInput)
|
|
42
|
+
nodeInput += nodeInputValue
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
var scriptTag = $("<script>").attr("type", "text/x-red").attr("data-template-name", `geyserwala-connect-${nodeKey}`).append(nodeInput);
|
|
20
46
|
scriptTag.find('#title').text(`Geyserwala Connect : ${nodeLabel}`);
|
|
21
47
|
$('body').append(scriptTag.prop('outerHTML'));
|
|
22
48
|
}
|
|
23
49
|
|
|
24
|
-
function registerType(
|
|
25
|
-
addInputDialog(
|
|
50
|
+
function registerType(nodeKey, nodeLabel, valueType, icon, input) {
|
|
51
|
+
addInputDialog(nodeKey, nodeLabel, valueType)
|
|
26
52
|
|
|
27
|
-
RED.nodes.registerType(`geyserwala-connect-${
|
|
53
|
+
RED.nodes.registerType(`geyserwala-connect-${nodeKey}`, {
|
|
28
54
|
category: 'Geyserwala Connect',
|
|
29
55
|
paletteLabel: nodeLabel,
|
|
30
56
|
defaults: {
|
|
31
57
|
name: { value: nodeLabel },
|
|
32
58
|
geyserwalaApi: { type: "geyserwala-connect-api", required: true },
|
|
59
|
+
valueKey: { value: nodeKey.startsWith('custom-') ? "" : nodeKey, required: true },
|
|
60
|
+
valueType: { value: valueType ? valueType.name: "", required: true},
|
|
33
61
|
},
|
|
34
62
|
inputs: input ? 1 : 0,
|
|
35
63
|
outputs: 1,
|
|
@@ -42,20 +70,21 @@
|
|
|
42
70
|
}
|
|
43
71
|
|
|
44
72
|
// Icons: https://fontawesome.com/v4/icons/
|
|
45
|
-
registerType('status', "Status", "font-awesome/fa-envelope-o", false);
|
|
46
|
-
registerType('mode', "Mode", "font-awesome/fa-
|
|
73
|
+
registerType('status', "Status", String, "font-awesome/fa-envelope-o", false);
|
|
74
|
+
registerType('mode', "Mode", String, "font-awesome/fa-sliders", true);
|
|
47
75
|
|
|
48
|
-
registerType('tank-temp', "Tank Temp", "font-awesome/fa-thermometer-half", false);
|
|
49
|
-
registerType('element-demand', "Element Demand", "font-awesome/fa-fire", false);
|
|
76
|
+
registerType('tank-temp', "Tank Temp", Number, "font-awesome/fa-thermometer-half", false);
|
|
77
|
+
registerType('element-demand', "Element Demand", Boolean, "font-awesome/fa-fire", false);
|
|
50
78
|
|
|
51
|
-
registerType('external-setpoint', "External Setpoint", "inject.png", true);
|
|
52
|
-
registerType('external-demand', "External Demand", "serial.png", true);
|
|
53
|
-
registerType('external-disable', "External Disable", "font-awesome/fa-stop-circle-o", true);
|
|
79
|
+
registerType('external-setpoint', "External Setpoint", Number, "inject.png", true);
|
|
80
|
+
registerType('external-demand', "External Demand", Number, "serial.png", true);
|
|
81
|
+
registerType('external-disable', "External Disable", Number, "font-awesome/fa-stop-circle-o", true);
|
|
54
82
|
|
|
55
|
-
registerType('setpoint', "Setpoint", "inject.png", true);
|
|
56
|
-
registerType('boost-demand', "Boost Demand", "font-awesome/fa-power-off", true);
|
|
83
|
+
registerType('setpoint', "Setpoint", Number, "inject.png", true);
|
|
84
|
+
registerType('boost-demand', "Boost Demand", Boolean, "font-awesome/fa-power-off", true);
|
|
57
85
|
|
|
58
|
-
registerType('collector-temp', "Collector Temp", "font-awesome/fa-thermometer-half", false);
|
|
59
|
-
registerType('pump-status', "Pump Status", "font-awesome/fa-recycle", false);
|
|
86
|
+
registerType('collector-temp', "Collector Temp", Number, "font-awesome/fa-thermometer-half", false);
|
|
87
|
+
registerType('pump-status', "Pump Status", Boolean, "font-awesome/fa-recycle", false);
|
|
60
88
|
|
|
89
|
+
registerType('custom-io', "Custom", null, "font-awesome/fa-cogs", true);
|
|
61
90
|
</script>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module.exports = function (RED) {
|
|
2
|
-
function createNode (
|
|
2
|
+
function createNode (nodeKey) {
|
|
3
3
|
function Node(config) {
|
|
4
4
|
RED.nodes.createNode(this, config);
|
|
5
5
|
|
|
@@ -16,7 +16,15 @@ module.exports = function (RED) {
|
|
|
16
16
|
|
|
17
17
|
this.api.registerNode(this)
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
const valueKey = config.valueKey
|
|
20
|
+
const valueType = {
|
|
21
|
+
"": Number,
|
|
22
|
+
"Boolean": Boolean,
|
|
23
|
+
"Number": Number,
|
|
24
|
+
"String": String,
|
|
25
|
+
}[config.valueType]
|
|
26
|
+
|
|
27
|
+
this.api.subscribe(valueKey, valueType, (payload) => {
|
|
20
28
|
try {
|
|
21
29
|
this.send({ topic: valueKey, payload: payload })
|
|
22
30
|
} catch (error) {
|
|
@@ -28,35 +36,36 @@ module.exports = function (RED) {
|
|
|
28
36
|
this.api.unregister(this);
|
|
29
37
|
});
|
|
30
38
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
})
|
|
39
|
-
}
|
|
39
|
+
this.on('input', function (message) {
|
|
40
|
+
try {
|
|
41
|
+
this.api.send(valueKey, message.payload)
|
|
42
|
+
} catch (error) {
|
|
43
|
+
RED.log.error(`{Geyserwala Connect} Sending: ${error.message}`);
|
|
44
|
+
}
|
|
45
|
+
})
|
|
40
46
|
this.on('close', function () {
|
|
41
47
|
this.api.unregister(this);
|
|
42
48
|
});
|
|
43
49
|
}
|
|
44
50
|
|
|
45
|
-
RED.nodes.registerType(`geyserwala-connect-${
|
|
51
|
+
RED.nodes.registerType(`geyserwala-connect-${nodeKey}`, Node);
|
|
46
52
|
}
|
|
47
53
|
|
|
48
|
-
createNode('
|
|
49
|
-
createNode('
|
|
54
|
+
createNode('status');
|
|
55
|
+
createNode('mode');
|
|
56
|
+
|
|
57
|
+
createNode('tank-temp');
|
|
58
|
+
createNode('element-demand');
|
|
59
|
+
|
|
60
|
+
createNode('external-setpoint');
|
|
61
|
+
createNode('external-demand');
|
|
62
|
+
createNode('external-disable');
|
|
50
63
|
|
|
51
|
-
createNode('
|
|
52
|
-
createNode('
|
|
53
|
-
createNode('external-disable', Number, true);
|
|
64
|
+
createNode('setpoint');
|
|
65
|
+
createNode('boost-demand');
|
|
54
66
|
|
|
55
|
-
createNode('
|
|
56
|
-
createNode('
|
|
57
|
-
createNode('setpoint', Number, true);
|
|
58
|
-
createNode('boost-demand', Boolean, true);
|
|
67
|
+
createNode('collector-temp');
|
|
68
|
+
createNode('pump-status');
|
|
59
69
|
|
|
60
|
-
createNode('
|
|
61
|
-
createNode('pump-status', Boolean, false);
|
|
70
|
+
createNode('custom-io');
|
|
62
71
|
}
|
package/CHANGELOG
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# Change Log - Geyserwala Connect Node-RED plugin
|
|
2
|
-
|
|
3
|
-
## [0.0.4] - 2023-12-05
|
|
4
|
-
|
|
5
|
-
Migrate to persistent latch signals, with programable hold time
|
|
6
|
-
|
|
7
|
-
### Added
|
|
8
|
-
- element-disable signal, accepts integer of number or seconds to latch, or true (defaults to 24 hours). Zero/false will clear.
|
|
9
|
-
|
|
10
|
-
### Changed
|
|
11
|
-
- naming to geyserwala-connect-...
|
|
12
|
-
- element-enable signal: accepts integer of number of seconds to latch, or true (defaults to 24 hours). Zero/false will clear.
|
|
13
|
-
|
|
14
|
-
### Removed
|
|
15
|
-
- lowpower-enable: replaced by element-disable.
|
|
16
|
-
|
|
17
|
-
## [0.0.3] - 2023-09-01
|
|
18
|
-
|
|
19
|
-
Initial development
|