Hallo Lóránt,
super Timing…gerade heute habe ich etwas daran experimentiert. Das Schreiben der Register funktioniert.
Meine applyPower-Methode sieht so aus:
public void applyPower(int activePowerWanted, int reactivePowerWanted) throws OpenemsNamedException {
CycleCounter++;
// Read-only mode -> switch to max. self consumption automatic
if (this.config.readOnlyMode() ) {
if ( CycleCounter > 60) {
CycleCounter=0;
// Switch to automatic mode
EnumWriteChannel setControlModeChannel = this.channel(SolarEdgeHybridEss.ChannelId.SET_CONTROL_MODE);
setControlModeChannel.setNextWriteValue(ControlMode.SE_CTRL_MODE_MAX_SELF_CONSUMPTION);
// The next 2 are fallback values which should become active after the 60 seonds timeout
EnumWriteChannel setChargeDischargeDefaultMode = this.channel(SolarEdgeHybridEss.ChannelId.SET_CHARGE_DISCHARGE_DEFAULT_MODE); //Same enum as Remote control mode
setChargeDischargeDefaultMode.setNextWriteValue(ChargeDischargeMode.SE_CHARGE_POLICY_MAX_SELF_CONSUMPTION); // This mode is active after remote control timeout exceeded
IntegerWriteChannel setCommandTimeout = this.channel(SolarEdgeHybridEss.ChannelId.SET_REMOTE_CONTROL_TIMEOUT);
setCommandTimeout.setNextWriteValue(60); // Our Remote-commands are only valid for a minute
setLimits();
}
return;
}
else {
if (CycleCounter > 0) { // Set values every Cycle
CycleCounter=0;
//read_only is NOT enabled
EnumWriteChannel setControlMode = this.channel(SolarEdgeHybridEss.ChannelId.SET_CONTROL_MODE);
EnumWriteChannel setChargePolicy = this.channel(SolarEdgeHybridEss.ChannelId.SET_STORAGE_CHARGE_POLICY);
EnumWriteChannel setChargeDischargeDefaultMode = this.channel(SolarEdgeHybridEss.ChannelId.SET_CHARGE_DISCHARGE_DEFAULT_MODE); //Same enum as Remote control mode
EnumWriteChannel setChargeDischargeMode = this.channel(SolarEdgeHybridEss.ChannelId.SET_REMOTE_CONTROL_COMMAND_MODE); //Same enum as Remote control default mode
IntegerWriteChannel setChargePowerLimit = this.channel(SolarEdgeHybridEss.ChannelId.SET_MAX_CHARGE_POWER);
IntegerWriteChannel setDischargePowerLimit = this.channel(SolarEdgeHybridEss.ChannelId.SET_MAX_DISCHARGE_POWER);
IntegerWriteChannel setCommandTimeout = this.channel(SolarEdgeHybridEss.ChannelId.SET_REMOTE_CONTROL_TIMEOUT);
if (isControlModeRemote() == false)
{
setControlMode.setNextWriteValue(ControlMode.SE_CTRL_MODE_REMOTE); // Now the device can be remote controlled
setChargePolicy.setNextWriteValue(AcChargePolicy.SE_CHARGE_DISCHARGE_MODE_ALWAYS); // Always allowed.When used with Maximize self-consumption, only excess power is used for charging (charging from the grid is not allowed)
}
// setControlMode.setNextWriteValue(ControlMode.SE_CTRL_MODE_REMOTE); // Now the device can be remote controlled
// setChargePolicy.setNextWriteValue(AcChargePolicy.SE_CHARGE_DISCHARGE_MODE_ALWAYS); // Always allowed.When used with Maximize self-consumption, only excess power is used for charging (charging from the grid is not allowed)
// The next 2 are fallback values which should become active after the 60 seonds timeout
setChargeDischargeDefaultMode.setNextWriteValue(ChargeDischargeMode.SE_CHARGE_POLICY_MAX_SELF_CONSUMPTION); // This mode is active after remote control timeout exceeded
setCommandTimeout.setNextWriteValue(60); // Our Remote-commands are only valid for a minute
if (activePowerWanted <= 0) { // Negative Values are for charging
setChargeDischargeMode.setNextWriteValue(ChargeDischargeMode.SE_CHARGE_POLICY_PV_AC); // Mode for charging
setChargePowerLimit.setNextWriteValue(activePowerWanted * -1); // Values for register must be positive
}
else {
setChargeDischargeMode.setNextWriteValue(ChargeDischargeMode.SE_CHARGE_POLICY_MAX_EXPORT); // Mode for discharging
setDischargePowerLimit.setNextWriteValue(activePowerWanted);
}
}
}
}
Der Modbus-Task schreibt alle Register auf Einmal:
protocol.addTask(//
new FC16WriteRegistersTask(0xE004,
m(SolarEdgeHybridEss.ChannelId.SET_CONTROL_MODE, new SignedWordElement(0xE004)),
m(SolarEdgeHybridEss.ChannelId.SET_STORAGE_CHARGE_POLICY, new SignedWordElement(0xE005)), // Max. charge power. Negative values
m(SolarEdgeHybridEss.ChannelId.SET_MAX_CHARGE_LIMIT, new FloatDoublewordElement(0xE006).wordOrder(WordOrder.LSWMSW)), // kWh or percent
m(SolarEdgeHybridEss.ChannelId.SET_STORAGE_BACKUP_LIMIT, new FloatDoublewordElement(0xE008).wordOrder(WordOrder.LSWMSW)), // Percent of capacity
m(SolarEdgeHybridEss.ChannelId.SET_CHARGE_DISCHARGE_DEFAULT_MODE, new UnsignedWordElement(0xE00A)), // Usually set to 1 (Charge PV excess only)
m(SolarEdgeHybridEss.ChannelId.SET_REMOTE_CONTROL_TIMEOUT, new UnsignedDoublewordElement(0xE00B).wordOrder(WordOrder.LSWMSW)),
m(SolarEdgeHybridEss.ChannelId.SET_REMOTE_CONTROL_COMMAND_MODE, new UnsignedWordElement(0xE00D)),
m(SolarEdgeHybridEss.ChannelId.SET_MAX_CHARGE_POWER, new FloatDoublewordElement(0xE00E).wordOrder(WordOrder.LSWMSW)), // Max. charge power. Negative values
m(SolarEdgeHybridEss.ChannelId.SET_MAX_DISCHARGE_POWER, new FloatDoublewordElement(0xE010).wordOrder(WordOrder.LSWMSW)) // Max. discharge power. Positive values
)); // Disabled, automatic, remote controlled, etc.
Kommentare und Programmierstil sind noch nicht so richtig schick…
Ich habe versuchsweise mal den Balancing-Controller für optimierten Eigenverbrauch aktiviert. Fehler beim Modbus-Write bekomme ich zwar nicht, aber die Anlage “überregelt” ziemlich heftig. Die Cycle-Time ist bei 1 Sekunde.
Auf GitHib ist der Code noch nicht - kommt in den nächsten Tagen…
Gruß,
Klinki