Add image publishing functionality to Litter Box Camera: implement base64 encoding and MQTT publishing on image capture

This commit is contained in:
Joshua King
2026-03-06 08:55:37 -05:00
parent 6dd6e39c04
commit 71f35fe822

View File

@@ -113,11 +113,15 @@ globals:
type: int
restore_value: yes
initial_value: '0'
- id: motion_cooldown_active
type: bool
initial_value: 'false'
- id: publish_next_image
type: bool
initial_value: 'false'
# -----------------------------------------------------------------------------
# Camera Configuration (OV3660 - DFR1154 Specific)
# -----------------------------------------------------------------------------
@@ -150,6 +154,36 @@ esp32_camera:
brightness: 0
contrast: 1
saturation: 0
on_image:
then:
- lambda: |-
if (!id(publish_next_image)) return;
id(publish_next_image) = false;
const uint8_t *data = x->get_data();
size_t len = x->get_data_length();
size_t out_len = 4 * ((len + 2) / 3);
char *buf = (char *)malloc(out_len + 1);
if (!buf) return;
static const char b64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
size_t j = 0;
for (size_t i = 0; i < len; i += 3) {
uint32_t b = ((uint32_t)data[i] << 16);
if (i + 1 < len) b |= ((uint32_t)data[i + 1] << 8);
if (i + 2 < len) b |= data[i + 2];
buf[j++] = b64[(b >> 18) & 0x3F];
buf[j++] = b64[(b >> 12) & 0x3F];
buf[j++] = (i + 1 < len) ? b64[(b >> 6) & 0x3F] : '=';
buf[j++] = (i + 2 < len) ? b64[b & 0x3F] : '=';
}
buf[j] = '\0';
id(mqtt_client).publish("litter_box/camera/image", buf);
ESP_LOGI("capture", "Published image (%d bytes raw, %d base64)", len, j);
id(status_message).publish_state("Image sent for analysis");
free(buf);
# Web server for manual viewing
esp32_camera_web_server:
@@ -293,26 +327,8 @@ script:
- 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);
}
id(publish_next_image) = true;
id(litter_cam).request_image(esphome::esp32_camera::SINGLE_SHOT);
- light.turn_off: status_led
- lambda: 'id(motion_cooldown_active) = true;'
- delay: 30s