Add Litter Box Camera configuration for ESP32-S3 with camera and sensor integration
This commit is contained in:
318
esphome/litter-box-cam.yaml
Normal file
318
esphome/litter-box-cam.yaml
Normal file
@@ -0,0 +1,318 @@
|
||||
# =============================================================================
|
||||
# LITTER BOX MONITOR - DFRobot ESP32-S3 AI Camera
|
||||
# =============================================================================
|
||||
|
||||
substitutions:
|
||||
device_name: litter-box-cam
|
||||
friendly_name: "Litter Box Camera"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Core Device Configuration
|
||||
# -----------------------------------------------------------------------------
|
||||
esphome:
|
||||
name: ${device_name}
|
||||
friendly_name: ${friendly_name}
|
||||
platformio_options:
|
||||
build_flags: "-DBOARD_HAS_PSRAM"
|
||||
board_build.arduino.memory_type: qio_opi
|
||||
|
||||
esp32:
|
||||
board: esp32-s3-devkitc-1
|
||||
framework:
|
||||
type: arduino
|
||||
version: latest
|
||||
flash_size: 16MB
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# PSRAM Configuration (Critical for camera)
|
||||
# -----------------------------------------------------------------------------
|
||||
psram:
|
||||
mode: octal
|
||||
speed: 80MHz
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Logging & API
|
||||
# -----------------------------------------------------------------------------
|
||||
logger:
|
||||
level: INFO
|
||||
|
||||
api:
|
||||
encryption:
|
||||
key: !secret api_encryption_key
|
||||
|
||||
services:
|
||||
- service: capture_and_analyze
|
||||
then:
|
||||
- script.execute: capture_image_script
|
||||
|
||||
- service: update_status
|
||||
variables:
|
||||
needs_scooping: bool
|
||||
litter_level_low: bool
|
||||
cat_present: bool
|
||||
cleanliness_score: int
|
||||
then:
|
||||
- lambda: |-
|
||||
id(needs_scooping_sensor).publish_state(needs_scooping);
|
||||
id(litter_level_low_sensor).publish_state(litter_level_low);
|
||||
id(cat_present_sensor).publish_state(cat_present);
|
||||
id(cleanliness_score_sensor).publish_state(cleanliness_score);
|
||||
id(last_analysis_time).publish_state(id(homeassistant_time).now().timestamp);
|
||||
if (cat_present) {
|
||||
id(daily_cat_visits) += 1;
|
||||
id(cat_visits_sensor).publish_state(id(daily_cat_visits));
|
||||
}
|
||||
|
||||
ota:
|
||||
- platform: esphome
|
||||
password: !secret ota_password
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# WiFi Configuration
|
||||
# -----------------------------------------------------------------------------
|
||||
wifi:
|
||||
ssid: !secret wifi_iot_ssid
|
||||
password: !secret wifi_password
|
||||
|
||||
ap:
|
||||
ssid: "${device_name}-AP"
|
||||
password: !secret wifi_password
|
||||
|
||||
captive_portal:
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# MQTT Configuration
|
||||
# -----------------------------------------------------------------------------
|
||||
mqtt:
|
||||
broker: !secret mqtt_broker
|
||||
username: !secret mqtt_username
|
||||
password: !secret mqtt_password
|
||||
topic_prefix: litter_box
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Time Synchronization
|
||||
# -----------------------------------------------------------------------------
|
||||
time:
|
||||
- platform: homeassistant
|
||||
id: homeassistant_time
|
||||
on_time:
|
||||
- seconds: 0
|
||||
minutes: 0
|
||||
hours: 0
|
||||
then:
|
||||
- lambda: |-
|
||||
id(daily_cat_visits) = 0;
|
||||
id(cat_visits_sensor).publish_state(0);
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Global Variables
|
||||
# -----------------------------------------------------------------------------
|
||||
globals:
|
||||
- id: daily_cat_visits
|
||||
type: int
|
||||
restore_value: yes
|
||||
initial_value: '0'
|
||||
|
||||
- id: motion_cooldown_active
|
||||
type: bool
|
||||
initial_value: 'false'
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Camera Configuration (OV3660 - DFR1154 Specific)
|
||||
# -----------------------------------------------------------------------------
|
||||
esp32_camera:
|
||||
id: litter_cam
|
||||
name: "Litter Box Camera"
|
||||
|
||||
# Hardware Interface - DFR1154 Pinout
|
||||
external_clock:
|
||||
pin: GPIO5
|
||||
frequency: 20MHz
|
||||
i2c_pins:
|
||||
sda: GPIO8
|
||||
scl: GPIO9
|
||||
data_pins: [GPIO16, GPIO18, GPIO21, GPIO17, GPIO14, GPIO7, GPIO6, GPIO4]
|
||||
vsync_pin: GPIO1
|
||||
href_pin: GPIO2
|
||||
pixel_clock_pin: GPIO15
|
||||
|
||||
# Image Parameters
|
||||
max_framerate: 10 fps
|
||||
idle_framerate: 0.1 fps
|
||||
resolution: 800x600
|
||||
jpeg_quality: 10
|
||||
vertical_flip: true
|
||||
horizontal_mirror: false
|
||||
aec_mode: AUTO
|
||||
agc_mode: AUTO
|
||||
wb_mode: AUTO
|
||||
brightness: 0
|
||||
contrast: 1
|
||||
saturation: 0
|
||||
|
||||
# Web server for manual viewing
|
||||
esp32_camera_web_server:
|
||||
- port: 8080
|
||||
mode: stream
|
||||
- port: 8081
|
||||
mode: snapshot
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# GPIO Outputs
|
||||
# -----------------------------------------------------------------------------
|
||||
output:
|
||||
- id: led_status
|
||||
platform: gpio
|
||||
pin: GPIO3
|
||||
|
||||
- id: ir_led
|
||||
platform: gpio
|
||||
pin: GPIO47
|
||||
|
||||
- id: speaker_gain
|
||||
platform: gpio
|
||||
pin: GPIO41
|
||||
|
||||
- id: speaker_mode
|
||||
platform: gpio
|
||||
pin: GPIO40
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Lights
|
||||
# -----------------------------------------------------------------------------
|
||||
light:
|
||||
- platform: binary
|
||||
name: "Status LED"
|
||||
id: status_led
|
||||
output: led_status
|
||||
|
||||
- platform: binary
|
||||
name: "IR Night Vision"
|
||||
id: ir_night_vision
|
||||
output: ir_led
|
||||
restore_mode: RESTORE_DEFAULT_OFF
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Binary Sensors
|
||||
# -----------------------------------------------------------------------------
|
||||
binary_sensor:
|
||||
- platform: template
|
||||
name: "Motion Detected"
|
||||
id: motion_detected
|
||||
device_class: motion
|
||||
|
||||
- platform: template
|
||||
name: "Needs Scooping"
|
||||
id: needs_scooping_sensor
|
||||
device_class: problem
|
||||
icon: "mdi:shovel"
|
||||
|
||||
- platform: template
|
||||
name: "Litter Level Low"
|
||||
id: litter_level_low_sensor
|
||||
device_class: problem
|
||||
icon: "mdi:cup-outline"
|
||||
|
||||
- platform: template
|
||||
name: "Cat Present"
|
||||
id: cat_present_sensor
|
||||
device_class: occupancy
|
||||
icon: "mdi:cat"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Sensors
|
||||
# -----------------------------------------------------------------------------
|
||||
sensor:
|
||||
- platform: wifi_signal
|
||||
name: "WiFi Signal"
|
||||
update_interval: 60s
|
||||
|
||||
- platform: template
|
||||
name: "Cleanliness Score"
|
||||
id: cleanliness_score_sensor
|
||||
unit_of_measurement: "%"
|
||||
icon: "mdi:star"
|
||||
accuracy_decimals: 0
|
||||
|
||||
- platform: template
|
||||
name: "Daily Cat Visits"
|
||||
id: cat_visits_sensor
|
||||
icon: "mdi:paw"
|
||||
accuracy_decimals: 0
|
||||
|
||||
- platform: template
|
||||
name: "Last Analysis"
|
||||
id: last_analysis_time
|
||||
device_class: timestamp
|
||||
icon: "mdi:clock-outline"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Text Sensors
|
||||
# -----------------------------------------------------------------------------
|
||||
text_sensor:
|
||||
- platform: version
|
||||
name: "ESPHome Version"
|
||||
|
||||
- platform: template
|
||||
name: "Status Message"
|
||||
id: status_message
|
||||
icon: "mdi:message-text"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Switches
|
||||
# -----------------------------------------------------------------------------
|
||||
switch:
|
||||
- platform: restart
|
||||
name: "Restart Camera"
|
||||
|
||||
- platform: template
|
||||
name: "Auto Capture Enabled"
|
||||
id: auto_capture_enabled
|
||||
optimistic: true
|
||||
restore_mode: RESTORE_DEFAULT_ON
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Buttons
|
||||
# -----------------------------------------------------------------------------
|
||||
button:
|
||||
- platform: template
|
||||
name: "Capture Now"
|
||||
icon: "mdi:camera"
|
||||
on_press:
|
||||
- script.execute: capture_image_script
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Scripts
|
||||
# -----------------------------------------------------------------------------
|
||||
script:
|
||||
- id: capture_image_script
|
||||
mode: single
|
||||
then:
|
||||
- lambda: 'ESP_LOGI("capture", "Capturing image...");'
|
||||
- light.turn_on: status_led
|
||||
- delay: 200ms
|
||||
- lambda: |-
|
||||
auto cam = id(litter_cam);
|
||||
camera::Camera::FrameBuffer *fb = cam->get_image();
|
||||
if (fb) {
|
||||
size_t out_len = 4 * ((fb->length + 2) / 3);
|
||||
char *base64_buffer = (char *)malloc(out_len + 1);
|
||||
if (base64_buffer) {
|
||||
size_t encoded_len = 0;
|
||||
int ret = mbedtls_base64_encode(
|
||||
(unsigned char *)base64_buffer, out_len + 1, &encoded_len,
|
||||
fb->buf, fb->length);
|
||||
if (ret == 0) {
|
||||
base64_buffer[encoded_len] = '\0';
|
||||
id(mqtt_client).publish("litter_box/camera/image", base64_buffer);
|
||||
ESP_LOGI("capture", "Published image");
|
||||
id(status_message).publish_state("Image sent for analysis");
|
||||
}
|
||||
free(base64_buffer);
|
||||
}
|
||||
cam->return_image(fb);
|
||||
}
|
||||
- light.turn_off: status_led
|
||||
- lambda: 'id(motion_cooldown_active) = true;'
|
||||
- delay: 30s
|
||||
- lambda: 'id(motion_cooldown_active) = false;'
|
||||
Reference in New Issue
Block a user