Add image publishing functionality to Litter Box Camera: implement base64 encoding and MQTT publishing on image capture
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user