added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.goecharger-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
|
||||
|
||||
<feature name="openhab-binding-goecharger" description="Go-eCharger Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.goecharger/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.goecharger.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link GoEChargerBindingConstants} class defines common constants, which
|
||||
* are used across the whole binding.
|
||||
*
|
||||
* @author Samuel Brucksch - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class GoEChargerBindingConstants {
|
||||
|
||||
private static final String BINDING_ID = "goecharger";
|
||||
|
||||
// List of all Thing Type UIDs
|
||||
public static final ThingTypeUID THING_TYPE_GOE = new ThingTypeUID(BINDING_ID, "goe");
|
||||
|
||||
// List of all Channel ids
|
||||
public static final String MAX_CURRENT = "maxCurrent";
|
||||
public static final String ACCESS_CONFIGURATION = "accessConfiguration";
|
||||
public static final String PWM_SIGNAL = "pwmSignal";
|
||||
public static final String ERROR = "error";
|
||||
public static final String VOLTAGE_L1 = "voltageL1";
|
||||
public static final String VOLTAGE_L2 = "voltageL2";
|
||||
public static final String VOLTAGE_L3 = "voltageL3";
|
||||
public static final String CURRENT_L1 = "currentL1";
|
||||
public static final String CURRENT_L2 = "currentL2";
|
||||
public static final String CURRENT_L3 = "currentL3";
|
||||
public static final String POWER_L1 = "powerL1";
|
||||
public static final String POWER_L2 = "powerL2";
|
||||
public static final String POWER_L3 = "powerL3";
|
||||
public static final String ALLOW_CHARGING = "allowCharging";
|
||||
public static final String CABLE_ENCODING = "cableCurrent";
|
||||
public static final String PHASES = "phases";
|
||||
public static final String TEMPERATURE = "temperature";
|
||||
public static final String SESSION_CHARGE_CONSUMPTION = "sessionChargedEnergy";
|
||||
public static final String SESSION_CHARGE_CONSUMPTION_LIMIT = "sessionChargeEnergyLimit";
|
||||
public static final String TOTAL_CONSUMPTION = "totalChargedEnergy";
|
||||
public static final String FIRMWARE = "firmware";
|
||||
|
||||
public static final String API_URL = "http://%IP%/status";
|
||||
public static final String MQTT_URL = "http://%IP%/mqtt?payload=%KEY%=%VALUE%";
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.goecharger.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* The {@link GoEChargerConfiguration} class contains fields mapping thing configuration parameters.
|
||||
*
|
||||
* @author Samuel Brucksch - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class GoEChargerConfiguration {
|
||||
|
||||
public @Nullable String ip;
|
||||
public Integer refreshInterval = 5;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.goecharger.internal;
|
||||
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.binding.goecharger.internal.handler.GoEChargerHandler;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
||||
/**
|
||||
* The {@link GoEChargerHandlerFactory} is responsible for creating things and
|
||||
* thing handlers.
|
||||
*
|
||||
* @author Samuel Brucksch - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(configurationPid = "binding.goecharger", service = ThingHandlerFactory.class)
|
||||
public class GoEChargerHandlerFactory extends BaseThingHandlerFactory {
|
||||
|
||||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.singleton(THING_TYPE_GOE);
|
||||
private final HttpClient httpClient;
|
||||
|
||||
@Activate
|
||||
public GoEChargerHandlerFactory(final @Reference HttpClientFactory httpClientFactory) {
|
||||
this.httpClient = httpClientFactory.getCommonHttpClient();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
||||
if (THING_TYPE_GOE.equals(thingTypeUID)) {
|
||||
return new GoEChargerHandler(thing, httpClient);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.goecharger.internal.api;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* The {@link GoEStatusResponse} class represents a json response from the
|
||||
* charger.
|
||||
*
|
||||
* @author Samuel Brucksch - Initial contribution
|
||||
*/
|
||||
public class GoEStatusResponseDTO {
|
||||
@SerializedName("version")
|
||||
public String version;
|
||||
|
||||
@SerializedName("car")
|
||||
public Integer pwmSignal;
|
||||
|
||||
@SerializedName("ast")
|
||||
public Integer accessConfiguration;
|
||||
|
||||
@SerializedName("amp")
|
||||
public Integer maxCurrent;
|
||||
|
||||
@SerializedName("nrg")
|
||||
public Integer[] energy;
|
||||
|
||||
@SerializedName("err")
|
||||
public Integer errorCode;
|
||||
|
||||
@SerializedName("alw")
|
||||
public Integer allowCharging;
|
||||
|
||||
@SerializedName("cbl")
|
||||
public Integer cableEncoding;
|
||||
|
||||
@SerializedName("pha")
|
||||
public Integer phases;
|
||||
|
||||
@SerializedName("tmp")
|
||||
public Integer temperature;
|
||||
|
||||
@SerializedName("dws")
|
||||
public Long sessionChargeConsumption;
|
||||
|
||||
@SerializedName("dwo")
|
||||
public Integer sessionChargeConsumptionLimit;
|
||||
|
||||
@SerializedName("eto")
|
||||
public Long totalChargeConsumption;
|
||||
|
||||
@SerializedName("fwv")
|
||||
public String firmware;
|
||||
}
|
||||
@@ -0,0 +1,438 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.goecharger.internal.handler;
|
||||
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.ACCESS_CONFIGURATION;
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.ALLOW_CHARGING;
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.CABLE_ENCODING;
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.CURRENT_L1;
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.CURRENT_L2;
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.CURRENT_L3;
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.ERROR;
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.FIRMWARE;
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.MAX_CURRENT;
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.PHASES;
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.POWER_L1;
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.POWER_L2;
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.POWER_L3;
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.PWM_SIGNAL;
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.SESSION_CHARGE_CONSUMPTION;
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.SESSION_CHARGE_CONSUMPTION_LIMIT;
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.TEMPERATURE;
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.TOTAL_CONSUMPTION;
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.VOLTAGE_L1;
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.VOLTAGE_L2;
|
||||
import static org.openhab.binding.goecharger.internal.GoEChargerBindingConstants.VOLTAGE_L3;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.measure.quantity.ElectricCurrent;
|
||||
import javax.measure.quantity.Energy;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.openhab.binding.goecharger.internal.GoEChargerBindingConstants;
|
||||
import org.openhab.binding.goecharger.internal.GoEChargerConfiguration;
|
||||
import org.openhab.binding.goecharger.internal.api.GoEStatusResponseDTO;
|
||||
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.library.types.StringType;
|
||||
import org.openhab.core.library.unit.SIUnits;
|
||||
import org.openhab.core.library.unit.SmartHomeUnits;
|
||||
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.openhab.core.types.UnDefType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
/**
|
||||
* The {@link GoEChargerHandler} is responsible for handling commands, which are
|
||||
* sent to one of the channels.
|
||||
*
|
||||
* @author Samuel Brucksch - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class GoEChargerHandler extends BaseThingHandler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(GoEChargerHandler.class);
|
||||
|
||||
private @Nullable GoEChargerConfiguration config;
|
||||
|
||||
private List<String> allChannels = new ArrayList<>();
|
||||
|
||||
private final Gson gson = new Gson();
|
||||
|
||||
private @Nullable ScheduledFuture<?> refreshJob;
|
||||
|
||||
private final HttpClient httpClient;
|
||||
|
||||
public GoEChargerHandler(Thing thing, HttpClient httpClient) {
|
||||
super(thing);
|
||||
this.httpClient = httpClient;
|
||||
}
|
||||
|
||||
private State getValue(String channelId, GoEStatusResponseDTO goeResponse) {
|
||||
switch (channelId) {
|
||||
case MAX_CURRENT:
|
||||
if (goeResponse.maxCurrent == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
return new QuantityType<>(goeResponse.maxCurrent, SmartHomeUnits.AMPERE);
|
||||
case PWM_SIGNAL:
|
||||
if (goeResponse.pwmSignal == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
String pwmSignal = null;
|
||||
switch (goeResponse.pwmSignal) {
|
||||
case 1:
|
||||
pwmSignal = "READY_NO_CAR";
|
||||
break;
|
||||
case 2:
|
||||
pwmSignal = "CHARGING";
|
||||
break;
|
||||
case 3:
|
||||
pwmSignal = "WAITING_FOR_CAR";
|
||||
break;
|
||||
case 4:
|
||||
pwmSignal = "CHARGING_DONE_CAR_CONNECTED";
|
||||
break;
|
||||
default:
|
||||
}
|
||||
return new StringType(pwmSignal);
|
||||
case ERROR:
|
||||
if (goeResponse.errorCode == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
String error = null;
|
||||
switch (goeResponse.errorCode) {
|
||||
case 0:
|
||||
error = "NONE";
|
||||
break;
|
||||
case 1:
|
||||
error = "RCCB";
|
||||
break;
|
||||
case 3:
|
||||
error = "PHASE";
|
||||
break;
|
||||
case 8:
|
||||
error = "NO_GROUND";
|
||||
break;
|
||||
default:
|
||||
error = "INTERNAL";
|
||||
break;
|
||||
}
|
||||
return new StringType(error);
|
||||
case ACCESS_CONFIGURATION:
|
||||
if (goeResponse.accessConfiguration == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
String accessConfiguration = null;
|
||||
switch (goeResponse.accessConfiguration) {
|
||||
case 0:
|
||||
accessConfiguration = "OPEN";
|
||||
break;
|
||||
case 1:
|
||||
accessConfiguration = "RFID";
|
||||
break;
|
||||
case 2:
|
||||
accessConfiguration = "AWATTAR";
|
||||
break;
|
||||
case 3:
|
||||
accessConfiguration = "TIMER";
|
||||
break;
|
||||
default:
|
||||
}
|
||||
return new StringType(accessConfiguration);
|
||||
case ALLOW_CHARGING:
|
||||
if (goeResponse.allowCharging == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
return goeResponse.allowCharging == 1 ? OnOffType.ON : OnOffType.OFF;
|
||||
case CABLE_ENCODING:
|
||||
if (goeResponse.cableEncoding == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
return new QuantityType<>(goeResponse.cableEncoding, SmartHomeUnits.AMPERE);
|
||||
case PHASES:
|
||||
if (goeResponse.energy == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
int count = 0;
|
||||
if (goeResponse.energy[4] > 0) { // current P1
|
||||
count++;
|
||||
}
|
||||
if (goeResponse.energy[5] > 0) { // current P2
|
||||
count++;
|
||||
}
|
||||
if (goeResponse.energy[6] > 0) { // current P3
|
||||
count++;
|
||||
}
|
||||
return new DecimalType(count);
|
||||
case TEMPERATURE:
|
||||
if (goeResponse.temperature == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
return new QuantityType<>(goeResponse.temperature, SIUnits.CELSIUS);
|
||||
case SESSION_CHARGE_CONSUMPTION:
|
||||
if (goeResponse.sessionChargeConsumption == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
return new QuantityType<>((Double) (goeResponse.sessionChargeConsumption / 360000d),
|
||||
SmartHomeUnits.KILOWATT_HOUR);
|
||||
case SESSION_CHARGE_CONSUMPTION_LIMIT:
|
||||
if (goeResponse.sessionChargeConsumptionLimit == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
return new QuantityType<>((Double) (goeResponse.sessionChargeConsumptionLimit / 10d),
|
||||
SmartHomeUnits.KILOWATT_HOUR);
|
||||
case TOTAL_CONSUMPTION:
|
||||
if (goeResponse.totalChargeConsumption == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
return new QuantityType<>((Double) (goeResponse.totalChargeConsumption / 10d),
|
||||
SmartHomeUnits.KILOWATT_HOUR);
|
||||
case FIRMWARE:
|
||||
if (goeResponse.firmware == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
return new StringType(goeResponse.firmware);
|
||||
case VOLTAGE_L1:
|
||||
if (goeResponse.energy == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
return new QuantityType<>(goeResponse.energy[0], SmartHomeUnits.VOLT);
|
||||
case VOLTAGE_L2:
|
||||
if (goeResponse.energy == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
return new QuantityType<>(goeResponse.energy[1], SmartHomeUnits.VOLT);
|
||||
case VOLTAGE_L3:
|
||||
if (goeResponse.energy == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
return new QuantityType<>(goeResponse.energy[2], SmartHomeUnits.VOLT);
|
||||
case CURRENT_L1:
|
||||
if (goeResponse.energy == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
// values come in as A*10, 41 means 4.1A
|
||||
return new QuantityType<>((Double) (goeResponse.energy[4] / 10d), SmartHomeUnits.AMPERE);
|
||||
case CURRENT_L2:
|
||||
if (goeResponse.energy == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
return new QuantityType<>((Double) (goeResponse.energy[5] / 10d), SmartHomeUnits.AMPERE);
|
||||
case CURRENT_L3:
|
||||
if (goeResponse.energy == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
return new QuantityType<>((Double) (goeResponse.energy[6] / 10d), SmartHomeUnits.AMPERE);
|
||||
case POWER_L1:
|
||||
if (goeResponse.energy == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
// values come in as kW*10, 41 means 4.1kW
|
||||
return new QuantityType<>(goeResponse.energy[7] * 100, SmartHomeUnits.WATT);
|
||||
case POWER_L2:
|
||||
if (goeResponse.energy == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
return new QuantityType<>(goeResponse.energy[8] * 100, SmartHomeUnits.WATT);
|
||||
case POWER_L3:
|
||||
if (goeResponse.energy == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
return new QuantityType<>(goeResponse.energy[9] * 100, SmartHomeUnits.WATT);
|
||||
}
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (command instanceof RefreshType) {
|
||||
// we can not update single channels and refresh is triggered automatically
|
||||
// anyways
|
||||
return;
|
||||
}
|
||||
|
||||
String key = null;
|
||||
String value = null;
|
||||
switch (channelUID.getId()) {
|
||||
case MAX_CURRENT:
|
||||
key = "amp";
|
||||
if (command instanceof DecimalType) {
|
||||
value = String.valueOf(((DecimalType) command).intValue());
|
||||
} else if (command instanceof QuantityType<?>) {
|
||||
value = String.valueOf(
|
||||
((QuantityType<ElectricCurrent>) command).toUnit(SmartHomeUnits.AMPERE).intValue());
|
||||
}
|
||||
break;
|
||||
case SESSION_CHARGE_CONSUMPTION_LIMIT:
|
||||
key = "dwo";
|
||||
if (command instanceof DecimalType) {
|
||||
value = String.valueOf(((DecimalType) command).intValue() * 10);
|
||||
} else if (command instanceof QuantityType<?>) {
|
||||
value = String.valueOf(
|
||||
((QuantityType<Energy>) command).toUnit(SmartHomeUnits.KILOWATT_HOUR).intValue() * 10);
|
||||
}
|
||||
break;
|
||||
case ALLOW_CHARGING:
|
||||
key = "alw";
|
||||
if (command instanceof OnOffType) {
|
||||
value = command == OnOffType.ON ? "1" : "0";
|
||||
}
|
||||
break;
|
||||
case ACCESS_CONFIGURATION:
|
||||
key = "ast";
|
||||
if (command instanceof StringType) {
|
||||
switch (command.toString().toUpperCase()) {
|
||||
case "OPEN":
|
||||
value = "0";
|
||||
break;
|
||||
case "RFID":
|
||||
value = "1";
|
||||
break;
|
||||
case "AWATTAR":
|
||||
value = "2";
|
||||
break;
|
||||
case "TIMER":
|
||||
value = "3";
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
if (key != null && value != null) {
|
||||
sendData(key, value);
|
||||
} else {
|
||||
logger.warn("Could not update channel {} with key {} and value {}", channelUID.getId(), key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
config = getConfigAs(GoEChargerConfiguration.class);
|
||||
allChannels = getThing().getChannels().stream().map(channel -> channel.getUID().getId())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
updateStatus(ThingStatus.UNKNOWN);
|
||||
|
||||
startAutomaticRefresh();
|
||||
logger.debug("Finished initializing!");
|
||||
}
|
||||
|
||||
private String getUrl(String type) {
|
||||
return type.replace("%IP%", StringUtils.trimToEmpty(config.ip));
|
||||
}
|
||||
|
||||
private void sendData(String key, String value) {
|
||||
String urlStr = getUrl(GoEChargerBindingConstants.MQTT_URL).replace("%KEY%", key).replace("%VALUE%", value);
|
||||
logger.debug("POST URL = {}", urlStr);
|
||||
|
||||
try {
|
||||
ContentResponse contentResponse = httpClient.newRequest(urlStr).method(HttpMethod.POST)
|
||||
.timeout(5, TimeUnit.SECONDS).send();
|
||||
String response = contentResponse.getContentAsString();
|
||||
logger.debug("POST Response: {}", response);
|
||||
GoEStatusResponseDTO result = gson.fromJson(response, GoEStatusResponseDTO.class);
|
||||
updateChannelsAndStatus(result, null);
|
||||
} catch (InterruptedException | TimeoutException | ExecutionException | JsonSyntaxException e) {
|
||||
updateChannelsAndStatus(null, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request new data from Go-E charger
|
||||
*
|
||||
* @return the Go-E charger object mapping the JSON response or null in case of
|
||||
* error
|
||||
* @throws ExecutionException
|
||||
* @throws TimeoutException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@Nullable
|
||||
private GoEStatusResponseDTO getGoEData()
|
||||
throws InterruptedException, TimeoutException, ExecutionException, JsonSyntaxException {
|
||||
String urlStr = getUrl(GoEChargerBindingConstants.API_URL);
|
||||
logger.debug("GET URL = {}", urlStr);
|
||||
|
||||
ContentResponse contentResponse = httpClient.newRequest(urlStr).method(HttpMethod.GET)
|
||||
.timeout(5, TimeUnit.SECONDS).send();
|
||||
|
||||
String response = contentResponse.getContentAsString();
|
||||
logger.debug("GET Response: {}", response);
|
||||
return gson.fromJson(response, GoEStatusResponseDTO.class);
|
||||
}
|
||||
|
||||
private void updateChannelsAndStatus(@Nullable GoEStatusResponseDTO goeResponse, @Nullable String message) {
|
||||
if (goeResponse == null) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, message);
|
||||
allChannels.forEach(channel -> updateState(channel, UnDefType.UNDEF));
|
||||
} else {
|
||||
updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE);
|
||||
allChannels.forEach(channel -> updateState(channel, getValue(channel, goeResponse)));
|
||||
}
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
// Request new GoE data
|
||||
try {
|
||||
GoEStatusResponseDTO goeResponse = getGoEData();
|
||||
updateChannelsAndStatus(goeResponse, null);
|
||||
} catch (InterruptedException | TimeoutException | ExecutionException e) {
|
||||
updateChannelsAndStatus(null, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void startAutomaticRefresh() {
|
||||
if (refreshJob == null || refreshJob.isCancelled()) {
|
||||
GoEChargerConfiguration config = getConfigAs(GoEChargerConfiguration.class);
|
||||
int delay = config.refreshInterval.intValue();
|
||||
logger.debug("Running refresh job with delay {} s", delay);
|
||||
refreshJob = scheduler.scheduleWithFixedDelay(this::refresh, 0, delay, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
logger.debug("Disposing the Go-E Charger handler.");
|
||||
|
||||
final ScheduledFuture<?> refreshJob = this.refreshJob;
|
||||
if (refreshJob != null && !refreshJob.isCancelled()) {
|
||||
refreshJob.cancel(true);
|
||||
this.refreshJob = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<binding:binding id="goecharger" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
|
||||
|
||||
<name>Go-eCharger Binding</name>
|
||||
<description>This is the binding for Go-eCharger.</description>
|
||||
<author>Samuel Brucksch</author>
|
||||
|
||||
</binding:binding>
|
||||
@@ -0,0 +1,196 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="goecharger"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="goe">
|
||||
<label>Go-eCharger</label>
|
||||
<description>Go-eCharger thing that represents the wallbox configuration and readings</description>
|
||||
|
||||
<channels>
|
||||
<channel id="maxCurrent" typeId="current"/>
|
||||
<channel id="pwmSignal" typeId="pwm"/>
|
||||
<channel id="error" typeId="err"/>
|
||||
<channel id="voltageL1" typeId="vl1"/>
|
||||
<channel id="voltageL2" typeId="vl2"/>
|
||||
<channel id="voltageL3" typeId="vl3"/>
|
||||
<channel id="currentL1" typeId="cl1"/>
|
||||
<channel id="currentL2" typeId="cl2"/>
|
||||
<channel id="currentL3" typeId="cl3"/>
|
||||
<channel id="powerL1" typeId="pl1"/>
|
||||
<channel id="powerL2" typeId="pl2"/>
|
||||
<channel id="powerL3" typeId="pl3"/>
|
||||
<channel id="phases" typeId="pha"/>
|
||||
<channel id="sessionChargeEnergyLimit" typeId="scl"/>
|
||||
<channel id="sessionChargedEnergy" typeId="scs"/>
|
||||
<channel id="totalChargedEnergy" typeId="eto"/>
|
||||
<channel id="allowCharging" typeId="alw"/>
|
||||
<channel id="cableCurrent" typeId="cbl"/>
|
||||
<channel id="temperature" typeId="tmp"/>
|
||||
<channel id="firmware" typeId="fmw"/>
|
||||
<channel id="accessConfiguration" typeId="ast"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="ip" type="text" required="true">
|
||||
<label>IP Address</label>
|
||||
<description>The IP address of the Go-eCharger</description>
|
||||
<context>network-address</context>
|
||||
</parameter>
|
||||
<parameter name="refreshInterval" type="integer" required="false" unit="s">
|
||||
<label>Refresh Interval</label>
|
||||
<description>Refresh interval for acquiring data from Go-eCharger in seconds</description>
|
||||
<unitLabel>s</unitLabel>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
<channel-type id="ast">
|
||||
<item-type>String</item-type>
|
||||
<label>Access Configuration</label>
|
||||
<description>Currently set access configuration of the Go-eCharger</description>
|
||||
<state readOnly="false">
|
||||
<options>
|
||||
<option value="OPEN">Open</option>
|
||||
<option value="RFID">RFID</option>
|
||||
<option value="TIMER">Timer</option>
|
||||
<option value="AWATTAR">aWATTar</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="current">
|
||||
<item-type>Number:ElectricCurrent</item-type>
|
||||
<label>Maximum Current</label>
|
||||
<description>Maximum current per phase allowed to use for charging</description>
|
||||
<state pattern="%d %unit%" readOnly="false"/>
|
||||
</channel-type>
|
||||
<channel-type id="pwm">
|
||||
<item-type>String</item-type>
|
||||
<label>PWM signal status</label>
|
||||
<description>Pulse-width modulation signal status</description>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="READY_NO_CAR">Ready (no car)</option>
|
||||
<option value="CHARGING">Charging</option>
|
||||
<option value="WAITING_FOR_CAR">Waiting for car</option>
|
||||
<option value="CHARGING_DONE_CAR_CONNECTED">Charging done (car connected)</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="err">
|
||||
<item-type>String</item-type>
|
||||
<label>Error Code</label>
|
||||
<description>Error code of Go-eCharger</description>
|
||||
<state readOnly="true">
|
||||
<options>
|
||||
<option value="NONE">None</option>
|
||||
<option value="RCCB">RCCB</option>
|
||||
<option value="NO_GROUND">No ground</option>
|
||||
<option value="INTERNAL">Internal</option>
|
||||
</options>
|
||||
</state>
|
||||
</channel-type>
|
||||
<channel-type id="vl1">
|
||||
<item-type>Number:ElectricPotential</item-type>
|
||||
<label>Voltage L1</label>
|
||||
<description>Voltage on L1</description>
|
||||
<state pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="vl2">
|
||||
<item-type>Number:ElectricPotential</item-type>
|
||||
<label>Voltage L2</label>
|
||||
<description>Voltage on L2</description>
|
||||
<state pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="vl3">
|
||||
<item-type>Number:ElectricPotential</item-type>
|
||||
<label>Voltage L3</label>
|
||||
<description>Voltage on L3</description>
|
||||
<state pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="cl1">
|
||||
<item-type>Number:ElectricCurrent</item-type>
|
||||
<label>Current L1</label>
|
||||
<description>Current on L1</description>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="cl2">
|
||||
<item-type>Number:ElectricCurrent</item-type>
|
||||
<label>Current L2</label>
|
||||
<description>Current on L2</description>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="cl3">
|
||||
<item-type>Number:ElectricCurrent</item-type>
|
||||
<label>Current L3</label>
|
||||
<description>Current on L3</description>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="pl1">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>Power L1</label>
|
||||
<description>Power on L1</description>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="pl2">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>Power L2</label>
|
||||
<description>Power on L2</description>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="pl3">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>Power L3</label>
|
||||
<description>Power on L3</description>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="pha">
|
||||
<item-type>Number</item-type>
|
||||
<label>Phases</label>
|
||||
<description>Amount of phases currently used for charging</description>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="scl">
|
||||
<item-type>Number:Energy</item-type>
|
||||
<label>Current Session Charge Energy Limit</label>
|
||||
<description>Wallbox stops charging after defined value, deactivate with value 0</description>
|
||||
<state pattern="%.1f %unit%" readOnly="false"/>
|
||||
</channel-type>
|
||||
<channel-type id="scs">
|
||||
<item-type>Number:Energy</item-type>
|
||||
<label>Current Session Charged Energy</label>
|
||||
<description>Amount of energy that has been charged in this session</description>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="eto">
|
||||
<item-type>Number:Energy</item-type>
|
||||
<label>Total Charged Energy</label>
|
||||
<description>Amount of energy that has been charged since installation</description>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="alw">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Allow Charging</label>
|
||||
<description>If true charging is allowed</description>
|
||||
<state readOnly="false"/>
|
||||
</channel-type>
|
||||
<channel-type id="cbl">
|
||||
<item-type>Number:ElectricCurrent</item-type>
|
||||
<label>Cable Encoding</label>
|
||||
<description>Specifies the max amps that can be charged with that cable</description>
|
||||
<state pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="tmp">
|
||||
<item-type>Number:Temperature</item-type>
|
||||
<label>Temperature</label>
|
||||
<description>Temperature of the Go-eCharger</description>
|
||||
<state pattern="%d %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="fmw">
|
||||
<item-type>String</item-type>
|
||||
<label>Firmware</label>
|
||||
<description>Firmware Version</description>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
Reference in New Issue
Block a user