[evcc] Charge Plan Time is not converted to correct Timezone (#17620) (#17640)

Signed-off-by: Laith Budairi <laith.budairi@exalt.ps>
Signed-off-by: Ciprian Pascu <contact@ciprianpascu.ro>
This commit is contained in:
Laith-Budairi 2024-10-28 11:21:03 +02:00 committed by Ciprian Pascu
parent d24333aa52
commit f13c5c5072
3 changed files with 27 additions and 6 deletions

View File

@ -33,6 +33,7 @@ import org.openhab.binding.evcc.internal.api.dto.PV;
import org.openhab.binding.evcc.internal.api.dto.Plan; import org.openhab.binding.evcc.internal.api.dto.Plan;
import org.openhab.binding.evcc.internal.api.dto.Result; import org.openhab.binding.evcc.internal.api.dto.Result;
import org.openhab.binding.evcc.internal.api.dto.Vehicle; import org.openhab.binding.evcc.internal.api.dto.Vehicle;
import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.library.CoreItemFactory; import org.openhab.core.library.CoreItemFactory;
import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.DecimalType;
@ -66,6 +67,7 @@ import org.slf4j.LoggerFactory;
@NonNullByDefault @NonNullByDefault
public class EvccHandler extends BaseThingHandler { public class EvccHandler extends BaseThingHandler {
private final Logger logger = LoggerFactory.getLogger(EvccHandler.class); private final Logger logger = LoggerFactory.getLogger(EvccHandler.class);
private final TimeZoneProvider timeZoneProvider;
private @Nullable EvccAPI evccAPI; private @Nullable EvccAPI evccAPI;
private @Nullable ScheduledFuture<?> statePollingJob; private @Nullable ScheduledFuture<?> statePollingJob;
@ -79,8 +81,9 @@ public class EvccHandler extends BaseThingHandler {
Map<String, Triple<Boolean, Float, ZonedDateTime>> vehiclePlans = new HashMap<>(); Map<String, Triple<Boolean, Float, ZonedDateTime>> vehiclePlans = new HashMap<>();
public EvccHandler(Thing thing) { public EvccHandler(Thing thing, TimeZoneProvider timeZoneProvider) {
super(thing); super(thing);
this.timeZoneProvider = timeZoneProvider;
} }
@Override @Override
@ -376,7 +379,7 @@ public class EvccHandler extends BaseThingHandler {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR, updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR,
"@text/offline.configuration-error.no-host"); "@text/offline.configuration-error.no-host");
} else { } else {
this.evccAPI = new EvccAPI(url); this.evccAPI = new EvccAPI(url, timeZoneProvider);
logger.debug("Setting up refresh job ..."); logger.debug("Setting up refresh job ...");
statePollingJob = scheduler.scheduleWithFixedDelay(this::refresh, 0, config.refreshInterval, statePollingJob = scheduler.scheduleWithFixedDelay(this::refresh, 0, config.refreshInterval,
TimeUnit.SECONDS); TimeUnit.SECONDS);

View File

@ -18,12 +18,15 @@ import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.thing.Thing; import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID; import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.binding.BaseThingHandlerFactory; import org.openhab.core.thing.binding.BaseThingHandlerFactory;
import org.openhab.core.thing.binding.ThingHandler; import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.core.thing.binding.ThingHandlerFactory; 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.Component;
import org.osgi.service.component.annotations.Reference;
/** /**
* The {@link EvccHandlerFactory} is responsible for creating things and thing * The {@link EvccHandlerFactory} is responsible for creating things and thing
@ -37,6 +40,13 @@ public class EvccHandlerFactory extends BaseThingHandlerFactory {
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_DEVICE); private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_DEVICE);
private final TimeZoneProvider timeZoneProvider;
@Activate
public EvccHandlerFactory(final @Reference TimeZoneProvider timeZoneProvider) {
this.timeZoneProvider = timeZoneProvider;
}
@Override @Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) { public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID); return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
@ -47,7 +57,7 @@ public class EvccHandlerFactory extends BaseThingHandlerFactory {
ThingTypeUID thingTypeUID = thing.getThingTypeUID(); ThingTypeUID thingTypeUID = thing.getThingTypeUID();
if (THING_TYPE_DEVICE.equals(thingTypeUID)) { if (THING_TYPE_DEVICE.equals(thingTypeUID)) {
return new EvccHandler(thing); return new EvccHandler(thing, timeZoneProvider);
} }
return null; return null;

View File

@ -16,12 +16,14 @@ import static org.openhab.binding.evcc.internal.EvccBindingConstants.EVCC_REST_A
import static org.openhab.binding.evcc.internal.EvccBindingConstants.LONG_CONNECTION_TIMEOUT_MILLISEC; import static org.openhab.binding.evcc.internal.EvccBindingConstants.LONG_CONNECTION_TIMEOUT_MILLISEC;
import java.io.IOException; import java.io.IOException;
import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.evcc.internal.api.dto.Result; import org.openhab.binding.evcc.internal.api.dto.Result;
import org.openhab.binding.evcc.internal.api.dto.Status; import org.openhab.binding.evcc.internal.api.dto.Status;
import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.io.net.http.HttpUtil; import org.openhab.core.io.net.http.HttpUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -40,10 +42,12 @@ import com.google.gson.JsonSyntaxException;
public class EvccAPI { public class EvccAPI {
private final Logger logger = LoggerFactory.getLogger(EvccAPI.class); private final Logger logger = LoggerFactory.getLogger(EvccAPI.class);
private final Gson gson = new Gson(); private final Gson gson = new Gson();
private final TimeZoneProvider timeZoneProvider;
private String host; private String host;
public EvccAPI(String host) { public EvccAPI(String host, TimeZoneProvider timeZoneProvider) {
this.host = (host.endsWith("/") ? host.substring(0, host.length() - 1) : host); this.host = (host.endsWith("/") ? host.substring(0, host.length() - 1) : host);
this.timeZoneProvider = timeZoneProvider;
} }
/** /**
@ -144,8 +148,12 @@ public class EvccAPI {
} }
public String setVehiclePlan(String vehicleName, int planSoC, ZonedDateTime planTime) throws EvccApiException { public String setVehiclePlan(String vehicleName, int planSoC, ZonedDateTime planTime) throws EvccApiException {
return httpRequest(this.host + EVCC_REST_API + "vehicles/" + vehicleName + "/plan/soc/" + planSoC + "/" ZoneId zoneId = timeZoneProvider.getTimeZone();
+ planTime.toLocalDateTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) + "Z", "POST"); ZonedDateTime adjustedTime = planTime.withZoneSameInstant(zoneId);
String formattedTime = adjustedTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
return httpRequest(
this.host + EVCC_REST_API + "vehicles/" + vehicleName + "/plan/soc/" + planSoC + "/" + formattedTime,
"POST");
} }
public String removeVehiclePlan(String vehicleName) throws EvccApiException { public String removeVehiclePlan(String vehicleName) throws EvccApiException {