Recently, I got my hands on a Xiaomi Dafang and wanted to hook it up to my OpenHAB via MQTT. So I flashed the device with the Xiaomi DaFang Hacks custom firmware and got to work. I noticed that there are not many guides on how to pair the Dafang Hacks firmware with OpenHAB. This post is designed to help others looking to achieve this pairing. NOTE: The Xiaomi DaFang is identical to the WyzeCam Pan so the exact same procedure will work for it too.
Firstly, make sure you have the MQTT Binding and the JSONPath Transformation installed as they are required for this to work.
The Dafang Hacks firmware comes with some helpful pre-configured MQTT topics:
TOPIC/PREFIX // <---- This returns a JSON payload with connection info
TOPIC/PREFIX/leds/ir
TOPIC/PREFIX/ir_cut
TOPIC/PREFIX/night_mode/auto
TOPIC/PREFIX/leds/blue
TOPIC/PREFIX/leds/yellow
TOPIC/PREFIX/motion/detection
TOPIC/PREFIX/rtsp_h264_server
TOPIC/PREFIX/rtsp_mjpeg_server
TOPIC/PREFIX/motion/send_mail
TOPIC/PREFIX/brightness
TOPIC/PREFIX/night_mode
TOPIC/PREFIX/motion/tracking
The Dafang Hacks firmware also provides another way to set values via MQTT; by sending a TOPIC/PREFIX/set
command followed by any one of these values:
reboot
shutdown
blue_led_on
blue_led_off
yellow_led_on
yellow_led_off
ir_led_on
ir_led_off
ir_cut_on
ir_cut_off
motor_left
motor_right
motor_up
motor_down
motor_vcalibrate
motor_hcalibrate
motor_calibrate
motor_PTZ
audio_test
h264_start
h264_noseg_start
mjpeg_start
h264_nosegmentation_start
xiaomi_start
rtsp_stop
set_http_password
auto_night_mode_start
auto_night_mode_stop
toggle-rtsp-nightvision-on
toggle-rtsp-nightvision-off
flip-on
flip-off
motion_detection_on
motion_detection_off
set_video_size
set_region_of_interest
offDebug
onDebug
conf_timelapse
conf_audioin
update
show_updateProgress
motion_detection_mail_on
motion_detection_mail_off
motion_detection_led_on
motion_detection_led_off
motion_detection_snapshot_on
motion_detection_snapshot_off
motion_detection_mqtt_on
motion_detection_mqtt_off
First step is to create an “mqtt.things” file. In it you will define a Bridge representing your MQTT Broker. In this example, I’m using a locally installed instance of Mosquitto. Paste in the following content, replacing “home” with your camera topic and “camera-name” with your camera name (…durr ):
Bridge mqtt:broker:mosquitto "Mosquitto" [ host="localhost", port=1883, secure=false, username="USERNAME", password="PASSWORD", clientID="openHAB2" ]
{
// Xiaomi Dafang
Thing topic somecamera "Some Camera" @ "Some Room" {
Channels:
Type string : system "System" [ commandTopic="home/camera-name/set" ]
Type string : vertical "Vertical" [ commandTopic="home/camera-name/motors/vertical/set" ]
Type string : horizontal "Horizonzal" [ commandTopic="home/camera-name/motors/horizontal/set" ]
Type switch : irleds "IR LEDs" [ stateTopic="home/camera-name/leds/ir", commandTopic="home/camera-name/leds/ir/set" ]
Type switch : ircutoff "IR Cut-Off Filter" [ stateTopic="home/camera-name/ir_cut", commandTopic="home/camera-name/ir_cut/set" ]
Type switch : nightauto "Night Mode Auto" [ stateTopic="home/camera-name/night_mode/auto", commandTopic="home/camera-name/night_mode/auto/set" ]
Type switch : blueled "Blue LED" [ stateTopic="home/camera-name/leds/blue", commandTopic="home/camera-name/leds/blue/set" ]
Type switch : yellowled "Yellow LED" [ stateTopic="home/camera-name/leds/yellow", commandTopic="home/camera-name/leds/yellow/set" ]
Type switch : motion "Motion Detection" [ stateTopic="home/camera-name/motion/detection", commandTopic="home/camera-name/motion/detection/set" ]
Type switch : rtsph264 "RTSP H264 Server" [ stateTopic="home/camera-name/rtsp_h264_server", commandTopic="home/camera-name/rtsp_h264_server/set" ]
Type switch : rtspmjpeg "RTSP MJEPG Server" [ stateTopic="home/camera-name/rtsp_mjpeg_server", commandTopic="home/camera-name/rtsp_mjpeg_server/set" ]
Type switch : motiontrack "Motion Tracking" [ stateTopic="home/camera-name/motion/tracking", commandTopic="home/camera-name/motion/tracking/set" ]
Type switch : motionmail "Motion Send Mail" [ stateTopic="home/camera-name/motion/send_mail", commandTopic="home/camera-name/motion/send_mail/set" ]
Type string : motionled "Motion LED" [ commandTopic="home/camera-name/set" ]
Type string : motionsnapshot "Motion Snapshot" [ commandTopic="home/camera-name/set" ]
Type string : motionmqtt "Motion MQTT" [ commandTopic="home/camera-name/set" ]
Type number : brightness "Brightness" [ stateTopic="home/camera-name/brightness" ]
Type switch : nightmode "Night Mode" [ stateTopic="home/camera-name/night_mode", commandTopic="home/camera-name/night_mode/set" ]
Type string : audiotest "Audio Test" [ commandTopic="home/camera-name/set" ]
Type string : flipimage "Flip Image" [ commandTopic="home/camera-name/set" ]
Type string : calibrate "Calibrate Motor" [ commandTopic="home/camera-name/set" ]
Type string : uptime "Uptime" [ stateTopic="home/camera-name", transformationPattern="JSONPATH:$.uptime" ]
Type string : ssid "WiFi SSID" [ stateTopic="home/camera-name", transformationPattern="JSONPATH:$.ssid" ]
Type string : bitrate "WiFi Bitrate" [ stateTopic="home/camera-name", transformationPattern="JSONPATH:$.bitrate" ]
Type string : rssi "WiFi Signal Strength" [ stateTopic="home/camera-name", transformationPattern="JSONPATH:$.signal_level" ]
Type string : linkquality "WiFi Link Quality" [ stateTopic="home/camera-name", transformationPattern="JSONPATH:$.link_quality" ]
Type string : noiselevel "Noise Level" [ stateTopic="home/camera-name", transformationPattern="JSONPATH:$.noise_level" ]
}
}
Notice that the MQTT command is the same for a few of these items;
commandTopic="home/camera-name/set"
This is because the commands for these items will be configured in the sitemap. Also notice how these items are Strings and not Switches. Switches will not allow for custom MQTT statuses to be sent but Strings will.
The next step is to create a “cameras.items” file. Paste in the following:
// Xiaomi Dafang
Group GF_Camera_01 "Some Camera" <dafang> (Cameras, Xiaomi)
String Cam01_System "System" <dafang> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:system", autoupdate="false"}
String Cam01_Vertical "Vertical" <vertical> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:vertical", autoupdate="false"}
String Cam01_Horizontal "Horizonzal" <horizontal> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:horizonzal", autoupdate="false"}
Switch Cam01_IR_LEDs "IR LEDs [%s]" <led_purple> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:irleds" }
Switch Cam01_IR_CutOff "IR Cut-Off Filter [%s]" <led_purple> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:ircutoff" }
Switch Cam01_Night_Mode_Auto "Night Mode Auto [%s]" <scene> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:nightauto" }
Switch Cam01_Blue_LED "Blue LED [%s]" <led_blue> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:blueled" }
Switch Cam01_Yellow_LED "Yellow LED [%s]" <led_yellow> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:yellowled" }
Switch Cam01_Motion_Detection "Motion Detection [%s]" <motion_detection> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:motion" }
Switch Cam01_RTSP_H264_Server "RTSP H264 Server [%s]" <h264> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:rtsph264" }
Switch Cam01_RTSP_MJPEG_Server "RTSP MJEPG Server [%s]" <mjpeg> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:rtspmjpeg" }
Switch Cam01_Motion_Send_Mail "Motion Send Mail [%s]" <gmail> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:motionmail" }
String Cam01_Motion_LED "Motion LED" <led_yellow> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:motionled" }
String Cam01_Motion_Snapshot "Motion Snapshot" <snapshot> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:motionsnapshot" }
String Cam01_Motion_MQTT "Motion MQTT" <mqtt> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:motionmqtt" }
Number Cam01_Brightness "Brightness [%s]" <brightness> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:brightness" }
Switch Cam01_Night_Mode "Night Mode [%s]" <night> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:nightmode" }
Switch Cam01_Motion_Tracking "Motion Tracking [%s]" <motion_tracking> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:motiontrack" }
String Cam01_Audio_Test "Audio Test" <audio> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:audiotest", autoupdate="false"}
String Cam01_Flip_Image "Flip Image" <flip> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:flipimage", autoupdate="false"}
String Cam01_Calibrate "Calibrate Motor" <calibrate> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:calibrate", autoupdate="false"}
String Cam01_Calibrate_Axis "Calibrate Motor Axis" <calibrate> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:calibrate", autoupdate="false"}
String Cam01_Uptime "Uptime [%s]" <none> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:uptime" }
String Cam01_SSID "WiFi SSID [%s]" <wifi> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:ssid" }
String Cam01_BitRate "WiFi Bitrate [%s]" <wifi> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:bitrate" }
String Cam01_RSSI "WiFi Signal Strength [%s]" <wifi> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:rssi" }
String Cam01_Link_Quality "WiFi Link Quality [%s]" <wifi> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:linkquality" }
String Cam01_Noise "WiFi Noise Level [%s]" <none> (GF_Camera_01) { channel="mqtt:topic:mosquitto:somecamera:noiselevel" }
Next put the following group into your sitemap:
Group item=GF_Camera_01 label="Xiaomi Dafang" icon="dafang" {
Switch item=Cam01_System label="System" mappings=["reboot"="Reboot", "shutdown"="Shutdown", "update"="Update"]
Switch item=Cam01_Vertical label="Vertical Movement" mappings=["up"="Up","down"="Down"]
Switch item=Cam01_Horizontal label="Horizontal Movement" mappings=["left"="Left","right"="Right"]
Switch item=Cam01_IR_LEDs label="IR LEDs []"
Switch item=Cam01_IR_CutOff label="IR Cut-Off Filter []"
Switch item=Cam01_Night_Mode_Auto label="Night Mode Auto []"
Switch item=Cam01_Motion_Detection label="Motion Detection []"
Switch item=Cam01_Blue_LED label="Blue LED []"
Switch item=Cam01_Yellow_LED label="Yellow LED []"
Switch item=Cam01_RTSP_H264_Server label="RTSP H264 Server []"
Switch item=Cam01_RTSP_MJPEG_Server label="RTSP MJPEG Server []"
Switch item=Cam01_Motion_Send_Mail label="Send Mail on Motion Detection []"
Switch item=Cam01_Motion_LED label="LED on Motion Detection []" mappings=["motion_detection_led_on"="On", "motion_detection_led_off"="Off"]
Switch item=Cam01_Motion_MQTT label="MQTT on Motion Detection" mappings=["motion_detection_mqtt_on"="On", "motion_detection_mqtt_off"="Off"]
Text item=Cam01_Brightness label="Brightness [%s]" icon="brightness"
Switch item=Cam01_Night_Mode label="Night Mode []"
Switch item=Cam01_Motion_Tracking label="Motion Tracking []"
Switch item=Cam01_Audio_Test label="Audio Test" mappings=["audio_test"="Play"]
Switch item=Cam01_Flip_Image label="Flip Image" mappings=["flip-on"="Inverted", "flip-off"="Normal"]
Switch item=Cam01_Calibrate label="Calibrate Motor" mappings=["motor_calibrate"="Now"]
Switch item=Cam01_Calibrate_Axis label="Calibrate Motor Axis" mappings=["motor_vcalibrate"="Vertical", "motor_hcalibrate"="Horizontal"]
Text item=Cam01_RSSI label="WiFi Signal Strength [%s]"
}
While the video stream from this camera works well when viewed via other methods (VLC, etc), I have not yet managed to get the stream showing in the OpenHAB GUI (Web or Android) using the Video element. Here is what I have tried while the camera is set to H264 RTSP or MJPEG RTSP;
Video icon="dafang" url="rtsp://xxx.xxx.xxx.xxx:8554/unicast"
Video icon="dafang" url="rtsp://xxx.xxx.xxx.xxx:8554/unicast" encoding="h264"
Video icon="dafang" url="http://xxx.xxx.xxx.xxx:8554/unicast"
Video icon="dafang" url="http://xxx.xxx.xxx.xxx:8554/unicast.m3u8" encoding="hls"
Video icon="dafang" url="http://xxx.xxx.xxx.xxx:8554/unicast.mpd" encoding="mpeg-dash"
Video icon="dafang" url="http://xxx.xxx.xxx.xxx:8554/unicast" encoding="mjpeg"
However, I did get the video feed to show in OpenHAB GUI (Web) by using the Image element to create this item in the sitemap:
Image url="http://xxx.xxx.xxx.xxx/cgi-bin/currentpic.cgi" refresh=1000
# OR with authentication:
Image url="http://USERNAME:PASSWORD@HOSTNAME/cgi-bin/currentpic.cgi" refresh=1000
Had no luck displaying the video feed in the OH Android application though.
Hopefully this helps somebody. Do let me know if there is anything left out of this guide or if you got the video stream working via some other method.