Change Parameter - ESP32-Cam - Flash and HA

Hi,

I searched a lot, but found nothing, or I am not able to put the pieces together.

I want to change this parameters by HA and set them persistant.

Is this possible?

Regards

>   vertical_flip: true
>   horizontal_mirror: false
>   resolution: 800X600 # 400x296
>   max_framerate: 12 fps

from this declaration

esp32_camera:
  name: "${devicename} Kamera"
  id: "${devicename_id}_kamera"
  external_clock:
    pin: GPIO0
    frequency: 20MHz
  i2c_pins:
    sda: GPIO26
    scl: GPIO27
  data_pins: [GPIO5, GPIO18, GPIO19, GPIO21, GPIO36, GPIO39, GPIO34, GPIO35]
  vsync_pin: GPIO25
  href_pin: GPIO23
  pixel_clock_pin: GPIO22
  power_down_pin: GPIO32
  vertical_flip: true
  horizontal_mirror: false
  resolution: 800X600 # 400x296
  max_framerate: 12 fps

Not sure to get what you ask, sorry.
You did a configuration in ESPHome, specifying

But you’d like to be able to change those 4 parameters from HA?

YEs i want to change them by a lovalace card switch entity.

I don’t think you can change any of the the parameters you presented at runtime. This configurations are “burned in” to the firmware when compiled.

This is also my feeling. I can’t see a way to do it.

I don’t think you can change any of the the parameters you presented at runtime. This configurations are “burned in” to the firmware when compiled.

Nope :slight_smile: There is an API, for which you can create your device local API and UI configuration. Will write a write-up later. Credit to the API goes to someone else who I forgot, the UI elements are OC by me.

in ESPHome YAML:

api:
  id: ${device_name}_api
  services:  # change camera parameters on-the-fly
  - service: camera_set_param
    variables:
      name: string
      value: int
    then:
      - lambda: |-
          bool state_return = false;
          if (("contrast" == name) && (value >= -2) && (value <= 2)) { id(${device_name}_camera).set_contrast(value); state_return = true; }
          if (("brightness" == name) && (value >= -2) && (value <= 2)) { id(${device_name}_camera).set_brightness(value); state_return = true; }
          if (("saturation" == name) && (value >= -2) && (value <= 2)) { id(${device_name}_camera).set_saturation(value); state_return = true; }
          if (("special_effect" == name) && (value >= 0U) && (value <= 6U)) { id(${device_name}_camera).set_special_effect((esphome::esp32_camera::ESP32SpecialEffect)value); state_return = true; }
          if (("aec_mode" == name) && (value >= 0U) && (value <= 1U)) { id(${device_name}_camera).set_aec_mode((esphome::esp32_camera::ESP32GainControlMode)value); state_return = true; }
          if (("aec2" == name) && (value >= 0U) && (value <= 1U)) { id(${device_name}_camera).set_aec2(value); state_return = true; }
          if (("ae_level" == name) && (value >= -2) && (value <= 2)) { id(${device_name}_camera).set_ae_level(value); state_return = true; }
          if (("aec_value" == name) && (value >= 0U) && (value <= 1200U)) { id(${device_name}_camera).set_aec_value(value); state_return = true; }
          if (("agc_mode" == name) && (value >= 0U) && (value <= 1U)) { id(${device_name}_camera).set_agc_mode((esphome::esp32_camera::ESP32GainControlMode)value); state_return = true; }
          if (("agc_value" == name) && (value >= 0U) && (value <= 30U)) { id(${device_name}_camera).set_agc_value(value); state_return = true; }
          if (("agc_gain_ceiling" == name) && (value >= 0U) && (value <= 6U)) { id(${device_name}_camera).set_agc_gain_ceiling((esphome::esp32_camera::ESP32AgcGainCeiling)value); state_return = true; }
          if (("wb_mode" == name) && (value >= 0U) && (value <= 4U)) { id(${device_name}_camera).set_wb_mode((esphome::esp32_camera::ESP32WhiteBalanceMode)value); state_return = true; }
          if (("test_pattern" == name) && (value >= 0U) && (value <= 1U)) { id(${device_name}_camera).set_test_pattern(value); state_return = true; }
          if (true == state_return) {
            id(${device_name}_camera).update_camera_parameters();
            ESP_LOGI("esp32_camera", "parameter %s:%d", name.c_str(), (int)value);
          }
          else {
            ESP_LOGW("esp32_camera", "parameter error in name or data range");
          }

then in Home Assistant Service call:

service: esphome.camera_set_param
data:
  name: contrast
  value: 2

3 Likes

Apologies for my inexperience here but what sort of construct is this control dashboard? Is this a series of cards that have the service calls behind them (if so, what sort of card allows parameters to be entered and passed in the service call?), is it an automation script? Something else? Just point me in the right direction…

I think you got this code from:
https://jamesachambers.com/cheap-esp32-cam-home-assistant-esphome-camera-guide/

But he does not posted the HA card construction.
I’d also like this. My camera does not show all of this API configuration on its entity card.

EDIT:
Managed to do that. The options apears directly on entity’s page and they can be used on any card. I still need to implement other options, but you can get the idea. just put this on esphome YAML:

##################################################
globals:
  - id: brightness_atual
    type: int
    restore_value: yes
    initial_value: "0"
  - id: contraste_atual
    type: int
    initial_value: "0"
    restore_value: yes
  - id: saturacao_atual
    type: int
    initial_value: "0"
    restore_value: yes
  - id: vflip
    type: bool
    restore_value: yes
    initial_value: "true"
  - id: hmirror
    type: bool
    restore_value: yes
    initial_value: "false"
  - id: resolucao_atual
    type: int
    restore_value: yes
    initial_value: '4'

##################################################
esphome:
  on_boot:
    - priority: 600
      then:
        - lambda: |-
            using FrameSize_t = esphome::esp32_camera::ESP32CameraFrameSize;

            id(espcam).set_vertical_flip(id(vflip));
            id(espcam).set_horizontal_mirror(id(hmirror));
            delay(50); 

            id(espcam).set_brightness(id(brightness_atual));
            id(espcam).set_contrast(id(contraste_atual));
            id(espcam).set_saturation(id(saturacao_atual));
            id(espcam).set_frame_size((FrameSize_t) id(resolucao_atual));

          

##################################################
esp32_camera:
  id: espcam
  name: ${friendly_name}

  external_clock:
    pin: GPIO0
    frequency: 10MHz
  i2c_pins:
    sda: GPIO26
    scl: GPIO27
  data_pins: [GPIO5, GPIO18, GPIO19, GPIO21, GPIO36, GPIO39, GPIO34, GPIO35]

  # the order of the data_pins is significant, don't mix up the order
  vsync_pin: GPIO25
  href_pin: GPIO23
  pixel_clock_pin: GPIO22
  power_down_pin: GPIO32


  ## Image Config
  resolution: "1024x768"
  max_framerate: 30fps
  idle_framerate: 0.2fps
  jpeg_quality: 10

  brightness: 2
  contrast: 1
  saturation: 0
  special_effect: none
  # exposure settings
  aec_mode: auto
  aec2: false
  ae_level: 0
  aec_value: 300
  # gain settings
  agc_mode: auto
  agc_gain_ceiling: 2x
  agc_value: 0
  # white balance setting
  wb_mode: auto

  vertical_flip: true
  horizontal_mirror: false


output:
  - platform: ledc
    pin: GPIO4
    channel: 2      # channel 1 is used for esp32_camera
    id: led
  # red status light
  - platform: gpio
    pin:
      number: GPIO33
      inverted: True
    id: gpio_33

light:
  - platform: monochromatic
    output: led
    name: Luz
  - platform: binary
    output: gpio_33
    name: OnBoard Led

binary_sensor:
  - platform: status
    name: Status


##################################################
esp32_camera_web_server:
  - port: 8080
    mode: stream
  - port: 8081
    mode: snapshot
##################################################
# AJUSTES DA CÂMERA
#          if (("aec_mode" == name) && (value >= 0U) && (value <= 1U)) { id(espcam).set_aec_mode((esphome::esp32_camera::ESP32GainControlMode)value); state_return = true; }
#          if (("aec2" == name) && (value >= 0U) && (value <= 1U)) { id(espcam).set_aec2(value); state_return = true; }
#          if (("ae_level" == name) && (value >= -2) && (value <= 2)) { id(espcam).set_ae_level(value); state_return = true; }
#          if (("aec_value" == name) && (value >= 0U) && (value <= 1200U)) { id(espcam).set_aec_value(value); state_return = true; }
#          if (("agc_mode" == name) && (value >= 0U) && (value <= 1U)) { id(espcam).set_agc_mode((esphome::esp32_camera::ESP32GainControlMode)value); state_return = true; }
#          if (("agc_value" == name) && (value >= 0U) && (value <= 30U)) { id(espcam).set_agc_value(value); state_return = true; }
#          if (("agc_gain_ceiling" == name) && (value >= 0U) && (value <= 6U)) { id(espcam).set_agc_gain_ceiling((esphome::esp32_camera::ESP32AgcGainCeiling)value); state_return = true; }
#          if (("test_pattern" == name) && (value >= 0U) && (value <= 1U)) { id(espcam).set_test_pattern(value); state_return = true; }

number:
  - platform: template
    entity_category: config
    name: "Brightness"
    id: brightness
    optimistic: true
    min_value: -2.0 
    max_value: 2.0 
    step: 1.0
    set_action:
      lambda: |-
        id(espcam).set_brightness(x);
        id(brightness_atual) = x;
        id(espcam).update_camera_parameters();
  - platform: template
    entity_category: config
    name: "Contrast"
    id: contrast
    optimistic: true
    min_value: -2.0 
    max_value: 2.0  
    step: 1.0
    set_action:
      lambda: |-
        id(espcam).set_contrast(x);
        id(contraste_atual) = x;
        id(espcam).update_camera_parameters();

  - platform: template
    entity_category: config
    name: "Saturation"
    id: saturation
    optimistic: true
    min_value: -2.0 
    max_value: 2.0  
    step: 1.0
    set_action:
      lambda: |-
        id(espcam).set_saturation(x);
        id(saturacao_atual) = x;
        id(espcam).update_camera_parameters();


  - platform: template
    name: "JPEG Quality (10=high)"
    id: jpeg_quality
    icon: mdi:quality-high
    entity_category: config
    
    # Range da Qualidade (de 10 a 63) 10 = Máx)
    min_value: 10.0
    max_value: 63.0
    step: 1.0 # Passos de 1 em 1
    
    set_action:
      lambda: |-
        id(espcam).set_jpeg_quality(id(jpeg_quality).state);
        id(espcam).update_camera_parameters();

select:
  - platform: template
    entity_category: config
    name: "White Balance"
    id: white_balance
    optimistic: true
    options:
      - "Auto"
      - "Sunny"
      - "Cloudy"
      - "Office"
      - "Home"
      
    set_action:
      - lambda: |-
          using namespace esphome::esp32_camera;

          if (x == "Auto") {
            id(espcam).set_wb_mode(ESP32_WB_MODE_AUTO);
          } else if (x == "Sunny") {
            id(espcam).set_wb_mode(ESP32_WB_MODE_SUNNY);
          } else if (x == "Cloudy") {
            id(espcam).set_wb_mode(ESP32_WB_MODE_CLOUDY);
          } else if (x == "Office") {
            id(espcam).set_wb_mode(ESP32_WB_MODE_OFFICE);
          } else if (x == "Home") {
            id(espcam).set_wb_mode(ESP32_WB_MODE_HOME);
          }

          id(espcam).update_camera_parameters();

  - platform: template 
    name: "Special Effect"
    id: special_effect
    entity_category: config
    icon: mdi:palette-swatch
    optimistic: true
    options:
      - Negative
      - grayscale
      - red_tint
      - green_tint
      - blue_tint
      - sepia
      - None

    # 3. Código Lambda para Ação
    set_action:
      lambda: |-
        using namespace esphome::esp32_camera;

        if (x == "None") {
          id(espcam).set_special_effect(ESP32_SPECIAL_EFFECT_NONE);
        } else if (x == "Negative") {
          id(espcam).set_special_effect(ESP32_SPECIAL_EFFECT_NEGATIVE);
        } else if (x == "grayscale") {
          id(espcam).set_special_effect(ESP32_SPECIAL_EFFECT_GRAYSCALE);
        } else if (x == "red_tint") {
          id(espcam).set_special_effect(ESP32_SPECIAL_EFFECT_RED_TINT);
        } else if (x == "green_tint") {
          id(espcam).set_special_effect(ESP32_SPECIAL_EFFECT_GREEN_TINT);
        } else if (x == "blue_tint") {
          id(espcam).set_special_effect(ESP32_SPECIAL_EFFECT_BLUE_TINT);
        } else if (x == "sepia") {
          id(espcam).set_special_effect(ESP32_SPECIAL_EFFECT_SEPIA);
        }
        
        id(espcam).update_camera_parameters(); 

  - platform: template
    name: "Resolution"
    id: cam_resolution
    icon: mdi:aspect-ratio
    entity_category: config
    optimistic: true
    options:
      - 1024x768
      - 800x600 # SVGA
      - 640x480 # VGA (Comum para a maioria)
      - 320x240 # QVGA (Boa para streaming rápido)
      # Adicione outras resoluções suportadas pelo seu modelo (ex: 1024x768, 1600x1200, 1280x1024)

    set_action:
      lambda: |-
        using FrameSize_t = esphome::esp32_camera::ESP32CameraFrameSize;
        int resolucao = 4;

        if (x == "1024x768") {
          resolucao = 6;
          
        } else if (x == "800x600") {
          resolucao = 5;
        } else if (x == "640x480") {
          resolucao = 4;
        } else if (x == "320x240") {
          resolucao = 3;
        } else {
          // Fallback para 640x480 (VGA) se a opção for inválida
          resolucao = 4;
        }

        id(espcam).set_frame_size((FrameSize_t) resolucao);
        id(resolucao_atual) = resolucao;
        id(espcam).update_camera_parameters(); 


switch:
  - platform: restart
    name: "Reiniciar"

  - platform: template
    name: "Vertical Flip"
    id: v_flip
    icon: mdi:flip-vertical
    entity_category: config
    optimistic: true

    turn_on_action:
      lambda: |-
        id(espcam).set_vertical_flip(true);
        id(vflip) = true;
        delay(50); 
        
    turn_off_action:
      lambda: |-
        id(espcam).set_vertical_flip(false);
        id(vflip) = false;
        delay(50);

  - platform: template
    name: "Horizontal Mirror"
    id: h_mirror
    icon: mdi:flip-horizontal
    entity_category: config
    optimistic: true

    turn_on_action:
      - lambda: |-
          id(espcam).set_horizontal_mirror(true);
          id(hmirror) = true;
          delay(50); 
    turn_off_action:
      - lambda: |-
          id(espcam).set_horizontal_mirror(false);
          id(hmirror) = false;
          delay(50); 

Last Update: updated YAML code with full control.
Still cant call update_parameters with set vflip or hmirror.

1 Like

Hi!, I am trying to get the configuration o the entity page, when you say put this on esphome YAML, do you mean the camera YAML?

Thanks!

Sorry about the delay.
Yes. It’s the camera esphome YAML.
I’ll update with my full code.
I just can´t get to work the change hmirror and vflip, properly, the camera gets stuck on startup. But it’s managable by changing the option and change another after that, like brightness.

1 Like

Alex, thanks a lot for taking the time to answer and loading you full config, It helped me a lot to adapt mine. and is working now!!

I’ll try to implement the other properties and load mi YAML.

1 Like

once again thanks Alex.
I’ve managed to take in all the parameter, and might take a while to try them all.,so far I’m having the same issue as you with v_flip not working and h_mirror only working when updated by other entity (which has id(espcam).update_camera_parameters(); )

looks like this:

long story short, here’s the full code:

##################################################
globals:
  - id: brightness_actual
    type: int
    restore_value: yes
    initial_value: "0"
  - id: contrast_actual
    type: int
    initial_value: "0"
    restore_value: yes
  - id: saturation_actual
    type: int
    initial_value: "0"
    restore_value: yes
  - id: vflip
    type: bool
    restore_value: yes
    initial_value: "true"
  - id: hmirror
    type: bool
    restore_value: yes
    initial_value: "false"
  - id: resolution_actual
    type: int
    restore_value: yes
    initial_value: '4'

##################################################
substitutions:
  name: "tiny-cam"
  friendly_name: "Tiny-Cam"

esphome:
  name: "tiny-cam"
  friendly_name: Tiny-Cam
  min_version: 2025.9.0
  name_add_mac_suffix: false
  on_boot:
    - priority: 600
      then:
        - lambda: |-
            using FrameSize_t = esphome::esp32_camera::ESP32CameraFrameSize;

            id(espcam).set_vertical_flip(id(vflip));
            id(espcam).set_horizontal_mirror(id(hmirror));
            delay(50); 

            id(espcam).set_brightness(id(brightness_actual));
            id(espcam).set_contrast(id(contrast_actual));
            id(espcam).set_saturation(id(saturation_actual));
            id(espcam).set_frame_size((FrameSize_t) id(resolution_actual));
esp32:
  variant: esp32
  framework:
    type: esp-idf

# Enable logging
logger:
  level: VERBOSE
  tx_buffer_size: 256
  
# Enable Home Assistant API
api:
  encryption:
    key: "XXXXXXXXXXX your code XXXXXXXXXXX"

# Allow Over-The-Air updates
ota:
- platform: esphome

wifi:
  networks:
  - ssid: !secret wifi_ssid
    password: !secret wifi_password
  - ssid: !secret wifi_ssid2
    password: !secret wifi_password2

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "$friendly_name Fallback Hotspot"
    password: "hfjgkhfgajhgdf"

esp32_camera:
  name: $friendly_name
  id: espcam
  external_clock:
    pin: GPIO0
    frequency: 10MHz
  i2c_pins:
    sda: GPIO26
    scl: GPIO27
  data_pins: [GPIO5, GPIO18, GPIO19, GPIO21, GPIO36, GPIO39, GPIO34, GPIO35]
  vsync_pin: GPIO25
  href_pin: GPIO23
  pixel_clock_pin: GPIO22
  power_down_pin: GPIO32
  
# Image/Video settings, https://esphome.io/components/esp32_camera.html

  max_framerate: 30 fps    # default: 10 fps, max 60
  idle_framerate: 0.2 fps # default: 0.1 fps - framerate for 'picture' in HA dashboard
  resolution: 1280x1024
  jpeg_quality: 10
  vertical_flip: true
  horizontal_mirror: True
  contrast: 0 # default: 0, variable -2 to 2
  brightness: 2 # default: 0, variable -2 to 2
  saturation: 0 # default: 0, variable -2 to 2
 # exposure settings
  aec_mode: AUTO
  aec2: True
  ae_level: 0
  aec_value: 300
  # gain settings
  agc_mode: AUTO
  agc_gain_ceiling: 2X
  agc_value: 8
  # white balance setting
  wb_mode: auto
  
# Server video/pictures, https://esphome.io/components/esp32_camera_web_server.html

esp32_camera_web_server:
  - port: 8080
    mode: stream
  - port: 8081
    mode: snapshot

time:
  - platform: homeassistant
    id: homeassistant_time

output:
#flashlight
  - platform: ledc
    channel: 2
    pin: GPIO4
    id: gpio_4
#statuslight led 33 for wifi connect
  - platform: gpio
    pin:
      number: GPIO33
      inverted: True
    id: gpio_33

light:
#flashlight
  - platform: monochromatic
    output: gpio_4
    name: $friendly_name light
#statuslight led 33 for wifi connect
  - platform: binary
    output: gpio_33
    name: $friendly_name wifi light state

sensor:
  - platform: wifi_signal
    name: $friendly_name Wifi signal
    update_interval: 10s
  - platform: uptime
    name: $friendly_name Uptime

text_sensor:
  - platform: version
    name: $friendly_name ESPHome Version
  - platform: wifi_info
    ssid:
      name: $friendly_name WiFi

# Camera Settings
#          if (("aec_mode" == name) && (value >= 0U) && (value <= 1U)) { id(espcam).set_aec_mode((esphome::esp32_camera::ESP32GainControlMode)value); state_return = true; }
#          if (("aec2" == name) && (value >= 0U) && (value <= 1U)) { id(espcam).set_aec2(value); state_return = true; }
#          if (("ae_level" == name) && (value >= -2) && (value <= 2)) { id(espcam).set_ae_level(value); state_return = true; }
#          if (("aec_value" == name) && (value >= 0U) && (value <= 1200U)) { id(espcam).set_aec_value(value); state_return = true; }
#          if (("agc_mode" == name) && (value >= 0U) && (value <= 1U)) { id(espcam).set_agc_mode((esphome::esp32_camera::ESP32GainControlMode)value); state_return = true; }
#          if (("agc_value" == name) && (value >= 0U) && (value <= 30U)) { id(espcam).set_agc_value(value); state_return = true; }
#          if (("agc_gain_ceiling" == name) && (value >= 0U) && (value <= 6U)) { id(espcam).set_agc_gain_ceiling((esphome::esp32_camera::ESP32AgcGainCeiling)value); state_return = true; }
#          if (("test_pattern" == name) && (value >= 0U) && (value <= 1U)) { id(espcam).set_test_pattern(value); state_return = true; }

number:
  - platform: template
    entity_category: config
    name: "5.Brightness"
    id: brightness
    optimistic: true
    min_value: -2.0 
    max_value: 2.0 
    step: 1.0
    set_action:
      lambda: |-
        id(espcam).set_brightness(x);
        id(brightness_actual) = x;
        id(espcam).update_camera_parameters();
  - platform: template
    entity_category: config
    name: "6.Contrast"
    id: contrast
    optimistic: true
    min_value: -2.0 
    max_value: 2.0  
    step: 1.0
    set_action:
      lambda: |-
        id(espcam).set_contrast(x);
        id(contrast_actual) = x;
        id(espcam).update_camera_parameters();

  - platform: template
    entity_category: config
    name: "7.Saturation"
    id: saturation
    optimistic: true
    min_value: -2.0 
    max_value: 2.0  
    step: 1.0
    set_action:
      lambda: |-
        id(espcam).set_saturation(x);
        id(saturation_actual) = x;
        id(espcam).update_camera_parameters();

  - platform: template
    name: "2.JPEG Quality (10=high)"
    id: jpeg_quality
    icon: mdi:quality-high
    entity_category: config
    
    # Quality Range(from 10 to 63) 10 = Máx)
    min_value: 10.0
    max_value: 63.0
    step: 1.0 # step 1 on 1
    
    set_action:
      lambda: |-
        id(espcam).set_jpeg_quality(id(jpeg_quality).state);
        id(espcam).update_camera_parameters();
        
  - platform: template
    entity_category: config
    name: "12. ae level" #(when aec_mode is set to auto)
    id: ae_level
    optimistic: true
    min_value: -2.0 
    max_value: 2.0 
    step: 1.0
    set_action:
      lambda: |-
        id(espcam).set_ae_level(x);
        id(espcam).update_camera_parameters();

  - platform: template
    entity_category: config
    name: "13. aec value" #(when aec_mode is set to auto)
    id: ae_value
    optimistic: true
    min_value: 0 
    max_value: 1200
    step: 300.0
    set_action:
      lambda: |-
        id(espcam).set_aec_value(x);
        id(espcam).update_camera_parameters();

  - platform: template
    entity_category: config
    name: "15. agc value"
    id: agc_value
    optimistic: true
    min_value: 0 
    max_value: 30 
    step: 5.0
    set_action:
      lambda: |-
        id(espcam).set_agc_value(x);
        id(espcam).update_camera_parameters();                

select:
  - platform: template
    entity_category: config
    name: "8.White Balance"
    id: white_balance
    optimistic: true
    options:
      - "Auto"
      - "Sunny"
      - "Cloudy"
      - "Office"
      - "Home"
      
    set_action:
      - lambda: |-
          using namespace esphome::esp32_camera;

          if (x == "Auto") {
            id(espcam).set_wb_mode(ESP32_WB_MODE_AUTO);
          } else if (x == "Sunny") {
            id(espcam).set_wb_mode(ESP32_WB_MODE_SUNNY);
          } else if (x == "Cloudy") {
            id(espcam).set_wb_mode(ESP32_WB_MODE_CLOUDY);
          } else if (x == "Office") {
            id(espcam).set_wb_mode(ESP32_WB_MODE_OFFICE);
          } else if (x == "Home") {
            id(espcam).set_wb_mode(ESP32_WB_MODE_HOME);
          }

          id(espcam).update_camera_parameters();

  - platform: template 
    name: "9.Special Effect"
    id: special_effect
    entity_category: config
    icon: mdi:palette-swatch
    optimistic: true
    options:
      - Negative
      - grayscale
      - red_tint
      - green_tint
      - blue_tint
      - sepia
      - None

    # 3. code for lambda action
    set_action:
      lambda: |-
        using namespace esphome::esp32_camera;

        if (x == "None") {
          id(espcam).set_special_effect(ESP32_SPECIAL_EFFECT_NONE);
        } else if (x == "Negative") {
          id(espcam).set_special_effect(ESP32_SPECIAL_EFFECT_NEGATIVE);
        } else if (x == "grayscale") {
          id(espcam).set_special_effect(ESP32_SPECIAL_EFFECT_GRAYSCALE);
        } else if (x == "red_tint") {
          id(espcam).set_special_effect(ESP32_SPECIAL_EFFECT_RED_TINT);
        } else if (x == "green_tint") {
          id(espcam).set_special_effect(ESP32_SPECIAL_EFFECT_GREEN_TINT);
        } else if (x == "blue_tint") {
          id(espcam).set_special_effect(ESP32_SPECIAL_EFFECT_BLUE_TINT);
        } else if (x == "sepia") {
          id(espcam).set_special_effect(ESP32_SPECIAL_EFFECT_SEPIA);
        }
        
        id(espcam).update_camera_parameters(); 

  - platform: template
    name: "1.Resolution"
    id: cam_resolution
    icon: mdi:aspect-ratio
    entity_category: config
    optimistic: true
    options:
      - 1024x768
      - 800x600 # SVGA
      - 640x480 # VGA (common for most)
      - 320x240 # QVGA (good for fast streaming)
      # add other supported resolutions for your model (ex: 1024x768, 1600x1200, 1280x1024)

    set_action:
      lambda: |-
        using FrameSize_t = esphome::esp32_camera::ESP32CameraFrameSize;
        int resolution = 4;

        if (x == "1024x768") {
          resolution = 6;
          
        } else if (x == "800x600") {
          resolution = 5;
        } else if (x == "640x480") {
          resolution = 4;
        } else if (x == "320x240") {
          resolution = 3;
        } else {
          // Fallback para 640x480 (VGA) se a opção for inválida
          resolution = 4;
        }

        id(espcam).set_frame_size((FrameSize_t) resolution);
        id(resolution_actual) = resolution;
        id(espcam).update_camera_parameters(); 

  - platform: template
    entity_category: config
    name: "10. aec mode "
    id: aec_mode
    optimistic: true
    options:
      - Auto #ae_level has no effect here
      - Manual #aec_value has no effect here
      
    set_action:
      - lambda: |-
          using namespace esphome::esp32_camera;

          if (x == "Auto") {
            id(espcam).set_aec_mode(ESP32_GC_MODE_AUTO);
          } else if (x == "Manual") {
            id(espcam).set_aec_mode(ESP32_GC_MODE_MANU);
          }

          id(espcam).update_camera_parameters();

  - platform: template
    entity_category: config
    name: "14. agc mode"
    id: agc_mode
    optimistic: true
    options:
      - Auto # agc_value has no effect here
      - Manual #agc_gain_ceiling has no effect here
      
    set_action:
      - lambda: |-
          using namespace esphome::esp32_camera;

          if (x == "Auto") {
            id(espcam).set_agc_mode(ESP32_GC_MODE_AUTO);
          } else if (x == "Manual") {
            id(espcam).set_agc_mode(ESP32_GC_MODE_MANU);
          }

          id(espcam).update_camera_parameters();

  - platform: template
    name: "16. gain ceiling"
    id: agc_gain_ceiling
    icon: mdi:shuriken
    entity_category: config
    optimistic: true
    options:
      - 2x #: Camera is less sensitive, picture is clean (without visible noise)
      - 4x
      - 8x
      - 16x
      - 32x
      - 64x
      - 128x #: Camera is more sensitive, but picture contain lot of noise
      
    set_action:
      lambda: |-
        using namespace esphome::esp32_camera;

         if (x == "2x") {
          id(espcam).set_agc_gain_ceiling(ESP32_GAINCEILING_2X);
        } else if (x == "4x") {
          id(espcam).set_agc_gain_ceiling(ESP32_GAINCEILING_4X);
        } else if (x == "8x") {
          id(espcam).set_agc_gain_ceiling(ESP32_GAINCEILING_8X);
        } else if (x == "16x") {
          id(espcam).set_agc_gain_ceiling(ESP32_GAINCEILING_16X);
        } else if (x == "32x") {
          id(espcam).set_agc_gain_ceiling(ESP32_GAINCEILING_32X);
        } else if (x == "64x") {
          id(espcam).set_agc_gain_ceiling(ESP32_GAINCEILING_64X);
        } else if (x == "128x") {
          id(espcam).set_agc_gain_ceiling(ESP32_GAINCEILING_128X);
        }
        
        id(espcam).update_camera_parameters(); ; 

switch:
  - platform: restart
    name: "17. $friendly_name restart"

  - platform: template
    name: "3.Vertical Flip"
    id: v_flip
    icon: mdi:flip-vertical
    entity_category: config
    optimistic: true
#Not getting it to work yet
    turn_on_action:
      lambda: |-
        id(espcam).set_vertical_flip(true);
        id(vflip) = true;

    turn_off_action:
      lambda: |-
        id(espcam).set_vertical_flip(true);
        id(vflip) = true;


  - platform: template
    name: "4.Horizontal Mirror"
    id: h_mirror
    icon: mdi:flip-horizontal
    entity_category: config
    optimistic: true
#working_Will update only when other action is called (id(espcam).update_camera_parameters(); ;)
    turn_on_action:
      - lambda: |-
          id(espcam).set_horizontal_mirror(true);
          id(hmirror) = true;

    turn_off_action:
      - lambda: |-
          id(espcam).set_horizontal_mirror(false);
          id(hmirror) = false;

  - platform: template
    name: "11. aec2"
    id: aec2
    icon: mdi:brightness-4
    entity_category: config
    optimistic: true
#Not sure if it works
    turn_on_action:
      lambda: |-
        id(espcam).set_aec2(true);
        
    turn_off_action:
      lambda: |-
        id(espcam).set_aec2(false);
1 Like

I wonder if I regoister a service to change these parameters and call it from HA will solve the problem. I will try it as soon as I can.

1 Like