Merge branch 'gtxaspec:master' into master

This commit is contained in:
sideup66 2022-07-31 15:35:23 -04:00 committed by GitHub
commit 9297121a98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 1117 additions and 80 deletions

View File

@ -229,7 +229,11 @@ Note: In my testing, the micro-usb cables included with the various cameras do n
Remote Accessories:
When USB Direct connectivity is enabled, the camera will be unable to communicate with accessories. To enable remote spotlight accessory support, enable the following variable and set the IP Address of the host as follows:
When USB Direct connectivity is enabled, the camera will be unable to communicate with accessories. To enable remote usb accessory support, enable the following variable and set the IP Address of the host as follows:
Scenario: Spotlight accessory needs to be located away from the camera, yet we desire spotlight control from within the app and camera. Plug the Spotlight into the nearby router running linux. Configure variables as below on camera, and run socat on the router. The app will now detect the spotlight accessory, just as if it was plugged in to the camera directly!
```
REMOTE_SPOTLIGHT="true"
REMOTE_SPOTLIGHT_HOST="0.0.0.0"
@ -241,7 +245,7 @@ Then, run the following command on the host where the spotlight is attached to:
socat TCP4-LISTEN:9000,reuseaddr,fork /dev/ttyUSB0,raw,echo=0
```
Change ```/dev/ttyUSB0``` to whatever path your spotlight enumerated to if necessary. The camera will now be able to control the spotlight.
Change ```/dev/ttyUSB0``` to whatever path your accessory enumerated to if necessary. The camera will now be able to control the usb accessory.
---
@ -281,6 +285,7 @@ ENABLE_NFSv4="true"
```
---
RTSP streaming:
The RTSP server supports the two video streams provided by the camera, 1080p/360p (1296p/480p for the DB3). You can choose to enable a single stream of your choice, or both. Audio is also available. Set your login credentials here, server listening port, and the stream bitrate.
(ENC_PARAMETER variable accepts numbers only. 0=FIXQP, 1=CBR, 2=VBR, 4=CAPPED VBR, 8=CAPPED QUALITY. Currently only 2, 4, and 8 are working)
@ -303,7 +308,6 @@ RTSP_LOW_RES_MAX_BITRATE=""
RTSP_LOW_RES_TARGET_BITRATE=""
RTSP_LOW_RES_ENC_PARAMETER=""
RTSP_LOW_RES_FPS=""
```
the singular stream will be located at ```rtsp://login:password@IP_ADDRESS:8554/unicast```
multiple streams are located at ```rtsp://login:password@IP_ADDRESS:8554/video1_unicast``` and ```rtsp://login:password@IP_ADDRESS:8554/video2_unicast```
@ -342,6 +346,8 @@ Run a custom script:
CUSTOM_SCRIPT_PATH=""
```
Note: any executable files placed in `wz_mini/etc/rc.local.d` will be automatically run at boot time, irregardless of the custom script variable specified in the configuration.
---
RTMP Streaming:
@ -444,19 +450,25 @@ Enabled by default. These options control the WiFi Drivers. V2/V3 use the 8189
---
```
DISABLE_MOTOR="true"
```
Disable the movement capability on motorized devices. You will no longer be able to move the device from the mobile app, or command line. Best used to convert a motorized unit to fixed
---
```
ENABLE_FSCK_ON_BOOT="true"
```
run fsck.vfat on boot. This runs fsck.vfat, the FAT disk repair utility on the micro sd card, automatically repairing most issues, including corruption. Increases boot time. During the repair process, the LEDs on the camera will flash RED-off-BLUE-off-PURPLE-off to inform the user the repair program is running. Once the program has completed, the LED will switch to RED, resuming the normal boot process.
---
```
ENABLE_CAR_DRIVER="true"
```
Loads the appropriate driver for the car to function. On devices other than a V2 with the car firmware, the car may be controlled via `car_control.sh` on the command line. experimental!
@ -467,8 +479,25 @@ Loads the appropriate driver for the car to function. On devices other than a V
---
```
ENABLE_LOCAL_DNS="true"
```
Enables `dnsmasq`, a lightweight, local, caching DNS server on the camera. Fixes potential DNS flooding on the local network. Upstream DNS servers may be specified in `wz_mini/etc/resolv.dnsmasq`
---
```
WEB_SERVER_ENABLED="true"
```
Enables the local webserver, for configuration, car control, or to retreive an image snapshot via a web browser. Available at : `http://<ip>/` Thank you @virmaior!
---
## Latest Updates
* 07-25-22: Add dnsmasq local dns option in configuration to prevent dns flooding on local networks. Added web server capability for configuration and car control.
* 07-14-22: Add car compatability with normally unsupported devices.
* 07-13-22: Includes latest build of libcallback, better RTSP video and audio performance: fixed broken audio caused by motor_stop on T20 devices, fixed waitMotion errors. `cmd jpeg` currently still broken on T20 devices, updated scripts to account for changed. Some usage of `cmd` has changes, please see command output. Kernel & modules updated to prepare for H265 support on T31.
* 07-08-22: Added support for multiple custom scripts, simply create scripts ending in .sh in wz_mini/etc/rc.local.d. You can prefix them with numbers to order execution if desired.

View File

@ -16,6 +16,7 @@ echo "CAR: c: reverse right"
echo "CAR: x: all stop"
echo "CAR: h: headlight on/off"
echo "CAR: j: irled on/off"
echo "CAR: b: honk"
echo -e ""
echo "CAR: 1: quit ASAP!"
echo -e ""
@ -133,6 +134,12 @@ elif [ "$input" = "h" ]; then
elif [ "$input" = "j" ]; then
irled
elif [ "$input" = "x" ]; then
echo -ne "\xaa\x55\x43\x06\x29\x80\x80\x00\x02\x71" > /dev/ttyUSB0
elif [ "$input" = "b" ]; then
/opt/wz_mini/bin/cmd aplay /opt/wz_mini/usr/share/audio/honk.wav 70 > /dev/null 2>&1 &
elif [ "$input" = "1" ]; then
#exit
echo -ne "\xaa\x55\x43\x06\x29\x80\x80\x00\x02\x71" > /dev/ttyUSB0

Binary file not shown.

View File

@ -55,6 +55,8 @@ cp /system/bin/app.ver /opt/wz_mini/tmp/log_gather/system_app.ver
echo "gather mmc info"
cat /sys/bus/mmc/devices/mmc1\:0001/mmc1\:0001\:1/* > /opt/wz_mini/tmp/log_gather/mmc_sys.log
echo "gather lsusb"
lsusb > /opt/wz_mini/tmp/log_gather/lsusb.log
if [ -f /tmp/sd_check_result.txt ]; then
echo "copy sd_check_result.txt"

View File

@ -0,0 +1,3 @@
#!/bin/sh
nano /opt/wz_mini/wz_mini.conf

View File

@ -8,8 +8,10 @@ domain-needed
bogus-priv
dns-forward-max=150
cache-size=1000
min-cache-ttl=86400
neg-ttl=3600
no-poll
resolv-file=/opt/wz_mini/etc/resolv.dnsmasq
addn-hosts=/opt/wz_mini/etc/hosts
#log-facility=-
#log-queries

View File

@ -0,0 +1 @@
127.0.0.1 localhost

View File

@ -48,14 +48,58 @@ wait_wlan() {
##Check if the driver has been loaded for the onboard wlan0, store the MAC.
while true
do
if ifconfig wlan0 | grep "inet addr"; then
store_mac
break
elif ifconfig wlan0 | grep "inet addr" && [[ "$ENABLE_USB_ETH" == "true" || "$ENABLE_USB_DIRECT" == "true" ]]; then
if ifconfig wlan0 | grep "HWaddr"; then
echo "wlan0 hwaddr is up"
store_mac
break
else
echo "wlan0 hwaddr not ready yet..."
sleep 5
fi
echo " wlan0 not ready yet..."
done
}
wpa_check() {
##Check if wpa_supplicant has been created by iCamera
if [ -e /tmp/wpa_supplicant.conf ]; then
wait_wlan
echo "wpa_supplicant.conf ready"
else
echo "wpa_supplicant.conf not ready, wait some time for creation."
COUNT=0
ATTEMPTS=15
until [[ -e /tmp/wpa_supplicant.conf ]] || [[ $COUNT -eq $ATTEMPTS ]]; do
echo -e "$(( COUNT++ ))... \c"
sleep 5
wpa_check
done
if [[ $COUNT -eq $ATTEMPTS ]]; then
echo "time exceeded waiting for iCamera, continue potentially broken condition without network."
fi
fi
}
wlanold_check() {
#Have we renamed interfaces yet?
if [ -d /sys/class/net/wlanold ]; then
echo "wlanold exist"
eth_wlan_up
else
echo "wlanold doesn't exist"
if [[ "$BONDING_ENABLED" == "true" ]] && ([[ "$ENABLE_USB_ETH" == "true" ]] || [[ "$ENABLE_USB_DIRECT" == "true" ]]); then
rename_interface_and_setup_bonding bond0 "$BONDING_PRIMARY_INTERFACE" "$BONDING_SECONDARY_INTERFACE"
else
rename_interface $1
fi
fi
}
netloop() {
##While loop for check
while true
do
wlanold_check $1
echo "wlan0 not ready yet..."
sleep 5
done
}
@ -166,48 +210,6 @@ eth_wlan_up() {
break
}
wpa_check() {
#Check if wpa_supplicant has been created by iCamera
if [ -e /tmp/wpa_supplicant.conf ]; then
echo "wpa_supplicant.conf ready"
wlanold_check $1
else
echo "wpa_supplicant.conf not ready, wait some time for creation."
COUNT=0
ATTEMPTS=15
until [[ -e /tmp/wpa_supplicant.conf ]] || [[ $COUNT -eq $ATTEMPTS ]]; do
echo -e "$(( COUNT++ ))... \c"
sleep 5
done
[[ $COUNT -eq $ATTEMPTS ]] && echo "time exceeded waiting for iCamera, continue potentially broken condition without network." && wlanold_check $1
fi
}
wlanold_check() {
#Have we renamed interfaces yet?
if [ -d /sys/class/net/wlanold ]; then
echo "wlanold exist"
eth_wlan_up
else
echo "wlanold doesn't exist"
if [[ "$BONDING_ENABLED" == "true" ]] && ([[ "$ENABLE_USB_ETH" == "true" ]] || [[ "$ENABLE_USB_DIRECT" == "true" ]]); then
rename_interface_and_setup_bonding bond0 "$BONDING_PRIMARY_INTERFACE" "$BONDING_SECONDARY_INTERFACE"
else
rename_interface $1
fi
fi
}
netloop() {
##While loop for check
while true
do
wpa_check $1
echo "wlan0 not ready yet..."
sleep 5
done
}
swap_enable() {
if [ -e /opt/wz_mini/swap ]; then
echo "Swap file exists"
@ -249,7 +251,7 @@ done
}
first_run_check
wait_wlan
wpa_check
#Set module dir depending on platform
if [ -f /opt/wz_mini/tmp/.T20 ]; then
@ -383,13 +385,8 @@ if [[ "$ENABLE_USB_DIRECT" == "true" ]]; then
swap_enable
#loop begin
while true
do
wpa_check usb0
echo "wlan0 not ready yet..."
sleep 1
done
netloop usb0
else
echo "USB Direct disabled"
fi
@ -407,13 +404,8 @@ if [[ "$ENABLE_USB_RNDIS" == "true" ]]; then
swap_enable
#loop begin
while true
do
wpa_check usb0
echo "wlan0 not ready yet..."
sleep 1
done
netloop usb0
fi
else
echo "usb rndis disabled"
@ -593,6 +585,16 @@ if [[ "$NIGHT_DROP_DISABLE" == "true" ]]; then
touch /opt/wz_mini/tmp/.nd
fi
if [[ "$ENABLE_LOCAL_DNS" == "true" ]]; then
dnsmasq -C /opt/wz_mini/etc/dnsmasq.conf
rm -f /tmp/resolv.conf
cp /opt/wz_mini/etc/resolv.conf /tmp/resolv.conf
fi
if [[ "$WEB_SERVER_ENABLED" == "true" ]]; then
httpd -p 80 -h /opt/wz_mini/www
fi
hostname_set
touch /opt/wz_mini/tmp/.wz_user_firstrun
pkill -f dumpload #Kill dumpload so it won't waste cpu or ram gathering cores and uploading them when something crashes

View File

@ -0,0 +1 @@
root:x:0:0:root:/opt/wz_mini/root:/bin/sh

View File

@ -0,0 +1 @@
nameserver 127.0.0.1

View File

@ -1,4 +1,4 @@
#List your desired upstream dns servers here
#nameserver 8.8.8.8
#nameserver 8.8.4.4
nameserver 1.1.1.1
nameserver 1.0.0.1

View File

@ -92,6 +92,7 @@ NIGHT_DROP_DISABLE="false"
DISABLE_MOTOR="false"
ENABLE_FSCK_ON_BOOT="false"
ENABLE_CAR_DRIVER="false"
ENABLE_LOCAL_DNS="false"
#####DEBUG#####
#drops you to a shell via serial, doesn't load app_init.sh
@ -99,5 +100,8 @@ DEBUG_ENABLED="false"
DEBUG_INITRAMFS_ENABLED="false"
DEBUG_PASSWORD="false"
####WEB####
WEB_SERVER_ENABLED="false"
#####SCRIPTING#####
CUSTOM_SCRIPT_PATH=""

View File

@ -1 +1 @@
Fri Jul 15 11:46:04 AM PDT 2022
Tue Jul 26 07:57:02 AM PDT 2022

Binary file not shown.

View File

@ -0,0 +1,31 @@
.wz_car_BUTTON {
background-color: #4CAF50; /* Green */
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
}
.wz_car_BUTTON_N {
background-color: #4CAF50; /* Green */
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
margin: 4px 2px;
cursor: pointer;
}
.wz_car_TABLE {
width: 55%;
border-collapse: collapse;
float: left;
}

View File

@ -0,0 +1,57 @@
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script type="text/javascript" src="car.js"></script>
<link rel="stylesheet" href="car.css">
</head>
<body>
<h2>wz_mini Car Control</h2>
<table class="wz_car_TABLE" border="1">
<tbody>
<tr style="height: 21px;">
<td style="width: 33.3333%; height: 21px; text-align: left;"><button id="forward_left" class="wz_car_BUTTON">q: forward left</button></td>
<td style="width: 33.3333%; height: 21px; text-align: center;"><button id="forward" class="wz_car_BUTTON">w: forward</button></td>
<td style="width: 33.3333%; height: 21px; text-align: right;"><button id="forward_right" class="wz_car_BUTTON">e: forward right</button></td>
</tr>
<tr style="height: 18px;">
<td style="width: 33.3333%; height: 18px; text-align: left;"><button id="left" class="wz_car_BUTTON">a; left</button></td>
<td style="width: 33.3333%; height: 18px; text-align: center;"><button id="reverse" class="wz_car_BUTTON">s: rear</button></td>
<td style="width: 33.3333%; height: 18px; text-align: right;"><button id="right" class="wz_car_BUTTON">d: right</button></td>
</tr>
<tr style="height: 18px;">
<td style="width: 33.3333%; height: 18px; text-align: left;"><button id="reverse_left" class="wz_car_BUTTON">z: rear left</button></td>
<td style="width: 33.3333%; height: 18px; text-align: center;"><button id="all_stop" class="wz_car_BUTTON">x: all stop</button></td>
<td style="width: 33.3333%; height: 18px; text-align: right;"><button id="reverse_right" class="wz_car_BUTTON">c: rear right</button></td>
</tr>
<td style="width: 33.3333%; height: 18px; text-align: center;">
<button id="headlight_on" class="wz_car_BUTTON_N">h: headlight on</button>
<button id="headlight_off" class="wz_car_BUTTON_N">g: headlight off</button>
</td>
<td style="width: 33.3333%; height: 18px; text-align: center;"><button id="irled_on" class="wz_car_BUTTON">j: ir led on</button><button id="irled_off" class="wz_car_BUTTON">k: ir led off</button></td>
<td style="width: 33.3333%; height: 18px; text-align: right;"><button id="honk" class="wz_car_BUTTON">b: honk</button></td>
</tr>
</tbody>
</table>
<p><img id="car_feed" src="/cgi-bin/jpeg.cgi?channel=1" /></p>
Speed Sleep: <input type="text" size=5 id="sleep_timer" name="sleep_timer" value="0.15">
Car Speed:
<input type="radio" id="speed_fast" class="speed" name="fast" value="fast">
<label for="fast">Fast</label>
<input type="radio" id="speed_slow" class="speed" name="slow" value="slow">
<label for="slow">Slow</label>
<button onclick="set_vars()">Set Variables</button>
</body>
</html>

View File

@ -0,0 +1,77 @@
const queryString = window.location.search;
console.log(queryString);
const urlParams = new URLSearchParams(queryString);
const speed = urlParams.get('speed')
console.log("speed is", speed);
const sleep_timer = urlParams.get('sleep_time')
console.log("sleep_timer is", sleep_timer);
function set_sleep() {
sleep_timer2 = document.getElementById("sleep_timer").value;
window.location = "car.html?sleep_time=" + sleep_timer2;
}
function set_vars() {
sleep_timer2 = document.getElementById("sleep_timer").value;
var speed = $('input[class="speed"]:checked').val();
window.location = "car.html?sleep_time=" + sleep_timer2 + "&speed=" + speed;
}
var wz_mini_car = {
post: function(action)
{
$.post( "../cgi-bin/car.sh", { speed: speed, action: action, sleep_time: sleep_timer } );
} ,
init: function() {
this.logarray = [];
$("[class*='BUTTON']").on('click',function(e) {
var action = $(this).attr('id');
wz_mini_car.post(action);
});
/* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch
switch is strict
*/
addEventListener("keydown", function (e) {
var action = false;
switch(e.key) {
case "w": action = "forward"; break;
case "s": action = "reverse"; break;
case "a": action = "left"; break;
case "d": action = "right"; break;
case "q": action = "forward_left" ; break;
case "e": action = "forward_right"; break;
case "z": action = "reverse_left"; break;
case "c": action = "reverse_right" ; break;
case "x": action = "all_stop" ; break;
case "h": action = "headlight_on" ; break;
case "g": action = "headlight_off" ; break;
case "j": action = "irled_on" ; break;
case "k": action = "irled_off" ; break;
case "b": action = "honk" ; break;
}
if (action) {
wz_mini_car.post(action);
}
});
},
log: function(text)
{
this.logarray.push(text);
}
}
$(document).ready(function() {
wz_mini_car.init();
});
setInterval(function() {
var myImageElement = document.getElementById('car_feed');
myImageElement.src = '/cgi-bin/jpeg.cgi?channel=1&rand=' + Math.random();
}, 1000);

View File

@ -0,0 +1,23 @@
Network Interface Bonding Support
BONDING_ENABLED="false"
BONDING_PRIMARY_INTERFACE="eth0"
BONDING_SECONDARY_INTERFACE="wlan0"
BONDING_LINK_MONITORING_FREQ_MS="100"
BONDING_DOWN_DELAY_MS="5000"
BONDING_UP_DELAY_MS="5000"
Bonding description is best described here: https://wiki.debian.org/Bonding#Configuration_-_Example_2_.28.22Laptop-Mode.22.29:
("Laptop-Mode")
Tie cable and wireless network interfaces (RJ45/WLAN) together to define a single, virtual (i.e. bonding) network interface (e.g. bond0). As long as the network cable is connected, its interface (e.g. eth0) is used for the network traffic. If you pull the RJ45-plug, ifenslave switches over to the wireless interface (e.g. wlan0) transparently, without any loss of network packages. After reconnecting the network cable, ifenslave switches back to eth0 ("failover mode"). From the outside (=network) view it doesn't matter which interface is active. The bonding device presents its own software-defined (i.e. virtual) MAC address, different from the hardware defined MACs of eth0 or wlan0. The dhcp server will use this MAC to assign an ip address to the bond0 device. So the computer has one unique ip address under which it can be identified. Without bonding each interface would have its own ip address. Currenly supported with ethernet adapters and usb-direct mode.
BONDING_PRIMARY_INTERFACE Specifies the interface that should be the primary. Typically "eth0".
BONDING_SECONDARY_INTERFACE Specifies the interface that should be the secondary. Typically "wlan0".
BONDING_LINK_MONITORING_FREQ_MS Specifies the MII link monitoring frequency in milliseconds. This determines how often the link state of each slave is inspected for link failures.
BONDING_DOWN_DELAY_MS Specifies the time, in milliseconds, to wait before disabling a slave after a link failure has been detected. This option is only valid for the miimon link monitor. The downdelay value should be a multiple of the miimon value; if not, it will be rounded down to the nearest multiple.
BONDING_UP_DELAY_MS Specifies the time, in milliseconds, to wait before enabling a slave after a link recovery has been detected. This option is only valid for the miimon link monitor. The updelay value should be a multiple of the miimon value; if not, it will be rounded down to the nearest multiple.

View File

@ -0,0 +1,4 @@
If a remote or app update is initiated, the camera will reboot due to the failure of the update. The firmware update should not proceed again for some time, or at all.
When a firmware update is initiated, due to a bootloader issue (bug?), we intercept the update process and flash it manually. This should now result in a successful update, if it doesn't, please restore the unit's firmware manually using demo_wcv3.bin on the micro sd card.

View File

@ -0,0 +1,4 @@
ENABLE_MP4_WRITE="false"
Forces the camera to skip writing files to /tmp, and write them directly to your storage medium or network mount, prevents trashing. Normally videos are written to /tmp then moved using mv, which can overload camera and or remote network connections. Useful for NFS/CIFS remote video storage.

View File

@ -0,0 +1,5 @@
the next time you boot your camera, make sure your USB cable is connected to the router. Remember, the camera has to be setup initially with Wi-Fi for this to work. After setup, Wi-Fi is no longer needed. Note that using USB Direct disables the onboard Wi-Fi. Change the MAC Address if you desire via USB_DIRECT_MAC_ADDR variable.
Connectivity is supported using a direct USB connection only... this means a single cable from the camera, to a supported host (An OpenWRT router, for example) that supports the usb-cdc-ncm specification. (NCM, not ECM) If you have an OpenWrt based router, install the kmod-usb-net-cdc-ncm package. The camera should automatically pull the IP from the router with most configurations. You can also use any modern linux distro to provide internet to the camera, provided it supports CDC_NCM. enjoy!
Note: In my testing, the micro-usb cables included with the various cameras do not pass data, so they will not work. Make sure you have a micro-usb cable that passes data!

View File

@ -0,0 +1,13 @@
USB Ethernet Adapter support:
ENABLE_USB_ETH="true"
ENABLE_USB_ETH_MODULE_AUTODETECT="true"
ENABLE_USB_ETH_MODULE_MANUAL=""
To have the Ethernet NIC be auto-detected and loaded automatically, set the ENABLE_USB_ETH_MODULE_AUTODETECT value to true.
To load a specific USB Ethernet NIC driver, set ENABLE_USB_ETH_MODULE_MANUAL to one of the following: asix, ax88179_178a, cdc_ether, r8152
NOTE: There is a possibility of a conflict between Ethernet NIC adapters that report themselves as PCI ID '0bda:8152'. (Realtek 8152 and CDC Ethernet) Since the 8152 is Realtek's product, that driver will be the one used for products that report that PCI ID. If you happen to have a CDC Ethernet product that uses that specific PCI ID, please set the ENABLE_USB_ETH_MODULE_AUTODETECT option to false, and set ENABLE_USB_ETH_MODULE_MANUAL to "cdc_ether"
The next time you boot your camera, make sure your USB Ethernet Adapter is connected to the camera and ethernet. The camera has to be setup initially with Wi-Fi for this to work. After setup, Wi-Fi is no longer needed, as long as you are using the USB Ethernet Adapter. Note that using USB Ethernet disables the onboard Wi-Fi.

View File

@ -0,0 +1,6 @@
USB Mass Storage Support:
ENABLE_USB_STORAGE="true"
If you would like to mount an EXT3/4 filesystem, also change:
ENABLE_EXT4="true"

View File

@ -0,0 +1,19 @@
Wireguard support is available as a kernel module:
ENABLE_WIREGUARD="true"
Use the command wg to setup. See https://www.wireguard.com/quickstart/ for more info.
Some users have asked about tailscale support, I have tested and it works. See the issue #30 for further information.
Example setup:
ENABLE_WIREGUARD="true"
WIREGUARD_IPV4="192.168.2.101/32"
WIREGUARD_PEER_ENDPOINT="x.x.x.x:51820"
WIREGUARD_PEER_PUBLIC_KEY="INSERT_PEER_PUBLIC_KEY_HERE"
WIREGUARD_PEER_ALLOWED_IPS="192.168.2.0/24"
WIREGUARD_PEER_KEEP_ALIVE="25"
To retrieve the public key that you'll need to add the peer to your wireguard endpoint:
Use SSH to log in
wg

View File

@ -0,0 +1,8 @@
When USB Direct connectivity is enabled, the camera will be unable to communicate with accessories. To enable remote spotlight accessory support, enable the following variable and set the IP Address of the host as follows:
REMOTE_SPOTLIGHT="true"
REMOTE_SPOTLIGHT_HOST="0.0.0.0"
Then, run the following command on the host where the spotlight is attached to:
socat TCP4-LISTEN:9000,reuseaddr,fork /dev/ttyUSB0,raw,echo=0
Change /dev/ttyUSB0 to whatever path your spotlight enumerated to if necessary. The camera will now be able to control the spotlight.

View File

@ -0,0 +1,10 @@
RTMP Streaming:
RTMP_STREAM_ENABLED="true"
RTMP_STREAM_FEED="video1_unicast"
RMTP_STREAM_SERVICE="youtube"
RTMP_STREAM_DISABLE_AUDIO="false"
RTMP_STREAM_YOUTUBE_KEY="xxx-xxx-xxx-xxx"
RTMP_STREAM_TWITCH_KEY=""
RTMP_STREAM_FACEBOOK_KEY=""
Live stream DIRECTLY from the camera's local RTSP server to: youtube / twitch / facebook live. Audio must be enabled in the RTSP section of the configuration for this to work.

View File

@ -0,0 +1,25 @@
RTSP streaming: The RTSP server supports the two video streams provided by the camera, 1080p/360p (1296p/480p for the DB3). You can choose to enable a single stream of your choice, or both. Audio is also available. Set your login credentials here, server listening port, and the stream bitrate. (ENC_PARAMETER variable accepts numbers only. 0=FIXQP, 1=CBR, 2=VBR, 4=CAPPED VBR, 8=CAPPED QUALITY. Currently only 2, 4, and 8 are working)
RTSP_LOGIN="admin"
RTSP_PASSWORD=""
RTSP_PORT="8554"
RTSP_HI_RES_ENABLED="true"
RTSP_HI_RES_ENABLE_AUDIO="true"
RTSP_HI_RES_MAX_BITRATE="2048"
RTSP_HI_RES_TARGET_BITRATE="1024"
RTSP_HI_RES_ENC_PARAMETER="2"
RTSP_HI_RES_FPS="15"
RTSP_LOW_RES_ENABLED="false"
RTSP_LOW_RES_ENABLE_AUDIO="false"
RTSP_LOW_RES_MAX_BITRATE=""
RTSP_LOW_RES_TARGET_BITRATE=""
RTSP_LOW_RES_ENC_PARAMETER=""
RTSP_LOW_RES_FPS=""
the singular stream will be located at rtsp://login:password@IP_ADDRESS:8554/unicast multiple streams are located at rtsp://login:password@IP_ADDRESS:8554/video1_unicast and rtsp://login:password@IP_ADDRESS:8554/video2_unicast
Note: If you don't set the password, the password will be set to the unique MAC address of the camera, in all uppercase, including the colons... for example:. AA:BB:CC:00:11:22. It's typically printed on the camera. Higher video bitrates may overload your Wi-Fi connection, so a wired connection is recommended.
Huge credit to @mnakada for his libcallback library: https://github.com/mnakada/atomcam_tools

View File

@ -0,0 +1,7 @@
Use as a USB Video Class (UVC) Web Camera for your PC is supported. I have tested with Windows 10, Linux, and Android TV, and it appears as a Generic HD Camera. Audio is supported. This mode disables all other functionality, and only works as a USB Web Camera for your PC. Experimental. Note that the cables typically included with the camera do not data, use a known working micro-usb cable which supports data.
Supported modes: MJPG,Video 360p/720p/1080p
WEB_CAM_ENABLE="true"
WEB_CAM_BIT_RATE="8000"
WEB_CAM_FPS_RATE="25"

View File

@ -0,0 +1,95 @@
#!/bin/sh
set -x
echo "HTTP/1.1 200"
echo -e "Content-type: text/html\n\n"
echo ""
read POST_STRING
SPEED=$(echo $POST_STRING | sed 's/.*speed=//;s/\&.*//')
ACTION=$(echo $POST_STRING | sed 's/.*action=//;s/\&.*//')
SLEEP_TIME=$(echo $POST_STRING | sed 's/.*sleep_time=//;s/\&.*//')
echo "raw post string: $POST_STRING"
echo "speed: $SPEED"
echo "action: $ACTION"
echo "sleep: $SLEEP_TIME"
if [ "$ACTION" = "forward" ]; then
if [ "$SPEED" = "slow" ]; then
echo "slow"
echo -ne "\xaa\x55\x43\x06\x29\x80\xca\x00\x02\xbb" > /dev/ttyUSB0
else
echo "forward"
echo -ne "\xaa\x55\x43\x06\x29\x80\xe3\x00\x02\xd4" > /dev/ttyUSB0
fi
sleep $SLEEP_TIME
echo -ne "\xaa\x55\x43\x06\x29\x80\x80\x00\x02\x71" > /dev/ttyUSB0
elif [ "$ACTION" = "reverse" ]; then
echo "reverse"
echo -ne "\xaa\x55\x43\x06\x29\x80\x36\x00\x02\x27" > /dev/ttyUSB0
sleep $SLEEP_TIME
echo -ne "\xaa\x55\x43\x06\x29\x80\x80\x00\x02\x71" > /dev/ttyUSB0
elif [ "$ACTION" = "left" ]; then
echo "left"
echo -ne "\xaa\x55\x43\x06\x29\x76\x81\x00\x02\x68" > /dev/ttyUSB0
sleep $SLEEP_TIME
echo -ne "\xaa\x55\x43\x06\x29\x80\x80\x00\x02\x71" > /dev/ttyUSB0
elif [ "$ACTION" = "right" ]; then
echo "right"
echo -ne "\xaa\x55\x43\x06\x29\x8a\x81\x00\x02\x7c" > /dev/ttyUSB0
sleep $SLEEP_TIME
echo -ne "\xaa\x55\x43\x06\x29\x80\x80\x00\x02\x71" > /dev/ttyUSB0
elif [ "$ACTION" = "forward_left" ]; then
echo "left_forward"
echo -ne "\xaa\x55\x43\x06\x29\x76\xe3\x00\x02\xca" > /dev/ttyUSB0
sleep $SLEEP_TIME
echo -ne "\xaa\x55\x43\x06\x29\x80\x80\x00\x02\x71" > /dev/ttyUSB0
elif [ "$ACTION" = "forward_right" ]; then
echo "right_forward"
echo -ne "\xaa\x55\x43\x06\x29\x8a\xe3\x00\x02\xde" > /dev/ttyUSB0
sleep $SLEEP_TIME
echo -ne "\xaa\x55\x43\x06\x29\x80\x80\x00\x02\x71" > /dev/ttyUSB0
elif [ "$ACTION" = "reverse_left" ]; then
echo "left_reverse"
echo -ne "\xaa\x55\x43\x06\x29\x76\x36\x00\x02\x1d" > /dev/ttyUSB0
sleep $SLEEP_TIME
echo -ne "\xaa\x55\x43\x06\x29\x80\x80\x00\x02\x71" > /dev/ttyUSB0
elif [ "$ACTION" = "reverse_right" ]; then
echo "right_reverse"
echo -ne "\xaa\x55\x43\x06\x29\x8a\x36\x00\x02\x31" > /dev/ttyUSB0
sleep $SLEEP_TIME
echo -ne "\xaa\x55\x43\x06\x29\x80\x80\x00\x02\x71" > /dev/ttyUSB0
elif [ "$ACTION" = "all_stop" ]; then
echo "all stop"
echo -ne "\xaa\x55\x43\x06\x29\x80\x80\x00\x02\x71" > /dev/ttyUSB0
elif [ "$ACTION" = "headlight_on" ]; then
echo "headlight_on"
echo -ne "\xaa\x55\x43\x04\x1e\x01\x01\x65" > /dev/ttyUSB0
elif [ "$ACTION" = "headlight_off" ]; then
echo "headlight_off"
echo -ne "\xaa\x55\x43\x04\x1e\x02\x01\x66" > /dev/ttyUSB0
elif [ "$ACTION" = "irled_on" ]; then
echo "irled_on"
cmd irled on > /dev/null
elif [ "$ACTION" = "irled_off" ]; then
echo "irled_off"
cmd irled off > /dev/null
elif [ "$ACTION" = "honk" ]; then
echo "honk"
/opt/wz_mini/bin/cmd aplay /opt/wz_mini/usr/share/audio/honk.wav 70 > /dev/null 2>&1 &
else
echo "no input"
fi

View File

@ -0,0 +1,290 @@
#!/bin/sh
# This serves a rudimentary webpage based on wz_mini.conf
base_dir=/opt/wz_mini/
base_hack_ini=/opt/wz_mini/wz_mini.conf
hack_ini=$base_hack_ini
www_dir=/opt/wz_mini/www/cgi-bin/
camver=V3
camfirmware=$(tail -n1 /configs/app.ver | cut -f2 -d= )
hackver=$(cat /opt/wz_mini/usr/bin/app.ver)
title="Wyze $camver on $camfirmware running wz_mini $hackver as $HOSTNAME"
updated=false
echo "HTTP/1.1 200"
echo -e "Content-type: text/html\n\n"
echo ""
reboot_camera() {
echo "rebooting camera (refreshing screen in 90 seconds)"
echo '<script type="text/javascript">setTimeout(function(){ document.location.reload (); },90 * 1000)</script>'
exit
}
shft() {
# SE loop did not work -- thanks ash!
suff=8
while [ "$suff" -gt 0 ] ;
do
if [[ -f "$1.$suff" ]] ; then
nxt=$((suff + 1))
mv -f "$1.$suff" "$1.$nxt"
fi
suff=$((suff-1))
done
mv -f "$1" "$1.1"
}
function revert_config
{
mv "$hack_ini" "$hack_ini.old"
mv "$hack_ini.$1" "$hack_ini"
}
function revert_menu
{
echo '<h2 id="revert" >Revert Menu</a>'
echo '<div class="old_configs">'
echo 'Prior Versions : '
xuff=0
while [ "$xuff" -lt 9 ] ;
do
xuff=$((xuff + 1))
if [[ -f "$1.$xuff" ]] ; then
filedate=$(date -r "$1.$xuff" )
class=""
if [ "$1.$xuff" = "$2" ];
then
class="current_revert"
fi
echo '<div class="revert_DIV '$class'"><div><a href="?action=show_revert&version='"$xuff"'">'"$xuff </a></div><div> $filedate</div></div>"
fi
done
echo '</div>'
}
function version_info
{
echo "<div id='$1'>"
echo "<div class='ver_DIV' vertype='Camera'>$camver</div>"
echo "<div class='ver_DIV' vertype='Camera Firmware'>$camfirmware</div>"
echo "<div class='ver_DIV' vertype='wz_mini'>$hackver</div>"
echo "<div class='ver_DIV' vertype='Hostname'> $HOSTNAME</div>"
echo "</div>"
}
if [[ $REQUEST_METHOD = 'GET' ]]; then
#since ash does not handle arrays we create variables using eval
IFS='&'
for PAIR in $QUERY_STRING
do
K=$(echo $PAIR | cut -f1 -d=)
VA=$(echo $PAIR | cut -f2 -d=)
eval GET_$K=$VA
done
if [[ "$GET_action" = "reboot" ]]; then
reboot_camera
fi
if [[ "$GET_action" = "revert" ]]; then
revert_config "$GET_version"
fi
if [[ "$GET_action" = "show_revert" ]]; then
hack_ini="$hack_ini.$GET_version"
fi
fi
#test for post
if [[ $REQUEST_METHOD = 'POST' ]]; then
if [ "$CONTENT_LENGTH" -gt 0 ]; then
read -n $CONTENT_LENGTH POST_DATA <&0
while read line
do eval "echo ${line}"
done
fi
#since ash does not handle arrays we create variables using eval
IFS='&'
for PAIR in $POST_DATA
do
K=$(echo $PAIR | cut -f1 -d=)
VA=$(echo $PAIR | cut -f2 -d=)
VB=\"${VA//%3A/:}\"
#echo "<div>$K=$VB</div>"
eval POST_$K=\"$VB\"
done
#switch back to going through the config file
output="$hack_ini.new"
#name our output file
while IFS= read -r \ARGUMENT; do
#cycle through each line of the current config
#copy through all comments
if [ -z "$ARGUMENT" ]; then
echo -ne "\n" >> $output
elif [[ ${ARGUMENT:0:1} == "#" ]] ; then
#echo $ARGUMENT $'\n'
echo -ne $ARGUMENT"\n" >> $output
else
#for non-comments check to see if we have an entry in the POST data by deciphering the key from the ini file and using eval for our fake array
KEY=$(echo $ARGUMENT | cut -f1 -d=)
test=$(eval echo \$POST_$KEY)
#echo "key was $KEY test was ... $test <br /> "
if [[ "$test" ]]; then
#if in the fake array then we use the new value
#echo "<div style=\"color:#c00\">matched </div>"
echo -ne $KEY=\"$test\""\n" >> $output
else
#if not in the fake array we use the current value
#echo "<div>key not found</div>"
echo -ne $ARGUMENT"\n" >> $output
fi
fi
done < $hack_ini
shft $hack_ini
mv $output $hack_ini
updated=true
fi
function documentation_to_html
{
if [[ -f "$www_dir$1.md" ]]; then
printf '<div class="ii_explain"><pre>'
cat "$web_dir$1.md"
printf '</pre></div>'
fi
}
function ini_to_html_free
{
classes=""
if [ "$1" = "USB_DIRECT_MAC_ADDR" ]; then
classes=" mac_addr"
fi
if grep -q -wi "$1" numerics.txt; then
classes=" numeric"
fi
printf '<div class="ii"><div class="ii_key_DIV">%s</div><div class="ii_value_DIV"><input class="ii_value'$classes'" type="text" name="%s" value="%s" /></div>' $1 $1 $2
documentation_to_html $1
printf '</div>'
}
function ini_to_html_tf
{
printf '<div class="ii"><div class="ii_key_DIV">%s</div>' $1
printf '<div class="ii_value_DIV">'
if [[ "$2" == "true" ]]; then
printf '<input class="ii_radio" type="radio" name="%s" value="true" checked="checked" /> True &nbsp;' $1
printf '<input class="ii_radio" type="radio" name="%s" value="false" /> False &nbsp;' $1
else
printf '<input class="ii_radio" type="radio" name="%s" value="true" /> True &nbsp;' $1
printf '<input class="ii_radio" type="radio" name="%s" value="false" checked="checked" /> False &nbsp;' $1
fi
printf '</div>'
documentation_to_html $1
printf '</div>'
}
#function to handle camera feed
function html_cam_feed
{
printf '<img id="current_feed" src="/cgi-bin/jpeg.cgi?channel=1" class="feed" />'
}
function handle_css
{
echo -ne "<style type=\"text/css\">"
cat config.css
echo -ne '</style>';
}
echo -ne "<html><head><title>$title</title>"
handle_css wz_mini_web.css
echo '<script type="text/javascript" src="/config.js" ></script>'
echo -ne "</head>"
echo -ne '<body>'
echo -ne "<h1>$title</h1>";
if [ "$updated" = true ];
then
echo '<div class="message_DIV">configuration file updated. <a href="?action=reboot">Reboot<a/> to use changes. Or <a href="#revert">Revert</a> to a prior configuration</div>';
fi
html_cam_feed
if [ $base_hack_ini != $hack_ini ]; then
echo '<div><a href="?action=revert&version='$GET_version'">Revert</a> to this version</a></div>'
fi
echo -ne '<form name="update_config" method="POST" enctype="application/x-www-form-urlencoded" >'
CONFIG_BLOCK=0
while IFS= read -r ARGUMENT; do
if [ -z "$ARGUMENT" ] ; then
echo -ne ""
elif [[ ${ARGUMENT:0:1} == "#" ]] ; then
if [[ ${ARGUMENT:0:4} == "####" ]]; then
if [ "$CONFIG_BLOCK" -gt 0 ]; then
echo '</div>'
fi
CONFIG_BLOCK=$((CONFIG_BLOCK + 1))
echo '<div class="ii_block" block_number="'$CONFIG_BLOCK'" >'
BTITLE=${ARGUMENT//#/ }
echo -ne '<div class="ii_block_name">'$BTITLE'</div>'
else
echo -ne '<div class="ii_info">'$ARGUMENT'</div>'
fi
else
KEY=$(echo $ARGUMENT | cut -f1 -d=)
VAL=$(echo $ARGUMENT | cut -f2 -d=)
VALUE=${VAL//\"/}
case "$VALUE" in
"true") ini_to_html_tf $KEY $VALUE ;;
"false") ini_to_html_tf $KEY $VALUE ;;
*) ini_to_html_free $KEY $VALUE
esac
fi
done < $hack_ini
if [ "$CONFIG_BLOCK" -gt 0 ]; then
echo '</div>'
fi
echo -ne '<input type="submit" name="update" value="Update" />'
echo -ne '</form>'
revert_menu $base_hack_ini $hack_ini
version_info "display_BAR"
echo -ne '</body></html>'

View File

@ -0,0 +1,145 @@
BODY {
--feed_ratio: 2.5;
--display_bar_height: 20px;
--border-color: #ccc;
padding-bottom: var(--display_bar_height);
}
H1 {
background-color:blue;
color:white;
height:calc(108px * (var(--feed_ratio) - 1));
margin-top:0;
padding:5px;
margin-bottom:108px;
width:calc(100% - (192px * var(--feed_ratio)));
}
.ii_block {
border:3px solid var(--border-color);
margin-bottom:5px;
padding:2px;
border-radius:3px;
}
.ii_block_name {
background-color:var(--border-color);
text-align:center;
font-weight:bold;
color:#fff;
margin:-2px;
margin-bottom:3px;
}
.ii_info {
color:#333;
}
.ii {
width:100%;
position:relative;
display:flex;
}
.ii_key_DIV {
flex:0 0 40vw;
font-weight:bold;
}
.ii_value_DIV {
flex: 0 0 40vw;
text-align:right;
}
.ii_value {
width:75%;
}
.feed {
position:absolute;
top:10px;
right:0px;
width:calc(192px * var(--feed_ratio));
height:calc(108px * var(--feed_ratio));
z-index:10;
}
.ii_explain {
height:25px;
overflow:hidden;
width:25px;
position:relative;
}
.ii_explain:hover {
height: auto;
position: absolute;
left: 10%;
width: 80%;
border-radius: 3px;
padding: 5px;
background-color: #ccc;
z-index: 10;
border: 3px solid blue;
font-family: monospace;
white-space:pre-wrap;
}
.ii_explain:hover PRE {
white-space:pre-wrap;
}
.ii_explain:hover:after {
content:"";
border:none;
margin:0;
padding:0;
width:0;
height:0;
}
.ii_explain:after {
color:white;
content:"?";
text-align:center;
background-color:blue;
border:2px solid #ccc;
border-radius:3px;
padding-left:2px;
padding-right:2px;
position:absolute;
left:0;
top:0;
width:100%;
height:100%;
}
.revert_DIV {
display:flex;
width:100%;
}
.revert_DIV DIV:nth-child(1) {
width:30px;
}
.current_revert {
background-color:#edf054;
}
#display_BAR {
position:fixed;
bottom:0;
background-color:blue;
border-top:1px solid lightblue;
color:#fff;
display:flex;
width:100%;
height:var(--display_bar_height);
}
#display_BAR DIV {
padding-right:15px;
}
.ver_DIV {
padding-left:60px;
min-width:120px;
font-family:monospace;
flex: 1 0 120px;
}
.ver_DIV:before {
content:attr(vertype);
font-weight:bold;
padding-right:10px;
}
.ver_DIV[vertype="wz_mini"] {
flex:1 0 400px;
}
.fail_val {
background-color:#fcc;
}

View File

@ -0,0 +1,29 @@
#!/bin/sh
#test for jpeg
if [[ $REQUEST_METHOD = 'GET' ]]; then
echo "entered GET"
#since ash does not handle arrays we create variables using eval
IFS='&'
for PAIR in $QUERY_STRING
do
K=$(echo $PAIR | cut -f1 -d=)
VA=$(echo $PAIR | cut -f2 -d=)
#VB=${VA//%3A/:}
#echo "<div>$K=$VA</div>"
eval GET_$K=$VA
done
fi
if [ -z "$GET_channel" ];
then
echo "X-Channel-Override: 0"
GET_channel=0
fi
echo "X-Channel: $GET_channel"
cmd jpeg "$GET_channel"

View File

@ -0,0 +1,8 @@
WEB_CAM_BIT_RATE
WEB_CAM_FPS_RATE
BONDING_LINK_MONITORING_FREQ_MS
BONDING_DOWN_DELAY_MS
BONDING_UP_DELAY_MS
RTSP_PORT
AUDIO_PROMPT_VOLUME

View File

@ -0,0 +1,59 @@
var feed_interval_frequency = 1000;
var mac_re = /^[0-9a-f]{1,2}([\.:-])(?:[0-9a-f]{1,2}\1){4}[0-9a-f]{1,2}$/mi;
// https://stackoverflow.com/questions/14636536/how-to-check-if-a-variable-is-an-integer-in-javascript#14794066
function isInt(value) {
return !isNaN(value) &&
parseInt(Number(value)) == value &&
!isNaN(parseInt(value, 10));
}
function scrollTop()
{
window.scrollTo({
top: 0,
behavior: "smooth"
});
}
window.onload = function()
{
var feed = document.getElementById("current_feed");
function update_image()
{
feed.src = feed.src.split("&")[0] + "&load=" + new Date().getTime();
}
feed_interval = setInterval(update_image, feed_interval_frequency);
document.querySelector('[name="update_config"]').addEventListener('submit',
function(e){
const mac_addrs = document.getElementsByClassName('mac_addr');
for (let i=0; i < mac_addrs.length; i++) {
mac_addrs[i].classList.remove("fail_val");
if (mac_addrs[i].value == "") { continue; }
if (!mac_re.test(mac_addrs[i].value)) {
mac_addrs[i].classList.add("fail_val");
scrollTop();
console.log("failed on mac address test for " + mac_addrs[i].name + " for value " + mac_addrs[i].value);
e.preventDefault();
}
}
const numerics = document.getElementsByClassName('numeric');
for (let i=0; i < numerics.length; i++) {
numerics[i].classList.remove("fail_val");
if (numerics[i].value == "") { continue; }
if (!isInt(numerics[i].value)) {
numerics[i].classList.add("fail_val");
scrollTop();
console.log("failed on integer test for " + numerics[i].name);
e.preventDefault();
}
}
}
);
}

View File

@ -0,0 +1,10 @@
<html>
<head><title>WZ Mini</title></head>
<body>
<h1>wz_mini web server</h1>
<p><a href="cgi-bin/config.cgi">Configuration Editor</a></p>
<p><a href="car/car.html">Car Interface</a></p>
<p><a href="cgi-bin/jpeg.cgi">Current Screen</a></p>
</body>
</html>

View File

@ -79,6 +79,7 @@ NIGHT_DROP_DISABLE="false"
DISABLE_MOTOR="false"
ENABLE_FSCK_ON_BOOT="false"
ENABLE_CAR_DRIVER="false"
ENABLE_LOCAL_DNS="false"
#####DEBUG#####
#drops you to a shell via serial, doesn't load app_init.sh
@ -86,5 +87,8 @@ DEBUG_ENABLED="false"
DEBUG_INITRAMFS_ENABLED="false"
DEBUG_PASSWORD="false"
####WEB####
WEB_SERVER_ENABLED="false"
#####SCRIPTING#####
CUSTOM_SCRIPT_PATH="/opt/wz_mini/etc/crontab/start_cron.sh"

View File

@ -1,24 +1,48 @@
6324f7357788d664bae80bc9d41c04c6 SD_ROOT/factory_t31_ZMC6tiIDQN
d41d8cd98f00b204e9800998ecf8427e SD_ROOT/wz_mini/mnt/.gitignore
28cf061770da7b83fbc3752c455a02c3 SD_ROOT/wz_mini/etc/dnsmasq.conf
e17a4aeac39b2dbb5a71d05c4ba0a067 SD_ROOT/wz_mini/www/cgi-bin/WEB_CAM_ENABLE.md
53fc10943d0ee83ed92e58123d24fc02 SD_ROOT/wz_mini/www/cgi-bin/jpeg.cgi
ffc9d653967b2c25d9635d3240209db0 SD_ROOT/wz_mini/www/cgi-bin/DISABLE_FW_UPGRADE.md
8a756026f05a35173b8748260b694e7d SD_ROOT/wz_mini/www/cgi-bin/RTSP_HI_RES_ENABLED.md
d5012a6758e30050b1dc8528e7968ac0 SD_ROOT/wz_mini/www/cgi-bin/ENABLE_USB_STORAGE.md
b8f611d1dee2db10c8adf9f57e7274ad SD_ROOT/wz_mini/www/cgi-bin/ENABLE_USB_ETH.md
4c911538bfc2f9190f6be19f6a63513c SD_ROOT/wz_mini/www/cgi-bin/BONDING_ENABLED.md
111c98593be14b3ac82526aa0e233b70 SD_ROOT/wz_mini/www/cgi-bin/config.css
bd74b1a5dfb722ea1109ea89a039a3e5 SD_ROOT/wz_mini/www/cgi-bin/RTMP_STREAM_ENABLED.md
8e14bf2616556d8a45dbb9b183d86d57 SD_ROOT/wz_mini/www/cgi-bin/ENABLE_MP4_WRITE.md
a2820a7dcfb92bb21fe17de185a16ee9 SD_ROOT/wz_mini/www/cgi-bin/numerics.txt
1013ee7201755bcf9047635b637e17c9 SD_ROOT/wz_mini/www/cgi-bin/ENABLE_WIREGUARD.md
842b228d85468ab31c99e1521b35e37e SD_ROOT/wz_mini/www/cgi-bin/REMOTE_SPOTLIGHT.md
389958bbebb7ba74d15cddb8b66e3d27 SD_ROOT/wz_mini/www/cgi-bin/config.cgi
d43f6b975afedc1f7a5e5c4999dbcbbd SD_ROOT/wz_mini/www/cgi-bin/car.sh
042848359c3840f5973baffca2457a5d SD_ROOT/wz_mini/www/cgi-bin/ENABLE_USB_DIRECT.md
f3ce2f03c67b1996b2ea33c02baffcfe SD_ROOT/wz_mini/www/config.js
e344ffc55222c029c5d324037a5aa1f3 SD_ROOT/wz_mini/www/car/car.js
540acfdf2638c341e1d168f1af5203de SD_ROOT/wz_mini/www/car/car.css
63b23f78d6703f0c9a2e970604104996 SD_ROOT/wz_mini/www/car/car.html
bd11d9a8352eca6a16554c87be50b2f5 SD_ROOT/wz_mini/www/index.html
32373fa3531a11c1aad41d12830b9c04 SD_ROOT/wz_mini/etc/dnsmasq.conf
34c6a4c3a941ff2becd9f487826d7692 SD_ROOT/wz_mini/etc/uvc.config
ad7d1a2f9db3079617731b5854ce3b6a SD_ROOT/wz_mini/etc/init.d/wz_cam.sh
f97ffcb1482d564bf2557684a4c68846 SD_ROOT/wz_mini/etc/init.d/wz_init.sh
470ce77070b8f8abb3a0a9d059fac6fa SD_ROOT/wz_mini/etc/init.d/wz_user.sh
4a423cfe7bd91090480da83b85a248b9 SD_ROOT/wz_mini/etc/init.d/wz_user.sh
4eaf541a47e60035992435b115463541 SD_ROOT/wz_mini/etc/init.d/wz_post.sh
e3034eac02d8eda9902ca9cf89f0a586 SD_ROOT/wz_mini/etc/inittab
840aa9c26726201f7cffbf001bee193a SD_ROOT/wz_mini/etc/uvc_jxf22.config
d41d8cd98f00b204e9800998ecf8427e SD_ROOT/wz_mini/etc/rc.local.d/.gitignore
7c885d8d7ea04c23d1e6622608d40cca SD_ROOT/wz_mini/etc/wz_mini.conf.dist
ac436b39b69f26fb65e993c2dfefb421 SD_ROOT/wz_mini/etc/wz_mini.conf.dist
4291fb00ec609b5b007ff9b3048e9248 SD_ROOT/wz_mini/etc/hosts
8b5e58acfcbb20034dc4873a08b45fd9 SD_ROOT/wz_mini/etc/profile
2c2df1b9cb603f9c31c46162d6ac307f SD_ROOT/wz_mini/etc/alsa/alsa.conf
9e5591da95042bcca910403bde25dc60 SD_ROOT/wz_mini/etc/fstab
3962900301ef8743c68e42ecef4d2811 SD_ROOT/wz_mini/etc/passwd
c838ac76efbe3d3fc3c4805789a6519f SD_ROOT/wz_mini/etc/uvc_jxf23.config
f08b7b96247b3ebd74eee451370d22db SD_ROOT/wz_mini/etc/resolv.dnsmasq
9dafc0f6aa1ea4f8e7ccf0caafd5e28d SD_ROOT/wz_mini/etc/resolv.dnsmasq
d41d8cd98f00b204e9800998ecf8427e SD_ROOT/wz_mini/etc/configs/.gitignore
d0541c45c77ad3c5f27f06f03547c4f2 SD_ROOT/wz_mini/etc/shadow
c838ac76efbe3d3fc3c4805789a6519f SD_ROOT/wz_mini/etc/uvc_v2.config
c2aec0b677cf239f374dda8583314332 SD_ROOT/wz_mini/etc/ssh/authorized_keys
949343428bded6a653a85910f6bdb48e SD_ROOT/wz_mini/etc/resolv.conf
d41d8cd98f00b204e9800998ecf8427e SD_ROOT/wz_mini/etc/wireguard/.gitignore
d41d8cd98f00b204e9800998ecf8427e SD_ROOT/wz_mini/log/.gitignore
d41d8cd98f00b204e9800998ecf8427e SD_ROOT/wz_mini/root/.gitignore
@ -42,13 +66,13 @@ c77675d150e2274de3cfe08c5c295f8f SD_ROOT/wz_mini/bin/ld
14e944353e335cff9430080e1ca007f6 SD_ROOT/wz_mini/bin/busybox
aba4bad7530f7f702d4c27b103cc970d SD_ROOT/wz_mini/bin/scp
c5d2801b7117b8db6275647110e6c8f1 SD_ROOT/wz_mini/bin/iwconfig.sh
649430b2d519d279e8c6095665266480 SD_ROOT/wz_mini/bin/car_control.sh
982eb631746ad427d96d28c9a2ea7b25 SD_ROOT/wz_mini/bin/car_control.sh
67ab51181a29f16e60d879d793d4407f SD_ROOT/wz_mini/bin/audioplay_t20
78aaf46b312749d71c1f93a97f80fa74 SD_ROOT/wz_mini/bin/nm
e6bcaf0465750b67cff55eb3e380e624 SD_ROOT/wz_mini/bin/curl
02c62618633915a282a547411524ed3c SD_ROOT/wz_mini/bin/v4l2rtspserver
a9b8e51b956806e27021e6524ba917ed SD_ROOT/wz_mini/bin/ranlib
2393ba8bfe8c86775b8eb7b40fa2fe57 SD_ROOT/wz_mini/bin/dnsmasq
b3ff7a1d56ccd35b40c3260a4f6e9235 SD_ROOT/wz_mini/bin/dnsmasq
c23e3da466dc9701bee036ec034583b7 SD_ROOT/wz_mini/bin/rsync
ff5a2354e4be9cc244f3ac8f304e930a SD_ROOT/wz_mini/bin/size
a8970288e72c871bff6a4484f1e733d6 SD_ROOT/wz_mini/bin/readelf
@ -62,10 +86,11 @@ e6a6a9dd8ce138686083a3d4303cea40 SD_ROOT/wz_mini/bin/iperf3
79d69cd251a8cdadd9957cdaec2034fc SD_ROOT/wz_mini/bin/rtmp-stream.sh
5d1359af0c7c5d326b8682a62f910620 SD_ROOT/wz_mini/bin/strace
516118bfcc0f0ddc93fb9339b3c6a315 SD_ROOT/wz_mini/bin/xtables-multi
17a23742c599a262e4144c499fa66845 SD_ROOT/wz_mini/bin/gather_wz_logs.sh
9be9aab45620d83fecc8b963954cf4f1 SD_ROOT/wz_mini/bin/gather_wz_logs.sh
097cd91a56f2b0caea1dd87ae0e51a54 SD_ROOT/wz_mini/bin/screen
fbbc2a8f362d05fc31557b1a534b42c6 SD_ROOT/wz_mini/bin/wget
35420095a770c9bb6177788842f55bba SD_ROOT/wz_mini/bin/dropbearconvert
236738891ee40c5855ee3a31159ec10a SD_ROOT/wz_mini/bin/wz_mini_edit.sh
91449927b9bf0dc2a231bab59da957c4 SD_ROOT/wz_mini/bin/dbclient
3b3e8d38ba7fa70f29f6c340d36f3620 SD_ROOT/wz_mini/bin/iwlist
9041242b97793eb7f25943ecbfa86804 SD_ROOT/wz_mini/bin/ar
@ -79,6 +104,7 @@ e2e7f9190edcfb31af42fb00c59919ab SD_ROOT/wz_mini/usr/share/audio/upgrade_mode_v
eaf86f91cb1b15b2191a8845ae88e3c8 SD_ROOT/wz_mini/usr/share/audio/init_v2.wav
02fed0e4b2382d839f630ce0477aba26 SD_ROOT/wz_mini/usr/share/audio/init.wav
5754f767c1334df202983aed2a20a050 SD_ROOT/wz_mini/usr/share/audio/binbin_v3.wav
6e01838f67f7e6e51a6891e1c411318a SD_ROOT/wz_mini/usr/share/audio/honk.wav
ac9f3a5d097d25d5d972c3d2ad288df9 SD_ROOT/wz_mini/usr/bin/ucamera_v2
7626ba23cc36b88491b010dd6eff72de SD_ROOT/wz_mini/usr/bin/iCamera
1e64fdad40c82ecce420f71701ec3d6d SD_ROOT/wz_mini/usr/bin/watch_up.sh
@ -86,7 +112,7 @@ b339aee882a5d1c943ad08e4282ec3fd SD_ROOT/wz_mini/usr/bin/iCamera-dbg
20b061689308b2cee7edf3b9b906bca7 SD_ROOT/wz_mini/usr/bin/ucamera
3777d9e80c8b517c01a124e6360b6525 SD_ROOT/wz_mini/usr/bin/imp_helper.sh
580b1b6e91e72b4a4fef7b21d8954403 SD_ROOT/wz_mini/usr/bin/getSensorType
94b88087a273ecdfea996b88e1f9c419 SD_ROOT/wz_mini/usr/bin/app.ver
e2c5fb721593fe52f7bf43a81d78b302 SD_ROOT/wz_mini/usr/bin/app.ver
4c780f0455481d106d47d89f0ae04ed5 SD_ROOT/wz_mini/lib/uClibc.tar
9afeb088e4cbabbe0b04033b560204d0 SD_ROOT/wz_mini/lib/libimp.so
4100755cb6cc6e3b76da20c7e3690e16 SD_ROOT/wz_mini/lib/libalog.so
@ -235,9 +261,9 @@ c6a2e765996b4a8bfe351757785fb989 SD_ROOT/wz_mini/lib/modules/3.10.14__isvp_swan
14865a6e2e2df87a8362c6f20377a934 SD_ROOT/wz_mini/lib/libtinyalsa.so.2
bd383994491e4bdca81788c168feb2eb SD_ROOT/wz_mini/lib/libasound.so.2
f6f0d5a9ebd916de6bdb9695067809ae SD_ROOT/wz_mini/lib/libaudioProcess.so
7c885d8d7ea04c23d1e6622608d40cca SD_ROOT/wz_mini/wz_mini.conf
ac436b39b69f26fb65e993c2dfefb421 SD_ROOT/wz_mini/wz_mini.conf
d41d8cd98f00b204e9800998ecf8427e SD_ROOT/wz_mini/tmp/.gitignore
30cd28d6e52753c4afe5d6bca209bfc7 v2_install/compile_image.sh
283fca97d62c1c199eb2b04877998879 v2_install/compile_image.sh
53db8da5b90bc9b219dbb1d58e934bda v2_install/fw_tool.sh
71f103530794f9cb15aa6bb7f1e5b8a7 v2_install/v2_kernel.bin
f01d641b98388e273c1f0ba682ebc75b v2_install/.gitignore

View File

@ -4,10 +4,16 @@ UA_STRING="Mozilla/5.0 (Macintosh; Intel Mac OS X 12_4) AppleWebKit/605.1.15 (KH
DL_URL=$(wget --header="Accept: text/html" --user-agent="$UA_STRING" -qO- https://support.wyze.com/hc/en-us/articles/360024852172-Release-Notes-Firmware | grep -Eo "(http|https)://[a-zA-Z0-9./?=_-]*" | grep /v2/ | sort -t . -k2r,5 | grep demo | head -1)
PAN_DL_URL=$(wget --header="Accept: text/html" --user-agent="$UA_STRING" -qO- https://support.wyze.com/hc/en-us/articles/360024852172-Release-Notes-Firmware | grep -Eo "(http|https)://[a-zA-Z0-9./?=_-]*" | grep /pan/ | sort -t . -k2r,5 | grep demo | head -1)
tools() {
echo "checking for tools"
command -v wget >/dev/null 2>&1 || { echo >&2 "wget is not installed. Aborting."; exit 1; }
command -v mkimage >/dev/null 2>&1 || { echo >&2 "mkimage is not installed. Aborting."; exit 1; }
command -v unzip >/dev/null 2>&1 || { echo >&2 "unzip is not installed. Aborting."; exit 1; }
echo "tools OK"
}
download(){
rm -f demo.bin
echo "create temporary work directory"
mkdir v2_ro
@ -22,12 +28,23 @@ else
if [[ "$1" == "pan" ]]; then
echo "build for pan"
wget $PAN_DL_URL -O ./v2_ro/demo.zip
elif [[ "$1" == "" ]]; then
else
echo "build for v2"
wget $DL_URL -O ./v2_ro/demo.zip
fi
if [[ $(md5sum ./v2_ro/demo.zip) == *"a69b6d5ffdbce89463fa83f7f06ec10b"* ]]; then
echo "v2 4.9.8.1002"
elif [[ $(md5sum ./v2_ro/demo.zip) == *"91793d32fd797a10df572f4f5d72bc55"* ]]; then
echo "pan v1 4.10.8.1002"
else
echo "md5sum failed check, please manually supply file"
rm -rf v2_ro
exit 1
fi
fi
echo "extracting firmware to temporary work directory"
unzip v2_ro/demo*.zip -d ./v2_ro/
@ -47,3 +64,16 @@ echo "remove temporary work directory"
rm -rf v2_ro
echo "demo.bin ready. Please copy demo.bin to your memory card"
}
read -r -p "wz_mini: this will download the latest firmware version from the vendor and compile a modified demo.bin. Are you sure? [y/N]" response
case "$response" in
[yY][eE][sS]|[yY])
tools
download $1
;;
*)
echo "User declined, exit"
;;
esac