@atelieruldetehnologii/node-red-custome-solutions 0.62.22
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/NOTICE +56 -0
- package/PROPRIETARY-LICENSE.txt +157 -0
- package/README.md +105 -0
- package/TERMS-AND-CONDITIONS.md +311 -0
- package/advantech-read/advantech-read.html +775 -0
- package/advantech-read/advantech-read.js +449 -0
- package/advantech-write/advantech-write.html +413 -0
- package/advantech-write/advantech-write.js +338 -0
- package/bess-control/bess-control.html +569 -0
- package/bess-control/bess-control.js +541 -0
- package/bess-control/lib/allocation.js +149 -0
- package/bess-control/lib/batteries.js +86 -0
- package/bess-control/lib/helpers.js +157 -0
- package/bess-control/lib/messages.js +131 -0
- package/bess-control/lib/runtime.js +156 -0
- package/carlo-gavazzi/carlo-gavazzi.html +4327 -0
- package/carlo-gavazzi/carlo-gavazzi.js +3081 -0
- package/control-export/control-export.html +3644 -0
- package/control-export/control-export.js +2192 -0
- package/control-reactive/control-reactive.html +3136 -0
- package/control-reactive/control-reactive.js +2124 -0
- package/fronius-emulator/README.md +258 -0
- package/fronius-emulator/fronius-emulator.html +170 -0
- package/fronius-emulator/fronius-emulator.js +520 -0
- package/fronius-emulator/lib/binary-codec.js +65 -0
- package/fronius-emulator/lib/fronius-register-map.js +185 -0
- package/fronius-emulator/lib/modbus-parser.js +61 -0
- package/fronius-emulator/lib/modbus-tcp-server.js +224 -0
- package/fronius-emulator/lib/validation.js +206 -0
- package/fronius-emulator/lib/virtual-meter.js +132 -0
- package/fronius-read/fronius-read.html +3944 -0
- package/fronius-read/fronius-read.js +1466 -0
- package/fronius-read/lib/inverter-profiles.js +711 -0
- package/fronius-read/lib/sunspec-core.js +303 -0
- package/fronius-read/lib/sunspec-model-parsers.js +845 -0
- package/fronius-write/fronius-write.html +1789 -0
- package/fronius-write/fronius-write.js +2531 -0
- package/influxdb/influxdb.html +1077 -0
- package/influxdb/influxdb.js +1487 -0
- package/janitza/janitza.html +2562 -0
- package/janitza/janitza.js +1500 -0
- package/janitza/lib/janitza-profiles.js +371 -0
- package/lib/a3-test-server.js +199 -0
- package/lib/adam-6000-profiles.js +173 -0
- package/lib/licensing/constants.js +103 -0
- package/lib/licensing/device-id.js +251 -0
- package/lib/licensing/errors.js +21 -0
- package/lib/licensing/license-client.js +377 -0
- package/lib/licensing/license-state.js +50 -0
- package/lib/licensing/node-guard.js +150 -0
- package/lib/licensing/package-integrity.js +167 -0
- package/lib/licensing/package-integrity.json +513 -0
- package/lib/licensing/public-key.pem +3 -0
- package/lib/licensing/public-key.pem.example +2 -0
- package/lib/licensing/public-keys.js +18 -0
- package/lib/licensing/storage.js +63 -0
- package/lib/licensing/token-verifier.js +84 -0
- package/lib/numbers.js +26 -0
- package/license/atelier-license.html +88 -0
- package/license/atelier-license.js +170 -0
- package/modbus-tcp-discover/modbus-tcp-discover.html +190 -0
- package/modbus-tcp-discover/modbus-tcp-discover.js +706 -0
- package/multi-battery/multi-battery.html +649 -0
- package/multi-battery/multi-battery.js +668 -0
- package/multi-grid/multi-grid.html +745 -0
- package/multi-grid/multi-grid.js +1392 -0
- package/multi-inverter/lib/engine-core.js +237 -0
- package/multi-inverter/multi-inverter.html +2674 -0
- package/multi-inverter/multi-inverter.js +1393 -0
- package/package.json +109 -0
- package/phoenix-contact/lib/eem-ma370-advanced.js +175 -0
- package/phoenix-contact/lib/eem-ma370.js +138 -0
- package/phoenix-contact/lib/integrations.js +149 -0
- package/phoenix-contact/lib/phoenix-contact-profile.js +35030 -0
- package/phoenix-contact/phoenix-contact.html +840 -0
- package/phoenix-contact/phoenix-contact.js +679 -0
- package/pv-generator/pv-generator.html +284 -0
- package/pv-generator/pv-generator.js +387 -0
- package/pylontech-read/pylontech-read.html +763 -0
- package/pylontech-read/pylontech-read.js +518 -0
- package/pylontech-write/pylontech-write.html +405 -0
- package/pylontech-write/pylontech-write.js +546 -0
- package/scada-aggregator/lib/aggregate.js +72 -0
- package/scada-aggregator/lib/groups.js +39 -0
- package/scada-aggregator/scada-aggregator.html +108 -0
- package/scada-aggregator/scada-aggregator.js +117 -0
- package/scada-server/lib/aggregator-map.js +58 -0
- package/scada-server/lib/encoding.js +235 -0
- package/scada-server/lib/modbus-server.js +492 -0
- package/scada-server/lib/object-path.js +18 -0
- package/scada-server/lib/register-map.js +288 -0
- package/scada-server/scada-server.html +1419 -0
- package/scada-server/scada-server.js +704 -0
- package/scripts/check-syntax.js +66 -0
- package/scripts/package-integrity.js +46 -0
- package/scripts/package-release.js +116 -0
- package/scripts/run-tests.js +2178 -0
- package/scripts/tgz-integrity.js +74 -0
- package/sma-read/lib/sunspec-core.js +83 -0
- package/sma-read/lib/sunspec-model-parsers.js +853 -0
- package/sma-read/sma-read.html +659 -0
- package/sma-read/sma-read.js +458 -0
- package/sma-write/sma-write.html +105 -0
- package/sma-write/sma-write.js +270 -0
- package/victron-read/lib/mqtt-state.js +176 -0
- package/victron-read/victron-read.html +1074 -0
- package/victron-read/victron-read.js +1222 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
function clamp(value, min, max) {
|
|
4
|
+
if (!Number.isFinite(value)) return min;
|
|
5
|
+
return Math.min(Math.max(value, min), max);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function roundAllocations(map) {
|
|
9
|
+
const out = {};
|
|
10
|
+
Object.keys(map || {}).forEach(function (k) {
|
|
11
|
+
out[k] = Math.round(Number(map[k] || 0));
|
|
12
|
+
});
|
|
13
|
+
return out;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function capacityOf(list) {
|
|
17
|
+
return list.reduce(function (sum, inv) { return sum + inv.maxW; }, 0);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function minCapacityOf(list) {
|
|
21
|
+
return list.reduce(function (sum, inv) { return sum + inv.minW; }, 0);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function totalFreshPower(map) {
|
|
25
|
+
return Object.keys(map || {}).reduce(function (sum, k) {
|
|
26
|
+
return sum + Number(map[k] || 0);
|
|
27
|
+
}, 0);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function weightMap(strategy, list, freshMap) {
|
|
31
|
+
const weights = {};
|
|
32
|
+
|
|
33
|
+
list.forEach(function (inv) {
|
|
34
|
+
if (strategy === "equal") {
|
|
35
|
+
weights[inv.id] = 1;
|
|
36
|
+
} else if (strategy === "max_power") {
|
|
37
|
+
weights[inv.id] = inv.maxW;
|
|
38
|
+
} else if (strategy === "headroom") {
|
|
39
|
+
const current = Number(freshMap[inv.id] || 0);
|
|
40
|
+
weights[inv.id] = Math.max(0, inv.maxW - current);
|
|
41
|
+
} else {
|
|
42
|
+
const current = Number(freshMap[inv.id] || 0);
|
|
43
|
+
weights[inv.id] = Math.max(0, current);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return weights;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function chooseEffectiveStrategy(strategy, activeList, freshMap, staleList) {
|
|
51
|
+
if (strategy !== "current_power") return strategy;
|
|
52
|
+
|
|
53
|
+
const haveFreshForAll = staleList.length === 0 && activeList.length > 0;
|
|
54
|
+
const positiveFresh = Object.values(freshMap).some(function (v) { return Number(v) > 0; });
|
|
55
|
+
|
|
56
|
+
if (haveFreshForAll && positiveFresh) {
|
|
57
|
+
return "current_power";
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return "max_power";
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function allocateIterative(siteLimitW, activeList, freshMap, strategy) {
|
|
64
|
+
const allocations = {};
|
|
65
|
+
|
|
66
|
+
activeList.forEach(function (inv) {
|
|
67
|
+
allocations[inv.id] = 0;
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (activeList.length === 0) {
|
|
71
|
+
return {
|
|
72
|
+
allocations: allocations,
|
|
73
|
+
clipped: siteLimitW > 0,
|
|
74
|
+
unallocatedW: Math.max(0, siteLimitW),
|
|
75
|
+
availableCapacityW: 0,
|
|
76
|
+
minCapacityW: 0
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const totalMax = capacityOf(activeList);
|
|
81
|
+
const totalMin = minCapacityOf(activeList);
|
|
82
|
+
const cappedSiteLimit = clamp(siteLimitW, 0, totalMax);
|
|
83
|
+
|
|
84
|
+
let remaining = cappedSiteLimit;
|
|
85
|
+
|
|
86
|
+
activeList.forEach(function (inv) {
|
|
87
|
+
const baseMin = Math.min(inv.minW, inv.maxW);
|
|
88
|
+
allocations[inv.id] = baseMin;
|
|
89
|
+
remaining -= baseMin;
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
remaining = Math.max(0, remaining);
|
|
93
|
+
|
|
94
|
+
let eligible = activeList.filter(function (inv) {
|
|
95
|
+
return allocations[inv.id] < inv.maxW;
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
let loops = 0;
|
|
99
|
+
|
|
100
|
+
while (remaining > 0.5 && eligible.length > 0 && loops < 20) {
|
|
101
|
+
loops += 1;
|
|
102
|
+
|
|
103
|
+
const weights = weightMap(strategy, eligible, freshMap);
|
|
104
|
+
let sumWeights = eligible.reduce(function (sum, inv) {
|
|
105
|
+
return sum + Number(weights[inv.id] || 0);
|
|
106
|
+
}, 0);
|
|
107
|
+
|
|
108
|
+
if (sumWeights <= 0) {
|
|
109
|
+
eligible.forEach(function (inv) {
|
|
110
|
+
weights[inv.id] = 1;
|
|
111
|
+
});
|
|
112
|
+
sumWeights = eligible.length;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
let distributed = 0;
|
|
116
|
+
|
|
117
|
+
eligible.forEach(function (inv) {
|
|
118
|
+
const share = remaining * (weights[inv.id] / sumWeights);
|
|
119
|
+
const room = inv.maxW - allocations[inv.id];
|
|
120
|
+
const add = Math.min(room, share);
|
|
121
|
+
allocations[inv.id] += add;
|
|
122
|
+
distributed += add;
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
if (distributed <= 0.001) break;
|
|
126
|
+
|
|
127
|
+
remaining -= distributed;
|
|
128
|
+
eligible = activeList.filter(function (inv) {
|
|
129
|
+
return allocations[inv.id] < inv.maxW - 0.001;
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
Object.keys(allocations).forEach(function (id) {
|
|
134
|
+
allocations[id] = Math.round(allocations[id]);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const allocated = Object.values(allocations).reduce(function (sum, v) {
|
|
138
|
+
return sum + Number(v || 0);
|
|
139
|
+
}, 0);
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
allocations: allocations,
|
|
143
|
+
clipped: siteLimitW > totalMax,
|
|
144
|
+
unallocatedW: Math.max(0, Math.round(cappedSiteLimit - allocated)),
|
|
145
|
+
availableCapacityW: totalMax,
|
|
146
|
+
minCapacityW: totalMin
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function perInverterPolicyValue(inv, behavior, fixedValueW) {
|
|
151
|
+
if (behavior === "set_inverter_min") {
|
|
152
|
+
return clamp(Number(inv.minW || 0), 0, Number(inv.maxW || 0));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (behavior === "fixed_value") {
|
|
156
|
+
return clamp(Number(fixedValueW || 0), 0, Number(inv.maxW || 0));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return 0;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function buildPolicyAllocations(activeList, behavior, fixedValueW) {
|
|
163
|
+
const allocations = {};
|
|
164
|
+
|
|
165
|
+
activeList.forEach(function (inv) {
|
|
166
|
+
allocations[inv.id] = Math.round(perInverterPolicyValue(inv, behavior, fixedValueW));
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
const total = Object.values(allocations).reduce(function (sum, v) {
|
|
170
|
+
return sum + Number(v || 0);
|
|
171
|
+
}, 0);
|
|
172
|
+
|
|
173
|
+
return {
|
|
174
|
+
allocations: allocations,
|
|
175
|
+
totalW: total
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function applyPolicyToStale(allocations, activeList, staleList, behavior, fixedValueW) {
|
|
180
|
+
const staleSet = new Set(staleList || []);
|
|
181
|
+
const out = Object.assign({}, allocations || {});
|
|
182
|
+
let changed = false;
|
|
183
|
+
|
|
184
|
+
activeList.forEach(function (inv) {
|
|
185
|
+
if (!staleSet.has(inv.id)) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const forced = Math.round(perInverterPolicyValue(inv, behavior, fixedValueW));
|
|
190
|
+
if (Number(out[inv.id] || 0) !== forced) {
|
|
191
|
+
changed = true;
|
|
192
|
+
}
|
|
193
|
+
out[inv.id] = forced;
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
allocations: out,
|
|
198
|
+
changed: changed
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function smoothAllocations(newAllocations, alpha, previousMap) {
|
|
203
|
+
const a = clamp(Number(alpha || 1), 0.01, 1);
|
|
204
|
+
|
|
205
|
+
if (a >= 0.999) {
|
|
206
|
+
const rounded = roundAllocations(newAllocations);
|
|
207
|
+
Object.keys(rounded).forEach(function (id) {
|
|
208
|
+
previousMap[id] = Number(rounded[id] || 0);
|
|
209
|
+
});
|
|
210
|
+
return rounded;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const out = {};
|
|
214
|
+
|
|
215
|
+
Object.keys(newAllocations || {}).forEach(function (id) {
|
|
216
|
+
const prev = Number.isFinite(previousMap[id]) ? previousMap[id] : Number(newAllocations[id] || 0);
|
|
217
|
+
const next = Number(newAllocations[id] || 0);
|
|
218
|
+
const smooth = a * next + (1 - a) * prev;
|
|
219
|
+
previousMap[id] = smooth;
|
|
220
|
+
out[id] = Math.round(smooth);
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
return out;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
module.exports = {
|
|
227
|
+
clamp,
|
|
228
|
+
roundAllocations,
|
|
229
|
+
capacityOf,
|
|
230
|
+
minCapacityOf,
|
|
231
|
+
totalFreshPower,
|
|
232
|
+
chooseEffectiveStrategy,
|
|
233
|
+
allocateIterative,
|
|
234
|
+
buildPolicyAllocations,
|
|
235
|
+
applyPolicyToStale,
|
|
236
|
+
smoothAllocations
|
|
237
|
+
};
|