groupTypes.stream().map(NetatmoThingTypeProvider::toGroupName).collect(Collectors.toSet()));
} catch (ReflectiveOperationException e) {
throw new IllegalArgumentException(
- "Error creating or initializing helper class : %s".formatted(e.getMessage()));
+ "Error creating or initializing helper class: %s".formatted(e.getMessage()));
}
}
}
}
private record Snapshot(String url, ZonedDateTime expiresAt) {
+ // If the snapshot is expired we consider it as not available, so do not provide the url
+ public @Nullable String url() {
+ return expiresAt.isAfter(ZonedDateTime.now().withZoneSameInstant(expiresAt.getZone())) ? url : null;
+ }
}
private ZonedDateTime time = ZonedDateTime.now();
import java.util.Deque;
import java.util.HashMap;
import java.util.Map;
-import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutionException;
updateStatus(ThingStatus.ONLINE);
- getThing().getThings().stream().filter(Thing::isEnabled).map(Thing::getHandler).filter(Objects::nonNull)
- .map(CommonInterface.class::cast).forEach(CommonInterface::expireData);
+ getThing().getThings().stream().filter(Thing::isEnabled).map(Thing::getHandler)
+ .filter(CommonInterface.class::isInstance).map(CommonInterface.class::cast)
+ .forEach(CommonInterface::expireData);
}
private boolean authenticate(@Nullable String code, @Nullable String redirectUri) {
throw exception;
} catch (NetatmoException e) {
if (e.getStatusCode() == ServiceError.MAXIMUM_USAGE_REACHED) {
- updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "@text/maximum-usage-reached");
prepareReconnection(null, null);
}
throw e;
import org.openhab.binding.netatmo.internal.handler.channelhelper.CameraChannelHelper;
import org.openhab.binding.netatmo.internal.handler.channelhelper.ChannelHelper;
import org.openhab.binding.netatmo.internal.providers.NetatmoDescriptionProvider;
+import org.openhab.binding.netatmo.internal.utils.ChannelTypeUtils;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.thing.ChannelUID;
eventHelper.setUrls(newVpnUrl, localUrl);
}
vpnUrl = newVpnUrl;
- if (!SdCardStatus.SD_CARD_WORKING.equals(newData.getSdStatus())
- || !AlimentationStatus.ALIM_CORRECT_POWER.equals(newData.getAlimStatus())) {
- statusReason = "%s, %s".formatted(newData.getSdStatus(), newData.getAlimStatus());
+ if (!SdCardStatus.SD_CARD_WORKING.equals(newData.getSdStatus())) {
+ statusReason = newData.getSdStatus().toString();
+ }
+ if (!AlimentationStatus.ALIM_CORRECT_POWER.equals(newData.getAlimStatus())) {
+ statusReason = newData.getAlimStatus().toString();
}
}
private void updateSubGroup(WebhookEvent event, String group) {
handler.updateState(group, CHANNEL_EVENT_TYPE, toStringType(event.getEventType()));
handler.updateState(group, CHANNEL_EVENT_TIME, toDateTimeType(event.getTime()));
- handler.updateState(group, CHANNEL_EVENT_SNAPSHOT, toRawType(event.getSnapshotUrl()));
- handler.updateState(group, CHANNEL_EVENT_SNAPSHOT_URL, toStringType(event.getSnapshotUrl()));
- handler.updateState(group, CHANNEL_EVENT_VIGNETTE, toRawType(event.getVignetteUrl()));
- handler.updateState(group, CHANNEL_EVENT_VIGNETTE_URL, toStringType(event.getVignetteUrl()));
- handler.updateState(group, CHANNEL_EVENT_SUBTYPE,
- Objects.requireNonNull(event.getSubTypeDescription().map(d -> toStringType(d)).orElse(UnDefType.NULL)));
+ updatePictureIfUrlPresent(event.getSnapshotUrl(), group, CHANNEL_EVENT_SNAPSHOT, CHANNEL_EVENT_SNAPSHOT_URL);
+ updatePictureIfUrlPresent(event.getVignetteUrl(), group, CHANNEL_EVENT_VIGNETTE, CHANNEL_EVENT_VIGNETTE_URL);
+ handler.updateState(group, CHANNEL_EVENT_SUBTYPE, Objects.requireNonNull(
+ event.getSubTypeDescription().map(ChannelTypeUtils::toStringType).orElse(UnDefType.NULL)));
final String message = event.getName();
handler.updateState(group, CHANNEL_EVENT_MESSAGE,
message == null || message.isBlank() ? UnDefType.NULL : toStringType(message));
handler.updateState(personChannelUID, personId);
}
+ private void updatePictureIfUrlPresent(@Nullable String snapShotUrl, String group, String pictureChannel,
+ String urlChannel) {
+ if (snapShotUrl != null) {
+ handler.updateState(group, pictureChannel, toRawType(snapShotUrl));
+ handler.updateState(group, urlChannel, toStringType(snapShotUrl));
+ }
+ }
+
@Override
public void handleCommand(String channelName, Command command) {
if (command instanceof OnOffType && CHANNEL_MONITORING.equals(channelName)) {
import org.openhab.binding.netatmo.internal.handler.CommonInterface;
import org.openhab.binding.netatmo.internal.handler.channelhelper.ChannelHelper;
import org.openhab.binding.netatmo.internal.providers.NetatmoDescriptionProvider;
+import org.openhab.binding.netatmo.internal.utils.ChannelTypeUtils;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.types.Command;
protected void updateWebhookEvent(WebhookEvent event) {
super.updateWebhookEvent(event);
- handler.updateState(GROUP_LAST_EVENT, CHANNEL_EVENT_SUBTYPE,
- Objects.requireNonNull(event.getSubTypeDescription().map(d -> toStringType(d)).orElse(UnDefType.NULL)));
+ handler.updateState(GROUP_LAST_EVENT, CHANNEL_EVENT_SUBTYPE, Objects.requireNonNull(
+ event.getSubTypeDescription().map(ChannelTypeUtils::toStringType).orElse(UnDefType.NULL)));
final String message = event.getName();
handler.updateState(GROUP_LAST_EVENT, CHANNEL_EVENT_MESSAGE,
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 static org.openhab.binding.netatmo.internal.utils.ChannelTypeUtils.toStringType;
import java.util.Set;
case CHANNEL_EVENT_TYPE -> toStringType(event.getEventType());
case CHANNEL_EVENT_TIME -> new DateTimeType(event.getTime());
case CHANNEL_EVENT_MESSAGE -> toStringType(event.getName());
- case CHANNEL_EVENT_SNAPSHOT -> toRawType(event.getSnapshotUrl());
- case CHANNEL_EVENT_SNAPSHOT_URL -> toStringType(event.getSnapshotUrl());
- case CHANNEL_EVENT_VIGNETTE -> toRawType(event.getVignetteUrl());
- case CHANNEL_EVENT_VIGNETTE_URL -> toStringType(event.getVignetteUrl());
+ case CHANNEL_EVENT_SNAPSHOT -> checkUrlPresence(event.getSnapshotUrl(), true);
+ case CHANNEL_EVENT_SNAPSHOT_URL -> checkUrlPresence(event.getSnapshotUrl(), false);
+ case CHANNEL_EVENT_VIGNETTE -> checkUrlPresence(event.getVignetteUrl(), true);
+ case CHANNEL_EVENT_VIGNETTE_URL -> checkUrlPresence(event.getVignetteUrl(), false);
default -> super.internalGetHomeEvent(channelId, groupId, event);
};
}
case CHANNEL_EVENT_CAMERA_ID -> toStringType(event.getCameraId());
case CHANNEL_EVENT_SUBTYPE ->
event.getSubTypeDescription().map(ChannelTypeUtils::toStringType).orElse(UnDefType.NULL);
- case CHANNEL_EVENT_SNAPSHOT -> toRawType(event.getSnapshotUrl());
- case CHANNEL_EVENT_SNAPSHOT_URL -> toStringType(event.getSnapshotUrl());
+ case CHANNEL_EVENT_SNAPSHOT -> checkUrlPresence(event.getSnapshotUrl(), true);
+ case CHANNEL_EVENT_SNAPSHOT_URL -> checkUrlPresence(event.getSnapshotUrl(), false);
default -> null;
};
}
+ protected @Nullable State checkUrlPresence(@Nullable String url, boolean asRaw) {
+ return url != null ? asRaw ? toRawType(url) : toStringType(url) : null;
+ }
+
@Override
protected @Nullable State internalGetHomeEvent(String channelId, @Nullable String groupId, HomeEvent event) {
+ String videoId = event.getVideoId();
+ if (videoId == null) {
+ return null;
+ }
return switch (channelId) {
- case CHANNEL_EVENT_VIDEO_STATUS ->
- event.getVideoId() != null ? toStringType(event.getVideoStatus()) : UnDefType.NULL;
+ case CHANNEL_EVENT_VIDEO_STATUS -> toStringType(event.getVideoStatus());
case CHANNEL_EVENT_VIDEO_LOCAL_URL -> getStreamURL(true, event.getVideoId(), event.getVideoStatus());
case CHANNEL_EVENT_VIDEO_VPN_URL -> getStreamURL(false, event.getVideoId(), event.getVideoStatus());
default -> null;
data-over-limit = Data seems quite old
request-time-out = Request timed out - will attempt reconnection later
deserialization-unknown = Deserialization lead to an unknown code
+maximum-usage-reached = Maximum usage reached. Will try reconnection after `reconnectInterval` seconds.
homestatus-unknown-error = Unknown error
homestatus-internal-error = Internal error