A local Control4 camera driver for the Ajax Systems Baseline Video Surveillance IP cameras (TurretCam, BulletCam and DomeCam, baseline series). It talks to the camera directly over ONVIF on the local network.
There is no cloud service and no Ajax account involved: the camera's own ONVIF user, created in Ajax PRO, is all it needs. The camera's Ajax app keeps working alongside the driver.
8080 ONVIF/HTTP, 8443 ONVIF/HTTPS (optional), 8554 RTSP video (Ajax does not use the usual 554). On the controller: the playback relay port. Nothing is opened to the internet.- Open the camera: Settings › Service › Connection via ONVIF. Turn it on.
- Add an ONVIF user with a password. Write both down: they are the driver's Username and Password. Use letters and digits in the user name (a quote or control character is refused).
- Check the camera's time zone and that its clock is set automatically (NTP).
- For line-crossing events, draw the lines in the camera's detection settings and give each a clear name ("Driveway", "Front Gate"): the driver names its events after them.
- For event playback: SD card in, recording on.
- Add the driver and set Camera IP Address, Username and Password. Leave ONVIF Transport on HTTP 8080 and ONVIF Port blank unless you have a reason (see Properties).
- Wait a few seconds. Status should read "Online" and the Camera Information properties (Manufacturer AJAX, Model, Firmware, Video Streams, Event Subscription "Subscribed") fill in.
- The driver fills in the camera page itself once the camera accepts the login, then reads it back. Camera Page says "verified", or exactly what to set if it did not take (then press Load Defaults on the camera page). Navigators take the Digest login from this page, so live view needs it in every Video Mode.
- Leave Video Mode on "Dynamic (H.265 / H.264)". Set the camera's streams as under Video & Audio.
- Refresh Navigators (Tools › Refresh Navigators) so they pick up the camera.
- Check live view on a touch screen and in the app, then walk in front of the camera: Detected Now and Last Event change, and a History record appears.
The camera has two streams: main (3840×2160 on the test camera) and sub (720×480). Both ship as H.265. The driver reads the codec from ONVIF Media2, because Media1 on this camera reports H.264 for streams that are really H.265. The Video Streams property shows what it found.
Video Mode, and when to use each
Ajax PRO: camera › Settings › Video stream / Image. The camera ships with a 4K main stream at only 1,800 kbps, which smears any motion.
The camera sends G.711 A-law (PCMA). Control4 camera audio plays G.711 u-law (PCMU), so out of the box Navigators play no camera audio. The Audio property says which the camera uses.
The action Set Audio to G.711 u-law switches the camera's audio encoder to u-law; it changes only the encoding, reads it back and reports in Last Command. It is never done automatically, because it also changes what the camera's own recordings and the Ajax app get. Turn on Advertise Camera Audio once the camera is on u-law, and turn on the camera's microphone in Ajax PRO.
The driver subscribes to the camera's ONVIF events (object detection, line crossing, recording, motion) and keeps the subscription alive (renewed every 5 minutes, re-made if the camera drops it, with a watchdog for silence). Detection settings themselves — zones, sensitivity, classes — are made in Ajax PRO.
Composer: When <camera> …
Lines are drawn and named in Ajax PRO. The driver reads them from the camera's rules when it connects (Detection Lines lists them) and gives each its own "Line Crossed: <name>" event and LINE_<NAME>_ variables. After adding or renaming a line, run Refresh Camera Info, then refresh Composer's programming view. At most 32 lines; names are cut to 64 characters.
Composer: Device Actions on the camera. Each writes to the camera, is checked against what the camera reported it supports, clamps a level to the camera's range, then reads the setting back. A refused write changes nothing and says why in Last Command. Writes need the camera online.
Composer: the driver's Actions tab.
- Porch lights at night. When Person Detected, If it is after sunset, turn on Porch Lights. When All Objects Cleared, delay 2 minutes, turn them off.
- Driveway arrival. When Line Crossed: Driveway, If Vehicle is Detected, announce "Car in the driveway" and turn on the garage lights.
- Camera down alert. When Camera Offline, send a push notification. When Login Failed, notify the installer (someone changed the ONVIF password).
- Busy day. When Person Detected, If PERSON_TODAY > 50, send an email once.
Each detection that is switched on makes one record in the Control4 History (category Cameras, subcategory IP Camera), attached to the camera proxy so it shows on the camera in the app's History / Timeline and can raise a push notification there. Types: Person, Vehicle, Animal (a pet), Other Object and Line Crossing.
The per-type History properties choose what is recorded. Composer events fire whatever these say; they only decide History. Recording and camera online / offline are not History records — use the RECORDING_ACTIVE and CAMERA_ONLINE variables and their events instead.
Each record of a detection carries a playback link. The camera can only seek its SD recording when the player sends an RTSP Range: clock= header, and the Control4 app can only open a URL. So the link points at a small RTSP relay in this driver on the controller. When the app opens it, the relay opens the camera's SD recording with the camera's Digest login, asks it to seek to the event, then passes the video through. The camera login never appears in the link.
Playback works remotely through Control4's remote access, though main-stream playback may be choppy there. The camera records H.265; a player that cannot play H.265 will not play it.
Every setting is kept across a driver update. After an update, refresh Navigators and close and reopen the app, so they ask the driver for the stream addresses again.