diff --git a/bundles/org.openhab.binding.netatmo/README.md b/bundles/org.openhab.binding.netatmo/README.md index 93fe27c99f2..6cd14ea6e8e 100644 --- a/bundles/org.openhab.binding.netatmo/README.md +++ b/bundles/org.openhab.binding.netatmo/README.md @@ -460,6 +460,7 @@ The Home thing has the following configuration elements: | securityId | String | No | Id of a home holding security monitoring devices | At least one of these parameter must be filled - at most two : + * id or securityId * id or energyId * securityId and energyId diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/SecurityApi.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/SecurityApi.java index 8acaef8c72e..1b82c00f983 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/SecurityApi.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/SecurityApi.java @@ -18,7 +18,6 @@ import java.net.URI; import java.time.ZonedDateTime; import java.util.Comparator; import java.util.List; -import java.util.stream.Collectors; import javax.ws.rs.core.UriBuilder; @@ -94,7 +93,7 @@ public class SecurityApi extends RestManager { // Remove unneeded events being before oldestKnown return events.stream().filter(event -> freshestEventTime == null || event.getTime().isAfter(freshestEventTime)) - .sorted(Comparator.comparing(HomeEvent::getTime).reversed()).collect(Collectors.toList()); + .sorted(Comparator.comparing(HomeEvent::getTime).reversed()).toList(); } public List getPersonEvents(String homeId, String personId) throws NetatmoException { diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/data/EventSubType.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/data/EventSubType.java index 7cf497e66c8..44748ffc103 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/data/EventSubType.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/data/EventSubType.java @@ -43,6 +43,8 @@ public enum EventSubType { BATTERY_VERY_LOW(1, EventType.BATTERY_STATUS), SMOKE_CLEARED(0, EventType.SMOKE), SMOKE_DETECTED(1, EventType.SMOKE), + HUSH_ACTIVATED(0, EventType.HUSH), + HUSH_DEACTIVATED(1, EventType.HUSH), SOUND_TEST_OK(0, EventType.SOUND_TEST), SOUND_TEST_ERROR(1, EventType.SOUND_TEST), DETECTOR_READY(0, EventType.TAMPERED), diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/data/EventType.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/data/EventType.java index dfb8de510a7..c7ff566c7de 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/data/EventType.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/data/EventType.java @@ -28,6 +28,8 @@ import com.google.gson.annotations.SerializedName; @NonNullByDefault public enum EventType { UNKNOWN(), + @SerializedName("webhook_activation") // Ack of a 'webhook set' Api Call + WEBHOOK_ACTIVATION(ModuleType.ACCOUNT), @SerializedName("person") // When the Indoor Camera detects a face PERSON(ModuleType.PERSON, ModuleType.WELCOME), @@ -71,6 +73,15 @@ public enum EventType { @SerializedName("module_end_update") // Module's firmware update is over MODULE_END_UPDATE(ModuleType.WELCOME), + @SerializedName("tag_big_move") // Module's firmware update is over + TAG_BIG_MOVE(ModuleType.WELCOME), + + @SerializedName("tag_open") // Module's firmware update is over + TAG_OPEN(ModuleType.WELCOME), + + @SerializedName("tag_small_move") // Module's firmware update is over + TAG_SMALL_MOVE(ModuleType.WELCOME), + @SerializedName("connection") // When the camera connects to Netatmo servers CONNECTION(ModuleType.WELCOME, ModuleType.PRESENCE), diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/HomeData.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/HomeData.java index 78cc04350e2..0a971c6b8df 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/HomeData.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/HomeData.java @@ -38,17 +38,50 @@ public class HomeData extends NAThing implements NAModule, LocationEx { public class HomesDataResponse extends ApiResponse> { } + public class Security extends HomeData { + private NAObjectMap persons = new NAObjectMap<>(); + + public NAObjectMap getPersons() { + return persons; + } + + public List getKnownPersons() { + return persons.values().stream().filter(HomeDataPerson::isKnown).toList(); + } + } + + public class Energy extends HomeData { + private String temperatureControlMode = ""; + private SetpointMode thermMode = SetpointMode.UNKNOWN; + private int thermSetpointDefaultDuration; + private List schedules = List.of(); + + public int getThermSetpointDefaultDuration() { + return thermSetpointDefaultDuration; + } + + public SetpointMode getThermMode() { + return thermMode; + } + + public String getTemperatureControlMode() { + return temperatureControlMode; + } + + public List getThermSchedules() { + return schedules; + } + + public @Nullable ThermProgram getActiveProgram() { + return schedules.stream().filter(ThermProgram::isSelected).findFirst().orElse(null); + } + } + private double altitude; private double[] coordinates = {}; private @Nullable String country; private @Nullable String timezone; - private @Nullable String temperatureControlMode; - private SetpointMode thermMode = SetpointMode.UNKNOWN; - private int thermSetpointDefaultDuration; - private List schedules = List.of(); - - private NAObjectMap persons = new NAObjectMap<>(); private NAObjectMap rooms = new NAObjectMap<>(); private NAObjectMap modules = new NAObjectMap<>(); @@ -77,26 +110,6 @@ public class HomeData extends NAThing implements NAModule, LocationEx { return Optional.ofNullable(timezone); } - public int getThermSetpointDefaultDuration() { - return thermSetpointDefaultDuration; - } - - public SetpointMode getThermMode() { - return thermMode; - } - - public NAObjectMap getPersons() { - return persons; - } - - public List getKnownPersons() { - return persons.values().stream().filter(HomeDataPerson::isKnown).collect(Collectors.toList()); - } - - public Optional getTemperatureControlMode() { - return Optional.ofNullable(temperatureControlMode); - } - public NAObjectMap getRooms() { return rooms; } @@ -108,12 +121,4 @@ public class HomeData extends NAThing implements NAModule, LocationEx { public Set getFeatures() { return getModules().values().stream().map(m -> m.getType().feature).collect(Collectors.toSet()); } - - public List getThermSchedules() { - return schedules; - } - - public @Nullable ThermProgram getActiveProgram() { - return schedules.stream().filter(ThermProgram::isSelected).findFirst().orElse(null); - } } diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/HomeStatusPerson.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/HomeStatusPerson.java index 17d02300895..8ede32652e7 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/HomeStatusPerson.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/HomeStatusPerson.java @@ -31,7 +31,7 @@ public class HomeStatusPerson extends NAThing { return ModuleType.PERSON; } - public boolean isOutOfSight() { - return outOfSight; + public boolean atHome() { + return !outOfSight; } } diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/NAHomeStatus.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/NAHomeStatus.java index c7a18ec075c..f13e2d97644 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/NAHomeStatus.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/api/dto/NAHomeStatus.java @@ -32,22 +32,26 @@ public class NAHomeStatus { public class HomeStatus extends NAThing { private @Nullable NAObjectMap modules; - private @Nullable NAObjectMap persons; - private @Nullable NAObjectMap rooms; public NAObjectMap getModules() { NAObjectMap localModules = modules; return localModules != null ? localModules : new NAObjectMap<>(); } + } - public NAObjectMap getPersons() { - NAObjectMap localPersons = persons; - return localPersons != null ? localPersons : new NAObjectMap<>(); - } + public class Energy extends HomeStatus { + private NAObjectMap rooms = new NAObjectMap<>(); public NAObjectMap getRooms() { - NAObjectMap localRooms = rooms; - return localRooms != null ? localRooms : new NAObjectMap<>(); + return rooms; + } + } + + public class Security extends HomeStatus { + private NAObjectMap persons = new NAObjectMap<>(); + + public NAObjectMap getPersons() { + return persons; } } diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/deserialization/NADeserializer.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/deserialization/NADeserializer.java index 4213b18bdcb..93c931d3c15 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/deserialization/NADeserializer.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/deserialization/NADeserializer.java @@ -19,6 +19,9 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.netatmo.internal.api.NetatmoException; import org.openhab.binding.netatmo.internal.api.data.ModuleType; +import org.openhab.binding.netatmo.internal.api.dto.HomeData; +import org.openhab.binding.netatmo.internal.api.dto.NAHomeStatus; +import org.openhab.binding.netatmo.internal.api.dto.NAHomeStatus.HomeStatus; import org.openhab.core.i18n.TimeZoneProvider; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OpenClosedType; @@ -49,22 +52,26 @@ public class NADeserializer { .registerTypeAdapter(NAObjectMap.class, new NAObjectMapDeserializer()) .registerTypeAdapter(NAPushType.class, new NAPushTypeDeserializer()) .registerTypeAdapter(ModuleType.class, new ModuleTypeDeserializer()) - .registerTypeAdapter(ZonedDateTime.class, - (JsonDeserializer) (json, type, jsonDeserializationContext) -> { - long netatmoTS = json.getAsJsonPrimitive().getAsLong(); - Instant i = Instant.ofEpochSecond(netatmoTS); - return ZonedDateTime.ofInstant(i, timeZoneProvider.getTimeZone()); - }) + .registerTypeAdapter(HomeStatus.class, + (JsonDeserializer) (json, type, context) -> context.deserialize(json, + json.getAsJsonObject().has("persons") ? NAHomeStatus.Security.class + : NAHomeStatus.Energy.class)) + .registerTypeAdapter(HomeData.class, + (JsonDeserializer) (json, type, context) -> context.deserialize(json, + json.getAsJsonObject().has("therm_mode") ? HomeData.Energy.class + : HomeData.Security.class)) + .registerTypeAdapter(ZonedDateTime.class, (JsonDeserializer) (json, type, context) -> { + long netatmoTS = json.getAsJsonPrimitive().getAsLong(); + Instant i = Instant.ofEpochSecond(netatmoTS); + return ZonedDateTime.ofInstant(i, timeZoneProvider.getTimeZone()); + }) .registerTypeAdapter(OnOffType.class, - (JsonDeserializer) (json, type, jsonDeserializationContext) -> OnOffType + (JsonDeserializer) (json, type, context) -> OnOffType .from(json.getAsJsonPrimitive().getAsString())) - .registerTypeAdapter(OpenClosedType.class, - (JsonDeserializer) (json, type, jsonDeserializationContext) -> { - String value = json.getAsJsonPrimitive().getAsString().toUpperCase(); - return "TRUE".equals(value) || "1".equals(value) ? OpenClosedType.CLOSED - : OpenClosedType.OPEN; - }) - .create(); + .registerTypeAdapter(OpenClosedType.class, (JsonDeserializer) (json, type, context) -> { + String value = json.getAsJsonPrimitive().getAsString().toUpperCase(); + return "TRUE".equals(value) || "1".equals(value) ? OpenClosedType.CLOSED : OpenClosedType.OPEN; + }).create(); } public T deserialize(Class clazz, String json) throws NetatmoException { diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/deserialization/NAPushTypeDeserializer.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/deserialization/NAPushTypeDeserializer.java index 69767428b6d..d552ddea868 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/deserialization/NAPushTypeDeserializer.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/deserialization/NAPushTypeDeserializer.java @@ -32,6 +32,7 @@ import com.google.gson.JsonElement; */ @NonNullByDefault class NAPushTypeDeserializer implements JsonDeserializer { + private final Logger logger = LoggerFactory.getLogger(NAPushTypeDeserializer.class); @Override @@ -40,15 +41,19 @@ class NAPushTypeDeserializer implements JsonDeserializer { final String[] elements = string.split("-"); ModuleType moduleType = ModuleType.UNKNOWN; EventType eventType = EventType.UNKNOWN; + if (elements.length == 2) { moduleType = fromNetatmoObject(elements[0]); eventType = fromEvent(elements[1]); - } else { - logger.warn("Unexpected syntax received for push_type field : {}", string); + } else if (elements.length == 1) { + moduleType = ModuleType.ACCOUNT; + eventType = fromEvent(string); } + if (moduleType.equals(ModuleType.UNKNOWN) || eventType.equals(EventType.UNKNOWN)) { logger.warn("Unknown module or event type : {}, deserialized to '{}-{}'", string, moduleType, eventType); } + return new NAPushType(moduleType, eventType); } diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/ApiBridgeHandler.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/ApiBridgeHandler.java index 9e7ad42a396..c3b82096946 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/ApiBridgeHandler.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/ApiBridgeHandler.java @@ -61,6 +61,7 @@ import org.openhab.binding.netatmo.internal.api.WeatherApi; import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.FeatureArea; import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.Scope; import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.ServiceError; +import org.openhab.binding.netatmo.internal.api.dto.HomeData; import org.openhab.binding.netatmo.internal.api.dto.HomeDataModule; import org.openhab.binding.netatmo.internal.api.dto.NAMain; import org.openhab.binding.netatmo.internal.api.dto.NAModule; @@ -395,8 +396,9 @@ public class ApiBridgeHandler extends BaseBridgeHandler { || h.getFeatures().contains(FeatureArea.WEATHER) && h.getFeatures().size() == 1)) .forEach(home -> { action.apply(home, accountUID).ifPresent(homeUID -> { - home.getKnownPersons().forEach(person -> action.apply(person, homeUID)); - + if (home instanceof HomeData.Security securityData) { + securityData.getKnownPersons().forEach(person -> action.apply(person, homeUID)); + } Map bridgesUids = new HashMap<>(); home.getRooms().values().stream().forEach(room -> { diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/CommonInterface.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/CommonInterface.java index c80eec1df16..91637754459 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/CommonInterface.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/CommonInterface.java @@ -18,7 +18,6 @@ import java.util.Objects; import java.util.Optional; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; import java.util.stream.Stream; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -134,8 +133,7 @@ public interface CommonInterface { if (thing instanceof Bridge) { return ((Bridge) thing).getThings().stream().filter(Thing::isEnabled) .filter(th -> th.getStatusInfo().getStatusDetail() != ThingStatusDetail.BRIDGE_OFFLINE) - .map(Thing::getHandler).filter(Objects::nonNull).map(CommonInterface.class::cast) - .collect(Collectors.toList()); + .map(Thing::getHandler).filter(Objects::nonNull).map(CommonInterface.class::cast).toList(); } return List.of(); } diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/AlarmEventCapability.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/AlarmEventCapability.java index 83c4a125671..08c380d4850 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/AlarmEventCapability.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/AlarmEventCapability.java @@ -12,13 +12,20 @@ */ package org.openhab.binding.netatmo.internal.handler.capability; +import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*; +import static org.openhab.binding.netatmo.internal.utils.ChannelTypeUtils.*; + import java.util.List; import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.binding.netatmo.internal.api.dto.NAObject; +import org.openhab.binding.netatmo.internal.api.dto.WebhookEvent; import org.openhab.binding.netatmo.internal.handler.CommonInterface; import org.openhab.binding.netatmo.internal.handler.channelhelper.ChannelHelper; import org.openhab.binding.netatmo.internal.providers.NetatmoDescriptionProvider; +import org.openhab.core.thing.ChannelUID; +import org.openhab.core.thing.ThingUID; +import org.openhab.core.types.UnDefType; /** * {@link AlarmEventCapability} gives the ability to handle Alarm modules events @@ -34,6 +41,22 @@ public class AlarmEventCapability extends HomeSecurityThingCapability { super(handler, descriptionProvider, channelHelpers); } + @Override + protected void updateWebhookEvent(WebhookEvent event) { + super.updateWebhookEvent(event); + + final ThingUID thingUid = handler.getThing().getUID(); + handler.updateState(new ChannelUID(thingUid, GROUP_LAST_EVENT, CHANNEL_EVENT_TYPE), + toStringType(event.getEventType())); + handler.updateState(new ChannelUID(thingUid, GROUP_LAST_EVENT, CHANNEL_EVENT_TIME), + toDateTimeType(event.getTime())); + handler.updateState(new ChannelUID(thingUid, GROUP_LAST_EVENT, CHANNEL_EVENT_SUBTYPE), + event.getSubTypeDescription().map(d -> toStringType(d)).orElse(UnDefType.NULL)); + final String message = event.getName(); + handler.updateState(new ChannelUID(thingUid, GROUP_LAST_EVENT, CHANNEL_EVENT_MESSAGE), + message == null || message.isBlank() ? UnDefType.NULL : toStringType(message)); + } + @Override public List updateReadings() { return getSecurityCapability().map(cap -> cap.getDeviceLastEvent(handler.getId(), moduleType.apiName)) diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/CameraCapability.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/CameraCapability.java index fbc6418c872..c63294a5620 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/CameraCapability.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/CameraCapability.java @@ -17,7 +17,6 @@ import static org.openhab.binding.netatmo.internal.utils.ChannelTypeUtils.*; import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; @@ -35,8 +34,10 @@ import org.openhab.binding.netatmo.internal.handler.channelhelper.ChannelHelper; import org.openhab.binding.netatmo.internal.providers.NetatmoDescriptionProvider; import org.openhab.core.library.types.OnOffType; import org.openhab.core.thing.ChannelUID; +import org.openhab.core.thing.Thing; import org.openhab.core.thing.ThingUID; import org.openhab.core.types.Command; +import org.openhab.core.types.State; import org.openhab.core.types.StateOption; import org.openhab.core.types.UnDefType; @@ -53,6 +54,8 @@ public class CameraCapability extends HomeSecurityThingCapability { protected @Nullable String localUrl; protected @Nullable String vpnUrl; + private boolean hasSubEventGroup; + private boolean hasLastEventGroup; public CameraCapability(CommonInterface handler, NetatmoDescriptionProvider descriptionProvider, List channelHelpers) { @@ -63,6 +66,13 @@ public class CameraCapability extends HomeSecurityThingCapability { "CameraCapability must find a CameraChannelHelper, please file a bug report.")); } + @Override + public void initialize() { + Thing thing = handler.getThing(); + hasSubEventGroup = !thing.getChannelsOfGroup(GROUP_SUB_EVENT).isEmpty(); + hasLastEventGroup = !thing.getChannelsOfGroup(GROUP_LAST_EVENT).isEmpty(); + } + @Override public void updateHomeStatusModule(HomeStatusModule newData) { super.updateHomeStatusModule(newData); @@ -85,23 +95,13 @@ public class CameraCapability extends HomeSecurityThingCapability { protected void updateWebhookEvent(WebhookEvent event) { super.updateWebhookEvent(event); - final ThingUID thingUid = handler.getThing().getUID(); - handler.updateState(new ChannelUID(thingUid, GROUP_SUB_EVENT, CHANNEL_EVENT_TYPE), - toStringType(event.getEventType())); - handler.updateState(new ChannelUID(thingUid, GROUP_SUB_EVENT, CHANNEL_EVENT_TIME), - toDateTimeType(event.getTime())); - handler.updateState(new ChannelUID(thingUid, GROUP_SUB_EVENT, CHANNEL_EVENT_SNAPSHOT), - toRawType(event.getSnapshotUrl())); - handler.updateState(new ChannelUID(thingUid, GROUP_SUB_EVENT, CHANNEL_EVENT_SNAPSHOT_URL), - toStringType(event.getSnapshotUrl())); - handler.updateState(new ChannelUID(thingUid, GROUP_SUB_EVENT, CHANNEL_EVENT_VIGNETTE), - toRawType(event.getVignetteUrl())); - handler.updateState(new ChannelUID(thingUid, GROUP_SUB_EVENT, CHANNEL_EVENT_VIGNETTE_URL), - toStringType(event.getVignetteUrl())); + if (hasSubEventGroup) { + updateSubGroup(event, thing.getUID(), GROUP_SUB_EVENT); + } - final String message = event.getName(); - handler.updateState(new ChannelUID(thingUid, GROUP_SUB_EVENT, CHANNEL_EVENT_MESSAGE), - message == null || message.isBlank() ? UnDefType.NULL : toStringType(message)); + if (hasLastEventGroup) { + updateSubGroup(event, thing.getUID(), GROUP_LAST_EVENT); + } // The channel should get triggered at last (after super and sub methods), because this allows rules to access // the new updated data from the other channels. @@ -111,6 +111,25 @@ public class CameraCapability extends HomeSecurityThingCapability { handler.triggerChannel(CHANNEL_HOME_EVENT, eventType); } + private void updateSubGroup(WebhookEvent event, ThingUID thingUid, String group) { + handler.updateState(new ChannelUID(thingUid, group, CHANNEL_EVENT_TYPE), toStringType(event.getEventType())); + handler.updateState(new ChannelUID(thingUid, group, CHANNEL_EVENT_TIME), toDateTimeType(event.getTime())); + handler.updateState(new ChannelUID(thingUid, group, CHANNEL_EVENT_SNAPSHOT), toRawType(event.getSnapshotUrl())); + handler.updateState(new ChannelUID(thingUid, group, CHANNEL_EVENT_SNAPSHOT_URL), + toStringType(event.getSnapshotUrl())); + handler.updateState(new ChannelUID(thingUid, group, CHANNEL_EVENT_VIGNETTE), toRawType(event.getVignetteUrl())); + handler.updateState(new ChannelUID(thingUid, group, CHANNEL_EVENT_VIGNETTE_URL), + toStringType(event.getVignetteUrl())); + handler.updateState(new ChannelUID(thingUid, group, CHANNEL_EVENT_SUBTYPE), + event.getSubTypeDescription().map(d -> toStringType(d)).orElse(UnDefType.NULL)); + final String message = event.getName(); + handler.updateState(new ChannelUID(thingUid, group, CHANNEL_EVENT_MESSAGE), + message == null || message.isBlank() ? UnDefType.NULL : toStringType(message)); + State personId = event.getPersons().isEmpty() ? UnDefType.NULL + : toStringType(event.getPersons().values().iterator().next().getId()); + handler.updateState(personChannelUID, personId); + } + @Override public void handleCommand(String channelName, Command command) { if (command instanceof OnOffType && CHANNEL_MONITORING.equals(channelName)) { @@ -125,8 +144,8 @@ public class CameraCapability extends HomeSecurityThingCapability { super.beforeNewData(); getSecurityCapability().ifPresent(cap -> { NAObjectMap persons = cap.getPersons(); - descriptionProvider.setStateOptions(personChannelUID, persons.values().stream() - .map(p -> new StateOption(p.getId(), p.getName())).collect(Collectors.toList())); + descriptionProvider.setStateOptions(personChannelUID, + persons.values().stream().map(p -> new StateOption(p.getId(), p.getName())).toList()); }); } diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/Capability.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/Capability.java index 9a88c2d4852..f7c75e0038f 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/Capability.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/Capability.java @@ -63,32 +63,32 @@ public class Capability { public final @Nullable String setNewData(NAObject newData) { beforeNewData(); - if (newData instanceof HomeData) { - updateHomeData((HomeData) newData); + if (newData instanceof HomeData homeData) { + updateHomeData(homeData); } - if (newData instanceof HomeStatus) { - updateHomeStatus((HomeStatus) newData); + if (newData instanceof HomeStatus homeStatus) { + updateHomeStatus(homeStatus); } - if (newData instanceof HomeStatusModule) { - updateHomeStatusModule((HomeStatusModule) newData); + if (newData instanceof HomeStatusModule homeStatusModule) { + updateHomeStatusModule(homeStatusModule); } - if (newData instanceof Event) { - updateEvent((Event) newData); + + if (newData instanceof HomeEvent homeEvent) { + updateHomeEvent(homeEvent); + } else if (newData instanceof WebhookEvent webhookEvent && webhookEvent.getEventType().validFor(moduleType)) { + updateWebhookEvent(webhookEvent); + } else if (newData instanceof Event event) { + updateEvent(event); } - if (newData instanceof WebhookEvent) { - updateWebhookEvent((WebhookEvent) newData); + + if (newData instanceof NAThing naThing) { + updateNAThing(naThing); } - if (newData instanceof HomeEvent) { - updateHomeEvent((HomeEvent) newData); + if (newData instanceof NAMain naMain) { + updateNAMain(naMain); } - if (newData instanceof NAThing) { - updateNAThing((NAThing) newData); - } - if (newData instanceof NAMain) { - updateNAMain((NAMain) newData); - } - if (newData instanceof Device) { - updateNADevice((Device) newData); + if (newData instanceof Device device) { + updateNADevice(device); } afterNewData(newData); return statusReason; diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/EnergyCapability.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/EnergyCapability.java index efd6eb22572..832d2252dcd 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/EnergyCapability.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/EnergyCapability.java @@ -15,7 +15,6 @@ package org.openhab.binding.netatmo.internal.handler.capability; import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*; import java.time.ZonedDateTime; -import java.util.stream.Collectors; import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.binding.netatmo.internal.api.EnergyApi; @@ -26,6 +25,7 @@ import org.openhab.binding.netatmo.internal.api.dto.HomeData; import org.openhab.binding.netatmo.internal.api.dto.HomeDataModule; import org.openhab.binding.netatmo.internal.api.dto.HomeDataRoom; import org.openhab.binding.netatmo.internal.api.dto.HomeStatusModule; +import org.openhab.binding.netatmo.internal.api.dto.NAHomeStatus; import org.openhab.binding.netatmo.internal.api.dto.NAHomeStatus.HomeStatus; import org.openhab.binding.netatmo.internal.api.dto.Room; import org.openhab.binding.netatmo.internal.config.HomeConfiguration; @@ -65,38 +65,41 @@ public class EnergyCapability extends RestCapability { @Override protected void updateHomeData(HomeData homeData) { - NAObjectMap rooms = homeData.getRooms(); - NAObjectMap modules = homeData.getModules(); - handler.getActiveChildren(FeatureArea.ENERGY).forEach(childHandler -> { - String childId = childHandler.getId(); - rooms.getOpt(childId) - .ifPresentOrElse(roomData -> childHandler.setNewData(roomData.ignoringForThingUpdate()), () -> { - modules.getOpt(childId) - .ifPresent(childData -> childHandler.setNewData(childData.ignoringForThingUpdate())); - modules.values().stream().filter(module -> childId.equals(module.getBridge())) - .forEach(bridgedModule -> childHandler.setNewData(bridgedModule)); - }); - }); - descriptionProvider.setStateOptions(new ChannelUID(thing.getUID(), GROUP_ENERGY, CHANNEL_PLANNING), - homeData.getThermSchedules().stream().map(p -> new StateOption(p.getId(), p.getName())) - .collect(Collectors.toList())); - setPointDefaultDuration = homeData.getThermSetpointDefaultDuration(); + if (homeData instanceof HomeData.Energy energyData) { + NAObjectMap rooms = energyData.getRooms(); + NAObjectMap modules = energyData.getModules(); + handler.getActiveChildren(FeatureArea.ENERGY).forEach(childHandler -> { + String childId = childHandler.getId(); + rooms.getOpt(childId) + .ifPresentOrElse(roomData -> childHandler.setNewData(roomData.ignoringForThingUpdate()), () -> { + modules.getOpt(childId).ifPresent( + childData -> childHandler.setNewData(childData.ignoringForThingUpdate())); + modules.values().stream().filter(module -> childId.equals(module.getBridge())) + .forEach(bridgedModule -> childHandler.setNewData(bridgedModule)); + }); + }); + descriptionProvider.setStateOptions(new ChannelUID(thing.getUID(), GROUP_ENERGY, CHANNEL_PLANNING), + energyData.getThermSchedules().stream().map(p -> new StateOption(p.getId(), p.getName())).toList()); + setPointDefaultDuration = energyData.getThermSetpointDefaultDuration(); + } } @Override protected void updateHomeStatus(HomeStatus homeStatus) { - NAObjectMap rooms = homeStatus.getRooms(); - NAObjectMap modules = homeStatus.getModules(); - handler.getActiveChildren(FeatureArea.ENERGY).forEach(childHandler -> { - String childId = childHandler.getId(); - rooms.getOpt(childId).ifPresentOrElse(roomData -> childHandler.setNewData(roomData), () -> { - modules.getOpt(childId).ifPresent(moduleData -> { - childHandler.setNewData(moduleData); - modules.values().stream().filter(module -> childId.equals(module.getBridge())) - .forEach(bridgedModule -> childHandler.setNewData(bridgedModule)); + if (homeStatus instanceof NAHomeStatus.Energy energyStatus) { + NAObjectMap rooms = energyStatus.getRooms(); + NAObjectMap modules = energyStatus.getModules(); + handler.getActiveChildren(FeatureArea.ENERGY).forEach(childHandler -> { + String childId = childHandler.getId(); + rooms.getOpt(childId).ifPresentOrElse(roomData -> childHandler.setNewData(roomData), () -> { + modules.getOpt(childId).ifPresent(moduleData -> { + childHandler.setNewData(moduleData); + modules.values().stream().filter(module -> childId.equals(module.getBridge())) + .forEach(bridgedModule -> childHandler.setNewData(bridgedModule)); + }); }); }); - }); + } } public void setThermPoint(String roomId, SetpointMode mode, long endtime, double temp) { diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/PersonCapability.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/PersonCapability.java index ce73a84cafd..7881aecff59 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/PersonCapability.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/PersonCapability.java @@ -13,11 +13,11 @@ package org.openhab.binding.netatmo.internal.handler.capability; import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*; +import static org.openhab.binding.netatmo.internal.utils.ChannelTypeUtils.*; import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; import java.util.stream.Stream; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -28,13 +28,16 @@ import org.openhab.binding.netatmo.internal.api.dto.Event; import org.openhab.binding.netatmo.internal.api.dto.HomeDataModule; import org.openhab.binding.netatmo.internal.api.dto.HomeEvent; import org.openhab.binding.netatmo.internal.api.dto.NAObject; +import org.openhab.binding.netatmo.internal.api.dto.WebhookEvent; import org.openhab.binding.netatmo.internal.handler.CommonInterface; import org.openhab.binding.netatmo.internal.handler.channelhelper.ChannelHelper; import org.openhab.binding.netatmo.internal.providers.NetatmoDescriptionProvider; import org.openhab.core.library.types.OnOffType; import org.openhab.core.thing.ChannelUID; +import org.openhab.core.thing.ThingUID; import org.openhab.core.types.Command; import org.openhab.core.types.StateOption; +import org.openhab.core.types.UnDefType; /** * {@link PersonCapability} gives the ability to handle Person specifics @@ -60,7 +63,7 @@ public class PersonCapability extends HomeSecurityThingCapability { Stream cameras = cap.getModules().values().stream() .filter(module -> module.getType() == ModuleType.WELCOME); descriptionProvider.setStateOptions(cameraChannelUID, - cameras.map(p -> new StateOption(p.getId(), p.getName())).collect(Collectors.toList())); + cameras.map(p -> new StateOption(p.getId(), p.getName())).toList()); }); } @@ -71,6 +74,28 @@ public class PersonCapability extends HomeSecurityThingCapability { } } + @Override + protected void updateWebhookEvent(WebhookEvent event) { + super.updateWebhookEvent(event); + + ThingUID thingUid = thing.getUID(); + + handler.updateState(new ChannelUID(thingUid, GROUP_LAST_EVENT, CHANNEL_EVENT_SUBTYPE), + event.getSubTypeDescription().map(d -> toStringType(d)).orElse(UnDefType.NULL)); + + final String message = event.getName(); + handler.updateState(new ChannelUID(thingUid, GROUP_LAST_EVENT, CHANNEL_EVENT_MESSAGE), + message == null || message.isBlank() ? UnDefType.NULL : toStringType(message)); + + handler.updateState(new ChannelUID(thingUid, GROUP_LAST_EVENT, CHANNEL_EVENT_TIME), + toDateTimeType(event.getTime())); + + handler.updateState(new ChannelUID(thingUid, GROUP_LAST_EVENT, CHANNEL_EVENT_SNAPSHOT), + toRawType(event.getSnapshotUrl())); + + handler.updateState(cameraChannelUID, toStringType(event.getCameraId())); + } + @Override public void updateEvent(Event event) { super.updateEvent(event); diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/SecurityCapability.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/SecurityCapability.java index c2b8fd41a81..84e422ae208 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/SecurityCapability.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/capability/SecurityCapability.java @@ -31,6 +31,7 @@ import org.openhab.binding.netatmo.internal.api.dto.HomeDataPerson; import org.openhab.binding.netatmo.internal.api.dto.HomeEvent; import org.openhab.binding.netatmo.internal.api.dto.HomeStatusModule; import org.openhab.binding.netatmo.internal.api.dto.HomeStatusPerson; +import org.openhab.binding.netatmo.internal.api.dto.NAHomeStatus; import org.openhab.binding.netatmo.internal.api.dto.NAHomeStatus.HomeStatus; import org.openhab.binding.netatmo.internal.api.dto.NAObject; import org.openhab.binding.netatmo.internal.config.HomeConfiguration; @@ -69,34 +70,38 @@ class SecurityCapability extends RestCapability { @Override protected void updateHomeData(HomeData homeData) { - persons = homeData.getPersons(); - modules = homeData.getModules(); - handler.getActiveChildren(FeatureArea.SECURITY).forEach(childHandler -> { - String childId = childHandler.getId(); - persons.getOpt(childId) - .ifPresentOrElse(personData -> childHandler.setNewData(personData.ignoringForThingUpdate()), () -> { - modules.getOpt(childId) - .ifPresent(childData -> childHandler.setNewData(childData.ignoringForThingUpdate())); - modules.values().stream().filter(module -> childId.equals(module.getBridge())) - .forEach(bridgedModule -> childHandler.setNewData(bridgedModule)); - }); - }); + if (homeData instanceof HomeData.Security securityData) { + persons = securityData.getPersons(); + modules = homeData.getModules(); + handler.getActiveChildren(FeatureArea.SECURITY).forEach(childHandler -> { + String childId = childHandler.getId(); + persons.getOpt(childId).ifPresentOrElse( + personData -> childHandler.setNewData(personData.ignoringForThingUpdate()), () -> { + modules.getOpt(childId).ifPresent( + childData -> childHandler.setNewData(childData.ignoringForThingUpdate())); + modules.values().stream().filter(module -> childId.equals(module.getBridge())) + .forEach(bridgedModule -> childHandler.setNewData(bridgedModule)); + }); + }); + } } @Override protected void updateHomeStatus(HomeStatus homeStatus) { - NAObjectMap persons = homeStatus.getPersons(); - NAObjectMap modules = homeStatus.getModules(); - handler.getActiveChildren(FeatureArea.SECURITY).forEach(childHandler -> { - String childId = childHandler.getId(); - persons.getOpt(childId).ifPresentOrElse(personData -> childHandler.setNewData(personData), () -> { - modules.getOpt(childId).ifPresent(childData -> { - childHandler.setNewData(childData); - modules.values().stream().filter(module -> childId.equals(module.getBridge())) - .forEach(bridgedModule -> childHandler.setNewData(bridgedModule)); + if (homeStatus instanceof NAHomeStatus.Security securityStatus) { + NAObjectMap persons = securityStatus.getPersons(); + NAObjectMap modules = securityStatus.getModules(); + handler.getActiveChildren(FeatureArea.SECURITY).forEach(childHandler -> { + String childId = childHandler.getId(); + persons.getOpt(childId).ifPresentOrElse(personData -> childHandler.setNewData(personData), () -> { + modules.getOpt(childId).ifPresent(childData -> { + childHandler.setNewData(childData); + modules.values().stream().filter(module -> childId.equals(module.getBridge())) + .forEach(bridgedModule -> childHandler.setNewData(bridgedModule)); + }); }); }); - }); + } } @Override diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/channelhelper/EnergyChannelHelper.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/channelhelper/EnergyChannelHelper.java index 3f9852d1a6b..b6fdf8e2a6c 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/channelhelper/EnergyChannelHelper.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/channelhelper/EnergyChannelHelper.java @@ -50,13 +50,12 @@ public class EnergyChannelHelper extends ChannelHelper { @Override protected @Nullable State internalGetProperty(String channelId, NAThing data, Configuration config) { - if (data instanceof HomeData) { - HomeData homeData = (HomeData) data; - SetpointMode thermMode = homeData.getThermMode(); - ThermProgram currentProgram = homeData.getActiveProgram(); + if (data instanceof HomeData.Energy energyData) { + SetpointMode thermMode = energyData.getThermMode(); + ThermProgram currentProgram = energyData.getActiveProgram(); switch (channelId) { case CHANNEL_SETPOINT_DURATION: - return toQuantityType(homeData.getThermSetpointDefaultDuration(), Units.MINUTE); + return toQuantityType(energyData.getThermSetpointDefaultDuration(), Units.MINUTE); case CHANNEL_PLANNING: return (currentProgram != null ? toStringType(currentProgram.getName()) : null); case CHANNEL_SETPOINT_END_TIME: diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/channelhelper/PersonChannelHelper.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/channelhelper/PersonChannelHelper.java index affb4c17f79..6ad93027707 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/channelhelper/PersonChannelHelper.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/channelhelper/PersonChannelHelper.java @@ -54,7 +54,7 @@ public class PersonChannelHelper extends ChannelHelper { HomeStatusPerson person = (HomeStatusPerson) naThing; switch (channelId) { case CHANNEL_PERSON_AT_HOME: - return OnOffType.from(!person.isOutOfSight()); + return OnOffType.from(person.atHome()); case CHANNEL_LAST_SEEN: return toDateTimeType(person.getLastSeen()); } diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/channelhelper/SecurityChannelHelper.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/channelhelper/SecurityChannelHelper.java index 44732fcebd6..ea1886122e6 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/channelhelper/SecurityChannelHelper.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/handler/channelhelper/SecurityChannelHelper.java @@ -17,15 +17,14 @@ import static org.openhab.binding.netatmo.internal.utils.ChannelTypeUtils.toRawT import java.util.List; import java.util.Set; -import java.util.stream.Collectors; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.netatmo.internal.api.dto.HomeData; +import org.openhab.binding.netatmo.internal.api.dto.HomeDataPerson; import org.openhab.binding.netatmo.internal.api.dto.HomeStatusPerson; -import org.openhab.binding.netatmo.internal.api.dto.NAHomeStatus.HomeStatus; +import org.openhab.binding.netatmo.internal.api.dto.NAHomeStatus; import org.openhab.binding.netatmo.internal.api.dto.NAObject; -import org.openhab.binding.netatmo.internal.deserialization.NAObjectMap; import org.openhab.core.library.types.DecimalType; import org.openhab.core.types.State; import org.openhab.core.types.UnDefType; @@ -50,16 +49,11 @@ public class SecurityChannelHelper extends ChannelHelper { @Override public void setNewData(@Nullable NAObject data) { super.setNewData(data); - if (data instanceof HomeData) { - HomeData homeData = (HomeData) data; - knownIds = homeData.getPersons().values().stream().filter(person -> person.isKnown()).map(p -> p.getId()) - .collect(Collectors.toList()); - } - if (data instanceof HomeStatus) { - HomeStatus status = (HomeStatus) data; - NAObjectMap allPersons = status.getPersons(); - List present = allPersons.values().stream().filter(p -> !p.isOutOfSight()) - .collect(Collectors.toList()); + if (data instanceof HomeData.Security securityData) { + knownIds = securityData.getKnownPersons().stream().map(HomeDataPerson::getId).toList(); + } else if (data instanceof NAHomeStatus.Security securityStatus) { + List present = securityStatus.getPersons().values().stream() + .filter(HomeStatusPerson::atHome).toList(); persons = present.size(); unknowns = present.stream().filter(person -> !knownIds.contains(person.getId())).count(); diff --git a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/providers/NetatmoThingTypeProvider.java b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/providers/NetatmoThingTypeProvider.java index 320f7f1e9d6..cb66f0e2207 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/providers/NetatmoThingTypeProvider.java +++ b/bundles/org.openhab.binding.netatmo/src/main/java/org/openhab/binding/netatmo/internal/providers/NetatmoThingTypeProvider.java @@ -18,7 +18,6 @@ import java.util.Collection; import java.util.List; import java.util.Locale; import java.util.Optional; -import java.util.stream.Collectors; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; @@ -63,8 +62,7 @@ public class NetatmoThingTypeProvider implements ThingTypeProvider { @Override public Collection getThingTypes(@Nullable Locale locale) { return ModuleType.AS_SET.stream().filter(mt -> mt != ModuleType.UNKNOWN) - .map(mt -> Optional.ofNullable(getThingType(mt.thingTypeUID, locale))).map(Optional::get) - .collect(Collectors.toList()); + .map(mt -> Optional.ofNullable(getThingType(mt.thingTypeUID, locale))).map(Optional::get).toList(); } @Override @@ -95,7 +93,7 @@ public class NetatmoThingTypeProvider implements ThingTypeProvider { private List getGroupDefinitions(ModuleType thingType) { return thingType.getGroupTypes().stream().map(groupType -> new ChannelGroupDefinition(toGroupName(groupType), - new ChannelGroupTypeUID(BINDING_ID, groupType))).collect(Collectors.toList()); + new ChannelGroupTypeUID(BINDING_ID, groupType))).toList(); } public static String toGroupName(String groupeTypeName) { diff --git a/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/i18n/netatmo.properties b/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/i18n/netatmo.properties index a7eb434fbf4..d86de3707eb 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/i18n/netatmo.properties +++ b/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/i18n/netatmo.properties @@ -70,8 +70,8 @@ channel-group-type.netatmo.rain.channel.sum-1.label = Rain 1h channel-group-type.netatmo.rain.channel.sum-1.description = Quantity of water over last hour. channel-group-type.netatmo.rain.channel.sum-24.label = Rain 24h channel-group-type.netatmo.rain.channel.sum-24.description = Quantity of water during the current day. -channel-group-type.netatmo.security.label = Home Security channel-group-type.netatmo.security-event.label = Home Security Event +channel-group-type.netatmo.security.label = Home Security channel-group-type.netatmo.setpoint.label = Setpoint channel-group-type.netatmo.setpoint.channel.end.label = Setpoint End channel-group-type.netatmo.setpoint.channel.end.description = End time of the currently applied setpoint. @@ -81,13 +81,6 @@ channel-group-type.netatmo.signal.label = Signal channel-group-type.netatmo.siren.label = Siren Status channel-group-type.netatmo.status-doorbell.label = Camera Status channel-group-type.netatmo.status.label = Camera Status -channel-group-type.netatmo.sub-event.label = Sub Event -channel-group-type.netatmo.sub-event.channel.time.label = Sub-Event Timestamp -channel-group-type.netatmo.sub-event.channel.time.description = Moment when the sub-event occurred. -channel-group-type.netatmo.sub-event.channel.vignette.label = Vignette -channel-group-type.netatmo.sub-event.channel.vignette.description = Vignette of the Snapshot. -channel-group-type.netatmo.sub-event.channel.vignette-url.label = Vignette URL -channel-group-type.netatmo.sub-event.channel.vignette-url.description = URL of the vignette. channel-group-type.netatmo.sub-event-doorbell.label = Sub Event channel-group-type.netatmo.sub-event-doorbell.channel.time.label = Sub-Event Timestamp channel-group-type.netatmo.sub-event-doorbell.channel.time.description = Moment when the sub-event occurred. @@ -95,6 +88,13 @@ channel-group-type.netatmo.sub-event-doorbell.channel.vignette.label = Vignette channel-group-type.netatmo.sub-event-doorbell.channel.vignette.description = Vignette of the Snapshot. channel-group-type.netatmo.sub-event-doorbell.channel.vignette-url.label = Vignette URL channel-group-type.netatmo.sub-event-doorbell.channel.vignette-url.description = URL of the vignette. +channel-group-type.netatmo.sub-event.label = Sub Event +channel-group-type.netatmo.sub-event.channel.time.label = Sub-Event Timestamp +channel-group-type.netatmo.sub-event.channel.time.description = Moment when the sub-event occurred. +channel-group-type.netatmo.sub-event.channel.vignette.label = Vignette +channel-group-type.netatmo.sub-event.channel.vignette.description = Vignette of the Snapshot. +channel-group-type.netatmo.sub-event.channel.vignette-url.label = Vignette URL +channel-group-type.netatmo.sub-event.channel.vignette-url.description = URL of the vignette. channel-group-type.netatmo.tag.label = Door Tag channel-group-type.netatmo.temperature-extended.label = Temperature channel-group-type.netatmo.temperature-extended.channel.max-time.label = Today Max Timestamp @@ -189,6 +189,8 @@ channel-type.netatmo.event-subtype.state.option.BATTERY_LOW = Battery low channel-type.netatmo.event-subtype.state.option.BATTERY_VERY_LOW = Battery very low channel-type.netatmo.event-subtype.state.option.SMOKE_CLEARED = Smoke cleared channel-type.netatmo.event-subtype.state.option.SMOKE_DETECTED = Smoke detected +channel-type.netatmo.event-subtype.state.option.HUSH_ACTIVATED = Smoke detection activated +channel-type.netatmo.event-subtype.state.option.HUSH_DEACTIVATED = Smoke detection deactivated channel-type.netatmo.event-subtype.state.option.WIFI_STATUS_OK = Wi-Fi status ok channel-type.netatmo.event-subtype.state.option.WIFI_STATUS_ERROR = Wi-Fi status error channel-type.netatmo.event-subtype.state.option.CO_OK = Carbon Monoxide OK diff --git a/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/thing/channels.xml b/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/thing/channels.xml index 08efba66f0c..ae4b96ff0ea 100644 --- a/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/thing/channels.xml +++ b/bundles/org.openhab.binding.netatmo/src/main/resources/OH-INF/thing/channels.xml @@ -404,6 +404,8 @@ + + diff --git a/bundles/org.openhab.binding.netatmo/src/test/java/org/openhab/binding/netatmo/internal/handler/channelhelper/EventCameraChannelHelperTest.java b/bundles/org.openhab.binding.netatmo/src/test/java/org/openhab/binding/netatmo/internal/handler/channelhelper/EventCameraChannelHelperTest.java index 3460529490e..e96a07d34ce 100644 --- a/bundles/org.openhab.binding.netatmo/src/test/java/org/openhab/binding/netatmo/internal/handler/channelhelper/EventCameraChannelHelperTest.java +++ b/bundles/org.openhab.binding.netatmo/src/test/java/org/openhab/binding/netatmo/internal/handler/channelhelper/EventCameraChannelHelperTest.java @@ -17,6 +17,7 @@ import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*; import java.util.Collections; +import org.eclipse.jdt.annotation.NonNullByDefault; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.openhab.binding.netatmo.internal.api.data.EventType; @@ -27,9 +28,10 @@ import org.openhab.core.types.State; /** * @author Sven Strohschein - Initial contribution */ +@NonNullByDefault public class EventCameraChannelHelperTest { - private EventCameraChannelHelper helper; + private @NonNullByDefault({}) EventCameraChannelHelper helper; @BeforeEach public void before() {