Skip to content

Commit

Permalink
Buffer last event requests per child modules
Browse files Browse the repository at this point in the history
This is targetted to decrease the number of requests transmitted to Netatmo API.
Solves openhab#13358

Signed-off-by: clinique <gael@lhopital.org>
  • Loading branch information
clinique committed Oct 4, 2022
1 parent 12389f0 commit 83e0ccb
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@

import java.net.URI;
import java.util.Collection;
import java.util.stream.Collectors;

import javax.ws.rs.core.UriBuilder;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.FeatureArea;
import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.FloodLightMode;
import org.openhab.binding.netatmo.internal.api.dto.Home;
Expand Down Expand Up @@ -62,33 +62,29 @@ public boolean addwebhook(URI uri) throws NetatmoException {
return true;
}

public Collection<HomeEvent> getPersonEvents(String homeId, String personId) throws NetatmoException {
UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_GET_EVENTS, PARAM_HOME_ID, homeId, PARAM_PERSON_ID, personId,
PARAM_OFFSET, 1);
NAEventsDataResponse response = get(uriBuilder, NAEventsDataResponse.class);
BodyResponse<Home> body = response.getBody();
private Collection<HomeEvent> getEvents(@Nullable Object... params) throws NetatmoException {
UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_GET_EVENTS, params);
BodyResponse<Home> body = get(uriBuilder, NAEventsDataResponse.class).getBody();
if (body != null) {
Home home = body.getElement();
if (home != null) {
return home.getEvents().stream().filter(event -> personId.equals(event.getPersonId()))
.collect(Collectors.toList());
return home.getEvents();
}
}
throw new NetatmoException("home should not be null");
}

public Collection<HomeEvent> getHomeEvents(String homeId) throws NetatmoException {
return getEvents(PARAM_HOME_ID, homeId);
}

public Collection<HomeEvent> getPersonEvents(String homeId, String personId) throws NetatmoException {
return getEvents(PARAM_HOME_ID, homeId, PARAM_PERSON_ID, personId, PARAM_OFFSET, 1);
}

public Collection<HomeEvent> getDeviceEvents(String homeId, String deviceId, String deviceType)
throws NetatmoException {
UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_GET_EVENTS, PARAM_HOME_ID, homeId, PARAM_DEVICE_ID, deviceId,
PARAM_DEVICES_TYPE, deviceType);
BodyResponse<Home> body = get(uriBuilder, NAEventsDataResponse.class).getBody();
if (body != null) {
Home home = body.getElement();
if (home != null) {
return home.getEvents();
}
}
throw new NetatmoException("home should not be null");
return getEvents(PARAM_HOME_ID, homeId, PARAM_DEVICE_ID, deviceId, PARAM_DEVICES_TYPE, deviceType);
}

public String ping(String vpnUrl) throws NetatmoException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -97,9 +96,8 @@ protected void beforeNewData() {
public List<NAObject> updateReadings() {
List<NAObject> result = new ArrayList<>();
securityCapability.ifPresent(cap -> {
Collection<HomeEvent> events = cap.getDeviceEvents(handler.getId(), moduleType.apiName);
if (!events.isEmpty()) {
HomeEvent event = events.iterator().next();
HomeEvent event = cap.getLastDeviceEvent(handler.getId(), moduleType.apiName);
if (event != null) {
result.add(event);
result.addAll(event.getSubevents());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ protected List<NAObject> updateReadings(HomeApi api) {
result.add(homeStatus);
}
} catch (NetatmoException e) {
logger.warn("Error gettting Home informations : {}", e.getMessage());
logger.warn("Error getting Home informations : {}", e.getMessage());
}
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand Down Expand Up @@ -90,9 +89,9 @@ public void updateEvent(Event event) {
public List<NAObject> updateReadings() {
List<NAObject> result = new ArrayList<>();
securityCapability.ifPresent(cap -> {
Collection<HomeEvent> events = cap.getPersonEvents(handler.getId());
if (!events.isEmpty()) {
result.add(events.iterator().next());
HomeEvent event = cap.getLastPersonEvent(handler.getId());
if (event != null) {
result.add(event);
}
});
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
*/
package org.openhab.binding.netatmo.internal.handler.capability;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
Expand All @@ -27,6 +30,7 @@
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.HomeStatus;
import org.openhab.binding.netatmo.internal.api.dto.NAObject;
import org.openhab.binding.netatmo.internal.deserialization.NAObjectMap;
import org.openhab.binding.netatmo.internal.handler.CommonInterface;
import org.slf4j.Logger;
Expand All @@ -42,6 +46,8 @@
class SecurityCapability extends RestCapability<SecurityApi> {
private final Logger logger = LoggerFactory.getLogger(SecurityCapability.class);

private static final Map<String, HomeEvent> eventBuffer = new HashMap<>();

SecurityCapability(CommonInterface handler) {
super(handler, SecurityApi.class);
}
Expand Down Expand Up @@ -110,7 +116,55 @@ protected void updateHomeEvent(HomeEvent homeEvent) {
});
}

public Collection<HomeEvent> getDeviceEvents(String cameraId, String deviceType) {
@Override
protected List<NAObject> updateReadings(SecurityApi api) {
List<NAObject> result = new ArrayList<>();
try {
Collection<HomeEvent> lastEvents = api.getHomeEvents(handler.getId());
lastEvents.stream().forEach(event -> {
HomeEvent previousEvent = eventBuffer.get(event.getCameraId());
if (previousEvent == null || previousEvent.getTime().isBefore(event.getTime())) {
eventBuffer.put(event.getCameraId(), event);
}
String personId = event.getPersonId();
if (personId != null) {
previousEvent = eventBuffer.get(personId);
if (previousEvent == null || previousEvent.getTime().isBefore(event.getTime())) {
eventBuffer.put(personId, event);
}
}
});
} catch (NetatmoException e) {
logger.warn("Error retrieving last events for home '{}' : {}", handler.getId(), e.getMessage());
}
return result;
}

public @Nullable HomeEvent getLastPersonEvent(String personId) {
HomeEvent event = eventBuffer.get(personId);
if (event == null) {
Collection<HomeEvent> events = requestPersonEvents(personId);
if (!events.isEmpty()) {
event = events.iterator().next();
eventBuffer.put(personId, event);
}
}
return event;
}

public @Nullable HomeEvent getLastDeviceEvent(String cameraId, String deviceType) {
HomeEvent event = eventBuffer.get(cameraId);
if (event == null) {
Collection<HomeEvent> events = requestDeviceEvents(cameraId, deviceType);
if (!events.isEmpty()) {
event = events.iterator().next();
eventBuffer.put(cameraId, event);
}
}
return event;
}

private Collection<HomeEvent> requestDeviceEvents(String cameraId, String deviceType) {
return getApi().map(api -> {
try {
return api.getDeviceEvents(handler.getId(), cameraId, deviceType);
Expand All @@ -121,7 +175,7 @@ public Collection<HomeEvent> getDeviceEvents(String cameraId, String deviceType)
}).orElse(List.of());
}

public Collection<HomeEvent> getPersonEvents(String personId) {
private Collection<HomeEvent> requestPersonEvents(String personId) {
return getApi().map(api -> {
try {
return api.getPersonEvents(handler.getId(), personId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
package org.openhab.binding.netatmo.internal.handler.capability;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.eclipse.jdt.annotation.NonNullByDefault;
Expand Down Expand Up @@ -41,9 +40,9 @@ public SmokeCapability(CommonInterface handler, NetatmoDescriptionProvider descr
public List<NAObject> updateReadings() {
List<NAObject> result = new ArrayList<>();
securityCapability.ifPresent(cap -> {
Collection<HomeEvent> events = cap.getDeviceEvents(handler.getId(), moduleType.apiName);
if (!events.isEmpty()) {
result.add(events.iterator().next());
HomeEvent event = cap.getLastDeviceEvent(handler.getId(), moduleType.apiName);
if (event != null) {
result.add(event);
}
});
return result;
Expand Down

0 comments on commit 83e0ccb

Please sign in to comment.