Remove camera streaming feature as not working as expected

Clean code due to camera stream removed and left camera snap feature only
This commit is contained in:
Luc 2020-10-26 16:44:18 +01:00
parent 24d7d96c08
commit 2aa146a926
21 changed files with 584 additions and 1761 deletions

View File

@ -62,15 +62,9 @@ Note:
* Get/Set WebSocket port
[ESP161]<port>pwd=<admin password>
* Get/Set camera server state which can be ON, OFF, but not saved in EEPROM
[ESP170]<state>pwd=<admin password>
* Get/Set Camera port
[ESP171]<port>pwd=<admin password>
* Get/Set Camera command value / list all values in JSON/plain
label can be: light/framesize/quality/contrast/brightness/saturation/gainceiling/colorbar/awb/agc/aec/hmirror/vflip/awb_gain/agc_gain/aec_value/aec2/cw/bpc/wpc/raw_gma/lenc/special_effect/wb_mode/ae_level
[ESP172]<plain><label=value> pwd=<admin password>
[ESP170]<plain><label=value> pwd=<admin password>
* Get/Set Ftp state which can be ON, OFF, CLOSE
[ESP180]<state>pwd=<admin password>
@ -143,27 +137,32 @@ ESP_HTTP_ON 328 //1 byte = flag
ESP_TELNET_ON 329 //1 byte = flag
ESP_WEBSOCKET_ON 330 //1 byte = flag
ESP_SD_SPEED_DIV 331 //1 byte = flag
ESP_NOTIFICATION_TOKEN1 332 //64 bytes 63+1 = string ; warning does not support multibyte char like chinese
ESP_NOTIFICATION_TOKEN2 396 //64 bytes 63+1 = string ; warning does not support multibyte char like chinese
ESP_SENSOR_TYPE 460//1 bytes = flag
ESP_TARGET_FW 461 //1 bytes = flag
ESP_TIMEZONE 462//1 bytes = flag
ESP_TIME_IS_DST 463//1 bytes = flag
ESP_TIME_SERVER1 464//129 bytes 128+1 = string ; warning does not support multibyte char like chinese
ESP_TIME_SERVER2 593 //129 bytes 128+1 = string ; warning does not support multibyte char like chinese
ESP_TIME_SERVER3 722 //129 bytes 128+1 = string ; warning does not support multibyte char like chinese
ESP_IS_DIRECT_SD 850//1 bytes = flag
ESP_PRIMARY_SD 851//1 bytes = flag
ESP_SECONDARY_SD 852//1 bytes = flag
ESP_DIRECT_SD_CHECK 853//1 bytes = flag
ESP_SD_CHECK_UPDATE_AT_BOOT 854//1 bytes = flag
ESP_NOTIFICATION_SETTINGS 855//128 bytes 127+1 = string ; warning does not support multibyte char like chinese
ESP_CALIBRATION_1 983 //4 bytes = int
ESP_CALIBRATION_2 987 //4 bytes = int
ESP_CALIBRATION_3 991 //4 bytes = int
ESP_CALIBRATION_4 995 //4 bytes = int
ESP_CALIBRATION_5 999 //4 bytes = int
ESP_AUTO_NOTIFICATION 1004 //1 byte = flag
ESP_NOTIFICATION_TOKEN1 332 //64 bytes 63+1 = string ; warning does not support multibyte char like chinese
ESP_NOTIFICATION_TOKEN2 396 //64 bytes 63+1 = string ; warning does not support multibyte char like chinese
ESP_SENSOR_TYPE 460 //1 bytes = flag
ESP_TARGET_FW 461 //1 bytes = flag
ESP_TIMEZONE 462 //1 bytes = flag
ESP_TIME_IS_DST 463 //1 bytes = flag
ESP_TIME_SERVER1 464 //129 bytes 128+1 = string ; warning does not support multibyte char like chinese
ESP_TIME_SERVER2 593 //129 bytes 128+1 = string ; warning does not support multibyte char like chinese
ESP_TIME_SERVER3 722 //129 bytes 128+1 = string ; warning does not support multibyte char like chinese
ESP_SD_DEVICE_TYPE 851 //1 bytes = flag
ESP_SD_MOUNT 852 //1 bytes = flag
ESP_SESSION_TIMEOUT 853 //1 bytes = flag
ESP_DIRECT_SD_CHECK 854 //1 bytes = flag
ESP_SD_CHECK_UPDATE_AT_BOOT 855//1 bytes = flag
ESP_NOTIFICATION_SETTINGS 856 //129 bytes 128+1 = string ; warning does not support multibyte char like chinese
ESP_CALIBRATION_1 985 //4 bytes = int
ESP_CALIBRATION_2 989 //4 bytes = int
ESP_CALIBRATION_3 993 //4 bytes = int
ESP_CALIBRATION_4 997 //4 bytes = int
ESP_CALIBRATION_5 1001 //4 bytes = int
ESP_FREE_ENTRY 1005 //4 bytes = int
ESP_FTP_CTRL_PORT 1009 //4 bytes = int
ESP_FTP_DATA_ACTIVE_PORT 1013 //4 bytes = int
ESP_FTP_DATA_PASSIVE_PORT 1017 //4 bytes = int
ESP_FTP_ON 1021 //1 byte = flag
ESP_AUTO_NOTIFICATION 1022 //1 byte = flag
*Get available AP list (limited to 30)
output is JSON or plain text according parameter

View File

@ -205,20 +205,18 @@
//CAMERA_MODEL_M5STACK_WIDE 3
//CAMERA_MODEL_AI_THINKER 4 e.g. used by ESP32-CAM
//CAMERA_MODEL_WROVER_KIT 5
#define CAMERA_DEVICE CAMERA_MODEL_AI_THINKER
//#define CAMERA_DEVICE CAMERA_MODEL_AI_THINKER
//#define CAMERA_DEVICE_FLIP_VERTICALY //comment to disable
//#define CAMERA_DEVICE_FLIP_HORIZONTALY//comment to disable
#define CUSTOM_CAMERA_NAME "ESP32-CAM"
#define CAMERA_INDEPENDANT_TASK
//Allow remote access by enabling cross origin access
//check https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
//this should be enabled only in specific cases
//like show the camera in web page different than device web server
//if you do not know what is that then better left it commented
#define ESP_ACCESS_CONTROL_ALLOW_ORIGIN
//#define ESP_ACCESS_CONTROL_ALLOW_ORIGIN
//ESP_GCODE_HOST_FEATURE : allow to send GCODE with ack
#define ESP_GCODE_HOST_FEATURE

View File

@ -1,736 +0,0 @@
<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>ESP32 OV2460</title>
<style>
body {
font-family: Arial,Helvetica,sans-serif;
background: #181818;
color: #EFEFEF;
font-size: 16px
}
h2 {
font-size: 18px
}
section.main {
display: flex
}
#menu,section.main {
flex-direction: column
}
#menu {
display: none;
flex-wrap: nowrap;
min-width: 340px;
background: #363636;
padding: 8px;
border-radius: 4px;
margin-top: -10px;
margin-right: 10px;
}
#content {
display: flex;
flex-wrap: wrap;
align-items: stretch
}
figure {
padding: 0px;
margin: 0;
-webkit-margin-before: 0;
margin-block-start: 0;
-webkit-margin-after: 0;
margin-block-end: 0;
-webkit-margin-start: 0;
margin-inline-start: 0;
-webkit-margin-end: 0;
margin-inline-end: 0
}
figure img {
display: block;
width: 100%;
height: auto;
border-radius: 4px;
margin-top: 8px;
}
@media (min-width: 800px) and (orientation:landscape) {
#content {
display:flex;
flex-wrap: nowrap;
align-items: stretch
}
figure img {
display: block;
max-width: 100%;
max-height: calc(100vh - 40px);
width: auto;
height: auto
}
figure {
padding: 0 0 0 0px;
margin: 0;
-webkit-margin-before: 0;
margin-block-start: 0;
-webkit-margin-after: 0;
margin-block-end: 0;
-webkit-margin-start: 0;
margin-inline-start: 0;
-webkit-margin-end: 0;
margin-inline-end: 0
}
}
section#buttons {
display: flex;
flex-wrap: nowrap;
justify-content: space-between
}
#nav-toggle {
cursor: pointer;
display: block
}
#nav-toggle-cb {
outline: 0;
opacity: 0;
width: 0;
height: 0
}
#nav-toggle-cb:checked+#menu {
display: flex
}
.input-group {
display: flex;
flex-wrap: nowrap;
line-height: 22px;
margin: 5px 0
}
.input-group>label {
display: inline-block;
padding-right: 10px;
min-width: 47%
}
.input-group input,.input-group select {
flex-grow: 1
}
.range-max,.range-min {
display: inline-block;
padding: 0 5px
}
button {
display: block;
margin: 5px;
padding: 0 12px;
border: 0;
line-height: 28px;
cursor: pointer;
color: #fff;
background: #ff3034;
border-radius: 5px;
font-size: 16px;
outline: 0
}
button:hover {
background: #ff494d
}
button:active {
background: #f21c21
}
button.disabled {
cursor: default;
background: #a0a0a0
}
input[type=range] {
-webkit-appearance: none;
width: 100%;
height: 22px;
background: #363636;
cursor: pointer;
margin: 0
}
input[type=range]:focus {
outline: 0
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 2px;
cursor: pointer;
background: #EFEFEF;
border-radius: 0;
border: 0 solid #EFEFEF
}
input[type=range]::-webkit-slider-thumb {
border: 1px solid rgba(0,0,30,0);
height: 22px;
width: 22px;
border-radius: 50px;
background: #ff3034;
cursor: pointer;
-webkit-appearance: none;
margin-top: -11.5px
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #EFEFEF
}
input[type=range]::-moz-range-track {
width: 100%;
height: 2px;
cursor: pointer;
background: #EFEFEF;
border-radius: 0;
border: 0 solid #EFEFEF
}
input[type=range]::-moz-range-thumb {
border: 1px solid rgba(0,0,30,0);
height: 22px;
width: 22px;
border-radius: 50px;
background: #ff3034;
cursor: pointer
}
input[type=range]::-ms-track {
width: 100%;
height: 2px;
cursor: pointer;
background: 0 0;
border-color: transparent;
color: transparent
}
input[type=range]::-ms-fill-lower {
background: #EFEFEF;
border: 0 solid #EFEFEF;
border-radius: 0
}
input[type=range]::-ms-fill-upper {
background: #EFEFEF;
border: 0 solid #EFEFEF;
border-radius: 0
}
input[type=range]::-ms-thumb {
border: 1px solid rgba(0,0,30,0);
height: 22px;
width: 22px;
border-radius: 50px;
background: #ff3034;
cursor: pointer;
height: 2px
}
input[type=range]:focus::-ms-fill-lower {
background: #EFEFEF
}
input[type=range]:focus::-ms-fill-upper {
background: #363636
}
.switch {
display: block;
position: relative;
line-height: 22px;
font-size: 16px;
height: 22px
}
.switch input {
outline: 0;
opacity: 0;
width: 0;
height: 0
}
.slider {
width: 50px;
height: 22px;
border-radius: 22px;
cursor: pointer;
background-color: grey
}
.slider,.slider:before {
display: inline-block;
transition: .4s
}
.slider:before {
position: relative;
content: "";
border-radius: 50%;
height: 16px;
width: 16px;
left: 4px;
top: 3px;
background-color: #fff
}
input:checked+.slider {
background-color: #ff3034
}
input:checked+.slider:before {
-webkit-transform: translateX(26px);
transform: translateX(26px)
}
select {
border: 1px solid #363636;
font-size: 14px;
height: 22px;
outline: 0;
border-radius: 5px
}
.image-container {
position: relative;
min-width: 160px
}
.close {
position: absolute;
right: 5px;
top: 5px;
background: #ff3034;
width: 16px;
height: 16px;
border-radius: 100px;
color: #fff;
text-align: center;
line-height: 18px;
cursor: pointer
}
.hidden {
display: none
}
</style>
</head>
<body>
<section class="main">
<div id="logo">
<label for="nav-toggle-cb" id="nav-toggle">&nbsp;&nbsp;Toggle esp32-cam settings</label>
</div>
<div id="content">
<div id="sidebar">
<input type="checkbox" id="nav-toggle-cb" checked="checked">
<nav id="menu">
<div class="input-group" id="framesize-group">
<label for="framesize">Resolution</label>
<select id="framesize" class="default-action">
<option value="10">UXGA(1600x1200)</option>
<option value="9">SXGA(1280x1024)</option>
<option value="8">XGA(1024x768)</option>
<option value="7">SVGA(800x600)</option>
<option value="6">VGA(640x480)</option>
<option value="5" selected="selected">CIF(400x296)</option>
<option value="4">QVGA(320x240)</option>
<option value="3">HQVGA(240x176)</option>
<option value="0">QQVGA(160x120)</option>
</select>
</div>
<div class="input-group" id="quality-group">
<label for="quality">Quality</label>
<div class="range-min">10</div>
<input type="range" id="quality" min="10" max="63" value="10" class="default-action">
<div class="range-max">63</div>
</div>
<div class="input-group" id="brightness-group">
<label for="brightness">Brightness</label>
<div class="range-min">-2</div>
<input type="range" id="brightness" min="-2" max="2" value="0" class="default-action">
<div class="range-max">2</div>
</div>
<div class="input-group" id="contrast-group">
<label for="contrast">Contrast</label>
<div class="range-min">-2</div>
<input type="range" id="contrast" min="-2" max="2" value="0" class="default-action">
<div class="range-max">2</div>
</div>
<div class="input-group" id="saturation-group">
<label for="saturation">Saturation</label>
<div class="range-min">-2</div>
<input type="range" id="saturation" min="-2" max="2" value="0" class="default-action">
<div class="range-max">2</div>
</div>
<div class="input-group" id="special_effect-group">
<label for="special_effect">Special Effect</label>
<select id="special_effect" class="default-action">
<option value="0" selected="selected">No Effect</option>
<option value="1">Negative</option>
<option value="2">Grayscale</option>
<option value="3">Red Tint</option>
<option value="4">Green Tint</option>
<option value="5">Blue Tint</option>
<option value="6">Sepia</option>
</select>
</div>
<div class="input-group" id="awb-group">
<label for="awb">AWB</label>
<div class="switch">
<input id="awb" type="checkbox" class="default-action" checked="checked">
<label class="slider" for="awb"></label>
</div>
</div>
<div class="input-group" id="awb_gain-group">
<label for="awb_gain">AWB Gain</label>
<div class="switch">
<input id="awb_gain" type="checkbox" class="default-action" checked="checked">
<label class="slider" for="awb_gain"></label>
</div>
</div>
<div class="input-group" id="wb_mode-group">
<label for="wb_mode">WB Mode</label>
<select id="wb_mode" class="default-action">
<option value="0" selected="selected">Auto</option>
<option value="1">Sunny</option>
<option value="2">Cloudy</option>
<option value="3">Office</option>
<option value="4">Home</option>
</select>
</div>
<div class="input-group" id="aec-group">
<label for="aec">AEC SENSOR</label>
<div class="switch">
<input id="aec" type="checkbox" class="default-action" checked="checked">
<label class="slider" for="aec"></label>
</div>
</div>
<div class="input-group" id="aec2-group">
<label for="aec2">AEC DSP</label>
<div class="switch">
<input id="aec2" type="checkbox" class="default-action" checked="checked">
<label class="slider" for="aec2"></label>
</div>
</div>
<div class="input-group" id="ae_level-group">
<label for="ae_level">AE Level</label>
<div class="range-min">-2</div>
<input type="range" id="ae_level" min="-2" max="2" value="0" class="default-action">
<div class="range-max">2</div>
</div>
<div class="input-group hidden" id="aec_value-group">
<label for="aec_value">Exposure</label>
<div class="range-min">0</div>
<input type="range" id="aec_value" min="0" max="1200" value="204" class="default-action">
<div class="range-max">1200</div>
</div>
<div class="input-group" id="agc-group">
<label for="agc">AGC</label>
<div class="switch">
<input id="agc" type="checkbox" class="default-action" checked="checked">
<label class="slider" for="agc"></label>
</div>
</div>
<div class="input-group hidden" id="agc_gain-group">
<label for="agc_gain">Gain</label>
<div class="range-min">1x</div>
<input type="range" id="agc_gain" min="0" max="30" value="5" class="default-action">
<div class="range-max">31x</div>
</div>
<div class="input-group" id="gainceiling-group">
<label for="gainceiling">Gain Ceiling</label>
<div class="range-min">2x</div>
<input type="range" id="gainceiling" min="0" max="6" value="0" class="default-action">
<div class="range-max">128x</div>
</div>
<div class="input-group" id="bpc-group">
<label for="bpc">BPC</label>
<div class="switch">
<input id="bpc" type="checkbox" class="default-action">
<label class="slider" for="bpc"></label>
</div>
</div>
<div class="input-group" id="wpc-group">
<label for="wpc">WPC</label>
<div class="switch">
<input id="wpc" type="checkbox" class="default-action" checked="checked">
<label class="slider" for="wpc"></label>
</div>
</div>
<div class="input-group" id="raw_gma-group">
<label for="raw_gma">Raw GMA</label>
<div class="switch">
<input id="raw_gma" type="checkbox" class="default-action" checked="checked">
<label class="slider" for="raw_gma"></label>
</div>
</div>
<div class="input-group" id="lenc-group">
<label for="lenc">Lens Correction</label>
<div class="switch">
<input id="lenc" type="checkbox" class="default-action" checked="checked">
<label class="slider" for="lenc"></label>
</div>
</div>
<div class="input-group" id="hmirror-group">
<label for="hmirror">H-Mirror</label>
<div class="switch">
<input id="hmirror" type="checkbox" class="default-action" checked="checked">
<label class="slider" for="hmirror"></label>
</div>
</div>
<div class="input-group" id="vflip-group">
<label for="vflip">V-Flip</label>
<div class="switch">
<input id="vflip" type="checkbox" class="default-action" checked="checked">
<label class="slider" for="vflip"></label>
</div>
</div>
<div class="input-group" id="dcw-group">
<label for="dcw">DCW (Downsize EN)</label>
<div class="switch">
<input id="dcw" type="checkbox" class="default-action" checked="checked">
<label class="slider" for="dcw"></label>
</div>
</div>
<div class="input-group" id="colorbar-group">
<label for="colorbar">Color Bar</label>
<div class="switch">
<input id="colorbar" type="checkbox" class="default-action">
<label class="slider" for="colorbar"></label>
</div>
</div>
<div class="input-group" id="light-group">
<label for="light">Light</label>
<div class="switch">
<input id="light" type="checkbox" class="default-action">
<label class="slider" for="light"></label>
</div>
</div>
<section id="buttons">
<button id="toggle-stream">Start Stream</button>
</section>
</nav>
</div>
<figure>
<div id="stream-container" class="image-container hidden">
<div class="close" id="close-stream">×</div>
<img id="stream" src="">
</div>
</figure>
</div>
</section>
<script>
var camera_port = "9600"
document.addEventListener('DOMContentLoaded', function (event) {
var baseHost = document.location.origin
var streamUrl = baseHost + ':' + camera_port;
const hide = el => {
el.classList.add('hidden')
}
const show = el => {
el.classList.remove('hidden')
}
const disable = el => {
el.classList.add('disabled')
el.disabled = true
}
const enable = el => {
el.classList.remove('disabled')
el.disabled = false
}
const updateValue = (el, value, updateRemote) => {
updateRemote = updateRemote == null ? true : updateRemote
let initialValue
if (el.type === 'checkbox') {
initialValue = el.checked
value = !!value
el.checked = value
} else {
initialValue = el.value
el.value = value
}
if (updateRemote && initialValue !== value) {
updateConfig(el);
} else if(!updateRemote){
if(el.id === "aec"){
value ? hide(exposure) : show(exposure)
} else if(el.id === "agc"){
if (value) {
show(gainCeiling)
hide(agcGain)
} else {
hide(gainCeiling)
show(agcGain)
}
} else if(el.id === "awb_gain"){
value ? show(wb) : hide(wb)
}
}
}
function updateConfig (el) {
let value
switch (el.type) {
case 'checkbox':
value = el.checked ? 1 : 0
break
case 'range':
case 'select-one':
value = el.value
break
case 'button':
case 'submit':
value = '1'
break
default:
return
}
const query = `${baseHost}/command?cmd=` + encodeURIComponent(`[ESP172]${el.id}=${value}`)
fetch(query)
.then(response => {
console.log(`request to ${query} finished, status: ${response.status}`)
})
}
document
.querySelectorAll('.close')
.forEach(el => {
el.onclick = () => {
hide(el.parentNode)
}
})
// read initial camera stream port
fetch(`${baseHost}/command?cmd=` + encodeURIComponent('[ESP800]'))
.then(function (response) {
return response.json()
})
.then(function (info) {
//get stream port
camera_port = info.Cam_port;
document.title = info.Cam_name;
fetch(`${baseHost}/command?cmd=` + encodeURIComponent(`[ESP172]`))
.then(function (response) {
return response.json()
})
.then(function (state) {
document
.querySelectorAll('.default-action')
.forEach(el => {
console.log(el + " " + state[el.id])
updateValue(el, parseInt(state[el.id]), false)
})
})
})
const view = document.getElementById('stream')
const viewContainer = document.getElementById('stream-container')
const streamButton = document.getElementById('toggle-stream')
const closeButton = document.getElementById('close-stream')
const stopStream = () => {
window.stop();
streamButton.innerHTML = 'Start Stream'
}
const startStream = () => {
view.src = `${streamUrl}/stream`
show(viewContainer)
streamButton.innerHTML = 'Stop Stream'
}
// Attach actions to buttons
closeButton.onclick = () => {
stopStream()
hide(viewContainer)
}
streamButton.onclick = () => {
const streamEnabled = streamButton.innerHTML === 'Stop Stream'
if (streamEnabled) {
stopStream()
} else {
startStream()
}
}
// Attach default on change action
document
.querySelectorAll('.default-action')
.forEach(el => {
el.onchange = () => updateConfig(el)
})
// Custom actions
// Gain
const agc = document.getElementById('agc')
const agcGain = document.getElementById('agc_gain-group')
const gainCeiling = document.getElementById('gainceiling-group')
agc.onchange = () => {
updateConfig(agc)
if (agc.checked) {
show(gainCeiling)
hide(agcGain)
} else {
hide(gainCeiling)
show(agcGain)
}
}
// Exposure
const aec = document.getElementById('aec')
const exposure = document.getElementById('aec_value-group')
aec.onchange = () => {
updateConfig(aec)
aec.checked ? hide(exposure) : show(exposure)
}
// AWB
const awb = document.getElementById('awb_gain')
const wb = document.getElementById('wb_mode-group')
awb.onchange = () => {
updateConfig(awb)
awb.checked ? show(wb) : hide(wb)
}
// Framesize
const framesize = document.getElementById('framesize')
framesize.onchange = () => {
updateConfig(framesize)
}
})
</script>
</body></html>

View File

@ -389,17 +389,12 @@ bool Commands::execute_internal_command (int cmd, const char* cmd_params, level_
break;
#endif //WS_DATA_FEATURE
#ifdef CAMERA_DEVICE
//Set carmera server state which can be ON, OFF
//[ESP170]<state>pwd=<admin password>
//Get/Set Camera command value / list all values in JSON/plain
//[ESP170]label=<value>pwd=<admin password>
//label can be: light/framesize/quality/contrast/brightness/saturation/gainceiling/colorbar/awb/agc/aec/hmirror/vflip/awb_gain/agc_gain/aec_value/aec2/cw/bpc/wpc/raw_gma/lenc/special_effect/wb_mode/ae_level
case 170:
response = ESP170(cmd_params, auth_type, output);
break;
case 171:
response = ESP171(cmd_params, auth_type, output);
break;
case 172:
response = ESP172(cmd_params, auth_type, output);
break;
#endif //CAMERA_DEVICE
#ifdef FTP_FEATURE
//Set Ftp state which can be ON, OFF

View File

@ -79,8 +79,6 @@ public:
#endif //WS_DATA_FEATURE
#if defined(CAMERA_DEVICE)
bool ESP170(const char* cmd_params, level_authenticate_type auth_level, ESP3DOutput * output);
bool ESP171(const char* cmd_params, level_authenticate_type auth_level, ESP3DOutput * output);
bool ESP172(const char* cmd_params, level_authenticate_type auth_level, ESP3DOutput * output);
#endif //CAMERA_DEVICE
#if defined(FTP_FEATURE)
bool ESP180(const char* cmd_params, level_authenticate_type auth_level, ESP3DOutput * output);

View File

@ -64,9 +64,7 @@ const char * help[]= {"[ESP] - display this help",
"[ESP161](Port) - display/set WebSocket port",
#endif //WS_DATA_FEATURE
#if defined(CAMERA_DEVICE)
"[ESP170](State) - display/set Camera state which can be ON, OFF, CLOSE",
"[ESP171](Port) - display/set Camera port",
"[ESP172](plain) (label=value) - display(JSON/plain)/set Camera commands",
"[ESP170](plain) (label=value) - display(JSON/plain)/set Camera commands",
#endif //CAMERA_DEVICE
#if defined(FTP_FEATURE)
"[ESP180](State) - display/set FTP state which can be ON, OFF",
@ -180,8 +178,6 @@ const uint cmdlist[]= {0,
#endif //WS_DATA_FEATURE
#if defined(CAMERA_DEVICE)
170,
171,
172,
#endif //CAMERA_DEVICE
#if defined(FTP_FEATURE)
180,

View File

@ -1,5 +1,5 @@
/*
ESP170.cpp - ESP3D command class
ESP122.cpp - ESP3D command class
Copyright (c) 2014 Luc Lebosse. All rights reserved.
@ -21,12 +21,15 @@
#if defined (CAMERA_DEVICE)
#include "../commands.h"
#include "../esp3doutput.h"
#include "esp_camera.h"
#include "../settings_esp3d.h"
#include "../../modules/authentication/authentication_service.h"
#include "../../modules/network/netservices.h"
#include "../../modules/camera/camera.h"
//Set camera server state which can be ON, OFF
//[ESP170]<state>pwd=<admin password>
//Set Camera command value / list all values in JSON/plain
//[ESP170]<plain><label=value> pwd=<admin password>
//label can be: light/framesize/quality/contrast/brightness/saturation/gainceiling/colorbar
// /awb/agc/aec/hmirror/vflip/awb_gain/agc_gain/aec_value/aec2/cw/bpc/wpc
// /raw_gma/lenc/special_effect/wb_mode/ae_level
bool Commands::ESP170(const char* cmd_params, level_authenticate_type auth_type, ESP3DOutput * output)
{
bool response = true;
@ -39,10 +42,447 @@ bool Commands::ESP170(const char* cmd_params, level_authenticate_type auth_type,
#else
(void)auth_type;
#endif //AUTHENTICATION_FEATURE
if (!esp3d_camera.started()) {
output->printERROR("No camera initialized!", 401);
return false;
}
parameter = get_param (cmd_params, "");
//get
if (parameter.length() == 0) {
output->printMSG(!esp3d_camera.serverstarted()?"Camera OFF":"Camera ON");
bool plain = hastag (cmd_params, "plain");
if ((parameter.length() == 0) || plain) {
sensor_t * s = esp_camera_sensor_get();
if (s == nullptr) {
if (!plain) {
output->print ("{\"status\":\"error\"}");
} else {
output->printERROR("No camera initialized!", 401);
}
return false;
}
if (!plain) {
output->print ("{\"status\":\"ok\",");
}
//framesize
if (!plain) {
output->print ("\"");
}
output->print ("framesize");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.framesize);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//quality
if (!plain) {
output->print ("\"");
}
output->print ("quality");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.quality);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//brightness
if (!plain) {
output->print ("\"");
}
output->print ("brightness");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.brightness);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//contrast
if (!plain) {
output->print ("\"");
}
output->print ("contrast");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.contrast);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//saturation
if (!plain) {
output->print ("\"");
}
output->print ("saturation");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.saturation);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//sharpness
if (!plain) {
output->print ("\"");
}
output->print ("sharpness");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.sharpness);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//special_effect
if (!plain) {
output->print ("\"");
}
output->print ("special_effect");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.special_effect);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//wb_mode
if (!plain) {
output->print ("\"");
}
output->print ("wb_mode");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.wb_mode);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//awb
if (!plain) {
output->print ("\"");
}
output->print ("awb");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.awb);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//awb_gain
if (!plain) {
output->print ("\"");
}
output->print ("awb_gain");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.awb_gain);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//aec
if (!plain) {
output->print ("\"");
}
output->print ("aec");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.aec);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//aec2
if (!plain) {
output->print ("\"");
}
output->print ("aec2");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.aec2);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//ae_level
if (!plain) {
output->print ("\"");
}
output->print ("ae_level");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.ae_level);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//aec_value
if (!plain) {
output->print ("\"");
}
output->print ("aec_value");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.aec_value);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//agc
if (!plain) {
output->print ("\"");
}
output->print ("agc");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.agc);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//agc_gain
if (!plain) {
output->print ("\"");
}
output->print ("agc_gain");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.agc_gain);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//gainceiling
if (!plain) {
output->print ("\"");
}
output->print ("gainceiling");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.gainceiling);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//bpc
if (!plain) {
output->print ("\"");
}
output->print ("bpc");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.bpc);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//wpc
if (!plain) {
output->print ("\"");
}
output->print ("wpc");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.wpc);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//raw_gma
if (!plain) {
output->print ("\"");
}
output->print ("raw_gma");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.raw_gma);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//lenc
if (!plain) {
output->print ("\"");
}
output->print ("lenc");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.lenc);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//vflip
if (!plain) {
output->print ("\"");
}
output->print ("vflip");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.vflip);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//hmirror
if (!plain) {
output->print ("\"");
}
output->print ("hmirror");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.hmirror);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//dcw
if (!plain) {
output->print ("\"");
}
output->print ("dcw");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.dcw);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//colorbar
if (!plain) {
output->print ("\"");
}
output->print ("colorbar");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.colorbar);
if (!plain) {
output->print ("\"");
} else {
output->printLN("");
}
#if CAM_LED_PIN != -1
//light
if (!plain) {
output->print (",\"");
}
output->print ("light");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (digitalRead(CAM_LED_PIN)==HIGH?1:0);
if (!plain) {
output->print ("\"");
} else {
output->printLN("");
}
#endif //CAM_LED_PIN
if (!plain) {
output->print ("}");
}
} else { //set
#ifdef AUTHENTICATION_FEATURE
if (auth_type != LEVEL_ADMIN) {
@ -50,23 +490,29 @@ bool Commands::ESP170(const char* cmd_params, level_authenticate_type auth_type,
return false;
}
#endif //AUTHENTICATION_FEATURE
parameter.toUpperCase();
if (!((parameter == "ON") || (parameter == "OFF"))) {
output->printERROR("Only ON or OFF mode supported!");
String label = get_label (cmd_params, "=");
if (label.length()==0) {
output->printERROR("Missing command!");
return false;
}
String labels = label+"=";
String value = get_param (cmd_params,labels.c_str());
if (value.length()==0) {
output->printERROR("Invalid value!");
return false;
}
int r = esp3d_camera.command(label.c_str(), value.c_str());
if (r == -1) {
output->printERROR("Unknow command!");
response = false;
} else if (r == 1) {
output->printERROR("Invalid value!");
response = false;
} else {
if (parameter == "ON") {
if(esp3d_camera.startStreamServer()) {
output->printMSG ("ok");
}
} else {
if(esp3d_camera.stopStreamServer()) {
output->printMSG ("ok");
}
}
output->printMSG ("ok");
}
}
return response;
}
#endif //HTTP_FEATURE && CAMERA_DEVICE
#endif //CAMERA_DEVICE

View File

@ -1,66 +0,0 @@
/*
ESP171.cpp - ESP3D command class
Copyright (c) 2014 Luc Lebosse. All rights reserved.
This code is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../../include/esp3d_config.h"
#if defined (CAMERA_DEVICE)
#include "../commands.h"
#include "../esp3doutput.h"
#include "../settings_esp3d.h"
#include "../../modules/authentication/authentication_service.h"
//Set Camera port
//[ESP171]<port>pwd=<admin password>
bool Commands::ESP171(const char* cmd_params, level_authenticate_type auth_type, ESP3DOutput * output)
{
bool response = true;
String parameter;
#ifdef AUTHENTICATION_FEATURE
if (auth_type == LEVEL_GUEST) {
output->printERROR("Wrong authentication!", 401);
return false;
}
#else
(void)auth_type;
#endif //AUTHENTICATION_FEATURE
parameter = get_param (cmd_params, "");
//get
if (parameter.length() == 0) {
output->printMSG(String(Settings_ESP3D::read_uint32(ESP_CAMERA_PORT)).c_str());
} else { //set
#ifdef AUTHENTICATION_FEATURE
if (auth_type != LEVEL_ADMIN) {
output->printERROR("Wrong authentication!", 401);
return false;
}
#endif //AUTHENTICATION_FEATURE
uint ibuf = parameter.toInt();
if ((ibuf > Settings_ESP3D::get_max_int32_value(ESP_CAMERA_PORT)) || (ibuf < Settings_ESP3D::get_min_int32_value(ESP_CAMERA_PORT))) {
output->printERROR ("Incorrect port!");
return false;
}
if (!Settings_ESP3D::write_uint32 (ESP_CAMERA_PORT, ibuf)) {
output->printERROR ("Set failed!");
response = false;
} else {
output->printMSG ("ok");
}
}
return response;
}
#endif //CAMERA_DEVICE

View File

@ -1,515 +0,0 @@
/*
ESP122.cpp - ESP3D command class
Copyright (c) 2014 Luc Lebosse. All rights reserved.
This code is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../../include/esp3d_config.h"
#if defined (CAMERA_DEVICE)
#include "../commands.h"
#include "../esp3doutput.h"
#include "esp_camera.h"
#include "../settings_esp3d.h"
#include "../../modules/authentication/authentication_service.h"
#include "../../modules/camera/camera.h"
//Set Camera command value / list all values in JSON/plain
//[ESP172]<plain><label=value> pwd=<admin password>
bool Commands::ESP172(const char* cmd_params, level_authenticate_type auth_type, ESP3DOutput * output)
{
bool response = true;
String parameter;
#ifdef AUTHENTICATION_FEATURE
if (auth_type == LEVEL_GUEST) {
output->printERROR("Wrong authentication!", 401);
return false;
}
#else
(void)auth_type;
#endif //AUTHENTICATION_FEATURE
if (!esp3d_camera.started()) {
output->printERROR("No camera initialized!", 401);
return false;
}
parameter = get_param (cmd_params, "");
//get
bool plain = hastag (cmd_params, "plain");
if ((parameter.length() == 0) || plain) {
sensor_t * s = esp_camera_sensor_get();
if (s == nullptr) {
if (!plain) {
output->print ("{\"status\":\"error\"}");
} else {
output->printERROR("No camera initialized!", 401);
}
return false;
}
if (!plain) {
output->print ("{\"status\":\"ok\",");
}
//framesize
if (!plain) {
output->print ("\"");
}
output->print ("framesize");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.framesize);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//quality
if (!plain) {
output->print ("\"");
}
output->print ("quality");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.quality);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//brightness
if (!plain) {
output->print ("\"");
}
output->print ("brightness");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.brightness);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//contrast
if (!plain) {
output->print ("\"");
}
output->print ("contrast");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.contrast);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//saturation
if (!plain) {
output->print ("\"");
}
output->print ("saturation");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.saturation);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//sharpness
if (!plain) {
output->print ("\"");
}
output->print ("sharpness");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.sharpness);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//special_effect
if (!plain) {
output->print ("\"");
}
output->print ("special_effect");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.special_effect);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//wb_mode
if (!plain) {
output->print ("\"");
}
output->print ("wb_mode");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.wb_mode);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//awb
if (!plain) {
output->print ("\"");
}
output->print ("awb");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.awb);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//awb_gain
if (!plain) {
output->print ("\"");
}
output->print ("awb_gain");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.awb_gain);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//aec
if (!plain) {
output->print ("\"");
}
output->print ("aec");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.aec);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//aec2
if (!plain) {
output->print ("\"");
}
output->print ("aec2");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.aec2);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//ae_level
if (!plain) {
output->print ("\"");
}
output->print ("ae_level");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.ae_level);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//aec_value
if (!plain) {
output->print ("\"");
}
output->print ("aec_value");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.aec_value);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//agc
if (!plain) {
output->print ("\"");
}
output->print ("agc");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.agc);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//agc_gain
if (!plain) {
output->print ("\"");
}
output->print ("agc_gain");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.agc_gain);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//gainceiling
if (!plain) {
output->print ("\"");
}
output->print ("gainceiling");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.gainceiling);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//bpc
if (!plain) {
output->print ("\"");
}
output->print ("bpc");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.bpc);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//wpc
if (!plain) {
output->print ("\"");
}
output->print ("wpc");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.wpc);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//raw_gma
if (!plain) {
output->print ("\"");
}
output->print ("raw_gma");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.raw_gma);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//lenc
if (!plain) {
output->print ("\"");
}
output->print ("lenc");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.lenc);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//vflip
if (!plain) {
output->print ("\"");
}
output->print ("vflip");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.vflip);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//hmirror
if (!plain) {
output->print ("\"");
}
output->print ("hmirror");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.hmirror);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//dcw
if (!plain) {
output->print ("\"");
}
output->print ("dcw");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.dcw);
if (!plain) {
output->print ("\",");
} else {
output->printLN("");
}
//colorbar
if (!plain) {
output->print ("\"");
}
output->print ("colorbar");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (s->status.colorbar);
if (!plain) {
output->print ("\"");
} else {
output->printLN("");
}
#if CAM_LED_PIN != -1
//light
if (!plain) {
output->print (",\"");
}
output->print ("light");
if (!plain) {
output->print ("\":\"");
} else {
output->print (" : ");
}
output->print (digitalRead(CAM_LED_PIN)==HIGH?1:0);
if (!plain) {
output->print ("\"");
} else {
output->printLN("");
}
#endif //CAM_LED_PIN
if (!plain) {
output->print ("}");
}
} else { //set
#ifdef AUTHENTICATION_FEATURE
if (auth_type != LEVEL_ADMIN) {
output->printERROR("Wrong authentication!", 401);
return false;
}
#endif //AUTHENTICATION_FEATURE
String label = get_label (cmd_params, "=");
if (label.length()==0) {
output->printERROR("Missing command!");
return false;
}
String labels = label+"=";
String value = get_param (cmd_params,labels.c_str());
if (value.length()==0) {
output->printERROR("Invalid value!");
return false;
}
int r = esp3d_camera.command(label.c_str(), value.c_str());
if (r == -1) {
output->printERROR("Unknow command!");
response = false;
} else if (r == 1) {
output->printERROR("Invalid value!");
response = false;
} else {
output->printMSG ("ok");
}
}
return response;
}
#endif //CAMERA_DEVICE

View File

@ -419,18 +419,6 @@ bool Commands::ESP400(const char* cmd_params, level_authenticate_type auth_type,
output->print (Settings_ESP3D::get_min_string_size(ESP_NOTIFICATION_SETTINGS));
output->print ("\"}");
#endif //NOTIFICATION_FEATURE
#ifdef CAMERA_DEVICE
//Camera Port
output->print (",{\"F\":\"device/camera\",\"P\":\"");
output->print (ESP_CAMERA_PORT);
output->print ("\",\"T\":\"I\",\"V\":\"");
output->print (Settings_ESP3D::read_uint32(ESP_CAMERA_PORT));
output->print ("\",\"H\":\"port\",\"S\":\"");
output->print (Settings_ESP3D::get_max_int32_value(ESP_CAMERA_PORT));
output->print ("\",\"M\":\"");
output->print (Settings_ESP3D::get_min_int32_value(ESP_CAMERA_PORT));
output->print ("\"}");
#endif //CAMERA_DEVICE
#ifdef BUZZER_DEVICE
//Buzzer state
output->print (",{\"F\":\"device/device\",\"P\":\"");

View File

@ -22,9 +22,6 @@
#include "../esp3doutput.h"
#include "../settings_esp3d.h"
#include "../../modules/authentication/authentication_service.h"
#ifdef CAMERA_DEVICE
#include "../../modules/camera/camera.h"
#endif //CAMERA_DEVICE
#ifdef SENSOR_DEVICE
#include "../../modules/sensor/sensor.h"
#endif //SENSOR_DEVICE
@ -130,11 +127,6 @@ bool Commands::ESP401(const char* cmd_params, level_authenticate_type auth_type,
esp3d_sensor.setInterval(sval.toInt());
break;
#endif //SENSOR_DEVICE
#ifdef CAMERA_DEVICE
case ESP_CAMERA_PORT:
//esp3d_camera.begin();
break;
#endif //CAMERA_DEVICE
default:
break;
}

View File

@ -493,22 +493,6 @@ bool Commands::ESP420(const char* cmd_params, level_authenticate_type auth_type,
} else {
output->printLN("");
}
//camera port
if (!plain) {
output->print (",{\"id\":\"");
}
output->print ("camera ports");
if (!plain) {
output->print ("\",\"value\":\"");
} else {
output->print (": ");
}
output->printf ("%d - %d",esp3d_camera.port(), esp3d_camera.port()+1);
if (!plain) {
output->print ("\"}");
} else {
output->printLN("");
}
}
#endif //CAMERA_DEVICE

View File

@ -263,18 +263,6 @@ bool Commands::ESP800(const char* cmd_params, level_authenticate_type auth_type,
output->print("\"");
}
#ifdef CAMERA_DEVICE
//camera port
if (plain) {
output->print("Camera port:");
} else {
output->print(",\"Cam_port\":\"");
}
output->print(esp3d_camera.port());
if(plain) {
output->printLN("");
} else {
output->print("\"");
}
//camera ID
if (plain) {
output->print("Camera ID:");

View File

@ -129,7 +129,6 @@
#define DEFAULT_FTP_ACTIVE_PORT 20L
#define DEFAULT_FTP_PASSIVE_PORT 55600L
#define DEFAULT_WEBSOCKET_PORT 8282L
#define DEFAULT_CAMERA_PORT 9600L
#define DEFAULT_TELNET_PORT 23L
#define DEFAULT_SENSOR_INTERVAL 30000L
#define DEFAULT_BOOT_DELAY 10000L
@ -408,11 +407,6 @@ uint32_t Settings_ESP3D::get_default_int32_value(int pos)
res = DEFAULT_WEBSOCKET_PORT;
break;
#endif //WS_DATA_FEATURE
#ifdef CAMERA_DEVICE
case ESP_CAMERA_PORT:
res = DEFAULT_CAMERA_PORT;
break;
#endif //CAMERA_DEVICE
#if defined(SENSOR_DEVICE)
case ESP_SENSOR_INTERVAL:
res = DEFAULT_SENSOR_INTERVAL;
@ -432,11 +426,6 @@ uint32_t Settings_ESP3D::get_max_int32_value(int pos)
case ESP_BOOT_DELAY:
res = MAX_BOOT_DELAY;
break;
#ifdef CAMERA_DEVICE
case ESP_CAMERA_PORT:
res = MAX_HTTP_PORT;
break;
#endif //CAMERA_DEVICE
#ifdef FTP_FEATURE
case ESP_FTP_CTRL_PORT:
case ESP_FTP_DATA_ACTIVE_PORT:
@ -478,11 +467,6 @@ uint32_t Settings_ESP3D::get_min_int32_value(int pos)
case ESP_BOOT_DELAY:
res = MIN_BOOT_DELAY;
break;
#ifdef CAMERA_DEVICE
case ESP_CAMERA_PORT:
res =MIN_HTTP_PORT;
break;
#endif //CAMERA_DEVICE
#ifdef FTP_FEATURE
case ESP_FTP_CTRL_PORT:
case ESP_FTP_DATA_ACTIVE_PORT:
@ -1133,11 +1117,6 @@ bool Settings_ESP3D::reset()
Settings_ESP3D::write_uint32 (ESP_TELNET_PORT, Settings_ESP3D::get_default_int32_value(ESP_TELNET_PORT));
#endif //TELNET
#ifdef CAMERA_DEVICE
//Camera Port
Settings_ESP3D::write_uint32 (ESP_CAMERA_PORT, Settings_ESP3D::get_default_int32_value(ESP_CAMERA_PORT));
#endif //CAMERA_DEVICE
#ifdef WS_DATA_FEATURE
//Websocket On
Settings_ESP3D::write_byte(ESP_WEBSOCKET_ON,Settings_ESP3D::get_default_byte_value(ESP_WEBSOCKET_ON));

View File

@ -86,7 +86,7 @@
#define ESP_CALIBRATION_3 993 //4 bytes = int
#define ESP_CALIBRATION_4 997 //4 bytes = int
#define ESP_CALIBRATION_5 1001 //4 bytes = int
#define ESP_CAMERA_PORT 1005 //4 bytes = int
#define ESP_FREE_ENTRY 1005 //4 bytes = int
#define ESP_FTP_CTRL_PORT 1009 //4 bytes = int
#define ESP_FTP_DATA_ACTIVE_PORT 1013 //4 bytes = int
#define ESP_FTP_DATA_PASSIVE_PORT 1017 //4 bytes = int

View File

@ -22,7 +22,7 @@
#define _VERSION_ESP3D_H
//version and sources location
#define FW_VERSION "3.0.0.a65"
#define FW_VERSION "3.0.0.a66"
#define REPOSITORY "https://github.com/luc-github/ESP3D/tree/3.0"
#endif //_VERSION_ESP3D_H

View File

@ -21,190 +21,50 @@
#include "../../include/esp3d_config.h"
#ifdef CAMERA_DEVICE
#include "camera.h"
#include "../../core/settings_esp3d.h"
#include "../network/netservices.h"
#include "../../core/esp3doutput.h"
#include "../../core/esp3d.h"
#include "../network/netconfig.h"
#include <WebServer.h>
#include <esp_camera.h>
#include "fd_forward.h"
#include <soc/soc.h> //not sure this one is needed
#include <soc/rtc_cntl_reg.h>
#include <driver/i2c.h>
#include <WebServer.h>
#define DEFAULT_FRAME_SIZE FRAMESIZE_SVGA
#define PART_BUFFER_SIZE 64
#define JPEG_COMPRESSION 80
#define MIN_WIDTH_COMPRESSION 400
#define PART_BOUNDARY "123456789000000000000987654321"
#define ESP3DSTREAM_RUNNING_PRIORITY 1
#define ESP3DSTREAM_RUNNING_CORE 0
#define CAMERA_YIELD 10
#define _STREAM_CONTENT_TYPE "multipart/x-mixed-replace;boundary=" PART_BOUNDARY
#define _STREAM_BOUNDARY "\r\n--" PART_BOUNDARY "\r\n"
#define _STREAM_PART "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n"
extern Esp3D myesp3d;
bool Camera::_initialised = false;
bool Camera::_connected = false;
Camera esp3d_camera;
STREAMSERVER * Camera::_streamserver = nullptr;
#ifdef CAMERA_INDEPENDANT_TASK
TaskHandle_t _hcameratask= nullptr;
#endif //CAMERA_INDEPENDANT_TASK
void Camera::handle_stream()
void Camera::handle_snap(WebServer * webserver)
{
log_esp3d("Camera stream reached");
if (!_initialised) {
log_esp3d("Camera not started");
_streamserver->send (500, "text/plain", "Camera not started");
return;
}
_connected = true;
#ifdef ESP_ACCESS_CONTROL_ALLOW_ORIGIN
_streamserver->enableCrossOrigin(true);
#endif //ESP_ACCESS_CONTROL_ALLOw_ORIGIN
camera_fb_t * fb = NULL;
bool res_error = false;
size_t _jpg_buf_len = 0;
uint8_t * _jpg_buf = NULL;
char * part_buf[PART_BUFFER_SIZE];
dl_matrix3du_t *image_matrix = NULL;
_streamserver->sendHeader(String(F("Content-Type")), String(F(_STREAM_CONTENT_TYPE)),true);
_streamserver->setContentLength(CONTENT_LENGTH_UNKNOWN);
_streamserver->send(200);
uint8_t retry = 0;
while(true) {
if (!_connected) {
log_esp3d("Camera is not connected");
_streamserver->send (500, "text/plain", "Camera is not connected");
_connected = false;
return;
}
log_esp3d("Camera capture ongoing");
fb = esp_camera_fb_get();
if (!fb) {
log_esp3d("Camera capture failed");
if ( retry < 3) {
log_esp3d("Retry %d",retry );
retry ++;
continue;
} else {
res_error = true;
}
} else {
if(fb->width > MIN_WIDTH_COMPRESSION) {
if(fb->format != PIXFORMAT_JPEG) {
bool jpeg_converted = frame2jpg(fb, JPEG_COMPRESSION, &_jpg_buf, &_jpg_buf_len);
esp_camera_fb_return(fb);
fb = NULL;
if(!jpeg_converted) {
log_esp3d("JPEG compression failed");
res_error = true;
}
} else {
_jpg_buf_len = fb->len;
_jpg_buf = fb->buf;
}
} else {
image_matrix = dl_matrix3du_alloc(1, fb->width, fb->height, 3);
if (!image_matrix) {
log_esp3d("dl_matrix3du_alloc failed");
res_error = true;
} else {
if(!fmt2rgb888(fb->buf, fb->len, fb->format, image_matrix->item)) {
log_esp3d("fmt2rgb888 failed");
res_error = true;
} else {
if (fb->format != PIXFORMAT_JPEG) {
if(!fmt2jpg(image_matrix->item, fb->width*fb->height*3, fb->width, fb->height, PIXFORMAT_RGB888, 90, &_jpg_buf, &_jpg_buf_len)) {
log_esp3d("fmt2jpg failed");
res_error = true;
}
esp_camera_fb_return(fb);
fb = NULL;
} else {
_jpg_buf = fb->buf;
_jpg_buf_len = fb->len;
}
}
dl_matrix3du_free(image_matrix);
}
}
}
//no one is connected so no need to stream
if (_streamserver->client().connected() == 0) {
break;
}
if(!res_error) {
size_t hlen = snprintf((char *)part_buf, PART_BUFFER_SIZE, _STREAM_PART, _jpg_buf_len);
_streamserver->sendContent_P ((const char *)part_buf, hlen);
}
if(!res_error) {
size_t processed = 0;
size_t packetSize = 2000;
uint8_t * currentbuf = _jpg_buf;
while (processed < _jpg_buf_len) {
_streamserver->sendContent_P ((const char *)&currentbuf[processed], packetSize);
processed+=packetSize;
if ((_jpg_buf_len - processed) < packetSize)packetSize = (_jpg_buf_len - processed);
vTaskDelay(1/ portTICK_PERIOD_MS);
}
}
if(!res_error) {
_streamserver->sendContent_P ((const char *)_STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
}
if(fb) {
esp_camera_fb_return(fb);
fb = NULL;
_jpg_buf = NULL;
} else if(_jpg_buf) {
free(_jpg_buf);
_jpg_buf = NULL;
}
if(res_error) {
log_esp3d("stream error stop connection");
break;
}
//Hal::wait(CAMERA_YIELD*100);
vTaskDelay(100 / portTICK_PERIOD_MS);
}
_connected = false;
_streamserver->sendContent("");
}
void Camera::handle_snap()
{
log_esp3d("Camera stream reached");
if (!_initialised) {
log_esp3d("Camera not started");
_streamserver->send (500, "text/plain", "Camera not started");
webserver->send (500, "text/plain", "Camera not started");
return;
}
sensor_t * s = esp_camera_sensor_get();
if (_streamserver->hasArg ("framesize") ) {
if(s->status.framesize != _streamserver->arg ("framesize").toInt()) {
command("framesize", _streamserver->arg ("framesize").c_str());
if (webserver->hasArg ("framesize") ) {
if(s->status.framesize != webserver->arg ("framesize").toInt()) {
command("framesize", webserver->arg ("framesize").c_str());
}
}
if (_streamserver->hasArg ("hmirror") ) {
command("hmirror", _streamserver->arg ("hmirror").c_str());
if (webserver->hasArg ("hmirror") ) {
command("hmirror", webserver->arg ("hmirror").c_str());
}
if (_streamserver->hasArg ("vflip") ) {
command("vflip", _streamserver->arg ("vflip").c_str());
if (webserver->hasArg ("vflip") ) {
command("vflip", webserver->arg ("vflip").c_str());
}
if (_streamserver->hasArg ("wb_mode") ) {
command("wb_mode", _streamserver->arg ("wb_mode").c_str());
if (webserver->hasArg ("wb_mode") ) {
command("wb_mode", webserver->arg ("wb_mode").c_str());
}
_connected = true;
#ifdef ESP_ACCESS_CONTROL_ALLOW_ORIGIN
_streamserver->enableCrossOrigin(true);
webserver->enableCrossOrigin(true);
#endif //ESP_ACCESS_CONTROL_ALLOw_ORIGIN
camera_fb_t * fb = NULL;
bool res_error = false;
@ -212,15 +72,15 @@ void Camera::handle_snap()
uint8_t * _jpg_buf = NULL;
char * part_buf[PART_BUFFER_SIZE];
dl_matrix3du_t *image_matrix = NULL;
_streamserver->sendHeader(String(F("Content-Type")), String(F("image/jpeg")),true);
_streamserver->sendHeader(String(F("Content-Disposition")), String(F("inline; filename=capture.jpg")),true);
_streamserver->setContentLength(CONTENT_LENGTH_UNKNOWN);
_streamserver->send(200);
webserver->sendHeader(String(F("Content-Type")), String(F("image/jpeg")),true);
webserver->sendHeader(String(F("Content-Disposition")), String(F("inline; filename=capture.jpg")),true);
webserver->setContentLength(CONTENT_LENGTH_UNKNOWN);
webserver->send(200);
log_esp3d("Camera capture ongoing");
fb = esp_camera_fb_get();
if (!fb) {
log_esp3d("Camera capture failed");
_streamserver->send (500, "text/plain", "Capture failed");
webserver->send (500, "text/plain", "Capture failed");
} else {
if(fb->width > MIN_WIDTH_COMPRESSION) {
if(fb->format != PIXFORMAT_JPEG) {
@ -263,7 +123,7 @@ void Camera::handle_snap()
}
}
if (!res_error) {
_streamserver->sendContent_P ((const char *)_jpg_buf, _jpg_buf_len);
webserver->sendContent_P ((const char *)_jpg_buf, _jpg_buf_len);
}
if(fb) {
@ -274,29 +134,13 @@ void Camera::handle_snap()
free(_jpg_buf);
_jpg_buf = NULL;
}
_connected = false;
_streamserver->sendContent("");
webserver->sendContent("");
}
#ifdef CAMERA_INDEPENDANT_TASK
void ESP3DStreamTaskfn( void * parameter )
{
Hal::wait(100); // Yield to other tasks
for(;;) {
esp3d_camera.process();
//Hal::wait(CAMERA_YIELD); // Yield to other tasks
vTaskDelay(10 / portTICK_PERIOD_MS);
}
vTaskDelete( NULL );
}
#endif //CAMERA_INDEPENDANT_TASK
Camera::Camera()
{
_server_started = false;
_started = false;
_connected = false;
_streamserver = nullptr;
_initialised = false;
}
Camera::~Camera()
@ -449,76 +293,6 @@ bool Camera::stopHardware()
return true;
}
bool Camera::startStreamServer()
{
stopStreamServer();
if (!_initialised) {
log_esp3d("Camera not initialised");
return false;
}
if (NetConfig::started() && (NetConfig::getMode()!= ESP_BT)) {
ESP3DOutput output(ESP_ALL_CLIENTS);
_port = Settings_ESP3D::read_uint32(ESP_CAMERA_PORT);
log_esp3d("Starting camera server");
_streamserver= new STREAMSERVER(_port);
if (!_streamserver) {
log_esp3d("Starting camera server failed");
output.printERROR("Starting camera server failed");
return false;
}
_streamserver->on("/snap",HTTP_ANY, handle_snap);
_streamserver->on("/",HTTP_ANY, handle_snap);
_streamserver->on("/stream",HTTP_ANY, handle_stream);
_streamserver->begin();
String stmp = "Camera server started port " + String(_port);
output.printMSG(stmp.c_str());
#ifdef CAMERA_INDEPENDANT_TASK
//create serial task once
if (_hcameratask == nullptr) {
xTaskCreatePinnedToCore(
ESP3DStreamTaskfn, /* Task function. */
"ESP3DStream Task", /* name of task. */
8192, /* Stack size of task */
NULL, /* parameter of the task */
ESP3DSTREAM_RUNNING_PRIORITY, /* priority of the task */
&_hcameratask, /* Task handle to keep track of created task */
ESP3DSTREAM_RUNNING_CORE /* Core to run the task */
);
if (_hcameratask == nullptr) {
log_esp3d("Camera Task creation failed");
return false;
}
}
#endif //CAMERA_INDEPENDANT_TASK
_server_started = true;
}
for (int j = 0; j < 5; j++) {
camera_fb_t * fb = esp_camera_fb_get(); // start the camera ... warm it up
if (fb == nullptr) {
log_esp3d("Failed to get fb");
}
esp_camera_fb_return(fb);
delay(20);
}
return _server_started;
}
bool Camera::stopStreamServer()
{
_connected = false;
if (_server_started) {
if (_streamserver) {
log_esp3d("Stop stream server");
_streamserver->stop();
delete _streamserver;
_streamserver = NULL;
}
_server_started = false;
}
return true;
}
//need to be call by device and by network
bool Camera::begin()
{
@ -548,32 +322,18 @@ bool Camera::begin()
} else {
log_esp3d("Cannot access camera sensor");
}
_started = startStreamServer();
_started = _initialised;
return _started;
}
void Camera::end()
{
if (_started) {
_started = false;
stopStreamServer();
}
}
void Camera::process()
{
if (_started) {
if (_streamserver) {
_streamserver->handleClient();
}
}
_started = false;
}
void Camera::handle()
{
#ifndef CAMERA_INDEPENDANT_TASK
process();
#endif //CAMERA_INDEPENDANT_TASK
//nothing to do
}
uint8_t Camera::GetModel()

View File

@ -22,15 +22,7 @@
#ifndef _CAMERA_H
#define _CAMERA_H
//class WebSocketsServer;
#if defined (ARDUINO_ARCH_ESP32)
class WebServer;
#define STREAMSERVER WebServer
#endif //ARDUINO_ARCH_ESP32
#if defined (ARDUINO_ARCH_ESP8266)
#include <ESP8266WebServer.h>
#define STREAMSERVER ESP8266WebServer
#endif //ARDUINO_ARCH_ESP8266
#include <WebServer.h>
class Camera
{
@ -41,46 +33,22 @@ public:
void end();
bool initHardware();
bool stopHardware();
bool startStreamServer();
bool stopStreamServer();
static void handle_stream();
static void handle_snap();
void process();
void handle_snap(WebServer * webserver);
void handle();
static int command(const char * param, const char * value);
int command(const char * param, const char * value);
uint8_t GetModel();
const char *GetModelString();
bool started()
{
return _started;
}
bool serverstarted()
{
return _server_started;
}
void connect(bool status)
{
_connected = status;
}
bool isconnected()
{
return _connected;
}
bool isinitialised()
{
return _initialised;
}
uint16_t port()
{
return _port;
}
private:
static bool _initialised;
static STREAMSERVER * _streamserver;
bool _server_started;
bool _initialised;
bool _started;
static bool _connected;
uint16_t _port;
};
extern Camera esp3d_camera;

View File

@ -0,0 +1,43 @@
/*
handle-snap.cpp - ESP3D http handle
Copyright (c) 2014 Luc Lebosse. All rights reserved.
This code is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../../../include/esp3d_config.h"
#if defined (HTTP_FEATURE) && defined (CAMERA_DEVICE)
#include "../../camera/camera.h"
#include "../http_server.h"
#if defined (ARDUINO_ARCH_ESP32)
#include <WebServer.h>
#endif //ARDUINO_ARCH_ESP32
#if defined (ARDUINO_ARCH_ESP8266)
#include <ESP8266WebServer.h>
#endif //ARDUINO_ARCH_ESP8266
#include "../../authentication/authentication_service.h"
#include "../../../core/commands.h"
#include "../../../core/esp3doutput.h"
void HTTP_Server::handle_snap()
{
level_authenticate_type auth_level = AuthenticationService::authenticated_level();
if (auth_level == LEVEL_GUEST) {
_webserver->send (401, "text/plain", "Wrong authentication!");
return;
}
esp3d_camera.handle_snap(_webserver);
}
#endif //HTTP_FEATURE && CAMERA_DEVICE

View File

@ -65,11 +65,14 @@ void HTTP_Server::init_handlers()
//web update
_webserver->on ("/updatefw", HTTP_ANY, handleUpdate, WebUpdateUpload);
#endif //WEB_UPDATE_FEATURE
#ifdef CAMERA_DEVICE
_webserver->on("/snap", HTTP_GET, handle_snap);
#endif //CAMERA_DEVICE
#ifdef SSDP_FEATURE
if(WiFi.getMode() != WIFI_AP) {
_webserver->on("/description.xml", HTTP_GET, handle_SSDP);
}
#endif
#endif //SSDP_FEATURE
#ifdef CAPTIVE_PORTAL_FEATURE
if(WiFi.getMode() == WIFI_AP) {
_webserver->on ("/generate_204", HTTP_ANY, handle_root);
@ -77,7 +80,7 @@ void HTTP_Server::init_handlers()
//do not forget the / at the end
_webserver->on ("/fwlink/", HTTP_ANY, handle_root);
}
#endif
#endif //CAPTIVE_PORTAL_FEATURE
}
bool HTTP_Server::StreamFSFile(const char* filename, const char * contentType)

View File

@ -66,8 +66,11 @@ private:
static const char * getContentType (const char * filename);
static const char * get_Splited_Value(String data, char separator, int index);
#ifdef SSDP_FEATURE
static void handle_SSDP ();
static void handle_SSDP();
#endif //SSDP_FEATURE
#ifdef CAMERA_DEVICE
static void handle_snap();
#endif //CAMERA_DEVICE
static void init_handlers();
static bool StreamFSFile(const char* filename, const char * contentType);
static void handle_root();