mirror of
				https://github.com/esphome/esphome.git
				synced 2025-11-04 00:51:49 +00:00 
			
		
		
		
	feat: esp32-camera add stream event (#3285)
This commit is contained in:
		@@ -1,5 +1,6 @@
 | 
			
		||||
import esphome.codegen as cg
 | 
			
		||||
import esphome.config_validation as cv
 | 
			
		||||
from esphome import automation
 | 
			
		||||
from esphome import pins
 | 
			
		||||
from esphome.const import (
 | 
			
		||||
    CONF_FREQUENCY,
 | 
			
		||||
@@ -12,6 +13,7 @@ from esphome.const import (
 | 
			
		||||
    CONF_RESOLUTION,
 | 
			
		||||
    CONF_BRIGHTNESS,
 | 
			
		||||
    CONF_CONTRAST,
 | 
			
		||||
    CONF_TRIGGER_ID,
 | 
			
		||||
)
 | 
			
		||||
from esphome.core import CORE
 | 
			
		||||
from esphome.components.esp32 import add_idf_sdkconfig_option
 | 
			
		||||
@@ -23,7 +25,14 @@ AUTO_LOAD = ["psram"]
 | 
			
		||||
 | 
			
		||||
esp32_camera_ns = cg.esphome_ns.namespace("esp32_camera")
 | 
			
		||||
ESP32Camera = esp32_camera_ns.class_("ESP32Camera", cg.PollingComponent, cg.EntityBase)
 | 
			
		||||
 | 
			
		||||
ESP32CameraStreamStartTrigger = esp32_camera_ns.class_(
 | 
			
		||||
    "ESP32CameraStreamStartTrigger",
 | 
			
		||||
    automation.Trigger.template(),
 | 
			
		||||
)
 | 
			
		||||
ESP32CameraStreamStopTrigger = esp32_camera_ns.class_(
 | 
			
		||||
    "ESP32CameraStreamStopTrigger",
 | 
			
		||||
    automation.Trigger.template(),
 | 
			
		||||
)
 | 
			
		||||
ESP32CameraFrameSize = esp32_camera_ns.enum("ESP32CameraFrameSize")
 | 
			
		||||
FRAME_SIZES = {
 | 
			
		||||
    "160X120": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_160X120,
 | 
			
		||||
@@ -111,6 +120,10 @@ CONF_TEST_PATTERN = "test_pattern"
 | 
			
		||||
CONF_MAX_FRAMERATE = "max_framerate"
 | 
			
		||||
CONF_IDLE_FRAMERATE = "idle_framerate"
 | 
			
		||||
 | 
			
		||||
# stream trigger
 | 
			
		||||
CONF_ON_STREAM_START = "on_stream_start"
 | 
			
		||||
CONF_ON_STREAM_STOP = "on_stream_stop"
 | 
			
		||||
 | 
			
		||||
camera_range_param = cv.int_range(min=-2, max=2)
 | 
			
		||||
 | 
			
		||||
CONFIG_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(
 | 
			
		||||
@@ -178,6 +191,20 @@ CONFIG_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(
 | 
			
		||||
        cv.Optional(CONF_IDLE_FRAMERATE, default="0.1 fps"): cv.All(
 | 
			
		||||
            cv.framerate, cv.Range(min=0, max=1)
 | 
			
		||||
        ),
 | 
			
		||||
        cv.Optional(CONF_ON_STREAM_START): automation.validate_automation(
 | 
			
		||||
            {
 | 
			
		||||
                cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
 | 
			
		||||
                    ESP32CameraStreamStartTrigger
 | 
			
		||||
                ),
 | 
			
		||||
            }
 | 
			
		||||
        ),
 | 
			
		||||
        cv.Optional(CONF_ON_STREAM_STOP): automation.validate_automation(
 | 
			
		||||
            {
 | 
			
		||||
                cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
 | 
			
		||||
                    ESP32CameraStreamStopTrigger
 | 
			
		||||
                ),
 | 
			
		||||
            }
 | 
			
		||||
        ),
 | 
			
		||||
    }
 | 
			
		||||
).extend(cv.COMPONENT_SCHEMA)
 | 
			
		||||
 | 
			
		||||
@@ -238,3 +265,11 @@ async def to_code(config):
 | 
			
		||||
    if CORE.using_esp_idf:
 | 
			
		||||
        cg.add_library("espressif/esp32-camera", "1.0.0")
 | 
			
		||||
        add_idf_sdkconfig_option("CONFIG_RTCIO_SUPPORT_RTC_GPIO_DESC", True)
 | 
			
		||||
 | 
			
		||||
    for conf in config.get(CONF_ON_STREAM_START, []):
 | 
			
		||||
        trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
 | 
			
		||||
        await automation.build_automation(trigger, [], conf)
 | 
			
		||||
 | 
			
		||||
    for conf in config.get(CONF_ON_STREAM_STOP, []):
 | 
			
		||||
        trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
 | 
			
		||||
        await automation.build_automation(trigger, [], conf)
 | 
			
		||||
 
 | 
			
		||||
@@ -282,8 +282,20 @@ void ESP32Camera::set_idle_update_interval(uint32_t idle_update_interval) {
 | 
			
		||||
void ESP32Camera::add_image_callback(std::function<void(std::shared_ptr<CameraImage>)> &&f) {
 | 
			
		||||
  this->new_image_callback_.add(std::move(f));
 | 
			
		||||
}
 | 
			
		||||
void ESP32Camera::start_stream(CameraRequester requester) { this->stream_requesters_ |= (1U << requester); }
 | 
			
		||||
void ESP32Camera::stop_stream(CameraRequester requester) { this->stream_requesters_ &= ~(1U << requester); }
 | 
			
		||||
void ESP32Camera::add_stream_start_callback(std::function<void()> &&callback) {
 | 
			
		||||
  this->stream_start_callback_.add(std::move(callback));
 | 
			
		||||
}
 | 
			
		||||
void ESP32Camera::add_stream_stop_callback(std::function<void()> &&callback) {
 | 
			
		||||
  this->stream_stop_callback_.add(std::move(callback));
 | 
			
		||||
}
 | 
			
		||||
void ESP32Camera::start_stream(CameraRequester requester) {
 | 
			
		||||
  this->stream_start_callback_.call();
 | 
			
		||||
  this->stream_requesters_ |= (1U << requester);
 | 
			
		||||
}
 | 
			
		||||
void ESP32Camera::stop_stream(CameraRequester requester) {
 | 
			
		||||
  this->stream_stop_callback_.call();
 | 
			
		||||
  this->stream_requesters_ &= ~(1U << requester);
 | 
			
		||||
}
 | 
			
		||||
void ESP32Camera::request_image(CameraRequester requester) { this->single_requesters_ |= (1U << requester); }
 | 
			
		||||
void ESP32Camera::update_camera_parameters() {
 | 
			
		||||
  sensor_t *s = esp_camera_sensor_get();
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@
 | 
			
		||||
 | 
			
		||||
#ifdef USE_ESP32
 | 
			
		||||
 | 
			
		||||
#include "esphome/core/automation.h"
 | 
			
		||||
#include "esphome/core/component.h"
 | 
			
		||||
#include "esphome/core/entity_base.h"
 | 
			
		||||
#include "esphome/core/helpers.h"
 | 
			
		||||
@@ -145,6 +146,9 @@ class ESP32Camera : public Component, public EntityBase {
 | 
			
		||||
  void request_image(CameraRequester requester);
 | 
			
		||||
  void update_camera_parameters();
 | 
			
		||||
 | 
			
		||||
  void add_stream_start_callback(std::function<void()> &&callback);
 | 
			
		||||
  void add_stream_stop_callback(std::function<void()> &&callback);
 | 
			
		||||
 | 
			
		||||
 protected:
 | 
			
		||||
  /* internal methods */
 | 
			
		||||
  uint32_t hash_base() override;
 | 
			
		||||
@@ -187,6 +191,8 @@ class ESP32Camera : public Component, public EntityBase {
 | 
			
		||||
  QueueHandle_t framebuffer_get_queue_;
 | 
			
		||||
  QueueHandle_t framebuffer_return_queue_;
 | 
			
		||||
  CallbackManager<void(std::shared_ptr<CameraImage>)> new_image_callback_;
 | 
			
		||||
  CallbackManager<void()> stream_start_callback_{};
 | 
			
		||||
  CallbackManager<void()> stream_stop_callback_{};
 | 
			
		||||
 | 
			
		||||
  uint32_t last_idle_request_{0};
 | 
			
		||||
  uint32_t last_update_{0};
 | 
			
		||||
@@ -195,6 +201,23 @@ class ESP32Camera : public Component, public EntityBase {
 | 
			
		||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
 | 
			
		||||
extern ESP32Camera *global_esp32_camera;
 | 
			
		||||
 | 
			
		||||
class ESP32CameraStreamStartTrigger : public Trigger<> {
 | 
			
		||||
 public:
 | 
			
		||||
  explicit ESP32CameraStreamStartTrigger(ESP32Camera *parent) {
 | 
			
		||||
    parent->add_stream_start_callback([this]() { this->trigger(); });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 protected:
 | 
			
		||||
};
 | 
			
		||||
class ESP32CameraStreamStopTrigger : public Trigger<> {
 | 
			
		||||
 public:
 | 
			
		||||
  explicit ESP32CameraStreamStopTrigger(ESP32Camera *parent) {
 | 
			
		||||
    parent->add_stream_stop_callback([this]() { this->trigger(); });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 protected:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}  // namespace esp32_camera
 | 
			
		||||
}  // namespace esphome
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user