Add configuration for Jordyn's A1 camera with web server support

This commit is contained in:
Joshua King
2026-02-12 07:45:52 -05:00
parent 4d2875ad21
commit 0924d6ac91
2 changed files with 327 additions and 39 deletions

View File

@@ -0,0 +1,83 @@
substitutions:
device_name: ljordyn-a1-camera
friendly_name: "Jordyn's A1 Camera"
esphome:
name: ${device_name}
friendly_name: ${friendly_name}
esp32:
board: esp32dev
framework:
type: esp-idf
#cpu_frequency: 240MHZ
# Enable logging
logger:
level: INFO
# Enable Home Assistant API
api:
encryption:
key: "PDB5LTKAcNWMC+MeE03/SKpqX42pcnITzmfwu761LjI="
ota:
- platform: esphome
password: "d207583702e4b979e28a43f6f52d19ae"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Jordyn-A1-Camera"
password: "jN4rzGokp5mt"
captive_portal:
i2c:
- id: camera_i2c
sda: GPIO26
scl: GPIO27
psram:
mode: quad
speed: 80MHz
esp32_camera:
external_clock:
pin: GPIO0
frequency: 20MHz
i2c_id: camera_i2c
data_pins: [GPIO5, GPIO18, GPIO19, GPIO21, GPIO36, GPIO39, GPIO34, GPIO35]
vsync_pin: GPIO25
href_pin: GPIO23
pixel_clock_pin: GPIO22
power_down_pin: GPIO32
resolution: 800x600
jpeg_quality: 15
vertical_flip: False
horizontal_mirror: False
max_framerate: 20 fps
idle_framerate: 0.05 fps
# Image settings
name: esp32-jordyn-a1-cam
brightness: 1
#contrast: 0
agc_gain_ceiling: 2X
agc_mode: MANUAL
agc_value: 5
# ...
esp32_camera_web_server:
- port: 80
mode: STREAM
- port: 8080
mode: SNAPSHOT
switch:
- platform: gpio
name: "${device_name}-flash"
pin: 4

View File

@@ -1,11 +1,16 @@
substitutions:
device_name: ha-family-room-remote
friendly_name: "Family Room HA Remote"
esphome:
name: ha-remote-1
friendly_name: ha-remote-1
name: ${device_name}
friendly_name: ${friendly_name}
on_boot:
priority: -10
then:
- light.turn_on: ha_remote_backlight
- lvgl.page.show: home
- component.update: battery_voltage
- lambda: |-
id(last_activity_ms) = millis();
@@ -19,21 +24,27 @@ logger:
api:
encryption:
key: "mn3Lv3ud5jCSOqH/QKcspUu7ShdZ0OGotm0G01p9r94="
key: !secret api_encryption_key
# Enable over-the-air updates
ota:
- platform: esphome
password: "680170fb1d63d3490b2fc710fe064749"
password: !secret ota_password
wifi:
ssid: !secret wifi_ssid
ssid: !secret wifi_iot_ssid
password: !secret wifi_password
power_save_mode: LIGHT
fast_connect: true
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "${friendly_name} Fallback"
password: !secret fallback_password
psram:
mode: octal
speed: 80MHz
i2c:
sda: 8
@@ -142,6 +153,48 @@ touchscreen:
- light.turn_on: ha_remote_backlight
# --- LVGL UI ---
sensor:
# Waveshare routes battery sensing to EXIO_ADC (GPIO14) through a resistor divider.
# Divider on schematic is 470k/100k, so scale ADC by (470+100)/100 = 5.7.
- platform: adc
id: battery_voltage
name: "HA Remote Battery Voltage"
pin: GPIO14
attenuation: auto
update_interval: 30s
device_class: voltage
state_class: measurement
unit_of_measurement: V
accuracy_decimals: 2
filters:
- multiply: 5.7
- median:
window_size: 7
send_every: 3
send_first_at: 1
- platform: copy
source_id: battery_voltage
name: "HA Remote Battery Level"
id: battery_level
device_class: battery
state_class: measurement
unit_of_measurement: "%"
accuracy_decimals: 0
filters:
- lambda: |-
float pct = (x - 3.20f) * 100.0f / (4.20f - 3.20f);
if (pct < 0.0f) return 0.0f;
if (pct > 100.0f) return 100.0f;
return pct;
on_value:
then:
- lambda: |-
if (id(battery_label) == nullptr) return;
char txt[24];
snprintf(txt, sizeof(txt), "Battery: %.0f%%", x);
lv_label_set_text(id(battery_label), txt);
text_sensor:
- platform: wifi_info
ip_address:
@@ -153,25 +206,172 @@ lvgl:
- main_display
touchscreens:
- touch_panel
disp_bg_color: 0x0A1020
style_definitions:
- id: glass_header
bg_color: 0x1A2740
bg_opa: 70%
border_color: 0xA7C8FF
border_width: 1
border_opa: 35%
radius: 22
pad_all: 0
shadow_color: 0x061022
shadow_width: 22
shadow_opa: 40%
shadow_ofs_x: 0
shadow_ofs_y: 8
- id: glass_chip
bg_color: 0xCFE1FF
bg_opa: 28%
border_color: 0xFFFFFF
border_width: 1
border_opa: 45%
radius: 18
pad_all: 0
- id: glass_tile_blue
bg_color: 0x7BB8FF
bg_opa: 30%
border_color: 0xE6F1FF
border_width: 1
border_opa: 35%
radius: 24
shadow_color: 0x091529
shadow_width: 24
shadow_opa: 35%
shadow_ofs_x: 0
shadow_ofs_y: 8
text_color: 0xF4F8FF
pressed:
bg_opa: 46%
border_opa: 65%
- id: glass_tile_pink
bg_color: 0xD99CFF
bg_opa: 30%
border_color: 0xF7E7FF
border_width: 1
border_opa: 35%
radius: 24
shadow_color: 0x1A0E2B
shadow_width: 24
shadow_opa: 35%
shadow_ofs_x: 0
shadow_ofs_y: 8
text_color: 0xFFF8FF
pressed:
bg_opa: 46%
border_opa: 65%
- id: glass_tile_amber
bg_color: 0xFFD29A
bg_opa: 30%
border_color: 0xFFF0D9
border_width: 1
border_opa: 35%
radius: 24
shadow_color: 0x2A1A08
shadow_width: 24
shadow_opa: 35%
shadow_ofs_x: 0
shadow_ofs_y: 8
text_color: 0xFFF9EE
pressed:
bg_opa: 46%
border_opa: 65%
- id: glass_tile_green
bg_color: 0x9BE2C6
bg_opa: 30%
border_color: 0xE4FFF3
border_width: 1
border_opa: 35%
radius: 24
shadow_color: 0x0B2018
shadow_width: 24
shadow_opa: 35%
shadow_ofs_x: 0
shadow_ofs_y: 8
text_color: 0xF3FFF9
pressed:
bg_opa: 46%
border_opa: 65%
- id: glass_tile_red
bg_color: 0xFF9FAF
bg_opa: 34%
border_color: 0xFFE8EC
border_width: 1
border_opa: 38%
radius: 24
shadow_color: 0x2A0A12
shadow_width: 24
shadow_opa: 36%
shadow_ofs_x: 0
shadow_ofs_y: 8
text_color: 0xFFF5F7
pressed:
bg_opa: 50%
border_opa: 70%
- id: glass_tile_violet
bg_color: 0xB8A8FF
bg_opa: 30%
border_color: 0xF0EAFF
border_width: 1
border_opa: 35%
radius: 24
shadow_color: 0x1A1230
shadow_width: 24
shadow_opa: 35%
shadow_ofs_x: 0
shadow_ofs_y: 8
text_color: 0xF7F3FF
pressed:
bg_opa: 46%
border_opa: 65%
theme:
label:
text_color: 0xEAF2FF
button:
text_color: 0xF6FAFF
pages:
- id: home
widgets:
- obj:
x: 14
y: 14
width: 772
height: 84
styles: glass_header
widgets:
- label:
id: status_label
x: 22
y: 14
text: "Family Room"
- label:
x: 22
y: 46
text: "Quick scenes and lighting controls"
- obj:
x: 594
y: 16
width: 160
height: 52
styles: glass_chip
widgets:
- label:
id: battery_label
align: center
text: "Battery: --%"
- label:
id: status_label
x: 20
y: 10
text: "HA Remote"
- label:
x: 20
y: 40
text: "Tap to wake • Idle 60s to sleep"
x: 22
y: 108
text: "Tap any card. Screen sleeps after 60s idle."
- button:
x: 40
y: 100
width: 220
height: 100
x: 24
y: 138
width: 244
height: 136
styles: glass_tile_blue
on_click:
- homeassistant.service:
service: light.toggle
@@ -183,10 +383,11 @@ lvgl:
text: "Living Room\nLights"
- button:
x: 290
y: 100
width: 220
height: 100
x: 278
y: 138
width: 244
height: 136
styles: glass_tile_pink
on_click:
- homeassistant.service:
service: light.toggle
@@ -198,10 +399,11 @@ lvgl:
text: "Kitchen\nLights"
- button:
x: 540
y: 100
width: 220
height: 100
x: 532
y: 138
width: 244
height: 136
styles: glass_tile_red
on_click:
- homeassistant.service:
service: script.turn_off_everything
@@ -211,10 +413,11 @@ lvgl:
text: "All Off"
- button:
x: 40
y: 230
width: 220
height: 100
x: 24
y: 286
width: 244
height: 136
styles: glass_tile_amber
on_click:
- homeassistant.service:
service: scene.turn_on
@@ -226,10 +429,11 @@ lvgl:
text: "Movie Time"
- button:
x: 290
y: 230
width: 220
height: 100
x: 278
y: 286
width: 244
height: 136
styles: glass_tile_green
on_click:
- homeassistant.service:
service: scene.turn_on
@@ -241,13 +445,14 @@ lvgl:
text: "Good Night"
- button:
x: 540
y: 230
width: 220
height: 100
x: 532
y: 286
width: 244
height: 136
styles: glass_tile_violet
on_click:
- light.toggle: ha_remote_backlight
widgets:
- label:
align: center
text: "Backlight\nToggle"
text: "Backlight\nToggle"