Wyze Cam: Difference between revisions
| Line 545: | Line 545: | ||
Note that the TZ_STR value is not what libc would expect. If you intend to set the TZ value in Linux as an environment variable, you need to convert the hour-minute values in the first field to be separated by a colon. For example, MST+0700MDT+0600 should instead be MST7:00MDT6:00 or MST7MDT6. In my case, the TZ value should be: <code>TZ=MST7:00MDT6:00,M3.2.0/02:00:00,M11.1.0/02:00:00</code> | Note that the TZ_STR value is not what libc would expect. If you intend to set the TZ value in Linux as an environment variable, you need to convert the hour-minute values in the first field to be separated by a colon. For example, MST+0700MDT+0600 should instead be MST7:00MDT6:00 or MST7MDT6. In my case, the TZ value should be: <code>TZ=MST7:00MDT6:00,M3.2.0/02:00:00,M11.1.0/02:00:00</code> | ||
==== | ==== iCamera Logs ==== | ||
To see the <code>iCamera</code> output, you'll have to restart <code>iCamera</code> in the foreground. This can be done by running <code>kill -9 $(pgrep iCamera)</code> and then immediately calling <code>/usr/bin/iCamera</code>. There is a hardware watchdog that needs to be satisfied or else the hardware will automatically reset. As a result, you'll have to make sure you start iCamera within 10 or so seconds. | |||
For the RTSP firmware, you'll have to also kill the <code>liveMediaServer</code> for <code>iCamera</code> to come up properly. Run: <code>kill -9 $(pgrep iCamera.patch) ; kill -9 $(pgrep liveMediaServer)</code> | |||
For the wz_mini_hacks, start iCamera with: <code>LD_PRELOAD=libsetunbuf.so /opt/wz_mini/usr/bin/iCamera -- dslog --priority DEBUG --facility USER iCamera</code> | |||
==Wyze Cam v2== | ==Wyze Cam v2== | ||
Revision as of 06:20, 16 September 2022
Wyze Cams are cheap wireless network cameras by Wyze Labs.
Wyze Cam v3
The Wyze Cam v3 is Wyze Lab's newest IP camera released in late 2020. It improves on the v2 with better night vision, higher FPS (15fps to 20fps for day / 10fps to 15fps for night), and is now better weather-proof by being able to operate between -20°C and 40°C. I have 2 Wyze Cams outdoors and exposed to the elements for the entirety of winter 2021-2022 and they're still working without any issues. However, the camera that faces west and is in direct sunlight appears to have a small fracture in its lens but doesn't appear to greatly affect the image quality.
Because the v3 uses the Ingenic T31 chip with secure boot enabled, you cannot load a modified firmware file (demo.bin) on the SD card as you could with the Wyze Cam v2. Rather, you need to rely on other approaches to modifying the firmware such as with WyzeHack's OTA update method or by exploiting the fact that uboot attempts to load a file from the SD card called factory_t31_ZMC6tiIDQN which can then be used to sideload hacks.[1]
RTSP streaming and firmware hacks
Real-time Streaming Protocol (RTSP) support exposes the camera's live video feed via the RTSP protocol. This is typically useful if you want to watch your camera (such as with VLC or MPC-HC), use some sort of network video recording (NVR), or use some sort of motion monitoring/recording system (like with Kerberos.io or Frigate).
As of 2022, the only official support for RTSP by Wyze Labs is an old beta version of the RTSP firmware (4.61.0.1). Their official statement is this firmware is not supported and recommends against using it. You may still download the firmware and flash it and the Wyze App still allows you to enable RTSP with this firmware version installed.
Here are some alternatives to the unsupported RTSP beta firmware. These hacks work with the latest official firmware released by Wyze. These methods may be preferable to the beta firmware simply because they're more up to date with known vulnerabilities being patched.
- Use the wyze-bridge docker stack to stream the video data from the Wyze cloud to a local RTMP server. This requires no changes to the firmware on the camera but wastes lots of internet bandwidth as the video feed is constantly uploaded (and downloaded if you're recording it locally). See: https://github.com/mrlt8/docker-wyze-bridge
- Use wz_mini_hacks project which is new as of 2022. This project takes the WyzeHacks work a little further and adds additional features. Thsi hack allows the camera to transmit its video feed to a remote RTMP server directly. Installation also involves using a SD card only. See: https://github.com/gtxaspec/wz_mini_hacks
- (Old and unsupported now) Use the WyzeHacks project to expose a video stream on your camera which can be transmitted to a local RTMP server using an externally running ffmpeg process. See: https://github.com/HclX/WyzeHacks
Wyze-bridge
Use the wyze-bridge docker stack available at https://github.com/mrlt8/docker-wyze-bridge. This will set up a container that will retrieve live video data from the Wyze cloud using your Wyze credentials and create a RTMP stream which is then pushed to a RTSP server running in another container. The end result is a local RTSP server that broadcasts your Wyze Cam.
The downside to this approach is that the video data is constantly streamed from your Wyze Cam to the cloud and then subsequently downloaded from the cloud to your local RTSP server. This introduces latency and uses lots of bandwidth. My testing with a relatively quiet video feed shows the camera uploading at around 100kb/s which would result in approximately 250GB being uploaded and an additional 250GB downloaded per month.
wz_mini_hacks
wz_mini_hacks is a collection of neat hacks that bundles a bunch of features. You may find it at https://github.com/gtxaspec/wz_mini_hacks. wz_mini_hacks side loads hacks to the official firmware using a SD card as part of the camera's boot process. This hack is completely reversible by either removing the SD card or removing the factory image that's loaded (factory_t31_ZMC6tiIDQN), since nothing is changed on the camera's flash memory itself.
To install the hack, it's suggested that you update to the latest supported version (4.36.9.139), though any versions from around this time frame should be compatible as they all use the same kernel version. If the install process doesn't work, try upgrading your firmware in the Wyze App or by manually reflashing the firmware. Next, copy the contents of the SD_ROOT directory to a FAT formatted SD card. Insert the SD card into the camera and power it on.
To get RTSP working, you will then need to edit the file wz_mini/wz_mini.conf file and enable the RTSP options. Eg:
RTSP_LOGIN="admin"
RTSP_PASSWORD="wyzecam"
RTSP_PORT="8554"
RTSP_HI_RES_ENABLED="true"
RTSP_HI_RES_ENABLE_AUDIO="true"
RTSP_HI_RES_FPS="15"
RTSP_HI_RES_MAX_BITRATE="2048"
RTSP_HI_RES_TARGET_BITRATE="1024"
RTSP_HI_RES_ENC_PARAMETER="2"
If you want the Wyze Cam to also push its video stream to a remote RTMP server, you can use the RTMP_STREAM_ENABLED options. However, this option only supports a few specific services such as YouTube, Twitch, and Facebook (based on the source code on the rtmp-stream.sh script). If you need to push it to a custom RTMP server, you will have to edit this script.
There is a cmd command that sends commands to iCamera. To control the IR LEDs, you can run cmd irled on and cmd irled off.
Issues with wz_mini_hacks
RTSP Stream codec: I had issues pushing the RTSP stream to the aler9 rtsp-simple-server using the default ffmpeg options. Because the aler9 RTSP server only accepts H264 and AAC codecs only, and because the Wyze Cam RTSP stream is using H265 and PCM, the audio stream has to be reencoded to AAC using ffmpeg.
The issue however is that when using the default ffmpeg command from the wz_mini_hacks RTMP stream script which uses the AAC HE profile, the aler9 RTSP server will drop the connection, resulting in ffmpeg logging av_interleaved_write_frame(): Broken pipe before quitting. The only way to get this working is to not use the aac_he audio profile. The ffmpeg command that seems to work for me is this:
$ /opt/wz_mini/bin/ffmpeg \
-rtsp_transport udp -y -i rtsp://admin:password@0.0.0.0:8554/unicast \
-vcodec copy -f flv \
-c:a libfdk_aac -afterburner 1 -channels 1 -b:a 128k \
rtmp://rtsp-server:1935/v3f
Even with this tweak, the ffmpeg stream to the aler9 RTSP server is very unreliable and constantly breaks.
Solution - You can tweak the rtsp-simple-server configuration file to automatically stream from the Wyze Cam directly without needing ffmpeg. Edit the rtsp-simple-server.yml config file and add the following:
camera:
source: "rtsp://admin:wyzecam@10.1.1.30:8554/unicast"
sourceProtocol: tcp
Note that I use TCP for this stream. Using UDP causes a lot of smearing to occur on my network. Setting it to TCP seems to fix this for the most part.
SSH not starting: For some reason, the SSH service (dropbear) doesn't start. This seems to only happen when I reboot the device and works again after I go in and delete some empty directories on the root of the SD card. Possibly corrupt FAT causing something to not work which gets fixed when I plug it into my computer?
Power cycling the Wyze Cam when it enters this state one more time seems to fix the issue. Could it be the SD cards I'm using needs a power cycle for it to show up properly to uboot?
WyzeHacks
Unsupported
WyzeHacks hasn't been updated for over a year and Wyze Labs has recently required newer firmware versions to be used by the cameras. As a result, this method is likely not viable anymore. See the wz_mini_hacks option below as an alternative.Thanks to the work by the authors of the WyzeHacks project (https://github.com/HclX/WyzeHacks) and its modified version by FiveLeavesLeft with the streaming support available (https://github.com/FiveLeavesLeft/WyzeHacks), you can stream video data directly from the camera without needing to download the data from the cloud as is the case with the wyze-bridge option. The hack sets up a h264 video stream on the Wyze cam (the file utility reports the data as a JVT NAL sequence) that need to be converted using ffmpeg and sent to the RTSP server.
To get this working:
- Load FiveLeavesLeft's version of WyzeHacks onto the Wyze Cam. More information on installing the hack is below. This method requires your Wyze credentials and works over the air without needing physical access to the device or the SD card. More in the WyzeHacks section below.
- Start a local RTMP server. Easiest thing to do is just run the RTSP server container with the following
docker-composestack. Create a docker-compose.yml file with the following contents. Replace the IP addresses as required. Add/remove the ffmpeg conversion containers as required. Make sure you are publishing to a unique path on the RTSP server.Place the contents in aversion: '3' services: rtsp-server: container_name: rtsp-server image: aler9/rtsp-simple-server environment: - RTSP_PROTOCOLS=tcp ports: - "10.1.1.Y:1935:1935" - "10.1.1.Y:8554:8554" - "10.1.1.Y:8888:8888" wyzecam-v2: image: registry.steamr.com/docker/alpine-ffmpeg:latest command: ["sh", "-c", "wget -q -O - 10.1.3.X:12345/ | ffmpeg -f h264 -i - -tune zerolatency -vcodec copy -f flv rtmp://rtsp-server:1935/v2"] restart: "always" wyzecam-v3: image: registry.steamr.com/docker/alpine-ffmpeg:latest command: ["sh", "-c", "wget -q -O - 10.1.3.X:12345/ | ffmpeg -f h264 -i - -tune zerolatency -vcodec copy -f flv rtmp://rtsp-server:1935/v3"] restart: "always"
docker-compose.ymlfile and then start up the stack withdocker-compose up -d. This should bring up both the RTSP server and the ffmpeg conversions for each camera. - If things are working right, you should be able to access the video feed at
rtsp://10.1.1.Y:8554/camera
I've used this hack on 4 Wyze Cam v3 devices and it works without any issues. The only limiting issue is that there is no audio with these streams since the video frames are retrieved using wget from an external server. Furthermore, there's no way to load this hack on newer units.
Remote access
Depending on which firmware hack you installed, you can connect to the Wyze Cam using either telnet or SSH.
The default username and password set on the Wyze Cam v3 is:
- Username:
root - Password:
WYom2020or, on newer firmwares:WYom20200(passwd hash isaVG8.5PMEOfnQ)
Firmware notes
Here are some notes on Wyze Cam v3 firmware.
Download older firmware files
You can download the firmware files from their servers at https://download.wyzecam.com/firmware/v3/. There is no directory listing, so you'll have to guess the filenames based on the firmware version numbers. The firmware versions are available from their release notes posted on their website at https://support.wyze.com/hc/en-us/articles/360024852172-Release-Notes-Firmware.
To help anyone who stumbles on this page, here are the links to some older versions:
How to downgrade firmware
To revert back to a specific firmware on the Wyze Cam, simply extract the .zip file into the root of a SD card. For the Wyze Cam v3, the firmware file should be named demo_wcv3.bin. Insert the SD card into the camera and then power it on while holding the setup button until both blue + red (appearing purple) LEDs are on.[2] The flashing process should take about a minute, though it will likely depend on the speed of your SD card.
As of January 2022, Wyze has restricted the ability to use certain older firmware versions[3] and is forcing users to use an updated Wyze app. I'm unsure what the minimum Wyze Cam version is, though I was able to roll back to 4.36.2.5 without issue.
Side loading hacks
The firmware files for the v3 are signed and verified using ed25519. The signature is placed at the last 64 bytes of the demo.bin file and is checked by uboot.
However, uboot also checks for a file called factory_t31_ZMC6tiIDQN on the SD card and attempts to boot that as the kernel image without any signature verification. You can build a custom image using the instructions at https://github.com/gtxaspec/wz_mini_hacks/blob/master/documentation/developer_environment.md.
Running without internet
Newer versions of the firmware (4.36.2.5 or later?) requires a constant internet connection to function. On these newer firmware versions, the internal iCamera process will reboot the camera when it's unable to contact the Wyze's servers. The reboot happens within about a minute or so and basically renders the device unusable at this state. The reboot is triggered by iCamera, possibly at a kernel or hardware watchdog level because locking down the reboot command isn't sufficient and killing iCamera eventually triggers a reboot as well. Making the Wyze domains resolve to another server is also ineffective as it also triggers a reboot.
The old firmware versions (4.36.0.x ~ 4.36.2.5 including the RTSP beta firmware 4.61.0.1) does not have the issue and I have had no issues using the Wyze Cam on these older versions after placing it on a non-routable network which effectively blocks all internet traffic to the camera. However, the iCamera process will attempt to restart the wireless connection periodically which results in 4-5 second disconnects every minute or so. The camera is functional even with these short disconnections, but it will cause stuttering and dropped frames.
Fixing the WiFi dropouts in iCamera
The iCamera program appears to bring the WiFi interface down and up when it is unable to reach some servers including Wyze's API server and Google. After 3 retries, the process will bounce the WiFi interface, kill and restart the DHCP client and WPA supplicant processes, and rewrite the hosts and resolv.conf files. It is this bouncing that causes the brief 4-5 second disconnects.
Fortunately, tracing down where exactly in the binary that triggers this behavior within the iCamera binary is made easy with the verbose iCamera debug messages (with source filenames and line numbers!) combined with some strace outputs I collected from the process during these dropout periods. There is a function that handles the network setup which sets up the WiFi interface, obtains an IP from DHCP, then attempts to check whether a domain works (DN something in the logs). When the domain check fails 3 times, it calls a few other functions to restart the network setup process over again.
The dropouts can be 'fixed' by overwriting the domain check with no-ops and ensuring that the retry loop never exits by no-opping out the decrement or store instructions. This will make iCamera retry the domain check rather than bouncing the network interface after 3 tries. There are other jobs that spawn via threadpool messages such as to validate the network (net-valid) and to uploading reboot log (upload-rebootlog). There are other calls to functions that send messages to a dongle (probably some other Wyze peripheral?). All these can be no-op'ed and be bypassed.
Here's the patch I came up with for 4.61.0.1. You can run this directly on the Wyze Cam and then reboot to apply. To revert, copy the original copy of iCamera script from SD_ROOT/wz_mini/usr/bin/iCamera onto your SD card.
#!/bin/sh
set -e
cd /tmp
# Make a copy to patch
cp /system/bin/iCamera iCamera
MD5Sum=$(md5sum iCamera | awk '{print $1}')
if [[ "$MD5Sum" != "04b90d6d77be72a4dd8c18da4b31946a" ]] ; then
echo "This patch is for iCamera in firmware 4.61.0.1"
exit 1
fi
# Patch out the calls to test cloud url, which calls that DN function
# This isn't strictly necessary, though it will cause iCamera to constantly retry the tests and spam the iCamera outputs with messages like
# DN:854]err: (getaddrinfo) fail:-2(Name or service not known), (domain: www.google.com
# so we'll comment these calls here to make it hush up
function patch_out_calls_to_test_cloud_url() {
for i in 0x603b0 0x602d4 ; do
echo "Original at $i"
dd if=iCamera bs=1 count=4 skip=$(($i)) 2>/dev/null | xxd
echo "Patched"
printf '\x00\x00\x00\x00' | dd conv=notrunc of=iCamera bs=1 seek=$(($i)) 2> /dev/null
dd if=iCamera bs=1 count=4 skip=$(($i)) 2>/dev/null | xxd
done
}
# Patch out the threadpool_add_job calls for net-valid and upload-rebootlog, and dongle send
function patch_out_jobs_after_connect () {
# Everything up until the last branch instruction
for i in $(seq 0x0070d0 4 0x07114) ; do
echo "Original at $i"
dd if=iCamera bs=1 count=4 skip=$(($i)) 2>/dev/null | xxd
echo "Patched"
# noop
printf '\x00\x00\x00\x00' | dd conv=notrunc of=iCamera bs=1 seek=$(($i)) 2> /dev/null
dd if=iCamera bs=1 count=4 skip=$(($i)) 2>/dev/null | xxd
done
}
# When our calls to DN check cloud url fails, we run into the code that calls funky_network_function(0). We don't want that. So noop all this out
# All the code that sets DAT_005e4d54=0, prints debug message, and calls funky_network_func(0) is nooped out here.
# This fixes the network from going back to the idle state and bouncing everything
function patch_out_network_reset_to_idle () {
for i in $(seq 0x006041c 4 0x06045c) ; do
echo "Original at $i"
dd if=iCamera bs=1 count=4 skip=$(($i)) 2>/dev/null | xxd
echo "Patched"
# noop
printf '\x00\x00\x00\x00' | dd conv=notrunc of=iCamera bs=1 seek=$(($i)) 2> /dev/null
dd if=iCamera bs=1 count=4 skip=$(($i)) 2>/dev/null | xxd
done
}
patch_out_calls_to_test_cloud_url
patch_out_jobs_after_connect
patch_out_network_reset_to_idle
# Place it on the SD card
cp iCamera /opt/wz_mini/usr/bin/iCamera.patched
# Patch the iCamera script to use the patched executable
sed -i 's/\/system\/bin\/iCamera/\/opt\/wz_mini\/usr\/bin\/iCamera.patched/' /opt/wz_mini/usr/bin/iCamera
This patch isn't quite complete however. I notice that there are DNS lookups to api.wyzecam.com is still being made every 5-7 seconds. Since this is on an isolated network, it might not really matter.
Configuring iCamera without internet
Here are some tips for those that are attempting to run their Wyze Cam on an isolate network or on a network that blocks internet access to these cameras:
- Configure the DHCP server so its DNS server is invalid (we don't need to resolve anything, not even NTP)
- If the subnet has internet access, you can also configure the default gateway to a non-routable address to block it from accessing the internet.
- Without NTP, you can set the date/time by having a remote server connect in periodically to run the
datecommand to set the hardware clock. - If you need to change a camera setting that's controlled by the Wyze App, the
/configs/.user_configsfile might be of interest to you (more about this below).
You might be wondering why I don't allow NTP. I tried to let only NTP traffic through during my testing but the system clock was never set. I think iCamera gets stuck in some sort of loop when it's unable to contact the Wyze servers and never gets around to setting the system clock. Setting the clock manually via telnet/SSH works decently enough for my needs.
Some observations about the v3
After getting telnet access, here are some stuff about the v3 which might be of interest.
[root@WyzeCam-ED6A:~]# cat /proc/cpuinfo
system type : Swan
machine : Unknown
processor : 0
cpu model : Ingenic Xburst V0.0 FPU V0.0
BogoMIPS : 1391.00
wait instruction : yes
microsecond timers : no
tlb_entries : 32
extra interrupt vector : yes
hardware watchpoint : yes, count: 1, address/irw mask: [0x0fff]
isa : mips32r1
ASEs implemented :
shadow register sets : 1
kscratch registers : 7
core : 0
VCED exceptions : not available
VCEI exceptions : not available
Hardware : isvp
Serial : 00000000 00000000 00000000 00000000
## MTD partitions hard coded to cmdline
[root@WyzeCam-ED6A:~]# cat /proc/cmdline
console=ttyS1,115200n8 mem=96M@0x0 rmem=32M@0x6000000 init=/linuxrc rootfstype=squashfs root=/dev/mtdblock2 rw mtdparts=jz_sfc:256K(boot),1984K(kernel),3904K(rootfs),3904K(app),1984K(kback),3904K(aback),384K(cfg),64K(para)
The firmware version can be found in /system/bin/app.ver:
[root@WyzeCam-7419:system]# cat /system/bin/app.ver
[VER]
appver=4.36.0.280
MTD Partitions
There is a 16MB flash. The MTD partitions are coded into the cmdline: mtdparts=jz_sfc:256K(boot),1984K(kernel),3904K(rootfs),3904K(app),1984K(kback),3904K(aback),384K(cfg),64K(para)
On startup, we see the following kernel message.
# dmesg
[ 0.433992] 8 cmdlinepart partitions found on MTD device jz_sfc
[ 0.440116] Creating 8 MTD partitions on "jz_sfc":
[ 0.445056] 0x000000000000-0x000000040000 : "boot"
[ 0.450404] 0x000000040000-0x000000230000 : "kernel"
[ 0.455910] 0x000000230000-0x000000600000 : "rootfs"
[ 0.461366] 0x000000600000-0x0000009d0000 : "app"
[ 0.466624] 0x0000009d0000-0x000000bc0000 : "kback"
[ 0.472007] 0x000000bc0000-0x000000f90000 : "aback"
[ 0.477436] 0x000000f90000-0x000000ff0000 : "cfg"
[ 0.482645] 0x000000ff0000-0x000001000000 : "para"
cfgonmtdblock6is mountedrwas/configs.apponmtdblock3is mountedroas/system.rootfsonmtdblock2is mountedroas/.
Camera configuration
The local camera configuration is stored in /configs/.user_config. The file itself looks something like this:
[NET]
bindOk=1
p2pid=####################
r_encr=################
[SETTING]
night_cut_thr=1
nightVision=3
night_led_ex=2
NIGHT_LED_flag=2
verSwitch=2
horSwitch=2
indicator=1
watermark_flag=2
recordType=3
drawBoxSwitch=2
bitRate=120
timezone=-6
[CAMERA_INFO]
TZ_STR=MST+0700MDT+0600,M3.2.0/02:00:00,M11.1.0/02:00:00
Some setting keys are described below. This is an incomplete list and was what I found by looking at the /configs/.user_configs file after changing each setting in the Wyze App. You should be able to change the values in this file and restart iCamera for it to take effect.
| key | description | values |
|---|---|---|
nightVision
|
Enable IR | 1 = on, 2 = off, 3 = auto |
night_led_ex
|
IR type? | 1 = near, 2 = far |
night_cut_thr
|
IR threshold | 1 = 'dusk mode', 2 = 'dark mode' |
indicator
|
Camera LED status lights | 1 = on, 2 = off |
verSwitch
|
Flip vertically | 1 = no flip, 2 = flip |
horSwitch
|
Flip horizontally | 1 = no flip, 2 = flip |
osdSwitch
|
Show timestamp | 1 = show, 2 = hide |
watermark_flag
|
Show wyze logo | 1 = show, 2 = hide |
AST
|
Audio recording | 1 = on, 2 = off |
recordType
|
Record to SD card | 1 = continuous, 2 = events only, 3 = no recording |
MASwitch
|
Record when motion detected | 1 = enable, 2 = disable |
AASwitch
|
Record when audio detected | 1 = enable, 2 = disable |
SASwitch
|
Record when smoke alarm detected | 1 = enable, 2 = disable |
CASwitch
|
Record when CO alarm detected | 1 = enable, 2 = disable |
AMALevel
|
Sound detection sensitivity | 2 through 254, higher is more sensitive |
MMALevel
|
Motion detection sensitivity | 2 through 254, higher is more sensitive |
drawBoxSwitch
|
Draw the green boxes around objects | 1 = enable, 2 = disable |
There are other setting keys that can be found in the iCamera startup logs. See below:
<Reading> /configs/.user_config
[user_config.c:373][USER SET] [indicator ] [2]
[user_config.c:373][USER SET] [nightVision ] [3]
[user_config.c:373][USER SET] [bitRate ] [120]
[user_config.c:373][USER SET] [res ] [1]
[user_config.c:373][USER SET] [fps ] [20]
[user_config.c:373][USER SET] [horSwitch ] [2]
[user_config.c:373][USER SET] [verSwitch ] [2]
[user_config.c:373][USER SET] [osdSwitch ] [1]
[user_config.c:373][USER SET] [logSd ] [1]
[user_config.c:373][USER SET] [logUdisk ] [1]
[user_config.c:373][USER SET] [telntSwitch ] [2]
[user_config.c:373][USER SET] [recordType ] [3]
[user_config.c:373][USER SET] [MASwitch ] [2]
[user_config.c:373][USER SET] [MALevel ] [5]
[user_config.c:373][USER SET] [AASwitch ] [2]
[user_config.c:373][USER SET] [AALevel ] [5]
[user_config.c:373][USER SET] [SASwitch ] [2]
[user_config.c:373][USER SET] [CASwitch ] [2]
[user_config.c:373][USER SET] [TBStart ] [0]
[user_config.c:373][USER SET] [TBDuration ] [1440]
[user_config.c:373][USER SET] [drawBoxSwitch] [2]
[user_config.c:360]timezone value -6 read from config file
[timesync_utility.c:160]TZ file is set with UTC-06:00[user_config.c:373][USER SET] [timezone ] [-6]
[user_config.c:373][USER SET] [MMALevel ] [100]
[user_config.c:373][USER SET] [AMALevel ] [100]
[user_config.c:373][USER SET] [MAT ] [0]
[user_config.c:373][USER SET] [AST ] [1]
[user_config.c:373][USER SET] [motionTrack ] [2]
[user_config.c:373][USER SET] [motionCruisin] [2]
[user_config.c:373][USER SET] [AASX ] [25]
[user_config.c:373][USER SET] [AASY ] [25]
[user_config.c:373][USER SET] [AALX ] [50]
[user_config.c:373][USER SET] [AALY ] [50]
[user_config.c:373][USER SET] [motionbackvalue] [1]
[user_config.c:373][USER SET] [slide_x ] [0]
[user_config.c:373][USER SET] [slide_y ] [0]
[user_config.c:373][USER SET] [preset_x ] [0]
[user_config.c:373][USER SET] [preset_y ] [0]
[user_config.c:373][USER SET] [ubootflag ] [0]
[user_config.c:373][USER SET] [exposureModel] [0]
[user_config.c:373][USER SET] [limit_max_x ] [0]
[user_config.c:373][USER SET] [limit_min_x ] [0]
[user_config.c:373][USER SET] [limit_max_y ] [0]
[user_config.c:373][USER SET] [limit_min_y ] [0]
[user_config.c:373][USER SET] [motor_limit_flag] [0]
[user_config.c:373][USER SET] [resolution_select_flag] [1]
[user_config.c:373][USER SET] [low_bitrate_num] [30]
[user_config.c:373][USER SET] [watermark_flag] [2]
[user_config.c:373][USER SET] [speaker_vol ] [50]
[user_config.c:373][USER SET] [pir_alarm_switch] [0]
[user_config.c:373][USER SET] [NIGHT_LED_flag] [2]
[user_config.c:373][USER SET] [sdcard_exist ] [0]
[user_config.c:373][USER SET] [autoRecordNum] [0]
[user_config.c:373][USER SET] [autoRecordMem] [0]
[user_config.c:373][USER SET] [dongle_led ] [1]
[user_config.c:373][USER SET] [alarmDate ] [255]
[user_config.c:373][USER SET] [alarmInterval] [300]
[user_config.c:373][USER SET] [SDEVICE_ACTION] [0]
[user_config.c:373][USER SET] [voice_switch ] [2]
[user_config.c:373][USER SET] [voice_scene ] [1]
[user_config.c:373][USER SET] [auto_clarity ] [2]
[user_config.c:373][USER SET] [cmc_upload ] [1]
[user_config.c:373][USER SET] [p2p_log ] [2]
[user_config.c:373][USER SET] [night_led_ex ] [2]
[user_config.c:373][USER SET] [night_cut_thr] [1]
[user_config.c:373][USER SET] [slightEnable ] [1]
[user_config.c:373][USER SET] [slightMode ] [2]
[user_config.c:373][USER SET] [slightLowLight] [2]
[user_config.c:373][USER SET] [slightBright ] [255]
[user_config.c:373][USER SET] [hms_enable ] [0]
[user_config.c:373][USER SET] [hms_state ] [0]
[user_config.c:373][USER SET] [slightPreemptSw] [0]
[user_config.c:320]timezone string set to [MST+0700MDT+0600,M3.2.0/02:00:00,M11.1.0/02:00:00]
Note that the TZ_STR value is not what libc would expect. If you intend to set the TZ value in Linux as an environment variable, you need to convert the hour-minute values in the first field to be separated by a colon. For example, MST+0700MDT+0600 should instead be MST7:00MDT6:00 or MST7MDT6. In my case, the TZ value should be: TZ=MST7:00MDT6:00,M3.2.0/02:00:00,M11.1.0/02:00:00
iCamera Logs
To see the iCamera output, you'll have to restart iCamera in the foreground. This can be done by running kill -9 $(pgrep iCamera) and then immediately calling /usr/bin/iCamera. There is a hardware watchdog that needs to be satisfied or else the hardware will automatically reset. As a result, you'll have to make sure you start iCamera within 10 or so seconds.
For the RTSP firmware, you'll have to also kill the liveMediaServer for iCamera to come up properly. Run: kill -9 $(pgrep iCamera.patch) ; kill -9 $(pgrep liveMediaServer)
For the wz_mini_hacks, start iCamera with: LD_PRELOAD=libsetunbuf.so /opt/wz_mini/usr/bin/iCamera -- dslog --priority DEBUG --facility USER iCamera
Wyze Cam v2
There are two firmwares available to the v2:
- Dafang Hacks (https://github.com/EliasKotlyar/Xiaomi-Dafang-Hacks) - this is a hack that is loaded with the stock firmware and adds additional features. You may also use the WyzeHacks on the Wyze Cam v2 which allows enabling telnet access on the stock firmware.
- OpenMiko (https://github.com/openmiko/openmiko) - A drop in replacement for the stock firmware and allows you to use the v2 without needing Wyze's cloud services.
RTSP streaming
There is an official firmware with RTSP streaming support built in. However, you may also do the same RTSP streaming hacks with Wyse-bridge and WyzeHacks as I described on the Wyze Cam v3 section above as it works just the same.
I ended up using the WyzeHacks on the v2 even with the RTSP firmware because the RTSP stream was less stable than the hacked h264 stream. Follow the WyzeHacks instructions in the Hacks section below.
Telnet access
The default username and password set on the Wyze Cam v2 is:
- Username:
root - Password:
ismart12
Dafang Hacks
Clone the git repository at https://github.com/EliasKotlyar/Xiaomi-Dafang-Hacks. Format a new SD card with FAT32 and copy everything from firmware_mod to the root of the SD card. Edit config/wpa_supplicant.conf to look something like this:
# For more configuration option please see:
# https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
ap_scan=1
network={
ssid="wifi-network-ssid"
# Uncomment to connect to Hidden SSIDs
#scan_ssid=1
key_mgmt=WPA-PSK
pairwise=CCMP TKIP
group=CCMP TKIP WEP104 WEP40
psk="wpa-passphrase"
priority=2
}
The default username and password is root and ismart12.
NFS notes
NFS can be mounted with
# mount -t nfs -o port=2049,nolock,proto=tcp nas:/data/public /mnt
A JPEG can be captured with
# /system/sdcard/bin/getimage > output.jpg
A quick and dirty way of just capturing pictures every couple seconds would be to create /system/sdcard/config/userscripts/startup/record.sh with
#!/bin/sh
while true ; do
while true ; do
if mount | grep -q nfs ; then
break
fi
echo "Attempting to mount /mnt"
mount -t nfs -o port=2049,nolock,proto=tcp nas:/data/public /mnt
done
Dir="/mnt/wyzecam02/snapshots/`date +%Y%m/%d`"
if [ ! -d $Dir ] ; then
mkdir -p $Dir
fi
/system/sdcard/bin/getimage > $Dir/`date +%H%M%S`.jpg
sleep 2
done &
Hacks
Applying the WyzeHacks hack
This option no longer works without spoofing DNS
Wyze Labs has restricted the payload URL and you can no longer arbitrarily pass in a random payload. As a result, this method won't work.You may try to work around the problem by spoofing the DNS for s3-us-west-2.amazonaws.com and try updating the firmware using this URL: http://s3-us-west-2.amazonaws.com/wuv2/upgrade/WLPP1/firmware/1.2.0.80a.bin
But your mileage may vary in the future as Wyze continues to change the way their API works.
This issue is tracked at https://github.com/HclX/WyzeHacks/issues/132
WyzeHacks contains a series of scripts that push an upload payload via the SD card or over the air that enables additional features including telnet access. To get WyzeHacks working, you will need a Linux computer with Python on the same subnet as the Wyze Cams.
What I did to get the Wyze Cam v3 (and later v2) running telnet was:
- Clone the git repository as well as the WyzeUpdater repo
- Run
build.shon the root directory. This should generate a new release under thereleasedirectory. - Go into the latest release directory
cd ./release/release_0_5_06/. Execute thewyze_updater.pyscript. - If prompted, enter your Wyze credentials. If you get an invalid token error, remove the existing token by running
rm ~/.wyze_token. - Any cameras associated with your account should be visible. Update the desired camera.
- You will see the script wait and print lots of
...'s. You can exit out of it by hitting Ctrl-C since the script does nothing past this point. Note that the update is automatic past this point. The Wyze Cam should come back online automatically. For the v3, the update took a few minutes. For the v2, it was nearly instantaneous.
The console output should look something like this:
$ ./remote_install.sh
Found local config file, including into firmware update archive...
Upgrade/config.inc
Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: requests in /usr/lib/python3.9/site-packages (2.25.1)
Requirement already satisfied: idna<3,>=2.5 in /usr/lib/python3.9/site-packages (from requests) (2.10)
Requirement already satisfied: urllib3<1.27,>=1.21.1 in /usr/lib/python3.9/site-packages (from requests) (1.25.10)
Requirement already satisfied: chardet<5,>=3.0.2 in /usr/lib/python3.9/site-packages (from requests) (4.0.0)
INFO:root:Trying saved credentials from /home/leo/.wyze_token.
INFO:root:Checking device, mac=7C78B23AF941
Device type: Camera (WYZE_CAKP2JFUS)
Device name: v3b
Firmware version: 4.36.0.280
IP Address: 10.1.3.252
Pushing firmware to this device? [y/N]:y
INFO:root:Serving firmware file './firmware.bin' as 'http://s3-us-west-2.amazonaws.com/wuv2/upgrade/WLPP1/firmware/1.2.0.80a.bin', md5=7cde34dd8669101e0a93ae962109d0be
INFO:root:Checking device, mac=A4DA222C2591
Press Ctrl+C when all the updates are done...
.......^C
INFO:root:Stopping http server...
Troubleshooting
Broken pipe while updating
Initially, I had issues with the script where it kept on getting a Broken Pipe exception and then bailing out. This somehow solved itself after moving the laptop to another room, so it might be an issue with the network.
DNS spoofing
Recently, Wyze Labs have changed their API such that you can no longer set an arbitrary firmware URL. Attempting to do so will result in a RuntimeError: Request failed, error 3005:UnauthorizedOperation error. To work around this, you will need to:
- Spoof
s3-us-west-2.amazonaws.comto a local web server hosting your wyze hacks firmware file - Serve the firmware from this web server, so that the URL
http://s3-us-west-2.amazonaws.com/wuv2/upgrade/WLPP1/firmware/1.2.0.80a.binworks - Edit the wyze_updater.py script so that the URL is set to this specific URL by adding the following line:
url = build_url(args.addr, args.ssl, args.port)
url = "http://s3-us-west-2.amazonaws.com/wuv2/upgrade/WLPP1/firmware/1.2.0.80a.bin"
Ensure that the MD5 checksum the wyze_updater.py script shows matches the MD5 of the file that's being served. If it mismatches, the update will fail and the camera will simply reboot without any changes.