├── wyze_cam_v3.jpg ├── lib ├── libssl.so.44 ├── libcrypto.so.42 ├── libmosquitto.so.1 └── libmosquittopp.so.1 ├── mqtt-controls.png ├── mqtt-diagnostic.png ├── bin ├── mosquitto_pub.bin ├── mosquitto_sub.bin ├── mosquitto_pub ├── mosquitto_sub ├── mqtt-daemon.sh ├── mqtt-autodiscovery.sh ├── mqtt-control.sh └── mqtt-status.sh ├── installer ├── DOTuser_config ├── S10httpd └── setup.sh ├── mosquitto.conf ├── install.sh ├── README.md └── LICENSE /wyze_cam_v3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/g8keeperzuul/wz_mini_hacks-MQTT/HEAD/wyze_cam_v3.jpg -------------------------------------------------------------------------------- /lib/libssl.so.44: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/g8keeperzuul/wz_mini_hacks-MQTT/HEAD/lib/libssl.so.44 -------------------------------------------------------------------------------- /mqtt-controls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/g8keeperzuul/wz_mini_hacks-MQTT/HEAD/mqtt-controls.png -------------------------------------------------------------------------------- /lib/libcrypto.so.42: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/g8keeperzuul/wz_mini_hacks-MQTT/HEAD/lib/libcrypto.so.42 -------------------------------------------------------------------------------- /mqtt-diagnostic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/g8keeperzuul/wz_mini_hacks-MQTT/HEAD/mqtt-diagnostic.png -------------------------------------------------------------------------------- /bin/mosquitto_pub.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/g8keeperzuul/wz_mini_hacks-MQTT/HEAD/bin/mosquitto_pub.bin -------------------------------------------------------------------------------- /bin/mosquitto_sub.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/g8keeperzuul/wz_mini_hacks-MQTT/HEAD/bin/mosquitto_sub.bin -------------------------------------------------------------------------------- /lib/libmosquitto.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/g8keeperzuul/wz_mini_hacks-MQTT/HEAD/lib/libmosquitto.so.1 -------------------------------------------------------------------------------- /lib/libmosquittopp.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/g8keeperzuul/wz_mini_hacks-MQTT/HEAD/lib/libmosquittopp.so.1 -------------------------------------------------------------------------------- /bin/mosquitto_pub: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #LD_LIBRARY_PATH='/thirdlib:/system/lib:/system/sdcard/lib' 3 | #/system/sdcard/bin/mosquitto_pub.bin "$@" 4 | LD_LIBRARY_PATH='/thirdlib:/system/lib:/media/mmc/mosquitto/lib' 5 | /media/mmc/mosquitto/bin/mosquitto_pub.bin "$@" 6 | 7 | -------------------------------------------------------------------------------- /bin/mosquitto_sub: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #LD_LIBRARY_PATH='/thirdlib:/system/lib:/system/sdcard/lib' 3 | #/system/sdcard/bin/mosquitto_sub.bin "$@" 4 | LD_LIBRARY_PATH='/thirdlib:/system/lib:/media/mmc/mosquitto/lib' 5 | /media/mmc/mosquitto/bin/mosquitto_sub.bin "$@" 6 | 7 | -------------------------------------------------------------------------------- /installer/DOTuser_config: -------------------------------------------------------------------------------- 1 | [NET] 2 | bindOk=1 3 | p2pid= 4 | r_encr= 5 | 6 | [SETTING] 7 | indicator=1 8 | timezone=-5 9 | watermark_flag=2 10 | osdSwitch=2 11 | drawBoxSwitch=2 12 | recordType=3 13 | AST=2 14 | MASwitch=2 15 | AASwitch=2 16 | SASwitch=2 17 | CASwitch=2 18 | nightVision=3 19 | night_led_ex=2 20 | night_cut_thr=2 21 | NIGHT_LED_flag=1 22 | verSwitch=1 23 | horSwitch=1 24 | 25 | [CAMERA_INFO] 26 | TZ_STR= 27 | -------------------------------------------------------------------------------- /mosquitto.conf: -------------------------------------------------------------------------------- 1 | # Seconds between camera status updates via MQTT 2 | STATUSINTERVAL=60 3 | 4 | MQTT_BROKER_HOST=10.0.0.200 5 | MQTT_BROKER_PORT=1883 6 | MQTT_USERNAME=mqtt-user 7 | MQTT_PASSWORD=passw0rd 8 | 9 | MQTT_HA_TOPIC_BASE="homeassistant" 10 | 11 | MOSQUITTOOPTS="" 12 | 13 | MOSQUITTO_PUB_BIN=/media/mmc/mosquitto/bin/mosquitto_pub 14 | #MOSQUITTO_PUB_BIN="echo /media/mmc/mosquitto/bin/mosquitto_pub" 15 | #MOSQUITTOPUBOPTS="-r" 16 | MOSQUITTOPUBOPTS="" 17 | 18 | MOSQUITTO_SUB_BIN=/media/mmc/mosquitto/bin/mosquitto_sub 19 | MOSQUITTOSUBOPTS="" -------------------------------------------------------------------------------- /installer/S10httpd: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ### BEGIN INIT INFO 3 | # Provides: 4 | # Short-Description: Basic Web Server 5 | # Description: If enabled, start the httpd web server 6 | ### END INIT INFO 7 | 8 | . /opt/wz_mini/wz_mini.conf 9 | 10 | case "$1" in 11 | start) 12 | 13 | echo "#####$(basename "$0")#####" 14 | 15 | if [[ "$WEB_SERVER_ENABLED" == "true" ]]; then 16 | httpd -p 80 -h /opt/wz_mini/www 17 | echo "httpd enabled" 18 | fi 19 | ;; 20 | stop) 21 | pkill httpd 22 | ;; 23 | restart) 24 | $0 stop 25 | $0 start 26 | ;; 27 | *) 28 | echo "Usage: $0 {start|stop}" 29 | exit 1 30 | ;; 31 | esac 32 | 33 | -------------------------------------------------------------------------------- /installer/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Run from your device 4 | # This script will: 5 | # + overwrite /configs/.user_config iCamera settings with all default settings 6 | # + overwrite web server init script with a fixed version 7 | # + reboot the device for all the changes to take effect 8 | 9 | # overwrite iCamera settings new full, default version (backup the original) 10 | echo "Backing up and applying default iCamera settings (.user_config)..." 11 | mv /configs/.user_config /media/mmc/mosquitto/installer/.user_config.original 12 | cp /media/mmc/mosquitto/installer/DOTuser_config /configs/.user_config 13 | 14 | # fix web server init script (backup the original) 15 | echo "Updating httpd init script..." 16 | mv /opt/wz_mini/etc/network.d/S10httpd /media/mmc/mosquitto/installer/S10httpd.original 17 | cp /media/mmc/mosquitto/installer/S10httpd /opt/wz_mini/etc/network.d/ 18 | 19 | # add daemons for mqtt-status.sh and mqtt-control.sh 20 | echo "Setting up MQTT daemon..." 21 | cp /media/mmc/mosquitto/bin/mqtt-daemon.sh /opt/wz_mini/etc/rc.local.d/S50mqtt-daemon 22 | 23 | echo "Rebooting device..." 24 | reboot 25 | -------------------------------------------------------------------------------- /bin/mqtt-daemon.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | mkdaemon() { 4 | # dmon options 5 | # --stderr-redir Redirects stderr to the log file as well 6 | # --max-respawns Sets the number of times dmon will restart a failed process 7 | # --environ Sets an environment variable. Used to remove buffering on stdout 8 | # 9 | # dslog options 10 | # --priority The syslog priority. Set to DEBUG as these are just the stdout of the 11 | # --max-files The number of logs that will exist at once 12 | # 13 | max_respawns=$1 14 | shift 15 | daemon_name=$1 16 | shift 17 | dmon \ 18 | --stderr-redir \ 19 | --max-respawns $max_respawns \ 20 | --environ "LD_PRELOAD=libsetunbuf.so" \ 21 | $@ \ 22 | -- dslog \ 23 | --priority DEBUG \ 24 | --facility USER \ 25 | $daemon_name 26 | } 27 | 28 | case "$1" in 29 | start) 30 | echo "#####$(basename "$0")#####" 31 | mkdaemon 0 mqtt-autodiscovery /media/mmc/mosquitto/bin/mqtt-autodiscovery.sh 32 | mkdaemon 0 mqtt-control /media/mmc/mosquitto/bin/mqtt-control.sh 33 | mkdaemon 0 mqtt-status /media/mmc/mosquitto/bin/mqtt-status.sh 34 | ;; 35 | stop) 36 | echo "Stopping $(basename "$0")..." 37 | # mqtt-autodiscovery.sh is not a daemon; it just runs once-and-done. 38 | kill -s SIGTERM $(pgrep "mosquitto_sub|mqtt-status.sh|mqtt-control.sh") 39 | ;; 40 | restart) 41 | $0 stop 42 | $0 start 43 | ;; 44 | *) 45 | echo "Usage: $0 {start|stop|restart}" 46 | exit 1 47 | ;; 48 | esac 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Run from your localhost 4 | # This script will: 5 | # + ssh copy all the MQTT requirements to the Wyze Cam V3 (that already has wz_mini hacks installed) 6 | # + overwrite /configs/.user_config iCamera settings with all default settings 7 | # + overwrite web server init script with a fixed version 8 | 9 | if [ -z "$1" ]; then 10 | echo "Usage: $0 " 11 | echo "Example: $ $0 10.0.0.172" 12 | echo "Ensure to update mosquitto.conf with MQTT broker connection details and desired status update interval." 13 | exit 1 14 | fi 15 | WYZECAMV3_HOST=$1 16 | 17 | OPENSSH_VERSION=$(ssh -V 2>&1) 18 | TARGET_VERSION="OpenSSH_8.8" 19 | SCP_ARGS="" 20 | # OpenSSH 8.8 onward uses SFTP protocol by default, which is unsupported on wz_mini_hacks 21 | if printf '%s\n' "$TARGET_VERSION" "$OPENSSH_VERSION" | sort -V | head -n1 | grep -q "$TARGET_VERSION"; then 22 | SCP_ARGS="-O" 23 | fi 24 | 25 | echo "Uploading MQTT client to camera at ${WYZECAMV3_HOST}..." 26 | ssh root@${WYZECAMV3_HOST} 'mkdir -p /media/mmc/mosquitto/bin; mkdir -p /media/mmc/mosquitto/lib; mkdir -p /media/mmc/mosquitto/installer' 27 | scp ${SCP_ARGS} ./installer/* root@${WYZECAMV3_HOST}:/media/mmc/mosquitto/installer 28 | scp ${SCP_ARGS} ./bin/* root@${WYZECAMV3_HOST}:/media/mmc/mosquitto/bin 29 | scp ${SCP_ARGS} ./lib/* root@${WYZECAMV3_HOST}:/media/mmc/mosquitto/lib 30 | scp ${SCP_ARGS} mosquitto.conf root@${WYZECAMV3_HOST}:/media/mmc/mosquitto 31 | 32 | echo "Installing MQTT client on camera..." 33 | ssh root@${WYZECAMV3_HOST} '/media/mmc/mosquitto/installer/setup.sh' 34 | echo "Camera rebooting..." 35 | echo "You should see MQTT messages published when camera restarts." 36 | echo "Done" 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Adding MQTT Status and Control Integration to a wz_mini_hack Installed Camera 2 | 3 | This project adds [Home Assistant](https://home-assistant.io) integration via MQTT to Wyze Cam V3. 4 | 5 | ![Wyze Cam V3](wyze_cam_v3.jpg) 6 | 7 | The [Wyze Cam V3](https://www.wyze.com/products/wyze-cam?related_selling_plan=41618559008930) is an inexpensive and [pretty capable](https://fccid.io/2AUIUWYZEC3) little IP camera. Of course Wyze would have you sign up for a monthly subscription in order to be able to fully utilitize the camera. However, with the [wz_mini_hacks project](https://github.com/gtxaspec/wz_mini_hacks), you are able to add RTSP video streaming capabilities that can be constrained to your local network. Using a free network video recorder such as [Frigate](https://frigate.video/), you can record as much video has you have storage space. While the Wyze Cam V3 has motion and basic object detection capabilities, once you have local RTSP streaming enabled, you can essentially disable those device features, and leverage the more powerful equivalents through Frigate. 8 | 9 | The [Xiaomi-Dafang-Hacks project](https://github.com/EliasKotlyar/Xiaomi-Dafang-Hacks) added a comprehensive set of new capabilities via a firmware replacement for the older Wyze Cam V2 (Ingenic T20) models. What was great about this project was the Home Assistant integration via MQTT it provided. Unfortunately the Dafang-Hacks isn't compatible with the new Ingenic T31 based cameras such as the Wyze Cam V3. This project aims to provide the same Home Assistant MQTT integration to the V3 using the Dafang-Hacks project as inspiration. 10 | 11 | ![Home Assistant device Controls](mqtt-controls.png) 12 | ![Home Assistant device Diagnostic](mqtt-diagnostic.png) 13 | 14 | ## Prerequisites 15 | 1. [wz_mini_hacks project](https://github.com/gtxaspec/wz_mini_hacks) installed to a Wyze Cam V3 and completely setup so that it has wireless networking configured so you can ssh to the device. 16 | 2. Make sure you have defined CUSTOM_HOMENAME in /opt/wz_mini/wz_mini.conf (on camera) 17 | 18 | ## Steps 19 | 1. Determine the IP of the camera and verify that you can open a secure shell (ssh). Generally a good idea to ensure that this IP remains stable (either statically assigned or permanent DHCP lease) 20 | 2. Download this project and make your personal modifications to mosquitto.conf 21 | 3. Run install.sh \. This script will upload the MQTT client and custom Home Assistant integration scripts and binaries to the camera and run a camera-local setup script. The camera will automatically reboot when complete. 22 | 4. Verify you can see new MQTT messages on the broker. 23 | 5. Verify you can see a new camera device in Home Assistant. During the boot process, the camera will send Home Assistant compatible MQTT auto-discovery messages so that the camera should appear immediately in Home Assistant (under Settings \> Devices). 24 | 25 | ## Usage 26 | The base topic name is: 27 | 28 | `(mosquitto.conf:MQTT_HA_TOPIC_BASE)/camera/(wz_mini.conf:CUSTOM_HOSTNAME)/(see below)` 29 | 30 | For example: 31 | 32 | `homeassistant/camera/wyzec3_838c` 33 | 34 | Simply, to read state (MQTT subscribe): 35 | 36 | `[base topic]/some-feature/optional-sub-feature` 37 | 38 | To write state update (MQTT publish): 39 | 40 | `[base topic]/some-feature/optional-sub-feature/set` 41 | 42 | Reading camera configuration supported features: 43 | ``` 44 | /osd_time -> ON|OFF 45 | /leds/indicator -> ON|OFF 46 | /night_mode -> ON|OFF 47 | /night_mode/auto -> ON|OFF 48 | /night_mode/early_activation -> ON|OFF 49 | /leds/ir_near -> ON|OFF 50 | /leds/ir_far -> ON|OFF 51 | /flip_vert -> ON|OFF 52 | /flip_horz -> ON|OFF 53 | /refresh_rate -> [integer] 54 | /rtsp_server/port -> [integer] 55 | /rtsp_server/authentication -> ON|OFF 56 | /rtsp_server/channel1 -> ON|OFF 57 | /rtsp_server/channel1/audio -> ON|OFF 58 | /rtsp_server/channel1/fps -> [integer] 59 | /rtsp_server/channel1/url -> [url] 60 | /rtsp_server/channel2 -> ON|OFF 61 | /rtsp_server/channel2/audio -> ON|OFF 62 | /rtsp_server/channel2/fps -> [integer] 63 | /rtsp_server/channel2/url -> [url] 64 | /rtsp_server/channel1/bitrate_max -> [integer] 65 | /rtsp_server/channel2/bitrate_max -> [integer] 66 | /rtsp_server/channel1/bitrate_target -> [integer] 67 | /rtsp_server/channel2/bitrate_target -> [integer] 68 | /rtsp_server/channel1/enc_params -> [string] 69 | /rtsp_server/channel2/enc_params -> [string] 70 | /web_console -> ON|OFF 71 | /web_console/available -> ON|OFF (if httpd is running) 72 | 73 | /status --> [JSON string] 74 | { 75 | "last_boot": "2022-11-10 21:10:43", 76 | "ts": "2022-11-12T02:00:45+00:00", 77 | "ip": "10.0.0.172", 78 | "link_quality": 79, 79 | "signal_level": 60, 80 | "noise_level": 0, 81 | "bit_rate": "72.2 Mb/s", 82 | "device": { 83 | "name": "wyzec3_838c", 84 | "identifiers": "D0:3F:27:5D:83:8C", 85 | "mf": "Wyze", 86 | "mdl": "WYZE_CAKP2JFUS", 87 | "sw": "4.36.9.139" 88 | }} 89 | ``` 90 | Writing camera configuration supported features: 91 | ``` 92 | /leds/indicator/set ON|OFF 93 | /osd_time/set ON|OFF 94 | /night_mode/set ON|OFF 95 | /night_mode/auto/set ON|OFF 96 | /night_mode/early_activation/set ON|OFF 97 | /leds/ir_near/set ON|OFF 98 | /leds/ir_far/set ON|OFF 99 | /flip_vert/set ON|OFF 100 | /flip_horz/set ON|OFF 101 | /play [filename.wav] [volume_1-100] 102 | /web_console/set ON|true|OFF|false 103 | /refresh_rate/set [integer] 104 | ``` 105 | With the exception of playing a sound, updating the refresh rate and enabling or disabling the web console, ALL other changes in state require that the camera be rebooted before the change takes effect. This reboot is automatically done, but it does mean there is usually at least 5 seconds before the update takes effect. It also means that multiple update requests need to be spaced out with an appropriate delay to allow the camera to recycle before being able to accept the next request. Not ideal, but due to the limitations of the wz_mini_hack, the best we can do for now. 106 | 107 | To access other, less frequently used configuration parameters, enable the web_console (starts httpd, port 80), added by the wz_mini_hacks project. This provides access to a rudimentary form via the browser for modifying all the configuration parameters. It also needs to reboot the camera to have the changes applied. Since the web console is not secured (no authentication options), generally keep it disabled and use MQTT instead (assuming the broker has been secured). 108 | -------------------------------------------------------------------------------- /bin/mqtt-autodiscovery.sh: -------------------------------------------------------------------------------- 1 | #!/opt/wz_mini/bin/bash 2 | 3 | # same as /media/mmc/wz_mini/wz_mini.conf 4 | MASTER_CONFIG="/opt/wz_mini/wz_mini.conf" # needed for CUSTOM_HOSTNAME' 5 | MQTT_CONFIG="/media/mmc/mosquitto/mosquitto.conf" 6 | 7 | source ${MASTER_CONFIG} 8 | source ${MQTT_CONFIG} 9 | 10 | mqtt_publish(){ # $1 = /my/topic $2 = payload 11 | echo "MQTT publish $1 -> $2" 12 | # Note: all discovery messages are RETAINED 13 | ${MOSQUITTO_PUB_BIN} -h "${MQTT_BROKER_HOST}" -p "${MQTT_BROKER_PORT}" -u "${MQTT_USERNAME}" -P "${MQTT_PASSWORD}" -t "$1" ${MOSQUITTOPUBOPTS} ${MOSQUITTOOPTS} -r -m "$2" 14 | } 15 | 16 | DEVICE_MODEL=$(/opt/wz_mini/etc/init.d/s04model start | grep detected | cut -f1 -d ' ') 17 | FW_VER=$(tail -n1 /configs/app.ver | cut -f2 -d= ) 18 | MAC=$(ifconfig wlan0 | grep HWaddr | cut -d 'HW' -f2 | cut -d ' ' -f2) 19 | 20 | # Model after HA MQTT discovery device json 21 | # "device": { 22 | # "name": "Gas Monitor", 23 | # "identifiers": "98:CD:AC:D3:63:18", 24 | # "mf": "UnexpectedMaker", 25 | # "mdl": "TinyPICO", 26 | # "sw": "20221020.1300" 27 | # } 28 | DEVICE_JSON="{\"name\":\"${CUSTOM_HOSTNAME}\", \"ids\":\"${MAC}\", \"mf\":\"Wyze\", \"mdl\":\"${DEVICE_MODEL}\", \"sw\": \"${FW_VER}\"}" 29 | TOPIC_BASE="${MQTT_HA_TOPIC_BASE}/camera/${CUSTOM_HOSTNAME}" 30 | 31 | # https://www.home-assistant.io/integrations/mqtt/ 32 | # //[/]/config 33 | # homeassistant/switch|number|sensor/wyzec3_838c/