How to configure a hacked Xiaomi Dafang to work with OpenHAB

Tags: #<Tag:0x00007f3873238b58> #<Tag:0x00007f38732389f0> #<Tag:0x00007f3873238860>

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 :wink:):

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.

14 Likes

I am interested in this topic, any updates?

Just a minor update: I did manage to get the camera feed to show in the OH Android app, though not the way I would have liked. What worked was disabling HTTP to HTTPS redirection in the Xiaomi Dafang Hacks firmware.

For anyone interested, I achieved this by;

Editing the lighttpd.conf file found in /system/sdcard/config/lightpd.conf and commenting out the following lines:

#$HTTP["scheme"] == "http" {
#    # capture vhost name with regex conditiona -> %0 in redirect pattern
#    # must be the most inner block to the redirect rule
#    $HTTP["host"] =~ ".*" {
#        url.redirect = (".*" => "https://%0$0")
#    }
#}

Then reboot the camera. You should be able to see an image element showing the video feed in the OH web interface and Android interfaces.

1 Like

And what about the Web GUI? Did you manage to show Video on the sitemap or just Image?

Ps.: I just saw the end of the previous post now… Does it have any downsides that it is only an Image element?

I am also interested in that topic. What I am searching for is a way to display motion detection images in the web view (habpanel). Did anyone manage to do this?

With the Image element configuration mentioned in the first post, the image is only updating every second. You could lower the refresh number to get more images per second but there is definitely a limit to what the Dafang could handle. Personally, I find once per second to be quite serviceable.

I have not looked into displaying the captured motion detection images on a sitemap/HABpanel but I do know that you can get the camera firmware to run a custom script when an image is captured by creating a custom script, making it executable and placing it in:

/system/sdcard/config/userscripts/motiondetection/SCRIPTNAME.sh

You could create a script that gets the public link to the latest image capture (these are stored @ /system/sdcard/motion/) and sends that link to an OpenHAB String item via MQTT. Then you could use that String item as the URL for an Image/Webview in your HABpanel.

Another option is to edit the existing script for snapping a picture (found @ /system/sdcard/scripts/detectionON.sh) and inject some extra lines to send the image link to an OpenHAB String item. Look around in the scripts for the Dafang firmware for inspiration on how to send an extra MQTT command.

I have used both Image and Webview elements to display images from the Dafang. You can request specific pictures from the camera using a cgi-currentpic link like:

Webview url="http://USERNAME:PASSWORD@HOSTNAME.DOMAIN/cgi-bin/currentpic.cgi?STRING_OF_NUMBERS" h=5 # Determines how many rows this element will occupy
# OR
Image url="http://USERNAME:PASSWORD@HOSTNAME.DOMAIN/cgi-bin/currentpic.cgi?STRING_OF_NUMBERS"
2 Likes

I was hoping to use my old iPad as a habPanel display today but I struggled all day to get a picture feed from newly hacked xiaomi dafang camera in habPanel with chrome/safari on my iPhone/iPad.

http://xxx.xxx.x.xx/cgi-bin/currentpic.cgi
This string finally got a picture in my sitemap/habPanel when Inviewed it on my PC with Chrome.

But nothing on the iPhone.
Any tips?

any way to contorl the microphone or the speaker with this hack ?

That is interesting. I mainly use Windows and Android so had not encountered this problem.

I had issues displaying the picture feed on Android until I disabled HTTP to HTTPS redirection on the camera. The process for doing that is mentioned in the third post. Have you tried that yet?

Yes, but as far as I am aware it does not support push-to-talk functionality. You can play pre-loaded audio files and initiate an audio recording. Either of these could be started manually or by adding a command to a script.

From the Dafang Hacks FAQ:

Cool thanks!

Thanks for the information. I will try to export the pictures stored on the SD card to my NAS. Maybe this way I can somehow embed the pic in habpanel.
I did not get MQTT to work with the new binding (lack of skill on my side unfortunately) released for v2.4. Is there any way to test/log this in openhab (for example I saw in the openhab logs that the cam items received updates)?

Not to worry, I have updated the first post in this thread with a working configuration for use with the new MQTT 2.4 Binding. :wink:

Awesome! Thanks a lot, now everything seems to be working

It is even easier as I just found out. No need to change/write scripts. The image of the motion is already provided in the topic “myhome/dafang/motion/snapshot”.
In the configuration file you just need to set

save_snapshot=true
publish_mqtt_message=true

Then you can add to the sample you provided in the first post:

mqtt.things:
Type image : motionimage "Motion Image" [ stateTopic="myhome/dafang/motion/snapshot" ]

camera.items:
String Cam01_Motion_Image "Motion Image" <snapshot> (GF_Camera_01) {channel="mqtt:topic:mosquitto:somecamera:motionimage"}

I have not added it to the sitemap yet but it displays perfectly as image widget in Habpanel.
Thanks again for the help and links!

2 Likes

Hi,
I’m interested too in this topic but I need extra help to create the mosquitto thing.
Would you please give me some tips about the steps I need to do to configure the Dafang and the mosquitto broker?

Where are you stuck? Is the firmware already running on your camera? For the mqtt part Max explained everything that needs to be done (see also links to the binding doc).

Sorry for the stupid questions:
The firmware is running on the camera.

  • Should I change some parameters in the root\config\mqtt.conf ?
  • Where should I copy files mqtt.things and camera items? OpenHab or Dafang?

After you installed the broker in openhab you add the address in the conf file of the camera. The other files you mentioned will be created in openhab in the usual folder for things and items.

Have you tried this with the non-panning original Xiaofang? The Dafang Hacks has support for the Wyze V2/Xiaofang 1S… so, will this example w/o the panning commands? Has anyone tried it?

I just hacked two WYZE V2 cameras and am hoping to get them working with HABPanel. Has anyone had any success? On a Mac, I can display the web interface, but for dashboard purposes it is not great because the video has a large frame around it. I’d like to just have the stream fill the panel. I ultimately want to use the dashboard on an iPad and Raspberry Pi.