[Netatmo] Add the capability to have a single home (#14595)
* Adding the capability to have a single home, common to energy and security --------- Signed-off-by: clinique <gael@lhopital.org>
This commit is contained in:
parent
f2e7597db6
commit
f37c4e555d
@ -444,11 +444,31 @@ All these channels except setpoint and setpoint-mode are read only.
|
|||||||
| battery | low-battery | Switch | Low battery |
|
| battery | low-battery | Switch | Low battery |
|
||||||
| battery | status | String | Description of the battery status (*) |
|
| battery | status | String | Description of the battery status (*) |
|
||||||
|
|
||||||
### Welcome Home
|
### Home
|
||||||
|
|
||||||
All these channels are read only.
|
A Home is the Thing holding various modules and devices. They can hold two areas of equipments : Security and Energy.
|
||||||
|
Depending on the way it is configured the behaviour will be adapted and available channels can vary.
|
||||||
|
|
||||||
**Supported channels for the Home thing:**
|
**Home Configuration**
|
||||||
|
|
||||||
|
The Home thing has the following configuration elements:
|
||||||
|
|
||||||
|
| Parameter | Type | Required | Description |
|
||||||
|
| ---------- | ------ | -------- | ----------------------------------------------------------------------------------- |
|
||||||
|
| id (1) | String | No | If you have a single type of equipment, this id is to be used for the home |
|
||||||
|
| energyId | String | No | Id of a home holding energy control devices |
|
||||||
|
| 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
|
||||||
|
|
||||||
|
(1) this parameter is only kept for backward compatibility.
|
||||||
|
|
||||||
|
All channels are read only.
|
||||||
|
|
||||||
|
**Supported channels for the Security Home thing:**
|
||||||
|
|
||||||
| Channel Group | Channel Id | Item Type | Description |
|
| Channel Group | Channel Id | Item Type | Description |
|
||||||
| ------------- | ---------------------- | --------- | ------------------------------------------------ |
|
| ------------- | ---------------------- | --------- | ------------------------------------------------ |
|
||||||
@ -456,9 +476,7 @@ All these channels are read only.
|
|||||||
| security | unknown-person-count | Number | Total number of unknown persons that are at home |
|
| security | unknown-person-count | Number | Total number of unknown persons that are at home |
|
||||||
| security | unknown-person-picture | Image | Snapshot of unknown person that is at home |
|
| security | unknown-person-picture | Image | Snapshot of unknown person that is at home |
|
||||||
|
|
||||||
All these channels are read only.
|
**Supported trigger channels for the Security Home thing:**
|
||||||
|
|
||||||
**Supported trigger channels for the Home thing:**
|
|
||||||
|
|
||||||
| Channel Type ID | Options | Description |
|
| Channel Type ID | Options | Description |
|
||||||
| ---------------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ---------------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
@ -493,7 +511,7 @@ All these channels are read only.
|
|||||||
Warnings:
|
Warnings:
|
||||||
|
|
||||||
- The URL of the live snapshot is a fixed URL so the value of the channel cameraLivePictureUrl / welcomeCameraLivePictureUrl will never be updated once first set by the binding. So to get a refreshed picture, you need to use the refresh parameter in your sitemap image element.
|
- The URL of the live snapshot is a fixed URL so the value of the channel cameraLivePictureUrl / welcomeCameraLivePictureUrl will never be updated once first set by the binding. So to get a refreshed picture, you need to use the refresh parameter in your sitemap image element.
|
||||||
- Some features like the video surveillance are accessed via the local network, so it may be helpful to set a static IP address for the camera within your local network.
|
- Some features like the video monitoring are accessed via the local network, so it may be helpful to set a static IP address for the camera within your local network.
|
||||||
|
|
||||||
**Supported channels for the Welcome Camera thing:**
|
**Supported channels for the Welcome Camera thing:**
|
||||||
|
|
||||||
|
|||||||
@ -84,7 +84,7 @@ public class RoomActions implements ThingActions {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getEnergyCapability()
|
getEnergyCapability()
|
||||||
.ifPresent(cap -> cap.setRoomThermTemp(roomHandler.getId(), temp, endTime, SetpointMode.MANUAL));
|
.ifPresent(cap -> cap.setRoomThermTemp(roomHandler.getId(), SetpointMode.MANUAL, endTime, temp));
|
||||||
}
|
}
|
||||||
|
|
||||||
@RuleAction(label = "@text/actionSetThermRoomModeSetpointLabel", description = "@text/actionSetThermRoomModeSetpointDesc")
|
@RuleAction(label = "@text/actionSetThermRoomModeSetpointLabel", description = "@text/actionSetThermRoomModeSetpointDesc")
|
||||||
@ -123,7 +123,7 @@ public class RoomActions implements ThingActions {
|
|||||||
|
|
||||||
long setpointEnd = targetEndTime;
|
long setpointEnd = targetEndTime;
|
||||||
SetpointMode setpointMode = targetMode;
|
SetpointMode setpointMode = targetMode;
|
||||||
getEnergyCapability().ifPresent(cap -> cap.setRoomThermTemp(roomHandler.getId(), 0, setpointEnd, setpointMode));
|
getEnergyCapability().ifPresent(cap -> cap.setRoomThermTemp(roomHandler.getId(), setpointMode, setpointEnd, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setThermRoomTempSetpoint(ThingActions actions, @Nullable Double temp, @Nullable Long endTime) {
|
public static void setThermRoomTempSetpoint(ThingActions actions, @Nullable Double temp, @Nullable Long endTime) {
|
||||||
|
|||||||
@ -44,7 +44,8 @@ public class NAObject {
|
|||||||
return ignoredForThingUpdate;
|
return ignoredForThingUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIgnoredForThingUpdate(boolean ignoredForThingUpdate) {
|
public NAObject ignoringForThingUpdate() {
|
||||||
this.ignoredForThingUpdate = ignoredForThingUpdate;
|
this.ignoredForThingUpdate = true;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,10 +55,6 @@ public class NAThing extends NAObject implements NAModule {
|
|||||||
return localReachable != null ? localReachable : true;
|
return localReachable != null ? localReachable : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setReachable(boolean reachable) {
|
|
||||||
this.reachable = reachable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @Nullable Dashboard getDashboardData() {
|
public @Nullable Dashboard getDashboardData() {
|
||||||
return dashboardData;
|
return dashboardData;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||||
|
*
|
||||||
|
* See the NOTICE file(s) distributed with this work for additional
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.openhab.binding.netatmo.internal.config;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.FeatureArea;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link HomeConfiguration} is responsible for holding configuration information for any
|
||||||
|
* Netatmo Home - security or energy, or both
|
||||||
|
*
|
||||||
|
* @author Gaël L'hopital - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class HomeConfiguration extends NAThingConfiguration {
|
||||||
|
public String securityId = "";
|
||||||
|
public String energyId = "";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return getIdForArea(energyId.isBlank() ? FeatureArea.SECURITY : FeatureArea.ENERGY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIdForArea(FeatureArea feature) {
|
||||||
|
return FeatureArea.ENERGY.equals(feature) ? energyId.isBlank() ? id : energyId
|
||||||
|
: FeatureArea.SECURITY.equals(feature) ? securityId.isBlank() ? id : securityId : id;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -24,6 +24,10 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
|||||||
public class NAThingConfiguration {
|
public class NAThingConfiguration {
|
||||||
public static final String ID = "id";
|
public static final String ID = "id";
|
||||||
|
|
||||||
public String id = "";
|
protected String id = "";
|
||||||
public int refreshInterval = -1;
|
public int refreshInterval = -1;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import java.util.stream.Stream;
|
|||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.binding.netatmo.internal.api.data.ModuleType;
|
import org.openhab.binding.netatmo.internal.api.data.ModuleType;
|
||||||
|
import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.FeatureArea;
|
||||||
import org.openhab.binding.netatmo.internal.api.dto.NAObject;
|
import org.openhab.binding.netatmo.internal.api.dto.NAObject;
|
||||||
import org.openhab.binding.netatmo.internal.api.dto.NAThing;
|
import org.openhab.binding.netatmo.internal.api.dto.NAThing;
|
||||||
import org.openhab.binding.netatmo.internal.config.NAThingConfiguration;
|
import org.openhab.binding.netatmo.internal.config.NAThingConfiguration;
|
||||||
@ -32,6 +33,7 @@ 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.HomeCapability;
|
||||||
import org.openhab.binding.netatmo.internal.handler.capability.RefreshCapability;
|
import org.openhab.binding.netatmo.internal.handler.capability.RefreshCapability;
|
||||||
import org.openhab.binding.netatmo.internal.handler.capability.RestCapability;
|
import org.openhab.binding.netatmo.internal.handler.capability.RestCapability;
|
||||||
|
import org.openhab.core.config.core.Configuration;
|
||||||
import org.openhab.core.thing.Bridge;
|
import org.openhab.core.thing.Bridge;
|
||||||
import org.openhab.core.thing.Channel;
|
import org.openhab.core.thing.Channel;
|
||||||
import org.openhab.core.thing.ChannelUID;
|
import org.openhab.core.thing.ChannelUID;
|
||||||
@ -107,7 +109,11 @@ public interface CommonInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
default String getId() {
|
default String getId() {
|
||||||
return (String) getThing().getConfiguration().get(NAThingConfiguration.ID);
|
return getConfiguration().as(NAThingConfiguration.class).getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
default Configuration getConfiguration() {
|
||||||
|
return getThing().getConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
default Stream<Channel> getActiveChannels() {
|
default Stream<Channel> getActiveChannels() {
|
||||||
@ -135,6 +141,10 @@ public interface CommonInterface {
|
|||||||
return List.of();
|
return List.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default Stream<CommonInterface> getActiveChildren(FeatureArea area) {
|
||||||
|
return getActiveChildren().stream().filter(child -> child.getModuleType().feature == area);
|
||||||
|
}
|
||||||
|
|
||||||
default <T extends RestCapability<?>> Optional<T> getHomeCapability(Class<T> clazz) {
|
default <T extends RestCapability<?>> Optional<T> getHomeCapability(Class<T> clazz) {
|
||||||
return getHomeHandler().map(handler -> handler.getCapabilities().get(clazz)).orElse(Optional.empty());
|
return getHomeHandler().map(handler -> handler.getCapabilities().get(clazz)).orElse(Optional.empty());
|
||||||
}
|
}
|
||||||
@ -197,7 +207,6 @@ public interface CommonInterface {
|
|||||||
} else {
|
} else {
|
||||||
setThingStatus(ThingStatus.UNKNOWN, ThingStatusDetail.NONE, null);
|
setThingStatus(ThingStatus.UNKNOWN, ThingStatusDetail.NONE, null);
|
||||||
setRefreshCapability();
|
setRefreshCapability();
|
||||||
getCapabilities().values().forEach(cap -> cap.initialize());
|
|
||||||
getScheduler().schedule(() -> {
|
getScheduler().schedule(() -> {
|
||||||
CommonInterface bridgeHandler = getBridgeHandler();
|
CommonInterface bridgeHandler = getBridgeHandler();
|
||||||
if (bridgeHandler != null) {
|
if (bridgeHandler != null) {
|
||||||
@ -207,9 +216,12 @@ public interface CommonInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default ModuleType getModuleType() {
|
||||||
|
return ModuleType.from(getThing().getThingTypeUID());
|
||||||
|
}
|
||||||
|
|
||||||
default void setRefreshCapability() {
|
default void setRefreshCapability() {
|
||||||
ModuleType moduleType = ModuleType.from(getThing().getThingTypeUID());
|
if (ModuleType.ACCOUNT.equals(getModuleType().getBridge())) {
|
||||||
if (ModuleType.ACCOUNT.equals(moduleType.getBridge())) {
|
|
||||||
NAThingConfiguration config = getThing().getConfiguration().as(NAThingConfiguration.class);
|
NAThingConfiguration config = getThing().getConfiguration().as(NAThingConfiguration.class);
|
||||||
getCapabilities().put(new RefreshCapability(this, getScheduler(), config.refreshInterval));
|
getCapabilities().put(new RefreshCapability(this, getScheduler(), config.refreshInterval));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,7 +89,7 @@ public class CameraCapability extends HomeSecurityThingCapability {
|
|||||||
@Override
|
@Override
|
||||||
protected void beforeNewData() {
|
protected void beforeNewData() {
|
||||||
super.beforeNewData();
|
super.beforeNewData();
|
||||||
homeCapability.ifPresent(cap -> {
|
securityCapability.ifPresent(cap -> {
|
||||||
NAObjectMap<HomeDataPerson> persons = cap.getPersons();
|
NAObjectMap<HomeDataPerson> persons = cap.getPersons();
|
||||||
descriptionProvider.setStateOptions(personChannelUID, persons.values().stream()
|
descriptionProvider.setStateOptions(personChannelUID, persons.values().stream()
|
||||||
.map(p -> new StateOption(p.getId(), p.getName())).collect(Collectors.toList()));
|
.map(p -> new StateOption(p.getId(), p.getName())).collect(Collectors.toList()));
|
||||||
|
|||||||
@ -28,9 +28,10 @@ public class CapabilityMap extends ConcurrentHashMap<Class<?>, Capability> {
|
|||||||
private static final long serialVersionUID = -3043492242108419801L;
|
private static final long serialVersionUID = -3043492242108419801L;
|
||||||
|
|
||||||
public void put(Capability capability) {
|
public void put(Capability capability) {
|
||||||
Class<? extends Capability> clazz = capability.getClass();
|
Class<?> clazz = capability.getClass();
|
||||||
if (super.get(clazz) == null) {
|
if (super.get(clazz) == null) {
|
||||||
super.put(clazz, capability);
|
super.put(clazz, capability);
|
||||||
|
capability.initialize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import java.util.stream.Collectors;
|
|||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.openhab.binding.netatmo.internal.api.EnergyApi;
|
import org.openhab.binding.netatmo.internal.api.EnergyApi;
|
||||||
import org.openhab.binding.netatmo.internal.api.NetatmoException;
|
import org.openhab.binding.netatmo.internal.api.NetatmoException;
|
||||||
|
import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.FeatureArea;
|
||||||
import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.SetpointMode;
|
import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.SetpointMode;
|
||||||
import org.openhab.binding.netatmo.internal.api.dto.HomeData;
|
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.HomeDataModule;
|
||||||
@ -27,6 +28,7 @@ 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.HomeStatusModule;
|
||||||
import org.openhab.binding.netatmo.internal.api.dto.NAHomeStatus.HomeStatus;
|
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.api.dto.Room;
|
||||||
|
import org.openhab.binding.netatmo.internal.config.HomeConfiguration;
|
||||||
import org.openhab.binding.netatmo.internal.deserialization.NAObjectMap;
|
import org.openhab.binding.netatmo.internal.deserialization.NAObjectMap;
|
||||||
import org.openhab.binding.netatmo.internal.handler.CommonInterface;
|
import org.openhab.binding.netatmo.internal.handler.CommonInterface;
|
||||||
import org.openhab.binding.netatmo.internal.providers.NetatmoDescriptionProvider;
|
import org.openhab.binding.netatmo.internal.providers.NetatmoDescriptionProvider;
|
||||||
@ -48,31 +50,32 @@ public class EnergyCapability extends RestCapability<EnergyApi> {
|
|||||||
|
|
||||||
private int setPointDefaultDuration = -1;
|
private int setPointDefaultDuration = -1;
|
||||||
private final NetatmoDescriptionProvider descriptionProvider;
|
private final NetatmoDescriptionProvider descriptionProvider;
|
||||||
|
private String energyId = "";
|
||||||
|
|
||||||
EnergyCapability(CommonInterface handler, NetatmoDescriptionProvider descriptionProvider) {
|
EnergyCapability(CommonInterface handler, NetatmoDescriptionProvider descriptionProvider) {
|
||||||
super(handler, EnergyApi.class);
|
super(handler, EnergyApi.class);
|
||||||
this.descriptionProvider = descriptionProvider;
|
this.descriptionProvider = descriptionProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
super.initialize();
|
||||||
|
energyId = handler.getConfiguration().as(HomeConfiguration.class).getIdForArea(FeatureArea.ENERGY);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateHomeData(HomeData homeData) {
|
protected void updateHomeData(HomeData homeData) {
|
||||||
NAObjectMap<HomeDataRoom> rooms = homeData.getRooms();
|
NAObjectMap<HomeDataRoom> rooms = homeData.getRooms();
|
||||||
NAObjectMap<HomeDataModule> modules = homeData.getModules();
|
NAObjectMap<HomeDataModule> modules = homeData.getModules();
|
||||||
handler.getActiveChildren().forEach(childHandler -> {
|
handler.getActiveChildren(FeatureArea.ENERGY).forEach(childHandler -> {
|
||||||
String childId = childHandler.getId();
|
String childId = childHandler.getId();
|
||||||
rooms.getOpt(childId).ifPresentOrElse(roomData -> {
|
rooms.getOpt(childId)
|
||||||
roomData.setIgnoredForThingUpdate(true);
|
.ifPresentOrElse(roomData -> childHandler.setNewData(roomData.ignoringForThingUpdate()), () -> {
|
||||||
childHandler.setNewData(roomData);
|
modules.getOpt(childId)
|
||||||
}, () -> {
|
.ifPresent(childData -> childHandler.setNewData(childData.ignoringForThingUpdate()));
|
||||||
modules.getOpt(childId).ifPresent(childData -> {
|
modules.values().stream().filter(module -> childId.equals(module.getBridge()))
|
||||||
childData.setIgnoredForThingUpdate(true);
|
.forEach(bridgedModule -> childHandler.setNewData(bridgedModule));
|
||||||
childHandler.setNewData(childData);
|
});
|
||||||
});
|
|
||||||
modules.values().stream().filter(module -> childId.equals(module.getBridge()))
|
|
||||||
.forEach(bridgedModule -> {
|
|
||||||
childHandler.setNewData(bridgedModule);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
descriptionProvider.setStateOptions(new ChannelUID(thing.getUID(), GROUP_ENERGY, CHANNEL_PLANNING),
|
descriptionProvider.setStateOptions(new ChannelUID(thing.getUID(), GROUP_ENERGY, CHANNEL_PLANNING),
|
||||||
homeData.getThermSchedules().stream().map(p -> new StateOption(p.getId(), p.getName()))
|
homeData.getThermSchedules().stream().map(p -> new StateOption(p.getId(), p.getName()))
|
||||||
@ -84,46 +87,22 @@ public class EnergyCapability extends RestCapability<EnergyApi> {
|
|||||||
protected void updateHomeStatus(HomeStatus homeStatus) {
|
protected void updateHomeStatus(HomeStatus homeStatus) {
|
||||||
NAObjectMap<Room> rooms = homeStatus.getRooms();
|
NAObjectMap<Room> rooms = homeStatus.getRooms();
|
||||||
NAObjectMap<HomeStatusModule> modules = homeStatus.getModules();
|
NAObjectMap<HomeStatusModule> modules = homeStatus.getModules();
|
||||||
handler.getActiveChildren().forEach(childHandler -> {
|
handler.getActiveChildren(FeatureArea.ENERGY).forEach(childHandler -> {
|
||||||
String childId = childHandler.getId();
|
String childId = childHandler.getId();
|
||||||
rooms.getOpt(childId).ifPresentOrElse(roomData -> childHandler.setNewData(roomData), () -> {
|
rooms.getOpt(childId).ifPresentOrElse(roomData -> childHandler.setNewData(roomData), () -> {
|
||||||
modules.getOpt(childId).ifPresentOrElse(childData -> {
|
modules.getOpt(childId).ifPresent(moduleData -> {
|
||||||
childHandler.setNewData(childData);
|
childHandler.setNewData(moduleData);
|
||||||
modules.values().stream().filter(module -> childId.equals(module.getBridge()))
|
modules.values().stream().filter(module -> childId.equals(module.getBridge()))
|
||||||
.forEach(bridgedModule -> {
|
.forEach(bridgedModule -> childHandler.setNewData(bridgedModule));
|
||||||
childHandler.setNewData(bridgedModule);
|
|
||||||
});
|
|
||||||
|
|
||||||
}, () -> {
|
|
||||||
// This module is not present in the homestatus data, so it is considered as unreachable
|
|
||||||
HomeStatusModule module = new HomeStatusModule();
|
|
||||||
module.setReachable(false);
|
|
||||||
childHandler.setNewData(module);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSetpointDefaultDuration() {
|
public void setThermPoint(String roomId, SetpointMode mode, long endtime, double temp) {
|
||||||
return setPointDefaultDuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRoomThermMode(String roomId, SetpointMode targetMode) {
|
|
||||||
getApi().ifPresent(api -> {
|
getApi().ifPresent(api -> {
|
||||||
try {
|
try {
|
||||||
api.setThermpoint(handler.getId(), roomId, targetMode,
|
api.setThermpoint(energyId, roomId, mode, endtime, temp);
|
||||||
targetMode == SetpointMode.MAX ? setpointEndTimeFromNow(setPointDefaultDuration) : 0, 0);
|
|
||||||
handler.expireData();
|
|
||||||
} catch (NetatmoException e) {
|
|
||||||
logger.warn("Error setting room thermostat mode '{}' : {}", targetMode, e.getMessage());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRoomThermTemp(String roomId, double temperature, long endtime, SetpointMode mode) {
|
|
||||||
getApi().ifPresent(api -> {
|
|
||||||
try {
|
|
||||||
api.setThermpoint(handler.getId(), roomId, mode, endtime, temperature);
|
|
||||||
handler.expireData();
|
handler.expireData();
|
||||||
} catch (NetatmoException e) {
|
} catch (NetatmoException e) {
|
||||||
logger.warn("Error setting room thermostat mode '{}' : {}", mode, e.getMessage());
|
logger.warn("Error setting room thermostat mode '{}' : {}", mode, e.getMessage());
|
||||||
@ -131,8 +110,16 @@ public class EnergyCapability extends RestCapability<EnergyApi> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRoomThermTemp(String roomId, double temperature) {
|
public void setRoomThermTemp(String roomId, SetpointMode mode, long endtime, double temp) {
|
||||||
setRoomThermTemp(roomId, temperature, setpointEndTimeFromNow(setPointDefaultDuration), SetpointMode.MANUAL);
|
setThermPoint(roomId, mode, endtime, temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRoomThermMode(String roomId, SetpointMode targetMode) {
|
||||||
|
setThermPoint(roomId, targetMode, targetMode == SetpointMode.MAX ? setpointEndTimeFromNow() : 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRoomThermTemp(String roomId, double temp) {
|
||||||
|
setThermPoint(roomId, SetpointMode.MANUAL, setpointEndTimeFromNow(), temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -141,7 +128,7 @@ public class EnergyCapability extends RestCapability<EnergyApi> {
|
|||||||
try {
|
try {
|
||||||
switch (channelName) {
|
switch (channelName) {
|
||||||
case CHANNEL_PLANNING:
|
case CHANNEL_PLANNING:
|
||||||
api.switchSchedule(handler.getId(), command.toString());
|
api.switchSchedule(energyId, command.toString());
|
||||||
break;
|
break;
|
||||||
case CHANNEL_SETPOINT_MODE:
|
case CHANNEL_SETPOINT_MODE:
|
||||||
SetpointMode targetMode = SetpointMode.valueOf(command.toString());
|
SetpointMode targetMode = SetpointMode.valueOf(command.toString());
|
||||||
@ -149,7 +136,7 @@ public class EnergyCapability extends RestCapability<EnergyApi> {
|
|||||||
logger.info("Switch to 'Manual' is done by setting a setpoint temp, command ignored");
|
logger.info("Switch to 'Manual' is done by setting a setpoint temp, command ignored");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
api.setThermMode(handler.getId(), targetMode.apiDescriptor);
|
api.setThermMode(energyId, targetMode.apiDescriptor);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
handler.expireData();
|
handler.expireData();
|
||||||
@ -161,7 +148,7 @@ public class EnergyCapability extends RestCapability<EnergyApi> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long setpointEndTimeFromNow(int duration_min) {
|
private long setpointEndTimeFromNow() {
|
||||||
return ZonedDateTime.now().plusMinutes(duration_min).toEpochSecond();
|
return ZonedDateTime.now().plusMinutes(setPointDefaultDuration).toEpochSecond();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,7 @@ package org.openhab.binding.netatmo.internal.handler.capability;
|
|||||||
import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*;
|
import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -25,12 +26,10 @@ import org.openhab.binding.netatmo.internal.api.HomeApi;
|
|||||||
import org.openhab.binding.netatmo.internal.api.NetatmoException;
|
import org.openhab.binding.netatmo.internal.api.NetatmoException;
|
||||||
import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.FeatureArea;
|
import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.FeatureArea;
|
||||||
import org.openhab.binding.netatmo.internal.api.dto.HomeData;
|
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.HomeDataPerson;
|
|
||||||
import org.openhab.binding.netatmo.internal.api.dto.Location;
|
import org.openhab.binding.netatmo.internal.api.dto.Location;
|
||||||
import org.openhab.binding.netatmo.internal.api.dto.NAHomeStatus.HomeStatus;
|
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.api.dto.NAObject;
|
||||||
import org.openhab.binding.netatmo.internal.deserialization.NAObjectMap;
|
import org.openhab.binding.netatmo.internal.config.HomeConfiguration;
|
||||||
import org.openhab.binding.netatmo.internal.handler.CommonInterface;
|
import org.openhab.binding.netatmo.internal.handler.CommonInterface;
|
||||||
import org.openhab.binding.netatmo.internal.providers.NetatmoDescriptionProvider;
|
import org.openhab.binding.netatmo.internal.providers.NetatmoDescriptionProvider;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -44,77 +43,74 @@ import org.slf4j.LoggerFactory;
|
|||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class HomeCapability extends RestCapability<HomeApi> {
|
public class HomeCapability extends RestCapability<HomeApi> {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(HomeCapability.class);
|
private final Logger logger = LoggerFactory.getLogger(HomeCapability.class);
|
||||||
|
private final Set<FeatureArea> featureAreas = new HashSet<>();
|
||||||
private final NetatmoDescriptionProvider descriptionProvider;
|
private final NetatmoDescriptionProvider descriptionProvider;
|
||||||
|
private Set<String> homeIds = Set.of();
|
||||||
private NAObjectMap<HomeDataPerson> persons = new NAObjectMap<>();
|
|
||||||
private NAObjectMap<HomeDataModule> modules = new NAObjectMap<>();
|
|
||||||
|
|
||||||
private Set<FeatureArea> featuresArea = Set.of();
|
|
||||||
|
|
||||||
public HomeCapability(CommonInterface handler, NetatmoDescriptionProvider descriptionProvider) {
|
public HomeCapability(CommonInterface handler, NetatmoDescriptionProvider descriptionProvider) {
|
||||||
super(handler, HomeApi.class);
|
super(handler, HomeApi.class);
|
||||||
this.descriptionProvider = descriptionProvider;
|
this.descriptionProvider = descriptionProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize() {
|
||||||
|
super.initialize();
|
||||||
|
HomeConfiguration config = handler.getConfiguration().as(HomeConfiguration.class);
|
||||||
|
homeIds = Set.of(config.getId(), config.energyId, config.securityId);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateHomeData(HomeData home) {
|
protected void updateHomeData(HomeData home) {
|
||||||
featuresArea = home.getFeatures();
|
if (hasArea(FeatureArea.SECURITY) && !handler.getCapabilities().containsKey(SecurityCapability.class)) {
|
||||||
if (hasFeature(FeatureArea.SECURITY) && !handler.getCapabilities().containsKey(SecurityCapability.class)) {
|
|
||||||
handler.getCapabilities().put(new SecurityCapability(handler));
|
handler.getCapabilities().put(new SecurityCapability(handler));
|
||||||
}
|
}
|
||||||
if (hasFeature(FeatureArea.ENERGY) && !handler.getCapabilities().containsKey(EnergyCapability.class)) {
|
if (hasArea(FeatureArea.ENERGY) && !handler.getCapabilities().containsKey(EnergyCapability.class)) {
|
||||||
handler.getCapabilities().put(new EnergyCapability(handler, descriptionProvider));
|
handler.getCapabilities().put(new EnergyCapability(handler, descriptionProvider));
|
||||||
}
|
}
|
||||||
if (firstLaunch) {
|
if (firstLaunch) {
|
||||||
home.getCountry().map(country -> properties.put(PROPERTY_COUNTRY, country));
|
home.getCountry().map(country -> properties.put(PROPERTY_COUNTRY, country));
|
||||||
home.getTimezone().map(tz -> properties.put(PROPERTY_TIMEZONE, tz));
|
home.getTimezone().map(tz -> properties.put(PROPERTY_TIMEZONE, tz));
|
||||||
properties.put(GROUP_LOCATION, ((Location) home).getLocation().toString());
|
properties.put(GROUP_LOCATION, ((Location) home).getLocation().toString());
|
||||||
properties.put(PROPERTY_FEATURE, featuresArea.stream().map(f -> f.name()).collect(Collectors.joining(",")));
|
properties.put(PROPERTY_FEATURE,
|
||||||
|
featureAreas.stream().map(FeatureArea::name).collect(Collectors.joining(",")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void afterNewData(@Nullable NAObject newData) {
|
protected void afterNewData(@Nullable NAObject newData) {
|
||||||
super.afterNewData(newData);
|
super.afterNewData(newData);
|
||||||
if (firstLaunch && !hasFeature(FeatureArea.SECURITY)) {
|
if (firstLaunch && !hasArea(FeatureArea.SECURITY)) {
|
||||||
handler.removeChannels(thing.getChannelsOfGroup(GROUP_SECURITY));
|
handler.removeChannels(thing.getChannelsOfGroup(GROUP_SECURITY));
|
||||||
}
|
}
|
||||||
if (firstLaunch && !hasFeature(FeatureArea.ENERGY)) {
|
if (firstLaunch && !hasArea(FeatureArea.ENERGY)) {
|
||||||
handler.removeChannels(thing.getChannelsOfGroup(GROUP_ENERGY));
|
handler.removeChannels(thing.getChannelsOfGroup(GROUP_ENERGY));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasFeature(FeatureArea seeked) {
|
private boolean hasArea(FeatureArea searched) {
|
||||||
return featuresArea.contains(seeked);
|
return featureAreas.contains(searched);
|
||||||
}
|
|
||||||
|
|
||||||
public NAObjectMap<HomeDataPerson> getPersons() {
|
|
||||||
return persons;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NAObjectMap<HomeDataModule> getModules() {
|
|
||||||
return modules;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<NAObject> updateReadings(HomeApi api) {
|
protected List<NAObject> updateReadings(HomeApi api) {
|
||||||
List<NAObject> result = new ArrayList<>();
|
List<NAObject> result = new ArrayList<>();
|
||||||
try {
|
homeIds.stream().filter(id -> !id.isEmpty()).forEach(id -> {
|
||||||
HomeData homeData = api.getHomeData(handler.getId());
|
try {
|
||||||
if (homeData != null) {
|
HomeData homeData = api.getHomeData(id);
|
||||||
result.add(homeData);
|
if (homeData != null) {
|
||||||
persons = homeData.getPersons();
|
result.add(homeData);
|
||||||
modules = homeData.getModules();
|
featureAreas.addAll(homeData.getFeatures());
|
||||||
|
}
|
||||||
|
HomeStatus homeStatus = api.getHomeStatus(id);
|
||||||
|
if (homeStatus != null) {
|
||||||
|
result.add(homeStatus);
|
||||||
|
}
|
||||||
|
} catch (NetatmoException e) {
|
||||||
|
logger.warn("Error getting Home informations : {}", e.getMessage());
|
||||||
}
|
}
|
||||||
HomeStatus homeStatus = api.getHomeStatus(handler.getId());
|
});
|
||||||
if (homeStatus != null) {
|
|
||||||
result.add(homeStatus);
|
|
||||||
}
|
|
||||||
} catch (NetatmoException e) {
|
|
||||||
logger.warn("Error getting Home informations : {}", e.getMessage());
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,7 +56,7 @@ public class PersonCapability extends HomeSecurityThingCapability {
|
|||||||
@Override
|
@Override
|
||||||
protected void beforeNewData() {
|
protected void beforeNewData() {
|
||||||
super.beforeNewData();
|
super.beforeNewData();
|
||||||
homeCapability.ifPresent(cap -> {
|
securityCapability.ifPresent(cap -> {
|
||||||
Stream<HomeDataModule> cameras = cap.getModules().values().stream()
|
Stream<HomeDataModule> cameras = cap.getModules().values().stream()
|
||||||
.filter(module -> module.getType() == ModuleType.WELCOME);
|
.filter(module -> module.getType() == ModuleType.WELCOME);
|
||||||
descriptionProvider.setStateOptions(cameraChannelUID,
|
descriptionProvider.setStateOptions(cameraChannelUID,
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
|||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.binding.netatmo.internal.api.NetatmoException;
|
import org.openhab.binding.netatmo.internal.api.NetatmoException;
|
||||||
import org.openhab.binding.netatmo.internal.api.SecurityApi;
|
import org.openhab.binding.netatmo.internal.api.SecurityApi;
|
||||||
|
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.data.NetatmoConstants.FloodLightMode;
|
||||||
import org.openhab.binding.netatmo.internal.api.dto.HomeData;
|
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.HomeDataModule;
|
||||||
@ -32,6 +33,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.HomeStatusPerson;
|
||||||
import org.openhab.binding.netatmo.internal.api.dto.NAHomeStatus.HomeStatus;
|
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.api.dto.NAObject;
|
||||||
|
import org.openhab.binding.netatmo.internal.config.HomeConfiguration;
|
||||||
import org.openhab.binding.netatmo.internal.deserialization.NAObjectMap;
|
import org.openhab.binding.netatmo.internal.deserialization.NAObjectMap;
|
||||||
import org.openhab.binding.netatmo.internal.handler.CommonInterface;
|
import org.openhab.binding.netatmo.internal.handler.CommonInterface;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -50,6 +52,10 @@ class SecurityCapability extends RestCapability<SecurityApi> {
|
|||||||
private final Map<String, HomeEvent> eventBuffer = new HashMap<>();
|
private final Map<String, HomeEvent> eventBuffer = new HashMap<>();
|
||||||
private @Nullable ZonedDateTime freshestEventTime;
|
private @Nullable ZonedDateTime freshestEventTime;
|
||||||
|
|
||||||
|
private NAObjectMap<HomeDataPerson> persons = new NAObjectMap<>();
|
||||||
|
private NAObjectMap<HomeDataModule> modules = new NAObjectMap<>();
|
||||||
|
private String securityId = "";
|
||||||
|
|
||||||
SecurityCapability(CommonInterface handler) {
|
SecurityCapability(CommonInterface handler) {
|
||||||
super(handler, SecurityApi.class);
|
super(handler, SecurityApi.class);
|
||||||
}
|
}
|
||||||
@ -58,27 +64,22 @@ class SecurityCapability extends RestCapability<SecurityApi> {
|
|||||||
public void initialize() {
|
public void initialize() {
|
||||||
super.initialize();
|
super.initialize();
|
||||||
freshestEventTime = null;
|
freshestEventTime = null;
|
||||||
|
securityId = handler.getConfiguration().as(HomeConfiguration.class).getIdForArea(FeatureArea.SECURITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateHomeData(HomeData homeData) {
|
protected void updateHomeData(HomeData homeData) {
|
||||||
NAObjectMap<HomeDataPerson> persons = homeData.getPersons();
|
persons = homeData.getPersons();
|
||||||
NAObjectMap<HomeDataModule> modules = homeData.getModules();
|
modules = homeData.getModules();
|
||||||
handler.getActiveChildren().forEach(childHandler -> {
|
handler.getActiveChildren(FeatureArea.SECURITY).forEach(childHandler -> {
|
||||||
String childId = childHandler.getId();
|
String childId = childHandler.getId();
|
||||||
persons.getOpt(childId).ifPresentOrElse(personData -> {
|
persons.getOpt(childId)
|
||||||
personData.setIgnoredForThingUpdate(true);
|
.ifPresentOrElse(personData -> childHandler.setNewData(personData.ignoringForThingUpdate()), () -> {
|
||||||
childHandler.setNewData(personData);
|
modules.getOpt(childId)
|
||||||
}, () -> {
|
.ifPresent(childData -> childHandler.setNewData(childData.ignoringForThingUpdate()));
|
||||||
modules.getOpt(childId).ifPresent(childData -> {
|
modules.values().stream().filter(module -> childId.equals(module.getBridge()))
|
||||||
childData.setIgnoredForThingUpdate(true);
|
.forEach(bridgedModule -> childHandler.setNewData(bridgedModule));
|
||||||
childHandler.setNewData(childData);
|
});
|
||||||
});
|
|
||||||
modules.values().stream().filter(module -> childId.equals(module.getBridge()))
|
|
||||||
.forEach(bridgedModule -> {
|
|
||||||
childHandler.setNewData(bridgedModule);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,21 +87,13 @@ class SecurityCapability extends RestCapability<SecurityApi> {
|
|||||||
protected void updateHomeStatus(HomeStatus homeStatus) {
|
protected void updateHomeStatus(HomeStatus homeStatus) {
|
||||||
NAObjectMap<HomeStatusPerson> persons = homeStatus.getPersons();
|
NAObjectMap<HomeStatusPerson> persons = homeStatus.getPersons();
|
||||||
NAObjectMap<HomeStatusModule> modules = homeStatus.getModules();
|
NAObjectMap<HomeStatusModule> modules = homeStatus.getModules();
|
||||||
handler.getActiveChildren().forEach(childHandler -> {
|
handler.getActiveChildren(FeatureArea.SECURITY).forEach(childHandler -> {
|
||||||
String childId = childHandler.getId();
|
String childId = childHandler.getId();
|
||||||
persons.getOpt(childId).ifPresentOrElse(personData -> childHandler.setNewData(personData), () -> {
|
persons.getOpt(childId).ifPresentOrElse(personData -> childHandler.setNewData(personData), () -> {
|
||||||
modules.getOpt(childId).ifPresentOrElse(childData -> {
|
modules.getOpt(childId).ifPresent(childData -> {
|
||||||
childHandler.setNewData(childData);
|
childHandler.setNewData(childData);
|
||||||
modules.values().stream().filter(module -> childId.equals(module.getBridge()))
|
modules.values().stream().filter(module -> childId.equals(module.getBridge()))
|
||||||
.forEach(bridgedModule -> {
|
.forEach(bridgedModule -> childHandler.setNewData(bridgedModule));
|
||||||
childHandler.setNewData(bridgedModule);
|
|
||||||
});
|
|
||||||
|
|
||||||
}, () -> {
|
|
||||||
// This module is not present in the homestatus data, so it is considered as unreachable
|
|
||||||
HomeStatusModule module = new HomeStatusModule();
|
|
||||||
module.setReachable(false);
|
|
||||||
childHandler.setNewData(module);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -108,27 +101,23 @@ class SecurityCapability extends RestCapability<SecurityApi> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateHomeEvent(HomeEvent homeEvent) {
|
protected void updateHomeEvent(HomeEvent homeEvent) {
|
||||||
String personId = homeEvent.getPersonId();
|
addEventIfKnownObject(homeEvent, homeEvent.getPersonId());
|
||||||
if (personId != null) {
|
addEventIfKnownObject(homeEvent, homeEvent.getCameraId());
|
||||||
handler.getActiveChildren().stream().filter(handler -> personId.equals(handler.getId())).findFirst()
|
}
|
||||||
.ifPresent(handler -> {
|
|
||||||
homeEvent.setIgnoredForThingUpdate(true);
|
private void addEventIfKnownObject(HomeEvent homeEvent, @Nullable String objectId) {
|
||||||
handler.setNewData(homeEvent);
|
if (objectId == null) {
|
||||||
});
|
return;
|
||||||
}
|
}
|
||||||
String cameraId = homeEvent.getCameraId();
|
handler.getActiveChildren(FeatureArea.SECURITY).filter(child -> child.getId().equals(objectId))
|
||||||
handler.getActiveChildren().stream().filter(handler -> cameraId.equals(handler.getId())).findFirst()
|
.forEach(child -> child.setNewData(homeEvent.ignoringForThingUpdate()));
|
||||||
.ifPresent(handler -> {
|
|
||||||
homeEvent.setIgnoredForThingUpdate(true);
|
|
||||||
handler.setNewData(homeEvent);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<NAObject> updateReadings(SecurityApi api) {
|
protected List<NAObject> updateReadings(SecurityApi api) {
|
||||||
List<NAObject> result = new ArrayList<>();
|
List<NAObject> result = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
for (HomeEvent event : api.getHomeEvents(handler.getId(), freshestEventTime)) {
|
for (HomeEvent event : api.getHomeEvents(securityId, freshestEventTime)) {
|
||||||
HomeEvent previousEvent = eventBuffer.get(event.getCameraId());
|
HomeEvent previousEvent = eventBuffer.get(event.getCameraId());
|
||||||
if (previousEvent == null || previousEvent.getTime().isBefore(event.getTime())) {
|
if (previousEvent == null || previousEvent.getTime().isBefore(event.getTime())) {
|
||||||
eventBuffer.put(event.getCameraId(), event);
|
eventBuffer.put(event.getCameraId(), event);
|
||||||
@ -145,11 +134,19 @@ class SecurityCapability extends RestCapability<SecurityApi> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (NetatmoException e) {
|
} catch (NetatmoException e) {
|
||||||
logger.warn("Error retrieving last events for home '{}' : {}", handler.getId(), e.getMessage());
|
logger.warn("Error retrieving last events for home '{}' : {}", securityId, e.getMessage());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NAObjectMap<HomeDataPerson> getPersons() {
|
||||||
|
return persons;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NAObjectMap<HomeDataModule> getModules() {
|
||||||
|
return modules;
|
||||||
|
}
|
||||||
|
|
||||||
public @Nullable HomeEvent getLastPersonEvent(String personId) {
|
public @Nullable HomeEvent getLastPersonEvent(String personId) {
|
||||||
HomeEvent event = eventBuffer.get(personId);
|
HomeEvent event = eventBuffer.get(personId);
|
||||||
if (event == null) {
|
if (event == null) {
|
||||||
@ -177,7 +174,7 @@ class SecurityCapability extends RestCapability<SecurityApi> {
|
|||||||
private Collection<HomeEvent> requestDeviceEvents(String moduleId, String deviceType) {
|
private Collection<HomeEvent> requestDeviceEvents(String moduleId, String deviceType) {
|
||||||
return getApi().map(api -> {
|
return getApi().map(api -> {
|
||||||
try {
|
try {
|
||||||
return api.getDeviceEvents(handler.getId(), moduleId, deviceType);
|
return api.getDeviceEvents(securityId, moduleId, deviceType);
|
||||||
} catch (NetatmoException e) {
|
} catch (NetatmoException e) {
|
||||||
logger.warn("Error retrieving last events of camera '{}' : {}", moduleId, e.getMessage());
|
logger.warn("Error retrieving last events of camera '{}' : {}", moduleId, e.getMessage());
|
||||||
return null;
|
return null;
|
||||||
@ -188,7 +185,7 @@ class SecurityCapability extends RestCapability<SecurityApi> {
|
|||||||
private Collection<HomeEvent> requestPersonEvents(String personId) {
|
private Collection<HomeEvent> requestPersonEvents(String personId) {
|
||||||
return getApi().map(api -> {
|
return getApi().map(api -> {
|
||||||
try {
|
try {
|
||||||
return api.getPersonEvents(handler.getId(), personId);
|
return api.getPersonEvents(securityId, personId);
|
||||||
} catch (NetatmoException e) {
|
} catch (NetatmoException e) {
|
||||||
logger.warn("Error retrieving last events of person '{}' : {}", personId, e.getMessage());
|
logger.warn("Error retrieving last events of person '{}' : {}", personId, e.getMessage());
|
||||||
return null;
|
return null;
|
||||||
@ -199,7 +196,7 @@ class SecurityCapability extends RestCapability<SecurityApi> {
|
|||||||
public void setPersonAway(String personId, boolean away) {
|
public void setPersonAway(String personId, boolean away) {
|
||||||
getApi().ifPresent(api -> {
|
getApi().ifPresent(api -> {
|
||||||
try {
|
try {
|
||||||
api.setPersonAwayStatus(handler.getId(), personId, away);
|
api.setPersonAwayStatus(securityId, personId, away);
|
||||||
handler.expireData();
|
handler.expireData();
|
||||||
} catch (NetatmoException e) {
|
} catch (NetatmoException e) {
|
||||||
logger.warn("Error setting person away/at home '{}' : {}", personId, e.getMessage());
|
logger.warn("Error setting person away/at home '{}' : {}", personId, e.getMessage());
|
||||||
@ -208,9 +205,7 @@ class SecurityCapability extends RestCapability<SecurityApi> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable String ping(String vpnUrl) {
|
public @Nullable String ping(String vpnUrl) {
|
||||||
return getApi().map(api -> {
|
return getApi().map(api -> api.ping(vpnUrl)).orElse(null);
|
||||||
return api.ping(vpnUrl);
|
|
||||||
}).orElse(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void changeStatus(@Nullable String localURL, boolean status) {
|
public void changeStatus(@Nullable String localURL, boolean status) {
|
||||||
@ -231,7 +226,7 @@ class SecurityCapability extends RestCapability<SecurityApi> {
|
|||||||
public void changeFloodlightMode(String cameraId, FloodLightMode mode) {
|
public void changeFloodlightMode(String cameraId, FloodLightMode mode) {
|
||||||
getApi().ifPresent(api -> {
|
getApi().ifPresent(api -> {
|
||||||
try {
|
try {
|
||||||
api.changeFloodLightMode(handler.getId(), cameraId, mode);
|
api.changeFloodLightMode(securityId, cameraId, mode);
|
||||||
handler.expireData();
|
handler.expireData();
|
||||||
} catch (NetatmoException e) {
|
} catch (NetatmoException e) {
|
||||||
logger.warn("Error changing Presence floodlight mode '{}' : {}", mode, e.getMessage());
|
logger.warn("Error changing Presence floodlight mode '{}' : {}", mode, e.getMessage());
|
||||||
|
|||||||
@ -111,11 +111,23 @@
|
|||||||
</config-description>
|
</config-description>
|
||||||
|
|
||||||
<config-description uri="netatmo:home">
|
<config-description uri="netatmo:home">
|
||||||
<parameter name="id" type="text" required="true">
|
<parameter name="id" type="text" required="false">
|
||||||
<label>@text/config.thingId.label</label>
|
<label>@text/config.thingId.label</label>
|
||||||
<description>@text/config.thingId.description</description>
|
<description>@text/config.thingId.description</description>
|
||||||
</parameter>
|
</parameter>
|
||||||
|
|
||||||
|
<parameter name="securityId" type="text" required="false">
|
||||||
|
<label>@text/config.securityId.label</label>
|
||||||
|
<description>@text/config.securityId.description</description>
|
||||||
|
<advanced>true</advanced>
|
||||||
|
</parameter>
|
||||||
|
|
||||||
|
<parameter name="energyId" type="text" required="false">
|
||||||
|
<label>@text/config.energyId.label</label>
|
||||||
|
<description>@text/config.energyId.description</description>
|
||||||
|
<advanced>true</advanced>
|
||||||
|
</parameter>
|
||||||
|
|
||||||
<parameter name="refreshInterval" type="integer" min="20" unit="s">
|
<parameter name="refreshInterval" type="integer" min="20" unit="s">
|
||||||
<label>@text/config.refreshInterval.label</label>
|
<label>@text/config.refreshInterval.label</label>
|
||||||
<description>@text/config.refreshInterval.description</description>
|
<description>@text/config.refreshInterval.description</description>
|
||||||
|
|||||||
@ -437,6 +437,10 @@ config.equipmentId.label = Equipment ID
|
|||||||
config.equipmentId.description = ID of the device (MAC address).
|
config.equipmentId.description = ID of the device (MAC address).
|
||||||
config.thingId.label = Thing ID
|
config.thingId.label = Thing ID
|
||||||
config.thingId.description = Unique identifier of the thing defined by Netatmo.
|
config.thingId.description = Unique identifier of the thing defined by Netatmo.
|
||||||
|
config.securityId.label = Security ID
|
||||||
|
config.securityId.description = Unique identifier of the home handling security devices.
|
||||||
|
config.energyId.label = Energy ID
|
||||||
|
config.energyId.description = Unique identifier of the home handling energy devices.
|
||||||
config.refreshInterval.label = Refresh Interval
|
config.refreshInterval.label = Refresh Interval
|
||||||
config.refreshInterval.description = The refresh interval to poll Netatmo API (in seconds).
|
config.refreshInterval.description = The refresh interval to poll Netatmo API (in seconds).
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user