mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[netatmo] Fix erroneous local URL handling (#16492)
* Wrong local URL handling * Adds configuration element ipAddress to Cameras (Welcome, Doorbell, Presence) so they remain reachable if API answer is in an incorrect network * Removing CameraConfiguration so binding does not break if thing configuration is not up-to-date --------- Signed-off-by: clinique <gael@lhopital.org> Signed-off-by: gael@lhopital.org <gael@lhopital.org> Signed-off-by: Ciprian Pascu <contact@ciprianpascu.ro>
This commit is contained in:
parent
f3bf285b85
commit
55c84385ab
@ -77,18 +77,18 @@ Once authentication process has been done, current refreshToken is stored in `/O
|
|||||||
| Thing Type | Type | Netatmo Object | Description | Thing Parameters |
|
| Thing Type | Type | Netatmo Object | Description | Thing Parameters |
|
||||||
| --------------- | ------ | -------------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
|
| --------------- | ------ | -------------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
|
||||||
| account | Bridge | N/A | This bridge represents an account, gateway to Netatmo API. | clientId, clientSecret, username, password, webHookUrl, reconnectInterval |
|
| account | Bridge | N/A | This bridge represents an account, gateway to Netatmo API. | clientId, clientSecret, username, password, webHookUrl, reconnectInterval |
|
||||||
| home | Bridge | NAHome | A home hosting Security or Energy devices and modules. | id, refreshInterval |
|
| home | Bridge | NAHome | A home hosting Security or Energy devices and modules. | id, refreshInterval, energyId, securityId |
|
||||||
| person | Thing | NAPerson | A person known by your Netatmo system. | id |
|
| person | Thing | NAPerson | A person known by your Netatmo system. | id |
|
||||||
| welcome | Thing | NACamera | The Netatmo Smart Indoor Camera (Welcome). | id |
|
| welcome | Thing | NACamera | The Netatmo Smart Indoor Camera (Welcome). | id, ipAddress |
|
||||||
| presence | Thing | NOC | The Netatmo Smart Outdoor Camera (Presence) camera with or without siren. | id |
|
| presence | Thing | NOC | The Netatmo Smart Outdoor Camera (Presence) camera with or without siren. | id, ipAddress |
|
||||||
| siren | Thing | NIS | The Netatmo Smart Indoor Siren. | id |
|
| siren | Thing | NIS | The Netatmo Smart Indoor Siren. | id |
|
||||||
| doorbell | Thing | NDB | The Netatmo Smart Video Doorbell device. | id |
|
| doorbell | Thing | NDB | The Netatmo Smart Video Doorbell device. | id, ipAddress |
|
||||||
| weather-station | Bridge | NAMain | Main indoor module reporting temperature, humidity, pressure, air quality and sound level. | id |
|
| weather-station | Bridge | NAMain | Main indoor module reporting temperature, humidity, pressure, air quality and sound level. | id, refreshInterval |
|
||||||
| outdoor | Thing | NAModule1 | Outdoor module reporting temperature and humidity. | id |
|
| outdoor | Thing | NAModule1 | Outdoor module reporting temperature and humidity. | id |
|
||||||
| wind | Thing | NAModule2 | Wind sensor reporting wind angle and strength. | id |
|
| wind | Thing | NAModule2 | Wind sensor reporting wind angle and strength. | id |
|
||||||
| rain | Thing | NAModule3 | Rain Gauge measuring precipitation. | id |
|
| rain | Thing | NAModule3 | Rain Gauge measuring precipitation. | id |
|
||||||
| indoor | Thing | NAModule4 | Additional indoor module reporting temperature, humidity and CO2 level. | id |
|
| indoor | Thing | NAModule4 | Additional indoor module reporting temperature, humidity and CO2 level. | id |
|
||||||
| home-coach | Thing | NHC | Healthy home coach reporting health-index, temperature, humidity, pressure, air quality, sound level. | id |
|
| home-coach | Thing | NHC | Healthy home coach reporting health-index, temperature, humidity, pressure, air quality, sound level. | id, refreshInterval |
|
||||||
| plug | Thing | NAPlug | The relay connected to the boiler controlling a Thermostat and zero or more valves. | id |
|
| plug | Thing | NAPlug | The relay connected to the boiler controlling a Thermostat and zero or more valves. | id |
|
||||||
| thermostat | Thing | NATherm1 | The Thermostat device placed in a given room. | id |
|
| thermostat | Thing | NATherm1 | The Thermostat device placed in a given room. | id |
|
||||||
| room | Thing | NARoom | A room in your house. | id |
|
| room | Thing | NARoom | A room in your house. | id |
|
||||||
|
@ -64,67 +64,70 @@ import org.openhab.core.thing.ThingTypeUID;
|
|||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public enum ModuleType {
|
public enum ModuleType {
|
||||||
UNKNOWN(FeatureArea.NONE, "", 1, null, Set.of()),
|
UNKNOWN(FeatureArea.NONE, "", 1, "virtual", null, Set.of()),
|
||||||
|
|
||||||
ACCOUNT(FeatureArea.NONE, "", 1, null, Set.of(), new ChannelGroup(ApiBridgeChannelHelper.class, GROUP_MONITORING)),
|
ACCOUNT(FeatureArea.NONE, "", 1, "api_bridge", null, Set.of(),
|
||||||
|
new ChannelGroup(ApiBridgeChannelHelper.class, GROUP_MONITORING)),
|
||||||
|
|
||||||
HOME(FeatureArea.NONE, "NAHome", 1, ACCOUNT,
|
HOME(FeatureArea.NONE, "NAHome", 1, "home", ACCOUNT,
|
||||||
Set.of(DeviceCapability.class, HomeCapability.class, ChannelHelperCapability.class),
|
Set.of(DeviceCapability.class, HomeCapability.class, ChannelHelperCapability.class),
|
||||||
new ChannelGroup(SecurityChannelHelper.class, GROUP_SECURITY_EVENT, GROUP_SECURITY),
|
new ChannelGroup(SecurityChannelHelper.class, GROUP_SECURITY_EVENT, GROUP_SECURITY),
|
||||||
new ChannelGroup(EnergyChannelHelper.class, GROUP_ENERGY)),
|
new ChannelGroup(EnergyChannelHelper.class, GROUP_ENERGY)),
|
||||||
|
|
||||||
PERSON(FeatureArea.SECURITY, "NAPerson", 1, HOME, Set.of(PersonCapability.class, ChannelHelperCapability.class),
|
PERSON(FeatureArea.SECURITY, "NAPerson", 1, "virtual", HOME,
|
||||||
|
Set.of(PersonCapability.class, ChannelHelperCapability.class),
|
||||||
new ChannelGroup(PersonChannelHelper.class, GROUP_PERSON),
|
new ChannelGroup(PersonChannelHelper.class, GROUP_PERSON),
|
||||||
new ChannelGroup(EventPersonChannelHelper.class, GROUP_PERSON_LAST_EVENT)),
|
new ChannelGroup(EventPersonChannelHelper.class, GROUP_PERSON_LAST_EVENT)),
|
||||||
|
|
||||||
WELCOME(FeatureArea.SECURITY, "NACamera", 1, HOME, Set.of(CameraCapability.class, ChannelHelperCapability.class),
|
WELCOME(FeatureArea.SECURITY, "NACamera", 1, "camera", HOME,
|
||||||
ChannelGroup.SIGNAL, ChannelGroup.EVENT,
|
Set.of(CameraCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL, ChannelGroup.EVENT,
|
||||||
new ChannelGroup(CameraChannelHelper.class, GROUP_SECURITY_EVENT, GROUP_CAM_STATUS, GROUP_CAM_LIVE)),
|
new ChannelGroup(CameraChannelHelper.class, GROUP_SECURITY_EVENT, GROUP_CAM_STATUS, GROUP_CAM_LIVE)),
|
||||||
|
|
||||||
TAG(FeatureArea.SECURITY, "NACamDoorTag", 1, WELCOME, Set.of(ChannelHelperCapability.class), ChannelGroup.SIGNAL,
|
TAG(FeatureArea.SECURITY, "NACamDoorTag", 1, "device", WELCOME, Set.of(ChannelHelperCapability.class),
|
||||||
ChannelGroup.BATTERY, ChannelGroup.TIMESTAMP, new ChannelGroup(DoorTagChannelHelper.class, GROUP_TAG)),
|
ChannelGroup.SIGNAL, ChannelGroup.BATTERY, ChannelGroup.TIMESTAMP,
|
||||||
|
new ChannelGroup(DoorTagChannelHelper.class, GROUP_TAG)),
|
||||||
|
|
||||||
SIREN(FeatureArea.SECURITY, "NIS", 1, WELCOME, Set.of(ChannelHelperCapability.class), ChannelGroup.SIGNAL,
|
SIREN(FeatureArea.SECURITY, "NIS", 1, "device", WELCOME, Set.of(ChannelHelperCapability.class), ChannelGroup.SIGNAL,
|
||||||
ChannelGroup.BATTERY, ChannelGroup.TIMESTAMP, new ChannelGroup(SirenChannelHelper.class, GROUP_SIREN)),
|
ChannelGroup.BATTERY, ChannelGroup.TIMESTAMP, new ChannelGroup(SirenChannelHelper.class, GROUP_SIREN)),
|
||||||
|
|
||||||
PRESENCE(FeatureArea.SECURITY, "NOC", 1, HOME, Set.of(PresenceCapability.class, ChannelHelperCapability.class),
|
PRESENCE(FeatureArea.SECURITY, "NOC", 1, "camera", HOME,
|
||||||
ChannelGroup.SIGNAL, ChannelGroup.EVENT,
|
Set.of(PresenceCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL, ChannelGroup.EVENT,
|
||||||
new ChannelGroup(PresenceChannelHelper.class, GROUP_SECURITY_EVENT, GROUP_CAM_STATUS, GROUP_CAM_LIVE,
|
new ChannelGroup(PresenceChannelHelper.class, GROUP_SECURITY_EVENT, GROUP_CAM_STATUS, GROUP_CAM_LIVE,
|
||||||
GROUP_PRESENCE),
|
GROUP_PRESENCE),
|
||||||
new ChannelGroup(EventCameraChannelHelper.class, GROUP_SUB_EVENT)),
|
new ChannelGroup(EventCameraChannelHelper.class, GROUP_SUB_EVENT)),
|
||||||
|
|
||||||
DOORBELL(FeatureArea.SECURITY, "NDB", 1, HOME, Set.of(DoorbellCapability.class, ChannelHelperCapability.class),
|
DOORBELL(FeatureArea.SECURITY, "NDB", 1, "camera", HOME,
|
||||||
ChannelGroup.SIGNAL,
|
Set.of(DoorbellCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL,
|
||||||
new ChannelGroup(CameraChannelHelper.class, GROUP_SECURITY_EVENT, GROUP_DOORBELL_STATUS,
|
new ChannelGroup(CameraChannelHelper.class, GROUP_SECURITY_EVENT, GROUP_DOORBELL_STATUS,
|
||||||
GROUP_DOORBELL_LIVE),
|
GROUP_DOORBELL_LIVE),
|
||||||
new ChannelGroup(EventCameraChannelHelper.class, GROUP_DOORBELL_LAST_EVENT, GROUP_DOORBELL_SUB_EVENT)),
|
new ChannelGroup(EventCameraChannelHelper.class, GROUP_DOORBELL_LAST_EVENT, GROUP_DOORBELL_SUB_EVENT)),
|
||||||
|
|
||||||
WEATHER_STATION(FeatureArea.WEATHER, "NAMain", 1, ACCOUNT,
|
WEATHER_STATION(FeatureArea.WEATHER, "NAMain", 1, "configurable", ACCOUNT,
|
||||||
Set.of(DeviceCapability.class, WeatherCapability.class, MeasureCapability.class,
|
Set.of(DeviceCapability.class, WeatherCapability.class, MeasureCapability.class,
|
||||||
ChannelHelperCapability.class),
|
ChannelHelperCapability.class),
|
||||||
ChannelGroup.SIGNAL, ChannelGroup.HUMIDITY, ChannelGroup.TSTAMP_EXT, ChannelGroup.MEASURE,
|
ChannelGroup.SIGNAL, ChannelGroup.HUMIDITY, ChannelGroup.TSTAMP_EXT, ChannelGroup.MEASURE,
|
||||||
ChannelGroup.AIR_QUALITY, ChannelGroup.LOCATION, ChannelGroup.NOISE, ChannelGroup.TEMP_INSIDE_EXT,
|
ChannelGroup.AIR_QUALITY, ChannelGroup.LOCATION, ChannelGroup.NOISE, ChannelGroup.TEMP_INSIDE_EXT,
|
||||||
new ChannelGroup(PressureChannelHelper.class, MeasureClass.PRESSURE, GROUP_TYPE_PRESSURE_EXTENDED)),
|
new ChannelGroup(PressureChannelHelper.class, MeasureClass.PRESSURE, GROUP_TYPE_PRESSURE_EXTENDED)),
|
||||||
|
|
||||||
OUTDOOR(FeatureArea.WEATHER, "NAModule1", 1, WEATHER_STATION,
|
OUTDOOR(FeatureArea.WEATHER, "NAModule1", 1, "device", WEATHER_STATION,
|
||||||
Set.of(MeasureCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL, ChannelGroup.HUMIDITY,
|
Set.of(MeasureCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL, ChannelGroup.HUMIDITY,
|
||||||
ChannelGroup.TSTAMP_EXT, ChannelGroup.MEASURE, ChannelGroup.BATTERY, ChannelGroup.TEMP_OUTSIDE_EXT),
|
ChannelGroup.TSTAMP_EXT, ChannelGroup.MEASURE, ChannelGroup.BATTERY, ChannelGroup.TEMP_OUTSIDE_EXT),
|
||||||
|
|
||||||
WIND(FeatureArea.WEATHER, "NAModule2", 1, WEATHER_STATION, Set.of(ChannelHelperCapability.class),
|
WIND(FeatureArea.WEATHER, "NAModule2", 1, "device", WEATHER_STATION, Set.of(ChannelHelperCapability.class),
|
||||||
ChannelGroup.SIGNAL, ChannelGroup.TSTAMP_EXT, ChannelGroup.BATTERY,
|
ChannelGroup.SIGNAL, ChannelGroup.TSTAMP_EXT, ChannelGroup.BATTERY,
|
||||||
new ChannelGroup(WindChannelHelper.class, GROUP_WIND)),
|
new ChannelGroup(WindChannelHelper.class, GROUP_WIND)),
|
||||||
|
|
||||||
RAIN(FeatureArea.WEATHER, "NAModule3", 1, WEATHER_STATION,
|
RAIN(FeatureArea.WEATHER, "NAModule3", 1, "device", WEATHER_STATION,
|
||||||
Set.of(MeasureCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL,
|
Set.of(MeasureCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL,
|
||||||
ChannelGroup.TSTAMP_EXT, ChannelGroup.MEASURE, ChannelGroup.BATTERY,
|
ChannelGroup.TSTAMP_EXT, ChannelGroup.MEASURE, ChannelGroup.BATTERY,
|
||||||
new ChannelGroup(RainChannelHelper.class, MeasureClass.RAIN_QUANTITY, GROUP_RAIN)),
|
new ChannelGroup(RainChannelHelper.class, MeasureClass.RAIN_QUANTITY, GROUP_RAIN)),
|
||||||
|
|
||||||
INDOOR(FeatureArea.WEATHER, "NAModule4", 1, WEATHER_STATION,
|
INDOOR(FeatureArea.WEATHER, "NAModule4", 1, "device", WEATHER_STATION,
|
||||||
Set.of(MeasureCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL,
|
Set.of(MeasureCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL,
|
||||||
ChannelGroup.TSTAMP_EXT, ChannelGroup.MEASURE, ChannelGroup.BATTERY, ChannelGroup.HUMIDITY,
|
ChannelGroup.TSTAMP_EXT, ChannelGroup.MEASURE, ChannelGroup.BATTERY, ChannelGroup.HUMIDITY,
|
||||||
ChannelGroup.TEMP_INSIDE_EXT, ChannelGroup.AIR_QUALITY),
|
ChannelGroup.TEMP_INSIDE_EXT, ChannelGroup.AIR_QUALITY),
|
||||||
|
|
||||||
HOME_COACH(FeatureArea.AIR_CARE, "NHC", 1, ACCOUNT,
|
HOME_COACH(FeatureArea.AIR_CARE, "NHC", 1, "configurable", ACCOUNT,
|
||||||
Set.of(DeviceCapability.class, AirCareCapability.class, MeasureCapability.class,
|
Set.of(DeviceCapability.class, AirCareCapability.class, MeasureCapability.class,
|
||||||
ChannelHelperCapability.class),
|
ChannelHelperCapability.class),
|
||||||
ChannelGroup.LOCATION, ChannelGroup.SIGNAL, ChannelGroup.NOISE, ChannelGroup.HUMIDITY,
|
ChannelGroup.LOCATION, ChannelGroup.SIGNAL, ChannelGroup.NOISE, ChannelGroup.HUMIDITY,
|
||||||
@ -132,24 +135,26 @@ public enum ModuleType {
|
|||||||
new ChannelGroup(AirQualityChannelHelper.class, GROUP_TYPE_AIR_QUALITY_EXTENDED),
|
new ChannelGroup(AirQualityChannelHelper.class, GROUP_TYPE_AIR_QUALITY_EXTENDED),
|
||||||
new ChannelGroup(PressureChannelHelper.class, MeasureClass.PRESSURE, GROUP_PRESSURE)),
|
new ChannelGroup(PressureChannelHelper.class, MeasureClass.PRESSURE, GROUP_PRESSURE)),
|
||||||
|
|
||||||
PLUG(FeatureArea.ENERGY, "NAPlug", 1, HOME, Set.of(ChannelHelperCapability.class), ChannelGroup.SIGNAL),
|
PLUG(FeatureArea.ENERGY, "NAPlug", 1, "device", HOME, Set.of(ChannelHelperCapability.class), ChannelGroup.SIGNAL),
|
||||||
|
|
||||||
VALVE(FeatureArea.ENERGY, "NRV", 1, PLUG, Set.of(ChannelHelperCapability.class), ChannelGroup.SIGNAL,
|
VALVE(FeatureArea.ENERGY, "NRV", 1, "device", PLUG, Set.of(ChannelHelperCapability.class), ChannelGroup.SIGNAL,
|
||||||
ChannelGroup.BATTERY_EXT),
|
ChannelGroup.BATTERY_EXT),
|
||||||
|
|
||||||
THERMOSTAT(FeatureArea.ENERGY, "NATherm1", 1, PLUG, Set.of(ChannelHelperCapability.class), ChannelGroup.SIGNAL,
|
THERMOSTAT(FeatureArea.ENERGY, "NATherm1", 1, "device", PLUG, Set.of(ChannelHelperCapability.class),
|
||||||
ChannelGroup.BATTERY_EXT, new ChannelGroup(Therm1ChannelHelper.class, GROUP_TYPE_TH_PROPERTIES)),
|
ChannelGroup.SIGNAL, ChannelGroup.BATTERY_EXT,
|
||||||
|
new ChannelGroup(Therm1ChannelHelper.class, GROUP_TYPE_TH_PROPERTIES)),
|
||||||
|
|
||||||
ROOM(FeatureArea.ENERGY, "NARoom", 1, HOME, Set.of(RoomCapability.class, ChannelHelperCapability.class),
|
ROOM(FeatureArea.ENERGY, "NARoom", 1, "virtual", HOME, Set.of(RoomCapability.class, ChannelHelperCapability.class),
|
||||||
new ChannelGroup(RoomChannelHelper.class, GROUP_TYPE_ROOM_PROPERTIES, GROUP_TYPE_ROOM_TEMPERATURE),
|
new ChannelGroup(RoomChannelHelper.class, GROUP_TYPE_ROOM_PROPERTIES, GROUP_TYPE_ROOM_TEMPERATURE),
|
||||||
new ChannelGroup(SetpointChannelHelper.class, GROUP_SETPOINT)),
|
new ChannelGroup(SetpointChannelHelper.class, GROUP_SETPOINT)),
|
||||||
|
|
||||||
SMOKE_DETECTOR(FeatureArea.SECURITY, "NSD", 1, HOME,
|
SMOKE_DETECTOR(FeatureArea.SECURITY, "NSD", 1, "device", HOME,
|
||||||
Set.of(AlarmEventCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL,
|
Set.of(AlarmEventCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL,
|
||||||
ChannelGroup.TIMESTAMP, ChannelGroup.ALARM_LAST_EVENT),
|
ChannelGroup.TIMESTAMP, ChannelGroup.ALARM_LAST_EVENT),
|
||||||
|
|
||||||
CO_DETECTOR(FeatureArea.SECURITY, "NCO", 1, HOME, Set.of(AlarmEventCapability.class, ChannelHelperCapability.class),
|
CO_DETECTOR(FeatureArea.SECURITY, "NCO", 1, "device", HOME,
|
||||||
ChannelGroup.SIGNAL, ChannelGroup.TIMESTAMP, ChannelGroup.ALARM_LAST_EVENT);
|
Set.of(AlarmEventCapability.class, ChannelHelperCapability.class), ChannelGroup.SIGNAL,
|
||||||
|
ChannelGroup.TIMESTAMP, ChannelGroup.ALARM_LAST_EVENT);
|
||||||
|
|
||||||
public static final EnumSet<ModuleType> AS_SET = EnumSet.allOf(ModuleType.class);
|
public static final EnumSet<ModuleType> AS_SET = EnumSet.allOf(ModuleType.class);
|
||||||
|
|
||||||
@ -160,8 +165,9 @@ public enum ModuleType {
|
|||||||
public final FeatureArea feature;
|
public final FeatureArea feature;
|
||||||
public final String apiName;
|
public final String apiName;
|
||||||
public final String thingTypeVersion;
|
public final String thingTypeVersion;
|
||||||
|
public final URI configDescription;
|
||||||
|
|
||||||
ModuleType(FeatureArea feature, String apiName, int thingTypeVersion, @Nullable ModuleType bridge,
|
ModuleType(FeatureArea feature, String apiName, int thingTypeVersion, String config, @Nullable ModuleType bridge,
|
||||||
Set<Class<? extends Capability>> capabilities, ChannelGroup... channelGroups) {
|
Set<Class<? extends Capability>> capabilities, ChannelGroup... channelGroups) {
|
||||||
this.bridgeType = Optional.ofNullable(bridge);
|
this.bridgeType = Optional.ofNullable(bridge);
|
||||||
this.feature = feature;
|
this.feature = feature;
|
||||||
@ -170,6 +176,7 @@ public enum ModuleType {
|
|||||||
this.channelGroups = Set.of(channelGroups);
|
this.channelGroups = Set.of(channelGroups);
|
||||||
this.thingTypeUID = new ThingTypeUID(BINDING_ID, name().toLowerCase().replace("_", "-"));
|
this.thingTypeUID = new ThingTypeUID(BINDING_ID, name().toLowerCase().replace("_", "-"));
|
||||||
this.thingTypeVersion = Integer.toString(thingTypeVersion);
|
this.thingTypeVersion = Integer.toString(thingTypeVersion);
|
||||||
|
this.configDescription = URI.create(BINDING_ID + ":" + config);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLogical() {
|
public boolean isLogical() {
|
||||||
@ -203,13 +210,6 @@ public enum ModuleType {
|
|||||||
return bridgeType.orElse(UNKNOWN);
|
return bridgeType.orElse(UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
public URI getConfigDescription() {
|
|
||||||
return URI.create(BINDING_ID + ":"
|
|
||||||
+ (equals(ACCOUNT) ? "api_bridge"
|
|
||||||
: equals(HOME) ? "home"
|
|
||||||
: (isLogical() ? "virtual" : UNKNOWN.equals(getBridge()) ? "configurable" : "device")));
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDepth() {
|
public int getDepth() {
|
||||||
ModuleType parent = getBridge();
|
ModuleType parent = getBridge();
|
||||||
return parent == UNKNOWN ? 1 : parent.getDepth() + 1;
|
return parent == UNKNOWN ? 1 : parent.getDepth() + 1;
|
||||||
|
@ -32,7 +32,6 @@ import org.openhab.binding.netatmo.internal.handler.capability.HomeCapability;
|
|||||||
import org.openhab.binding.netatmo.internal.handler.capability.ParentUpdateCapability;
|
import org.openhab.binding.netatmo.internal.handler.capability.ParentUpdateCapability;
|
||||||
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;
|
||||||
@ -69,6 +68,10 @@ public interface CommonInterface {
|
|||||||
|
|
||||||
void updateState(ChannelUID channelUID, State state);
|
void updateState(ChannelUID channelUID, State state);
|
||||||
|
|
||||||
|
default void updateState(String groupId, String id, State state) {
|
||||||
|
updateState(new ChannelUID(getThing().getUID(), groupId, id), state);
|
||||||
|
}
|
||||||
|
|
||||||
void setThingStatus(ThingStatus thingStatus, ThingStatusDetail thingStatusDetail,
|
void setThingStatus(ThingStatus thingStatus, ThingStatusDetail thingStatusDetail,
|
||||||
@Nullable String thingStatusReason);
|
@Nullable String thingStatusReason);
|
||||||
|
|
||||||
@ -108,11 +111,11 @@ public interface CommonInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
default String getId() {
|
default String getId() {
|
||||||
return getConfiguration().as(NAThingConfiguration.class).getId();
|
return getThingConfigAs(NAThingConfiguration.class).getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
default Configuration getConfiguration() {
|
default <T> T getThingConfigAs(Class<T> configurationClass) {
|
||||||
return getThing().getConfiguration();
|
return getThing().getConfiguration().as(configurationClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
default Stream<Channel> getActiveChannels() {
|
default Stream<Channel> getActiveChannels() {
|
||||||
|
@ -23,8 +23,7 @@ import org.openhab.binding.netatmo.internal.api.dto.WebhookEvent;
|
|||||||
import org.openhab.binding.netatmo.internal.handler.CommonInterface;
|
import org.openhab.binding.netatmo.internal.handler.CommonInterface;
|
||||||
import org.openhab.binding.netatmo.internal.handler.channelhelper.ChannelHelper;
|
import org.openhab.binding.netatmo.internal.handler.channelhelper.ChannelHelper;
|
||||||
import org.openhab.binding.netatmo.internal.providers.NetatmoDescriptionProvider;
|
import org.openhab.binding.netatmo.internal.providers.NetatmoDescriptionProvider;
|
||||||
import org.openhab.core.thing.ChannelUID;
|
import org.openhab.binding.netatmo.internal.utils.ChannelTypeUtils;
|
||||||
import org.openhab.core.thing.ThingUID;
|
|
||||||
import org.openhab.core.types.UnDefType;
|
import org.openhab.core.types.UnDefType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,15 +44,12 @@ public class AlarmEventCapability extends HomeSecurityThingCapability {
|
|||||||
protected void updateWebhookEvent(WebhookEvent event) {
|
protected void updateWebhookEvent(WebhookEvent event) {
|
||||||
super.updateWebhookEvent(event);
|
super.updateWebhookEvent(event);
|
||||||
|
|
||||||
final ThingUID thingUid = handler.getThing().getUID();
|
handler.updateState(GROUP_LAST_EVENT, CHANNEL_EVENT_TYPE, toStringType(event.getEventType()));
|
||||||
handler.updateState(new ChannelUID(thingUid, GROUP_LAST_EVENT, CHANNEL_EVENT_TYPE),
|
handler.updateState(GROUP_LAST_EVENT, CHANNEL_EVENT_TIME, toDateTimeType(event.getTime()));
|
||||||
toStringType(event.getEventType()));
|
handler.updateState(GROUP_LAST_EVENT, CHANNEL_EVENT_SUBTYPE,
|
||||||
handler.updateState(new ChannelUID(thingUid, GROUP_LAST_EVENT, CHANNEL_EVENT_TIME),
|
event.getSubTypeDescription().map(ChannelTypeUtils::toStringType).orElse(UnDefType.NULL));
|
||||||
toDateTimeType(event.getTime()));
|
|
||||||
handler.updateState(new ChannelUID(thingUid, GROUP_LAST_EVENT, CHANNEL_EVENT_SUBTYPE),
|
|
||||||
event.getSubTypeDescription().map(d -> toStringType(d)).orElse(UnDefType.NULL));
|
|
||||||
final String message = event.getName();
|
final String message = event.getName();
|
||||||
handler.updateState(new ChannelUID(thingUid, GROUP_LAST_EVENT, CHANNEL_EVENT_MESSAGE),
|
handler.updateState(GROUP_LAST_EVENT, CHANNEL_EVENT_MESSAGE,
|
||||||
message == null || message.isBlank() ? UnDefType.NULL : toStringType(message));
|
message == null || message.isBlank() ? UnDefType.NULL : toStringType(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,9 +15,13 @@ 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 static org.openhab.binding.netatmo.internal.utils.ChannelTypeUtils.*;
|
import static org.openhab.binding.netatmo.internal.utils.ChannelTypeUtils.*;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.UriBuilder;
|
||||||
|
import javax.ws.rs.core.UriBuilderException;
|
||||||
|
|
||||||
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.NetatmoConstants.AlimentationStatus;
|
import org.openhab.binding.netatmo.internal.api.data.NetatmoConstants.AlimentationStatus;
|
||||||
@ -32,14 +36,15 @@ import org.openhab.binding.netatmo.internal.handler.CommonInterface;
|
|||||||
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.providers.NetatmoDescriptionProvider;
|
import org.openhab.binding.netatmo.internal.providers.NetatmoDescriptionProvider;
|
||||||
|
import org.openhab.core.config.core.Configuration;
|
||||||
import org.openhab.core.library.types.OnOffType;
|
import org.openhab.core.library.types.OnOffType;
|
||||||
import org.openhab.core.thing.ChannelUID;
|
import org.openhab.core.thing.ChannelUID;
|
||||||
import org.openhab.core.thing.Thing;
|
|
||||||
import org.openhab.core.thing.ThingUID;
|
|
||||||
import org.openhab.core.types.Command;
|
import org.openhab.core.types.Command;
|
||||||
import org.openhab.core.types.State;
|
import org.openhab.core.types.State;
|
||||||
import org.openhab.core.types.StateOption;
|
import org.openhab.core.types.StateOption;
|
||||||
import org.openhab.core.types.UnDefType;
|
import org.openhab.core.types.UnDefType;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link CameraCapability} give to handle Welcome Camera specifics
|
* {@link CameraCapability} give to handle Welcome Camera specifics
|
||||||
@ -49,6 +54,10 @@ import org.openhab.core.types.UnDefType;
|
|||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class CameraCapability extends HomeSecurityThingCapability {
|
public class CameraCapability extends HomeSecurityThingCapability {
|
||||||
|
private static final String IP_ADDRESS = "ipAddress";
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(CameraCapability.class);
|
||||||
|
|
||||||
private final CameraChannelHelper cameraHelper;
|
private final CameraChannelHelper cameraHelper;
|
||||||
private final ChannelUID personChannelUID;
|
private final ChannelUID personChannelUID;
|
||||||
|
|
||||||
@ -60,7 +69,7 @@ public class CameraCapability extends HomeSecurityThingCapability {
|
|||||||
public CameraCapability(CommonInterface handler, NetatmoDescriptionProvider descriptionProvider,
|
public CameraCapability(CommonInterface handler, NetatmoDescriptionProvider descriptionProvider,
|
||||||
List<ChannelHelper> channelHelpers) {
|
List<ChannelHelper> channelHelpers) {
|
||||||
super(handler, descriptionProvider, channelHelpers);
|
super(handler, descriptionProvider, channelHelpers);
|
||||||
this.personChannelUID = new ChannelUID(thing.getUID(), GROUP_LAST_EVENT, CHANNEL_EVENT_PERSON_ID);
|
this.personChannelUID = new ChannelUID(thingUID, GROUP_LAST_EVENT, CHANNEL_EVENT_PERSON_ID);
|
||||||
this.cameraHelper = (CameraChannelHelper) channelHelpers.stream().filter(c -> c instanceof CameraChannelHelper)
|
this.cameraHelper = (CameraChannelHelper) channelHelpers.stream().filter(c -> c instanceof CameraChannelHelper)
|
||||||
.findFirst().orElseThrow(() -> new IllegalArgumentException(
|
.findFirst().orElseThrow(() -> new IllegalArgumentException(
|
||||||
"CameraCapability must find a CameraChannelHelper, please file a bug report."));
|
"CameraCapability must find a CameraChannelHelper, please file a bug report."));
|
||||||
@ -68,7 +77,6 @@ public class CameraCapability extends HomeSecurityThingCapability {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
Thing thing = handler.getThing();
|
|
||||||
hasSubEventGroup = !thing.getChannelsOfGroup(GROUP_SUB_EVENT).isEmpty();
|
hasSubEventGroup = !thing.getChannelsOfGroup(GROUP_SUB_EVENT).isEmpty();
|
||||||
hasLastEventGroup = !thing.getChannelsOfGroup(GROUP_LAST_EVENT).isEmpty();
|
hasLastEventGroup = !thing.getChannelsOfGroup(GROUP_LAST_EVENT).isEmpty();
|
||||||
}
|
}
|
||||||
@ -80,14 +88,15 @@ public class CameraCapability extends HomeSecurityThingCapability {
|
|||||||
String newVpnUrl = newData.getVpnUrl();
|
String newVpnUrl = newData.getVpnUrl();
|
||||||
if (newVpnUrl != null && !newVpnUrl.equals(vpnUrl)) {
|
if (newVpnUrl != null && !newVpnUrl.equals(vpnUrl)) {
|
||||||
// This will also decrease the number of requests emitted toward Netatmo API.
|
// This will also decrease the number of requests emitted toward Netatmo API.
|
||||||
localUrl = newData.isLocal() ? getSecurityCapability().map(cap -> cap.ping(newVpnUrl)).orElse(null) : null;
|
localUrl = newData.isLocal() ? ping(newVpnUrl) : null;
|
||||||
|
logger.debug("localUrl set to {} for camera {}", localUrl, thingUID);
|
||||||
cameraHelper.setUrls(newVpnUrl, localUrl);
|
cameraHelper.setUrls(newVpnUrl, localUrl);
|
||||||
eventHelper.setUrls(newVpnUrl, localUrl);
|
eventHelper.setUrls(newVpnUrl, localUrl);
|
||||||
}
|
}
|
||||||
vpnUrl = newVpnUrl;
|
vpnUrl = newVpnUrl;
|
||||||
if (!SdCardStatus.SD_CARD_WORKING.equals(newData.getSdStatus())
|
if (!SdCardStatus.SD_CARD_WORKING.equals(newData.getSdStatus())
|
||||||
|| !AlimentationStatus.ALIM_CORRECT_POWER.equals(newData.getAlimStatus())) {
|
|| !AlimentationStatus.ALIM_CORRECT_POWER.equals(newData.getAlimStatus())) {
|
||||||
statusReason = String.format("%s, %s", newData.getSdStatus(), newData.getAlimStatus());
|
statusReason = "%s, %s".formatted(newData.getSdStatus(), newData.getAlimStatus());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,11 +105,11 @@ public class CameraCapability extends HomeSecurityThingCapability {
|
|||||||
super.updateWebhookEvent(event);
|
super.updateWebhookEvent(event);
|
||||||
|
|
||||||
if (hasSubEventGroup) {
|
if (hasSubEventGroup) {
|
||||||
updateSubGroup(event, thing.getUID(), GROUP_SUB_EVENT);
|
updateSubGroup(event, GROUP_SUB_EVENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasLastEventGroup) {
|
if (hasLastEventGroup) {
|
||||||
updateSubGroup(event, thing.getUID(), GROUP_LAST_EVENT);
|
updateSubGroup(event, GROUP_LAST_EVENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The channel should get triggered at last (after super and sub methods), because this allows rules to access
|
// The channel should get triggered at last (after super and sub methods), because this allows rules to access
|
||||||
@ -111,19 +120,17 @@ public class CameraCapability extends HomeSecurityThingCapability {
|
|||||||
handler.triggerChannel(CHANNEL_HOME_EVENT, eventType);
|
handler.triggerChannel(CHANNEL_HOME_EVENT, eventType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateSubGroup(WebhookEvent event, ThingUID thingUid, String group) {
|
private void updateSubGroup(WebhookEvent event, String group) {
|
||||||
handler.updateState(new ChannelUID(thingUid, group, CHANNEL_EVENT_TYPE), toStringType(event.getEventType()));
|
handler.updateState(group, CHANNEL_EVENT_TYPE, toStringType(event.getEventType()));
|
||||||
handler.updateState(new ChannelUID(thingUid, group, CHANNEL_EVENT_TIME), toDateTimeType(event.getTime()));
|
handler.updateState(group, CHANNEL_EVENT_TIME, toDateTimeType(event.getTime()));
|
||||||
handler.updateState(new ChannelUID(thingUid, group, CHANNEL_EVENT_SNAPSHOT), toRawType(event.getSnapshotUrl()));
|
handler.updateState(group, CHANNEL_EVENT_SNAPSHOT, toRawType(event.getSnapshotUrl()));
|
||||||
handler.updateState(new ChannelUID(thingUid, group, CHANNEL_EVENT_SNAPSHOT_URL),
|
handler.updateState(group, CHANNEL_EVENT_SNAPSHOT_URL, toStringType(event.getSnapshotUrl()));
|
||||||
toStringType(event.getSnapshotUrl()));
|
handler.updateState(group, CHANNEL_EVENT_VIGNETTE, toRawType(event.getVignetteUrl()));
|
||||||
handler.updateState(new ChannelUID(thingUid, group, CHANNEL_EVENT_VIGNETTE), toRawType(event.getVignetteUrl()));
|
handler.updateState(group, CHANNEL_EVENT_VIGNETTE_URL, toStringType(event.getVignetteUrl()));
|
||||||
handler.updateState(new ChannelUID(thingUid, group, CHANNEL_EVENT_VIGNETTE_URL),
|
handler.updateState(group, CHANNEL_EVENT_SUBTYPE,
|
||||||
toStringType(event.getVignetteUrl()));
|
|
||||||
handler.updateState(new ChannelUID(thingUid, group, CHANNEL_EVENT_SUBTYPE),
|
|
||||||
event.getSubTypeDescription().map(d -> toStringType(d)).orElse(UnDefType.NULL));
|
event.getSubTypeDescription().map(d -> toStringType(d)).orElse(UnDefType.NULL));
|
||||||
final String message = event.getName();
|
final String message = event.getName();
|
||||||
handler.updateState(new ChannelUID(thingUid, group, CHANNEL_EVENT_MESSAGE),
|
handler.updateState(group, CHANNEL_EVENT_MESSAGE,
|
||||||
message == null || message.isBlank() ? UnDefType.NULL : toStringType(message));
|
message == null || message.isBlank() ? UnDefType.NULL : toStringType(message));
|
||||||
State personId = event.getPersons().isEmpty() ? UnDefType.NULL
|
State personId = event.getPersons().isEmpty() ? UnDefType.NULL
|
||||||
: toStringType(event.getPersons().values().iterator().next().getId());
|
: toStringType(event.getPersons().values().iterator().next().getId());
|
||||||
@ -161,4 +168,31 @@ public class CameraCapability extends HomeSecurityThingCapability {
|
|||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public @Nullable String ping(String vpnUrl) {
|
||||||
|
return getSecurityCapability().map(cap -> {
|
||||||
|
UriBuilder builder = UriBuilder.fromPath(cap.ping(vpnUrl));
|
||||||
|
URI apiLocalUrl = null;
|
||||||
|
try {
|
||||||
|
apiLocalUrl = builder.build();
|
||||||
|
if (apiLocalUrl.getHost().startsWith("169.254.")) {
|
||||||
|
logger.warn("Suspicious local IP address received: {}", apiLocalUrl);
|
||||||
|
Configuration config = handler.getThing().getConfiguration();
|
||||||
|
if (config.containsKey(IP_ADDRESS)) {
|
||||||
|
String provided = (String) config.get(IP_ADDRESS);
|
||||||
|
apiLocalUrl = builder.host(provided).build();
|
||||||
|
logger.info("Using {} as local url for '{}'", apiLocalUrl, thingUID);
|
||||||
|
} else {
|
||||||
|
logger.debug("No alternative ip Address provided, keeping API answer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (UriBuilderException e) { // Crashed at first URI build
|
||||||
|
logger.warn("API returned a badly formatted local url address for '{}': {}", thingUID, e.getMessage());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
logger.warn("Invalid fallback address provided in configuration for '{}' keeping API answer: {}",
|
||||||
|
thingUID, e.getMessage());
|
||||||
|
}
|
||||||
|
return apiLocalUrl != null ? apiLocalUrl.toString() : null;
|
||||||
|
}).orElse(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ import org.openhab.binding.netatmo.internal.api.dto.NAThing;
|
|||||||
import org.openhab.binding.netatmo.internal.api.dto.WebhookEvent;
|
import org.openhab.binding.netatmo.internal.api.dto.WebhookEvent;
|
||||||
import org.openhab.binding.netatmo.internal.handler.CommonInterface;
|
import org.openhab.binding.netatmo.internal.handler.CommonInterface;
|
||||||
import org.openhab.core.thing.Thing;
|
import org.openhab.core.thing.Thing;
|
||||||
|
import org.openhab.core.thing.ThingUID;
|
||||||
import org.openhab.core.thing.binding.ThingHandlerService;
|
import org.openhab.core.thing.binding.ThingHandlerService;
|
||||||
import org.openhab.core.types.Command;
|
import org.openhab.core.types.Command;
|
||||||
|
|
||||||
@ -50,6 +51,7 @@ public class Capability {
|
|||||||
protected final Thing thing;
|
protected final Thing thing;
|
||||||
protected final CommonInterface handler;
|
protected final CommonInterface handler;
|
||||||
protected final ModuleType moduleType;
|
protected final ModuleType moduleType;
|
||||||
|
protected final ThingUID thingUID;
|
||||||
|
|
||||||
protected boolean firstLaunch;
|
protected boolean firstLaunch;
|
||||||
protected Map<String, String> properties = Map.of();
|
protected Map<String, String> properties = Map.of();
|
||||||
@ -58,6 +60,7 @@ public class Capability {
|
|||||||
Capability(CommonInterface handler) {
|
Capability(CommonInterface handler) {
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
this.thing = handler.getThing();
|
this.thing = handler.getThing();
|
||||||
|
this.thingUID = thing.getUID();
|
||||||
this.moduleType = ModuleType.from(thing.getThingTypeUID());
|
this.moduleType = ModuleType.from(thing.getThingTypeUID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ public class EnergyCapability extends RestCapability<EnergyApi> {
|
|||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
super.initialize();
|
super.initialize();
|
||||||
energyId = handler.getConfiguration().as(HomeConfiguration.class).getIdForArea(FeatureArea.ENERGY);
|
energyId = handler.getThingConfigAs(HomeConfiguration.class).getIdForArea(FeatureArea.ENERGY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -77,7 +77,7 @@ public class EnergyCapability extends RestCapability<EnergyApi> {
|
|||||||
.forEach(bridgedModule -> childHandler.setNewData(bridgedModule));
|
.forEach(bridgedModule -> childHandler.setNewData(bridgedModule));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
descriptionProvider.setStateOptions(new ChannelUID(thing.getUID(), GROUP_ENERGY, CHANNEL_PLANNING),
|
descriptionProvider.setStateOptions(new ChannelUID(thingUID, GROUP_ENERGY, CHANNEL_PLANNING),
|
||||||
energyData.getThermSchedules().stream().map(p -> new StateOption(p.getId(), p.getName())).toList());
|
energyData.getThermSchedules().stream().map(p -> new StateOption(p.getId(), p.getName())).toList());
|
||||||
setPointDefaultDuration = energyData.getThermSetpointDefaultDuration();
|
setPointDefaultDuration = energyData.getThermSetpointDefaultDuration();
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ public class HomeCapability extends RestCapability<HomeApi> {
|
|||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
super.initialize();
|
super.initialize();
|
||||||
HomeConfiguration config = handler.getConfiguration().as(HomeConfiguration.class);
|
HomeConfiguration config = handler.getThingConfigAs(HomeConfiguration.class);
|
||||||
homeIds.add(config.getId());
|
homeIds.add(config.getId());
|
||||||
if (!config.energyId.isBlank()) {
|
if (!config.energyId.isBlank()) {
|
||||||
homeIds.add(config.energyId);
|
homeIds.add(config.energyId);
|
||||||
|
@ -34,7 +34,6 @@ import org.openhab.binding.netatmo.internal.handler.channelhelper.ChannelHelper;
|
|||||||
import org.openhab.binding.netatmo.internal.providers.NetatmoDescriptionProvider;
|
import org.openhab.binding.netatmo.internal.providers.NetatmoDescriptionProvider;
|
||||||
import org.openhab.core.library.types.OnOffType;
|
import org.openhab.core.library.types.OnOffType;
|
||||||
import org.openhab.core.thing.ChannelUID;
|
import org.openhab.core.thing.ChannelUID;
|
||||||
import org.openhab.core.thing.ThingUID;
|
|
||||||
import org.openhab.core.types.Command;
|
import org.openhab.core.types.Command;
|
||||||
import org.openhab.core.types.StateOption;
|
import org.openhab.core.types.StateOption;
|
||||||
import org.openhab.core.types.UnDefType;
|
import org.openhab.core.types.UnDefType;
|
||||||
@ -53,7 +52,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_LAST_EVENT, CHANNEL_EVENT_CAMERA_ID);
|
this.cameraChannelUID = new ChannelUID(thingUID, GROUP_PERSON_LAST_EVENT, CHANNEL_EVENT_CAMERA_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -78,21 +77,15 @@ public class PersonCapability extends HomeSecurityThingCapability {
|
|||||||
protected void updateWebhookEvent(WebhookEvent event) {
|
protected void updateWebhookEvent(WebhookEvent event) {
|
||||||
super.updateWebhookEvent(event);
|
super.updateWebhookEvent(event);
|
||||||
|
|
||||||
ThingUID thingUid = thing.getUID();
|
handler.updateState(GROUP_LAST_EVENT, CHANNEL_EVENT_SUBTYPE,
|
||||||
|
|
||||||
handler.updateState(new ChannelUID(thingUid, GROUP_LAST_EVENT, CHANNEL_EVENT_SUBTYPE),
|
|
||||||
event.getSubTypeDescription().map(d -> toStringType(d)).orElse(UnDefType.NULL));
|
event.getSubTypeDescription().map(d -> toStringType(d)).orElse(UnDefType.NULL));
|
||||||
|
|
||||||
final String message = event.getName();
|
final String message = event.getName();
|
||||||
handler.updateState(new ChannelUID(thingUid, GROUP_LAST_EVENT, CHANNEL_EVENT_MESSAGE),
|
handler.updateState(GROUP_LAST_EVENT, CHANNEL_EVENT_MESSAGE,
|
||||||
message == null || message.isBlank() ? UnDefType.NULL : toStringType(message));
|
message == null || message.isBlank() ? UnDefType.NULL : toStringType(message));
|
||||||
|
|
||||||
handler.updateState(new ChannelUID(thingUid, GROUP_LAST_EVENT, CHANNEL_EVENT_TIME),
|
handler.updateState(GROUP_LAST_EVENT, CHANNEL_EVENT_TIME, toDateTimeType(event.getTime()));
|
||||||
toDateTimeType(event.getTime()));
|
handler.updateState(GROUP_LAST_EVENT, CHANNEL_EVENT_SNAPSHOT, toRawType(event.getSnapshotUrl()));
|
||||||
|
|
||||||
handler.updateState(new ChannelUID(thingUid, GROUP_LAST_EVENT, CHANNEL_EVENT_SNAPSHOT),
|
|
||||||
toRawType(event.getSnapshotUrl()));
|
|
||||||
|
|
||||||
handler.updateState(cameraChannelUID, toStringType(event.getCameraId()));
|
handler.updateState(cameraChannelUID, toStringType(event.getCameraId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ 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);
|
securityId = handler.getThingConfigAs(HomeConfiguration.class).getIdForArea(FeatureArea.SECURITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -85,7 +85,7 @@ public class CameraChannelHelper extends ChannelHelper {
|
|||||||
if (!isMonitoring || (local && !isLocal) || url == null) {
|
if (!isMonitoring || (local && !isLocal) || url == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return String.format("%s%s", url, LIVE_PICTURE);
|
return "%s%s".formatted(url, LIVE_PICTURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private State getLiveStreamURL(boolean local, @Nullable String configQual, boolean isMonitoring) {
|
private State getLiveStreamURL(boolean local, @Nullable String configQual, boolean isMonitoring) {
|
||||||
@ -94,6 +94,6 @@ public class CameraChannelHelper extends ChannelHelper {
|
|||||||
return UnDefType.NULL;
|
return UnDefType.NULL;
|
||||||
}
|
}
|
||||||
String finalQual = configQual != null ? configQual : "poor";
|
String finalQual = configQual != null ? configQual : "poor";
|
||||||
return toStringType("%s/live/%s", url, local ? String.format("files/%s/index.m3u8", finalQual) : "index.m3u8");
|
return toStringType("%s/live/%s", url, local ? "files/%s/index.m3u8".formatted(finalQual) : "index.m3u8");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ public class NetatmoThingTypeProvider implements ThingTypeProvider {
|
|||||||
.withExtensibleChannelTypeIds(moduleType.getExtensions())
|
.withExtensibleChannelTypeIds(moduleType.getExtensions())
|
||||||
.withChannelGroupDefinitions(getGroupDefinitions(moduleType))
|
.withChannelGroupDefinitions(getGroupDefinitions(moduleType))
|
||||||
.withProperties(Map.of(PROPERTY_THING_TYPE_VERSION, moduleType.thingTypeVersion))
|
.withProperties(Map.of(PROPERTY_THING_TYPE_VERSION, moduleType.thingTypeVersion))
|
||||||
.withConfigDescriptionURI(moduleType.getConfigDescription());
|
.withConfigDescriptionURI(moduleType.configDescription);
|
||||||
|
|
||||||
ThingTypeUID bridgeType = moduleType.getBridge().thingTypeUID;
|
ThingTypeUID bridgeType = moduleType.getBridge().thingTypeUID;
|
||||||
if (!ModuleType.UNKNOWN.thingTypeUID.equals(bridgeType)) {
|
if (!ModuleType.UNKNOWN.thingTypeUID.equals(bridgeType)) {
|
||||||
|
@ -103,6 +103,18 @@
|
|||||||
</parameter>
|
</parameter>
|
||||||
</config-description>
|
</config-description>
|
||||||
|
|
||||||
|
<config-description uri="netatmo:camera">
|
||||||
|
<parameter name="id" type="text" pattern="([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})" required="true">
|
||||||
|
<label>@text/config.equipmentId.label</label>
|
||||||
|
<description>@text/config.equipmentId.description</description>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="ipAddress" type="text" required="false">
|
||||||
|
<label>@text/config.ipAddress.label</label>
|
||||||
|
<description>@text/config.ipAddress.description</description>
|
||||||
|
<context>network-address</context>
|
||||||
|
</parameter>
|
||||||
|
</config-description>
|
||||||
|
|
||||||
<config-description uri="netatmo:virtual">
|
<config-description uri="netatmo:virtual">
|
||||||
<parameter name="id" type="text" required="true">
|
<parameter name="id" type="text" required="true">
|
||||||
<label>@text/config.thingId.label</label>
|
<label>@text/config.thingId.label</label>
|
||||||
|
@ -444,6 +444,8 @@ config.reconnectInterval.label = Reconnect Interval
|
|||||||
config.reconnectInterval.description = The reconnection interval to Netatmo API (in s).
|
config.reconnectInterval.description = The reconnection interval to Netatmo API (in s).
|
||||||
config.equipmentId.label = Equipment ID
|
config.equipmentId.label = Equipment ID
|
||||||
config.equipmentId.description = ID of the device (MAC address).
|
config.equipmentId.description = ID of the device (MAC address).
|
||||||
|
config.ipAddress.label = Network Address
|
||||||
|
config.ipAddress.description = The IP or host name used as fallback in case of erroneous API answer to ping requests.
|
||||||
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.label = Security ID
|
||||||
|
Loading…
Reference in New Issue
Block a user