Sno Station
Sno Station is your agents' workstation: open-source software that turns the AI agents you already run into one squad on your own machine. Two heads are better than one, and they get better with every
DirectorLink · UniFi Protect for Control4: free, open-source drivers for UniFi Protect cameras and doorbells. Every camera added at once, live video, smart detections, doorbell rings and alerts with a
PluginsLua · PythonGitHub @DirectorLinkOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
DirectorLink · UniFi Protect for Control4: free, open-source driver for UniFi Protect cameras and doorbells.
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Free, open-source Control4 driver for UniFi Protect cameras and doorbells. Part of DirectorLink Drivers.
It works on your local network: the drivers talk straight to your UniFi console with Ubiquiti's official Protect Integration API, with no cloud, no extra hardware and no subscription.
Free. No subscription, no license key, no account with us.
Made by DirectorLink, the open-source management layer for Control4 homes. Works on its own: DirectorLink is not required.
DirectorLink is an independent project, not affiliated with Control4 or Snap One.Read the full README ↗Free, open-source Control4 driver for UniFi Protect cameras and doorbells. Part of DirectorLink Drivers.
It works on your local network: the drivers talk straight to your UniFi console with Ubiquiti's official Protect Integration API, with no cloud, no extra hardware and no subscription.
Free. No subscription, no license key, no account with us.
Made by DirectorLink, the open-source management layer for Control4 homes. Works on its own: DirectorLink is not required.
DirectorLink is an independent project, not affiliated with Control4 or Snap One.
Download: latest release · Help and updates: directorlink.io/drivers/unifi-protect
Field reports wanted. The drivers follow Ubiquiti's published API exactly and pass their tests against recorded API answers, but no installer has reported on them from a real UniFi system yet. If you install them, please send the log: see Field reports.
| Alerts on | Alert | Alerts off | Console or camera offline | Working |
| Feature | Control4 app | Programming |
|---|---|---|
| Add every camera and doorbell | Nothing to do: they appear, named as in UniFi Protect | Hub action: Add New Cameras |
| Pictures | Camera tiles and the camera view | Notification snapshots |
| Live video | The camera view, from the console's RTSP or RTSPS stream | — |
| Smart detections: person, vehicle, animal, package, face, license plate, line crossing, zone (intrusion), motion | — | Events, variables, conditionals and contacts on each camera |
| Doorbell rings (G4 Doorbell, G4 Doorbell Pro, G6 Entry) | Notifications with a snapshot | Ring (camera) and Doorbell Ring (hub) events, LAST_RING |
| Alerts for people: any detection, people and vehicles, or people only | Notifications with a snapshot | Alert (camera) and Camera Alert (hub) events, LAST_ALERT |
| One alerts tile for the home | Tap to turn alerts on or off. The icon shows alert, off, snoozed or offline | SET_ALERTS, SNOOZE_ALERTS, Alerts On/Off events |
| Sounds the camera listens for (smoke alarm, glass break, ...) | — | Sound Detected, LAST_SOUND |
| Health | The tile shows a console or camera that is offline | Console Offline/Online, Camera Offline/Online events |
There are two drivers. Install both:
| Driver in Composer | File | What it does |
|---|---|---|
| DirectorLink · UniFi Protect | DirectorLink-UniFi-Protect.c4z | Add it once per console. It connects to the console, adds its cameras, serves their pictures, passes on their events and gives the home one alerts tile. It shows in the project as UniFi Protect Hub. |
| DirectorLink · UniFi Protect Camera | DirectorLink-UniFi-Protect-Camera.c4z | One per camera or doorbell, added by the hub. Pictures, live video, detections, alerts, rings and programming. |
.c4z files from the latest release.Keep the exact file names. If your browser saves a second copy as
DirectorLink-UniFi-Protect (1).c4z, rename it before you upload. Composer knows a driver by its file name, so a renamed copy installs as a separate driver instead of updating the one you have.
192.168.50.1) and paste the API Key. Status says Connected, Console shows the Protect version, and Found On Console lists what it found, for example 5 cameras, 1 doorbell - 6 not added yet.Optional: add the UniFi Protect Hub to a room menu, for example Security, in Navigator settings, and rename it to something like Camera Alerts so the family knows what the tile does.
The hub's Live Video chooses which of the console's streams Control4 plays:
| Live Video | Stream | |
|---|---|---|
| RTSP (port 7447) (default) | rtsp://<console>:7447/<token> | Try this first. It is what Control4 apps play best. The video is not encrypted on the home network. |
| RTSPS (port 7441) | rtsps://<console>:7441/<token>?enableSrtp | Encrypted, but Control4 apps may not play it. Try it if you want encryption, and go back to RTSP if the video stops. |
Each camera has High, Medium and Low streams; Video Quality (Auto) gives small tiles the Low stream and full screen the High one. UniFi Protect has RTSP off for new cameras. With Create Streams on Automatic (the default) the hub switches on the streams of a camera that has none, which is the same as turning on RTSP for it in UniFi Protect.
Control4 apps and DirectorLink take a camera's pictures from its Control4 camera Properties page: address, port, login and snapshot path. The console only answers with the API key, which they cannot send, so the hub runs a small picture server on the controller (port 47080, see Picture Server). Each camera's page points at it, with that camera's own random Basic login. The hub fetches each picture from the console with the key and keeps it at most one second. A request with another camera's login, or no login, is refused.
Do not change the address, port or login on a camera's Properties page: the hub owns them and the driver puts them back.
Detections always fire their events, variables and contacts. Use them for automations, such as lights on when a person is detected at night.
Alerts are the part meant for people: the Alert and Camera Alert events, notifications, snapshots and the Control4 History. A detection becomes an alert when alerts are on for that camera and on the hub (its tile), are not snoozed, no alert is already active (Hold Time, 30 s by default, so one event alerts once), and the detection matches the camera's Alert On:
| Alert On | Alerts for |
|---|---|
| Any detection | everything the camera reports, motion included |
| People and vehicles | person, face, vehicle, license plate |
| People only | person, face |
Smart detections (person, vehicle, ...) need the camera's smart detections switched on in UniFi Protect.
With Snapshot With Alerts on Yes (the default), Alert, Ring, Camera Alert and Doorbell Ring wait up to 1.5 seconds for that camera's picture, so a notification always shows the picture of its own alert or ring. Set it to No for events without any wait (and without a picture).
G4 Doorbell, G4 Doorbell Pro and G6 Entry are cameras with a ring. Each press sets LAST_RING (the time, ISO 8601 UTC) and fires Ring on the camera and Doorbell Ring on the hub, whatever the alert settings. A camera is a doorbell when the console says so, or from its first ring; set Camera Type to Doorbell to say so yourself.
UniFi Protect Hub
| Property | |
|---|---|
| Status · Console · Cameras · Found On Console | What the hub is doing; the console and its Protect version; the cameras in the project; the cameras on the console |
| Event Connection · Picture Server · Last Error | The console's event stream; the picture server; the last thing that went wrong, with its time |
| Console Address · API Key | The console's IP address and the API key |
| Live Video · Create Streams | RTSP (default) or RTSPS; switch on missing streams |
| Ignored Cameras · Picture Server Port | Names or ids that Add New Cameras skips; the picture server's port (47080) |
| Alerts · Default Alert On · Snapshot With Alerts | Master switch; Alert On for new cameras; snapshot for notifications |
| Log Level | Also sets every camera's Log Level |
Actions: Connect Now · Add New Cameras · Update Camera Names · Send Settings To Cameras · Print Diagnostics
UniFi Protect Camera
| Property | |
|---|---|
| Camera Enabled · UniFi Camera · Camera Type | No stops events, alerts and pictures; the UniFi camera it shows (type a name to link a camera added by hand); Automatic, Camera or Doorbell |
| Status · Attention · Camera · Video · Pictures · Last Event · Managed By | Health in plain words, what to fix, kind and UniFi id, the live video and its streams, where pictures come from, the last event, the hub |
| Alerts · Alert On · Hold Time (s) | This camera's alerts, the alert filter, how long one alert lasts |
| Snapshot With Alerts · Record Alerts In History | Snapshot for notifications; Control4 History entries |
| Video Quality · Contact State When Active · Log Level | Auto / High / Medium / Low; Advanced |
Actions: Reconnect · Test Picture · Setup Report
From DirectorLink 1.10, the DirectorLink app shows these cameras and doorbells with their pictures, their alerts and their doorbell rings. Nothing needs to be set up: the camera driver follows the DirectorLink camera agreement, version 1, so DirectorLink recognizes it by what it says, not by its file name.
DIRECTORLINK_CAMERA = 1, DIRECTORLINK_CAMERA_KIND = camera or doorbell, and DIRECTORLINK_CAMERA_EVENTS = Alert=1 (a camera) or Alert=1,Ring=2 (a doorbell): the ids of its Alert and Ring events in driver.xml, so DirectorLink finds them without reading driver.xml. They are written on every start and follow the kind.LAST_ALERT to what it saw (Person, Vehicle, Animal, Package, Face, License Plate, Line Crossing, Intrusion, Motion), then fires the event Alert: once per alert.LAST_RING to the time (ISO 8601 UTC, a new value for every ring), then fires the event Ring. A camera whose kind is camera (Camera Type set to Camera) never fires Ring.DirectorLink takes the pictures the way Control4 apps do, from the camera's Properties page and the hub's picture server, so the API key never leaves the controller. Without DirectorLink the drivers work the same.
LAST_ALERT_TYPE at LAST_ALERT_CAMERA" with the attachment Snapshot from the camera that raised the alert or rang.LAST_RING_CAMERA" and show the camera on the touchscreens.SET_ALERTS On. When it disarms, run SET_ALERTS Off. SNOOZE_ALERTS pauses alerts for a number of minutes.LAST_OFFLINE_CAMERA.UniFi Protect Hub
ALERTS_ENABLED ALERT_ACTIVE ALL_ONLINE CONSOLE_ONLINE (BOOL) · CAMERAS_TOTAL CAMERAS_ONLINE (NUMBER) · LAST_ALERT_CAMERA LAST_ALERT_TYPE LAST_ALERT_TIME LAST_RING_CAMERA LAST_RING_TIME LAST_OFFLINE_CAMERA PROTECT_VERSION (STRING)SET_ALERTS (On/Off/Toggle) · SNOOZE_ALERTS (minutes) · REFRESHUniFi Protect Camera
DIRECTORLINK_CAMERA DIRECTORLINK_CAMERA_KIND DIRECTORLINK_CAMERA_EVENTS LAST_ALERT LAST_RING LAST_ALERT_TIME LAST_DETECTION LAST_SOUND (STRING) · ONLINE ALERTS_ENABLED ALERT_ACTIVE MOTION PERSON VEHICLE ANIMAL PACKAGE FACE LICENSE_PLATE LINE_CROSSING INTRUSION RINGING (BOOL)SET_ALERTS · SNOOZE_ALERTS · SET_ALERT_ON.c4z files from the latest release.DirectorLink-UniFi-Protect.c4z and DirectorLink-UniFi-Protect-Camera.c4z, not ... (1).c4z.| What you see | What to do |
|---|---|
| "The console refused the API key" | Make a new key in Settings → Control Plane → Integrations and paste it into API Key. |
| "UniFi Protect ... is too old" or "no UniFi Protect Integration API" | Update UniFi Protect on the console to 5.3 or newer. |
| "Cannot reach the console" | Console Address must be the console's IP (not a camera's), reachable from the controller on port 443. |
| "Could not add the camera driver" | Upload DirectorLink-UniFi-Protect-Camera.c4z (Driver → Add or Update Driver or Agent), then run Add New Cameras again. |
| No pictures | Check the hub's Picture Server. If the port is in use, choose another Picture Server Port. Run Test Picture on the camera: it fetches the picture exactly as Control4 apps do. |
| Pictures, but no live video | Control4 OS 3.3.2 or newer is needed. Try the other Live Video setting. Turn off Enhanced Encoding (H.265) for the camera in UniFi Protect. Check the camera's Video line lists streams. |
| No events or alerts | Check the hub's Event Connection says Live, and the camera's smart detections are on in UniFi Protect. For Alert, check alerts are on and the camera's Alert On. |
| A doorbell shows as a camera | It becomes a doorbell at its first ring, or set Camera Type to Doorbell. |
| No tile or no camera controls | Add the UniFi Protect Hub to a room menu, and refresh Navigator after installing or updating. |
For details, run Print Diagnostics on the hub and Setup Report on a camera, with Log Level set to Debug.
These drivers have not yet been reported working on a real UniFi system. If you install them:
driver_log.log, or the Lua tab output) in an issue.Every line of the drivers starts with UniFi Protect Hub: or UniFi Protect Camera '<name>':. At Debug the log shows every API request (status and time), every WebSocket message, every picture request and every event. It never shows the API key, stream tokens or picture passwords. Print Diagnostics lists the console's Protect version, the API's answer for every camera (names, ids, models, kinds, streams, and the fields the console sends), the event connection and the last 10 events.
Not confirmed on a real system yet: pictures on touchscreens, the app and DirectorLink; live video over RTSP and RTSPS; alerts and doorbell rings from a real console. Not expected to work yet: live video and pictures away from home (over 4Sight), since the stream and picture addresses are the home network's; audio; PTZ.
The drivers talk only to the UniFi console on your home network. They send nothing to DirectorLink or to Ubiquiti's cloud and collect no usage data.
The API key stays in your Control4 project and goes only to the console you enter. Reports and logs never show the API key, stream tokens or picture passwords.
Community-supported, best effort. Report problems in Issues.
Please include the console model, its UniFi Protect version, the camera models, your Control4 OS version, each driver's Driver Version, the Print Diagnostics and Setup Report output, and the log with Log Level set to Debug. Remove addresses and names you don't want to share. Reports that a model works are welcome too. Security problems: see SECURITY.md.
pip install lupa pillow
python tools/gen_hub_xml.py # after editing tools/hub_driver.xml.in
python tools/make_icons.py # after changing icons
cd tests && python test_static.py && python test_xml.py && python test_protocol.py && python test_hub.py && python test_camera.py && python test_integration.py && cd ..
python tools/build.py # -> dist/DirectorLink-UniFi-Protect.c4z, dist/DirectorLink-UniFi-Protect-Camera.c4z, dist/SHA256SUMS.txt
test_static.py needs luac 5.1 (apt install lua5.1). python tools/check_fixtures.py (with pip install jsonschema) checks the recorded API answers against Ubiquiti's OpenAPI specifications for Protect 5.3.48, 6.0.53, 6.1.79 and 6.2.83, downloaded from developer.ui.com.
| Path | Contents |
|---|---|
src/common/core.lua | Shared core: logging with secret redaction, timers, variables and events, utilities |
src/hub/json.lua | JSON decoder and encoder |
src/hub/websocket.lua | WebSocket client (RFC 6455) over a Control4 SSL network connection |
src/hub/protect.lua | Protect Integration API client: one host, the key in a header, no redirects, a request queue, 429 back-off |
src/hub/pictures.lua | The picture server on the controller (C4:CreateTCPServer) |
src/hub/, src/camera/ | The drivers: driver.lua, driver.xml (the hub's is generated), www/ documentation and icons |
tools/ | build.py, gen_hub_xml.py + hub_driver.xml.in, make_icons.py, check_fixtures.py |
tests/ | harness.py (Lua 5.1 with a stubbed Control4 API), fake_console.py (the console, from fixtures/), and the tests |
VERSION, CHANGELOG.md, docs/releases/ | The version, the change log, and the notes for each release |
build.py puts the Lua parts in front of each driver's driver.lua and stamps the version from VERSION and the build date into the packaged copies. The driver version Composer compares is major·1000000 + minor·10000 + patch·100 + build, where build is the beta number, or 99 for the release: 1.0.0-beta.1 → 1000001, 1.0.0 → 1000099. So each beta and the release after it count up.
The tests run the real driver code in Lua 5.1. The console is played by fake_console.py with recorded answers in the shape of Ubiquiti's OpenAPI schema (made-up values). They cover the connection and version checks, the API key going only to the console, redirects, rate limits, adding cameras, doorbells, streams, the WebSocket (handshake, framing, ping, close), event routing, the picture server (logins, the one-second picture, shared fetches), the camera page, stream URLs for Navigators, the alert filter, Hold Time, rings, the DirectorLink camera agreement, both drivers together end to end, and that no log line shows a secret.
How it works
GET /v1/meta/info (Protect version, refused below 5.3), /v1/nvrs, /v1/cameras, /v1/cameras/{id}/snapshot[?highQuality=true], GET and POST /v1/cameras/{id}/rtsps-stream, and the WebSockets /v1/subscribe/events and /v1/subscribe/devices, all under https://<console>/proxy/protect/integration/v1 with X-API-Key. C4:url follows redirects by itself and would carry that header along, so an OnHeaders callback stops any 3xx answer before it is followed.C4:AddDevice("DirectorLink-UniFi-Protect-Camera.c4z", room, name, callback). The new camera then receives DL_CONFIGURE through C4:SendToDevice (not logged by Director: it carries the picture login).C4:GetControllerNetworkAddress(), HTTP port = the picture server, Basic login; written with the commands Composer uses and checked with GET_PROPERTIES.requires_dynamic_stream_urls, and answers GET_STREAM_URLS with the console's stream (RTSP or RTSPS) for the requested resolution.DL_CONFIGURE, DL_STREAMS, DL_STATE, DL_EVENT, DL_HUB_ALERTS, DL_HUB_HELLO, DL_LOG_LEVEL, DL_CLAIM_FAILED (hub → camera); DL_CAMERA_STATUS, DL_CAMERA_ALERT, DL_CAMERA_RING (camera → hub).DirectorLink-UniFi-Protect/<version> (hub) or DirectorLink-UniFi-Protect-Camera/<version> (camera).Rules for new versions
VERSION is the only place the version is set..c4z files, and never change or remove proxy binding ids, the order of variables, event and command ids, or property names. Dealers' projects (and DirectorLink) depend on them. Adding new ones is fine, after the existing ones. If the ids of Alert (1) or Ring (2) ever change, DIRECTORLINK_CAMERA_EVENTS must say the new ones.VERSION, CHANGELOG.md, the change log in both www/documentation.html files, and docs/releases/v<version>.md. Then tag v<version>: GitHub Actions tests, builds and publishes the release with SHA256SUMS.txt (a pre-release for -beta versions).Apache License 2.0. See also NOTICE.
The UniFi Protect Integration API is used as Ubiquiti documents it at developer.ui.com. How the Control4 camera proxy behaves in the field was learned from the open-source C4-UnifiProtect drivers. No code was copied from them. Control4 interfaces follow the public Snap One DriverWorks documentation. DirectorLink's own source code: github.directorlink.io.
Installing third-party drivers or changing a Control4 project can affect compatibility, support, warranty or recovery. Keep a backup of your project.
Apache License 2.0. Copyright 2026 DirectorLink. DirectorLink is an independent project, not affiliated with Control4 or Snap One. Not affiliated with or endorsed by Ubiquiti. Product names are trademarks of their owners.