[netatmo] Add doorbell support (#12776)

* Adding doorbell handling to netatmo
Closes #8571

Signed-off-by: clinique <gael@lhopital.org>
This commit is contained in:
Gaël L'hopital 2022-05-24 21:56:55 +02:00 committed by GitHub
parent 308bb3013a
commit 55beb413bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 424 additions and 141 deletions

View File

@ -351,11 +351,11 @@ All these channels are read only.
**Supported channels for the Room thing:** **Supported channels for the Room thing:**
| Channel Group | Channel Id | Item Type | Description | | Channel Group | Channel Id | Item Type | Description |
|------------------|-----------------------|----------------------|---------------------------------------------------------| |---------------|-----------------------|----------------------|---------------------------------------------------------|
| room-temperature | value | Number:Temperature | Current temperature in the room | | temperature | value | Number:Temperature | Current temperature in the room |
| room-properties | window-open | Contact | Windows of the room are opened | | properties | window-open | Contact | Windows of the room are opened |
| room-properties | anticipating | Switch | Anticipates next scheduled setpoint | | properties | anticipating | Switch | Anticipates next scheduled setpoint |
| room-properties | heating-power-request | Number:Dimensionless | Percentage of heating power | | properties | heating-power-request | Number:Dimensionless | Percentage of heating power |
| setpoint | value | Number:Temperature | Thermostat temperature setpoint | | setpoint | value | Number:Temperature | Thermostat temperature setpoint |
| setpoint | mode | String | Chosen thermostat mode (home, frost guard, manual, max) | | setpoint | mode | String | Chosen thermostat mode (home, frost guard, manual, max) |
| setpoint | start | DateTime | Start time of the currently applied setpoint | | setpoint | start | DateTime | Start time of the currently applied setpoint |
@ -369,8 +369,8 @@ All these channels except setpoint and setpoint-mode are read only.
**Supported channels for the thermostat module:** **Supported channels for the thermostat module:**
| Channel Group | Channel Id | Item Type | Description | | Channel Group | Channel Id | Item Type | Description |
|---------------------|--------------------|----------------------|--------------------------------------------------| |---------------|-------------|--------------|--------------------------------------------------|
| th-properties | relay-status | Contact | Indicates if the boiler is currently heating | | properties | relay | Contact | Indicates if the boiler is currently heating |
| signal | strength | Number | Signal strength (0 for no signal, 1 for weak...) | | signal | strength | Number | Signal strength (0 for no signal, 1 for weak...) |
| signal | value | Number:Power | Signal strength in dBm | | signal | value | Number:Power | Signal strength in dBm |
| battery | value | Number | Battery level | | battery | value | Number | Battery level |
@ -438,7 +438,7 @@ All these channels are read only.
| | TAG_UNINSTALLED | Triggered when a tag gets uninstalled | | | TAG_UNINSTALLED | Triggered when a tag gets uninstalled |
| | TAG_OPEN | Triggered when an open event of a tag was detected | | | TAG_OPEN | Triggered when an open event of a tag was detected |
### Welcome and Presence Camera ### Welcome, Presence and Doorbell Cameras
Warnings: Warnings:
@ -503,6 +503,33 @@ Warnings:
(*) This channel is configurable : low, poor, high. (*) This channel is configurable : low, poor, high.
**Supported channels for the Welcome Doorbell thing:**
| Channel Group | Channel ID | Item Type | Read/Write | Description |
|---------------|-------------------|--------------|------------|---------------------------------------------------------------------------------------------------------------------------------------------|
| status | sd-card | String | Read-only | State of the SD card |
| status | alim | String | Read-only | State of the power connector |
| live | picture | Image | Read-only | Camera Live Snapshot |
| live | local-picture-url | String | Read-only | Local Url of the live snapshot for this camera |
| live | vpn-picture-url | String | Read-only | Url of the live snapshot for this camera through Netatmo VPN. |
| signal | strength | Number | Read-only | Signal strength (0 for no signal, 1 for weak...) |
| signal | value | Number:Power | Read-only | Signal strength in dBm |
| last-event | type | String | Read-only | Type of event |
| last-event | video-status | String | Read-only | Status of the video (recording, deleted or available) |
| last-event | time | DateTime | Read-only | Time of occurrence of event |
| last-event | local-video-url | String | Read-only | If the last event (depending upon event type) in the home lead a snapshot picture, the corresponding local video URL will be available here |
| last-event | vpn-video-url | String | Read-only | If the last event (depending upon event type) in the home lead a snapshot picture, the corresponding VPN video URL will be available here |
| sub-event | type | String | Read-only | Type of sub-event |
| sub-event | time | DateTime | Read-only | Time of occurrence of sub-event |
| sub-event | message | String | Read-only | Message sent by Netatmo corresponding to given sub-event |
| sub-event | snapshot-url | String | Read-only | Depending upon event type in the home, a snapshot picture of the corresponding local video URL will be available here |
| sub-event | vignette-url | String | Read-only | A vignette representing the snapshot |
| sub-event | snapshot | Image | Read-only | picture of the snapshot |
| sub-event | vignet | Image | Read-only | picture of the vignette |
Note: live feeds either locally or via VPN are not available in Netatmo API.
### Welcome Person ### Welcome Person
@ -516,17 +543,17 @@ Person things are automatically created in discovery process for all known perso
**Supported channels for the Person thing:** **Supported channels for the Person thing:**
| Channel Group | Channel ID | Item Type | Description | | Channel Group | Channel ID | Item Type | Description |
|----------------|----------------|--------------|--------------------------------------------------------| |---------------|--------------|-----------|--------------------------------------------------------|
| person | avatar-url | String | URL for the avatar of this person | | person | avatar-url | String | URL for the avatar of this person |
| person | avatar | Image | Avatar of this person | | person | avatar | Image | Avatar of this person |
| person | at-home | Switch | Indicates if this person is known to be at home or not | | person | at-home | Switch | Indicates if this person is known to be at home or not |
| person | last-seen | DateTime | Moment when this person was last seen | | person | last-seen | DateTime | Moment when this person was last seen |
| person-event | subtype | String | Sub-type of event | | last-event | subtype | String | Sub-type of event |
| person-event | message | String | Last event message from this person | | last-event | message | String | Last event message from this person |
| person-event | time | DateTime | Moment of the last event for this person | | last-event | time | DateTime | Moment of the last event for this person |
| person-event | snapshot | Image | Picture of the last event for this person | | last-event | snapshot | Image | Picture of the last event for this person |
| person-event | snapshot-url | String | URL for the picture of the last event for this person | | last-event | snapshot-url | String | URL for the picture of the last event for this person |
| person-event | camera-id | String | ID of the camera that triggered the event | | last-event | camera-id | String | ID of the camera that triggered the event |
All these channels except at-home are read only. All these channels except at-home are read only.

View File

@ -12,6 +12,8 @@
*/ */
package org.openhab.binding.netatmo.internal; package org.openhab.binding.netatmo.internal;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
/** /**
@ -35,6 +37,7 @@ public class NetatmoBindingConstants {
// Channel group ids // Channel group ids
public static final String GROUP_LAST_EVENT = "last-event"; public static final String GROUP_LAST_EVENT = "last-event";
public static final String GROUP_SUB_EVENT = "sub-event";
public static final String GROUP_TEMPERATURE = "temperature"; public static final String GROUP_TEMPERATURE = "temperature";
public static final String GROUP_HUMIDITY = "humidity"; public static final String GROUP_HUMIDITY = "humidity";
public static final String GROUP_AIR_QUALITY = "airquality"; public static final String GROUP_AIR_QUALITY = "airquality";
@ -51,22 +54,33 @@ public class NetatmoBindingConstants {
public static final String GROUP_CAM_LIVE = "live"; public static final String GROUP_CAM_LIVE = "live";
public static final String GROUP_PRESENCE = "presence"; public static final String GROUP_PRESENCE = "presence";
public static final String GROUP_PERSON = "person"; public static final String GROUP_PERSON = "person";
public static final String GROUP_PERSON_EVENT = "person-event"; public static final String GROUP_PROPERTIES = "properties";
public static final String GROUP_ROOM_TEMPERATURE = "room-temperature"; public static final String GROUP_SETPOINT = "setpoint";
public static final String GROUP_ROOM_PROPERTIES = "room-properties";
public static final String GROUP_TH_PROPERTIES = "th-properties";
public static final String GROUP_TH_SETPOINT = "setpoint";
public static final String GROUP_LOCATION = "location"; public static final String GROUP_LOCATION = "location";
// Alternative extended groups // Alternative extended groups
public static final String OPTION_EXTENDED = "-extended"; public static final String OPTION_EXTENDED = "-extended";
public static final String OPTION_OUTSIDE = "-outside"; public static final String OPTION_OUTSIDE = "-outside";
public static final String OPTION_DOORBELL = "-doorbell";
public static final String OPTION_PERSON = "-person";
public static final String OPTION_ROOM = "-room";
public static final String OPTION_THERMOSTAT = "-thermostat";
public static final Set<String> GROUP_VARIATIONS = Set.of(OPTION_EXTENDED, OPTION_OUTSIDE, OPTION_DOORBELL,
OPTION_PERSON, OPTION_ROOM, OPTION_THERMOSTAT);
public static final String GROUP_TYPE_TIMESTAMP_EXTENDED = GROUP_TIMESTAMP + OPTION_EXTENDED; public static final String GROUP_TYPE_TIMESTAMP_EXTENDED = GROUP_TIMESTAMP + OPTION_EXTENDED;
public static final String GROUP_TYPE_BATTERY_EXTENDED = GROUP_BATTERY + OPTION_EXTENDED; public static final String GROUP_TYPE_BATTERY_EXTENDED = GROUP_BATTERY + OPTION_EXTENDED;
public static final String GROUP_TYPE_PRESSURE_EXTENDED = GROUP_PRESSURE + OPTION_EXTENDED; public static final String GROUP_TYPE_PRESSURE_EXTENDED = GROUP_PRESSURE + OPTION_EXTENDED;
public static final String GROUP_TYPE_TEMPERATURE_EXTENDED = GROUP_TEMPERATURE + OPTION_EXTENDED; public static final String GROUP_TYPE_TEMPERATURE_EXTENDED = GROUP_TEMPERATURE + OPTION_EXTENDED;
public static final String GROUP_TYPE_AIR_QUALITY_EXTENDED = GROUP_AIR_QUALITY + OPTION_EXTENDED; public static final String GROUP_TYPE_AIR_QUALITY_EXTENDED = GROUP_AIR_QUALITY + OPTION_EXTENDED;
public static final String GROUP_TYPE_TEMPERATURE_OUTSIDE = GROUP_TEMPERATURE + OPTION_OUTSIDE; public static final String GROUP_TYPE_TEMPERATURE_OUTSIDE = GROUP_TEMPERATURE + OPTION_OUTSIDE;
public static final String GROUP_DOORBELL_STATUS = GROUP_CAM_STATUS + OPTION_DOORBELL;
public static final String GROUP_DOORBELL_LIVE = GROUP_CAM_LIVE + OPTION_DOORBELL;
public static final String GROUP_DOORBELL_LAST_EVENT = GROUP_LAST_EVENT + OPTION_DOORBELL;
public static final String GROUP_DOORBELL_SUB_EVENT = GROUP_SUB_EVENT + OPTION_DOORBELL;
public static final String GROUP_PERSON_LAST_EVENT = GROUP_LAST_EVENT + OPTION_PERSON;
public static final String GROUP_TYPE_ROOM_TEMPERATURE = GROUP_TEMPERATURE + OPTION_ROOM;
public static final String GROUP_TYPE_ROOM_PROPERTIES = GROUP_PROPERTIES + OPTION_ROOM;
public static final String GROUP_TYPE_TH_PROPERTIES = GROUP_PROPERTIES + OPTION_THERMOSTAT;
// Channel ids // Channel ids
public static final String CHANNEL_VALUE = "value"; public static final String CHANNEL_VALUE = "value";
@ -99,7 +113,7 @@ public class NetatmoBindingConstants {
public static final String CHANNEL_SETPOINT_MODE = "mode"; public static final String CHANNEL_SETPOINT_MODE = "mode";
public static final String CHANNEL_SETPOINT_START_TIME = "start"; public static final String CHANNEL_SETPOINT_START_TIME = "start";
public static final String CHANNEL_SETPOINT_END_TIME = "end"; public static final String CHANNEL_SETPOINT_END_TIME = "end";
public static final String CHANNEL_THERM_RELAY = "relay-status"; public static final String CHANNEL_THERM_RELAY = "relay";
public static final String CHANNEL_ANTICIPATING = "anticipating"; public static final String CHANNEL_ANTICIPATING = "anticipating";
public static final String CHANNEL_ROOM_WINDOW_OPEN = "window-open"; public static final String CHANNEL_ROOM_WINDOW_OPEN = "window-open";
public static final String CHANNEL_ROOM_HEATING_POWER = "heating-power-request"; public static final String CHANNEL_ROOM_HEATING_POWER = "heating-power-request";
@ -122,6 +136,8 @@ public class NetatmoBindingConstants {
public static final String CHANNEL_EVENT_TIME = "time"; public static final String CHANNEL_EVENT_TIME = "time";
public static final String CHANNEL_EVENT_SNAPSHOT = "snapshot"; public static final String CHANNEL_EVENT_SNAPSHOT = "snapshot";
public static final String CHANNEL_EVENT_SNAPSHOT_URL = "snapshot-url"; public static final String CHANNEL_EVENT_SNAPSHOT_URL = "snapshot-url";
public static final String CHANNEL_EVENT_VIGNETTE = "vignette";
public static final String CHANNEL_EVENT_VIGNETTE_URL = "vignette-url";
public static final String CHANNEL_EVENT_VIDEO_VPN_URL = "vpn-video-url"; public static final String CHANNEL_EVENT_VIDEO_VPN_URL = "vpn-video-url";
public static final String CHANNEL_EVENT_VIDEO_LOCAL_URL = "local-video-url"; public static final String CHANNEL_EVENT_VIDEO_LOCAL_URL = "local-video-url";
public static final String CHANNEL_EVENT_PERSON_ID = "person-id"; public static final String CHANNEL_EVENT_PERSON_ID = "person-id";

View File

@ -43,7 +43,7 @@ public class AircareApi extends RestManager {
* @throws NetatmoException If fail to call the API, e.g. server error or deserializing * @throws NetatmoException If fail to call the API, e.g. server error or deserializing
*/ */
public StationDataResponse getHomeCoachData(@Nullable String deviceId) throws NetatmoException { public StationDataResponse getHomeCoachData(@Nullable String deviceId) throws NetatmoException {
UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_HOMECOACH, PARAM_DEVICEID, deviceId); UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_HOMECOACH, PARAM_DEVICE_ID, deviceId);
return get(uriBuilder, StationDataResponse.class); return get(uriBuilder, StationDataResponse.class);
} }

View File

@ -45,7 +45,7 @@ public class EnergyApi extends RestManager {
* response body * response body
*/ */
public void switchSchedule(String homeId, String scheduleId) throws NetatmoException { public void switchSchedule(String homeId, String scheduleId) throws NetatmoException {
UriBuilder uriBuilder = getAppUriBuilder(SUB_PATH_SWITCHSCHEDULE, PARAM_HOMEID, homeId, PARAM_SCHEDULEID, UriBuilder uriBuilder = getAppUriBuilder(SUB_PATH_SWITCH_SCHEDULE, PARAM_HOME_ID, homeId, PARAM_SCHEDULE_ID,
scheduleId); scheduleId);
post(uriBuilder, ApiResponse.Ok.class, null, null); post(uriBuilder, ApiResponse.Ok.class, null, null);
} }
@ -63,7 +63,7 @@ public class EnergyApi extends RestManager {
* @throws NetatmoCommunicationException when call failed, e.g. server error or cannot deserialize * @throws NetatmoCommunicationException when call failed, e.g. server error or cannot deserialize
*/ */
public void setThermMode(String homeId, String mode) throws NetatmoException { public void setThermMode(String homeId, String mode) throws NetatmoException {
UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_SETTHERMMODE, PARAM_HOMEID, homeId, PARAM_MODE, mode); UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_SET_THERM_MODE, PARAM_HOME_ID, homeId, PARAM_MODE, mode);
post(uriBuilder, ApiResponse.Ok.class, null, null); post(uriBuilder, ApiResponse.Ok.class, null, null);
} }
@ -80,8 +80,8 @@ public class EnergyApi extends RestManager {
*/ */
public void setThermpoint(String homeId, String roomId, SetpointMode mode, long endtime, double temp) public void setThermpoint(String homeId, String roomId, SetpointMode mode, long endtime, double temp)
throws NetatmoException { throws NetatmoException {
UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_SETROOMTHERMPOINT, PARAM_HOMEID, homeId, PARAM_ROOMID, roomId, UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_SET_ROOM_THERMPOINT, PARAM_HOME_ID, homeId, PARAM_ROOM_ID,
PARAM_MODE, mode.apiDescriptor); roomId, PARAM_MODE, mode.apiDescriptor);
if (mode == SetpointMode.MANUAL || mode == SetpointMode.MAX) { if (mode == SetpointMode.MANUAL || mode == SetpointMode.MAX) {
uriBuilder.queryParam("endtime", endtime); uriBuilder.queryParam("endtime", endtime);
if (mode == SetpointMode.MANUAL) { if (mode == SetpointMode.MANUAL) {

View File

@ -44,7 +44,7 @@ public class HomeApi extends RestManager {
} }
public @Nullable HomeStatus getHomeStatus(String homeId) throws NetatmoException { public @Nullable HomeStatus getHomeStatus(String homeId) throws NetatmoException {
UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_HOMESTATUS, PARAM_HOMEID, homeId); UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_HOMESTATUS, PARAM_HOME_ID, homeId);
NAHomeStatusResponse response = get(uriBuilder, NAHomeStatusResponse.class); NAHomeStatusResponse response = get(uriBuilder, NAHomeStatusResponse.class);
NAHomeStatus body = response.getBody(); NAHomeStatus body = response.getBody();
@ -58,10 +58,10 @@ public class HomeApi extends RestManager {
public Collection<HomeData> getHomesData(@Nullable String homeId, @Nullable ModuleType type) public Collection<HomeData> getHomesData(@Nullable String homeId, @Nullable ModuleType type)
throws NetatmoException { throws NetatmoException {
UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_HOMES_DATA, PARAM_HOMEID, homeId); UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_HOMES_DATA, PARAM_HOME_ID, homeId);
if (type != null) { if (type != null) {
uriBuilder.queryParam(PARAM_GATEWAYTYPE, type.name()); uriBuilder.queryParam(PARAM_GATEWAY_TYPE, type.name());
} }
HomeData.HomesDataResponse response = get(uriBuilder, HomeData.HomesDataResponse.class); HomeData.HomesDataResponse response = get(uriBuilder, HomeData.HomesDataResponse.class);

View File

@ -46,7 +46,7 @@ public class SecurityApi extends RestManager {
* @throws NetatmoException If fail to call the API, e.g. server error or deserializing * @throws NetatmoException If fail to call the API, e.g. server error or deserializing
*/ */
public void dropWebhook() throws NetatmoException { public void dropWebhook() throws NetatmoException {
UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_DROPWEBHOOK); UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_DROP_WEBHOOK);
post(uriBuilder, ApiResponse.Ok.class, null, null); post(uriBuilder, ApiResponse.Ok.class, null, null);
} }
@ -57,13 +57,13 @@ public class SecurityApi extends RestManager {
* @throws NetatmoException If fail to call the API, e.g. server error or deserializing * @throws NetatmoException If fail to call the API, e.g. server error or deserializing
*/ */
public boolean addwebhook(URI uri) throws NetatmoException { public boolean addwebhook(URI uri) throws NetatmoException {
UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_ADDWEBHOOK, PARAM_URL, uri.toString()); UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_ADD_WEBHOOK, PARAM_URL, uri.toString());
post(uriBuilder, ApiResponse.Ok.class, null, null); post(uriBuilder, ApiResponse.Ok.class, null, null);
return true; return true;
} }
public Collection<HomeEvent> getPersonEvents(String homeId, String personId) throws NetatmoException { public Collection<HomeEvent> getPersonEvents(String homeId, String personId) throws NetatmoException {
UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_GETEVENTS, PARAM_HOMEID, homeId, PARAM_PERSONID, personId, UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_GET_EVENTS, PARAM_HOME_ID, homeId, PARAM_PERSON_ID, personId,
PARAM_OFFSET, 1); PARAM_OFFSET, 1);
NAEventsDataResponse response = get(uriBuilder, NAEventsDataResponse.class); NAEventsDataResponse response = get(uriBuilder, NAEventsDataResponse.class);
BodyResponse<Home> body = response.getBody(); BodyResponse<Home> body = response.getBody();
@ -77,10 +77,11 @@ public class SecurityApi extends RestManager {
throw new NetatmoException("home should not be null"); throw new NetatmoException("home should not be null");
} }
public Collection<HomeEvent> getCameraEvents(String homeId, String cameraId) throws NetatmoException { public Collection<HomeEvent> getCameraEvents(String homeId, String deviceId, String deviceType)
UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_GETEVENTS, PARAM_HOMEID, homeId, PARAM_DEVICEID, cameraId); throws NetatmoException {
NAEventsDataResponse response = get(uriBuilder, NAEventsDataResponse.class); UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_GET_EVENTS, PARAM_HOME_ID, homeId, PARAM_DEVICE_ID, deviceId,
BodyResponse<Home> body = response.getBody(); PARAM_DEVICES_TYPE, deviceType);
BodyResponse<Home> body = get(uriBuilder, NAEventsDataResponse.class).getBody();
if (body != null) { if (body != null) {
Home home = body.getElement(); Home home = body.getElement();
if (home != null) { if (home != null) {

View File

@ -56,7 +56,7 @@ public class WeatherApi extends RestManager {
*/ */
private StationDataResponse getStationsData(@Nullable String deviceId, boolean getFavorites) private StationDataResponse getStationsData(@Nullable String deviceId, boolean getFavorites)
throws NetatmoException { throws NetatmoException {
UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_GETSTATION, PARAM_DEVICEID, deviceId, // UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_GET_STATION, PARAM_DEVICE_ID, deviceId, //
PARAM_FAVORITES, getFavorites); PARAM_FAVORITES, getFavorites);
StationDataResponse response = get(uriBuilder, StationDataResponse.class); StationDataResponse response = get(uriBuilder, StationDataResponse.class);
return response; return response;
@ -127,8 +127,8 @@ public class WeatherApi extends RestManager {
private MeasureBodyElem<?> getMeasure(String deviceId, @Nullable String moduleId, @Nullable String scale, private MeasureBodyElem<?> getMeasure(String deviceId, @Nullable String moduleId, @Nullable String scale,
String measureType) throws NetatmoException { String measureType) throws NetatmoException {
// NAMeasuresResponse is not designed for optimize=false // NAMeasuresResponse is not designed for optimize=false
UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_GETMEASURE, PARAM_DEVICEID, deviceId, "real_time", true, UriBuilder uriBuilder = getApiUriBuilder(SUB_PATH_GET_MEASURE, PARAM_DEVICE_ID, deviceId, "real_time", true,
"date_end", "last", "optimize", true, "type", measureType.toLowerCase(), PARAM_MODULEID, moduleId); "date_end", "last", "optimize", true, "type", measureType.toLowerCase(), PARAM_MODULE_ID, moduleId);
if (scale != null) { if (scale != null) {
uriBuilder.queryParam("scale", scale.toLowerCase()); uriBuilder.queryParam("scale", scale.toLowerCase());

View File

@ -46,11 +46,14 @@ public enum EventType {
@SerializedName("movement") // When the Indoor Camera detects motion @SerializedName("movement") // When the Indoor Camera detects motion
MOVEMENT(ModuleType.WELCOME), MOVEMENT(ModuleType.WELCOME),
@SerializedName("human") // When the Indoor Camera detects human motion @SerializedName("human") // When the camera detects human motion
HUMAN(ModuleType.WELCOME), HUMAN(ModuleType.WELCOME, ModuleType.OUTDOOR, ModuleType.DOORBELL),
@SerializedName("animal") // When the Indoor Camera detects animal motion @SerializedName("animal") // When the camera detects animal motion
ANIMAL(ModuleType.WELCOME), ANIMAL(ModuleType.WELCOME, ModuleType.OUTDOOR),
@SerializedName("vehicle") // When the Outdoor Camera detects a car
VEHICLE(ModuleType.OUTDOOR),
@SerializedName("new_module") // A new Module has been paired with the Indoor Camera @SerializedName("new_module") // A new Module has been paired with the Indoor Camera
NEW_MODULE(ModuleType.WELCOME), NEW_MODULE(ModuleType.WELCOME),
@ -67,10 +70,10 @@ public enum EventType {
@SerializedName("module_end_update") // Module's firmware update is over @SerializedName("module_end_update") // Module's firmware update is over
MODULE_END_UPDATE(ModuleType.WELCOME), MODULE_END_UPDATE(ModuleType.WELCOME),
@SerializedName("connection") // When the Camera connects to Netatmo servers @SerializedName("connection") // When the camera connects to Netatmo servers
CONNECTION(ModuleType.WELCOME, ModuleType.PRESENCE), CONNECTION(ModuleType.WELCOME, ModuleType.PRESENCE),
@SerializedName("disconnection") // When the Camera loses connection with Netatmo servers @SerializedName("disconnection") // When the camera loses connection with Netatmo servers
DISCONNECTION(ModuleType.WELCOME, ModuleType.PRESENCE), DISCONNECTION(ModuleType.WELCOME, ModuleType.PRESENCE),
@SerializedName("on") // When Camera Monitoring is resumed @SerializedName("on") // When Camera Monitoring is resumed
@ -86,7 +89,16 @@ public enum EventType {
SD(ModuleType.WELCOME, ModuleType.PRESENCE), SD(ModuleType.WELCOME, ModuleType.PRESENCE),
@SerializedName("alim") // When Camera power supply status changes @SerializedName("alim") // When Camera power supply status changes
ALIM(ModuleType.WELCOME, ModuleType.PRESENCE); ALIM(ModuleType.WELCOME, ModuleType.PRESENCE),
@SerializedName("accepted_call") // When a call is incoming
ACCEPTED_CALL(ModuleType.DOORBELL),
@SerializedName("incoming_call") // When a call as been answered by a user
INCOMING_CALL(ModuleType.DOORBELL),
@SerializedName("missed_call") // When a call has not been answered by anyone
MISSED_CALL(ModuleType.DOORBELL);
private final Set<ModuleType> appliesTo; private final Set<ModuleType> appliesTo;
@ -99,7 +111,7 @@ public enum EventType {
return name().toLowerCase(); return name().toLowerCase();
} }
public boolean appliesOn(ModuleType searched) { public boolean validFor(ModuleType searched) {
return appliesTo.contains(searched); return appliesTo.contains(searched);
} }
} }

View File

@ -41,7 +41,9 @@ import org.openhab.binding.netatmo.internal.handler.channelhelper.BatteryChannel
import org.openhab.binding.netatmo.internal.handler.channelhelper.BatteryExtChannelHelper; import org.openhab.binding.netatmo.internal.handler.channelhelper.BatteryExtChannelHelper;
import org.openhab.binding.netatmo.internal.handler.channelhelper.CameraChannelHelper; import org.openhab.binding.netatmo.internal.handler.channelhelper.CameraChannelHelper;
import org.openhab.binding.netatmo.internal.handler.channelhelper.ChannelHelper; import org.openhab.binding.netatmo.internal.handler.channelhelper.ChannelHelper;
import org.openhab.binding.netatmo.internal.handler.channelhelper.DoorbellChannelHelper;
import org.openhab.binding.netatmo.internal.handler.channelhelper.EventChannelHelper; import org.openhab.binding.netatmo.internal.handler.channelhelper.EventChannelHelper;
import org.openhab.binding.netatmo.internal.handler.channelhelper.EventDoorbellChannelHelper;
import org.openhab.binding.netatmo.internal.handler.channelhelper.EventPersonChannelHelper; import org.openhab.binding.netatmo.internal.handler.channelhelper.EventPersonChannelHelper;
import org.openhab.binding.netatmo.internal.handler.channelhelper.HomeEnergyChannelHelper; import org.openhab.binding.netatmo.internal.handler.channelhelper.HomeEnergyChannelHelper;
import org.openhab.binding.netatmo.internal.handler.channelhelper.HomeSecurityChannelHelper; import org.openhab.binding.netatmo.internal.handler.channelhelper.HomeSecurityChannelHelper;
@ -75,8 +77,8 @@ import com.google.gson.annotations.SerializedName;
*/ */
@NonNullByDefault @NonNullByDefault
public enum ModuleType { public enum ModuleType {
UNKNOWN(FeatureArea.NONE, null, null, List.of(), List.of()), UNKNOWN(FeatureArea.NONE, "", null, List.of(), List.of()),
ACCOUNT(FeatureArea.NONE, null, null, List.of(), List.of()), ACCOUNT(FeatureArea.NONE, "", null, List.of(), List.of()),
@SerializedName("NAHome") @SerializedName("NAHome")
HOME(FeatureArea.NONE, "NAHome", ACCOUNT, HOME(FeatureArea.NONE, "NAHome", ACCOUNT,
List.of(DeviceCapability.class, EventCapability.class, HomeCapability.class, ChannelHelperCapability.class), List.of(DeviceCapability.class, EventCapability.class, HomeCapability.class, ChannelHelperCapability.class),
@ -92,14 +94,14 @@ public enum ModuleType {
@SerializedName("NOC") @SerializedName("NOC")
PRESENCE(FeatureArea.SECURITY, "NOC", HOME, PRESENCE(FeatureArea.SECURITY, "NOC", HOME,
List.of(EventCapability.class, PresenceCapability.class, ChannelHelperCapability.class), List.of(EventCapability.class, PresenceCapability.class, ChannelHelperCapability.class),
List.of(CameraChannelHelper.class, PresenceChannelHelper.class, SignalChannelHelper.class, List.of(PresenceChannelHelper.class, SignalChannelHelper.class, EventChannelHelper.class)),
EventChannelHelper.class)),
@SerializedName("NIS") @SerializedName("NIS")
SIREN(FeatureArea.SECURITY, "NIS", HOME, List.of(ChannelHelperCapability.class), SIREN(FeatureArea.SECURITY, "NIS", HOME, List.of(ChannelHelperCapability.class),
List.of(BatteryChannelHelper.class, TimestampChannelHelper.class, SignalChannelHelper.class)), List.of(BatteryChannelHelper.class, TimestampChannelHelper.class, SignalChannelHelper.class)),
@SerializedName("NDB") @SerializedName("NDB")
DOORBELL(FeatureArea.SECURITY, "NDB", HOME, List.of(ChannelHelperCapability.class), DOORBELL(FeatureArea.SECURITY, "NDB", HOME,
List.of(SignalChannelHelper.class)), List.of(EventCapability.class, CameraCapability.class, ChannelHelperCapability.class),
List.of(DoorbellChannelHelper.class, SignalChannelHelper.class, EventDoorbellChannelHelper.class)),
@SerializedName("NAMain") @SerializedName("NAMain")
WEATHER_STATION(FeatureArea.WEATHER, "NAMain", ACCOUNT, WEATHER_STATION(FeatureArea.WEATHER, "NAMain", ACCOUNT,
List.of(DeviceCapability.class, WeatherCapability.class, MeasureCapability.class, List.of(DeviceCapability.class, WeatherCapability.class, MeasureCapability.class,
@ -156,9 +158,9 @@ public enum ModuleType {
public final List<Class<? extends Capability>> capabilities; public final List<Class<? extends Capability>> capabilities;
public final ThingTypeUID thingTypeUID; public final ThingTypeUID thingTypeUID;
public final FeatureArea feature; public final FeatureArea feature;
public final @Nullable String apiName; public final String apiName;
ModuleType(FeatureArea feature, @Nullable String apiName, @Nullable ModuleType bridge, ModuleType(FeatureArea feature, String apiName, @Nullable ModuleType bridge,
List<Class<? extends Capability>> capabilities, List<Class<? extends ChannelHelper>> helpers) { List<Class<? extends Capability>> capabilities, List<Class<? extends ChannelHelper>> helpers) {
this.channelHelpers = helpers; this.channelHelpers = helpers;
this.bridgeType = bridge; this.bridgeType = bridge;

View File

@ -125,30 +125,31 @@ public class NetatmoConstants {
public static final String SUB_PATH_PERSON_AWAY = "setpersonsaway"; public static final String SUB_PATH_PERSON_AWAY = "setpersonsaway";
public static final String SUB_PATH_PERSON_HOME = "setpersonshome"; public static final String SUB_PATH_PERSON_HOME = "setpersonshome";
public static final String SUB_PATH_HOMES_DATA = "homesdata"; public static final String SUB_PATH_HOMES_DATA = "homesdata";
public static final String SUB_PATH_ADDWEBHOOK = "addwebhook"; public static final String SUB_PATH_ADD_WEBHOOK = "addwebhook";
public static final String SUB_PATH_DROPWEBHOOK = "dropwebhook"; public static final String SUB_PATH_DROP_WEBHOOK = "dropwebhook";
public static final String SUB_PATH_SETROOMTHERMPOINT = "setroomthermpoint"; public static final String SUB_PATH_SET_ROOM_THERMPOINT = "setroomthermpoint";
public static final String SUB_PATH_SETTHERMMODE = "setthermmode"; public static final String SUB_PATH_SET_THERM_MODE = "setthermmode";
public static final String SUB_PATH_SWITCHSCHEDULE = "switchschedule"; public static final String SUB_PATH_SWITCH_SCHEDULE = "switchschedule";
public static final String SUB_PATH_GETSTATION = "getstationsdata"; public static final String SUB_PATH_GET_STATION = "getstationsdata";
public static final String SUB_PATH_GETMEASURE = "getmeasure"; public static final String SUB_PATH_GET_MEASURE = "getmeasure";
public static final String SUB_PATH_HOMESTATUS = "homestatus"; public static final String SUB_PATH_HOMESTATUS = "homestatus";
public static final String SUB_PATH_HOMECOACH = "gethomecoachsdata"; public static final String SUB_PATH_HOMECOACH = "gethomecoachsdata";
public static final String SUB_PATH_GETEVENTS = "getevents"; public static final String SUB_PATH_GET_EVENTS = "getevents";
public static final String SUB_PATH_PING = "ping"; public static final String SUB_PATH_PING = "ping";
public static final String SUB_PATH_CHANGESTATUS = "changestatus"; public static final String SUB_PATH_CHANGESTATUS = "changestatus";
public static final String PARAM_DEVICEID = "device_id"; public static final String PARAM_DEVICE_ID = "device_id";
public static final String PARAM_MODULEID = "module_id"; public static final String PARAM_MODULE_ID = "module_id";
public static final String PARAM_HOMEID = "home_id"; public static final String PARAM_HOME_ID = "home_id";
public static final String PARAM_ROOMID = "room_id"; public static final String PARAM_ROOM_ID = "room_id";
public static final String PARAM_PERSONID = "person_id"; public static final String PARAM_PERSON_ID = "person_id";
public static final String PARAM_SCHEDULEID = "schedule_id"; public static final String PARAM_SCHEDULE_ID = "schedule_id";
public static final String PARAM_OFFSET = "offset"; public static final String PARAM_OFFSET = "offset";
public static final String PARAM_GATEWAYTYPE = "gateway_types"; public static final String PARAM_GATEWAY_TYPE = "gateway_types";
public static final String PARAM_MODE = "mode"; public static final String PARAM_MODE = "mode";
public static final String PARAM_URL = "url"; public static final String PARAM_URL = "url";
public static final String PARAM_FAVORITES = "get_favorites"; public static final String PARAM_FAVORITES = "get_favorites";
public static final String PARAM_STATUS = "status"; public static final String PARAM_STATUS = "status";
public static final String PARAM_DEVICES_TYPE = "device_types";
// Autentication process params // Autentication process params
public static final String PARAM_ERROR = "error"; public static final String PARAM_ERROR = "error";

View File

@ -13,6 +13,7 @@
package org.openhab.binding.netatmo.internal.api.dto; package org.openhab.binding.netatmo.internal.api.dto;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
@ -40,9 +41,11 @@ public class HomeEvent extends Event {
private @Nullable String personId; private @Nullable String personId;
private EventCategory category = EventCategory.UNKNOWN; private EventCategory category = EventCategory.UNKNOWN;
private @Nullable Snapshot snapshot; private @Nullable Snapshot snapshot;
private @Nullable Snapshot vignette;
private @Nullable String videoId; private @Nullable String videoId;
private VideoStatus videoStatus = VideoStatus.UNKNOWN; private VideoStatus videoStatus = VideoStatus.UNKNOWN;
private boolean isArrival; private boolean isArrival;
private List<HomeEvent> subevents = List.of();
@Override @Override
public ZonedDateTime getTime() { public ZonedDateTime getTime() {
@ -90,7 +93,20 @@ public class HomeEvent extends Event {
@Override @Override
public @Nullable String getSnapshotUrl() { public @Nullable String getSnapshotUrl() {
Snapshot localSnap = snapshot; Snapshot image = snapshot;
return localSnap != null ? localSnap.getUrl() : null; return image != null ? image.getUrl() : null;
}
public @Nullable String getVignetteUrl() {
Snapshot image = vignette;
return image != null ? image.getUrl() : null;
}
public List<HomeEvent> getSubevents() {
return subevents;
}
public @Nullable Snapshot getVignette() {
return vignette;
} }
} }

View File

@ -16,6 +16,7 @@ import java.util.Optional;
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.NetatmoConstants.AlimentationStatus; import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.AlimentationStatus;
import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.BatteryState; import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.BatteryState;
import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.FloodLightMode; import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.FloodLightMode;
@ -73,7 +74,8 @@ public class HomeStatusModule extends NAThing {
public State getMonitoring() { public State getMonitoring() {
OnOffType localStatus = monitoring; OnOffType localStatus = monitoring;
return localStatus != null ? localStatus : UnDefType.NULL; return localStatus != null ? localStatus // Monitoring is always active on Doorbell
: getType().equals(ModuleType.DOORBELL) ? OnOffType.ON : UnDefType.NULL;
} }
public FloodLightMode getFloodlight() { public FloodLightMode getFloodlight() {

View File

@ -97,9 +97,11 @@ public class CameraCapability extends HomeSecurityThingCapability {
public List<NAObject> updateReadings() { public List<NAObject> updateReadings() {
List<NAObject> result = new ArrayList<>(); List<NAObject> result = new ArrayList<>();
securityCapability.ifPresent(cap -> { securityCapability.ifPresent(cap -> {
Collection<HomeEvent> events = cap.getCameraEvents(handler.getId()); Collection<HomeEvent> events = cap.getCameraEvents(handler.getId(), moduleType.apiName);
if (!events.isEmpty()) { if (!events.isEmpty()) {
result.add(events.iterator().next()); HomeEvent event = events.iterator().next();
result.add(event);
result.addAll(event.getSubevents());
} }
}); });
return result; return result;

View File

@ -51,7 +51,7 @@ public class PersonCapability extends HomeSecurityThingCapability {
public PersonCapability(CommonInterface handler, NetatmoDescriptionProvider descriptionProvider, public PersonCapability(CommonInterface handler, NetatmoDescriptionProvider descriptionProvider,
List<ChannelHelper> channelHelpers) { List<ChannelHelper> channelHelpers) {
super(handler, descriptionProvider, channelHelpers); super(handler, descriptionProvider, channelHelpers);
this.cameraChannelUID = new ChannelUID(thing.getUID(), GROUP_PERSON_EVENT, CHANNEL_EVENT_CAMERA_ID); this.cameraChannelUID = new ChannelUID(thing.getUID(), GROUP_PERSON_LAST_EVENT, CHANNEL_EVENT_CAMERA_ID);
} }
@Override @Override
@ -78,7 +78,7 @@ public class PersonCapability extends HomeSecurityThingCapability {
EventType eventType = event.getEventType(); EventType eventType = event.getEventType();
ZonedDateTime localLast = lastEventTime; ZonedDateTime localLast = lastEventTime;
ZonedDateTime eventTime = event.getTime(); ZonedDateTime eventTime = event.getTime();
if ((localLast != null && !eventTime.isAfter(localLast)) || !eventType.appliesOn(ModuleType.PERSON)) { if ((localLast != null && !eventTime.isAfter(localLast)) || !eventType.validFor(ModuleType.PERSON)) {
return; // ignore incoming events if they are deprecated return; // ignore incoming events if they are deprecated
} }
lastEventTime = eventTime; lastEventTime = eventTime;

View File

@ -99,10 +99,10 @@ class SecurityCapability extends RestCapability<SecurityApi> {
}); });
} }
public Collection<HomeEvent> getCameraEvents(String cameraId) { public Collection<HomeEvent> getCameraEvents(String cameraId, String deviceType) {
return getApi().map(api -> { return getApi().map(api -> {
try { try {
return api.getCameraEvents(handler.getId(), cameraId); return api.getCameraEvents(handler.getId(), cameraId, deviceType);
} catch (NetatmoException e) { } catch (NetatmoException e) {
logger.warn("Error retrieving last events of camera '{}' : {}", cameraId, e.getMessage()); logger.warn("Error retrieving last events of camera '{}' : {}", cameraId, e.getMessage());
return null; return null;

View File

@ -39,7 +39,11 @@ public class CameraChannelHelper extends ChannelHelper {
private @Nullable String localUrl; private @Nullable String localUrl;
public CameraChannelHelper() { public CameraChannelHelper() {
super(GROUP_CAM_STATUS, GROUP_CAM_LIVE); this(GROUP_CAM_STATUS, GROUP_CAM_LIVE);
}
protected CameraChannelHelper(String... providedGroups) {
super(providedGroups);
} }
public void setUrls(String vpnUrl, @Nullable String localUrl) { public void setUrls(String vpnUrl, @Nullable String localUrl) {

View File

@ -20,6 +20,7 @@ import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.MeasureClass; import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.MeasureClass;
import org.openhab.binding.netatmo.internal.api.dto.Dashboard; import org.openhab.binding.netatmo.internal.api.dto.Dashboard;
import org.openhab.binding.netatmo.internal.api.dto.Event; import org.openhab.binding.netatmo.internal.api.dto.Event;
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.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.providers.NetatmoThingTypeProvider; import org.openhab.binding.netatmo.internal.providers.NetatmoThingTypeProvider;
@ -57,6 +58,12 @@ public abstract class ChannelHelper {
State result = null; State result = null;
if (channelGroups.isEmpty() || (groupId != null && channelGroups.contains(groupId))) { if (channelGroups.isEmpty() || (groupId != null && channelGroups.contains(groupId))) {
NAObject localData = data; NAObject localData = data;
if (localData instanceof HomeEvent) {
result = internalGetHomeEvent(channelId, groupId, (HomeEvent) localData);
if (result != null) {
return result;
}
}
if (localData instanceof Event) { if (localData instanceof Event) {
result = internalGetEvent(channelId, (Event) localData); result = internalGetEvent(channelId, (Event) localData);
if (result != null) { if (result != null) {
@ -108,6 +115,10 @@ public abstract class ChannelHelper {
return null; return null;
} }
protected @Nullable State internalGetHomeEvent(String channelId, @Nullable String groupId, HomeEvent event) {
return null;
}
public Set<String> getChannelGroupTypes() { public Set<String> getChannelGroupTypes() {
return channelGroupTypes; return channelGroupTypes;
} }

View File

@ -0,0 +1,31 @@
/**
* Copyright (c) 2010-2022 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.handler.channelhelper;
import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*;
import org.eclipse.jdt.annotation.NonNullByDefault;
/**
* The {@link DoorbellChannelHelper} handles specific channels of doorbells
*
* @author Gaël L'hopital - Initial contribution
*
*/
@NonNullByDefault
public class DoorbellChannelHelper extends CameraChannelHelper {
public DoorbellChannelHelper() {
super(GROUP_DOORBELL_STATUS, GROUP_DOORBELL_LIVE);
}
}

View File

@ -36,14 +36,14 @@ import org.openhab.core.types.UnDefType;
public class EventChannelHelper extends ChannelHelper { public class EventChannelHelper extends ChannelHelper {
private boolean isLocal; private boolean isLocal;
private @Nullable String vpnUrl, localUrl; private @Nullable String vpnUrl, localUrl;
private ModuleType moduleType = ModuleType.UNKNOWN; protected ModuleType moduleType = ModuleType.UNKNOWN;
public EventChannelHelper() { public EventChannelHelper() {
this(GROUP_LAST_EVENT); this(GROUP_LAST_EVENT);
} }
protected EventChannelHelper(String groupName) { protected EventChannelHelper(String... providedGroups) {
super(groupName); super(providedGroups);
} }
public void setModuleType(ModuleType moduleType) { public void setModuleType(ModuleType moduleType) {
@ -60,7 +60,7 @@ public class EventChannelHelper extends ChannelHelper {
public void setNewData(@Nullable NAObject data) { public void setNewData(@Nullable NAObject data) {
if (data instanceof Event) { if (data instanceof Event) {
Event event = (Event) data; Event event = (Event) data;
if (!event.getEventType().appliesOn(moduleType)) { if (!event.getEventType().validFor(moduleType)) {
return; return;
} }
} }
@ -87,16 +87,18 @@ public class EventChannelHelper extends ChannelHelper {
case CHANNEL_EVENT_SNAPSHOT_URL: case CHANNEL_EVENT_SNAPSHOT_URL:
return toStringType(event.getSnapshotUrl()); return toStringType(event.getSnapshotUrl());
} }
if (event instanceof HomeEvent) { return null;
HomeEvent homeEvent = (HomeEvent) event; }
@Override
protected @Nullable State internalGetHomeEvent(String channelId, @Nullable String groupId, HomeEvent event) {
switch (channelId) { switch (channelId) {
case CHANNEL_EVENT_VIDEO_STATUS: case CHANNEL_EVENT_VIDEO_STATUS:
return homeEvent.getVideoId() != null ? toStringType(homeEvent.getVideoStatus()) : UnDefType.NULL; return event.getVideoId() != null ? toStringType(event.getVideoStatus()) : UnDefType.NULL;
case CHANNEL_EVENT_VIDEO_LOCAL_URL: case CHANNEL_EVENT_VIDEO_LOCAL_URL:
return getStreamURL(true, homeEvent.getVideoId(), homeEvent.getVideoStatus()); return getStreamURL(true, event.getVideoId(), event.getVideoStatus());
case CHANNEL_EVENT_VIDEO_VPN_URL: case CHANNEL_EVENT_VIDEO_VPN_URL:
return getStreamURL(false, homeEvent.getVideoId(), homeEvent.getVideoStatus()); return getStreamURL(false, event.getVideoId(), event.getVideoStatus());
}
} }
return null; return null;
} }

View File

@ -0,0 +1,59 @@
/**
* Copyright (c) 2010-2022 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.handler.channelhelper;
import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*;
import static org.openhab.binding.netatmo.internal.utils.ChannelTypeUtils.*;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.netatmo.internal.api.dto.HomeEvent;
import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.types.State;
/**
* The {@link EventDoorbellChannelHelper} handles specific channels of doorbell events
*
* @author Gaël L'hopital - Initial contribution
*
*/
@NonNullByDefault
public class EventDoorbellChannelHelper extends EventChannelHelper {
public EventDoorbellChannelHelper() {
super(GROUP_DOORBELL_LAST_EVENT, GROUP_DOORBELL_SUB_EVENT);
}
@Override
protected @Nullable State internalGetHomeEvent(String channelId, @Nullable String groupId, HomeEvent event) {
if (groupId != null && GROUP_DOORBELL_SUB_EVENT.startsWith(groupId)) {
switch (channelId) {
case CHANNEL_EVENT_TYPE:
return toStringType(event.getEventType());
case CHANNEL_EVENT_TIME:
return new DateTimeType(event.getTime());
case CHANNEL_EVENT_MESSAGE:
return toStringType(event.getName());
case CHANNEL_EVENT_SNAPSHOT:
return toRawType(event.getSnapshotUrl());
case CHANNEL_EVENT_SNAPSHOT_URL:
return toStringType(event.getSnapshotUrl());
case CHANNEL_EVENT_VIGNETTE:
return toRawType(event.getVignetteUrl());
case CHANNEL_EVENT_VIGNETTE_URL:
return toStringType(event.getVignetteUrl());
}
}
return super.internalGetHomeEvent(channelId, groupId, event);
}
}

View File

@ -14,10 +14,11 @@ package org.openhab.binding.netatmo.internal.handler.channelhelper;
import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*; import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*;
import java.util.Set;
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.EventType; import org.openhab.binding.netatmo.internal.api.data.EventType;
import org.openhab.binding.netatmo.internal.api.data.ModuleType;
import org.openhab.binding.netatmo.internal.api.dto.Event; import org.openhab.binding.netatmo.internal.api.dto.Event;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
import org.openhab.core.types.State; import org.openhab.core.types.State;
@ -30,16 +31,16 @@ import org.openhab.core.types.State;
*/ */
@NonNullByDefault @NonNullByDefault
public class EventPersonChannelHelper extends EventChannelHelper { public class EventPersonChannelHelper extends EventChannelHelper {
public EventPersonChannelHelper() { public EventPersonChannelHelper() {
super(GROUP_PERSON_EVENT); super(GROUP_PERSON_LAST_EVENT);
} }
@Override @Override
protected @Nullable State internalGetEvent(String channelId, Event event) { protected @Nullable State internalGetEvent(String channelId, Event event) {
EventType eventType = event.getEventType(); EventType eventType = event.getEventType();
if (eventType.appliesOn(ModuleType.PERSON) && CHANNEL_PERSON_AT_HOME.equals(channelId)) { return eventType.validFor(moduleType) && CHANNEL_PERSON_AT_HOME.equals(channelId)
return OnOffType.from(EventType.PERSON.equals(eventType) || EventType.PERSON_HOME.equals(eventType)); ? OnOffType.from(Set.of(EventType.PERSON, EventType.PERSON_HOME).contains(eventType))
} : super.internalGetEvent(channelId, event);
return super.internalGetEvent(channelId, event);
} }
} }

View File

@ -29,9 +29,10 @@ import org.openhab.core.types.State;
* *
*/ */
@NonNullByDefault @NonNullByDefault
public class PresenceChannelHelper extends ChannelHelper { public class PresenceChannelHelper extends CameraChannelHelper {
public PresenceChannelHelper() { public PresenceChannelHelper() {
super(GROUP_PRESENCE); super(GROUP_CAM_STATUS, GROUP_CAM_LIVE, GROUP_PRESENCE);
} }
@Override @Override

View File

@ -33,7 +33,7 @@ import org.openhab.core.types.State;
public class RoomChannelHelper extends ChannelHelper { public class RoomChannelHelper extends ChannelHelper {
public RoomChannelHelper() { public RoomChannelHelper() {
super(GROUP_ROOM_PROPERTIES, GROUP_ROOM_TEMPERATURE); super(GROUP_TYPE_ROOM_TEMPERATURE, GROUP_TYPE_ROOM_PROPERTIES);
} }
@Override @Override

View File

@ -33,7 +33,7 @@ import org.openhab.core.types.UnDefType;
public class SetpointChannelHelper extends ChannelHelper { public class SetpointChannelHelper extends ChannelHelper {
public SetpointChannelHelper() { public SetpointChannelHelper() {
super(GROUP_TH_SETPOINT); super(GROUP_SETPOINT);
} }
@Override @Override

View File

@ -31,7 +31,7 @@ import org.openhab.core.types.State;
public class Therm1ChannelHelper extends ChannelHelper { public class Therm1ChannelHelper extends ChannelHelper {
public Therm1ChannelHelper() { public Therm1ChannelHelper() {
super(GROUP_TH_PROPERTIES); super(GROUP_TYPE_TH_PROPERTIES);
} }
@Override @Override

View File

@ -99,6 +99,10 @@ public class NetatmoThingTypeProvider implements ThingTypeProvider {
} }
public static String toGroupName(String groupeTypeName) { public static String toGroupName(String groupeTypeName) {
return groupeTypeName.replace(OPTION_EXTENDED, "").replace(OPTION_OUTSIDE, ""); String result = groupeTypeName;
for (String variation : GROUP_VARIATIONS) {
result = result.replace(variation, "");
}
return result;
} }
} }

View File

@ -18,6 +18,19 @@ channel-group-type.netatmo.energy.label = Home Energy
channel-group-type.netatmo.energy.channel.end.label = Mode End channel-group-type.netatmo.energy.channel.end.label = Mode End
channel-group-type.netatmo.energy.channel.end.description = End time of the currently applied setpoint. channel-group-type.netatmo.energy.channel.end.description = End time of the currently applied setpoint.
channel-group-type.netatmo.humidity.label = Humidity channel-group-type.netatmo.humidity.label = Humidity
channel-group-type.netatmo.last-event-doorbell.label = Last Event
channel-group-type.netatmo.last-event-doorbell.channel.local-video-url.label = Video Local URL
channel-group-type.netatmo.last-event-doorbell.channel.local-video-url.description = Local URL of the event recording.
channel-group-type.netatmo.last-event-doorbell.channel.time.label = Event Timestamp
channel-group-type.netatmo.last-event-doorbell.channel.time.description = Moment when event occurred.
channel-group-type.netatmo.last-event-doorbell.channel.vpn-video-url.label = Video VPN URL
channel-group-type.netatmo.last-event-doorbell.channel.vpn-video-url.description = URL of the event recording through Netatmo VPN.
channel-group-type.netatmo.last-event-person.label = Last Event
channel-group-type.netatmo.last-event-person.channel.message.description = Last event message from this person.
channel-group-type.netatmo.last-event-person.channel.snapshot.description = Picture of the last event for this person.
channel-group-type.netatmo.last-event-person.channel.snapshot-url.description = URL for the picture of the last event for this person.
channel-group-type.netatmo.last-event-person.channel.time.label = Person Timestamp
channel-group-type.netatmo.last-event-person.channel.time.description = Moment of the last event for this person.
channel-group-type.netatmo.last-event.label = Last Event channel-group-type.netatmo.last-event.label = Last Event
channel-group-type.netatmo.last-event.channel.local-video-url.label = Video Local URL channel-group-type.netatmo.last-event.channel.local-video-url.label = Video Local URL
channel-group-type.netatmo.last-event.channel.local-video-url.description = Local URL of the event recording. channel-group-type.netatmo.last-event.channel.local-video-url.description = Local URL of the event recording.
@ -25,6 +38,9 @@ channel-group-type.netatmo.last-event.channel.time.label = Event Timestamp
channel-group-type.netatmo.last-event.channel.time.description = Moment when event occurred. channel-group-type.netatmo.last-event.channel.time.description = Moment when event occurred.
channel-group-type.netatmo.last-event.channel.vpn-video-url.label = Video VPN URL channel-group-type.netatmo.last-event.channel.vpn-video-url.label = Video VPN URL
channel-group-type.netatmo.last-event.channel.vpn-video-url.description = URL of the event recording through Netatmo VPN. channel-group-type.netatmo.last-event.channel.vpn-video-url.description = URL of the event recording through Netatmo VPN.
channel-group-type.netatmo.live-doorbell.label = Live Monitoring
channel-group-type.netatmo.live-doorbell.channel.local-picture-url.label = Live Snapshot Local URL
channel-group-type.netatmo.live-doorbell.channel.local-picture-url.description = Local URL of the live snapshot for this camera.
channel-group-type.netatmo.live.label = Live Monitoring channel-group-type.netatmo.live.label = Live Monitoring
channel-group-type.netatmo.live.channel.local-picture-url.label = Live Snapshot Local URL channel-group-type.netatmo.live.channel.local-picture-url.label = Live Snapshot Local URL
channel-group-type.netatmo.live.channel.local-picture-url.description = Local URL of the live snapshot for this camera. channel-group-type.netatmo.live.channel.local-picture-url.description = Local URL of the live snapshot for this camera.
@ -36,12 +52,6 @@ channel-group-type.netatmo.live.channel.vpn-stream-url.label = Live Stream VPN U
channel-group-type.netatmo.live.channel.vpn-stream-url.description = URL of the live stream for this camera through Netatmo VPN. channel-group-type.netatmo.live.channel.vpn-stream-url.description = URL of the live stream for this camera through Netatmo VPN.
channel-group-type.netatmo.location.label = Location channel-group-type.netatmo.location.label = Location
channel-group-type.netatmo.noise.label = Noise channel-group-type.netatmo.noise.label = Noise
channel-group-type.netatmo.person-event.label = Last Event
channel-group-type.netatmo.person-event.channel.message.description = Last event message from this person.
channel-group-type.netatmo.person-event.channel.snapshot.description = Picture of the last event for this person.
channel-group-type.netatmo.person-event.channel.snapshot-url.description = URL for the picture of the last event for this person.
channel-group-type.netatmo.person-event.channel.time.label = Person Timestamp
channel-group-type.netatmo.person-event.channel.time.description = Moment of the last event for this person.
channel-group-type.netatmo.person.label = Person channel-group-type.netatmo.person.label = Person
channel-group-type.netatmo.person.channel.last-seen.label = Last Seen channel-group-type.netatmo.person.channel.last-seen.label = Last Seen
channel-group-type.netatmo.person.channel.last-seen.description = Moment when this person was last seen. channel-group-type.netatmo.person.channel.last-seen.description = Moment when this person was last seen.
@ -55,8 +65,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-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.label = Rain 24h
channel-group-type.netatmo.rain.channel.sum-24.description = Quantity of water during the current day. channel-group-type.netatmo.rain.channel.sum-24.description = Quantity of water during the current day.
channel-group-type.netatmo.room-properties.label = Room Status channel-group-type.netatmo.properties-room.label = Room Status
channel-group-type.netatmo.room-temperature.label = Room Temperature channel-group-type.netatmo.temperature-room.label = Room Temperature
channel-group-type.netatmo.security.label = Home Security channel-group-type.netatmo.security.label = Home Security
channel-group-type.netatmo.setpoint.label = Setpoint channel-group-type.netatmo.setpoint.label = Setpoint
channel-group-type.netatmo.setpoint.channel.end.label = Setpoint End channel-group-type.netatmo.setpoint.channel.end.label = Setpoint End
@ -64,7 +74,15 @@ channel-group-type.netatmo.setpoint.channel.end.description = End time of the cu
channel-group-type.netatmo.setpoint.channel.start.label = Setpoint Start channel-group-type.netatmo.setpoint.channel.start.label = Setpoint Start
channel-group-type.netatmo.setpoint.channel.start.description = Start time of the currently applied setpoint. channel-group-type.netatmo.setpoint.channel.start.description = Start time of the currently applied setpoint.
channel-group-type.netatmo.signal.label = Signal channel-group-type.netatmo.signal.label = Signal
channel-group-type.netatmo.status-doorbell.label = Camera Status
channel-group-type.netatmo.status.label = Camera Status channel-group-type.netatmo.status.label = Camera Status
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 then sub-event occurred.
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.temperature-extended.label = Temperature channel-group-type.netatmo.temperature-extended.label = Temperature
channel-group-type.netatmo.temperature-extended.channel.max-time.label = Today Max Timestamp channel-group-type.netatmo.temperature-extended.channel.max-time.label = Today Max Timestamp
channel-group-type.netatmo.temperature-extended.channel.max-time.description = Moment when temperature was measured at its maximum today. channel-group-type.netatmo.temperature-extended.channel.max-time.description = Moment when temperature was measured at its maximum today.
@ -82,7 +100,7 @@ channel-group-type.netatmo.temperature.channel.max-time.label = Today Max Timest
channel-group-type.netatmo.temperature.channel.max-time.description = Moment when temperature was measured at its maximum today. channel-group-type.netatmo.temperature.channel.max-time.description = Moment when temperature was measured at its maximum today.
channel-group-type.netatmo.temperature.channel.min-time.label = Today Min Timestamp channel-group-type.netatmo.temperature.channel.min-time.label = Today Min Timestamp
channel-group-type.netatmo.temperature.channel.min-time.description = Moment when temperature was measured at its minimum today. channel-group-type.netatmo.temperature.channel.min-time.description = Moment when temperature was measured at its minimum today.
channel-group-type.netatmo.th-properties.label = Thermostat channel-group-type.netatmo.properties-thermostat.label = Thermostat
channel-group-type.netatmo.timestamp-extended.label = Timestamp channel-group-type.netatmo.timestamp-extended.label = Timestamp
channel-group-type.netatmo.timestamp-extended.channel.last-seen.label = Last Seen channel-group-type.netatmo.timestamp-extended.channel.last-seen.label = Last Seen
channel-group-type.netatmo.timestamp-extended.channel.last-seen.description = Last time the module reported its presence. channel-group-type.netatmo.timestamp-extended.channel.last-seen.description = Last time the module reported its presence.
@ -154,10 +172,11 @@ channel-type.netatmo.event-type.description = Description of the event.
channel-type.netatmo.event-type.state.option.PERSON = Face detected channel-type.netatmo.event-type.state.option.PERSON = Face detected
channel-type.netatmo.event-type.state.option.PERSON_AWAY = Person has left home channel-type.netatmo.event-type.state.option.PERSON_AWAY = Person has left home
channel-type.netatmo.event-type.state.option.PERSON_HOME = Person is at home channel-type.netatmo.event-type.state.option.PERSON_HOME = Person is at home
channel-type.netatmo.event-type.state.option.OUTDOOR = Motion detected by Presence channel-type.netatmo.event-type.state.option.OUTDOOR = Motion detected by Outdoor Camera
channel-type.netatmo.event-type.state.option.MOVEMENT = Motion detected channel-type.netatmo.event-type.state.option.MOVEMENT = Motion detected
channel-type.netatmo.event-type.state.option.HUMAN = Human seen channel-type.netatmo.event-type.state.option.HUMAN = Human seen
channel-type.netatmo.event-type.state.option.ANIMAL = Animal seen channel-type.netatmo.event-type.state.option.ANIMAL = Animal seen
channel-type.netatmo.event-type.state.option.VEHICLE = Car seen
channel-type.netatmo.event-type.state.option.NEW_MODULE = New Module has been paired channel-type.netatmo.event-type.state.option.NEW_MODULE = New Module has been paired
channel-type.netatmo.event-type.state.option.MODULE_CONNECT = Module is connected with the Indoor Camera channel-type.netatmo.event-type.state.option.MODULE_CONNECT = Module is connected with the Indoor Camera
channel-type.netatmo.event-type.state.option.MODULE_DISCONNECT = Module lost its connection with the Indoor Camera channel-type.netatmo.event-type.state.option.MODULE_DISCONNECT = Module lost its connection with the Indoor Camera
@ -170,6 +189,9 @@ channel-type.netatmo.event-type.state.option.OFF = Monitoring stopped
channel-type.netatmo.event-type.state.option.BOOT = Camera booting channel-type.netatmo.event-type.state.option.BOOT = Camera booting
channel-type.netatmo.event-type.state.option.SD = SD card status changed channel-type.netatmo.event-type.state.option.SD = SD card status changed
channel-type.netatmo.event-type.state.option.ALIM = Power status changed channel-type.netatmo.event-type.state.option.ALIM = Power status changed
channel-type.netatmo.event-type.state.option.ACCEPTED_CALL = Call is incoming
channel-type.netatmo.event-type.state.option.INCOMING_CALL = Call has been answered by a user
channel-type.netatmo.event-type.state.option.MISSED_CALL = Call has not been answered by anyone
channel-type.netatmo.floodlight-mode.label = Floodlight channel-type.netatmo.floodlight-mode.label = Floodlight
channel-type.netatmo.floodlight-mode.description = State of the floodlight (On/Off/Auto) channel-type.netatmo.floodlight-mode.description = State of the floodlight (On/Off/Auto)
channel-type.netatmo.floodlight-mode.state.option.ON = On channel-type.netatmo.floodlight-mode.state.option.ON = On

View File

@ -55,8 +55,8 @@ channel-group-type.netatmo.rain.channel.sum-1.label = Pioggia 1h
channel-group-type.netatmo.rain.channel.sum-1.description = Quantità di acqua nell'ultima ora. channel-group-type.netatmo.rain.channel.sum-1.description = Quantità di acqua nell'ultima ora.
channel-group-type.netatmo.rain.channel.sum-24.label = Pioggia 24h channel-group-type.netatmo.rain.channel.sum-24.label = Pioggia 24h
channel-group-type.netatmo.rain.channel.sum-24.description = Quantità di acqua durante il giorno corrente. channel-group-type.netatmo.rain.channel.sum-24.description = Quantità di acqua durante il giorno corrente.
channel-group-type.netatmo.room-properties.label = Stato Stanza channel-group-type.netatmo.properties-room.label = Stato Stanza
channel-group-type.netatmo.room-temperature.label = Temperatura Stanza channel-group-type.netatmo.temperature-room.label = Temperatura Stanza
channel-group-type.netatmo.security.label = Sicurezza Domestica channel-group-type.netatmo.security.label = Sicurezza Domestica
channel-group-type.netatmo.setpoint.label = Valore Impostato channel-group-type.netatmo.setpoint.label = Valore Impostato
channel-group-type.netatmo.setpoint.channel.end.label = Fine Setpoint channel-group-type.netatmo.setpoint.channel.end.label = Fine Setpoint
@ -82,7 +82,7 @@ channel-group-type.netatmo.temperature.channel.max-time.label = Ora Temp Massima
channel-group-type.netatmo.temperature.channel.max-time.description = Momento quando oggi la temperatura è stata misurata al suo massimo. channel-group-type.netatmo.temperature.channel.max-time.description = Momento quando oggi la temperatura è stata misurata al suo massimo.
channel-group-type.netatmo.temperature.channel.min-time.label = Ora Temperatura Minima Oggi channel-group-type.netatmo.temperature.channel.min-time.label = Ora Temperatura Minima Oggi
channel-group-type.netatmo.temperature.channel.min-time.description = Momento in cui la temperatura è stata misurata al suo minimo oggi. channel-group-type.netatmo.temperature.channel.min-time.description = Momento in cui la temperatura è stata misurata al suo minimo oggi.
channel-group-type.netatmo.th-properties.label = Termostato channel-group-type.netatmo.properties-thermostat.label = Termostato
channel-group-type.netatmo.timestamp-extended.label = Data/Ora channel-group-type.netatmo.timestamp-extended.label = Data/Ora
channel-group-type.netatmo.timestamp-extended.channel.last-seen.label = Visto per l'ultima volta channel-group-type.netatmo.timestamp-extended.channel.last-seen.label = Visto per l'ultima volta
channel-group-type.netatmo.timestamp-extended.channel.last-seen.description = L'ultima volta che il modulo ha segnalato la sua presenza. channel-group-type.netatmo.timestamp-extended.channel.last-seen.description = L'ultima volta che il modulo ha segnalato la sua presenza.

View File

@ -318,10 +318,11 @@
<option value="PERSON">Face detected</option> <option value="PERSON">Face detected</option>
<option value="PERSON_AWAY">Person has left home</option> <option value="PERSON_AWAY">Person has left home</option>
<option value="PERSON_HOME">Person is at home</option> <option value="PERSON_HOME">Person is at home</option>
<option value="OUTDOOR">Motion detected by Presence</option> <option value="OUTDOOR">Motion detected by Outdoor Camera</option>
<option value="MOVEMENT">Motion detected</option> <option value="MOVEMENT">Motion detected</option>
<option value="HUMAN">Human seen</option> <option value="HUMAN">Human seen</option>
<option value="ANIMAL">Animal seen</option> <option value="ANIMAL">Animal seen</option>
<option value="VEHICLE">Car seen</option>
<option value="NEW_MODULE">New Module has been paired</option> <option value="NEW_MODULE">New Module has been paired</option>
<option value="MODULE_CONNECT">Module is connected with the Indoor Camera</option> <option value="MODULE_CONNECT">Module is connected with the Indoor Camera</option>
<option value="MODULE_DISCONNECT">Module lost its connection with the Indoor Camera</option> <option value="MODULE_DISCONNECT">Module lost its connection with the Indoor Camera</option>
@ -334,6 +335,9 @@
<option value="BOOT">Camera booting</option> <option value="BOOT">Camera booting</option>
<option value="SD">SD card status changed</option> <option value="SD">SD card status changed</option>
<option value="ALIM">Power status changed</option> <option value="ALIM">Power status changed</option>
<option value="ACCEPTED_CALL">Call is incoming</option>
<option value="INCOMING_CALL">Call has been answered by a user</option>
<option value="MISSED_CALL">Call has not been answered by anyone</option>
</options> </options>
</state> </state>
</channel-type> </channel-type>
@ -375,6 +379,7 @@
<option value="MOVEMENT"/> <option value="MOVEMENT"/>
<option value="HUMAN"/> <option value="HUMAN"/>
<option value="ANIMAL"/> <option value="ANIMAL"/>
<option value="VEHICLE"/>
<option value="NEW_MODULE"/> <option value="NEW_MODULE"/>
<option value="MODULE_CONNECT"/> <option value="MODULE_CONNECT"/>
<option value="MODULE_DISCONNECT"/> <option value="MODULE_DISCONNECT"/>
@ -387,6 +392,9 @@
<option value="BOOT"/> <option value="BOOT"/>
<option value="SD"/> <option value="SD"/>
<option value="ALIM"/> <option value="ALIM"/>
<option value="ACCEPTED_CALL"/>
<option value="INCOMING_CALL"/>
<option value="MISSED_CALL"/>
</options> </options>
</event> </event>
</channel-type> </channel-type>

View File

@ -11,14 +11,14 @@
</channels> </channels>
</channel-group-type> </channel-group-type>
<channel-group-type id="room-temperature"> <channel-group-type id="temperature-room">
<label>Room Temperature</label> <label>Room Temperature</label>
<channels> <channels>
<channel id="value" typeId="system.indoor-temperature"/> <channel id="value" typeId="system.indoor-temperature"/>
</channels> </channels>
</channel-group-type> </channel-group-type>
<channel-group-type id="room-properties"> <channel-group-type id="properties-room">
<label>Room Status</label> <label>Room Status</label>
<channels> <channels>
<channel id="window-open" typeId="window-open"/> <channel id="window-open" typeId="window-open"/>
@ -43,10 +43,10 @@
</channels> </channels>
</channel-group-type> </channel-group-type>
<channel-group-type id="th-properties"> <channel-group-type id="properties-thermostat">
<label>Thermostat</label> <label>Thermostat</label>
<channels> <channels>
<channel id="relay-status" typeId="heating-status"/> <channel id="relay" typeId="heating-status"/>
</channels> </channels>
</channel-group-type> </channel-group-type>

View File

@ -23,6 +23,14 @@
</channels> </channels>
</channel-group-type> </channel-group-type>
<channel-group-type id="status-doorbell">
<label>Camera Status</label>
<channels>
<channel id="sd-card" typeId="sd-card-status"/>
<channel id="alim" typeId="alim-status"/>
</channels>
</channel-group-type>
<channel-group-type id="live"> <channel-group-type id="live">
<label>Live Monitoring</label> <label>Live Monitoring</label>
<channels> <channels>
@ -46,6 +54,17 @@
</channels> </channels>
</channel-group-type> </channel-group-type>
<channel-group-type id="live-doorbell">
<label>Live Monitoring</label>
<channels>
<channel id="picture" typeId="live-picture"/>
<channel id="local-picture-url" typeId="live-picture-url">
<label>Live Snapshot Local URL</label>
<description>Local URL of the live snapshot for this camera.</description>
</channel>
</channels>
</channel-group-type>
<channel-group-type id="last-event"> <channel-group-type id="last-event">
<label>Last Event</label> <label>Last Event</label>
<channels> <channels>
@ -71,7 +90,49 @@
</channels> </channels>
</channel-group-type> </channel-group-type>
<channel-group-type id="person-event"> <channel-group-type id="sub-event-doorbell">
<label>Sub Event</label>
<channels>
<channel id="type" typeId="event-type"/>
<channel id="time" typeId="timestamp">
<label>Sub-Event Timestamp</label>
<description>Moment when then sub-event occurred.</description>
</channel>
<channel id="message" typeId="message"/>
<channel id="snapshot" typeId="event-picture"/>
<channel id="snapshot-url" typeId="event-picture-url"/>
<channel id="vignette" typeId="event-picture">
<label>Vignette</label>
<description>Vignette of the Snapshot.</description>
</channel>
<channel id="vignette-url" typeId="event-picture-url">
<label>Vignette URL</label>
<description>URL of the vignette.</description>
</channel>
</channels>
</channel-group-type>
<channel-group-type id="last-event-doorbell">
<label>Last Event</label>
<channels>
<channel id="type" typeId="event-type"/>
<channel id="video-status" typeId="video-status"/>
<channel id="time" typeId="timestamp">
<label>Event Timestamp</label>
<description>Moment when event occurred.</description>
</channel>
<channel id="local-video-url" typeId="video-url">
<label>Video Local URL</label>
<description>Local URL of the event recording.</description>
</channel>
<channel id="vpn-video-url" typeId="video-url">
<label>Video VPN URL</label>
<description>URL of the event recording through Netatmo VPN.</description>
</channel>
</channels>
</channel-group-type>
<channel-group-type id="last-event-person">
<label>Last Event</label> <label>Last Event</label>
<channels> <channels>
<channel id="subtype" typeId="event-subtype"/> <channel id="subtype" typeId="event-subtype"/>