Une autre question
Comment les cde et infos sont configurer dans jeedom ? Espeasy ?
Par script pour les entrées/sorties (led / GPIO12). Voir l’en-tête du code .ino pour les paramètres du script.
Pas d’ESPEasy puisque c’est du code compilé en direct.
Comme le dit @Theduck38
tu peut manipuler ces commandes depuis ton jeedom a l’aide du pulugin script
ou depuis un scénario
ex:
Attention néanmoins dans tes commandes de script il te faudra ajuster l’adresse IP à celle de ta caméra…
Tiens, j’ai une question concernant les récupérations d’états sur un script… comment fais-tu ?
Il faut appeler le « refresh » du script pour avoir des états à jour… tu passes par un scénario qui rafraîchit toutes les xx minutes chaque commande, ou l’auto-actualisation du script dans l’onglet « équipement » ?
Dans le cas présenté en exemple puisque c’est le même équipement il se trouve rafraîchi a chaque action ou au refresh
Dans un scénario tu peut demandé l’état sans passer par un plugin-script
Je vous laisse découvrir …
CODE V1.8
//---------------------------------------------------------------------------------------------------------------------
// DOCS UTILES:
// ------------
// SERVEUR WEB CAM: https://community.jeedom.com/t/tuto-camera-a-focale-fixe-basee-sur-esp32/17587/49
// LED WIFI: https://techtutorialsx.com/2018/02/03/esp32-arduino-async-server-controlling-http-methods-allowed/
// Installing Asyncwebserver: https://techtutorialsx.com/2017/12/01/esp32-arduino-asynchronous-http-webserver/
// IMAGE PARAMS: https://randomnerdtutorials.com/esp32-cam-ov2640-camera-settings/
// @drs
// modified @olive v1.71 jeudi 21 mai 2020 21h27
//
// PARAMETRES A MODIFIER:
// ----------------------
// RESOLUTION: FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA / QUALITY (10-63)
// WSPORT: port web (pour affichage images)
// ASYNCPORT: port AsyncWebServer (pour gestion LED)
// Paramètres image
//
// USAGE:
// ------
// http://ip-esp:WSPORT/ page d'accueil
// http://ip-esp:WSPORT/_ac page de config
// http://ip-esp:WSPORT/mjpg: stream
// http://ip-esp:WSPORT/snapshot.jpg image
//
// GESTION DE LA LED:
// ------------------
// http://ip-esp:ASYNCPORT/led Etat de la led (format binaire)
// http://ip-esp:ASYNCPORT/led/on Allume la LED
// http://ip-esp:ASYNCPORT/led/off Eteint la LED
// http://ip-esp:ASYNCPORT/led/toggle Allume/Eteint la LED
//
// GESTION DU GPIO12:
// ------------------
// http://ip-esp:ASYNCPORT/gpio12 Etat du gpio2 (format binaire)
// http://ip-esp:ASYNCPORT/gpio12/on Allume gpio12
// http://ip-esp:ASYNCPORT/gpio12/off Eteint gpio12
// http://ip-esp:ASYNCPORT/gpio12/toggle Allume/Eteint gpio12
//
// INTEGRATION JEEDOM:
// -------------------
// Plugin Camera:
// Laisser le type de camera sur "Aucun"
// Renseigner l'IP et le port (webserver)
// URL de snapshot: /snapshot.jpg
// URL de flux: /mjpg
//
// Script gestion led:
// Action/Default
// URL: voir ci-dessus
// Cocher "Pas d'erreurs"
// La réponse doit contenir: ok (en minuscule)
// Timeout: si besoin (pas nécessaire)
//
//---------------------------------------------------------------------------------------------------------------------
#include <WiFi.h>
#include <WebServer.h>
#include <ESPAsyncWebServer.h> //permet la connexion simultanee pour la gestion de la LED
#include <WiFiClient.h>
#include <AutoConnect.h> // Needs AutoConnect, PageBuilder libraries!
#include "soc/soc.h" //disable brownout problems
#include "soc/rtc_cntl_reg.h" //disable brownout problems
#include "esp_camera.h" // Pas sur de l'utilité. A vérifier
#define ENABLE_RTSPSERVER
#define ENABLE_WEBSERVER
#define RESOLUTION FRAMESIZE_CIF // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
#define QUALITY 10 // JPEG quality 10-63 (lower means better quality)
// PARAMETRES IMAGE
#define BRIGHT 1 // Brightness: -2 to 2
#define CONTRAST 0 // Contrast: -2 to 2
#define SATUR 0 // Color Saturation: -2 to 2
#define SPECIAL 0 // Special effects: 0 to 6 (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia)
#define WHITEBAL 1 // White Balance: 0 = disable , 1 = enable
#define AWBGAIN 1 // White Balance Gain: 0 = disable , 1 = enable
#define AWBMODE 3 // White Balance Mode: 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home)
#define EXPOS 1 // Exposure Control: 0 = disable , 1 = enable
#define AEC2 0 // 0 = disable , 1 = enable
#define AELEV 0 // -2 to 2
#define AECVAL 300 // 0 to 1200
#define GAINCT 1 // 0 = disable , 1 = enable
#define GAINAGC 0 // 0 = disable , 1 = enable
#define GAINCELL 0 // 0 = disable , 1 = enable
#define BPC 0 // 0 = disable , 1 = enable
#define WPC 1 // 0 = disable , 1 = enable
#define RAWGMA 1 // 0 = disable , 1 = enable
#define LENC 1 // Lens Correction: 0 = disable , 1 = enable
#define MIRROR 0 // Horizontal Mirror: 0 = disable , 1 = enable
#define FLIP 0 // Vertical Flip: 0 = disable , 1 = enable
#define DCW 1 // 0 = disable , 1 = enable
#define CBAR 0 // Set a colorBar: 0 = disable , 1 = enable
#define LED_BUILTIN 4 // VA SERVIR POUR ALLUMER et ETEINDRE LA LED - NE PAS MODIFIER CETTE VALEUR (GPIO4)
#include "OV2640.h"
#ifdef ENABLE_RTSPSERVER
#include "OV2640Streamer.h"
#include "CRtspSession.h"
#endif
OV2640 cam;
boolean useRTSP = true;
#define WSPORT 80 // modifier le port pour Webserver Image
#define ASYNCPORT 81 // modifier le port pour Webserver LED
WebServer server(WSPORT);
AsyncWebServer serverasync(ASYNCPORT);
AutoConnect Portal(server);
AutoConnectConfig acConfig;
#ifdef ENABLE_RTSPSERVER
WiFiServer rtspServer(554);
CStreamer *streamer;
#endif
void handle_jpg_stream(void)
{
WiFiClient client = server.client();
String response = "HTTP/1.1 200 OK\r\n";
response += "Content-Type: multipart/x-mixed-replace; boundary=frame\r\n\r\n";
server.sendContent(response);
while (1)
{
cam.run();
if (!client.connected())
break;
response = "--frame\r\n";
response += "Content-Type: image/jpeg\r\n\r\n";
server.sendContent(response);
client.write((char *)cam.getfb(), cam.getSize());
server.sendContent("\r\n");
if (!client.connected())
break;
}
}
void handle_jpg(void)
{
WiFiClient client = server.client();
cam.run();
if (!client.connected())
{
return;
}
String response = "HTTP/1.1 200 OK\r\n";
response += "Content-disposition: inline; filename=snapshot.jpg\r\n";
response += "Content-type: image/jpeg\r\n\r\n";
server.sendContent(response);
client.write((char *)cam.getfb(), cam.getSize());
}
void handle_root(void)
{
String reply ="<!doctype html>\
<style type=text/css>\
body {\
background-color: #272727; \
}\
<style>\
th, td {\
border: 1px solid black;\
background-color: #FFFF00; \
}\
table {\
border-collapse: collapse;\
background-color: #00AA00; \
}\
a {\
color: red; \
}\
</style>";
reply +=F("<html><head><meta charset='UTF-8'></head><table><tr><td colspan='2'><H1>ESP32CAM</H1></td></tr>");
reply +=F("<tr><td>VERSION </td><td>1.8</td></tr>");
reply += F("<tr><td>Resolution</td>");
switch(RESOLUTION) {
case FRAMESIZE_QVGA:
reply += F("<td>QVGA (320x240)</td>");
break;
case FRAMESIZE_CIF:
reply += F("<td>CIF (400x296)</td>");
break;
case FRAMESIZE_VGA:
reply += F("<td>VGA (640x480)</td>");
break;
case FRAMESIZE_SVGA:
reply += F("<td>SVGA (800x600)</td>");
break;
case FRAMESIZE_XGA:
reply += F("<td>XGA (1024x768)</td>");
break;
case FRAMESIZE_SXGA:
reply += F("<td>SXGA (1280x1024)</td>");
break;
case FRAMESIZE_UXGA:
reply += F("<td>UXGA (1600x1200)</td>");
break;
default:
reply += F("<td>Unknown</td>");
break;
}
reply += F("</tr><tr><td>PSRAM found</td>");
if (psramFound()){
reply += F("<td>TRUE</td></tr>");
} else {
reply += F("<td>FALSE</td></tr></tr>");
}
String IP = WiFi.localIP().toString();
String IPH = "http://" + IP + ":" + WSPORT;
String IPA = "http://" + IP + ":" + ASYNCPORT;
String IPR = "rstp://" + IP + ":554";
String url = IPH + "/snapshot.jpg";
reply += "<tr><td>Snapshot URL</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
url = IPH + "/mjpg";
reply += "<tr><td>HTTP MJPEG URL</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
url = IPR + "/mjpeg/1";
reply += "<tr><td>RTSP MJPEG URL</td><td>" + url;
url = IPH + "/_ac";
reply += "<tr><td>WiFi settings page</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
//LED
url = IPA + "/led/on";
reply += "<tr><td>Led_on</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
url = IPA + "/led/off";
reply += "<tr><td>Led_off</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
url = IPA + "/led/toggle";
reply += "<tr><td>Led_toggle</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
url = IPA + "/led";
reply += "<tr><td>Led_etat</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
//GPIO12
url = IPA + "/gpio12/on";
reply += "<tr><td>gpio12_on</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
url = IPA + "/gpio12/off";
reply += "<tr><td>gpio12_off</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
url = IPA + "/gpio12/toggle";
reply += "<tr><td>gpio12_toggle</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
url = IPA + "/gpio12";
reply += "<tr><td>gpio12_etat</td><td><a href='" + url + "'>" + url + "</a></td></tr>";
reply += "</table><img src='"+IPH+"/mjpg'>\
</body></html>";
server.send(200, "text/html", reply);
}
void handleNotFound()
{
String message = "Server is running!\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
server.send(200, "text/plain", message);
}
void setup(){
pinMode(LED_BUILTIN, OUTPUT); // pour LED
digitalWrite(LED_BUILTIN, LOW); // pour LED
pinMode(12, OUTPUT); // pour RELAIS SUR GPIO12
digitalWrite(12, LOW); // pour RELAIS SUR GPIO12
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
Serial.begin(115200);
// while (!Serial){;} // debug only
camera_config_t cconfig;
cconfig = esp32cam_aithinker_config;
if (psramFound()) {
cconfig.frame_size = RESOLUTION; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
cconfig.jpeg_quality = QUALITY;
cconfig.fb_count = 2;
} else {
if (RESOLUTION>FRAMESIZE_SVGA) {
cconfig.frame_size = FRAMESIZE_SVGA;
}
cconfig.jpeg_quality = 12;
cconfig.fb_count = 1;
}
cam.init(cconfig);
sensor_t * s = esp_camera_sensor_get();
s->set_brightness(s, BRIGHT);
s->set_contrast(s, CONTRAST);
s->set_saturation(s, SATUR);
s->set_special_effect(s, SPECIAL);
s->set_whitebal(s, WHITEBAL);
s->set_awb_gain(s, AWBGAIN);
s->set_wb_mode(s, AWBMODE);
s->set_exposure_ctrl(s, EXPOS);
s->set_aec2(s, AEC2);
s->set_ae_level(s, AELEV);
s->set_aec_value(s, AECVAL);
s->set_gain_ctrl(s, GAINCT);
s->set_agc_gain(s, GAINAGC);
s->set_gainceiling(s, (gainceiling_t)GAINCELL);
s->set_bpc(s, BPC);
s->set_wpc(s, WPC);
s->set_raw_gma(s, RAWGMA);
s->set_lenc(s, LENC);
s->set_hmirror(s, MIRROR);
s->set_vflip(s, FLIP);
s->set_dcw(s, DCW);
s->set_colorbar(s, CBAR);
server.on("/", handle_root);
server.on("/mjpg", HTTP_GET, handle_jpg_stream);
server.on("/snapshot.jpg", HTTP_GET, handle_jpg);
Portal.onNotFound(handleNotFound);
acConfig.apid = "ESP-" + String((uint32_t)(ESP.getEfuseMac() >> 32), HEX);
acConfig.psk = "configesp";
acConfig.apip = IPAddress(192,168,4,1);
acConfig.hostName = acConfig.apid;
acConfig.autoReconnect = true;
Portal.config(acConfig);
Portal.begin();
Serial.println(" ");
Serial.println("Adresse IP: " + WiFi.localIP().toString() );
Serial.println(" ");
// POUR LED
serverasync.on("/led/off", HTTP_ANY, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", "ok");
digitalWrite(LED_BUILTIN, LOW);
Serial.println("LED TURNED OFF");
});
serverasync.on("/led/on", HTTP_ANY, [](AsyncWebServerRequest *request){
request->send(200, "text/plain","ok");
digitalWrite(LED_BUILTIN, HIGH);
Serial.println("LED TURNED ON");
});
serverasync.on("/led/toggle", HTTP_ANY, [](AsyncWebServerRequest *request){
request->send(200, "text/plain","ok");
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
Serial.println("LED TURNED TOGGLE");
});
serverasync.on("/led", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", String(digitalRead(LED_BUILTIN)));
});
// POUR GPIO 12
serverasync.on("/gpio12/off", HTTP_ANY, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", "ok");
digitalWrite(12, LOW);
Serial.println("gpio12 TURNED OFF");
});
serverasync.on("/gpio12/on", HTTP_ANY, [](AsyncWebServerRequest *request){
request->send(200, "text/plain","ok");
digitalWrite(12, HIGH);
Serial.println("gpio12 TURNED ON");
});
serverasync.on("/gpio12/toggle", HTTP_ANY, [](AsyncWebServerRequest *request){
request->send(200, "text/plain","ok");
digitalWrite(12, !digitalRead(12));
Serial.println("gpio12 TURNED TOGGLE");
});
serverasync.on("/gpio12", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", String(digitalRead(12)));
});
serverasync.begin();
#ifdef ENABLE_RTSPSERVER
if (useRTSP) {
rtspServer.begin();
streamer = new OV2640Streamer(cam); // our streamer for UDP/TCP based RTP transport
}
#endif
}
void loop()
{
//server.handleClient();
Portal.handleClient();
#ifdef ENABLE_RTSPSERVER
if (useRTSP) {
uint32_t msecPerFrame = 100;
static uint32_t lastimage = millis();
// If we have an active client connection, just service that until gone
streamer->handleRequests(0); // we don't use a timeout here,
// instead we send only if we have new enough frames
uint32_t now = millis();
if (streamer->anySessions()) {
if (now > lastimage + msecPerFrame || now < lastimage) { // handle clock rollover
streamer->streamImage(now);
lastimage = now;
// check if we are overrunning our max frame rate
now = millis();
if (now > lastimage + msecPerFrame) {
printf("warning exceeding max frame rate of %d ms\n", now - lastimage);
}
}
}
WiFiClient rtspClient = rtspServer.accept();
if (rtspClient) {
Serial.print("client: ");
Serial.print(rtspClient.remoteIP());
Serial.println();
streamer->addSession(rtspClient);
}
}
#endif
}
@Theduck38 tu va devoir corriger le post 7 aussi
Bon boulot ! c’est OK pour moi (+ led OK mais pas testé le GPIO hormis etat qui est cohérent)
Je croyais que tu allais sortir une version avec tous les param de gestion cam en param optionels d’une url de params
http://192.168.1.x/params?RESOLUTION=FRAMESIZE_CIF?QUALITY=10?BRIGHT=1?WHITEBAL=0...
Mais là j’exagère peut-être
Je suis pas sur que ce soit interessant en ligne de commande mais pourquoi pas ?
pour tester le gpio il te suffit ou d’une voltmetre ou d’une led …
A mettre entre GND et IO12 tu doit trouvé 0 ou 3 volts.
Yes ça je maîtrise pas l’utilité sur cette cam. Merci
Cela avait été demandé en début de post pour avoir un contact sec il faut bien sur ajouter un relais …
Super, j’ai mis à jour le post avec les bibliothèques et la version actuelle.
Concernant le relais, c’était pour pouvoir commander un filtre IR si j’ai bien compris, voire déclencher de l’éclairage led IR pour une caméra nocturne. C’est un sujet que je ne maîtrise pas du tout (filtre IR, pas filtre etc…), mais ça pourrait être intéressant ; d’autant que les caméras devraient être directement compatibles.
J’ai tout commandé pour tester. Relais, les ir… Des que ça arrive je teste et vous dit.
Salut à tous,
Cela fait quelques temps que je cherchais un code fonctionnel, super et merci pour le boulot.
Une remarque sur la commande snapshot, c’est la photo n-1 qui remonte quand on sollicite url.
Par ailleurs, est-ce une limitation technique de ne pas avoir implémenté la maj via http ?
C’est très pratique quand l’objet est en production
A+
Comme je l’ait dit C arduino n’est pas vraiment ma tasse de tea …
Il faut que je travaille sur une base MicroPython la ce sera beaucoup plus simple de faire de la MAJ à distance en ligne …
patience !
Pour ma part, je ne suis pas un expert de la prog, mais je suis plus à l’aise en arduino donc en C
J’essaie de le faire mais avec déjà tout ces serveurs web, j’ai peur de mettre la grouille.
A+
Oui, j’ai dû l’indiquer quelque part dans le tuto… pas trouvé pourquoi.
en tout cas olive, super taf !!!
je serais aussi preneur si possible de la possiblité de couper les divers flux manuellement , dans l’optique d’économiser des ressources (si ça a un impact)
perso, le flux HTTP ne m’interesse pas du tout car j’utiliserais seulement le flux RTSP et les snapshots pour jeedom + tinyCAM monitor
encore merci pour le partage !
Bonjour,
j’essaye de reflashé mes esp32 pour les mettre sur la nouvelle version mais impossible de compiler.
j’ai bien un dossier libraries avec les bon dossier 1.8
j’ai bien le dossier ESP32_RTSP_Cam_v1.8
Tout ceci dans document arduino.
j’ai supprimer tous l’ancienne version pour éviter les conflits.
voici les messsages d’erreurs.
In file included from C:\Users\EDC292\Documents\Arduino\libraries\AutoConnect-master\src/AutoConnectAux.h:22:0,
from C:\Users\EDC292\Documents\Arduino\libraries\AutoConnect-master\src/AutoConnect.h:34,
Plusieurs bibliothèque trouvées pour « WiFi.h »
Utilisé : C:\Users\EDC292\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\WiFi
Non utilisé : C:\Program Files (x86)\Arduino\libraries\WiFi
from C:\Users\EDC292\Documents\Arduino\ESP32_RTSP_Cam_v1.8\ESP32_RTSP_Cam_v1.8.ino:60:
C:\Users\EDC292\Documents\Arduino\libraries\AutoConnect-master\src/AutoConnectElement.h:15:25: fatal error: ArduinoJson.h: No such file or directory
compilation terminated.
exit status 1
Erreur de compilation pour la carte ESP32 Wrover Module
il te faut rajouter la librairies arduinojson j’ai l’inpression
et autoconnect
j’ai ça :
Dallas et MAX a mon avis pas nécessaire