Loading sdk/build/www/index.html +136 −18 Original line number Diff line number Diff line Loading @@ -10,13 +10,15 @@ <body> <div class="box center"> <div class="box"> <h1>Mi Camera Photo</h1> <a href="http://192.168.42.1:50422" target="_blank">Photos</a> <a href="rtsp://192.168.42.1/live" target="_blank">Live Stream</a><br><br> <span class="flex"> <input type="button" id="buttonConnect" onclick="buttonConnectClick()" value="Connect"> <input type="button" id="buttonTurnOffApp" onclick="turnOffAppClick()" value="Turn off app" disabled=""> <button type="button" id="buttonPowerOff" onclick="powerOffClick()" value="Power off" disabled=""> <input type="button" id="buttonTurnOffApp" onclick="turnOffAppClick()" value="Turn off app" disabled> <button type="button" id="buttonPowerOff" onclick="powerOffClick()" value="Power off" disabled> <svg version="1.1" class="svgIcon" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="31.182px" height="31.182px" viewBox="0 0 31.182 31.182"> <path d="M15.591,16.089c-0.781,0-1.417-0.635-1.417-1.417V3.074c0-0.783,0.636-1.418,1.417-1.418c0.783,0,1.418,0.635,1.418,1.418 v11.598C17.009,15.454,16.374,16.089,15.591,16.089z"/> <path d="M15.591,29.524c-7.101,0-12.877-5.776-12.877-12.877c0-4.249,2.097-8.224,5.606-10.629c0.646-0.442,1.528-0.278,1.97,0.366 c0.443,0.646,0.278,1.528-0.367,1.972c-2.738,1.878-4.374,4.978-4.374,8.291c0,5.537,4.506,10.042,10.042,10.042 c5.537,0,10.042-4.505,10.042-10.042c0-3.314-1.636-6.414-4.375-8.292c-0.646-0.442-0.811-1.325-0.367-1.972 c0.442-0.646,1.323-0.811,1.971-0.366c3.511,2.405,5.606,6.38,5.606,10.63C28.468,23.748,22.691,29.524,15.591,29.524z"/> Loading @@ -24,23 +26,139 @@ </button> </span> <!-- <input type="checkbox" name="checkboxWifiOff" id="checkboxWifiOff" disabled=""> <label for="checkboxWifiOff" id="label-chekboxWifiOff">Turn off Wifi when disconnecting</label> --> <label class="switch"> <input id="checkboxWifiOff" type="checkbox" disabled><span class="slider"></span> <label for="checkboxWifiOff">Turn off Wifi when disconnecting</label> </label> <form id="wsForm" onsubmit="return false;"> <!-- onchange="wsFormOnChange()" --> <table id="wsFormTable1"> <tr> <td><label for="speedSelect">Speed:</label></td> <td><select id="speedSelect" name="speed" disabled> <option value="0">Auto</option> <option value="39168">1/6400</option> <option value="35968">1/3200</option> <option value="34768">1/2000</option> <option value="33768">1/1000</option> <option value="33268">1/500</option> <option value="33008">1/240</option> <option value="32888">1/120</option> <option value="32828">1/60</option> <option value="32798">1/30</option> <option value="32783">1/15</option> <option value="32776">1/8</option> <option value="32772">1/4</option> <option value="1">1</option> <option value="2">2</option> <option value="4">4</option> <option value="8">8</option> <option value="16">16</option> <option value="32">32</option> </select></td> <td><label for="isoSelect">ISO:</label></td> <td><select id="isoSelect" name="iso" disabled> <option value="0">Auto</option> <option value="50">50</option> <option value="100">100</option> <option value="200">200</option> <option value="400">400</option> <option value="800">800</option> <option value="1600">1600</option> </select></td> </tr> <tr> <td><label for="wbSelect">Whitebalance:</label></td> <td><select id="wbSelect" name="photoWB" disabled> <option value="0">Auto</option> <option value="1">Outdoor</option> <option value="2">Shadow</option> <option value="3">Cloudy</option> <option value="4">Night</option> </select></td> <td></td> <td></td> </tr> <tr> <td><label for="checkboxBracketing">Bracketing</label></td> <td><label class="switch"> <input id="checkboxBracketing" type="checkbox" disabled><span class="slider"></span> </label></td> <td><label for="checkboxTimelapse">Timelapse</label></td> <td><label class="switch"> <input id="checkboxTimelapse" type="checkbox" disabled><span class="slider"></span> </label></td> </tr> <tr> <td><label for="bracketingEvSelect">EV:</label></td> <td><select id="bracketingEvSelect" name="bracketingEV" disabled> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select></td> <td><label for="timelapseIntervalSelect">Interval:</label></td> <td><select id="timelapseIntervalSelect" name="timelapseInterval" disabled> <option value="10">10 s</option> <option value="30">30 s</option> <option value="60">1 min</option> <option value="120">2 min</option> <option value="180">3 min</option> <option value="240">4 min</option> <option value="320">5 min</option> <option value="480">8 min</option> <option value="600">10 min</option> <option value="900">15 min</option> <option value="1200">20 min</option> <option value="1500">25 min</option> <option value="1800">30 min</option> </select></td> </tr> <form id="wsForm" onsubmit="wsFormSubmit(); return false;"> <input id="wsForm-data" type="text" placeholder="Data to send" disabled=""> <input id="wsForm-submit" type="submit" value="Send" disabled=""> <tr> <td><label for="bracketingCountSelect">Count:</label></td> <td><select id="bracketingCountSelect" name="bracketingHalf" disabled> <option value="1">3</option> <option value="2">5</option> <option value="3">7</option> <option value="4">9</option> </select></td> <td><label for="timelapseCountSelect">Count:</label></td> <td><select id="timelapseCountSelect" name="timelapseCount" disabled> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> <option value="6">6</option> <option value="7">7</option> <option value="8">8</option> <option value="9">9</option> <option value="10">10</option> <option value="12">12</option> <option value="14">14</option> <option value="16">16</option> <option value="18">20</option> </select></td> </tr> </table> <table id="wsFormTable2"> <tr> <td><label for="checkboxWifiOff">Turn off Wifi when shooting<br> timelapse above 1 minute</label></td> <td><label class="switch"> <input id="checkboxWifiOff" type="checkbox" name="wifiOff" disabled><span class="slider"></span> </label> </td> </tr> </table> <button type="button" id="buttonShoot" onclick="wsFormSubmit();" name="cmd" value="SHOOT" disabled>Shoot!</button> </form> <a href="http://192.168.42.1:50422">Photos</a> <a href="rtsp://192.168.42.1/live">Live Stream</a> </div> <div id="notification-wrapper"><div id="notification" style="display: none;"></div></div> </body> Loading sdk/build/www/script.js +160 −56 Original line number Diff line number Diff line const CameraState = { DISCONNECTED: 0, SHOOTING: 1, READY: 2 } var ws; var notifying = false; var connected = false; var state = CameraState.DISCONNECTED; var host = "192.168.42.1"; function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } function waitFor(conditionFunction) { const poll = resolve => { Loading @@ -20,6 +28,7 @@ function waitFor(conditionFunction) { function wsConnect() { if (!("WebSocket" in window)) Loading @@ -45,23 +54,18 @@ function wsConnect() var json = JSON.parse(event.data); switch(json["cmd"]) { case "CONNECT": case "STATE": { document.getElementById("buttonConnect").disabled = false; if (json["param"] === true) { enableForm(true); notify("Connected!",false, 1000) if (json["param"] == CameraState.DISCONNECTED) ws.close(); // onclose will call setFormState else setCameraState(json["param"]); break; } else if (json["param"] === false) case "NOTIFY": { enableForm(false); ws.close(); notify("Couldn't connect. Maybe someone else is using the camera?", true, 2000); } else notify(json["param"]); break; return; } default: break; Loading @@ -73,60 +77,114 @@ function wsConnect() notify(`[message] Non-JSON data received from server: ${event.data}`, true); } }; ws.onping = function(event) ws.onping = function(event){} ws.onclose = function(event) { notify("ping!"); if (!event.wasClean && state != CameraState.DISCONNECTED) { notify('Connection died.'); } ws.onclose = function(event) setCameraState(CameraState.DISCONNECTED); }; ws.onerror = function(error){}; } function setCameraState(newState) { document.getElementById("buttonConnect").disabled = false; if (event.wasClean) let disabled = false; switch(newState) { if (event.code === 1000) notify(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`); } else case CameraState.DISCONNECTED: { // e.g. server process killed or network down // event.code is usually 1006 in this case if (!connected) notify("Couldn't connect. Maybe anothe user is using the app or you are not connected to the network?", true, 3000); else notify("Connection died.", true); document.getElementById("buttonConnect").value = "Connect"; document.getElementById("buttonShoot").innerHTML = "Shoot!"; disabled = true; switch(state) { //DISCONNECTED -> DISCONNECTED case CameraState.DISCONNECTED: notify("Couldn't connect. Maybe someone else is using the camera?", true, 2000); break; //READY/SHOOTING -> DISCONNECTED default: notify("Disconnected!", true, 2000); break; } break; } enableForm(false); connected = false; case CameraState.SHOOTING: { document.getElementById("buttonConnect").value = "Disconnect"; document.getElementById("buttonShoot").innerHTML = "Stop shooting!"; disabled = true; }; switch(state) { //DISCONNECTED -> SHOOTING case CameraState.DISCONNECTED: notify("Connected, camera is shooting!",false, 1000); break; ws.onerror = function(error){}; //REDY/SHOOTING -> SHOOTING default: notify("Shooting has started!",false, 1000); break; } break; } function enableForm(enable) case CameraState.READY: { var elements = document.getElementById("wsForm").elements; for (var i = 0, len = elements.length; i < len; ++i) document.getElementById("buttonConnect").value = "Disconnect"; document.getElementById("buttonShoot").innerHTML = "Shoot!"; disabled = false; switch(state) { elements[i].disabled = !enable; //DISCONNECTED -> READY case CameraState.DISCONNECTED: notify("Connected!",false, 1000); break; //SHOOTING -> READY case CameraState.SHOOTING: notify("Shooting has finished!",false, 1000); break; } break; } default: return; } document.getElementById("checkboxWifiOff").disabled = !enable; document.getElementById("buttonTurnOffApp").disabled = !enable; document.getElementById("buttonPowerOff").disabled = !enable; // disable/enable whole form var elements = document.getElementById("wsForm").elements; for (var i = 0, len = elements.length; i < len; ++i) elements[i].disabled = disabled; if (enable) document.getElementById("buttonConnect").value = "Disconnect"; else document.getElementById("buttonConnect").value = "Connect"; // disable/enable additional buttons outside form //document.getElementById("checkboxWifiOff").disabled = disabled; document.getElementById("buttonTurnOffApp").disabled = disabled; document.getElementById("buttonPowerOff").disabled = disabled; if (newState == CameraState.SHOOTING) document.getElementById("buttonShoot").disabled = false; state = newState; } function wsDisconnect() { if (document.getElementById("checkboxWifiOff").checked) /*if (document.getElementById("checkboxWifiOff").checked) ws.send('{"cmd":"WIFI_OFF"}'); document.getElementById("checkboxWifiOff").disabled = true; document.getElementById("checkboxWifiOff").disabled = true;*/ ws.close(1000, "disconnected by user"); connected = false; Loading @@ -146,15 +204,21 @@ function buttonConnectClick() function wsFormSubmit() { var input = document.getElementById('wsForm-data') ws.send(input.value); input.value = ""; if (state === CameraState.READY) { let str = JSON.stringify(wsFormToJson()); ws.send(str); } else if (state === CameraState.SHOOTING) { ws.send('{"cmd":"STOP"}'); } } function turnOffAppClick() { if (document.getElementById("checkboxWifiOff").checked) ws.send('{"cmd":"WIFI_OFF"}'); /*if (document.getElementById("checkboxWifiOff").checked) ws.send('{"cmd":"WIFI_OFF"}');*/ ws.send('{"cmd":"APP_OFF"}'); wsDisconnect(); } Loading @@ -168,8 +232,8 @@ function powerOffClick() async function notify(text, error = false, time = 1500) { if (error) console.error(text) if (error === true) console.error(text); else console.log(text); Loading @@ -191,3 +255,43 @@ async function notify(text, error = false, time = 1500) }); } function wsFormToJson() { form = document.getElementById("wsForm") var json = {}; for (var i = 0; i < form.length; i++) { if (form[i]["type"] === "checkbox") { json[form[i]['name']] = form[i].checked; } else { if (isNaN(form[i]['value'])) json[form[i]['name']] = form[i]['value']; else json[form[i]['name']] = parseInt(form[i]['value']); } } if (document.getElementById("checkboxBracketing").checked === false) { json["bracketingEV"] = 0; json["bracketingHalf"] = 0; } if (document.getElementById("checkboxTimelapse").checked === false) { json["timelapseCount"] = 0; json["timelapseInterval"] = 0; json["wifiOff"] = false; } else { if (json["timelapseInterval"] * json["timelapseCount"] < 60) json["wifiOff"] = false; } delete json[""] return json; } sdk/build/www/style.css +71 −19 Original line number Diff line number Diff line Loading @@ -3,6 +3,12 @@ body color: #fff6cb; background-color: #fffae0; } body,html { display: grid; height: 100%; } a { color: #fff6cb; Loading @@ -16,9 +22,11 @@ a:active { color: #ffecdd; } form label { margin: 5px 0px 12px 0px; vertical-align: middle; margin-right: 5px; } .flex { Loading @@ -31,7 +39,7 @@ form padding: 15px 30px 35px 30px; margin: auto; border-radius: 10px; min-width: 300px; width: 370px; } .center Loading @@ -49,15 +57,7 @@ form display: block; } #buttonPowerOff { padding: 2px; } #buttonPowerOff > svg { width: 26px; height: 26px; } #notification-wrapper Loading Loading @@ -107,7 +107,11 @@ input[type="submit"] border-radius: 3px; } input[type="submit"] { display: table; margin: 4px auto; } button:disabled, input[type="button"]:disabled, Loading @@ -123,11 +127,6 @@ input[type="checkbox" i]:disabled+label color: #777; } #buttonConnect,#wsForm-turnOffApp { width: 105px; } input { border-radius: 3px; Loading @@ -137,6 +136,10 @@ input[type=text] { padding: 7px; } select { padding: 6px; } input[type="checkbox"] { width: 20px; Loading @@ -144,3 +147,52 @@ input[type="checkbox"] { position: relative; margin: 7px 5px; } #wsForm { margin: 5px 0px 12px 0px; } #buttonPowerOff { padding: 2px; } #buttonPowerOff > svg { width: 26px; height: 26px; } /********** TABLE **********/ table { margin: 20px 0px; border-spacing: 0; } td:nth-child(2n) { text-align: left; } #wsFormTable1 td:nth-child(2n+3) { padding-left: 25px; } #wsFormTable1 tr:nth-child(2) td { padding-bottom: 10px; border-bottom: 1px solid #fff6cb; } #wsFormTable1 tr:nth-child(n+3) td:nth-child(2) { border-right: 1px solid #fff6cb; } #wsFormTable2 td:first-child { width: 200px; }1 No newline at end of file sdk/src/commander.cpp +93 −23 File changed.Preview size limit exceeded, changes collapsed. Show changes sdk/src/commander.h +6 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ public: void runReceiver(); void stopReceiver(); bool isShooting(); void enqueueCommand(const std::string& cmd); private: Loading Loading @@ -62,6 +64,10 @@ private: size_t _timelapseInterval; size_t _timelapseCount; bool _isShooting; std::mutex _isShootingMutex; bool _stopShooting; std::mutex _stopShootingMutex; std::condition_variable _stopShootingCV; Loading Loading
sdk/build/www/index.html +136 −18 Original line number Diff line number Diff line Loading @@ -10,13 +10,15 @@ <body> <div class="box center"> <div class="box"> <h1>Mi Camera Photo</h1> <a href="http://192.168.42.1:50422" target="_blank">Photos</a> <a href="rtsp://192.168.42.1/live" target="_blank">Live Stream</a><br><br> <span class="flex"> <input type="button" id="buttonConnect" onclick="buttonConnectClick()" value="Connect"> <input type="button" id="buttonTurnOffApp" onclick="turnOffAppClick()" value="Turn off app" disabled=""> <button type="button" id="buttonPowerOff" onclick="powerOffClick()" value="Power off" disabled=""> <input type="button" id="buttonTurnOffApp" onclick="turnOffAppClick()" value="Turn off app" disabled> <button type="button" id="buttonPowerOff" onclick="powerOffClick()" value="Power off" disabled> <svg version="1.1" class="svgIcon" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="31.182px" height="31.182px" viewBox="0 0 31.182 31.182"> <path d="M15.591,16.089c-0.781,0-1.417-0.635-1.417-1.417V3.074c0-0.783,0.636-1.418,1.417-1.418c0.783,0,1.418,0.635,1.418,1.418 v11.598C17.009,15.454,16.374,16.089,15.591,16.089z"/> <path d="M15.591,29.524c-7.101,0-12.877-5.776-12.877-12.877c0-4.249,2.097-8.224,5.606-10.629c0.646-0.442,1.528-0.278,1.97,0.366 c0.443,0.646,0.278,1.528-0.367,1.972c-2.738,1.878-4.374,4.978-4.374,8.291c0,5.537,4.506,10.042,10.042,10.042 c5.537,0,10.042-4.505,10.042-10.042c0-3.314-1.636-6.414-4.375-8.292c-0.646-0.442-0.811-1.325-0.367-1.972 c0.442-0.646,1.323-0.811,1.971-0.366c3.511,2.405,5.606,6.38,5.606,10.63C28.468,23.748,22.691,29.524,15.591,29.524z"/> Loading @@ -24,23 +26,139 @@ </button> </span> <!-- <input type="checkbox" name="checkboxWifiOff" id="checkboxWifiOff" disabled=""> <label for="checkboxWifiOff" id="label-chekboxWifiOff">Turn off Wifi when disconnecting</label> --> <label class="switch"> <input id="checkboxWifiOff" type="checkbox" disabled><span class="slider"></span> <label for="checkboxWifiOff">Turn off Wifi when disconnecting</label> </label> <form id="wsForm" onsubmit="return false;"> <!-- onchange="wsFormOnChange()" --> <table id="wsFormTable1"> <tr> <td><label for="speedSelect">Speed:</label></td> <td><select id="speedSelect" name="speed" disabled> <option value="0">Auto</option> <option value="39168">1/6400</option> <option value="35968">1/3200</option> <option value="34768">1/2000</option> <option value="33768">1/1000</option> <option value="33268">1/500</option> <option value="33008">1/240</option> <option value="32888">1/120</option> <option value="32828">1/60</option> <option value="32798">1/30</option> <option value="32783">1/15</option> <option value="32776">1/8</option> <option value="32772">1/4</option> <option value="1">1</option> <option value="2">2</option> <option value="4">4</option> <option value="8">8</option> <option value="16">16</option> <option value="32">32</option> </select></td> <td><label for="isoSelect">ISO:</label></td> <td><select id="isoSelect" name="iso" disabled> <option value="0">Auto</option> <option value="50">50</option> <option value="100">100</option> <option value="200">200</option> <option value="400">400</option> <option value="800">800</option> <option value="1600">1600</option> </select></td> </tr> <tr> <td><label for="wbSelect">Whitebalance:</label></td> <td><select id="wbSelect" name="photoWB" disabled> <option value="0">Auto</option> <option value="1">Outdoor</option> <option value="2">Shadow</option> <option value="3">Cloudy</option> <option value="4">Night</option> </select></td> <td></td> <td></td> </tr> <tr> <td><label for="checkboxBracketing">Bracketing</label></td> <td><label class="switch"> <input id="checkboxBracketing" type="checkbox" disabled><span class="slider"></span> </label></td> <td><label for="checkboxTimelapse">Timelapse</label></td> <td><label class="switch"> <input id="checkboxTimelapse" type="checkbox" disabled><span class="slider"></span> </label></td> </tr> <tr> <td><label for="bracketingEvSelect">EV:</label></td> <td><select id="bracketingEvSelect" name="bracketingEV" disabled> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select></td> <td><label for="timelapseIntervalSelect">Interval:</label></td> <td><select id="timelapseIntervalSelect" name="timelapseInterval" disabled> <option value="10">10 s</option> <option value="30">30 s</option> <option value="60">1 min</option> <option value="120">2 min</option> <option value="180">3 min</option> <option value="240">4 min</option> <option value="320">5 min</option> <option value="480">8 min</option> <option value="600">10 min</option> <option value="900">15 min</option> <option value="1200">20 min</option> <option value="1500">25 min</option> <option value="1800">30 min</option> </select></td> </tr> <form id="wsForm" onsubmit="wsFormSubmit(); return false;"> <input id="wsForm-data" type="text" placeholder="Data to send" disabled=""> <input id="wsForm-submit" type="submit" value="Send" disabled=""> <tr> <td><label for="bracketingCountSelect">Count:</label></td> <td><select id="bracketingCountSelect" name="bracketingHalf" disabled> <option value="1">3</option> <option value="2">5</option> <option value="3">7</option> <option value="4">9</option> </select></td> <td><label for="timelapseCountSelect">Count:</label></td> <td><select id="timelapseCountSelect" name="timelapseCount" disabled> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> <option value="6">6</option> <option value="7">7</option> <option value="8">8</option> <option value="9">9</option> <option value="10">10</option> <option value="12">12</option> <option value="14">14</option> <option value="16">16</option> <option value="18">20</option> </select></td> </tr> </table> <table id="wsFormTable2"> <tr> <td><label for="checkboxWifiOff">Turn off Wifi when shooting<br> timelapse above 1 minute</label></td> <td><label class="switch"> <input id="checkboxWifiOff" type="checkbox" name="wifiOff" disabled><span class="slider"></span> </label> </td> </tr> </table> <button type="button" id="buttonShoot" onclick="wsFormSubmit();" name="cmd" value="SHOOT" disabled>Shoot!</button> </form> <a href="http://192.168.42.1:50422">Photos</a> <a href="rtsp://192.168.42.1/live">Live Stream</a> </div> <div id="notification-wrapper"><div id="notification" style="display: none;"></div></div> </body> Loading
sdk/build/www/script.js +160 −56 Original line number Diff line number Diff line const CameraState = { DISCONNECTED: 0, SHOOTING: 1, READY: 2 } var ws; var notifying = false; var connected = false; var state = CameraState.DISCONNECTED; var host = "192.168.42.1"; function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } function waitFor(conditionFunction) { const poll = resolve => { Loading @@ -20,6 +28,7 @@ function waitFor(conditionFunction) { function wsConnect() { if (!("WebSocket" in window)) Loading @@ -45,23 +54,18 @@ function wsConnect() var json = JSON.parse(event.data); switch(json["cmd"]) { case "CONNECT": case "STATE": { document.getElementById("buttonConnect").disabled = false; if (json["param"] === true) { enableForm(true); notify("Connected!",false, 1000) if (json["param"] == CameraState.DISCONNECTED) ws.close(); // onclose will call setFormState else setCameraState(json["param"]); break; } else if (json["param"] === false) case "NOTIFY": { enableForm(false); ws.close(); notify("Couldn't connect. Maybe someone else is using the camera?", true, 2000); } else notify(json["param"]); break; return; } default: break; Loading @@ -73,60 +77,114 @@ function wsConnect() notify(`[message] Non-JSON data received from server: ${event.data}`, true); } }; ws.onping = function(event) ws.onping = function(event){} ws.onclose = function(event) { notify("ping!"); if (!event.wasClean && state != CameraState.DISCONNECTED) { notify('Connection died.'); } ws.onclose = function(event) setCameraState(CameraState.DISCONNECTED); }; ws.onerror = function(error){}; } function setCameraState(newState) { document.getElementById("buttonConnect").disabled = false; if (event.wasClean) let disabled = false; switch(newState) { if (event.code === 1000) notify(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`); } else case CameraState.DISCONNECTED: { // e.g. server process killed or network down // event.code is usually 1006 in this case if (!connected) notify("Couldn't connect. Maybe anothe user is using the app or you are not connected to the network?", true, 3000); else notify("Connection died.", true); document.getElementById("buttonConnect").value = "Connect"; document.getElementById("buttonShoot").innerHTML = "Shoot!"; disabled = true; switch(state) { //DISCONNECTED -> DISCONNECTED case CameraState.DISCONNECTED: notify("Couldn't connect. Maybe someone else is using the camera?", true, 2000); break; //READY/SHOOTING -> DISCONNECTED default: notify("Disconnected!", true, 2000); break; } break; } enableForm(false); connected = false; case CameraState.SHOOTING: { document.getElementById("buttonConnect").value = "Disconnect"; document.getElementById("buttonShoot").innerHTML = "Stop shooting!"; disabled = true; }; switch(state) { //DISCONNECTED -> SHOOTING case CameraState.DISCONNECTED: notify("Connected, camera is shooting!",false, 1000); break; ws.onerror = function(error){}; //REDY/SHOOTING -> SHOOTING default: notify("Shooting has started!",false, 1000); break; } break; } function enableForm(enable) case CameraState.READY: { var elements = document.getElementById("wsForm").elements; for (var i = 0, len = elements.length; i < len; ++i) document.getElementById("buttonConnect").value = "Disconnect"; document.getElementById("buttonShoot").innerHTML = "Shoot!"; disabled = false; switch(state) { elements[i].disabled = !enable; //DISCONNECTED -> READY case CameraState.DISCONNECTED: notify("Connected!",false, 1000); break; //SHOOTING -> READY case CameraState.SHOOTING: notify("Shooting has finished!",false, 1000); break; } break; } default: return; } document.getElementById("checkboxWifiOff").disabled = !enable; document.getElementById("buttonTurnOffApp").disabled = !enable; document.getElementById("buttonPowerOff").disabled = !enable; // disable/enable whole form var elements = document.getElementById("wsForm").elements; for (var i = 0, len = elements.length; i < len; ++i) elements[i].disabled = disabled; if (enable) document.getElementById("buttonConnect").value = "Disconnect"; else document.getElementById("buttonConnect").value = "Connect"; // disable/enable additional buttons outside form //document.getElementById("checkboxWifiOff").disabled = disabled; document.getElementById("buttonTurnOffApp").disabled = disabled; document.getElementById("buttonPowerOff").disabled = disabled; if (newState == CameraState.SHOOTING) document.getElementById("buttonShoot").disabled = false; state = newState; } function wsDisconnect() { if (document.getElementById("checkboxWifiOff").checked) /*if (document.getElementById("checkboxWifiOff").checked) ws.send('{"cmd":"WIFI_OFF"}'); document.getElementById("checkboxWifiOff").disabled = true; document.getElementById("checkboxWifiOff").disabled = true;*/ ws.close(1000, "disconnected by user"); connected = false; Loading @@ -146,15 +204,21 @@ function buttonConnectClick() function wsFormSubmit() { var input = document.getElementById('wsForm-data') ws.send(input.value); input.value = ""; if (state === CameraState.READY) { let str = JSON.stringify(wsFormToJson()); ws.send(str); } else if (state === CameraState.SHOOTING) { ws.send('{"cmd":"STOP"}'); } } function turnOffAppClick() { if (document.getElementById("checkboxWifiOff").checked) ws.send('{"cmd":"WIFI_OFF"}'); /*if (document.getElementById("checkboxWifiOff").checked) ws.send('{"cmd":"WIFI_OFF"}');*/ ws.send('{"cmd":"APP_OFF"}'); wsDisconnect(); } Loading @@ -168,8 +232,8 @@ function powerOffClick() async function notify(text, error = false, time = 1500) { if (error) console.error(text) if (error === true) console.error(text); else console.log(text); Loading @@ -191,3 +255,43 @@ async function notify(text, error = false, time = 1500) }); } function wsFormToJson() { form = document.getElementById("wsForm") var json = {}; for (var i = 0; i < form.length; i++) { if (form[i]["type"] === "checkbox") { json[form[i]['name']] = form[i].checked; } else { if (isNaN(form[i]['value'])) json[form[i]['name']] = form[i]['value']; else json[form[i]['name']] = parseInt(form[i]['value']); } } if (document.getElementById("checkboxBracketing").checked === false) { json["bracketingEV"] = 0; json["bracketingHalf"] = 0; } if (document.getElementById("checkboxTimelapse").checked === false) { json["timelapseCount"] = 0; json["timelapseInterval"] = 0; json["wifiOff"] = false; } else { if (json["timelapseInterval"] * json["timelapseCount"] < 60) json["wifiOff"] = false; } delete json[""] return json; }
sdk/build/www/style.css +71 −19 Original line number Diff line number Diff line Loading @@ -3,6 +3,12 @@ body color: #fff6cb; background-color: #fffae0; } body,html { display: grid; height: 100%; } a { color: #fff6cb; Loading @@ -16,9 +22,11 @@ a:active { color: #ffecdd; } form label { margin: 5px 0px 12px 0px; vertical-align: middle; margin-right: 5px; } .flex { Loading @@ -31,7 +39,7 @@ form padding: 15px 30px 35px 30px; margin: auto; border-radius: 10px; min-width: 300px; width: 370px; } .center Loading @@ -49,15 +57,7 @@ form display: block; } #buttonPowerOff { padding: 2px; } #buttonPowerOff > svg { width: 26px; height: 26px; } #notification-wrapper Loading Loading @@ -107,7 +107,11 @@ input[type="submit"] border-radius: 3px; } input[type="submit"] { display: table; margin: 4px auto; } button:disabled, input[type="button"]:disabled, Loading @@ -123,11 +127,6 @@ input[type="checkbox" i]:disabled+label color: #777; } #buttonConnect,#wsForm-turnOffApp { width: 105px; } input { border-radius: 3px; Loading @@ -137,6 +136,10 @@ input[type=text] { padding: 7px; } select { padding: 6px; } input[type="checkbox"] { width: 20px; Loading @@ -144,3 +147,52 @@ input[type="checkbox"] { position: relative; margin: 7px 5px; } #wsForm { margin: 5px 0px 12px 0px; } #buttonPowerOff { padding: 2px; } #buttonPowerOff > svg { width: 26px; height: 26px; } /********** TABLE **********/ table { margin: 20px 0px; border-spacing: 0; } td:nth-child(2n) { text-align: left; } #wsFormTable1 td:nth-child(2n+3) { padding-left: 25px; } #wsFormTable1 tr:nth-child(2) td { padding-bottom: 10px; border-bottom: 1px solid #fff6cb; } #wsFormTable1 tr:nth-child(n+3) td:nth-child(2) { border-right: 1px solid #fff6cb; } #wsFormTable2 td:first-child { width: 200px; }1 No newline at end of file
sdk/src/commander.cpp +93 −23 File changed.Preview size limit exceeded, changes collapsed. Show changes
sdk/src/commander.h +6 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ public: void runReceiver(); void stopReceiver(); bool isShooting(); void enqueueCommand(const std::string& cmd); private: Loading Loading @@ -62,6 +64,10 @@ private: size_t _timelapseInterval; size_t _timelapseCount; bool _isShooting; std::mutex _isShootingMutex; bool _stopShooting; std::mutex _stopShootingMutex; std::condition_variable _stopShootingCV; Loading