Live Bee Cameras from Painted Peacock Manor:

Introduction:

The left camera rotates its view among all my established hives here at Painted Peacock Manor:

At present I have five hives--four in the upper apiary and one in the Swarm Trap. The upper hives are identified by letters or numbers on the front of the hives, which are only sometimes visible on camera. From right to left:

The colony in the trap moved in on 4/7/21.

Bee Notes:

We're entering Spring here in Southern California. We had a little rain back in December and January, but nothing for a few weeks. Still, things are in bloom, and the girls are putting away nectar and pollen. My hives are still small, with 4-6 frames of bees, and no capped honey yet, but they're building up steadily. Hive F just superseded, and probably had a virgin queen when I inspected on 2/20/21.

Technical Notes:

This camera is a Reolink RLC-423S "turret" camera (now obsolete) with Pan/Zoom/Tilt, mounted to a metal fence about 12" from the front of the hive stands.


I didn't know that the RLC-423S supported POE, and the manual didn't say anything about it 🤦‍♂️, so I used a waterproof junction box to house a passive POE splitter and bunch of excess cabling:




The camera doesn't have a mic, so I'm using a playlist of royalty-free MP3s from YouTube as the soundtrack, because ffmpeg requires an audio track (see below).

I'm streaming the video via an old $38 Raspberry Pi 3B ($30 at the time), with each stream running on a separate instance of ffmpeg. Although ffmpeg is the "Swiss Army Knife" of video transcoding and manipulation, I'm using it only as a "relay station," to pull an RTSP stream from the camera and push it to the YouTube streaming server via RTMP. As such, it's not doing any transcoding at all. At most it's repackaging the mp4 video packets into flv format (Flash Video, which YouTube retains as its preferred input format for Stream Now video), and remuxing audio into the stream. Neither operation is especially CPU intensive, and ffmpeg consumes only 12% - 20% of the CPU on my little RPi computer.

The ffmpeg script is of the general form:

#!/bin/bash
cd /usr/local/bin/
while true
do
./ffmpeg -thread_queue_size 1024 -rtsp_transport tcp -i "rtsp://anonymous:password1@192.168.1.13:554/cam/realmonitor?channel=1&subtype=0" concat -safe 0 -i playlist.txt -vcodec copy -acodec copy -t 01:47:02 -f flv "rtmp://a.rtmp.youtube.com/live2/insert-your-youtube-streaming-key"
echo Stream2Complete
sleep 5s
done

I run this as a Raspbian service, along with a watchdog timer that is supposed to kill and restart the service if the YouTube stream goes down for more than 5 minutes. The watchdog script isn't working right now, because YouTube changed something in their data API and/or quotas back in 2020, so right now I'm doing a lot of manual fiddling with the service, so the stream goes offline more often than I'd like.

I have a separate service running to command the rotation from hive to hive. The camera's built-in "cruise" feature doesn't work very well, so I had to write my own.

At first I thought I was going to have to learn ONVIF, and then I found this post on IPCamTalk, which reads:

Just open your camera in the Chrome Browser, and press Ctrl Shift i (or Cmd Shift i on a Mac); then click on the "Network" tab at the top. Then run your camera using the regular controls and you will see the corresponding network commands appear in the network list.

From that I was able to snoop the commands that were sent by the web interface to the camera, and then I could duplicate them with a curl command. When I first started snooping the commands I was really surprised, because it's all timer-based. Apparently the RLC-423S motors have no idea where they are. Zooming in relies on the amount of time that the user has pressed the Zoom+ button in the UI, and releasing the mouse button sends a Stop command. Given the latency of a typical web link, it's not surprising that manual zoom and focus are pretty much useless. So I wrote a shell script, CommandPauseStop.sh, that I invoke like this:

./CommandPauseStop.sh ZoomInc 5

This issues one of several supported commands, such as ZoomInc, ZoomDec, FocusInc, or FocusDec, then waits a few seconds, and then issues a Stop:

#!/bin/bash

ReolinkToken=`curl -s GET "http://192.168.1.11/cgi-bin/api.cgi?cmd=Login&token=null" -d '[{"cmd":"Login","action":0,"param":{"User":{"userName":"admin","password":"1234567"}}}]' | jq -r '.[].value.Token.name'`

Cmd=$1
Pause=$2

curl -s POST "http://192.168.1.11/cgi-bin/api.cgi?cmd=PtzCtrl&token=$ReolinkToken" -d '[{"cmd":"PtzCtrl","action":0,"param":{"channel":0,"op":"'$Cmd'","speed":32}}]'

sleep $Pause

curl -s POST "http://192.168.1.11/cgi-bin/api.cgi?cmd=PtzCtrl&token=$ReolinkToken" -d '[{"cmd":"PtzCtrl","action":0,"param":{"channel":0,"op":"Stop"}}]'

It requires installation of the jq library to make parsing of the returned token easier.

Once I had the command set I was able to use the last command, ToPos, to cycle through each of the defined preset points and FocusInc after each one, since the camera doesn't store focus points with presets, because it can't, because the motors have no position sensors.

It's clunky, but it's been working steadily for 3+ years now. The only manual fiddling I've had to do is with the YouTube side of things.

The camera is powered by a 12V wall wart and a passive POE splitter/injector pair in my tack room, 40' away, connected by a long run of Cat5e cable zip-tied to that metal fence. Some day I might replace that with true POE, especially if I ever swap out that camera. But PTZ cameras are expensive, so I'll keep using this until it dies.

To do:

I welcome any and all feedback on any ways to improve this system or this page, including:

About:

I'm Steven Kan, and I call my house Painted Peacock Manor. You can find or reach me via: