diff --git a/homeai-esp32/PLAN.md b/homeai-esp32/PLAN.md index 0816133..8c8f377 100644 --- a/homeai-esp32/PLAN.md +++ b/homeai-esp32/PLAN.md @@ -67,6 +67,7 @@ ESP32-S3-BOX-3 | Sensor dock I2C SCL | GPIO40 | sensor bus (AHT-30, AT581x radar) | | Sensor dock I2C SDA | GPIO41 | sensor bus (AHT-30, AT581x radar) | | Radar presence output | GPIO21 | AT581x digital detection pin | +| Battery voltage ADC | GPIO1 | dock battery holder, voltage divider (×2) | --- @@ -117,6 +118,14 @@ Optional accessory dock connected via secondary I2C bus (GPIO40/41, 100kHz): - **AT581x mmWave radar** — presence detection via GPIO21, I2C for settings config - **Radar RF switch** — toggle radar on/off from HA - Radar configured on boot: sensing_distance=600, trigger_keep=5s, hw_frontend_reset=true +- **Battery monitoring** — ADC on GPIO1 with voltage divider (×2), reports voltage + percentage (Li-ion 3.0–4.2V curve) + +### Display Brightness + +Screen brightness adapts to context: +- **Radar presence** → wakes at configurable dim level (default 30%, adjustable 5–100% via "Radar brightness" entity in HA) +- **Voice activity** (listening, thinking, replying, error, timer) → full 100% brightness +- **Idle timeout** → screen off (configurable 1–60 min) ### Voice Assistant diff --git a/homeai-esp32/esphome/homeai-living-room.yaml b/homeai-esp32/esphome/homeai-living-room.yaml index b0f4fcf..dc77848 100644 --- a/homeai-esp32/esphome/homeai-living-room.yaml +++ b/homeai-esp32/esphome/homeai-living-room.yaml @@ -147,7 +147,9 @@ binary_sensor: id: radar_presence device_class: occupancy on_press: - - script.execute: screen_wake + - script.execute: + id: screen_wake + brightness_pct: !lambda return id(radar_brightness).state; - script.execute: screen_idle_timer # --- Display backlight --- @@ -371,22 +373,22 @@ script: - lambda: | switch(id(voice_assistant_phase)) { case ${voice_assist_listening_phase_id}: - id(screen_wake).execute(); + id(screen_wake).execute(100.0f); id(s3_box_lcd).show_page(listening_page); id(s3_box_lcd).update(); break; case ${voice_assist_thinking_phase_id}: - id(screen_wake).execute(); + id(screen_wake).execute(100.0f); id(s3_box_lcd).show_page(thinking_page); id(s3_box_lcd).update(); break; case ${voice_assist_replying_phase_id}: - id(screen_wake).execute(); + id(screen_wake).execute(100.0f); id(s3_box_lcd).show_page(replying_page); id(s3_box_lcd).update(); break; case ${voice_assist_error_phase_id}: - id(screen_wake).execute(); + id(screen_wake).execute(100.0f); id(s3_box_lcd).show_page(error_page); id(s3_box_lcd).update(); break; @@ -400,7 +402,7 @@ script: id(s3_box_lcd).update(); break; case ${voice_assist_timer_finished_phase_id}: - id(screen_wake).execute(); + id(screen_wake).execute(100.0f); id(s3_box_lcd).show_page(timer_finished_page); id(s3_box_lcd).update(); break; @@ -560,14 +562,12 @@ script: - id: screen_wake mode: restart + parameters: + brightness_pct: float then: - - if: - condition: - light.is_off: led - then: - - light.turn_on: - id: led - brightness: 100% + - light.turn_on: + id: led + brightness: !lambda return brightness_pct / 100.0f; # --- Switches --- @@ -689,6 +689,18 @@ number: max_value: 60 step: 1 initial_value: 1 + - platform: template + name: Radar brightness + id: radar_brightness + icon: "mdi:brightness-6" + entity_category: config + unit_of_measurement: "%" + optimistic: true + restore_value: true + min_value: 5 + max_value: 100 + step: 5 + initial_value: 30 # --- Sensor dock (ESP32-S3-BOX-3-SENSOR) --- @@ -709,6 +721,31 @@ sensor: window_size: 5 send_every: 5 update_interval: 30s + # --- Battery voltage (dock battery holder, GPIO1 with voltage divider) --- + - platform: adc + pin: GPIO1 + name: Battery Voltage + id: battery_voltage + attenuation: 12db + update_interval: 60s + filters: + - multiply: 2.0 # voltage divider ratio on dock + - sliding_window_moving_average: + window_size: 5 + send_every: 5 + - platform: template + name: Battery Level + id: battery_level + unit_of_measurement: "%" + device_class: battery + accuracy_decimals: 0 + update_interval: 60s + lambda: |- + float v = id(battery_voltage).state; + if (v >= 4.2) return 100.0f; + if (v <= 3.0) return 0.0f; + // Simple linear approximation for Li-ion 3.0V–4.2V + return (v - 3.0f) / 1.2f * 100.0f; at581x: i2c_id: sensor_bus