Camera api to protobuf - still and stream not tested

This commit is contained in:
Niklas Jensen
2026-01-30 14:30:42 +01:00
committed by nikguin04
parent 1a280f5356
commit e1f44a6f06
9 changed files with 146 additions and 154 deletions
+6 -5
View File
@@ -1,12 +1,12 @@
#pragma once
#include <ArduinoJson.h>
#include <esp_http_server.h>
#include <WiFi.h>
#include <features.h>
#include <template/stateful_persistence.h>
#include <template/stateful_endpoint.h>
#include <template/stateful_service.h>
#include <template/stateful_proto_endpoint.h>
#include <template/stateful_persistence_pb.h>
#include <settings/camera_settings.h>
@@ -19,6 +19,7 @@ namespace Camera {
#endif
#define PART_BOUNDARY "frame"
#define CAMERA_SETTINGS_FILE "/config/cameraSettings.pb"
camera_fb_t *safe_camera_fb_get();
sensor_t *safe_sensor_get();
@@ -33,10 +34,10 @@ class CameraService : public StatefulService<CameraSettings> {
esp_err_t cameraStill(httpd_req_t *request);
esp_err_t cameraStream(httpd_req_t *request);
StatefulHttpEndpoint<CameraSettings> endpoint;
StatefulProtoEndpoint<CameraSettings, api_CameraSettings> protoEndpoint;
private:
FSPersistence<CameraSettings> _persistence;
FSPersistencePB<CameraSettings> _persistence;
void updateCamera();
};
} // namespace Camera
+50 -101
View File
@@ -1,109 +1,58 @@
#pragma once
#include <template/state_result.h>
#include <platform_shared/api.pb.h>
#include <esp_camera.h>
namespace Camera {
#include <ArduinoJson.h>
#include <template/state_result.h>
#include <esp_camera.h>
// Use proto type directly as settings type
using CameraSettings = api_CameraSettings;
class CameraSettings {
public:
pixformat_t pixformat;
framesize_t framesize; // 0 - 10
uint8_t quality; // 0 - 63
int8_t brightness; //-2 - 2
int8_t contrast; //-2 - 2
int8_t saturation; //-2 - 2
int8_t sharpness; //-2 - 2
uint8_t denoise;
gainceiling_t gainceiling;
uint8_t whitebal;
uint8_t special_effect; // 0 - 6
uint8_t wb_mode; // 0 - 4
uint8_t awb;
uint8_t exposure_ctrl;
uint8_t awb_gain;
uint8_t gain_ctrl;
uint8_t aec;
uint8_t aec2;
int8_t ae_level; //-2 - 2
uint16_t aec_value; // 0 - 1200
uint8_t agc;
uint8_t agc_gain; // 0 - 30
uint8_t bpc;
uint8_t wpc;
uint8_t raw_gma;
uint8_t lenc;
uint8_t hmirror;
uint8_t vflip;
uint8_t dcw;
uint8_t colorbar;
// Default factory settings
inline CameraSettings CameraSettings_defaults() {
CameraSettings settings = api_CameraSettings_init_zero;
settings.pixformat = PIXFORMAT_JPEG;
settings.framesize = FRAMESIZE_VGA;
settings.quality = 12;
settings.brightness = 0;
settings.contrast = 0;
settings.saturation = 0;
settings.sharpness = 0;
settings.denoise = 0;
settings.gainceiling = GAINCEILING_2X;
settings.whitebal = 1;
settings.special_effect = 0;
settings.wb_mode = 0;
settings.awb = 1;
settings.exposure_ctrl = 1;
settings.awb_gain = 1;
settings.gain_ctrl = 1;
settings.aec = 1;
settings.aec2 = 0;
settings.ae_level = 0;
settings.aec_value = 300;
settings.agc = 1;
settings.agc_gain = 0;
settings.bpc = 0;
settings.wpc = 1;
settings.raw_gma = 1;
settings.lenc = 1;
settings.hmirror = 0;
settings.vflip = 0;
settings.dcw = 1;
settings.colorbar = 0;
return settings;
}
static void read(CameraSettings &settings, JsonVariant &root) {
root["pixformat"] = settings.pixformat;
root["framesize"] = settings.framesize;
root["quality"] = settings.quality;
root["brightness"] = settings.brightness;
root["contrast"] = settings.contrast;
root["saturation"] = settings.saturation;
root["sharpness"] = settings.sharpness;
root["denoise"] = settings.denoise;
root["special_effect"] = settings.special_effect;
root["wb_mode"] = settings.wb_mode;
root["exposure_ctrl"] = settings.exposure_ctrl;
root["gain_ctrl"] = settings.gain_ctrl;
root["awb"] = settings.awb;
root["awb_gain"] = settings.awb_gain;
root["aec"] = settings.aec;
root["aec2"] = settings.aec2;
root["ae_level"] = settings.ae_level;
root["aec_value"] = settings.aec_value;
root["agc"] = settings.agc;
root["agc_gain"] = settings.agc_gain;
root["gainceiling"] = settings.gainceiling;
root["bpc"] = settings.bpc;
root["wpc"] = settings.wpc;
root["raw_gma"] = settings.raw_gma;
root["lenc"] = settings.lenc;
root["hmirror"] = settings.hmirror;
root["vflip"] = settings.vflip;
root["dcw"] = settings.dcw;
root["colorbar"] = settings.colorbar;
}
// Proto read/update are identity functions since type is the same
inline void CameraSettings_read(const CameraSettings& settings, CameraSettings& proto) {
proto = settings;
}
static StateUpdateResult update(JsonVariant &root, CameraSettings &settings) {
settings.pixformat = root["pixformat"];
settings.framesize = root["framesize"];
settings.brightness = root["brightness"];
settings.contrast = root["contrast"];
settings.quality = root["quality"];
settings.contrast = root["contrast"];
settings.saturation = root["saturation"];
settings.sharpness = root["sharpness"];
settings.denoise = root["denoise"];
settings.exposure_ctrl = root["exposure_ctrl"];
settings.gain_ctrl = root["gain_ctrl"];
settings.special_effect = root["special_effect"];
settings.wb_mode = root["wb_mode"];
settings.awb = root["awb"];
settings.awb_gain = root["awb_gain"];
settings.aec = root["aec"];
settings.aec2 = root["aec2"];
settings.ae_level = root["ae_level"];
settings.aec_value = root["aec_value"];
settings.agc = root["agc"];
settings.agc_gain = root["agc_gain"];
settings.gainceiling = root["gainceiling"];
settings.bpc = root["bpc"];
settings.wpc = root["wpc"];
settings.raw_gma = root["raw_gma"];
settings.lenc = root["lenc"];
settings.hmirror = root["hmirror"];
settings.vflip = root["vflip"];
settings.dcw = root["dcw"];
settings.colorbar = root["colorbar"];
inline StateUpdateResult CameraSettings_update(const CameraSettings& proto, CameraSettings& settings) {
settings = proto;
return StateUpdateResult::CHANGED;
}
return StateUpdateResult::CHANGED;
};
};
} // namespace Camera
} // namespace Camera
+3 -4
View File
@@ -49,14 +49,13 @@ void setupServer() {
server.onProto("/api/system/sleep", HTTP_POST,
[&](httpd_req_t *request, api_Request *protoReq) { return system_service::handleSleep(request); });
#if USE_CAMERA
// TODO: REMAKE TO PROTO
server.on("/api/camera/still", HTTP_GET, [&](httpd_req_t *request) { return cameraService.cameraStill(request); });
server.on("/api/camera/stream", HTTP_GET,
[&](httpd_req_t *request) { return cameraService.cameraStream(request); });
server.on("/api/camera/settings", HTTP_GET,
[&](httpd_req_t *request) { return cameraService.endpoint.getState(request); });
server.on("/api/camera/settings", HTTP_POST, [&](httpd_req_t *request, JsonVariant &json) {
return cameraService.endpoint.handleStateUpdate(request, json);
[&](httpd_req_t *request) { return cameraService.protoEndpoint.getState(request); });
server.onProto("/api/camera/settings", HTTP_POST, [&](httpd_req_t *request, api_Request *protoReq) {
return cameraService.protoEndpoint.handleStateUpdate(request, protoReq);
});
#endif
server.on("/api/servo/config", HTTP_GET,
+9 -5
View File
@@ -31,8 +31,12 @@ sensor_t *safe_sensor_get() {
void safe_sensor_return() { xSemaphoreGiveRecursive(cameraMutex); }
CameraService::CameraService()
: endpoint(CameraSettings::read, CameraSettings::update, this),
_persistence(CameraSettings::read, CameraSettings::update, this, CAMERA_SETTINGS_FILE) {
: protoEndpoint(CameraSettings_read, CameraSettings_update, this,
API_REQUEST_EXTRACTOR(camera_settings, api_CameraSettings),
API_RESPONSE_ASSIGNER(camera_settings, api_CameraSettings)),
_persistence(CameraSettings_read, CameraSettings_update, this,
CAMERA_SETTINGS_FILE, api_CameraSettings_fields, api_CameraSettings_size,
CameraSettings_defaults()) {
addUpdateHandler([&](const std::string &originId) { updateCamera(); }, false);
}
@@ -149,14 +153,14 @@ void CameraService::updateCamera() {
safe_sensor_return();
return;
}
s->set_pixformat(s, state().pixformat);
s->set_framesize(s, state().framesize);
s->set_pixformat(s, static_cast<pixformat_t>(state().pixformat));
s->set_framesize(s, static_cast<framesize_t>(state().framesize));
s->set_brightness(s, state().brightness);
s->set_contrast(s, state().contrast);
s->set_saturation(s, state().saturation);
s->set_sharpness(s, state().sharpness);
s->set_denoise(s, state().denoise);
s->set_gainceiling(s, state().gainceiling);
s->set_gainceiling(s, static_cast<gainceiling_t>(state().gainceiling));
s->set_quality(s, state().quality);
s->set_colorbar(s, state().colorbar);
s->set_awb_gain(s, state().awb_gain);