import org.openhab.binding.netatmo.internal.providers.NetatmoDescriptionProvider;
import org.openhab.core.auth.client.oauth2.OAuthFactory;
import org.openhab.core.config.core.ConfigParser;
+import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.io.net.http.HttpClientFactory;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Thing;
private final HttpClient httpClient;
private final HttpService httpService;
private final OAuthFactory oAuthFactory;
+ private final TimeZoneProvider timeZoneProvider;
@Activate
public NetatmoHandlerFactory(final @Reference NetatmoDescriptionProvider stateDescriptionProvider,
final @Reference HttpClientFactory factory, final @Reference NADeserializer deserializer,
final @Reference HttpService httpService, final @Reference OAuthFactory oAuthFactory,
- Map<String, @Nullable Object> config) {
+ final @Reference TimeZoneProvider timeZoneProvider, Map<String, @Nullable Object> config) {
this.stateDescriptionProvider = stateDescriptionProvider;
this.httpClient = factory.getCommonHttpClient();
this.deserializer = deserializer;
this.httpService = httpService;
this.oAuthFactory = oAuthFactory;
+ this.timeZoneProvider = timeZoneProvider;
configChanged(config);
}
return new ApiBridgeHandler((Bridge) thing, httpClient, deserializer, configuration, httpService,
oAuthFactory);
}
- CommonInterface handler = moduleType.isABridge() ? new DeviceHandler((Bridge) thing) : new ModuleHandler(thing);
+ CommonInterface handler = moduleType.isABridge() ? new DeviceHandler((Bridge) thing, timeZoneProvider)
+ : new ModuleHandler(thing, timeZoneProvider);
List<ChannelHelper> helpers = new ArrayList<>();
moduleType.capabilities.forEach(capability -> {
Capability newCap = null;
+
if (capability == DeviceCapability.class) {
newCap = new DeviceCapability(handler);
} else if (capability == AirCareCapability.class) {
if (newCap != null) {
handler.getCapabilities().put(newCap);
} else {
- logger.warn("No factory entry defined to create Capability : {}", capability);
+ logger.warn("No factory entry defined to create Capability: {}", capability);
}
});
*/
package org.openhab.binding.netatmo.internal.api.dto;
+import java.time.Duration;
import java.util.List;
import java.util.Optional;
import java.util.Set;
private int thermSetpointDefaultDuration;
private List<ThermProgram> schedules = List.of();
- public int getThermSetpointDefaultDuration() {
- return thermSetpointDefaultDuration;
+ public Duration getSetpointDefaultDuration() {
+ return Duration.ofMinutes(thermSetpointDefaultDuration);
}
public SetpointMode getThermMode() {
}
@Override
- public Optional<String> getTimezone() {
- return Optional.ofNullable(timezone);
+ public @Nullable String getTimezone() {
+ return timezone;
}
public NAObjectMap<HomeDataRoom> getRooms() {
*/
package org.openhab.binding.netatmo.internal.api.dto;
+import java.time.DateTimeException;
+import java.time.ZoneId;
import java.util.Optional;
import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
/**
* The {@link LocationEx} is the common interface for dto holding an extra location data
public interface LocationEx extends Location {
Optional<String> getCountry();
- Optional<String> getTimezone();
+ @Nullable
+ String getTimezone();
+
+ public default ZoneId getZoneId(ZoneId fallback) {
+ String local = getTimezone();
+ if (local != null) {
+ try {
+ return ZoneId.of(local);
+ } catch (DateTimeException ignore) {
+ }
+ }
+ return fallback;
+ }
}
}
@Override
- public Optional<String> getTimezone() {
- return Optional.ofNullable(timezone);
+ public @Nullable String getTimezone() {
+ return timezone;
}
@Override
package org.openhab.binding.netatmo.internal.handler;
import java.time.Duration;
+import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Nullable
Bridge getBridge();
+ ZoneId getSystemTimeZone();
+
default @Nullable CommonInterface getBridgeHandler() {
Bridge bridge = getBridge();
return bridge != null && bridge.getHandler() instanceof DeviceHandler ? (DeviceHandler) bridge.getHandler()
*/
package org.openhab.binding.netatmo.internal.handler;
+import java.time.ZoneId;
import java.util.concurrent.ScheduledExecutorService;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.netatmo.internal.handler.capability.CapabilityMap;
+import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
@NonNullByDefault
public class DeviceHandler extends BaseBridgeHandler implements CommonInterface {
private final Logger logger = LoggerFactory.getLogger(DeviceHandler.class);
- private CapabilityMap capabilities = new CapabilityMap();
+ private final CapabilityMap capabilities = new CapabilityMap();
+ private final TimeZoneProvider timeZoneProvider;
- public DeviceHandler(Bridge bridge) {
+ public DeviceHandler(Bridge bridge, TimeZoneProvider timeZoneProvider) {
super(bridge);
+ this.timeZoneProvider = timeZoneProvider;
}
@Override
public ScheduledExecutorService getScheduler() {
return scheduler;
}
+
+ @Override
+ public ZoneId getSystemTimeZone() {
+ return timeZoneProvider.getTimeZone();
+ }
}
*/
package org.openhab.binding.netatmo.internal.handler;
+import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.netatmo.internal.handler.capability.CapabilityMap;
+import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
@NonNullByDefault
public class ModuleHandler extends BaseThingHandler implements CommonInterface {
private final Logger logger = LoggerFactory.getLogger(ModuleHandler.class);
- private CapabilityMap capabilities = new CapabilityMap();
+ private final CapabilityMap capabilities = new CapabilityMap();
+ private final TimeZoneProvider timeZoneProvider;
- public ModuleHandler(Thing thing) {
+ public ModuleHandler(Thing thing, TimeZoneProvider timeZoneProvider) {
super(thing);
+ this.timeZoneProvider = timeZoneProvider;
}
@Override
public ScheduledExecutorService getScheduler() {
return scheduler;
}
+
+ @Override
+ public ZoneId getSystemTimeZone() {
+ return timeZoneProvider.getTimeZone();
+ }
}
newData.getPlace().ifPresent(place -> {
place.getCity().map(city -> properties.put(PROPERTY_CITY, city));
place.getCountry().map(country -> properties.put(PROPERTY_COUNTRY, country));
- place.getTimezone().map(tz -> properties.put(PROPERTY_TIMEZONE, tz));
+ properties.put(PROPERTY_TIMEZONE, place.getZoneId(handler.getSystemTimeZone()).toString());
});
}
if (!newData.hasFreshData(DATA_AGE_LIMIT_S)) {
import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*;
+import java.time.Duration;
import java.time.ZonedDateTime;
import org.eclipse.jdt.annotation.NonNullByDefault;
private final Logger logger = LoggerFactory.getLogger(EnergyCapability.class);
private final NetatmoDescriptionProvider descriptionProvider;
- private int setPointDefaultDuration = -1;
+ private Duration setPointDefaultDuration = Duration.ofMinutes(120);
private String energyId = "";
EnergyCapability(CommonInterface handler, NetatmoDescriptionProvider descriptionProvider) {
});
descriptionProvider.setStateOptions(new ChannelUID(thingUID, GROUP_ENERGY, CHANNEL_PLANNING),
energyData.getThermSchedules().stream().map(p -> new StateOption(p.getId(), p.getName())).toList());
- setPointDefaultDuration = energyData.getThermSetpointDefaultDuration();
+ setPointDefaultDuration = energyData.getSetpointDefaultDuration();
}
}
}
private long setpointEndTimeFromNow() {
- return ZonedDateTime.now().plusMinutes(setPointDefaultDuration).toEpochSecond();
+ return handler.getHomeCapability(HomeCapability.class).map(cap -> {
+ ZonedDateTime now = ZonedDateTime.now().plus(setPointDefaultDuration);
+ now = now.withZoneSameInstant(cap.zoneId);
+ return now.toEpochSecond();
+ }).orElse(-1l);
}
}
import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*;
import java.time.Duration;
+import java.time.ZoneId;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
*/
@NonNullByDefault
public class HomeCapability extends CacheCapability<HomeApi> {
-
private final Logger logger = LoggerFactory.getLogger(HomeCapability.class);
private final Set<FeatureArea> featureAreas = new HashSet<>();
private final NetatmoDescriptionProvider descriptionProvider;
private final Set<String> homeIds = new HashSet<>(3);
+ protected ZoneId zoneId = ZoneId.systemDefault();
+
public HomeCapability(CommonInterface handler, NetatmoDescriptionProvider descriptionProvider) {
super(handler, Duration.ofSeconds(2), HomeApi.class);
this.descriptionProvider = descriptionProvider;
handler.removeChannels(thing.getChannelsOfGroup(GROUP_ENERGY));
}
home.getCountry().map(country -> properties.put(PROPERTY_COUNTRY, country));
- home.getTimezone().map(tz -> properties.put(PROPERTY_TIMEZONE, tz));
+ zoneId = home.getZoneId(handler.getSystemTimeZone());
+ properties.put(PROPERTY_TIMEZONE, zoneId.toString());
properties.put(GROUP_LOCATION, ((Location) home).getLocation().toString());
properties.put(PROPERTY_FEATURE,
featureAreas.stream().map(FeatureArea::name).collect(Collectors.joining(",")));
ThermProgram currentProgram = energyData.getActiveProgram();
switch (channelId) {
case CHANNEL_SETPOINT_DURATION:
- return toQuantityType(energyData.getThermSetpointDefaultDuration(), Units.MINUTE);
+ return toQuantityType(energyData.getSetpointDefaultDuration().getSeconds(), Units.SECOND);
case CHANNEL_PLANNING:
return (currentProgram != null ? toStringType(currentProgram.getName()) : null);
case CHANNEL_SETPOINT_END_TIME: