1
0
mirror of https://github.com/EliasKotlyar/Xiaomi-Dafang-Hacks.git synced 2025-09-09 15:40:45 +02:00

Implement new UI

Change summary:

- Incorporate the Bulma CSS framework
- Changed many of the functions in action.cgi scripts.cgi status.cgi getMotionInfo.cgi to return json so that we can have more elegant ajax-y UI flows
- Changed the "live" view to only refresh statuses on demand (when Camera Controls menu is hovered/clicked) instead of a constant interval refresh. I did not like the constant refresh in the current implementation because it was sometimes locking up the UI in the background.
- Changed the "live" view image to reload only after previous image is loaded instead of a constant refresh interval (uses image "onload" to trigger)
- Fixed up some bugs in configMotion.html and also made the UI work responsively
- Added a "shutdown" command (calls /sbin/halt) so that I can gracefully shutdown the camera instead of pulling the plug
- Add option to choose a dark UI theme
This commit is contained in:
ping
2018-04-14 23:45:10 +08:00
parent 6521d6e4b7
commit 63d23e2ae9
15 changed files with 1498 additions and 1477 deletions

View File

@@ -6,7 +6,6 @@ echo ""
source func.cgi
source /system/sdcard/scripts/common_functions.sh
echo "<br/>"
export LD_LIBRARY_PATH=/system/lib
export LD_LIBRARY_PATH=/thirdlib:$LD_LIBRARY_PATH
if [ -n "$F_cmd" ]; then
@@ -19,11 +18,18 @@ if [ -n "$F_cmd" ]; then
echo "<pre>"
tail /var/log/*
echo "</pre>"
return
;;
reboot)
echo "Rebooting device...<br/>"
echo "Rebooting device..."
/sbin/reboot
return
;;
shutdown)
echo "Shutting down device.."
/sbin/halt
return
;;
blue_led_on)
@@ -121,45 +127,42 @@ if [ -n "$F_cmd" ]; then
/system/sdcard/controlscripts/rtsp-h264 stop
;;
settz)
ntp_srv=$(printf '%b' "${F_ntp_srv//%/\\x}")
ntp_srv=$(printf '%b' "${F_ntp_srv//%/\\x}")
#lecture fichier ntp_serv.conf
conf_ntp_srv=$(cat /system/sdcard/config/ntp_srv.conf)
#lecture fichier ntp_serv.conf
conf_ntp_srv=$(cat /system/sdcard/config/ntp_srv.conf)
if [ $conf_ntp_srv != "$ntp_srv" ]; then
echo "Setting NTP Server to '$ntp_srv'...<br/>"
echo "$ntp_srv" > /system/sdcard/config/ntp_srv.conf
echo "Syncing time on '$ntp_srv'...<br/>"
if [ $conf_ntp_srv != "$ntp_srv" ]; then
echo "<p>Setting NTP Server to '$ntp_srv'...</p>"
echo "$ntp_srv" > /system/sdcard/config/ntp_srv.conf
echo "<p>Syncing time on '$ntp_srv'...</p>"
if [ "$(/system/sdcard/bin/busybox ntpd -q -n -p $ntp_srv 2>&1)" -eq 0 ]; then
echo "<br/>Success<br/>"
else echo "<br/>Failed<br/>"
fi
fi
echo "<p>Success</p>"
else
echo "<p>Failed</p>"
fi
fi
#lecture fichier ntp_serv.conf
conf_ntp_srv=$(cat /system/sdcard/config/ntp_srv.conf)
tz=$(printf '%b' "${F_tz//%/\\x}")
tz=$(printf '%b' "${F_tz//%/\\x}")
if [ "$(cat /etc/TZ)" != "$tz" ]; then
echo "Setting TZ to '$tz'...<br/>"
echo "<p>Setting TZ to '$tz'...</p>"
echo "$tz" > /etc/TZ
echo "Syncing time...<br/>"
if [ "$(/system/sdcard/bin/busybox ntpd -q -n -p $conf_ntp_srv 2>&1)" -eq 0 ]; then
echo "<br/>Success<br/>"
else echo "<br/>Failed<br/>"
echo "<p>Syncing time...</p>"
if [ "$(/system/sdcard/bin/busybox ntpd -q -n -p $$ntp_srv 2>&1)" -eq 0 ]; then
echo "<p>Success</p>"
else echo "<p>Failed</p>"
fi
fi
hst=$(printf '%b' "${F_hostname//%/\\x}")
if [ "$(cat /system/sdcard/config/hostname.conf)" != "$hst" ]; then
echo "Setting hostname to '$hst'...<br/>"
echo "<p>Setting hostname to '$hst'...</p>"
echo "$hst" > /system/sdcard/config/hostname.conf
if [ "$(hostname "$hst")" -eq 0 ]; then
echo "<br/>Success<br/>"
else echo "<br/>Failed<br/>"
echo "<p>Success</p>"
else echo "<p>Failed</p>"
fi
fi
return
;;
osd)
@@ -192,6 +195,7 @@ if [ -n "$F_cmd" ]; then
echo "SPACE=${F_spacepixels}" >> /system/sdcard/config/osd
/system/sdcard/bin/setconf -k p -v "${F_spacepixels}"
return
;;
setldravg)
@@ -199,6 +203,7 @@ if [ -n "$F_cmd" ]; then
ldravg=$(echo "$ldravg" | sed "s/[^0-9]//g")
echo AVG="$ldravg" > /system/sdcard/config/ldr-average.conf
echo "Average set to $ldravg iterations."
return
;;
auto_night_mode_start)
@@ -278,14 +283,12 @@ if [ -n "$F_cmd" ]; then
${cmdLine} 2>/dev/null >/dev/null &
else
echo "process v4l2rtspserver-master was not found"
echo "<BR>"
echo "<p>process v4l2rtspserver-master was not found</p>"
fi
fi
echo "Motion Configuration done"
echo "<BR>"
echo "<button title='Return to motion configuration page' onClick=\"window.location.href='/configmotion.html'\">Back to motion configuration</button>"
return
;;
offDebug)
/system/sdcard/controlscripts/debug-on-osd stop
@@ -297,6 +300,7 @@ if [ -n "$F_cmd" ]; then
onDebug)
/system/sdcard/controlscripts/debug-on-osd start
;;
conf_timelapse)
tlinterval=$(printf '%b' "${F_tlinterval/%/\\x}")
tlinterval=$(echo "$tlinterval" | sed "s/[^0-9\.]//g")
@@ -314,6 +318,7 @@ if [ -n "$F_cmd" ]; then
else
echo "Invalid timelapse duration"
fi
return
;;
*)

View File

@@ -6,366 +6,7 @@ source func.cgi
if [ -e "/etc/fang_hacks.cfg" ]; then source /etc/fang_hacks.cfg; fi
PATH="/bin:/sbin:/usr/bin:/system/bin"
CFG_MODE="${NETWORK_MODE:-0}"
CFG_CLIENT="/media/mmcblk0p2/data/etc/wpa_supplicant.conf"
CFG_AP="/media/mmcblk0p2/data/etc/hostapd.conf"
CFG_DHCPD="/media/mmcblk0p2/data/etc/udhcpd.conf"
if [ -n "$F_action" ]; then
case "$F_action" in
connect)
client_ssid=$(printf '%b' "${F_ssid//%/\\x}")
client_key=$(printf '%b' "${F_key//%/\\x}")
ACTION_MSG="$(/media/mmcblk0p2/data/etc/scripts/01-network.cgi connect "$client_ssid" "$client_key")"
ACTION_RC=$?
CFG_MODE=1
;;
apply)
ACTION_RC=1
apply_ssid=$(printf '%b' "${F_ssid//%/\\x}")
apply_key=$(printf '%b' "${F_key//%/\\x}")
case "$F_mode" in
0)
# apply cloud settings
if [ -n "$apply_ssid" ] && [ -n "${apply_key}" ]; then
ACTION_MSG="Updating cloud settings..."
echo -n "$apply_ssid" > /etc/config/.wifissid
echo -n "$apply_key" > /etc/config/.wifipasswd
ACTION_RC=0
CFG_MODE=0
fi
;;
1)
# apply wpa_supplicant settings
if [ -n "$apply_ssid" ] && [ -n "${apply_key}" ]; then
if [ -e "$CFG_CLIENT" ]; then
ACTION_MSG="Updating wpa_supplicant..."
sed -i.bak 's/^\(\sssid\).*/\1="'"${apply_ssid}"'"/; s/^\(\spsk\).*/\1="'"${apply_key}"'"/' "$CFG_CLIENT" 2>&1
ACTION_RC=$?
CFG_MODE=1
else
ACTION_MSG="$CFG_CLIENT doesn't exist!"
fi
fi
;;
2)
# apply hostapd settings
if [ -n "$apply_ssid" ] && [ -n "$apply_key" ]; then
if [ -e "$CFG_AP" ]; then
ACTION_MSG="Updating hostapd..."
sed -i.bak 's/^\(ssid\).*/\1='"${apply_ssid}"'/; s/^\(wpa_passphrase\).*/\1='"${apply_key}"'/' "$CFG_AP" 2>&1
ACTION_RC=$?
CFG_MODE=2
else
ACTION_MSG="$CFG_AP doesn't exist!"
fi
fi
;;
esac
if [ $ACTION_RC -eq 0 ]; then
# apply network.cgi mode
sed -i.bak 's/^NETWORK_MODE=[0-9]/NETWORK_MODE='$CFG_MODE'/' /etc/fang_hacks.cfg
ACTION_MSG="$ACTION_MSG<br/>Applying network.cgi mode $CFG_MODE"
echo "Restarting Network..."
ACTION_MSG="$ACTION_MSG<br/><pre>$(/media/mmcblk0p2/data/etc/scripts/01-network.cgi start 2>&1)</pre>"
fi
;;
esac
fi
if [ -e "$CFG_CLIENT" ]; then
CFG_SSID="$(cat "$CFG_CLIENT")"
fi
cat << EOF
<!DOCTYPE html>
<html>
<head>
<title>Fang Hacks</title>
<style type="text/css">
body { background-color: #B0E0E6; font-family: verdana, sans-serif; }
.err { color: red; }
hr { height: 1px; border: 0; border-top: 1px solid #aaa; }
button, input[type=submit] { background-color: #ddeaff; }
.tbl { border-collapse: collapse; border-spacing: 0;}
.tbl th { text-align: left; vertical-align: top; font-weight: bold; padding: 10px 5px; border-style: solid; border-width: 1px; overflow: hidden; word-break: normal; }
.tbl td { padding: 10px 5px; border-style: solid; border-width: 1px; overflow: hidden; word-break: normal; }
span.label { font-weight: bold; display: inline-block; }
span.error { font-weight: bold; color: red; display; inline-block; }
legend { font-size: 12 }
</style>
<script>
function updatePanel() {
if (document.getElementById('mode_cloud').checked) {
document.getElementById('cloud-pnl').style.display = 'block';
document.getElementById('client-pnl').style.display = 'none';
document.getElementById('ap-pnl').style.display = 'none';
} else if (document.getElementById('mode_client').checked) {
document.getElementById('cloud-pnl').style.display = 'none';
document.getElementById('client-pnl').style.display = 'block';
document.getElementById('ap-pnl').style.display = 'none';
if ("$ACTION_RC" == "0") {
// connect success, allow apply
document.getElementById('btn_apply').disabled = false;
} else {
document.getElementById('btn_apply').disabled = true;
}
} else if (document.getElementById('mode_ap').checked) {
document.getElementById('cloud-pnl').style.display = 'none';
document.getElementById('client-pnl').style.display = 'none';
document.getElementById('ap-pnl').style.display = 'block';
document.getElementById('btn_apply').disabled = false;
}
}
function updateNetworkDetails() {
var e = document.getElementById('network-list');
var ssid = e.options[e.selectedIndex].text;
var addr = document.getElementById(ssid + '_ADDR').value;
var enc = document.getElementById(ssid + '_ENC').value;
var qual = document.getElementById(ssid + '_QUAL').value;
document.getElementById('ssid_name').textContent = ssid;
document.getElementById('ssid_addr').textContent = addr;
document.getElementById('ssid_signal').textContent = qual + '%';
document.getElementById('ssid_encryption').textContent = enc;
document.getElementById('network-details').style.display = 'block';
document.getElementById('btn_connect').disabled = false;
document.getElementById('btn_apply').disabled = true;
document.getElementById('ssid_key').value = "";
}
function postData(to, p) {
var myForm = document.createElement("form");
myForm.method="post";
myForm.action = to;
for (var k in p) {
var myInput = document.createElement("input") ;
myInput.setAttribute("name", k) ;
myInput.setAttribute("value", p[k]);
myForm.appendChild(myInput) ;
}
document.body.appendChild(myForm);
myForm.submit();
document.body.removeChild(myForm);
}
function apply_config() {
if (document.getElementById('mode_cloud').checked) {
var data = {
action: 'apply',
mode: 0,
ssid: document.getElementById('cloud_ssid').value,
key: document.getElementById('cloud_key').value
};
postData('/cgi-bin/network', data);
} else if (document.getElementById('mode_client').checked) {
var data = {
action: 'apply',
mode: 1,
ssid: document.getElementById('ssid_name').textContent,
key: document.getElementById('ssid_key').value
};
if (data['key'].length >= 8 && data['key'].length <= 63) {
postData('/cgi-bin/network', data);
} else {
alert("Passphrase must be between 8 and 63 chars!");
}
} else if (document.getElementById('mode_ap').checked) {
var data = {
action: 'apply',
mode: 2,
ssid: document.getElementById('ap_ssid').value,
key: document.getElementById('ap_key').value
};
var addr = document.getElementById('ap_addr').value;
var msg = [
"A HotSpot named '" + data['ssid'] + "' will be created.",
"To continue using the device, you will first need to connect to it.",
"Once connected the status page can be accessed on:",
"",
"http://" + addr + "/cgi-bin/status",
"",
"Are you sure?"
].join("\n");
if (confirm(msg) != true) {
data = null;
}
}
if (typeof data !== 'undefined' && data) {
if (data['key'].length >= 8 && data['key'].length <= 63) {
postData('/cgi-bin/network', data);
} else {
alert("Passphrase must be between 8 and 63 chars!");
}
}
}
function connect_ssid() {
var ssid = document.getElementById('ssid_name').textContent;
var enc = document.getElementById(ssid + '_ENC').value;
if (enc != "WPA") { alert("Sorry, " + enc + " encryption is not supported!"); return; }
var data = {
action: 'connect',
ssid: ssid,
key: document.getElementById('ssid_key').value
};
if (data['key'].length >= 8 && data['key'].length <= 63) {
postData('/cgi-bin/network', data);
} else {
alert("Passphrase must be between 8 and 63 chars!");
}
}
function onLoad() {
var id = $(case $CFG_MODE in
0) echo -n \'mode_cloud\' ;;
1) echo -n \'mode_client\' ;;
2) echo -n \'mode_ap\' ;;
esac);
document.getElementById(id).checked = true;
EOF
if [ "$ACTION_RC" == 0 ]; then
if [ "$F_action" == "connect" ]; then
echo "document.getElementById('network.cgi-list').value = \"$client_ssid\";"
echo "updateNetworkDetails();"
echo "document.getElementById('ssid_key').value = \"$client_key\";"
fi
fi
cat << EOF
updatePanel();
}
window.onload = onLoad;
</script>
</head>
<body>
<h1>Network Settings</h1>
<hr/>
<button title='Status page' type='button' onClick="window.location.href='status.cgi'">Status</button>
<button title='Reboot the device' type='button' onClick="window.location.href='action.cgi?cmd=reboot'">Reboot</button>
<button title='Info' type='button' onClick="window.location.href='scripts.cgi'">Scripts</button>
<button title='View /tmp/hacks.log' type='button' onClick="window.location.href='action.cgi?cmd=showlog'">View log</button>
<!-- <hr/>
<div style='clear: both;'><pre>$ACTION_MSG</pre></div>
<div style='clear: both;'>
<fieldset style='display: inline-block;'>
<legend>Wireless Mode</legend>
<input style='' onClick='updatePanel()' type='radio' name='mode' id='mode_cloud' value='mode_cloud'/>
<label for='mode_cloud'>Cloud</label>
<input style='' onClick='updatePanel()' type='radio' name='mode' id='mode_client' value='mode_client'/>
<label for='mode_cloud'>Wireless Client</label>
<input style='' onClick='updatePanel()' type='radio' name='mode' id='mode_ap' value='mode_ap'/>
<label for='mode_ap'>Access Point</label>
</fieldset>
<br/>
<div id='client-pnl' style='display: none'>
<fieldset style='display: inline-block'>
<legend>Wireless Client</legend>
EOF
SSID="$(iwconfig wlan0 | grep ESSID | cut -d\" -f2)"
AP="$(iwconfig | grep -o "Access Point:.*" | grep -E -o "([0-9A-F]{2}:){5}[0-9A-F]{2}")"
if [ -n "$SSID" ]; then
echo "Connected to: $SSID<br/>"
echo "Access Point: $AP<br/>"
echo "<hr/>"
fi
echo "<div style='float: left'>"
echo "<form name='network.cgi-info'>"
echo "Select Access Point:<br/>"
echo "<select id='network.cgi-list' size='5' onChange='updateNetworkDetails()' style='width: 20em'>"
echo "<option value='' disabled selected style='display:none;'>Label</option>"
hidden=""
while read -r x; do
SSID=$(echo "$x" | cut -f1)
ADDR=$(echo "$x" | cut -f2)
ENC=$(echo "$x" | cut -f3)
QUAL=$(echo "$x" | cut -f4)
echo "<option id=\"${SSID}_OPT\">$SSID</option>"
hidden="$hidden
<input type='hidden' id=\"${SSID}_QUAL\" value=\"$QUAL\"/>
<input type='hidden' id=\"${SSID}_ENC\" value=\"$ENC\"/>
<input type='hidden' id=\"${SSID}_ADDR\" value=\"$ADDR\"/>"
done <<EOT
$(iwlist wlan0 scan 2>/dev/null | /system/sdcard/scripts/iwlist.awk | /system/sdcard/bin/busybox sort -rgk4)
EOT
echo "</select>"
echo "$hidden"
echo "</form>"
cat << EOF
</div>
<div id='network-details' style='float: left; padding: 0.5em; line-height: 1.5em; display: none'>
<span class='label' style='width: 5em'>Name:</span><span id='ssid_name'></span><br/>
<span class='label' style='width: 5em'>Address:</span><span id='ssid_addr'></span><br/>
<span class='label' style='width: 5em'>Signal:</span><span id='ssid_signal'></span><br/>
<span class='label' style='width: 5em'>Security:</span><span id='ssid_encryption'></span><br/>
</div>
<div style='clear: both'>
Passphrase:
<input type='text' id='ssid_key'/>
<button type='button' disabled id='btn_connect' title='Connect'
onClick='connect_ssid()'>Connect</button>
</div>
<div style='clear: both'/>
</fieldset>
</div> <!-- client-pnl -->
<div id='cloud-pnl' style='display: none'>
<fieldset style='display: inline-block'>
<legend>Cloud Mode</legend>
In this mode, network is managed by cloud apps.<br/>
A reboot is required to re-connect after settings are changed!<br/>
EOF
if [ "$DISABLE_CLOUD" -eq 1 ]; then
echo "<span class='error'>"
echo "Warning: Cloud apps are disabled!<br/>"
echo "If you apply this mode network.cgi will NOT be initialized after reboot!"
echo "</span>"
fi
echo "<hr/> "
echo "<div style='float: left'>"
echo "<form name='network.cgi-info'>"
echo "Cloud WiFi Settings:<br/>"
echo "<label for='cloud_ssid' style='display: inline-block; width: 8em'>Network SSID:</label>"
echo "<input id='cloud_ssid' value='$(cat /etc/config/.wifissid)' type='text'/><br/>"
echo "<label for='cloud_key' style='display: inline-block; width: 8em'>Passphrase:</label>"
echo "<input id='cloud_key' value='$(cat /etc/config/.wifipasswd)' type='text'/>"
echo "</form></div>"
cat << EOF
</fieldset>
</div> <!-- cloud-pnl -->
<div id='ap-pnl' style='display: none'>
<fieldset style='display: inline-block'>
<legend>Access Point</legend>
Create a Wireless Hotspot.<br/>
EOF
echo "<hr/>"
ap_addr="$(grep "^opt.*router" $CFG_DHCPD | awk '{print $3}')"
ap_ssid="$(grep "^ssid=" $CFG_AP | cut -d'=' -f2)"
ap_key="$(grep "^wpa_passphrase=" $CFG_AP | cut -d'=' -f2)"
echo "<div style='float: left'>"
echo "<form name='network.cgi-info'>"
echo "Hotspot settings:<br/>"
echo "<label for='ap_addr' style='display: inline-block; width: 8em'>IP Address:</label>"
echo "<input id='ap_addr' value='$ap_addr' type='text' disabled title='You must manually edit configs to change addressing!'/><br/>"
echo "<label for='ap_ssid' style='display: inline-block; width: 8em'>Network SSID:</label>"
echo "<input id='ap_ssid' value='$ap_ssid' type='text'/><br/>"
echo "<label for='ap_key' style='display: inline-block; width: 8em'>Passphrase:</label>"
echo "<input id='ap_key' value='$ap_key' type='text'/><br/>"
echo "</form></div>"
cat << EOF
</fieldset>
</div> <!-- ap-pnl -->
<hr/>
<button type='button' id='btn_apply' disabled onClick="apply_config()">Apply</button>
<hr/> -->
Information:
<pre>Interfaces:<br/>$(ifconfig; iwconfig)</pre>
<pre>Routes:<br/>$(route)</pre>

View File

@@ -1,34 +1,6 @@
#!/bin/sh
echo "Content-type: text/html"
echo ""
source func.cgi
cat << EOF
<!DOCTYPE html>
<html>
<head>
<title>Fang Hacks</title>
<style type="text/css">
body { background-color: #B0E0E6; font-family: verdana, sans-serif; }
.err { color: red; }
hr { height: 1px; border: 0; border-top: 1px solid #aaa; }
button, input[type=submit] { background-color: #ddeaff; }
.tbl { border-collapse: collapse; border-spacing: 0;}
.tbl th { text-align: left; vertical-align: top; font-weight: bold; padding: 10px 5px; border-style: solid; border-width: 1px; overflow: hidden; word-break: normal; }
.tbl td { padding: 10px 5px; border-style: solid; border-width: 1px; overflow: hidden; word-break: normal; }
</style>
</head>
<body>
<h1>Boot Scripts</h1>
<hr/>
<button title='Status page' type='button' onClick="window.location.href='status.cgi'">Status</button>
<button title='Reboot the device' type='button' onClick="window.location.href='action.cgi?cmd=reboot'">Reboot</button>
<button title='Network' type='button' onClick="window.location.href='network.cgi'">Network</button>
<button title='View /tmp/hacks.log' type='button' onClick="window.location.href='action.cgi?cmd=showlog'">View log</button>
<hr/>
EOF
SCRIPT_HOME="/system/sdcard/controlscripts/"
if [ -n "$F_script" ]; then
@@ -36,96 +8,135 @@ if [ -n "$F_script" ]; then
if [ -e "$SCRIPT_HOME/$script" ]; then
case "$F_cmd" in
start)
echo "Running script '$script'...<br/>"
echo "Content-type: text/html"
echo ""
echo "Running script '$script'..."
echo "<pre>$("$SCRIPT_HOME/$script" 2>&1)</pre>"
;;
disable)
echo "Disable script '$script'...<br/>"
rm "/system/sdcard/config/autostart/$script"
echo "Content-type: application/json"
echo ""
echo "{\"status\": \"ok\"}"
;;
stop)
echo "Stop script '$script'...<br/>"
echo "Content-type: text/html"
echo ""
status='unknown'
echo "Stopping script '$script'..."
echo "<pre>"
"$SCRIPT_HOME/$script" stop 2>&1 && echo "OK" || echo "NOK"
echo "<br/>"
echo "</pre>"
;;
enable)
echo "Enable script '$script'...<br/>"
echo "#!/bin/sh" > "/system/sdcard/config/autostart/$script"
echo "$SCRIPT_HOME$script" >> "/system/sdcard/config/autostart/$script"
echo "Content-type: application/json"
echo ""
echo "{\"status\": \"ok\"}"
;;
view)
echo "Contents of script '$script':<br/>"
echo "Content-type: text/html"
echo ""
echo "Contents of script '$script':"
echo "<pre>$(cat "$SCRIPT_HOME/$script" 2>&1)</pre>"
;;
*)
echo "Unsupported command '$F_cmd'<br/>"
echo "Content-type: text/html"
echo ""
echo "<p>Unsupported command '$F_cmd'</p>"
;;
esac
echo "<hr/>"
else
echo "$F_script is not a valid script!<br/>"
echo "Content-type: text/html"
echo ""
echo "<p>$F_script is not a valid script!</p>"
fi
return
fi
echo "Content-type: text/html"
echo ""
if [ ! -d "$SCRIPT_HOME" ]; then
echo "No scripts.cgi found in $SCRIPT_HOME<br/>"
echo "<p>No scripts.cgi found in $SCRIPT_HOME</p>"
else
SCRIPTS=$(ls -A "$SCRIPT_HOME")
echo "<table class='tbl'>"
echo "<tr><th>Service</th><th>Status</th><th/><th/><th>Autostart</th></tr>"
for i in $SCRIPTS; do
echo "<tr>"
echo "<td>$i</td>"
# Card - start
echo "<div class='card script_card'>"
# Header
echo "<header class='card-header'><p class='card-header-title'>"
# echo "<div class='card-content'>"
if [ -x "$SCRIPT_HOME/$i" ]; then
if grep -q "^status()" "$SCRIPT_HOME/$i"; then
status=$("$SCRIPT_HOME/$i" status)
if [ $? -eq 0 ]; then
if [ -n "$status" ]; then
bgcolor="green";
badge="";
else
bgcolor="orange";
badge="is-badge-warning";
fi
else
bgcolor="red"
badge="is-badge-danger"
status="NOK"
fi
echo "<td bgcolor='$bgcolor'>$status</td>";
echo "<span class='badge $badge' data-badge='$status'>$i</span>"
else
echo "<td/>"
echo "$i"
fi
# echo "</div>"
echo "</p></header>"
# Footer
echo "<footer class='card-footer'>"
echo "<span class='card-footer-item'>"
# Start / Stop / Run buttons
echo "<div class='buttons'>"
if grep -q "^start()" "$SCRIPT_HOME/$i"; then
if [ -z "$status" ]; then
echo "<td><button title='Start script' type='button' onClick=\"window.location.href='scripts.cgi?cmd=start&script=$i'\">Start</button</td>"
else
echo "<td><button title='Already running' disabled>Start</button>"
echo "<button data-target='/cgi-bin/scripts.cgi?cmd=start&script=$i' class='button is-link script_action_start' data-script='$i' "
if [ ! -z "$status" ]; then
echo "disabled"
fi
echo ">Start</button>"
else
echo "<td><button title='Run script' type='button' onClick=\"window.location.href='scripts.cgi?cmd=start&script=$i'\">Run</button></td>"
echo "<button data-target='/cgi-bin/scripts.cgi?cmd=start&script=$i' class='button is-link script_action_start' data-script='$i' "
echo ">Run</button>"
fi
if grep -q "^stop()" "$SCRIPT_HOME/$i"; then
if [ -n "$status" ]; then
echo "<td><button title='Stop script' type='button' onClick=\"window.location.href='scripts.cgi?cmd=stop&script=$i'\">Stop</button></td>"
else
echo "<td><button title='Not running' disabled>Stop</button>"
echo "<button data-target='/cgi-bin/scripts.cgi?cmd=stop&script=$i' class='button is-danger script_action_stop' data-script='$i' "
if [ ! -n "$status" ]; then
echo "disabled"
fi
else
echo "<td></td>"
echo ">Stop</button>"
fi
echo "</div>"
echo "</span>"
# Autostart Switch
echo "<span class='card-footer-item'>"
echo "<input type='checkbox' id='autorun_$i' name='autorun_$i' class='switch is-rtl autostart' data-script='$i' "
echo " data-unchecked='/cgi-bin/scripts.cgi?cmd=disable&script=$i'"
echo " data-checked='/cgi-bin/scripts.cgi?cmd=enable&script=$i'"
if [ -f "/system/sdcard/config/autostart/$i" ]; then
echo " checked='checked'"
fi
echo "'>"
echo "<label for='autorun_$i'>Autorun</label>"
echo "</span>"
# View link
echo "<a href='/cgi-bin/scripts.cgi?cmd=view&script=$i' class='card-footer-item view_script' data-script="$i">View</a>"
echo "</footer>"
fi
if [ -f "/system/sdcard/config/autostart/$i" ]; then
echo "<td><button title='Disable script' type='button' onClick=\"window.location.href='scripts.cgi?cmd=disable&script=$i'\">Disable</button></td>"
else
echo "<td><button title='Enable script' type='button' onClick=\"window.location.href='scripts.cgi?cmd=enable&script=$i'\">Enable</button></td>"
fi
echo "<td><button title='View script' type='button' onClick=\"window.location.href='scripts.cgi?cmd=view&script=$i'\">View</button></td>"
echo "</tr>"
# Card - End
echo "</div>"
done
echo "</table>"
fi
cat << EOF
</body>
</html>
EOF
script=$(cat /system/sdcard/www/scripts/scripts.cgi.js)
echo "<script>$script</script>"

View File

@@ -3,283 +3,548 @@
echo "Content-type: text/html"
echo ""
cat << EOF
<!DOCTYPE html>
<html>
<head>
<title>Fang Hacks</title>
<style type="text/css">
body { background-color: #B0E0E6; font-family: verdana, sans-serif; }
.err { color: red; }
hr { height: 1px; border: 0; border-top: 1px solid #aaa; }
button, input[type=submit] { background-color: #ddeaff; }
.tbl { border-collapse: collapse; border-spacing: 0;}
.tbl th { text-align: left; vertical-align: top; font-weight: bold; padding: 10px 5px; border-style: solid; border-width: 1px; overflow: hidden; word-break: normal; }
.tbl td { padding: 10px 5px; border-style: solid; border-width: 1px; overflow: hidden; word-break: normal; }
</style>
</head>
<body>
EOF
source header.cgi
# source header.cgi
cat << EOF
<br/>
<br/>
<!-- Date -->
<div class='card status_card'>
<header class='card-header'><p class='card-header-title'>Date</p></header>
<div class='card-content'>
<form id="tzForm" action="/cgi-bin/action.cgi?cmd=settz" method="post">
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label" for="tz">TZ</label>
</div>
<div class="field-body">
<div class="field">
<div class="control">
<input class="input" id="tz" name="tz" type="text" size="25" value="$(cat /etc/TZ)" />
</div>
<p>$(date)</p>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label" for="ntp_srv">NTP Server</label>
</div>
<div class="field-body">
<div class="field">
<div class="control">
<input class="input" id="ntp_srv" name="ntp_srv" type="text" size="25" value="$(cat /system/sdcard/config/ntp_srv.conf)" />
</div>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label" for="hostname">Hostname</label>
</div>
<div class="field-body">
<div class="field">
<div class="control">
<input class="input" id="hostname" name="hostname" type="text" size="15" value="$(hostname)" />
</div>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
</div>
<div class="field-body">
<div class="field">
<div class="control">
<input id="tzSubmit" class="button is-primary" type="submit" value="Set" />
</div>
</div>
</div>
</div>
</form>
</div>
</div>
<!-- Version -->
<div class='card status_card'>
<header class='card-header'><p class='card-header-title'>Version</p></header>
<div class='card-content'>
<p>$(cut -d'=' -f2 /etc/os-release)</p>
</div>
</div>
</p>
<hr/>
<button title='Reboot the device' type='button' onClick="window.location.href='action.cgi?cmd=reboot'">Reboot</button>
<button title='Manage scripts' type='button' onClick="window.location.href='scripts.cgi'">Manage scripts</button>
<button title='Network' type='button' onClick="window.location.href='network.cgi'">Network</button>
<button title='View /tmp/hacks.log' type='button' onClick="window.location.href='action.cgi?cmd=showlog'">View log</button>
<button title='Motion Configuration' type='button' onClick="window.open('/configmotion.html')">ConfigMotion</button>
<button title='live view' type='button' onClick="window.open('/live.html')">Live view</button>
<hr/>
<table class='tbl'>
<tr>
<th>Date:</th>
<td>
<form style="margin: 0px" action="/cgi-bin/action.cgi?cmd=settz" method="post">
$(date)
<label style="margin-left: 1em" for="tz">TZ:</label>
<input id="tz" name="tz" type="text" size="25" value="$(cat /etc/TZ)" />
<label for="ntp_srv">NTP Server:</label>
<input id="ntp_srv" name="ntp_srv" type="text" size="25" value="$(cat /system/sdcard/config/ntp_srv.conf)"/>
<label for="hostname">Hostname:</label>
<input id="hostname" name="hostname" type="text" size="15" value="$(hostname)" />
<input type="submit" value="Set" />
</form>
</td>
</tr>
<tr>
<th>Version:</th>
<td>$(cut -d'=' -f2 /etc/os-release) </td>
</tr>
<script>
function call(url){
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.send();
}
</script>
<script>
function call(url){
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.send();
}
</script>
<!-- Blue / Yellow LED -->
<div class='card status_card'>
<header class='card-header'><p class='card-header-title'>LED</p></header>
<div class='card-content'>
<div class="columns">
<div class="column">
<label>Blue LED</label>
<div class="buttons">
<button class="button is-link" onClick="call('/cgi-bin/action.cgi?cmd=blue_led_on')">On</button>
<button class="button is-warning" onClick="call('/cgi-bin/action.cgi?cmd=blue_led_off')">Off</button>
</div>
</div>
<tr>
<th>Blue LED:</th>
<td>
<button title='' type='button' onClick="call('action.cgi?cmd=blue_led_on')">On</button>
<button title='' type='button' onClick="call('action.cgi?cmd=blue_led_off')">Off</button>
</td>
</tr>
<tr>
<th>Yellow LED:</th>
<td>
<button title='' type='button' onClick="call('action.cgi?cmd=yellow_led_on')">On</button>
<button title='' type='button' onClick="call('action.cgi?cmd=yellow_led_off')">Off</button>
</td>
</tr>
<tr>
<th>IR LED:</th>
<td>
<button title='' type='button' onClick="call('action.cgi?cmd=ir_led_on')">On</button>
<button title='' type='button' onClick="call('action.cgi?cmd=ir_led_off')">Off</button>
</td>
</tr>
<tr>
<th>IR Cut:</th>
<td>
<button title='' type='button' onClick="call('action.cgi?cmd=ir_cut_on')">On</button>
<button title='' type='button' onClick="call('action.cgi?cmd=ir_cut_off')">Off</button>
</td>
</tr>
<tr>
<th>Auto Night Mode:</th>
<td>
<button title='' type='button' onClick="call('action.cgi?cmd=auto_night_mode_start')">On</button>
<button title='' type='button' onClick="call('action.cgi?cmd=auto_night_mode_stop')">Off</button>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Use average measurement on switching. Number of measurements: <form style="display: inline;" action="/cgi-bin/action.cgi?cmd=setldravg" method="post">
<select name="avg">
<option value="1" $(if [ "$(sed s/AVG=// /system/sdcard/config/ldr-average)" -eq 1 ]; then echo selected; fi)>1</option>
<option value="2" $(if [ "$(sed s/AVG=// /system/sdcard/config/ldr-average)" -eq 2 ]; then echo selected; fi)>2</option>
<option value="3" $(if [ "$(sed s/AVG=// /system/sdcard/config/ldr-average)" -eq 3 ]; then echo selected; fi)>3</option>
<option value="4" $(if [ "$(sed s/AVG=// /system/sdcard/config/ldr-average)" -eq 4 ]; then echo selected; fi)>4</option>
<option value="5" $(if [ "$(sed s/AVG=// /system/sdcard/config/ldr-average)" -eq 5 ]; then echo selected; fi)>5</option>
<option value="10" $(if [ "$(sed s/AVG=// /system/sdcard/config/ldr-average)" -eq 10 ]; then echo selected; fi)>10</option>
<option value="15" $(if [ "$(sed s/AVG=// /system/sdcard/config/ldr-average)" -eq 15 ]; then echo selected; fi)>15</option>
</select>
<input type="submit" value="Set" /> </form>
</td>
</tr>
<tr>
<th>RTSP-Server Nightvision</th>
<td>
<button title='' type='button' onClick="call('action.cgi?cmd=toggle-rtsp-nightvision-on')">On</button>
<button title='' type='button' onClick="call('action.cgi?cmd=toggle-rtsp-nightvision-off')">Off</button>
</td>
</tr>
<tr>
<th>RTSP-Flip</th>
<td>
<button title='' type='button' onClick="call('action.cgi?cmd=flip-on')">On</button>
<button title='' type='button' onClick="call('action.cgi?cmd=flip-off')">Off</button>
</td>
</tr>
<div class="column">
<label>Yellow LED</label>
<div class="buttons">
<button class="button is-link" onClick="call('/cgi-bin/action.cgi?cmd=yellow_led_on')">On</button>
<button class="button is-warning" onClick="call('/cgi-bin/action.cgi?cmd=yellow_led_off')">Off</button>
</div>
</div>
<tr>
<th>Motor:</th>
<td>
&nbsp;&nbsp;&nbsp;&nbsp;<button title="" type="button" onclick="call('action.cgi?cmd=motor_up&val='+document.getElementById('val').value)">&nbsp;Up&nbsp;</button>
<br>
<button title="" type="button" onclick="call('action.cgi?cmd=motor_left&val='+document.getElementById('val').value)">Left</button>&nbsp;
<button title="" type="button" onclick="call('action.cgi?cmd=motor_right&val='+document.getElementById('val').value)">Right</button>
<br> &nbsp;&nbsp;&nbsp;
<button title="" type="button" onclick="call('action.cgi?cmd=motor_down&val='+document.getElementById('val').value)">Down</button> &nbsp;&nbsp;&nbsp;
<input type="text" id="val" name="val" value="100">
<button title='' type='button' onClick="call('action.cgi?cmd=motor_vcalibrate')">Calibrate Vertical</button>
<button title='' type='button' onClick="call('action.cgi?cmd=motor_hcalibrate')">Calibrate Horizontal</button>
</td>
</div>
</div>
</div>
</tr>
<!-- IR LED / Cut-->
<div class='card status_card'>
<header class='card-header'><p class='card-header-title'>IR</p></header>
<div class='card-content'>
<div class="columns">
<div class="column">
<label>IR LED</label>
<div class="buttons">
<button class="button is-link" onClick="call('/cgi-bin/action.cgi?cmd=ir_led_on')">On</button>
<button class="button is-warning" onClick="call('/cgi-bin/action.cgi?cmd=ir_led_off')">Off</button>
</div>
</div>
<tr>
<th>Audio:</th>
<td>
<button title='' type='button' onClick="call('action.cgi?cmd=audio_test')">Test</button>
</td>
</tr>
<tr>
<th>Get Image</th>
<td>
<a href='currentpic.cgi' target='_blank'><button title='' type='button' onClick="">Get</button></a></br>
</td>
</tr>
<tr>
<th>Resolution</th>
<td>
<form style="margin: 0px" action="/cgi-bin/action.cgi?cmd=setvideosize" method="post">
Select video size: <select name="video_size">
<option value="-W 640 -H 360" $(if [ "$(cat /system/sdcard/config/video_size.conf | grep 640)" != "" ]; then echo selected; fi)>640x360</option>
<option value="-W 1280 -H 720" $(if [ "$(cat /system/sdcard/config/video_size.conf | grep 1280)" != "" ]; then echo selected; fi)>1280x720</option>
<option value="-W 1600 -H 900" $(if [ "$(cat /system/sdcard/config/video_size.conf | grep 1600)" != "" ]; then echo selected; fi)>1600x900</option>
<option value="-W 1920 -H 1080" $(if [ "$(cat /system/sdcard/config/video_size.conf | grep 1920)" != "" ]; then echo selected; fi)>1920x1080</option>
</select>
<input type="submit" value="Set" />
</form>
</td>
</tr>
<tr>
<th>Start H264 RTSP</th>
<td>
<button title='' type='button' onClick="call('action.cgi?cmd=h264_start')">Start</button>
<button title='' type='button' onClick="call('action.cgi?cmd=rtsp_stop')">Stop</button>
<br>
EOF
PATH="/bin:/sbin:/usr/bin:/media/mmcblk0p2/data/bin:/media/mmcblk0p2/data/sbin:/media/mmcblk0p2/data/usr/bin"
IP=$(ifconfig wlan0 |grep "inet addr" |awk '{print $2}' |awk -F: '{print $2}')
echo "Path to feed : <a href='rtsp://$IP:8554/unicast'>rtsp://$IP:8554/unicast</a></br>"
echo "HLS : <a href='http://$IP:8554/unicast.m3u8'>http://$IP:8554/unicast.m3u8</a></br>"
echo "MPEG-DASH : <a href='http://$IP:8554/unicast.mpd'>http://$IP:8554/unicast.mpd</a></br>"
cat << EOF
</td>
</tr>
<tr>
<th>Start MJPEG RTSP</th>
<td>
<button title='' type='button' onClick="call('action.cgi?cmd=mjpeg_start')">Start</button>
<button title='' type='button' onClick="call('action.cgi?cmd=rtsp_stop')">Stop</button>
<br>
EOF
PATH="/bin:/sbin:/usr/bin:/media/mmcblk0p2/data/bin:/media/mmcblk0p2/data/sbin:/media/mmcblk0p2/data/usr/bin"
IP=$(ifconfig wlan0 |grep "inet addr" |awk '{print $2}' |awk -F: '{print $2}')
echo "Path to feed : <a href='rtsp://$IP:8554/unicast'>rtsp://$IP:8554/unicast</a></br>"
cat << EOF
</td>
</tr>
<tr>
<th>OSD-Display</th>
<td>
<form style="margin: 0px" action="/cgi-bin/action.cgi?cmd=osd" method="post">
<input type="checkbox" name="OSDenable" value="enabled" $(if [ -f /system/sdcard/config/osd ]; then echo checked; fi)> Enable
Text: <input id="osdtext" name="osdtext" type="text" size="25" value="$(source /system/sdcard/config/osd && echo "$OSD")"/>
(Enter time-variables in <a href="http://strftime.org/" target="_blank">strftime</a> format)
<br>
Osd color <select name="color">
<option value="0" $(if [ "$(grep COLOR /system/sdcard/config/osd | sed s/COLOR=//)" -eq 0 ]; then echo selected; fi)>White</option>
<option value="1" $(if [ "$(grep COLOR /system/sdcard/config/osd | sed s/COLOR=//)" -eq 1 ]; then echo selected; fi)>Black</option>
<option value="2" $(if [ "$(grep COLOR /system/sdcard/config/osd | sed s/COLOR=//)" -eq 2 ]; then echo selected; fi)>Red</option>
<option value="3" $(if [ "$(grep COLOR /system/sdcard/config/osd | sed s/COLOR=//)" -eq 3 ]; then echo selected; fi)>Green</option>
<option value="4" $(if [ "$(grep COLOR /system/sdcard/config/osd | sed s/COLOR=//)" -eq 4 ]; then echo selected; fi)>Blue</option>
<option value="5" $(if [ "$(grep COLOR /system/sdcard/config/osd | sed s/COLOR=//)" -eq 5 ]; then echo selected; fi)>Cyan</option>
<option value="6" $(if [ "$(grep COLOR /system/sdcard/config/osd | sed s/COLOR=//)" -eq 6 ]; then echo selected; fi)>Yellow</option>
<option value="7" $(if [ "$(grep COLOR /system/sdcard/config/osd | sed s/COLOR=//)" -eq 7 ]; then echo selected; fi)>Purple</option>
</select> OSD text size <select name="size">
<option value="0" $(if [ "$(grep SIZE /system/sdcard/config/osd | sed s/SIZE=//)" -eq 0 ]; then echo selected; fi)>Small</option>
<option value="1" $(if [ "$(grep SIZE /system/sdcard/config/osd | sed s/SIZE=//)" -eq 1 ]; then echo selected; fi)>Bigger</option>
</select> Y position <input id="posy" name="posy" type="number" size="6" value="$(source /system/sdcard/config/osd && echo "$POSY")"/>
Pixels between chars (can be negative)<input id="spacepixels" name="spacepixels" type="number" size="4" value="$(source /system/sdcard/config/osd && echo "$SPACE")"/>
Fixed width <select name="fixedw">
<option value="0" $(if [ "$(grep FIXEDW /system/sdcard/config/osd | sed s/FIXEDW=//)" -eq 0 ]; then echo selected; fi)>No</option>
<option value="1" $(if [ "$(grep FIXEDW /system/sdcard/config/osd | sed s/FIXEDW=//)" -eq 1 ]; then echo selected; fi)>Yes</option>
</select>
<BR>
<BR>
<input type="submit" value=" Set " />
<div class="column">
<label>IR Cut</label>
<div class="buttons">
<button class="button is-link" onClick="call('/cgi-bin/action.cgi?cmd=ir_cut_on')">On</button>
<button class="button is-warning" onClick="call('/cgi-bin/action.cgi?cmd=ir_cut_off')">Off</button>
</div>
</div>
</div>
</div>
</div>
<!-- Auto Night Mode -->
<div class='card status_card'>
<header class='card-header'><p class='card-header-title'>Auto Night Mode</p></header>
<div class='card-content'>
<div class="columns">
<div class="column">
<button class="button is-link" onClick="call('/cgi-bin/action.cgi?cmd=auto_night_mode_start')">On</button>
<button class="button is-warning" onClick="call('/cgi-bin/action.cgi?cmd=auto_night_mode_stop')">Off</button>
</div>
<div class="column">
<form id="formldr" action="/cgi-bin/action.cgi?cmd=setldravg" method="post">
<p>Use average measurement on switching.</p>
<label class="label">Number of measurements</label>
<div class="field is-grouped">
<div class="control">
<div class="select">
<select class="select" name="avg">
<option value="1" $(if [ "$(sed s/AVG=// /system/sdcard/config/ldr-average)" -eq 1 ]; then echo selected; fi)>1</option>
<option value="2" $(if [ "$(sed s/AVG=// /system/sdcard/config/ldr-average)" -eq 2 ]; then echo selected; fi)>2</option>
<option value="3" $(if [ "$(sed s/AVG=// /system/sdcard/config/ldr-average)" -eq 3 ]; then echo selected; fi)>3</option>
<option value="4" $(if [ "$(sed s/AVG=// /system/sdcard/config/ldr-average)" -eq 4 ]; then echo selected; fi)>4</option>
<option value="5" $(if [ "$(sed s/AVG=// /system/sdcard/config/ldr-average)" -eq 5 ]; then echo selected; fi)>5</option>
<option value="10" $(if [ "$(sed s/AVG=// /system/sdcard/config/ldr-average)" -eq 10 ]; then echo selected; fi)>10</option>
<option value="15" $(if [ "$(sed s/AVG=// /system/sdcard/config/ldr-average)" -eq 15 ]; then echo selected; fi)>15</option>
</select>
</div>
</div>
<p class="control">
<input id="ldrSubmit" class="button is-primary" type="submit" value="Set" />
</p>
</div>
</form>
</td>
</tr>
<tr>
<th>Display debug info on OSD</th>
<td>
<button title='' type='button' onClick="call('/cgi-bin/action.cgi?cmd=onDebug')">On</button>
<button title='' type='button' onClick="call('/cgi-bin/action.cgi?cmd=offDebug')">Off</button>
</td>
</tr>
<tr>
<th>Timelapse</th>
<td>
<form style="display: inline;" action="/cgi-bin/action.cgi?cmd=conf_timelapse" method="post">
Interval: <input id="tlinterval" name="tlinterval" type="text" size="5" value="$(source /system/sdcard/config/timelapse.conf && echo "$TIMELAPSE_INTERVAL")"/>seconds,
Duration: <input id="tlduration" name="tlduration" type="text" size="5" value="$(source /system/sdcard/config/timelapse.conf && echo "$TIMELAPSE_DURATION")"/>minutes (set to 0 for unlimited)
<input type="submit" value="Set" />
</td>
</tr>
<tr>
<th>Start original Xiaomi Software:</th>
<td>
<button title='' type='button' onClick="call('action.cgi?cmd=xiaomi_start')">Start</button>
</td>
</tr>
<tr>
<th>Process list:</th>
<td>
<pre>$(ps)</td>
</tr>
<tr>
<th>Mounts:</th>
<td><pre>$(mount)</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</body>
</html>
<!-- RTSP -->
<div class='card status_card'>
<header class='card-header'><p class='card-header-title'>RTSP</p></header>
<div class='card-content'>
<div class="columns">
<div class="column">
<label>Night Vision</label>
<div class="buttons">
<button class="button is-link" onClick="call('/cgi-bin/action.cgi?cmd=toggle-rtsp-nightvision-on')">On</button>
<button class="button is-warning" onClick="call('/cgi-bin/action.cgi?cmd=toggle-rtsp-nightvision-off')">Off</button>
</div>
</div>
<div class="column">
<label>Flip</label>
<div class="buttons">
<button class="button is-link" onClick="call('/cgi-bin/action.cgi?cmd=flip-on')">On</button>
<button class="button is-warning" onClick="call('/cgi-bin/action.cgi?cmd=flip-off')">Off</button>
</div>
</div>
</div>
</div>
</div>
<!-- Motor -->
<div class='card status_card'>
<header class='card-header'><p class='card-header-title'>Motor</p></header>
<div class='card-content'>
<table class="motor_control">
<tr>
<td></td>
<td>
<button class="button is-link" onclick="call('/cgi-bin/action.cgi?cmd=motor_up&val='+document.getElementById('val').value)">&uarr; Up</button>
</td>
<td></td>
</tr>
<tr>
<td>
<button class="button is-link" onclick="call('/cgi-bin/action.cgi?cmd=motor_left&val='+document.getElementById('val').value)">&larr; Left</button>
</td>
<td>
<input class="input has-text-centered" type="text" id="val" name="val" value="100">
</td>
<td>
<button class="button is-link" onclick="call('/cgi-bin/action.cgi?cmd=motor_right&val='+document.getElementById('val').value)">Right &rarr;</button>
</td>
</tr>
<tr>
<td></td>
<td>
<button class="button is-link" onclick="call('/cgi-bin/action.cgi?cmd=motor_down&val='+document.getElementById('val').value)">&darr; Down</button>
</td>
<td></td>
</tr>
</table>
<div class="buttons">
<button class="button is-warning" onclick="call('/cgi-bin/action.cgi?cmd=motor_vcalibrate'">Calibrate Vertical</button>
<button class="button is-warning" onclick="call('/cgi-bin/action.cgi?cmd=motor_hcalibrate">Calibrate Horizontal</button>
</div>
</div>
</div>
<!-- Audio / Image -->
<div class='card status_card'>
<header class='card-header'><p class='card-header-title'>Tests</p></header>
<div class='card-content'>
<div class="columns">
<div class="column">
<label>Audio Test</label>
<div class="buttons">
<button class="button is-link" onClick="call('/cgi-bin/action.cgi?cmd=audio_test')">Test</button>
</div>
</div>
<div class="column">
<label>Image</label>
<div class="buttons">
<a class="button is-link" href='/cgi-bin/currentpic.cgi' target='_blank'>Get</a>
</div>
</div>
</div>
</div>
</div>
<!-- Resolution -->
<!--
This section was introduced in:
https://github.com/EliasKotlyar/Xiaomi-Dafang-Hacks/commit/eabe4cb9beb9243edba708967ab1de65d4861834
https://github.com/EliasKotlyar/Xiaomi-Dafang-Hacks/commit/34837e0383051b6251e9ecc891c9f87e0804a8c2
but there is no setvideosize in action.cgi and video_size.conf is not used anywhere else
-->
<!--
<div class='card status_card'>
<header class='card-header'><p class='card-header-title'>Resolution</p></header>
<div class='card-content'>
<form id="formResolution" action="/cgi-bin/action.cgi?cmd=setvideosize" method="post">
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label">Video Size</label>
</div>
<div class="field-body">
<div class="field">
<div class="control">
<div class="select">
<select name="video_size">
<option value="-W 640 -H 360" $(if [ "$(cat /system/sdcard/config/video_size.conf | grep 640)" != "" ]; then echo selected; fi)>640x360</option>
<option value="-W 1280 -H 720" $(if [ "$(cat /system/sdcard/config/video_size.conf | grep 1280)" != "" ]; then echo selected; fi)>1280x720</option>
<option value="-W 1600 -H 900" $(if [ "$(cat /system/sdcard/config/video_size.conf | grep 1600)" != "" ]; then echo selected; fi)>1600x900</option>
<option value="-W 1920 -H 1080" $(if [ "$(cat /system/sdcard/config/video_size.conf | grep 1920)" != "" ]; then echo selected; fi)>1920x1080</option>
</select>
</div>
</div>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
</div>
<div class="field-body">
<div class="field">
<div class="control">
<input id="resSubmit" class="button is-primary" type="submit" value="Set" />
</div>
</div>
</div>
</div>
</form>
</div>
</div>
-->
<!-- H264 RTSP -->
<div class='card status_card'>
<header class='card-header'><p class='card-header-title'>Start H264 RTSP</p></header>
<div class='card-content'>
<button class="button is-link" onClick="call('/cgi-bin/action.cgi?cmd=h264_start')">Start</button>
<button class="button is-warning" onClick="call('/cgi-bin/action.cgi?cmd=rtsp_stop')">Stop</button>
EOF
PATH="/bin:/sbin:/usr/bin:/media/mmcblk0p2/data/bin:/media/mmcblk0p2/data/sbin:/media/mmcblk0p2/data/usr/bin"
IP=$(ifconfig wlan0 |grep "inet addr" |awk '{print $2}' |awk -F: '{print $2}')
echo "<p>Path to feed : <a href='rtsp://$IP:8554/unicast'>rtsp://$IP:8554/unicast</a></p>"
echo "<p>HLS : <a href='http://$IP:8554/unicast.m3u8'>http://$IP:8554/unicast.m3u8</a></p>"
echo "<p>MPEG-DASH : <a href='http://$IP:8554/unicast.mpd'>http://$IP:8554/unicast.mpd</a></p>"
cat << EOF
</div>
</div>
<!-- MJPEG RTSP -->
<div class='card status_card'>
<header class='card-header'><p class='card-header-title'>Start MJGEP RTSP</p></header>
<div class='card-content'>
<button class="button is-link" onClick="call('/cgi-bin/action.cgi?cmd=mjpeg_start')">Start</button>
<button class="button is-warning" onClick="call('/cgi-bin/action.cgi?cmd=rtsp_stop')">Stop</button>
EOF
PATH="/bin:/sbin:/usr/bin:/media/mmcblk0p2/data/bin:/media/mmcblk0p2/data/sbin:/media/mmcblk0p2/data/usr/bin"
IP=$(ifconfig wlan0 |grep "inet addr" |awk '{print $2}' |awk -F: '{print $2}')
echo "<p>Path to feed : <a href='rtsp://$IP:8554/unicast'>rtsp://$IP:8554/unicast</a></p>"
cat << EOF
</div>
</div>
<!-- OSD -->
<div class='card status_card'>
<header class='card-header'><p class='card-header-title'>OSD Display</p></header>
<div class='card-content'>
<form id="formOSD" action="/cgi-bin/action.cgi?cmd=osd" method="post">
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label">Enable Text</label>
</div>
<div class="field-body">
<div class="field is-grouped">
<p class="control">
<input type="checkbox" name="OSDenable" value="enabled" $(if [ -f /system/sdcard/config/osd ]; then echo checked; fi) />
</p>
<p class="control">
<input class="input" id="osdtext" name="osdtext" type="text" size="25" value="$(source /system/sdcard/config/osd && echo "$OSD")"/>
<span class="help">
Enter time-variables in <a href="http://strftime.org/" target="_blank">strftime</a> format
</span>
</p>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label">OSD Color</label>
</div>
<div class="field-body">
<div class="field">
<div class="control">
<div class="select">
<select name="color">
<option value="0" $(if [ "$(grep COLOR /system/sdcard/config/osd | sed s/COLOR=//)" -eq 0 ]; then echo selected; fi)>White</option>
<option value="1" $(if [ "$(grep COLOR /system/sdcard/config/osd | sed s/COLOR=//)" -eq 1 ]; then echo selected; fi)>Black</option>
<option value="2" $(if [ "$(grep COLOR /system/sdcard/config/osd | sed s/COLOR=//)" -eq 2 ]; then echo selected; fi)>Red</option>
<option value="3" $(if [ "$(grep COLOR /system/sdcard/config/osd | sed s/COLOR=//)" -eq 3 ]; then echo selected; fi)>Green</option>
<option value="4" $(if [ "$(grep COLOR /system/sdcard/config/osd | sed s/COLOR=//)" -eq 4 ]; then echo selected; fi)>Blue</option>
<option value="5" $(if [ "$(grep COLOR /system/sdcard/config/osd | sed s/COLOR=//)" -eq 5 ]; then echo selected; fi)>Cyan</option>
<option value="6" $(if [ "$(grep COLOR /system/sdcard/config/osd | sed s/COLOR=//)" -eq 6 ]; then echo selected; fi)>Yellow</option>
<option value="7" $(if [ "$(grep COLOR /system/sdcard/config/osd | sed s/COLOR=//)" -eq 7 ]; then echo selected; fi)>Purple</option>
</select>
</div>
</div>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label">OSD Text Size</label>
</div>
<div class="field-body">
<div class="field">
<div class="control">
<div class="select">
<select name="size">
<option value="0" $(if [ "$(grep SIZE /system/sdcard/config/osd | sed s/SIZE=//)" -eq 0 ]; then echo selected; fi)>Small</option>
<option value="1" $(if [ "$(grep SIZE /system/sdcard/config/osd | sed s/SIZE=//)" -eq 1 ]; then echo selected; fi)>Bigger</option>
</select>
</div>
</div>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label">Pixels between chars</label>
</div>
<div class="field-body">
<div class="field">
<p class="control">
<input class="input" id="spacepixels" name="spacepixels" type="number" size="4" value="$(source /system/sdcard/config/osd && echo "$SPACE")"/>
</p>
<p class="help">Can be negative</p>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label">Y Position</label>
</div>
<div class="field-body">
<div class="field">
<p class="control">
<input class="input" id="posy" name="posy" type="number" size="6" value="$(source /system/sdcard/config/osd && echo "$POSY")"/>
</p>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label">Fixed width</label>
</div>
<div class="field-body">
<div class="field">
<div class="control">
<div class="select">
<select name="fixedw">
<option value="0" $(if [ "$(grep FIXEDW /system/sdcard/config/osd | sed s/FIXEDW=//)" -eq 0 ]; then echo selected; fi)>No</option>
<option value="1" $(if [ "$(grep FIXEDW /system/sdcard/config/osd | sed s/FIXEDW=//)" -eq 1 ]; then echo selected; fi)>Yes</option>
</select>
</div>
</div>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
</div>
<div class="field-body">
<div class="field">
<div class="control">
<input id="osdSubmit" class="button is-primary" type="submit" value="Set" />
</div>
</div>
</div>
</div>
</form>
</div>
</div>
<!-- OSD Debug -->
<div class='card status_card'>
<header class='card-header'><p class='card-header-title'>Display debug info on OSD</p></header>
<div class='card-content'>
<button class="button is-link" onClick="call('/cgi-bin/action.cgi?cmd=onDebug')">On</button>
<button class="button is-warning" onClick="call('/cgi-bin/action.cgi?cmd=offDebug')">Off</button>
</div>
</div>
<!-- Timelapse -->
<div class='card status_card'>
<header class='card-header'><p class='card-header-title'>Timelapse</p></header>
<div class='card-content'>
<form id="formTimelapse" action="/cgi-bin/action.cgi?cmd=conf_timelapse" method="post">
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label">Interval</label>
</div>
<div class="field-body">
<div class="field">
<div class="control">
<input class="input" id="tlinterval" name="tlinterval" type="text" size="5" value="$(source /system/sdcard/config/timelapse.conf && echo "$TIMELAPSE_INTERVAL")"/> seconds
</div>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
<label class="label">Duration</label>
</div>
<div class="field-body">
<div class="field">
<div class="control">
<input class="input" id="tlduration" name="tlduration" type="text" size="5" value="$(source /system/sdcard/config/timelapse.conf && echo "$TIMELAPSE_DURATION")"/> minutes
</div>
<p class="help">Set to 0 for unlimited</p>
</div>
</div>
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
</div>
<div class="field-body">
<div class="field">
<div class="control">
<input id="tlSubmit" class="button is-primary" type="submit" value="Set" />
</div>
</div>
</div>
</div>
</form>
</div>
</div>
<!-- Original Xiaomi Software -->
<div class='card status_card'>
<header class='card-header'><p class='card-header-title'>Start original Xiaomi Software</p></header>
<div class='card-content'>
<button class="button" onClick="call('/cgi-bin/action.cgi?cmd=xiaomi_start')">Start</button>
</div>
</div>
<!-- Process List -->
<div class='card status_card'>
<header class='card-header'><p class='card-header-title'>Process List</p></header>
<div class='card-content'>
<pre>$(ps)</pre>
</div>
</div>
<!-- Mounts -->
<div class='card status_card'>
<header class='card-header'><p class='card-header-title'>Mounts</p></header>
<div class='card-content'>
<pre>$(mount)</pre>
</div>
</div>
EOF
script=$(cat /system/sdcard/www/scripts/status.cgi.js)
echo "<script>$script</script>"

View File

@@ -1,211 +1,250 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "
http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!-- Use http://odyniec.net/projects/imgareaselect/ -->
<head>
<link rel="stylesheet" type="text/css" href="css/imgareaselect-animated.css" />
<script type="text/javascript" src="scripts/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="scripts/jquery.imgareaselect.pack.js"></script>
<title>Motion Configuration</title>
<style type="text/css">
body {
background-color: #B0E0E6;
font-family: verdana, sans-serif;
}
<script type="text/javascript">
.err {
color: red;
}
var originalMotionInfo;
hr {
height: 1px;
border: 0;
border-top: 1px solid #aaa;
}
button,
input[type=submit] {
background-color: #ddeaff;
}
.tbl {
border-collapse: collapse;
border-spacing: 0;
}
.tbl th {
text-align: left;
vertical-align: top;
font-weight: bold;
padding: 10px 5px;
border-style: solid;
border-width: 1px;
overflow: hidden;
word-break: normal;
}
.tbl td {
padding: 10px 5px;
border-style: solid;
border-width: 1px;
overflow: hidden;
word-break: normal;
}
.img h2 {
position: absolute;
top: 20%;
left: 20%;
font-size: 28pt;
text-align: center;
background-color: #B0E0E6
}
</style>
<script type="text/javascript">
function preview(img, selection) {
if (!selection.width || !selection.height)
return;
if (!selection.width || !selection.height) {
return;
}
var scaleX = 100 / selection.width;
var scaleY = 100 / selection.height;
var image = $(img);
$('#x0').val(selection.x1);
$('#y0').val(selection.y1);
$('#x1').val(selection.x2);
$('#y1').val(selection.y2);
$('#restart_server').val(1);
var scaleX = 100 / selection.width;
var scaleY = 100 / selection.height;
var originalWidth = image.prop('naturalWidth');
var originalHeight = image.prop('naturalHeight');
var renderedWidth = image.width();
var renderedHeight = image.height();
var x0 = Math.round((selection.x1 / renderedWidth) * originalWidth);
var y0 = Math.round((selection.y1 / renderedHeight) * originalHeight);
var x1 = Math.round((selection.x2 / renderedWidth) * originalWidth);
var y1 = Math.round((selection.y2 / renderedHeight) * originalHeight);
$('#x0').val(x0);
$('#y0').val(y0);
$('#x1').val(x1);
$('#y1').val(y1);
if (originalMotionInfo.region_of_interest[0] != x0 ||
originalMotionInfo.region_of_interest[1] != y0 ||
originalMotionInfo.region_of_interest[2] != x1 ||
originalMotionInfo.region_of_interest[3] != y1) {
// restart only if region has changed
$('#restart_server').val(1);
}
}
function setTracking(obj,init) {
function setTracking(obj, init) {
var ias = $('#picture').imgAreaSelect({
instance: true
var picture = $('#motion_picture');
var region_disabled = $('#region_disabled');
var motion_timeout = $('#motion_timeout');
var ias = picture.imgAreaSelect({
instance: true
});
if($(obj).is(":checked")){
ias.setOptions({
hide: true
});
$('#picture').css('opacity',0.5);
$("#RegionDisabled").show();
document.getElementById('motion_timeout').readOnly = false;
document.getElementById('motion_timeout').style.backgroundColor = "#FFFFFF";
if ($(obj).prop("checked")) {
ias.setOptions({
hide: true
});
picture.css('opacity', 0.5);
region_disabled.show();
motion_timeout.prop('readonly', false);
motion_timeout.css('backgroundColor', '#fff');
}else{
ias.setOptions({
show: true
});
$('#picture').css('opacity',1);
$("#RegionDisabled").hide();
document.getElementById('motion_timeout').readOnly = true;
document.getElementById('motion_timeout').style.backgroundColor = "#B0E0E6";
}
ias.update();
} else {
ias.setOptions({
show: true
});
picture.css('opacity', 1);
region_disabled.hide();
// grey out and disable field
motion_timeout.prop('readonly', true);
motion_timeout.css('backgroundColor', '#ccc');
}
ias.update();
if (init == false) {
$('#restart_server').val(1);
}
if (init == false) {
$('#restart_server').val(1);
}
}
$(function() {
var httpRequest = new XMLHttpRequest();
httpRequest.open('GET', 'cgi-bin/getMotionInfo.cgi', false);
httpRequest.send(null);
eval(httpRequest.responseText)
$('#picture').imgAreaSelect({
handles: true,
fadeSpeed: 200,
onSelectChange: preview,
movable: true,
persistent: true
});
var ias = $('#picture').imgAreaSelect({
instance: true
});
$(function () {
// Attach css to head <link rel="stylesheet" type="text/css" href="css/imgareaselect-animated.css" />
var imgareaselectCss = $("<link>", {
"rel": "stylesheet",
"type": "text/css",
"href": "css/imgareaselect-animated.css"
});
$('head').append(imgareaselectCss);
if ((region_of_interest[0] == 0 && region_of_interest[1] == 0 && region_of_interest[2] == 0 && region_of_interest[3] == 0) ||
(region_of_interest[0] > width || region_of_interest[1] > height || region_of_interest[2] > width || region_of_interest[3] > height))
{
ias.setSelection(0, 0, width, height, true);
}
else
{
ias.setSelection(region_of_interest[0], region_of_interest[1], region_of_interest[2], region_of_interest[3], false);
}
$.getScript('scripts/jquery.imgareaselect.pack.js', function () {
// imgareaselect script loaded
// get motion config info
$.ajax({
'url': 'cgi-bin/getMotionInfo.cgi',
'dataType': 'json'
}).done(function (motionInfo) {
originalMotionInfo = motionInfo;
var picture = $('#motion_picture');
picture.imgAreaSelect({
handles: true,
fadeSpeed: 200,
onSelectChange: preview,
movable: true,
persistent: true,
parent: '#motion_img_container'
});
var ias = picture.imgAreaSelect({
instance: true
});
if (motionInfo.region_of_interest[0] + motionInfo.region_of_interest[1] +
motionInfo.region_of_interest[2] + motionInfo.region_of_interest[3] == 0 ||
(motionInfo.region_of_interest[0] > motionInfo.width ||
motionInfo.region_of_interest[1] > motionInfo.height ||
motionInfo.region_of_interest[2] > motionInfo.width ||
motionInfo.region_of_interest[3] > motionInfo.height)
) {
ias.setSelection(0, 0, motionInfo.width, motionInfo.height, true);
} else {
ias.setSelection(
motionInfo.region_of_interest[0], motionInfo.region_of_interest[1],
motionInfo.region_of_interest[2], motionInfo.region_of_interest[3], false);
}
$('#x0').val(motionInfo.region_of_interest[0]);
$('#y0').val(motionInfo.region_of_interest[1]);
$('#x1').val(motionInfo.region_of_interest[2]);
$('#y1').val(motionInfo.region_of_interest[3]);
$('#restart_server').val(0);
$('#motion_indicator_color').val(motionInfo.motion_indicator_color).change();
$('#motion_sensitivity').val(motionInfo.motion_sensitivity).change();
$('#motion_tracking').prop('checked', motionInfo.motion_tracking);
$('#motion_timeout').val(motionInfo.motion_timeout).change();
setTracking($('#motion_tracking')[0], true);
});
});
$('#confMotionForm').submit(function (event) {
var b = $('#configMotionSubmit');
b.toggleClass('is-loading');
b.prop('disabled', !b.prop('disabled'));
var motion_tracking = '';
if ($('#motion_tracking').prop('checked')) {
motion_tracking = 'true';
}
var formData = {
'x0': $('input[name=x0]').val(),
'y0': $('input[name=y0]').val(),
'x1': $('input[name=x1]').val(),
'y1': $('input[name=y1]').val(),
'restart_server': $('input[name=restart_server]').val(),
'motion_sensitivity': $('select[name=motion_sensitivity]').val(),
'motion_indicator_color': $('select[name=motion_indicator_color]').val(),
'motion_tracking': $('input[name=motion_tracking]').val(),
'motion_timeout': $('input[name=motion_timeout]').val()
};
$.ajax({
type: 'POST',
url: $('#confMotionForm').attr('action'),
data: formData,
dataType: 'html',
encode: true
}).done(function (res) {
b.toggleClass('is-loading');
b.prop('disabled', !b.prop('disabled'));
showResult(res);
});
event.preventDefault();
});
$('#x0').val(region_of_interest[0]);
$('#y0').val(region_of_interest[1]);
$('#x1').val(region_of_interest[2]);
$('#y1').val(region_of_interest[3]);
$('#restart_server').val(0);
$('#motion_indicator_color').val(motion_indicator_color).change();
$('#motion_sensitivity').val(motion_sensitivity).change();
console.log(motion_tracking);
$('#motion_tracking').prop('checked',motion_tracking);
$('#motion_timeout').val(motion_timeout).change();
setTracking( $('#motion_tracking').get(0), true);
});
</script>
<h1 class="is-size-4">Configure Motion Settings</h1>
<p>
Select motion detection region. Changing the region will restart the rtsp server.
</p>
<div id="motion_img_container" style="margin: 1em 0; position:relative;">
<img id="motion_picture" src="/cgi-bin/currentpic.cgi" />
<span id="region_disabled" class="has-text-danger is-size-1" style="display: none; position: absolute; top: 10%; left: 30%; padding: 0.25em 0.5em; background-color: rgba(20, 20, 20, 0.5); border-radius: 0.25em;">
Region disabled
</span>
</div>
</script>
</head>
<body onload="">
<div class="container">
<div style="float: left; width: 50%;">
<p class="instructions">
Select motion detection region (changing region will restart the rtsp server)
</p>
<div class="img" style="margin: 0 0.3em;">
<img id="picture" src="/cgi-bin/currentpic.cgi" />
<span id="RegionDisabled">
<h2> Region disabled</h2>
</span>
</div>
<form style="margin: 0px" action="/cgi-bin/action.cgi?cmd=set_region_of_interest" method="post">
<div class="column is-two-thirds">
<form id="confMotionForm" action="/cgi-bin/action.cgi?cmd=set_region_of_interest" method="post">
<input id="x0" name="x0" type="hidden" />
<input id="y0" name="y0" type="hidden" />
<input id="x1" name="x1" type="hidden" />
<input id="y1" name="y1" type="hidden" />
<input id="restart_server" name="restart_server" type="hidden" /> Set sensitivity or deactivate
<select name="motion_sensitivity" id="motion_sensitivity">
<option value="-1">Motion deactivated</option>
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<input id="restart_server" name="restart_server" type="hidden" />
<br>Display motion indicator if motion is detected
<select name="motion_indicator_color" id="motion_indicator_color">
<option value="-1">Deactivated</option>
<option value="0">White</option>
<option value="1">Black</option>
<option value="2">Red</option>
<option value="3">Green</option>
<option value="4">Blue</option>
<option value="5">Cyan</option>
<option value="6">Yellow</option>
<option value="7">Purple</option>
</select>
<br>
Enable motion tracking (when enabled no region of interest is no more used)
<input type="checkbox" name="motion_tracking" id="motion_tracking" onchange="setTracking(this, false)">
<br> Motion Timeout (restore camera position after x seconds) -1 to deactivate
<input id="motion_timeout" name="motion_timeout" type="number" size="6">
<br>
<input type="submit" value="Configure motion" />
<div class="field">
<label class="label">Set sensitivity or deactivate</label>
<div class="control">
<div class="select">
<select name="motion_sensitivity" id="motion_sensitivity">
<option value="-1">Motion deactivated</option>
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</div>
</div>
</div>
</form>
</div>
</div>
</body>
<div class="field">
<label class="label">Display motion indicator if motion is detected</label>
<div class="control">
<div class="select">
<select name="motion_indicator_color" id="motion_indicator_color">
<option value="-1">Deactivated</option>
<option value="0">White</option>
<option value="1">Black</option>
<option value="2">Red</option>
<option value="3">Green</option>
<option value="4">Blue</option>
<option value="5">Cyan</option>
<option value="6">Yellow</option>
<option value="7">Purple</option>
</select>
</div>
</div>
</div>
<div class="field">
<div class="control">
<label class="checkbox">
<input type="checkbox" name="motion_tracking" id="motion_tracking" onchange="setTracking(this, false)"> Enable motion tracking (when enabled no region of interest is no more used)
</label>
</div>
</div>
<div class="field">
<label class="label">Motion Timeout</label>
<div class="control">
<input class="input" id="motion_timeout" name="motion_timeout" type="number" size="6">
</div>
<p class="help">Restore camera position after x seconds, -1 to deactivate</p>
</div>
<div class="field">
<div class="control">
<input id="configMotionSubmit" class="button is-primary" type="submit" value="Configure motion" />
</div>
</div>
</form>
</div>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
@-webkit-keyframes spinAround{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spinAround{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.quickview{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;background-color:#fff;max-width:calc(100% - 50px);position:fixed;top:0;bottom:0;z-index:35;-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-transition:.3s ease;transition:.3s ease;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000;will-change:transform}.quickview.is-marginless{max-width:100%}@media screen and (max-width:768px){.quickview{width:100%;right:-100%}}@media screen and (min-width:769px),print{.quickview{width:50%;right:-50%}}@media screen and (min-width:1024px){.quickview{width:35%;right:-35%}}@media screen and (min-width:1216px){.quickview{width:30%;right:-30%}}@media screen and (min-width:1408px){.quickview{width:25%;right:-25%}}@media screen and (max-width:768px){.quickview.is-left{left:-100%}}@media screen and (min-width:769px),print{.quickview.is-left{left:-50%}}@media screen and (min-width:1024px){.quickview.is-left{left:-35%}}@media screen and (min-width:1216px){.quickview.is-left{left:-30%}}@media screen and (min-width:1408px){.quickview.is-left{left:-25%}}.quickview.is-active{right:0;-webkit-box-shadow:5px 0 13px 3px rgba(0,0,0,.1);box-shadow:5px 0 13px 3px rgba(0,0,0,.1)}.quickview.is-active.is-left{left:0}.quickview-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:0 1rem;min-height:3.25em!important;border-bottom:1px solid #dbdbdb}.quickview-header.is-white{background-color:#fff}.quickview-header.is-white .title{color:#0a0a0a}.quickview-header.is-black{background-color:#0a0a0a}.quickview-header.is-black .title{color:#fff}.quickview-header.is-light{background-color:#f5f5f5}.quickview-header.is-light .title{color:#363636}.quickview-header.is-dark{background-color:#363636}.quickview-header.is-dark .title{color:#f5f5f5}.quickview-header.is-primary{background-color:#00d1b2}.quickview-header.is-primary .title{color:#fff}.quickview-header.is-link{background-color:#3273dc}.quickview-header.is-link .title{color:#fff}.quickview-header.is-info{background-color:#209cee}.quickview-header.is-info .title{color:#fff}.quickview-header.is-success{background-color:#23d160}.quickview-header.is-success .title{color:#fff}.quickview-header.is-warning{background-color:#ffdd57}.quickview-header.is-warning .title{color:rgba(0,0,0,.7)}.quickview-header.is-danger{background-color:#ff3860}.quickview-header.is-danger .title{color:#fff}.quickview-header .title{font-size:1rem;font-weight:300;margin-bottom:0}.quickview-header .title img{max-height:2em}.quickview-body{-webkit-box-flex:1;-ms-flex:1 1 0%;flex:1 1 0%;overflow-y:auto}.quickview-footer{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:0 1rem;min-height:4rem;background-color:#f5f5f5;border-top:1px solid #dbdbdb}.quickview-footer>*{margin:0 .4rem}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1,16 +1,245 @@
<html>
<!DOCTYPE html>
<html class="has-navbar-fixed-top">
<head>
<script type="text/javascript">
function Redirect() {
window.location = "/cgi-bin/status.cgi";
<meta charset=utf-8 />
<title>DafangHacks</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSS Framework -->
<link href="css/bulma.0.6.2.min.css" rel="stylesheet">
<link href="css/bulma-switch.1.0.1.min.css" rel="stylesheet">
<link href="css/bulma-badge.1.0.1.min.css" rel="stylesheet">
<link href="css/bulma-quickview.1.0.1.min.css" rel="stylesheet">
<!-- jQuery -->
<script src="scripts/jquery-3.3.1.min.js" type="text/javascript"></script>
<style id="custom_css">
body {
display: flex;
min-height: 100vh;
flex-direction: column;
}
document.write("You will be redirected to main page in 1 sec.");
setTimeout('Redirect()', 1);
</script>
#main {
flex: 1 0 auto;
}
.script_card,
.status_card {
max-width: 100%;
margin-bottom: 1em;
}
@media screen and (min-width: 1024px) {
.script_card,
.status_card {
max-width: 75%
}
}
.script_card div.show_script {
margin-top: 0.5em;
}
table.motor_control td {
width: 120px;
}
table.motor_control td button {
width: 100%;
}
#liveview {
padding: 0.25em;
border: dotted 1px #4a4a4a;
display: block;
margin: 0 auto;
}
#motion_picture {
display: block;
}
</style>
</head>
<body>
<nav class="navbar is-fixed-top" role="navigation" aria-label="main navigation">
<div class="container">
<div class="navbar-brand">
<a class="navbar-item" href="/">Dafang Hacks</a>
<a id="navbar_burger" role="button" class="navbar-burger" data-target="nav_menu" aria-label="menu" aria-expanded="false">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div class="navbar-menu" id="nav_menu">
<!-- left menu -->
<div class="navbar-start" id="common_nav">
<div class="navbar-item has-dropdown is-hoverable">
<span class="navbar-link">Manage</span>
<div class="navbar-dropdown is-boxed">
<a id="status" class="navbar-item onpage" href="javascript: void(0)" data-target="/cgi-bin/status.cgi">Status</a>
<a id="scripts" class="navbar-item onpage" href="javascript: void(0)" data-target="/cgi-bin/scripts.cgi">Manage Scripts</a>
<a id="network" class="navbar-item onpage" href="javascript: void(0)" data-target="/cgi-bin/network.cgi">Network Settings</a>
<a id="logs" class="navbar-item onpage" href="javascript: void(0)" data-target="/cgi-bin/action.cgi?cmd=showlog">Logs</a>
<a id="configmotion" class="navbar-item onpage" href="javascript: void(0)" data-target="/configmotion.html">Motion Config</a>
<a class="navbar-item prompt" href="javascript: void(0)" data-message="Are you sure you wish to reboot?" data-target="/cgi-bin/action.cgi?cmd=reboot">Reboot</a>
<a class="navbar-item prompt" href="javascript: void(0)" data-message="Are you sure you wish to shutdown?" data-target="/cgi-bin/action.cgi?cmd=shutdown">Shutdown</a>
</div>
</div>
<a class="navbar-item" href="javascript: getLiveImage();">Live</a>
</div>
<!-- right menu -->
<div class="navbar-end">
<div id="camcontrol_link" class="navbar-item has-dropdown">
<!-- Camera Movement Controls -->
<span class="navbar-link">Camera Controls</span>
<div class="navbar-dropdown is-boxed is-right">
<!-- left -->
<a class="navbar-item cam_button" href="javascript:void(0)" data-cmd="motor_left">
&#x25C0;
</a>
<!-- right -->
<a class="navbar-item cam_button" href="javascript:void(0)" data-cmd="motor_right">
&#x25B6;
</a>
<!-- up -->
<a class="navbar-item cam_button" href="javascript:void(0)" data-cmd="motor_up">
&#x25B2;
</a>
<!-- down -->
<a class="navbar-item cam_button" href="javascript:void(0)" data-cmd="motor_down">
&#x25BC;
</a>
<!-- Led: IR -->
<span class="navbar-item">
<input id="ir_led" type="checkbox" name="ir_led" class="switch" data-checked="/cgi-bin/action.cgi?cmd=ir_led_on" data-unchecked="/cgi-bin/action.cgi?cmd=ir_led_off">
<label for="ir_led">IR Led</label>
</span>
<!-- IR Cut -->
<span class="navbar-item">
<input id="ir_cut" type="checkbox" name="ir_cut" class="switch" data-checked="/cgi-bin/action.cgi?cmd=ir_cut_on" data-unchecked="/cgi-bin/action.cgi?cmd=ir_cut_off">
<label for="ir_cut">IR-Cut</label>
</span>
<!-- Auto Night Detect -->
<span class="navbar-item">
<input id="auto_night_detection" type="checkbox" name="auto_night_detection" class="switch" data-checked="/cgi-bin/scripts.cgi?cmd=start&script=auto-night-detection"
data-unchecked="/cgi-bin/scripts.cgi?cmd=stop&script=auto-night-detection">
<label for="auto_night_detection">Auto Night Detection</label>
</span>
<!-- LED: Blue -->
<span class="navbar-item">
<input id="blue_led" type="checkbox" name="blue_led" class="switch" data-checked="/cgi-bin/action.cgi?cmd=blue_led_on" data-unchecked="/cgi-bin/action.cgi?cmd=blue_led_off">
<label for="blue_led">Blue LED</label>
</span>
<!-- LED: Yellow -->
<span class="navbar-item">
<input id="yellow_led" type="checkbox" name="yellow_led" class="switch" data-checked="/cgi-bin/action.cgi?cmd=yellow_led_on"
data-unchecked="/cgi-bin/action.cgi?cmd=yellow_led_off">
<label for="yellow_led">Yellow LED</label>
</span>
<!-- Motion Detection -->
<span class="navbar-item">
<input id="motion_detection" type="checkbox" name="motion_detection" class="switch" data-checked="/cgi-bin/action.cgi?cmd=motion_detection_on"
data-unchecked="/cgi-bin/action.cgi?cmd=motion_detection_off">
<label for="motion_detection">Motion Detection</label>
</span>
<!-- RTSP H264 -->
<span class="navbar-item">
<input id="rtsp_h264" type="checkbox" name="rtsp_h264" class="switch" data-checked="/cgi-bin/scripts.cgi?cmd=start&script=rtsp-h264"
data-unchecked="/cgi-bin/scripts.cgi?cmd=stop&script=rtsp-h264">
<label for="rtsp_h264">RTSP H264 Server</label>
</span>
<!-- RTSP MJPEG -->
<span class="navbar-item">
<input id="rtsp_mjpeg" type="checkbox" name="rtsp_mjpeg" class="switch" data-checked="/cgi-bin/scripts.cgi?cmd=start&script=rtsp-mjpeg"
data-unchecked="/cgi-bin/scripts.cgi?cmd=stop&script=rtsp-mjpeg">
<label for="rtsp_mjpeg">RTSP MJPEG Server</label>
</span>
<!-- MQTT Status -->
<span class="navbar-item">
<input id="mqtt_control" type="checkbox" name="mqtt_control" class="switch" data-checked="/cgi-bin/scripts.cgi?cmd=start&script=mqtt-status"
data-unchecked="/cgi-bin/scripts.cgi?cmd=stop&script=mqtt-status">
<label for="mqtt_control">MQTT Status Server</label>
</span>
<!-- MQTT Control -->
<span class="navbar-item">
<input id="mqtt_status" type="checkbox" name="mqtt_status" class="switch" data-checked="/cgi-bin/scripts.cgi?cmd=start&script=mqtt-control"
data-unchecked="/cgi-bin/scripts.cgi?cmd=stop&script=mqtt-control">
<label for="mqtt_status">MQTT Control Server</label>
</span>
<!-- Startup Sound -->
<span class="navbar-item">
<input id="sound_on_startup" type="checkbox" name="sound_on_startup" class="switch" data-checked="/cgi-bin/scripts.cgi?cmd=start&script=sound-on-startup"
data-unchecked="/cgi-bin/scripts.cgi?cmd=stop&script=sound-on-startup">
<label for="sound_on_startup">Sound on Startup</label>
</span>
</div>
</div>
</div>
</div>
</div>
</nav>
<section id="main" class="section">
<div id="content" class="container">
<a id="liveviewlink" href="/cgi-bin/currentpic.cgi">
<img id="liveview" src="/cgi-bin/currentpic.cgi" onerror="this.src='css/unable_load.png';">
</a>
</div>
</section>
<footer class="footer">
<div class="container">
<div class="has-text-centered is-size-7">
<p>
<a href="https://github.com/EliasKotlyar/Xiaomi-Dafang-Hacks" target="_blank">
<strong>Dafang Hacks</strong>
</a> v0.0.1.
<a href="https://github.com/EliasKotlyar/Xiaomi-Dafang-Hacks/issues" target="_blank">Issues?</a>
</p>
<div class="dropdown is-hoverable">
<div class="dropdown-trigger">
<a class="is-small is-link" aria-haspopup="true" aria-controls="dropdown-menu">
<span>Theme</span>
</a>
</div>
<div class="dropdown-menu" role="menu">
<div class="dropdown-content">
<a id="theme_choice_0" href="javascript: setTheme('0')" class="theme_choice dropdown-item" data-css="css/bulma.0.6.2.min.css">
Light
</a>
<a id="theme_choice_1" href="javascript: setTheme('1')" class="theme_choice dropdown-item" data-css="https://cdn.jsdeliver.net/npm/bulmaswatch@0.6.2/slate/bulmaswatch.min.css">
Dark
</a>
</div>
</div>
</div>
</div>
</footer>
<div id="quickviewDefault" class="quickview">
<header class="quickview-header">
<p class="title">Quickview</p>
<span id="quickViewClose" class="delete" data-dismiss="quickview"></span>
</header>
<div class="quickview-body">
<div class="quickview-block" id="quicViewContent">
</div>
</div>
<footer class="quickview-footer">
</footer>
</div>
<script src="scripts/index.html.js" type="text/javascript"></script>
</body>
</html>

View File

@@ -1,558 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
body {
font-family: "Lato", sans-serif;
}
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: #111;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
}
.sidenav a {
padding: 6px 8px 6px 16px;
text-decoration: none;
font-size: 20px;
color: #818181;
display: block;
border: none;
background: none;
text-align: left;
cursor: pointer;
outline: none;
}
.dropdown-btn {
padding: 6px 8px 6px 16px;
text-decoration: none;
font-size: 20px;
color: #818181;
display: block;
border: none;
background: none;
text-align: left;
cursor: pointer;
outline: none;
width: 100%;
}
.sidenav a:hover,
.dropdown-btn:hover {
color: #f1f1f1;
}
.sidenav .closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
}
/* Main content */
.main {
margin-left: 250px;
/* Same as the width of the sidenav */
font-size: 20px;
/* Increased text to enable scrolling */
padding: 0px 10px;
}
/* Add an active class to the active dropdown button */
.active {
background-color: RoyalBlue;
color: white;
}
/* Dropdown container (hidden by default). Optional: add a lighter background color and some left padding to change the design of the dropdown content */
.dropdown-container {
display: none;
background-color: #262626;
padding-left: 8px;
}
/* Optional: Style the caret down icon */
.fa-caret-down {
float: right;
padding-right: 8px;
}
.switch {
position: relative;
display: inline-block;
width: 30px;
height: 17px;
}
.switch input {
display: none;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 13px;
width: 13px;
left: 2px;
bottom: 2px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked+.slider {
background-color: RoyalBlue;
}
input:focus+.slider {
box-shadow: 0 0 1px RoyalBlue;
}
input:checked+.slider:before {
-webkit-transform: translateX(13px);
-ms-transform: translateX(13px);
transform: translateX(13px);
}
/* Rounded sliders */
.slider.round {
border-radius: 17px;
}
.slider.round:before {
border-radius: 50%;
}
@media screen and (max-height: 450px) {
.sidenav {
padding-top: 15px;
}
.sidenav a {
font-size: 18px;
}
}
</style>
<script type="text/javascript" src="scripts/jquery-3.3.1.min.js"></script>
<script>
function openNav() {
document.getElementById("mySidenav").style.width = "300px";
}
function closeNav() {
document.getElementById("mySidenav").style.width = "0";
}
setInterval(function() {
$("#liveview").attr("src", "/cgi-bin/currentpic.cgi?" + new Date().getTime());
}, 4000);
function sync_states() {
function sync_toggle(entity) {
$.get("/cgi-bin/state.cgi", {
cmd: entity
})
.done(function(status) {
console.log(entity + " status " + status);
if (status.trim() == "ON") {
$('#' + entity + '_toggle').prop('checked', true);
} else {
$('#' + entity + '_toggle').prop('checked', false);
}
});
}
var entities = ["yellow_led", "blue_led", "ir_led", "ir_cut", "rtsp_h264", "rtsp_mjpeg", "auto_night_detection", "mqtt_status", "mqtt_control", "sound_on_startup", "motion_detection"];
for (var i in entities) {
sync_toggle(entities[i]);
}
}
window.onload = sync_states;
setInterval(function() {
sync_states()
}, 4000);
</script>
</head>
<body>
<div id="mySidenav" class="sidenav">
<a href="javascript:void(0)" class="closebtn" onclick="closeNav()">&times;</a>
<a id="live" href="javascript:void(0)">Live View</a>
<button class="dropdown-btn">Commands<i class="fa fa-caret-down"></i></button>
<div class="dropdown-container">
<a id="up" href="javascript:void(0)">&#9650;</a>
<a id="down" href="javascript:void(0)">&#9660;</a>
<a id="left" href="javascript:void(0)">&#9668;</a>
<a id="right" href="javascript:void(0)">&#9658;</a>
<a id="ir_led" href="javascript:void(0)">IR Led
<label class="switch">
<input id="ir_led_toggle" type="checkbox" checked>
<span class="slider round"></span>
</label>
</a>
<a id="ir_cut" href="javascript:void(0)">IR-Cut
<label class="switch">
<input id="ir_cut_toggle" type="checkbox" checked>
<span class="slider round"></span>
</label>
</a>
<a id="auto_night_detection" href="javascript:void(0)">Auto Night Detection
<label class="switch">
<input id="auto_night_detection_toggle" type="checkbox" checked>
<span class="slider round"></span>
</label>
</a>
<a id="yellow_led" href="javascript:void(0)">Yellow Led
<label class="switch">
<input id="yellow_led_toggle" type="checkbox" checked>
<span class="slider round"></span>
</label>
</a>
<a id="blue_led" href="javascript:void(0)">Blue Led
<label class="switch">
<input id="blue_led_toggle" type="checkbox" checked>
<span class="slider round"></span>
</label>
</a>
<a id="motion_detection" href="javascript:void(0)">Motion Detection
<label class="switch">
<input id="motion_detection_toggle" type="checkbox" checked>
<span class="slider round"></span>
</label>
</a>
<a id="rtsp_h264" href="javascript:void(0)">RTSP H264 Server
<label class="switch">
<input id="rtsp_h264_toggle" type="checkbox" checked>
<span class="slider round"></span>
</label>
</a>
<a id="rtsp_mjpeg" href="javascript:void(0)">RTSP MJPEG Server
<label class="switch">
<input id="rtsp_mjpeg_toggle" type="checkbox" checked>
<span class="slider round"></span>
</label>
</a>
<a id="mqtt_status" href="javascript:void(0)">MQTT Status Server
<label class="switch">
<input id="mqtt_status_toggle" type="checkbox" checked>
<span class="slider round"></span>
</label>
</a>
<a id="mqtt_control" href="javascript:void(0)">MQTT Control Server
<label class="switch">
<input id="mqtt_control_toggle" type="checkbox" checked>
<span class="slider round"></span>
</label>
</a>
<a id="sound_on_startup" href="javascript:void(0)">Sound on Startup
<label class="switch">
<input id="sound_on_startup_toggle" type="checkbox" checked>
<span class="slider round"></span>
</label>
</a>
</div>
<button class="dropdown-btn">Administration<i class="fa fa-caret-down"></i></button>
<div class="dropdown-container">
<a id="conf" href="javascript:void(0)">Configuration</a>
<a id="scripts" href="javascript:void(0)">Scripts</a>
<a id="motion" href="javascript:void(0)">Motion detection</a>
<a id="network" href="javascript:void(0)">Network</a>
<a id="logs" href="javascript:void(0)">Logs</a>
<a id="reboot" href="javascript:void(0)">Reboot</a>
</div>
</div>
<span style="font-size:30px;cursor:pointer" onclick="openNav()">&#9776;</span>
<div id="content" align="center">
<img id="liveview" src="/cgi-bin/currentpic.cgi" width="640" height="360" />
</div>
<script>
//Dropdown menu
var dropdown = document.getElementsByClassName("dropdown-btn");
var i;
for (i = 0; i < dropdown.length; i++) {
dropdown[i].addEventListener("click", function() {
this.classList.toggle("active");
var dropdownContent = this.nextElementSibling;
if (dropdownContent.style.display === "block") {
dropdownContent.style.display = "none";
} else {
dropdownContent.style.display = "block";
}
});
}
//LIVE VIEW
$("#live").click(function() {
$("#content").html("<img id='liveview' src='/cgi-bin/currentpic.cgi' width='640' height='360'/>")
})
//COMMANDS
// UP COMMAND
$("#up").click(function() {
$.get("/cgi-bin/action.cgi?cmd=motor_up").done(function(data) {});
$("#log").html("<b>Send UP Command</b>")
})
// DOWN COMMAND
$("#down").click(function() {
$.get("/cgi-bin/action.cgi?cmd=motor_down").done(function(data) {});
$("#log").html("<b>Send DOWN Command</b>")
})
// LEFT COMMAND
$("#left").click(function() {
$.get("/cgi-bin/action.cgi?cmd=motor_left").done(function(data) {});
$("#log").html("<b>Send LEFT Command</b>")
})
// RIGHT COMMAND
$("#right").click(function() {
$.get("/cgi-bin/action.cgi?cmd=motor_right").done(function(data) {});
$("#log").html("<b>Send RIGHT Command</b>")
})
// IR LED TOGGLE
$("#ir_led").click(function() {
$.get("/cgi-bin/state.cgi", {
cmd: "ir_led"
})
.done(function(status) {
if (status.trim() == "ON") {
$.get("/cgi-bin/action.cgi?cmd=ir_led_off").done(function(data) {});
$('#ir_led_toggle').prop('checked', false);
} else {
$.get("/cgi-bin/action.cgi?cmd=ir_led_on").done(function(data) {});
$('#ir_led_toggle').prop('checked', true);
}
});
})
// IR CUT TOGGLE
$("#ir_cut").click(function() {
$.get("/cgi-bin/state.cgi", {
cmd: "ir_cut"
})
.done(function(status) {
if (status.trim() == "ON") {
$.get("/cgi-bin/action.cgi?cmd=ir_cut_off").done(function(status) {});
$('#ir_cut_toggle').prop('checked', false);
} else {
$.get("/cgi-bin/action.cgi?cmd=ir_cut_on").done(function(data) {});
$('#ir_cut_toggle').prop('checked', true);
}
});
})
// AUTO NIGHT DETECTION TOGGLE
$("#auto_night_detection").click(function() {
$.get("/cgi-bin/state.cgi", {
cmd: "auto_night_detection"
})
.done(function(status) {
if (status.trim() == "ON") {
$.get("/cgi-bin/scripts.cgi?cmd=stop&script=auto-night-detection").done(function(status) {});
$('#auto_night_detection_toggle').prop('checked', false);
} else {
$.get("/cgi-bin/scripts.cgi?cmd=start&script=auto-night-detection").done(function(data) {});
$('#auto_night_detection_toggle').prop('checked', true);
}
});
})
// BLUE LED TOGGLE
$("#blue_led").click(function() {
$.get("/cgi-bin/state.cgi", {
cmd: "blue_led"
})
.done(function(status) {
if (status.trim() == "ON") {
$.get("/cgi-bin/action.cgi?cmd=blue_led_off").done(function(data) {});
$('#blue_led_toggle').prop('checked', false);
} else {
$.get("/cgi-bin/action.cgi?cmd=blue_led_on").done(function(data) {});
$('#blue_led_toggle').prop('checked', true);
}
});
})
// YELLOW LED TOGGLE
$("#yellow_led").click(function() {
$.get("/cgi-bin/state.cgi", {
cmd: "yellow_led"
})
.done(function(status) {
if (status.trim() == "ON") {
$.get("/cgi-bin/action.cgi?cmd=yellow_led_off").done(function(data) {});
$('#yellow_led_toggle').prop('checked', false);
} else {
$.get("/cgi-bin/action.cgi?cmd=yellow_led_on").done(function(data) {});
$('#yellow_led_toggle').prop('checked', true);
}
});
})
// MOTION DETECTION TOGGLE
$("#motion_detection").click(function() {
$.get("/cgi-bin/state.cgi", {
cmd: "motion_detection"
})
.done(function(status) {
if (status.trim() == "ON") {
$.get("/cgi-bin/action.cgi?cmd=motion_detection_off").done(function(data) {});
$('#motion_detection_toggle').prop('checked', false);
} else {
$.get("/cgi-bin/action.cgi?cmd=motion_detection_on").done(function(data) {});
$('#motion_detection_toggle').prop('checked', true);
}
});
})
// RTSP H264 TOGGLE
$("#rtsp_h264").click(function() {
$.get("/cgi-bin/state.cgi", {
cmd: "rtsp_h264"
})
.done(function(status) {
if (status.trim() == "ON") {
$.get("/cgi-bin/scripts.cgi?cmd=stop&script=rtsp-h264").done(function(data) {});
$('#rtsp_h264_toggle').prop('checked', false);
} else {
$.get("/cgi-bin/scripts.cgi?cmd=start&script=rtsp-h264").done(function(data) {});
$('#rtsp_h264_toggle').prop('checked', true);
}
});
})
// RTSP MJPEG TOGGLE
$("#rtsp_mjpeg").click(function() {
$.get("/cgi-bin/state.cgi", {
cmd: "rtsp_mjpeg"
})
.done(function(status) {
if (status.trim() == "ON") {
$.get("/cgi-bin/scripts.cgi?cmd=stop&script=rtsp-mjpeg").done(function(data) {});
$('#rtsp_mjpeg_toggle').prop('checked', false);
} else {
$.get("/cgi-bin/scripts.cgi?cmd=start&script=rtsp-mjpeg").done(function(data) {});
$('#rtsp_mjpeg_toggle').prop('checked', true);
}
});
})
// MQTT STATUS TOGGLE
$("#mqtt_status").click(function() {
$.get("/cgi-bin/state.cgi", {
cmd: "mqtt_status"
})
.done(function(status) {
if (status.trim() == "ON") {
$.get("/cgi-bin/scripts.cgi?cmd=stop&script=mqtt-status").done(function(data) {});
$('#mqtt_status_toggle').prop('checked', false);
} else {
$.get("/cgi-bin/scripts.cgi?cmd=start&script=mqtt-status").done(function(data) {});
$('#mqtt_status_toggle').prop('checked', true);
}
});
})
// MQTT STATUS TOGGLE
$("#mqtt_control").click(function() {
$.get("/cgi-bin/state.cgi", {
cmd: "mqtt_control"
})
.done(function(status) {
if (status.trim() == "ON") {
$.get("/cgi-bin/scripts.cgi?cmd=stop&script=mqtt-control").done(function(data) {});
$('#mqtt_control_toggle').prop('checked', false);
} else {
$.get("/cgi-bin/scripts.cgi?cmd=start&script=mqtt-control").done(function(data) {});
$('#mqtt_control_toggle').prop('checked', true);
}
});
})
// SOUND ON STARTUP TOGGLE
$("#sound_on_startup").click(function() {
$.get("/cgi-bin/state.cgi", {
cmd: "sound_on_startup"
})
.done(function(status) {
if (status.trim() == "ON") {
$.get("/cgi-bin/scripts.cgi?cmd=stop&script=sound-on-startup").done(function(data) {});
$('#sound_on_startup_toggle').prop('checked', false);
} else {
$.get("/cgi-bin/scripts.cgi?cmd=start&script=sound-on-startup").done(function(data) {});
$('#sound_on_startup_toggle').prop('checked', true);
}
});
})
//ADMINISTRATIVE COMMANDS
$("#conf").click(function() {
$("#content").load("/cgi-bin/status.cgi");
})
//MANAGE RUNNING SCRIPTS
$("#scripts").click(function() {
$("#content").load("/cgi-bin/scripts.cgi");
})
//CONFIGURE MOTION
$("#motion").click(function() {
$("#content").load("/configmotion.html");
})
//NETWORK
$("#network").click(function() {
$("#content").load("/cgi-bin/network.cgi");
})
//LOGS
$("#logs").click(function() {
$("#content").load("/cgi-bin/action.cgi?cmd=showlog");
})
//REBOOT
$("#reboot").click(function() {
$("#content").html("<h1>Are you sure you want to reboot ?</h1> <br /><button onclick=\"window.location.href='/cgi-bin/action.cgi?cmd=reboot'\">YES</button> <button onclick=\"window.location.href='livestream.html'\">NO</button>")
})
</script>
</body>
</html>

View File

@@ -0,0 +1,214 @@
var SWITCHES = [
"yellow_led", "blue_led", "ir_led", "ir_cut",
"rtsp_h264", "rtsp_mjpeg", "auto_night_detection",
"mqtt_status", "mqtt_control",
"sound_on_startup", "motion_detection"];
var timeoutJobs = {};
function getLiveImage() {
var ts = new Date().getTime();
var html = "<a href=\"/cgi-bin/currentpic.cgi?\"" + ts +
"\"><img id=\"liveview\" src=\"/cgi-bin/currentpic.cgi?" + ts + "\" " +
"onerror=\"this.src='css/unable_load.png'; \"" +
"onload=\"scheduleRefreshLiveImage(4000);\"></a>";
$('#content').html(html);
}
function refreshLiveImage() {
var ts = new Date().getTime();
$("#liveview").attr("src", "/cgi-bin/currentpic.cgi?" + ts);
$("#liveviewlink").attr("href", "/cgi-bin/currentpic.cgi?" + ts);
}
function scheduleRefreshLiveImage(interval) {
if (timeoutJobs['refreshLiveImage'] != undefined) {
clearTimeout(timeoutJobs['refreshLiveImage']);
}
timeoutJobs['refreshLiveImage'] = setTimeout(refreshLiveImage, interval);
}
function syncSwitch(sw) {
var e = $('#' + sw);
if (!e.prop('disabled')) {
$.get("/cgi-bin/state.cgi", {
cmd: sw
}).done(function (status) {
// console.log(sw + " status " + status);
e.prop('checked', (status.trim() == "on"));
});
}
}
function syncSwitches() {
for (var i in SWITCHES) {
if (timeoutJobs[SWITCHES[i]] != undefined) {
clearTimeout(timeoutJobs[SWITCHES[i]]);
}
syncSwitch(SWITCHES[i]);
}
}
function showResult(txt) {
var qv = $("#quickviewDefault");
var v = $("#quicViewContent");
if (qv.hasClass("is-active")) {
// hide first if it's already active
qv.toggleClass("is-active");
}
v.html(txt);
qv.toggleClass("is-active");
// auto close after 2.5 seconds
setTimeout(function () { $("#quickViewClose").click(); }, 2500);
}
$(document).ready(function () {
setTheme(getThemeChoice());
// Load link into #content
$('.onpage').click(function () {
var e = $(this);
var target = e.data('target');
var cachebuster = "_=" + new Date().getTime();
if (target.indexOf("?") >= 0) {
// append as additional param
cachebuster = "&" + cachebuster;
} else {
// new param
cachebuster = "?" + cachebuster;
}
$('#content').load(target + cachebuster);
});
// Load link into window
$('.direct').click(function () {
window.location.href = $(this).data('target');
});
// Ask before proceeding
$('.prompt').click(function () {
var e = $(this);
if (confirm(e.data('message'))) {
window.location.href = e.data('target');
}
});
// Camera controls
$(".cam_button").click(function () {
var b = $(this);
$.get("/cgi-bin/action.cgi?cmd=" + b.data('cmd')).done(function (data) {
setTimeout(refreshLiveImage, 500);
});
});
// Switch controls
$(".switch").click(function () {
var e = $(this);
e.prop('disabled', true);
$.get("/cgi-bin/state.cgi", {
cmd: e.attr('id')
}).done(function (status) {
if (status.trim() == "on") {
$.get(e.data('unchecked')).done(function (data) {
e.prop('checked', false);
});
} else {
$.get(e.data('checked')).done(function (data) {
e.prop('checked', true);
});
}
e.prop('disabled', false);
});
});
// Initial syncing of switches
timeoutJobs['syncSwitches'] = setTimeout(syncSwitches, 10);
$('#camcontrol_link').hover(function () {
// for desktop
var e = $(this);
e.toggleClass('is-active');
if (!e.hasClass('is-active')) {
return;
}
// refresh switches on hover over Camera Controls menu
if (timeoutJobs['syncSwitches'] != undefined) {
clearTimeout(timeoutJobs['syncSwitches']);
}
timeoutJobs['syncSwitches'] = setTimeout(syncSwitches, 10);
}, function () { $(this).toggleClass('is-active'); });
// Hookup navbar burger for mobile
$('#navbar_burger').click(function () {
// for mobile
var e = $(this);
e.toggleClass('is-active');
$('#' + e.data('target')).toggleClass('is-active');
if (!e.hasClass('is-active')) {
return;
}
// refresh switches on burger is tapped
if (timeoutJobs['syncSwitches'] != undefined) {
clearTimeout(timeoutJobs['syncSwitches']);
}
timeoutJobs['syncSwitches'] = setTimeout(syncSwitches, 10);
});
// Close action for quickview
$("#quickViewClose").click(function () {
$("#quickviewDefault").removeClass("is-active");
});
// Use the hash for direct linking
if (document.location.hash != "") {
$(document.location.hash).click();
}
// Make liveview self refresh
$("#liveview").attr("onload", "scheduleRefreshLiveImage(4000);");
});
// set theme cookie
function setCookie(name, value) {
document.cookie = encodeURIComponent(name) + "=" + encodeURIComponent(value) + "; path=/";
}
// get theme cookie
function getCookie(name) {
var nameEQ = encodeURIComponent(name) + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) === ' ')
c = c.substring(1, c.length);
if (c.indexOf(nameEQ) === 0)
return decodeURIComponent(c.substring(nameEQ.length, c.length));
}
return null;
}
function setTheme(c) {
if (!c) {
return;
}
// clear any existing choice
$('.theme_choice').removeClass('is-active');
var theme = $('#theme_choice_' + c);
theme.addClass('is-active'); // set active
if (theme.data('css')) {
// Purge any current custom theme
$('link.custom_theme').remove();
// Append css to head
var css = $('<link>', {
'class': 'custom_theme',
'rel': 'stylesheet',
'href': theme.data('css'),
});
$('head').append(css);
// reapply the custom css
var customCss = $('#custom_css').clone();
$('#custom_css').remove()
$('head').append(customCss);
setCookie('theme', c);
}
}
function getThemeChoice() {
var c = getCookie('theme');
return c;
}

View File

@@ -0,0 +1,64 @@
$(document).ready(function () {
$("button.script_action_stop").click(function () {
var e = $(this); console.log(e.prop("disabled"));
if (!e.prop("disabled")) {
e.prop("disabled", !e.prop("disabled"));
e.addClass("is-loading");
$.get(e.data("target")).done(function (res) {
$("#show_" + e.data("script")).html(res);
$("#content").load("/cgi-bin/scripts.cgi");
});
}
return false;
});
$("button.script_action_start").click(function () {
var e = $(this); console.log(e.prop("disabled"));
if (!e.prop("disabled")) {
e.prop("disabled", !e.prop("disabled"));
e.addClass("is-loading");
$.get(e.data("target")).done(function (res) {
$("#show_" + e.data("script")).html(res);
$("#content").load("/cgi-bin/scripts.cgi");
});
}
return false;
});
$("input.autostart").click(function () {
var e = $(this);
e.prop("disabled", true);
if (e.prop("checked")) {
$.get(e.data("checked")).done(function (res) {
e.prop("disabled", false);
if (res.status == "ok") {
e.prop("checked", !e.prop("checked"));
}
});
} else {
$.get(e.data("unchecked")).done(function (res) {
e.prop("disabled", false);
if (res.status == "ok") {
e.prop("checked", !e.prop("checked"));
}
});
}
return false;
});
$(".view_script").click(function () {
var e = $(this);
var qv = $("#quickviewDefault");
var v = $("#quicViewContent");
if (qv.hasClass("is-active")) {
// hide first if it's already active
qv.toggleClass("is-active");
}
v.html("Loading...");
v.load(e.attr("href"));
qv.toggleClass("is-active");
return false;
});
});

View File

@@ -0,0 +1,98 @@
$(document).ready(function () {
$('#tzForm').submit(function (event) {
var b = $('#tzSubmit');
b.toggleClass('is-loading');
b.prop('disabled', !b.prop('disabled'));
var formData = {
'tz': $('input[name=tz]').val(),
'hostname': $('input[name=hostname]').val()
};
$.ajax({
type: 'POST',
url: $('#tzForm').attr('action'),
data: formData,
dataType: 'html',
encode: true
}).done(function (res) {
b.toggleClass('is-loading');
b.prop('disabled', !b.prop('disabled'));
showResult(res);
// reload after 2s
setTimeout(function () { $('#content').load('/cgi-bin/status.cgi'); }, 2000);
});
event.preventDefault();
});
$('#formOSD').submit(function (event) {
var b = $('#osdSubmit');
b.toggleClass('is-loading');
b.prop('disabled', !b.prop('disabled'));
var formData = {
'OSDenable': $('input[name=OSDenable]').val(),
'osdtext': $('input[name=osdtext]').val(),
'color': $('select[name=color]').val(),
'size': $('select[name=size]').val(),
'spacepixels': $('input[name=spacepixels]').val(),
'posy': $('input[name=posy]').val(),
'fixedw': $('select[name=fixedw]').val()
};
$.ajax({
type: 'POST',
url: $('#formOSD').attr('action'),
data: formData,
dataType: 'html',
encode: true
}).done(function (res) {
b.toggleClass('is-loading');
b.prop('disabled', !b.prop('disabled'));
showResult(res);
});
event.preventDefault();
});
$('#formldr').submit(function (event) {
var b = $('#ldrSubmit');
b.toggleClass('is-loading');
b.prop('disabled', !b.prop('disabled'));
var formData = {
'avg': $('select[name=avg]').val()
};
$.ajax({
type: 'POST',
url: $('#formldr').attr('action'),
data: formData,
dataType: 'html',
encode: true
}).done(function (res) {
b.toggleClass('is-loading');
b.prop('disabled', !b.prop('disabled'));
showResult(res);
});
event.preventDefault();
});
$('#formTimelapse').submit(function (event) {
var b = $('#tlSubmit');
b.toggleClass('is-loading');
b.prop('disabled', !b.prop('disabled'));
var formData = {
'tlinterval': $('input[name=tlinterval]').val(),
'tlduration': $('input[name=tlduration]').val()
};
$.ajax({
type: 'POST',
url: $('#formTimelapse').attr('action'),
data: formData,
dataType: 'html',
encode: true
}).done(function (res) {
b.toggleClass('is-loading');
b.prop('disabled', !b.prop('disabled'));
showResult(res);
});
event.preventDefault();
});
});