Hacking the XiaomiFang Wifi camera

I’m very interested about this camera too :slight_smile:

image

I have 2 of these Xiaomi DaFang cameras and I’ve integrated them with HA.
Note that you will need ffmpeg to get this working.
I personally use motion in the middle to perform motion detection / recording and streaming (I use that streamed feed in HA). Plus for some reason the quality is better than HA directly pulling the RTSP feed.

  1. Get the modified firmware from https://github.com/EliasKotlyar/Xiaomi-Dafang-Hacks
  2. Once installed and setup as per the instructions, start the RTSP sever (use the MJPEG RTSP)
  3. If connecting from HA directly, use this config:
camera:
  - platform: ffmpeg
    name: Cam
    input: -rtsp_transport tcp -i rtsp://192.168.x.x:8554/unicast

if using motion in the middle, your config should look like this:

- platform: mjpeg
  mjpeg_url: http://192.168.x.x:808x
  name: Cam

in addition you can control some functions of the camera directly from HA like the blue/yellow LED, IR Filter and IR LED, X and y motor movements etc. The way I achieved this is with a combination of scrape sensors and template switches.
For the scrape sensors I had to create a few web pages to return statuses. I can’t attach them here so I’m posting one example for the blue LED:

#!/bin/sh

echo "Content-type: text/html"
echo ""

getgpio(){
GPIOPIN=$1
cat /sys/class/gpio/gpio$GPIOPIN/value
}

cat << EOF
<!DOCTYPE html>
<html>
<head>
<title>Fang Hacks Blue LED Status</title>
</style>
</head>
<body>
EOF
# status of 0 means on, status of 1 means off
getgpio 39
cat << EOF
</body>
</html>
EOF

Save the file as blue.cgi on the SD card under www/cgi-bin
For other functions, simply replace the GPIO number (39 here) with the one matching the function that you need:

Blue LED: 39
Yellow LED: 38
IR Cut: 26
IR LED: 49

Then you can create scrape sensors, here is the example for the blue LED:

- platform: scrape
  resource: http://192.168.x.x/cgi-bin/blue.cgi
  name: dafang_blue_led_status_scrape
  select: "body"

Create 2 simple shell commands to turn the LED on or off:

dafang_blue_led_on: wget http://192.168.x.x/cgi-bin/action.cgi?cmd=blue_led_on
dafang_blue_led_off: wget http://192.168.x.x/cgi-bin/action.cgi?cmd=blue_led_off

Then create a template switch:

- platform: template
  switches:
    dafang_blue_led:
      friendly_name: Dafang Blue LED
      value_template: "{{ is_state('sensor.dafang_blue_led_status_scrape', '\n0\n') }}"
      turn_on:
        service: shell_command.dafang_blue_led_on
      turn_off:
        service: shell_command.dafang_blue_led_off

Here is the result:
image

Hope this helps

13 Likes

Thanks for sharing!

1 Like

Does tracking work?

No not yet, at least not natively, but there are web commands that you can use to control the motor, depending on what app you use.

Thanks for sharing! How do you start the server? I can’t find how to do that on Github.

Go on the IP address of your camera, it’ll show a webpage that looks like this:

Click on the on of the RTSP Server options as per your needs.

Thanks for the quick reply. I get a blanc page on my cam’s IP.
Guess something went wrong with the installation.

I can access the cam through:
http://cam_IP/cgi-bin/hello.cgi

Looks like either the custom firmware wasn’t correctly or successfully installed. Try again?

I just tried again unfortunately without luck.

If I understand correctly, the order is:

Installation of the custom firmware with the microSD bootloader
1. Download CFW-Binary
2. Format your microSD to FAT. NTFS, EXFAT etc. won't work.
3. Put it to microSD and rename it to "demo.bin". There should be no other files on the microSD! This is really important and it won't work if there are any other files on there.
4. Shutdown the Dafang camera, remove the power cable and plug the microSD into the Dafang
   Hold the setup button on the Dafang camera
5. Plug in the USB power cable
6. Wait until the firmware has finished flashing (like 5 minutes). Disconnect the power as soon as the base 
   starts moving.
7. Remove the microSD and try to start the Dafang camera
   You should see the blue led shining up for 5 seconds (not blinking) before the base starts moving. If not, something went wrong. You should try another microSD. Start over from step 1.

After that, I delete all files from the microSD and then:

1. Clone the repository from github. If you are on windows download the repository as zip file.
2. Copy everything from "firmware_mod" folder into the root of the microSD
   It should look like this:

E:/
├── bin
├── config
├── run.sh
├── scripts
└── www

3. Modify the file config/wpa_supplicant.conf on the microSD to match your wifi-settings
4. Insert the microSD and start the camera.

Right?

That looks right. Do you see the blue light for 5 sec ( not flashing)?
Note: when you hold the setup while powering the camera, you don’t need to hold for like 5min, just hold for a few sec.
Also try a different SD card if you can, there have been reports of some that didn’t work. I personally managed to flash with Sandisk cards.

Nope :frowning:

I don’t see anything happening with the led at all when I hold the setup button and then powering the camera.
I’m using a brandnew Sandisk SD card, freshly formatted. I will try with another one.

you won’t see anything while you hold the button if I remember well (been a couple of months now)
Hold the button, power the camera, wait like 5 sec and release the button, then wait
when the camera spins, take power off and that should be it.

how long will this approx. take?

Thank you for your help but I have one question:

Which one is the port in this URL?
mjpeg_url: http://192.168.x.x:808x

Hacked camera is working always in 8854 port. Isn’t?

Hi @Pharizna,

It all depends on what you use to get the initial feed. In my post I wrote this:
If connecting from HA directly, use this config:

- platform: ffmpeg
  name: Cam
  input: -rtsp_transport tcp -i rtsp://192.168.x.x:8554/unicast

if using motion in the middle, your config should look like this:

- platform: mjpeg
  mjpeg_url: http://192.168.x.x:808x
  name: Cam

(If you use motion you’ll have to set rtsp://192.168.x.x:8554/unicast as your camera feed for the netcam_url setting

so it you use motion you can set the port on which you’ll stream with setting stream_port

Following your great ideas, I did a more lightweight solution.

I have abandoned scrape sensors (every time a timeout occurred, HASS log was terribly polluted), and used a single command_line sensor using curl with a scan_interval of 60 seconds (even though scrape sensors are usually refreshed every 30 seconds, I thought 60 was more than enough).

In my all.cgi file (placed in the same folder as yours), I bundled everything you had in your separate cgi files and outputted a list of all values separated by commas:

#!/bin/sh

echo "Content-type: text/plain"
echo ""

getgpio(){
GPIOPIN=$1
cat /sys/class/gpio/gpio$GPIOPIN/value
}

# Blue Led
blue=$(getgpio 39)
# Yellow Led
yellow=$(getgpio 38)
# IR Cut
ir_cut=$(getgpio 26)
# IR Led
ir_led=$(getgpio 49)
# RTSP status
string=$(pidof v4l2rtspserver-master)
if [[ ${#string} == "0" ]]; then
  rtsp="off"
else
  rstp="on"
fi
echo $blue,$yellow,$ir_cut,$ir_led,$rstp

and then in terms of HA configuration:

  - platform: command_line
    name: dafang_status
    command: "/usr/bin/curl -s -X GET -H\"Content-Type:text/plain\" http://Dafang_IP/cgi-bin/all.cgi"
    scan_interval: 60

  - platform: template
    sensors:
      dafang_blue_led_status:
        value_template: "{{ states.sensor.dafang_status.state.split(',')[0] }}"
      dafang_yellow_led_status:
        value_template: "{{ states.sensor.dafang_status.state.split(',')[1] }}"
      dafang_ir_led_status:
        value_template: "{{ states.sensor.dafang_status.state.split(',')[2] }}"
      dafang_ir_cut_status:
        value_template: "{{ states.sensor.dafang_status.state.split(',')[3] }}"
      dafang_rtsp_status:
        value_template: "{{ states.sensor.dafang_status.state.split(',')[4] }}"

In terms of the remaining (switch templates + command line/scripts), I followed your idea.

This way, we can achieve the same you have but with a single curl call every minute, instead of call per scrape sensor every 30 seconds.

Hope this is useful.

1 Like

Would you be able to share a bit more about the motion implementation you did? Settings, etc.

I’m curious to see how it behaves.

Btw, where are you saving motion’s detections (pictures/videos)? In the camera SD card or in some other place (Rpi SD card)?

Thanks for any insights.

For motion, settings depend on what you want to do. Best is to start with stock settings and add / amend as per your needs.
Check motion’s github page: https://github.com/Motion-Project/motion
All you’ll need is to add the RTSP Stream in the settings (rtsp://192.168.x.x:8554/unicast). You can define where you want the videos to be saved. I save them in my dropbox folder for added redundancy.