hab das Script inzwischen ganz schön umgebaut.
Zum Thema Priorisierung ist das hier wesentlich:
// These register spaces need to be read:
const RegisterSpacesToReadContinuously = [[32000, 116], // read often: Inverter.ActivePower: 32080, Inverter.InputPower: 32064
[37100, 114], // read often: Meter.ActivePower: 37113
[37700, 100], // read often: Inverter.Battery.SOC: 37760, Inverter.Battery.ChargeAndDischargePower: 37765
[47075, 10], // read often: MaximumChargingPower,...
[37000, 68], // Batterystack,... --> read rarely
[37800, 100], // Batterystack --> read rarely
[38200, 100], // Batterystack --> read rarely
[38300, 100], // Batterystack --> read rarely
[38400, 100], // Batterystack --> read rarely
[30000, 81] // ProcessDeviceInfo() --> read rarely
// [35300, 40] // Inverter.ActiveAdjustement.* --> no use
];
var RegisterSpacesToReadContinuouslyPtr = 0;
const RegisterSpacesToReadPrioLoops = 56; // number of fast read cycles before full read cycle (~ every 15 mins at 4s cycle time)
const RegisterSpacesToReadFast = 4; // number of registers to be read fast
var RegisterSpacesToReadPrioLoopCount = 0;
Dazu kommen noch für meine Schreibarbeiten ins Register 47075 (mehr brauche ich derzeit nicht):
var triggerWriteProcessing = false; // write instead of read a register
var batteryChargePower = 0; // value to be written into register 47075
Die werden im Ablauf gesetzt durch on() oder durch zeitliche Ereignisse...
Dann die Intervall-Funktion:
setInterval(function()
// -------------------
// This is the main function triggering a read or a write via modbus-tcp every xx seconds (see value below in ms)
// Processing of data is triggered as soon as one complete set of registers is copied
// with 4 seconds, new values are displyed every 16/40 seconds
{
var RegisterSpacesToReadContinuouslyLength;
if (triggerprocessing == 1)
{
ProcessData();
triggerprocessing = 0;
}
if (triggerWriteProcessing == false) // read register (either read or write in one interval)
{
console.debug("Triggering read of inverter at address " +
RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][0] +
" with length " + RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][1]);
readRegisterSpace(RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][0], RegisterSpacesToReadContinuously[RegisterSpacesToReadContinuouslyPtr][1]);
RegisterSpacesToReadContinuouslyPtr++;
if (RegisterSpacesToReadPrioLoopCount == 0) RegisterSpacesToReadContinuouslyLength = RegisterSpacesToReadContinuously.length;
else RegisterSpacesToReadContinuouslyLength = RegisterSpacesToReadFast; // number of registers to be read
if (RegisterSpacesToReadContinuouslyPtr >= RegisterSpacesToReadContinuouslyLength)
{
RegisterSpacesToReadContinuouslyPtr = 0;
RegisterSpacesToReadPrioLoopCount++;
if (RegisterSpacesToReadPrioLoopCount >= RegisterSpacesToReadPrioLoops) RegisterSpacesToReadPrioLoopCount = 0;
triggerprocessing = 1; // everything was read, now set the datapoints
}
}
else // triggerWriteProcessing == true --> write register
{
client.writeRegisters(47075, [0, batteryChargePower]); // write the value 0, xxx to registers starting at address 47075
triggerWriteProcessing = false;
}
}, 4000);
Hinweis - statt
// get SOC of first battery stack and combine to one string
var BatOverview = "";
for(var j = 1; j <= BatteryUnits[0][0]; j++)
{
if (j > 1) BatOverview += ", ";
BatOverview += getState("javascript.0.Solarpower.Huawei.Inverter.1.Batterystack.1.Battery" + j + ".BatterySOC").val + "%";
}
setState("javascript.0.Solarpower.Derived.BatteryOverview", BatOverview);
hab ich, weil nur 5kWh Batterie:
// get SOC of all batteries and combine to one string (only one battery here...)
var BatOverview = getState("javascript.0.Solarpower.Huawei.Inverter.Battery.SOC").val;
setState("javascript.0.Solarpower.Derived.BatteryOverview", BatOverview);
das spart Registerbereiche - Inverter.1.Batterystack.1.Battery.* wird bei mir ja nur noch alle 15 Minuten aktualisiert. Selbiges für YieldToday, IsBatteryLoading.
(und ja, den DP Derived.BatteryOverview könnte ich mir sparen indem ich gleich Inverter.Battery.SOC verwende...)
BatOverview und der DP Derived.BatteryOverview sind bei mir auch kein String, sondern 'ne Zahl, weil ich damit weiterrechne.