Skip to content

Commit

Permalink
Merge pull request openhab#1 from RealMalWare/E3DC
Browse files Browse the repository at this point in the history
Added write function for power settings
  • Loading branch information
bjoernbrings authored Feb 8, 2021
2 parents 04cac5d + f5d011e commit aa8b269
Show file tree
Hide file tree
Showing 6 changed files with 318 additions and 139 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public class E3DCBindingConstants {
public static final String CHANNEL_PowerLimitsUsed = "PowerLimitsUsed";
public static final String CHANNEL_MaxDischarge = "MaxDischarge";
public static final String CHANNEL_MaxCharge = "MaxCharge";
public static final String CHANNEL_DischargeStart = "DischargeStart";
public static final String CHANNEL_WeatherRegulatedCharge = "WeatherRegulatedCharge";
public static final String CHANNEL_PowerSave = "PowerSave";
public static final String CHANNEL_EmergencyPowerStatus = "EmergencyPowerStatus";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.e3dc.internal.rscp.RSCPData;
import org.openhab.binding.e3dc.internal.rscp.RSCPFrame;
import org.openhab.binding.e3dc.internal.rscp.RSCPTag;
import org.openhab.binding.e3dc.internal.rscp.util.AES256Helper;
import org.openhab.binding.e3dc.internal.rscp.util.BouncyAES256Helper;
import org.openhab.binding.e3dc.internal.rscp.util.ByteUtils;
Expand Down Expand Up @@ -92,14 +93,64 @@ public void connectE3DC() {
}
}

public void setPowerLimitsUsed(Boolean value) {
setBoolValue(RSCPTag.TAG_EMS_REQ_SET_POWER_SETTINGS, RSCPTag.TAG_EMS_POWER_LIMITS_USED, value);
}

public void setMaxDischargePower(int value) {
setuint32CharValue(RSCPTag.TAG_EMS_REQ_SET_POWER_SETTINGS, RSCPTag.TAG_EMS_MAX_DISCHARGE_POWER, value);
}

public void setMaxChargePower(int value) {
setuint32CharValue(RSCPTag.TAG_EMS_REQ_SET_POWER_SETTINGS, RSCPTag.TAG_EMS_MAX_CHARGE_POWER, value);
}

public void setDischargeStartPower(int value) {
setuint32CharValue(RSCPTag.TAG_EMS_REQ_SET_POWER_SETTINGS, RSCPTag.TAG_EMS_DISCHARGE_START_POWER, value);
}

public void setWeatherRegulatedChargeEnable(Boolean value) {
char charValue = (char) (value ? 1 : 0);
setCharValue(RSCPTag.TAG_EMS_REQ_SET_POWER_SETTINGS, RSCPTag.TAG_EMS_WEATHER_REGULATED_CHARGE_ENABLED,
charValue);
}

public void setPowerSaveEnable(Boolean value) {
char charValue = (char) (value ? 1 : 0);
setCharValue(RSCPTag.TAG_EMS_REQ_SET_POWER_SETTINGS, RSCPTag.TAG_EMS_POWERSAVE_ENABLED, charValue);
}

public void setuint32CharValue(RSCPTag containerTag, RSCPTag tag, int value) {
logger.debug("setuint32CharValue container:{} tag:{} vale:{}", containerTag.name(), tag.name(), value);
byte[] reqFrame = E3DCRequests.buildRequestSetFrame(containerTag, tag, value);
handleRequest(reqFrame);
}

public void setCharValue(RSCPTag containerTag, RSCPTag tag, char value) {
logger.tracetrace("setCharValue container:{} tag:{} vale:{}", containerTag.name(), tag.name(), value);
byte[] reqFrame = E3DCRequests.buildRequestSetFrame(containerTag, tag, value);
handleRequest(reqFrame);
}

public void setBoolValue(RSCPTag containerTag, RSCPTag tag, Boolean value) {
logger.trace("setBoolValue container:{} tag:{} vale:{}", containerTag.name(), tag.name(), value);
byte[] reqFrame = E3DCRequests.buildRequestSetFrame(containerTag, tag, value);
handleRequest(reqFrame);
}

public void requestE3DCData() {
byte[] reqFrame = E3DCRequests.buildRequestFrame();
handleRequest(reqFrame);
}

public void handleRequest(byte[] reqFrame) {
if (isNotConnected()) {
connectE3DC();
}
byte[] reqFrame = E3DCRequests.buildRequestFrame();
logger.debug("Unencrypted frame to send: {}", ByteUtils.byteArrayToHexString(reqFrame));
Integer bytesSent = sendFrameToServer(aesHelper::encrypt, reqFrame);
byte[] decBytesReceived = receiveFrameFromServer(aesHelper::decrypt);
logger.warn("Decrypted frame received: {}", ByteUtils.byteArrayToHexString(decBytesReceived));
logger.debug("Decrypted frame received: {}", ByteUtils.byteArrayToHexString(decBytesReceived));
RSCPFrame responseFrame = RSCPFrame.builder().buildFromRawBytes(decBytesReceived);

handleE3DCResponse(responseFrame);
Expand Down Expand Up @@ -150,6 +201,11 @@ public void handleUpdateData(RSCPData data) {
for (RSCPData containedData : containedDataList) {
handleUpdatePowerSettingsData(containedData);
}
} else if ("TAG_EMS_SET_POWER_SETTINGS".equals(dt)) {
List<RSCPData> containedDataList = data.getContainerData();
for (RSCPData containedData : containedDataList) {
handleUpdatePowerSettingsData(containedData);
}
} else if ("TAG_EMS_EMERGENCY_POWER_STATUS".equals(dt)) {
handle.updateState(E3DCBindingConstants.CHANNEL_EmergencyPowerStatus,
new DecimalType(data.getValueAsInt().orElse(-1)));
Expand Down Expand Up @@ -199,23 +255,39 @@ private void handleUpdatePMData(RSCPData data) {

private void handleUpdatePowerSettingsData(RSCPData data) {
String dt = data.getDataTag().name();
logger.debug("handleUpdatePowerSettingsData : {}: {}", dt, data.getValueAsString());

if ("TAG_EMS_POWER_LIMITS_USED".equals(dt)) {
handle.updateState(E3DCBindingConstants.CHANNEL_PowerLimitsUsed,
OnOffType.from(data.getValueAsBool().orElse(false)));
} else if ("TAG_EMS_RES_TAG_EMS_POWER_LIMITS_USED".equals(dt)) {
// maybe update TAG_EMS_POWER_LIMITS_USED...?
} else if ("TAG_EMS_MAX_DISCHARGE_POWER".equals(dt)) {
handle.updateState(E3DCBindingConstants.CHANNEL_MaxDischarge,
new QuantityType<>(data.getValueAsInt().get(), Units.WATT));
} else if ("TAG_EMS_RES_MAX_DISCHARGE_POWER".equals(dt)) {
// maybe update TAG_EMS_MAX_DISCHARGE_POWER...?
} else if ("TAG_EMS_MAX_CHARGE_POWER".equals(dt)) {
handle.updateState(E3DCBindingConstants.CHANNEL_MaxCharge,
new QuantityType<>(data.getValueAsInt().get(), Units.WATT));
} else if ("TAG_EMS_RES_MAX_CHARGE_POWER".equals(dt)) {
// maybe update TAG_EMS_MAX_CHARGE_POWER...?
} else if ("TAG_EMS_DISCHARGE_START_POWER".equals(dt)) {
handle.updateState(E3DCBindingConstants.CHANNEL_DischargeStart,
new QuantityType<>(data.getValueAsInt().get(), Units.WATT));
} else if ("TAG_EMS_RES_DISCHARGE_START_POWER".equals(dt)) {
// maybe update TAG_EMS_DISCHARGE_START_POWER...?
} else if ("TAG_EMS_WEATHER_REGULATED_CHARGE_ENABLED".equals(dt)) {
handle.updateState(E3DCBindingConstants.CHANNEL_WeatherRegulatedCharge,
OnOffType.from(data.getValueAsBool().orElse(false)));
} else if ("TAG_EMS_RES_WEATHER_REGULATED_CHARGE_ENABLE".equals(dt)) {
// maybe update TAG_EMS_WEATHER_REGULATED_CHARGE_ENABLED...?
} else if ("TAG_EMS_POWERSAVE_ENABLED".equals(dt)) {
boolean result = data.getValueAsBool().orElse(false);

handle.updateState(E3DCBindingConstants.CHANNEL_PowerSave, OnOffType.from(result));
} else if ("TAG_EMS_RES_POWERSAVE_ENABLED".equals(dt)) {
// maybe update TAG_EMS_POWERSAVE_ENABLED...?
}
}

Expand All @@ -225,8 +297,10 @@ private boolean isNotConnected() {

public void close() {
try {
socket.close();
socket = null;
if (socket != null) {
socket.close();
socket = null;
}
} catch (IOException e) {
logger.info("Couldn't close connection: {}", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingStatusDetail;
import org.openhab.core.thing.binding.BaseThingHandler;
import org.openhab.core.types.Command;
import org.openhab.core.types.RefreshType;
import org.openhab.core.types.State;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -49,6 +53,63 @@ public E3DCHandler(Thing thing) {
@Override
public void handleCommand(ChannelUID channelUID, Command command) {

this.logger.debug("handleCommand channel:{} command:{}", channelUID, command);
if (command instanceof RefreshType) {
return;
}

if (E3DCBindingConstants.CHANNEL_WeatherRegulatedCharge.equals(channelUID.getId())) {
boolean value = (command == OnOffType.ON);
e3dcconnect.setWeatherRegulatedChargeEnable(value);
}

if (E3DCBindingConstants.CHANNEL_PowerSave.equals(channelUID.getId())) {
boolean value = (command == OnOffType.ON);
e3dcconnect.setPowerSaveEnable(value);
}

if (E3DCBindingConstants.CHANNEL_PowerLimitsUsed.equals(channelUID.getId())) {
boolean value = (command == OnOffType.ON);
e3dcconnect.setPowerLimitsUsed(value);
}

if (E3DCBindingConstants.CHANNEL_MaxCharge.equals(channelUID.getId())) {
int value = convertCommandToIntValue(command, 100, 3000);
e3dcconnect.setMaxChargePower(value);
}

if (E3DCBindingConstants.CHANNEL_MaxDischarge.equals(channelUID.getId())) {
int value = convertCommandToIntValue(command, 100, 3000);
e3dcconnect.setMaxDischargePower(value);
}

if (E3DCBindingConstants.CHANNEL_DischargeStart.equals(channelUID.getId())) {
int value = convertCommandToIntValue(command, 0, 500);
e3dcconnect.setDischargeStartPower(value);
}
}

public int convertCommandToIntValue(Command command, int min, int max) {
this.logger.debug("convertCommandToIntValue command: {}", command);

int value;
double fValue;

if (command instanceof DecimalType) {
fValue = ((DecimalType) command).floatValue();
logger.trace("convertCommandToIntValue DecimalType fValue: {}", Double.valueOf(fValue));
} else if (command instanceof QuantityType) {
fValue = ((QuantityType<?>) command).doubleValue();
logger.trace("convertCommandToIntValue QuantityType fValue: {}", Double.valueOf(fValue));
} else {
throw new NumberFormatException("Command type '" + command + "' not supported");
}

value = (int) fValue;
value = Math.min(max, value);
value = Math.max(min, value);

return value;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,41 @@ public static byte[] buildRequestFrame() {
return reqFrame1.getAsByteArray();
}

public static byte[] buildRequestSetFrame(RSCPTag containerTag, RSCPTag tag, Boolean value) {
Builder buildFrame = RSCPFrame.builder().timestamp(Instant.now()).addData(
RSCPData.builder().tag(containerTag).containerValues(Arrays.asList(ReqGeni(tag, value))).build());
return requestFrameFromBuildFrame(buildFrame);
}

public static byte[] buildRequestSetFrame(RSCPTag containerTag, RSCPTag tag, char value) {
Builder buildFrame = RSCPFrame.builder().timestamp(Instant.now()).addData(
RSCPData.builder().tag(containerTag).containerValues(Arrays.asList(ReqGeni(tag, value))).build());
return requestFrameFromBuildFrame(buildFrame);
}

public static byte[] buildRequestSetFrame(RSCPTag containerTag, RSCPTag tag, int value) {
Builder buildFrame = RSCPFrame.builder().timestamp(Instant.now()).addData(
RSCPData.builder().tag(containerTag).containerValues(Arrays.asList(ReqGeni(tag, value))).build());
return requestFrameFromBuildFrame(buildFrame);
}

public static byte[] requestFrameFromBuildFrame(Builder buildFrame) {
RSCPFrame reqFrame = buildFrame.build();
return reqFrame.getAsByteArray();
}

public static RSCPData ReqGeni(RSCPTag tag, Boolean i) {
return RSCPData.builder().tag(tag).boolValue(i).build();
}

public static RSCPData ReqGeni(RSCPTag tag, int i) {
return RSCPData.builder().tag(tag).uint32Value(i).build();
}

public static RSCPData ReqGeni(RSCPTag tag, char c) {
return RSCPData.builder().tag(tag).uchar8Value(c).build();
}

public static RSCPData ReqGeni(RSCPTag tag, short s) {
return RSCPData.builder().tag(tag).int16Value(s).build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -663,4 +663,4 @@ private void validate() {
}
}
}
}
}
Loading

0 comments on commit aa8b269

Please sign in to comment.