@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,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const METER_ROLES = Object.freeze(["grid", "pv", "battery"]);
|
|
4
|
+
|
|
5
|
+
function normalizeMeterRole(value) {
|
|
6
|
+
return METER_ROLES.includes(value) ? value : "grid";
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function finitePositive(value) {
|
|
10
|
+
const numeric = Number(value);
|
|
11
|
+
return Number.isFinite(numeric) && numeric > 0 ? numeric : null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function gridReferenceFromSnapshot(snapshot) {
|
|
15
|
+
const source = snapshot && snapshot.measurements;
|
|
16
|
+
if (!source || !snapshot.lastUpdate || snapshot.stale) return null;
|
|
17
|
+
const voltageL1 = finitePositive(source.voltageL1);
|
|
18
|
+
const voltageL2 = finitePositive(source.voltageL2);
|
|
19
|
+
const voltageL3 = finitePositive(source.voltageL3);
|
|
20
|
+
const frequency = finitePositive(source.frequency);
|
|
21
|
+
if (voltageL1 === null || voltageL2 === null || voltageL3 === null || frequency === null) return null;
|
|
22
|
+
return {
|
|
23
|
+
voltageL1,
|
|
24
|
+
voltageL2,
|
|
25
|
+
voltageL3,
|
|
26
|
+
frequency,
|
|
27
|
+
timestamp: snapshot.lastUpdate
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function deriveSecondaryMeasurements(role, sourcePower, gridReference, invertSourceSign) {
|
|
32
|
+
const meterRole = normalizeMeterRole(role);
|
|
33
|
+
if (meterRole === "grid") throw new Error("secondary meter role must be pv or battery");
|
|
34
|
+
let source = Number(sourcePower);
|
|
35
|
+
if (!Number.isFinite(source)) throw new RangeError("global power must be a finite number");
|
|
36
|
+
if (!gridReference) throw new Error("Grid Meter Unit ID 1 reference is not available");
|
|
37
|
+
if (invertSourceSign) source = -source;
|
|
38
|
+
|
|
39
|
+
// Composite mode exposes the context value without an implicit sign change:
|
|
40
|
+
// PV production stays positive; battery charge is positive and discharge negative.
|
|
41
|
+
const power = source;
|
|
42
|
+
const phasePower = power / 3;
|
|
43
|
+
const voltageL1 = finitePositive(gridReference.voltageL1);
|
|
44
|
+
const voltageL2 = finitePositive(gridReference.voltageL2);
|
|
45
|
+
const voltageL3 = finitePositive(gridReference.voltageL3);
|
|
46
|
+
const frequency = finitePositive(gridReference.frequency);
|
|
47
|
+
if (voltageL1 === null || voltageL2 === null || voltageL3 === null || frequency === null) {
|
|
48
|
+
throw new Error("Grid Meter Unit ID 1 reference contains invalid voltage or frequency");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
power,
|
|
53
|
+
powerL1: phasePower,
|
|
54
|
+
powerL2: phasePower,
|
|
55
|
+
powerL3: phasePower,
|
|
56
|
+
voltageL1,
|
|
57
|
+
voltageL2,
|
|
58
|
+
voltageL3,
|
|
59
|
+
currentL1: Math.abs(phasePower) / voltageL1,
|
|
60
|
+
currentL2: Math.abs(phasePower) / voltageL2,
|
|
61
|
+
currentL3: Math.abs(phasePower) / voltageL3,
|
|
62
|
+
frequency,
|
|
63
|
+
reactivePower: 0,
|
|
64
|
+
reactivePowerL1: 0,
|
|
65
|
+
reactivePowerL2: 0,
|
|
66
|
+
reactivePowerL3: 0,
|
|
67
|
+
apparentPower: Math.abs(power),
|
|
68
|
+
apparentPowerL1: Math.abs(phasePower),
|
|
69
|
+
apparentPowerL2: Math.abs(phasePower),
|
|
70
|
+
apparentPowerL3: Math.abs(phasePower),
|
|
71
|
+
powerFactor: 1,
|
|
72
|
+
powerFactorL1: 1,
|
|
73
|
+
powerFactorL2: 1,
|
|
74
|
+
powerFactorL3: 1
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function normalizedEnergyState(value) {
|
|
79
|
+
const source = value && typeof value === "object" ? value : {};
|
|
80
|
+
return {
|
|
81
|
+
importEnergy: Number.isFinite(Number(source.importEnergy)) && Number(source.importEnergy) >= 0 ? Number(source.importEnergy) : 0,
|
|
82
|
+
exportEnergy: Number.isFinite(Number(source.exportEnergy)) && Number(source.exportEnergy) >= 0 ? Number(source.exportEnergy) : 0,
|
|
83
|
+
lastTimestampMs: Number.isFinite(Number(source.lastTimestampMs)) ? Number(source.lastTimestampMs) : null,
|
|
84
|
+
lastPower: Number.isFinite(Number(source.lastPower)) ? Number(source.lastPower) : null
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function integrateDirectionalEnergy(previous, power, timestampMs, maxGapMs) {
|
|
89
|
+
const state = normalizedEnergyState(previous);
|
|
90
|
+
const currentPower = Number(power);
|
|
91
|
+
const now = Number(timestampMs);
|
|
92
|
+
const maximumGap = Number(maxGapMs);
|
|
93
|
+
if (!Number.isFinite(currentPower) || !Number.isFinite(now)) throw new RangeError("power and timestamp must be finite");
|
|
94
|
+
|
|
95
|
+
if (state.lastTimestampMs !== null && state.lastPower !== null) {
|
|
96
|
+
const elapsedMs = now - state.lastTimestampMs;
|
|
97
|
+
if (elapsedMs > 0 && (!Number.isFinite(maximumGap) || maximumGap <= 0 || elapsedMs <= maximumGap)) {
|
|
98
|
+
const elapsedHours = elapsedMs / 3600000;
|
|
99
|
+
const previousPower = state.lastPower;
|
|
100
|
+
if (previousPower >= 0 && currentPower >= 0) {
|
|
101
|
+
state.importEnergy += ((previousPower + currentPower) / 2) * elapsedHours;
|
|
102
|
+
} else if (previousPower <= 0 && currentPower <= 0) {
|
|
103
|
+
state.exportEnergy += ((Math.abs(previousPower) + Math.abs(currentPower)) / 2) * elapsedHours;
|
|
104
|
+
} else {
|
|
105
|
+
const totalMagnitude = Math.abs(previousPower) + Math.abs(currentPower);
|
|
106
|
+
const crossingFraction = totalMagnitude > 0 ? Math.abs(previousPower) / totalMagnitude : 0;
|
|
107
|
+
const firstHours = elapsedHours * crossingFraction;
|
|
108
|
+
const secondHours = elapsedHours - firstHours;
|
|
109
|
+
if (previousPower > 0) {
|
|
110
|
+
state.importEnergy += previousPower * firstHours / 2;
|
|
111
|
+
state.exportEnergy += Math.abs(currentPower) * secondHours / 2;
|
|
112
|
+
} else {
|
|
113
|
+
state.exportEnergy += Math.abs(previousPower) * firstHours / 2;
|
|
114
|
+
state.importEnergy += currentPower * secondHours / 2;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
state.lastTimestampMs = now;
|
|
121
|
+
state.lastPower = currentPower;
|
|
122
|
+
return state;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
module.exports = {
|
|
126
|
+
METER_ROLES,
|
|
127
|
+
normalizeMeterRole,
|
|
128
|
+
gridReferenceFromSnapshot,
|
|
129
|
+
deriveSecondaryMeasurements,
|
|
130
|
+
normalizedEnergyState,
|
|
131
|
+
integrateDirectionalEnergy
|
|
132
|
+
};
|