Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[netatmo] Enhance RefreshCapability #16574

Merged
merged 18 commits into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 7 additions & 4 deletions bundles/org.openhab.binding.netatmo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,12 @@ Once authentication process has been done, current refreshToken is stored in `/O
| presence | Thing | NOC | The Netatmo Smart Outdoor Camera (Presence) camera with or without siren. | id, ipAddress |
| siren | Thing | NIS | The Netatmo Smart Indoor Siren. | id |
| doorbell | Thing | NDB | The Netatmo Smart Video Doorbell device. | id, ipAddress |
| weather-station | Bridge | NAMain | Main indoor module reporting temperature, humidity, pressure, air quality and sound level. | id |
| weather-station | Bridge | NAMain | Main indoor module reporting temperature, humidity, pressure, air quality and sound level. | id, refreshInterval |
| outdoor | Thing | NAModule1 | Outdoor module reporting temperature and humidity. | id |
| wind | Thing | NAModule2 | Wind sensor reporting wind angle and strength. | id |
| rain | Thing | NAModule3 | Rain Gauge measuring precipitation. | id |
| indoor | Thing | NAModule4 | Additional indoor module reporting temperature, humidity and CO2 level. | id |
| home-coach | Thing | NHC | Healthy home coach reporting health-index, temperature, humidity, pressure, air quality, sound level. | id |
| home-coach | Thing | NHC | Healthy home coach reporting health-index, temperature, humidity, pressure, air quality, sound level. | id, refreshInterval |
| plug | Thing | NAPlug | The relay connected to the boiler controlling a Thermostat and zero or more valves. | id |
| thermostat | Thing | NATherm1 | The Thermostat device placed in a given room. | id |
| room | Thing | NARoom | A room in your house. | id |
Expand Down Expand Up @@ -161,8 +161,8 @@ If you did not manually create things in the *.things file, the Netatmo Binding

### Weather Station Main Indoor Device

Weather station does not need any refreshInterval setting.
Based on a standard update period of 10mn by Netatmo systems - it will auto adapt to stick closest as possible to last data availability.
Weather station uses a default `refreshInterval` of 10 minutes (can be adjusted), based on a standard update period of Netatmo systems.
It will auto-adapt to stick as closely as possible to the last data availability.

**Supported channels for the main indoor module:**

Expand Down Expand Up @@ -330,6 +330,9 @@ All these channels are read only.

### Healthy Home Coach Device

Home Coach uses a default `refreshInterval` of 10 minutes (can be adjusted), based on a standard update period of Netatmo systems.
It will auto-adapt to stick as closely as possible to the last data availability.

**Supported channels for the healthy home coach device:**

| Channel Group | Channel Id | Item Type | Description |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,11 @@
import org.openhab.binding.netatmo.internal.handler.capability.DoorbellCapability;
import org.openhab.binding.netatmo.internal.handler.capability.HomeCapability;
import org.openhab.binding.netatmo.internal.handler.capability.MeasureCapability;
import org.openhab.binding.netatmo.internal.handler.capability.ParentUpdateCapability;
import org.openhab.binding.netatmo.internal.handler.capability.PersonCapability;
import org.openhab.binding.netatmo.internal.handler.capability.PresenceCapability;
import org.openhab.binding.netatmo.internal.handler.capability.RefreshAutoCapability;
import org.openhab.binding.netatmo.internal.handler.capability.RefreshCapability;
import org.openhab.binding.netatmo.internal.handler.capability.RoomCapability;
import org.openhab.binding.netatmo.internal.handler.capability.WeatherCapability;
import org.openhab.binding.netatmo.internal.handler.channelhelper.ChannelHelper;
Expand Down Expand Up @@ -148,6 +151,12 @@ private BaseThingHandler buildHandler(Thing thing, ModuleType moduleType) {
newCap = new MeasureCapability(handler, helpers);
} else if (capability == ChannelHelperCapability.class) {
newCap = new ChannelHelperCapability(handler, helpers);
} else if (capability == RefreshAutoCapability.class) {
newCap = new RefreshAutoCapability(handler);
} else if (capability == RefreshCapability.class) {
newCap = new RefreshCapability(handler);
} else if (capability == ParentUpdateCapability.class) {
newCap = new ParentUpdateCapability(handler);
}
if (newCap != null) {
handler.getCapabilities().put(newCap);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@
import org.openhab.binding.netatmo.internal.handler.capability.DoorbellCapability;
import org.openhab.binding.netatmo.internal.handler.capability.HomeCapability;
import org.openhab.binding.netatmo.internal.handler.capability.MeasureCapability;
import org.openhab.binding.netatmo.internal.handler.capability.ParentUpdateCapability;
import org.openhab.binding.netatmo.internal.handler.capability.PersonCapability;
import org.openhab.binding.netatmo.internal.handler.capability.PresenceCapability;
import org.openhab.binding.netatmo.internal.handler.capability.RefreshAutoCapability;
import org.openhab.binding.netatmo.internal.handler.capability.RefreshCapability;
import org.openhab.binding.netatmo.internal.handler.capability.RoomCapability;
import org.openhab.binding.netatmo.internal.handler.capability.WeatherCapability;
import org.openhab.binding.netatmo.internal.handler.channelhelper.AirQualityChannelHelper;
Expand Down Expand Up @@ -70,91 +73,100 @@ public enum ModuleType {
new ChannelGroup(ApiBridgeChannelHelper.class, GROUP_MONITORING)),

HOME(FeatureArea.NONE, "NAHome", 1, "home", ACCOUNT,
Set.of(DeviceCapability.class, HomeCapability.class, ChannelHelperCapability.class),
Set.of(DeviceCapability.class, HomeCapability.class, ChannelHelperCapability.class,
RefreshCapability.class),
new ChannelGroup(SecurityChannelHelper.class, GROUP_SECURITY_EVENT, GROUP_SECURITY),
new ChannelGroup(EnergyChannelHelper.class, GROUP_ENERGY)),

PERSON(FeatureArea.SECURITY, "NAPerson", 1, "virtual", HOME,
Set.of(PersonCapability.class, ChannelHelperCapability.class),
Set.of(PersonCapability.class, ChannelHelperCapability.class, ParentUpdateCapability.class),
new ChannelGroup(PersonChannelHelper.class, GROUP_PERSON),
new ChannelGroup(EventPersonChannelHelper.class, GROUP_PERSON_LAST_EVENT)),

WELCOME(FeatureArea.SECURITY, "NACamera", 1, "camera", HOME,
Set.of(CameraCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL, ChannelGroup.EVENT,
Set.of(CameraCapability.class, ChannelHelperCapability.class, ParentUpdateCapability.class),
ChannelGroup.SIGNAL, ChannelGroup.EVENT,
new ChannelGroup(CameraChannelHelper.class, GROUP_SECURITY_EVENT, GROUP_CAM_STATUS, GROUP_CAM_LIVE)),

TAG(FeatureArea.SECURITY, "NACamDoorTag", 1, "device", WELCOME, Set.of(ChannelHelperCapability.class),
ChannelGroup.SIGNAL, ChannelGroup.BATTERY, ChannelGroup.TIMESTAMP,
new ChannelGroup(DoorTagChannelHelper.class, GROUP_TAG)),
TAG(FeatureArea.SECURITY, "NACamDoorTag", 1, "device", WELCOME,
Set.of(ChannelHelperCapability.class, ParentUpdateCapability.class), ChannelGroup.SIGNAL,
ChannelGroup.BATTERY, ChannelGroup.TIMESTAMP, new ChannelGroup(DoorTagChannelHelper.class, GROUP_TAG)),

SIREN(FeatureArea.SECURITY, "NIS", 1, "device", WELCOME, Set.of(ChannelHelperCapability.class), ChannelGroup.SIGNAL,
SIREN(FeatureArea.SECURITY, "NIS", 1, "device", WELCOME,
Set.of(ChannelHelperCapability.class, ParentUpdateCapability.class), ChannelGroup.SIGNAL,
ChannelGroup.BATTERY, ChannelGroup.TIMESTAMP, new ChannelGroup(SirenChannelHelper.class, GROUP_SIREN)),

PRESENCE(FeatureArea.SECURITY, "NOC", 1, "camera", HOME,
Set.of(PresenceCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL, ChannelGroup.EVENT,
Set.of(PresenceCapability.class, ChannelHelperCapability.class, ParentUpdateCapability.class),
ChannelGroup.SIGNAL, ChannelGroup.EVENT,
new ChannelGroup(PresenceChannelHelper.class, GROUP_SECURITY_EVENT, GROUP_CAM_STATUS, GROUP_CAM_LIVE,
GROUP_PRESENCE),
new ChannelGroup(EventCameraChannelHelper.class, GROUP_SUB_EVENT)),

DOORBELL(FeatureArea.SECURITY, "NDB", 1, "camera", HOME,
Set.of(DoorbellCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL,
Set.of(DoorbellCapability.class, ChannelHelperCapability.class, ParentUpdateCapability.class),
ChannelGroup.SIGNAL,
new ChannelGroup(CameraChannelHelper.class, GROUP_SECURITY_EVENT, GROUP_DOORBELL_STATUS,
GROUP_DOORBELL_LIVE),
new ChannelGroup(EventCameraChannelHelper.class, GROUP_DOORBELL_LAST_EVENT, GROUP_DOORBELL_SUB_EVENT)),

WEATHER_STATION(FeatureArea.WEATHER, "NAMain", 1, "device", ACCOUNT,
WEATHER_STATION(FeatureArea.WEATHER, "NAMain", 1, "weather", ACCOUNT,
Set.of(DeviceCapability.class, WeatherCapability.class, MeasureCapability.class,
ChannelHelperCapability.class),
ChannelHelperCapability.class, RefreshAutoCapability.class),
ChannelGroup.SIGNAL, ChannelGroup.HUMIDITY, ChannelGroup.TSTAMP_EXT, ChannelGroup.MEASURE,
ChannelGroup.AIR_QUALITY, ChannelGroup.LOCATION, ChannelGroup.NOISE, ChannelGroup.TEMP_INSIDE_EXT,
new ChannelGroup(PressureChannelHelper.class, MeasureClass.PRESSURE, GROUP_TYPE_PRESSURE_EXTENDED)),

OUTDOOR(FeatureArea.WEATHER, "NAModule1", 1, "device", WEATHER_STATION,
Set.of(MeasureCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL, ChannelGroup.HUMIDITY,
ChannelGroup.TSTAMP_EXT, ChannelGroup.MEASURE, ChannelGroup.BATTERY, ChannelGroup.TEMP_OUTSIDE_EXT),
Set.of(MeasureCapability.class, ChannelHelperCapability.class, ParentUpdateCapability.class),
ChannelGroup.SIGNAL, ChannelGroup.HUMIDITY, ChannelGroup.TSTAMP_EXT, ChannelGroup.MEASURE,
ChannelGroup.BATTERY, ChannelGroup.TEMP_OUTSIDE_EXT),

WIND(FeatureArea.WEATHER, "NAModule2", 1, "device", WEATHER_STATION, Set.of(ChannelHelperCapability.class),
ChannelGroup.SIGNAL, ChannelGroup.TSTAMP_EXT, ChannelGroup.BATTERY,
new ChannelGroup(WindChannelHelper.class, GROUP_WIND)),
WIND(FeatureArea.WEATHER, "NAModule2", 1, "device", WEATHER_STATION,
Set.of(ChannelHelperCapability.class, ParentUpdateCapability.class), ChannelGroup.SIGNAL,
ChannelGroup.TSTAMP_EXT, ChannelGroup.BATTERY, new ChannelGroup(WindChannelHelper.class, GROUP_WIND)),

RAIN(FeatureArea.WEATHER, "NAModule3", 1, "device", WEATHER_STATION,
Set.of(MeasureCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL,
ChannelGroup.TSTAMP_EXT, ChannelGroup.MEASURE, ChannelGroup.BATTERY,
Set.of(MeasureCapability.class, ChannelHelperCapability.class, ParentUpdateCapability.class),
ChannelGroup.SIGNAL, ChannelGroup.TSTAMP_EXT, ChannelGroup.MEASURE, ChannelGroup.BATTERY,
new ChannelGroup(RainChannelHelper.class, MeasureClass.RAIN_QUANTITY, GROUP_RAIN)),

INDOOR(FeatureArea.WEATHER, "NAModule4", 1, "device", WEATHER_STATION,
Set.of(MeasureCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL,
ChannelGroup.TSTAMP_EXT, ChannelGroup.MEASURE, ChannelGroup.BATTERY, ChannelGroup.HUMIDITY,
ChannelGroup.TEMP_INSIDE_EXT, ChannelGroup.AIR_QUALITY),
Set.of(MeasureCapability.class, ChannelHelperCapability.class, ParentUpdateCapability.class),
ChannelGroup.SIGNAL, ChannelGroup.TSTAMP_EXT, ChannelGroup.MEASURE, ChannelGroup.BATTERY,
ChannelGroup.HUMIDITY, ChannelGroup.TEMP_INSIDE_EXT, ChannelGroup.AIR_QUALITY),

HOME_COACH(FeatureArea.AIR_CARE, "NHC", 1, "device", ACCOUNT,
HOME_COACH(FeatureArea.AIR_CARE, "NHC", 1, "weather", ACCOUNT,
Set.of(DeviceCapability.class, AirCareCapability.class, MeasureCapability.class,
ChannelHelperCapability.class),
ChannelHelperCapability.class, RefreshAutoCapability.class),
ChannelGroup.LOCATION, ChannelGroup.SIGNAL, ChannelGroup.NOISE, ChannelGroup.HUMIDITY,
ChannelGroup.TEMP_INSIDE, ChannelGroup.MEASURE, ChannelGroup.TSTAMP_EXT,
new ChannelGroup(AirQualityChannelHelper.class, GROUP_TYPE_AIR_QUALITY_EXTENDED),
new ChannelGroup(PressureChannelHelper.class, MeasureClass.PRESSURE, GROUP_PRESSURE)),

PLUG(FeatureArea.ENERGY, "NAPlug", 1, "device", HOME, Set.of(ChannelHelperCapability.class), ChannelGroup.SIGNAL),
PLUG(FeatureArea.ENERGY, "NAPlug", 1, "device", HOME,
Set.of(ChannelHelperCapability.class, ParentUpdateCapability.class), ChannelGroup.SIGNAL),

VALVE(FeatureArea.ENERGY, "NRV", 1, "device", PLUG, Set.of(ChannelHelperCapability.class), ChannelGroup.SIGNAL,
VALVE(FeatureArea.ENERGY, "NRV", 1, "device", PLUG,
Set.of(ChannelHelperCapability.class, ParentUpdateCapability.class), ChannelGroup.SIGNAL,
ChannelGroup.BATTERY_EXT),

THERMOSTAT(FeatureArea.ENERGY, "NATherm1", 1, "device", PLUG, Set.of(ChannelHelperCapability.class),
ChannelGroup.SIGNAL, ChannelGroup.BATTERY_EXT,
new ChannelGroup(Therm1ChannelHelper.class, GROUP_TYPE_TH_PROPERTIES)),
THERMOSTAT(FeatureArea.ENERGY, "NATherm1", 1, "device", PLUG,
Set.of(ChannelHelperCapability.class, ParentUpdateCapability.class), ChannelGroup.SIGNAL,
ChannelGroup.BATTERY_EXT, new ChannelGroup(Therm1ChannelHelper.class, GROUP_TYPE_TH_PROPERTIES)),

ROOM(FeatureArea.ENERGY, "NARoom", 1, "virtual", HOME, Set.of(RoomCapability.class, ChannelHelperCapability.class),
ROOM(FeatureArea.ENERGY, "NARoom", 1, "virtual", HOME,
Set.of(RoomCapability.class, ChannelHelperCapability.class, ParentUpdateCapability.class),
new ChannelGroup(RoomChannelHelper.class, GROUP_TYPE_ROOM_PROPERTIES, GROUP_TYPE_ROOM_TEMPERATURE),
new ChannelGroup(SetpointChannelHelper.class, GROUP_SETPOINT)),

SMOKE_DETECTOR(FeatureArea.SECURITY, "NSD", 1, "device", HOME,
Set.of(AlarmEventCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL,
ChannelGroup.TIMESTAMP, ChannelGroup.ALARM_LAST_EVENT),
Set.of(AlarmEventCapability.class, ChannelHelperCapability.class, ParentUpdateCapability.class),
ChannelGroup.SIGNAL, ChannelGroup.TIMESTAMP, ChannelGroup.ALARM_LAST_EVENT),

CO_DETECTOR(FeatureArea.SECURITY, "NCO", 1, "device", HOME,
Set.of(AlarmEventCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL,
ChannelGroup.TIMESTAMP, ChannelGroup.ALARM_LAST_EVENT);
Set.of(AlarmEventCapability.class, ChannelHelperCapability.class, ParentUpdateCapability.class),
ChannelGroup.SIGNAL, ChannelGroup.TIMESTAMP, ChannelGroup.ALARM_LAST_EVENT);

public static final EnumSet<ModuleType> AS_SET = EnumSet.allOf(ModuleType.class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class NAThingConfiguration {
public static final String ID = "id";

protected String id = "";
public int refreshInterval = -1;
public int refreshInterval = 120;
jlaur marked this conversation as resolved.
Show resolved Hide resolved

public String getId() {
return id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@
*/
package org.openhab.binding.netatmo.internal.handler;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

import org.eclipse.jdt.annotation.NonNullByDefault;
Expand All @@ -28,8 +31,6 @@
import org.openhab.binding.netatmo.internal.handler.capability.Capability;
import org.openhab.binding.netatmo.internal.handler.capability.CapabilityMap;
import org.openhab.binding.netatmo.internal.handler.capability.HomeCapability;
import org.openhab.binding.netatmo.internal.handler.capability.ParentUpdateCapability;
import org.openhab.binding.netatmo.internal.handler.capability.RefreshCapability;
import org.openhab.binding.netatmo.internal.handler.capability.RestCapability;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Channel;
Expand Down Expand Up @@ -87,6 +88,10 @@ void setThingStatus(ThingStatus thingStatus, ThingStatusDetail thingStatusDetail
: null;
}

default Optional<ScheduledFuture<?>> schedule(Runnable arg0, Duration delay) {
return Optional.of(getScheduler().schedule(arg0, delay.getSeconds(), TimeUnit.SECONDS));
}

default @Nullable ApiBridgeHandler getAccountHandler() {
Bridge bridge = getBridge();
BridgeHandler bridgeHandler = null;
Expand Down Expand Up @@ -221,15 +226,14 @@ default void commonInitialize() {
setThingStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED, null);
} else if (!ThingStatus.ONLINE.equals(bridge.getStatus())) {
setThingStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, null);
getCapabilities().remove(RefreshCapability.class);
getCapabilities().remove(ParentUpdateCapability.class);
getCapabilities().getParentUpdate().ifPresent(Capability::dispose);
getCapabilities().getRefresh().ifPresent(Capability::dispose);
} else {
setThingStatus(ThingStatus.UNKNOWN, ThingStatusDetail.NONE, null);
if (ModuleType.ACCOUNT.equals(getModuleType().getBridge())) {
NAThingConfiguration config = getThing().getConfiguration().as(NAThingConfiguration.class);
getCapabilities().put(new RefreshCapability(this, config.refreshInterval));
}
getCapabilities().put(new ParentUpdateCapability(this));
getCapabilities().getParentUpdate().ifPresentOrElse(Capability::initialize, () -> {
int interval = getThingConfigAs(NAThingConfiguration.class).refreshInterval;
jlaur marked this conversation as resolved.
Show resolved Hide resolved
getCapabilities().getRefresh().ifPresent(cap -> cap.setInterval(Duration.ofSeconds(interval)));
});
}
}

Expand Down