-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
[unifiprotect] Unifi Protect Binding Initial Contribution #19411
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 11 commits
0772272
65d6aff
99f33f5
1488105
3b865aa
3900b75
94df107
0b42526
5d1146c
927cc2f
e902eee
69d5ebe
e7f9678
a5002ee
d7c6fe5
1e50d7e
8cf0d62
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| This content is produced and maintained by the openHAB project. | ||
|
|
||
| * Project home: https://www.openhab.org | ||
|
|
||
| == Declared Project Licenses | ||
|
|
||
| This program and the accompanying materials are made available under the terms | ||
| of the Eclipse Public License 2.0 which is available at | ||
| https://www.eclipse.org/legal/epl-2.0/. | ||
|
|
||
| == Source Code | ||
|
|
||
| https://github.com/openhab/openhab-addons |
Large diffs are not rendered by default.
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this file |
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think the image can have a better quality with a lower size. If you need help, please paste me the original high res screenshots. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
|
|
||
| <modelVersion>4.0.0</modelVersion> | ||
|
|
||
| <parent> | ||
| <groupId>org.openhab.addons.bundles</groupId> | ||
| <artifactId>org.openhab.addons.reactor.bundles</artifactId> | ||
| <version>5.1.0-SNAPSHOT</version> | ||
| </parent> | ||
|
|
||
| <artifactId>org.openhab.binding.unifiprotect</artifactId> | ||
|
|
||
| <name>openHAB Add-ons :: Bundles :: UnifiProtect Binding</name> | ||
|
|
||
| </project> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <features name="org.openhab.binding.unifiprotect-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0"> | ||
| <repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository> | ||
|
|
||
| <feature name="openhab-binding-unifiprotect" description="Unifi Protect Binding" version="${project.version}"> | ||
| <feature>openhab-runtime-base</feature> | ||
| <bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.unifiprotect/${project.version}</bundle> | ||
| </feature> | ||
| </features> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,159 @@ | ||
| /* | ||
| * Copyright (c) 2010-2025 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.unifiprotect.internal; | ||
|
|
||
| import org.eclipse.jdt.annotation.NonNullByDefault; | ||
| import org.openhab.core.thing.ThingTypeUID; | ||
|
|
||
| /** | ||
| * The {@link UnifiProtectBindingConstants} class defines common constants, which are | ||
| * used across the whole binding. | ||
| * | ||
| * @author Dan Cunningham - Initial contribution | ||
| */ | ||
| @NonNullByDefault | ||
| public class UnifiProtectBindingConstants { | ||
|
|
||
| public static final String BINDING_ID = "unifiprotect"; | ||
| public static final String SERVICE_ID = "org.openhab." + BINDING_ID; | ||
|
|
||
| // List of all Thing Type UIDs | ||
| public static final ThingTypeUID THING_TYPE_NVR = new ThingTypeUID(BINDING_ID, "nvr"); | ||
| public static final ThingTypeUID THING_TYPE_CAMERA = new ThingTypeUID(BINDING_ID, "camera"); | ||
| public static final ThingTypeUID THING_TYPE_LIGHT = new ThingTypeUID(BINDING_ID, "light"); | ||
| public static final ThingTypeUID THING_TYPE_SENSOR = new ThingTypeUID(BINDING_ID, "sensor"); | ||
|
|
||
| // List of all Configuration ids | ||
| public static final String DEVICE_ID = "deviceId"; | ||
| public static final String SNAPSHOT_SEQUENCE = "sequence"; | ||
|
|
||
| // List of all Property ids | ||
| public static final String PROPERTY_WEBRTC_URL = "webrtc-url"; // also used as base url for all webrtc urls | ||
| public static final String PROPERTY_SNAPSHOT_URL = "snapshot-url"; | ||
|
|
||
| // List of all Channel ids | ||
|
|
||
| // Shared | ||
| public static final String CHANNEL_STATUS = "status"; | ||
|
|
||
| // Camera | ||
| public static final String CHANNEL_SNAPSHOT = "snapshot"; | ||
| public static final String CHANNEL_SNAPSHOT_LABEL = "Snapshot"; | ||
| public static final String CHANNEL_SNAPSHOT_URL = "snapshot-url"; | ||
| public static final String CHANNEL_SNAPSHOT_URL_LABEL = "Snapshot URL"; | ||
| public static final String CHANNEL_MIC_VOLUME = "mic-volume"; | ||
| public static final String CHANNEL_VIDEO_MODE = "video-mode"; | ||
| public static final String CHANNEL_HDR_TYPE = "hdr-type"; | ||
| public static final String CHANNEL_OSD_NAME = "osd-name"; | ||
| public static final String CHANNEL_OSD_DATE = "osd-date"; | ||
| public static final String CHANNEL_OSD_LOGO = "osd-logo"; | ||
| public static final String CHANNEL_LED_ENABLED = "led-enabled"; | ||
| public static final String CHANNEL_ACTIVE_PATROL_SLOT = "active-patrol-slot"; | ||
| public static final String CHANNEL_RTSP_URL_HIGH = "rtsp-url-high"; | ||
| public static final String CHANNEL_RTSP_URL_HIGH_LABEL = "RTSP URL High"; | ||
| public static final String CHANNEL_RTSP_URL_MEDIUM = "rtsp-url-medium"; | ||
| public static final String CHANNEL_RTSP_URL_MEDIUM_LABEL = "RTSP URL Medium"; | ||
| public static final String CHANNEL_RTSP_URL_LOW = "rtsp-url-low"; | ||
| public static final String CHANNEL_RTSP_URL_LOW_LABEL = "RTSP URL Low"; | ||
| public static final String CHANNEL_RTSP_URL_PACKAGE = "rtsp-url-package"; | ||
| public static final String CHANNEL_RTSP_URL_PACKAGE_LABEL = "RTSP URL Package"; | ||
| public static final String CHANNEL_RTSP_URL = "rtsp-url"; | ||
| public static final String CHANNEL_WEBRTC_URL = "webrtc-url"; | ||
| public static final String CHANNEL_WEBRTC_URL_HIGH = "webrtc-url-high"; | ||
| public static final String CHANNEL_WEBRTC_URL_HIGH_LABEL = "WebRTC URL High Quality"; | ||
| public static final String CHANNEL_WEBRTC_URL_MEDIUM = "webrtc-url-medium"; | ||
| public static final String CHANNEL_WEBRTC_URL_MEDIUM_LABEL = "WebRTC URL Medium Quality"; | ||
| public static final String CHANNEL_WEBRTC_URL_LOW = "webrtc-url-low"; | ||
| public static final String CHANNEL_WEBRTC_URL_LOW_LABEL = "WebRTC URL Low Quality"; | ||
| public static final String CHANNEL_WEBRTC_URL_PACKAGE = "webrtc-url-package"; | ||
| public static final String CHANNEL_WEBRTC_URL_PACKAGE_LABEL = "WebRTC URL Package Quality"; | ||
| // Triggers and Contacts | ||
| public static final String CHANNEL_MOTION = "motion"; | ||
| public static final String CHANNEL_MOTION_START = "motion-start"; | ||
| public static final String CHANNEL_MOTION_START_LABEL = "Motion Start"; | ||
| public static final String CHANNEL_MOTION_UPDATE = "motion-update"; | ||
| public static final String CHANNEL_MOTION_UPDATE_LABEL = "Motion Update"; | ||
| public static final String CHANNEL_MOTION_CONTACT = "motion-contact"; | ||
| public static final String CHANNEL_MOTION_SNAPSHOT = "motion-snapshot"; | ||
| public static final String CHANNEL_MOTION_SNAPSHOT_LABEL = "Motion Snapshot"; | ||
|
|
||
| public static final String CHANNEL_SMART_DETECT_AUDIO = "smart-detect-audio"; | ||
| public static final String CHANNEL_SMART_DETECT_AUDIO_START = "smart-detect-audio-start"; | ||
| public static final String CHANNEL_SMART_DETECT_AUDIO_START_LABEL = "Smart Detect Audio Start"; | ||
| public static final String CHANNEL_SMART_DETECT_AUDIO_UPDATE = "smart-detect-audio-update"; | ||
| public static final String CHANNEL_SMART_DETECT_AUDIO_UPDATE_LABEL = "Smart Detect Audio Update"; | ||
| public static final String CHANNEL_SMART_DETECT_AUDIO_CONTACT = "smart-detect-audio-contact"; | ||
| public static final String CHANNEL_SMART_DETECT_AUDIO_SNAPSHOT = "smart-detect-audio-snapshot"; | ||
| public static final String CHANNEL_SMART_DETECT_AUDIO_SNAPSHOT_LABEL = "Smart Detect Audio Snapshot"; | ||
|
|
||
| public static final String CHANNEL_SMART_DETECT_ZONE = "smart-detect-zone"; | ||
| public static final String CHANNEL_SMART_DETECT_ZONE_START = "smart-detect-zone-start"; | ||
| public static final String CHANNEL_SMART_DETECT_ZONE_START_LABEL = "Smart Detect Zone Start"; | ||
| public static final String CHANNEL_SMART_DETECT_ZONE_UPDATE = "smart-detect-zone-update"; | ||
| public static final String CHANNEL_SMART_DETECT_ZONE_UPDATE_LABEL = "Smart Detect Zone Update"; | ||
| public static final String CHANNEL_SMART_DETECT_ZONE_CONTACT = "smart-detect-zone-contact"; | ||
| public static final String CHANNEL_SMART_DETECT_ZONE_SNAPSHOT = "smart-detect-zone-snapshot"; | ||
| public static final String CHANNEL_SMART_DETECT_ZONE_SNAPSHOT_LABEL = "Smart Detect Zone Snapshot"; | ||
|
|
||
| public static final String CHANNEL_SMART_DETECT_LINE = "smart-detect-line"; | ||
| public static final String CHANNEL_SMART_DETECT_LINE_START = "smart-detect-line-start"; | ||
| public static final String CHANNEL_SMART_DETECT_LINE_START_LABEL = "Smart Detect Line Start"; | ||
| public static final String CHANNEL_SMART_DETECT_LINE_UPDATE = "smart-detect-line-update"; | ||
| public static final String CHANNEL_SMART_DETECT_LINE_UPDATE_LABEL = "Smart Detect Line Update"; | ||
| public static final String CHANNEL_SMART_DETECT_LINE_CONTACT = "smart-detect-line-contact"; | ||
| public static final String CHANNEL_SMART_DETECT_LINE_SNAPSHOT = "smart-detect-line-snapshot"; | ||
| public static final String CHANNEL_SMART_DETECT_LINE_SNAPSHOT_LABEL = "Smart Detect Line Snapshot"; | ||
|
|
||
| public static final String CHANNEL_SMART_DETECT_LOITER = "smart-detect-loiter"; | ||
| public static final String CHANNEL_SMART_DETECT_LOITER_START = "smart-detect-loiter-start"; | ||
| public static final String CHANNEL_SMART_DETECT_LOITER_START_LABEL = "Smart Detect Loiter Start"; | ||
| public static final String CHANNEL_SMART_DETECT_LOITER_UPDATE = "smart-detect-loiter-update"; | ||
| public static final String CHANNEL_SMART_DETECT_LOITER_UPDATE_LABEL = "Smart Detect Loiter Update"; | ||
| public static final String CHANNEL_SMART_DETECT_LOITER_CONTACT = "smart-detect-loiter-contact"; | ||
| public static final String CHANNEL_SMART_DETECT_LOITER_SNAPSHOT = "smart-detect-loiter-snapshot"; | ||
| public static final String CHANNEL_SMART_DETECT_LOITER_SNAPSHOT_LABEL = "Smart Detect Loiter Snapshot"; | ||
|
|
||
| public static final String CHANNEL_RING = "ring"; | ||
| public static final String CHANNEL_RING_LABEL = "Ring"; | ||
| public static final String CHANNEL_RING_CONTACT = "ring-contact"; | ||
| public static final String CHANNEL_RING_SNAPSHOT = "ring-snapshot"; | ||
| public static final String CHANNEL_RING_SNAPSHOT_LABEL = "Ring Snapshot"; | ||
|
|
||
| // Light (floodlight) | ||
| public static final String CHANNEL_LIGHT = "light"; | ||
| public static final String CHANNEL_IS_DARK = "is-dark"; | ||
| public static final String CHANNEL_PIR_MOTION = "pir-motion"; | ||
| public static final String CHANNEL_LAST_MOTION = "last-motion"; | ||
| public static final String CHANNEL_LIGHT_MODE = "light-mode"; | ||
| public static final String CHANNEL_ENABLE_AT = "enable-at"; | ||
| public static final String CHANNEL_INDICATOR_ENABLED = "indicator-enabled"; | ||
| public static final String CHANNEL_PIR_DURATION = "pir-duration"; | ||
| public static final String CHANNEL_PIR_SENSITIVITY = "pir-sensitivity"; | ||
| public static final String CHANNEL_LED_LEVEL = "led-level"; | ||
|
|
||
| // Sensor | ||
| public static final String CHANNEL_BATTERY = "battery"; | ||
| public static final String CHANNEL_CONTACT = "contact"; | ||
| public static final String CHANNEL_TEMPERATURE = "temperature"; | ||
| public static final String CHANNEL_HUMIDITY = "humidity"; | ||
| public static final String CHANNEL_ILLUMINANCE = "illuminance"; | ||
| public static final String CHANNEL_SENSOR_MOTION = "motion"; | ||
| public static final String CHANNEL_ALARM_CONTACT = "alarm-contact"; | ||
| public static final String CHANNEL_ALARM = "alarm"; | ||
| public static final String CHANNEL_WATER_LEAK_CONTACT = "water-leak-contact"; | ||
| public static final String CHANNEL_WATER_LEAK = "water-leak"; | ||
| public static final String CHANNEL_TAMPER_CONTACT = "tamper-contact"; | ||
| public static final String CHANNEL_TAMPER = "tamper"; | ||
| public static final String CHANNEL_OPENED = "opened"; | ||
| public static final String CHANNEL_CLOSED = "closed"; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,135 @@ | ||
| /* | ||
| * Copyright (c) 2010-2025 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.unifiprotect.internal; | ||
|
|
||
| import java.io.IOException; | ||
| import java.util.Map; | ||
| import java.util.Set; | ||
|
|
||
| import org.eclipse.jdt.annotation.NonNullByDefault; | ||
| import org.openhab.binding.unifiprotect.internal.api.UniFiProtectApiClient; | ||
| import org.openhab.binding.unifiprotect.internal.api.dto.Camera; | ||
| import org.openhab.binding.unifiprotect.internal.api.dto.Light; | ||
| import org.openhab.binding.unifiprotect.internal.api.dto.Sensor; | ||
| import org.openhab.binding.unifiprotect.internal.handler.UnifiProtectNVRHandler; | ||
| import org.openhab.core.config.discovery.AbstractThingHandlerDiscoveryService; | ||
| import org.openhab.core.config.discovery.DiscoveryResult; | ||
| import org.openhab.core.config.discovery.DiscoveryResultBuilder; | ||
| import org.openhab.core.thing.ThingUID; | ||
| import org.openhab.core.thing.binding.ThingHandler; | ||
| import org.osgi.service.component.annotations.Component; | ||
| import org.osgi.service.component.annotations.ServiceScope; | ||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
|
|
||
| /** | ||
| * Discovery service for UniFi Access Door things. | ||
| * | ||
| * @author Dan Cunningham - Initial contribution | ||
| */ | ||
| @Component(scope = ServiceScope.PROTOTYPE, service = UnifiProtectDiscoveryService.class) | ||
| @NonNullByDefault | ||
| public class UnifiProtectDiscoveryService extends AbstractThingHandlerDiscoveryService<UnifiProtectNVRHandler> { | ||
|
|
||
| private final Logger logger = LoggerFactory.getLogger(UnifiProtectDiscoveryService.class); | ||
|
|
||
| public UnifiProtectDiscoveryService() { | ||
| super(UnifiProtectNVRHandler.class, Set.of(UnifiProtectBindingConstants.THING_TYPE_CAMERA, | ||
| UnifiProtectBindingConstants.THING_TYPE_LIGHT, UnifiProtectBindingConstants.THING_TYPE_SENSOR), 30, | ||
| false); | ||
| } | ||
|
|
||
| @Override | ||
| public void setThingHandler(ThingHandler handler) { | ||
| logger.debug("setThingHandler {}", handler); | ||
| if (handler instanceof UnifiProtectNVRHandler childDiscoveryHandler) { | ||
| childDiscoveryHandler.setDiscoveryService(this); | ||
| this.thingHandler = childDiscoveryHandler; | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| protected void startScan() { | ||
| removeOlderResults(getTimestampOfLastScan()); | ||
| final UniFiProtectApiClient client = thingHandler.getApiClient(); | ||
| if (client == null) { | ||
| return; | ||
| } | ||
| discoverCameras(client); | ||
| discoverLights(client); | ||
| discoverSensors(client); | ||
| } | ||
|
|
||
| public void discoverCameras(UniFiProtectApiClient client) { | ||
| try { | ||
| for (Camera c : client.listCameras()) { | ||
| discoverCamera(c); | ||
| } | ||
| } catch (IOException e) { | ||
| logger.trace("Camera discovery failed", e); | ||
| } | ||
| } | ||
|
|
||
| public void discoverLights(UniFiProtectApiClient client) { | ||
| try { | ||
| for (Light l : client.listLights()) { | ||
| discoverLight(l); | ||
| } | ||
| } catch (IOException e) { | ||
| logger.trace("Light discovery failed", e); | ||
| } | ||
| } | ||
|
|
||
| public void discoverSensors(UniFiProtectApiClient client) { | ||
| try { | ||
| for (Sensor s : client.listSensors()) { | ||
| discoverSensor(s); | ||
| } | ||
| } catch (IOException e) { | ||
| logger.trace("Light discovery failed", e); | ||
| } | ||
| } | ||
|
|
||
| public void discoverCamera(Camera c) { | ||
| ThingUID uid = new ThingUID(UnifiProtectBindingConstants.THING_TYPE_CAMERA, thingHandler.getThing().getUID(), | ||
| c.id); | ||
| Map<String, Object> props = Map.of(UnifiProtectBindingConstants.DEVICE_ID, c.id); | ||
| DiscoveryResult result = DiscoveryResultBuilder.create(uid).withBridge(thingHandler.getThing().getUID()) | ||
| .withThingType(UnifiProtectBindingConstants.THING_TYPE_CAMERA).withProperties(props) | ||
| .withRepresentationProperty(UnifiProtectBindingConstants.DEVICE_ID) | ||
| .withLabel("UniFi Protect Camera: " + c.name).build(); | ||
| thingDiscovered(result); | ||
| } | ||
|
|
||
| public void discoverLight(Light l) { | ||
| ThingUID uid = new ThingUID(UnifiProtectBindingConstants.THING_TYPE_LIGHT, thingHandler.getThing().getUID(), | ||
| l.id); | ||
| Map<String, Object> props = Map.of(UnifiProtectBindingConstants.DEVICE_ID, l.id); | ||
| DiscoveryResult result = DiscoveryResultBuilder.create(uid).withBridge(thingHandler.getThing().getUID()) | ||
| .withThingType(UnifiProtectBindingConstants.THING_TYPE_LIGHT).withProperties(props) | ||
| .withRepresentationProperty(UnifiProtectBindingConstants.DEVICE_ID) | ||
| .withLabel("UniFi Protect Light: " + l.name).build(); | ||
| thingDiscovered(result); | ||
| } | ||
|
|
||
| public void discoverSensor(Sensor s) { | ||
| ThingUID uid = new ThingUID(UnifiProtectBindingConstants.THING_TYPE_SENSOR, thingHandler.getThing().getUID(), | ||
| s.id); | ||
| Map<String, Object> props = Map.of(UnifiProtectBindingConstants.DEVICE_ID, s.id); | ||
| DiscoveryResult result = DiscoveryResultBuilder.create(uid).withBridge(thingHandler.getThing().getUID()) | ||
| .withThingType(UnifiProtectBindingConstants.THING_TYPE_SENSOR).withProperties(props) | ||
| .withRepresentationProperty(UnifiProtectBindingConstants.DEVICE_ID) | ||
| .withLabel("UniFi Protect Sensor: " + s.name).build(); | ||
| thingDiscovered(result); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be my eyes, but i can;t see anything on this screenshot, while i think it is helpfull. While doing so i think the filesize can be reduced.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry i don't understand, is the image not rendering for you? I just checked on my repo, and its rendering and shows where to generate a key
Is there a resize tool (like imagemagick, gimp, photoshop, etc...) and options you typically use? would be happy to run my screenshots through that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant to say that the quality is low and i hardly can read it. dark blue, grey and dark green colors on a black background.
Most of the times i use irfanview, but many tools can do this. low bit PNG with decent resolution.