]> git.basschouten.com Git - openhab-addons.git/commitdiff
[netatmo] Consider timezone of the house when defining the end time of a setpoint...
authorGaël L'hopital <gael@lhopital.org>
Mon, 21 Oct 2024 18:32:01 +0000 (20:32 +0200)
committerGitHub <noreply@github.com>
Mon, 21 Oct 2024 18:32:01 +0000 (20:32 +0200)
* Consider timezone of the house when defining the end time of a setpoint

Signed-off-by: Gaël L'hopital <gael@lhopital.org>
bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/NetatmoHandlerFactory.java
bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/HomeData.java
bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/LocationEx.java
bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/Place.java
bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/CommonInterface.java
bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/DeviceHandler.java
bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/ModuleHandler.java
bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/DeviceCapability.java
bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/EnergyCapability.java
bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/HomeCapability.java
bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/channelhelper/EnergyChannelHelper.java

index 9af2f0ad26903acb193f047a1ab30bea256fd05a..031595a9ed6b12a7b8a2bbb12eea3aeba6b5a46f 100644 (file)
@@ -47,6 +47,7 @@ import org.openhab.binding.netatmo.internal.handler.channelhelper.ChannelHelper;
 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;
@@ -80,17 +81,19 @@ public class NetatmoHandlerFactory extends BaseThingHandlerFactory {
     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);
     }
 
@@ -119,7 +122,8 @@ public class NetatmoHandlerFactory extends BaseThingHandlerFactory {
             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<>();
 
@@ -127,6 +131,7 @@ public class NetatmoHandlerFactory extends BaseThingHandlerFactory {
 
         moduleType.capabilities.forEach(capability -> {
             Capability newCap = null;
+
             if (capability == DeviceCapability.class) {
                 newCap = new DeviceCapability(handler);
             } else if (capability == AirCareCapability.class) {
@@ -161,7 +166,7 @@ public class NetatmoHandlerFactory extends BaseThingHandlerFactory {
             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);
             }
         });
 
index e28a4a9a8216e240408f11e82a8ab1d3ab77d291..f19ab05fca68325c75fe7c24c289e1d3cd95054a 100644 (file)
@@ -12,6 +12,7 @@
  */
 package org.openhab.binding.netatmo.internal.api.dto;
 
+import java.time.Duration;
 import java.util.List;
 import java.util.Optional;
 import java.util.Set;
@@ -59,8 +60,8 @@ public class HomeData extends NAThing implements NAModule, LocationEx {
         private int thermSetpointDefaultDuration;
         private List<ThermProgram> schedules = List.of();
 
-        public int getThermSetpointDefaultDuration() {
-            return thermSetpointDefaultDuration;
+        public Duration getSetpointDefaultDuration() {
+            return Duration.ofMinutes(thermSetpointDefaultDuration);
         }
 
         public SetpointMode getThermMode() {
@@ -109,8 +110,8 @@ public class HomeData extends NAThing implements NAModule, LocationEx {
     }
 
     @Override
-    public Optional<String> getTimezone() {
-        return Optional.ofNullable(timezone);
+    public @Nullable String getTimezone() {
+        return timezone;
     }
 
     public NAObjectMap<HomeDataRoom> getRooms() {
index d3ca9a7ec41a228dea5e0cd045d037c9a7b6a42e..b6e60eba432db8c517487a74a2dbff3613c54dd8 100644 (file)
  */
 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
@@ -26,5 +29,17 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
 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;
+    }
 }
index f391f38ec3913cece6b7d86248543018616bbedb..b0855df2d57f37659e609b8108b84367e7abe376 100644 (file)
@@ -42,8 +42,8 @@ public class Place implements LocationEx {
     }
 
     @Override
-    public Optional<String> getTimezone() {
-        return Optional.ofNullable(timezone);
+    public @Nullable String getTimezone() {
+        return timezone;
     }
 
     @Override
index aac0f4b00413312785cb3fa92b323f06fb29041f..68ff8086ef973ef12cf7cd8a9c5941e923951095 100644 (file)
@@ -13,6 +13,7 @@
 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;
@@ -83,6 +84,8 @@ public interface CommonInterface {
     @Nullable
     Bridge getBridge();
 
+    ZoneId getSystemTimeZone();
+
     default @Nullable CommonInterface getBridgeHandler() {
         Bridge bridge = getBridge();
         return bridge != null && bridge.getHandler() instanceof DeviceHandler ? (DeviceHandler) bridge.getHandler()
index 61b60c6ddfd63dc48e7f7e0503afb932323414a0..5db67fba77ad8fb4c97db733b3f7f7689d077d38 100644 (file)
  */
 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;
@@ -39,10 +41,12 @@ import org.slf4j.LoggerFactory;
 @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
@@ -118,4 +122,9 @@ public class DeviceHandler extends BaseBridgeHandler implements CommonInterface
     public ScheduledExecutorService getScheduler() {
         return scheduler;
     }
+
+    @Override
+    public ZoneId getSystemTimeZone() {
+        return timeZoneProvider.getTimeZone();
+    }
 }
index ab8625fc1fad757edbcd944d8ca56a66739b6efa..9c9a99cbc95ef8686556f7c5dcbfc08f291cdb9d 100644 (file)
@@ -12,6 +12,7 @@
  */
 package org.openhab.binding.netatmo.internal.handler;
 
+import java.time.ZoneId;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -20,6 +21,7 @@ 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;
@@ -43,10 +45,12 @@ import org.slf4j.LoggerFactory;
 @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
@@ -129,4 +133,9 @@ public class ModuleHandler extends BaseThingHandler implements CommonInterface {
     public ScheduledExecutorService getScheduler() {
         return scheduler;
     }
+
+    @Override
+    public ZoneId getSystemTimeZone() {
+        return timeZoneProvider.getTimeZone();
+    }
 }
index f132c730310a37ea6c1ccf4b0dd23867ca880a8c..eb52da6a7d4dbedabb7f3d1ac525359856eccd08 100644 (file)
@@ -47,7 +47,7 @@ public class DeviceCapability extends Capability {
             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)) {
index 50299eff8bb2fdd97652320266de8fcfd76f03ce..1cdfd5d50422e647737652c2c04754d1b9f863b8 100644 (file)
@@ -14,6 +14,7 @@ package org.openhab.binding.netatmo.internal.handler.capability;
 
 import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*;
 
+import java.time.Duration;
 import java.time.ZonedDateTime;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -48,7 +49,7 @@ public class EnergyCapability extends RestCapability<EnergyApi> {
     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) {
@@ -79,7 +80,7 @@ public class EnergyCapability extends RestCapability<EnergyApi> {
             });
             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();
         }
     }
 
@@ -157,6 +158,10 @@ public class EnergyCapability extends RestCapability<EnergyApi> {
     }
 
     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);
     }
 }
index d15646ea341b3cad7a655a1d74fa06c1b7e1fd8d..2089dfe6f71a85896f44a4aa9973f31c728da227 100644 (file)
@@ -15,6 +15,7 @@ package org.openhab.binding.netatmo.internal.handler.capability;
 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;
@@ -44,12 +45,13 @@ import org.slf4j.LoggerFactory;
  */
 @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;
@@ -88,7 +90,8 @@ public class HomeCapability extends CacheCapability<HomeApi> {
                 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(",")));
index fb5352ec015a7e122131b0a9627e8c577a4b6957..f2cb35fcbb600562a4ef8d8ba8e2d487819702ed 100644 (file)
@@ -55,7 +55,7 @@ public class EnergyChannelHelper extends ChannelHelper {
             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: