From 635fc29b038315b02849b0b163cb94a2ebdf3f37 Mon Sep 17 00:00:00 2001 From: Dan Webb Date: Tue, 22 Jul 2025 11:12:11 +0100 Subject: [PATCH] feat: Move to ESP-IDF framework The ESP-IDF framework is smaller than the arduino framework, so has a few features missing. But we now fit in memory again on ESPHome 2025.7.0+ Additionally: - Add lefthook - Add yamllint hook - Lint files. We found a few bugs - Add Taskfile for common tasks (run, compile logs) Signed-off-by: Dan Webb --- .github/workflows/lint.yaml | 18 + .gitignore | 1 + .lefthook.yaml | 9 + .yamllint | 10 + Taskfile.yml | 90 +++ esphome/loopon_unity.yaml | 824 +++++++++++------------ esphome/loopon_unity_2.yaml | 834 ++++++++++++------------ esphome/loopon_unity_esp_idf.yaml | 405 ++++++++++++ esphome/loopon_unity_no_power_save.yaml | 784 +++++++++++----------- 9 files changed, 1754 insertions(+), 1221 deletions(-) create mode 100644 .github/workflows/lint.yaml create mode 100644 .lefthook.yaml create mode 100644 .yamllint create mode 100644 Taskfile.yml create mode 100644 esphome/loopon_unity_esp_idf.yaml diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 0000000..f8fa70c --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,18 @@ +--- +name: Lint +on: [push, pull_request] +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.12' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install yamllint + - name: Run yamllint + run: yamllint . diff --git a/.gitignore b/.gitignore index 722d5e7..59458bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .vscode +.esphome_cache diff --git a/.lefthook.yaml b/.lefthook.yaml new file mode 100644 index 0000000..f589734 --- /dev/null +++ b/.lefthook.yaml @@ -0,0 +1,9 @@ +--- +assert_lefthook_installed: true +skip_lfs: true + +pre-commit: + parallel: true + jobs: + - name: yamllint + run: yamllint . diff --git a/.yamllint b/.yamllint new file mode 100644 index 0000000..d3a5962 --- /dev/null +++ b/.yamllint @@ -0,0 +1,10 @@ +--- +extends: relaxed +rules: + line-length: + max: 256 + level: warning + document-start: disable +ignore: + - ".esphome_cache/**" + - "esphome/.esphome/**" diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 0000000..39b8d88 --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,90 @@ +--- +version: "3" + +vars: + CACHE_DIR: "{{.USER_WORKING_DIR}}/.esphome_cache" + +tasks: + default: + desc: List all tasks + cmd: task --list-all + + setup-cache: + desc: Create cache directories if they don't exist + cmds: + - mkdir -p "{{.CACHE_DIR}}/pip" + - mkdir -p "{{.CACHE_DIR}}/platformio" + generates: + - "{{.CACHE_DIR}}/pip" + - "{{.CACHE_DIR}}/platformio" + + compile: + desc: Compile the ESPHome config + deps: [setup-cache] + cmd: >- + docker run --rm + -v "$PWD/esphome:/config" + -v "{{.CACHE_DIR}}/pip:/root/.cache/pip" + -v "{{.CACHE_DIR}}/platformio:/root/.platformio" + -it esphome/esphome compile loopon_unity_esp_idf.yaml + + flash: + desc: Flash the ESPHome firmware to the Unity sensor + deps: [setup-cache] + cmds: + - echo "Flashing firmware to Unity sensor..." + - >- + docker run --rm + -v "$PWD/esphome:/config" + -v "{{.CACHE_DIR}}/pip:/root/.cache/pip" + -v "{{.CACHE_DIR}}/platformio:/root/.platformio" + --privileged + --network host + -v /dev:/dev + -it esphome/esphome + upload loopon_unity_esp_idf.yaml --device /dev/cu.usbmodem2101 + + monitor: + desc: Monitor the ESPHome firmware serial output + deps: [setup-cache] + cmds: + - echo "Connecting to Unity sensor serial monitor..." + - >- + docker run --rm + -v "$PWD/esphome:/config" + -v "{{.CACHE_DIR}}/pip:/root/.cache/pip" + -v "{{.CACHE_DIR}}/platformio:/root/.platformio" + --privileged + -v /dev:/dev + -it esphome/esphome + logs loopon_unity_esp_idf.yaml + + run: + desc: Run and watch the ESPHome firmware in real-time (upload + monitor) + deps: [setup-cache] + cmds: + - echo "Running Unity sensor firmware (uploading and monitoring)..." + - >- + docker run --rm + -v "$PWD/esphome:/config" + -v "{{.CACHE_DIR}}/pip:/root/.cache/pip" + -v "{{.CACHE_DIR}}/platformio:/root/.platformio" + --privileged + -v /dev/cu.usbmodem2101:/dev/cu.usbmodem2101 + -it esphome/esphome + run loopon_unity_esp_idf.yaml --device /dev/cu.usbmodem2101 + + log: + desc: Alternative way to monitor logs (same as monitor task) + deps: [setup-cache] + cmds: + - echo "Connecting to Unity sensor logs..." + - >- + docker run --rm + -v "$PWD/esphome:/config" + -v "{{.CACHE_DIR}}/pip:/root/.cache/pip" + -v "{{.CACHE_DIR}}/platformio:/root/.platformio" + --privileged + -v /dev:/dev + -it esphome/esphome + logs loopon_unity_esp_idf.yaml diff --git a/esphome/loopon_unity.yaml b/esphome/loopon_unity.yaml index 7f996cd..37ca8c6 100644 --- a/esphome/loopon_unity.yaml +++ b/esphome/loopon_unity.yaml @@ -1,412 +1,412 @@ -## Unity by LoopOn -## https://loopon.tech/products/unity-sensor - -substitutions: - name: unity - device_name: Unity - device_make: LoopOn - sw_version: "1.2.17" - bh1750_addr: "0x23" # Addr pad unsoldered=0x23 / soldered=0x5C - ld2410_name: mmWave - -esphome: - name: "${name}" - friendly_name: "${device_name}" - comment: "${device_name} by ${device_make}" - name_add_mac_suffix: true - min_version: "2024.9.2" - project: - name: "${device_make}.${device_name}" - version: "${sw_version}" - platformio_options: - board_build.mcu: esp32c3 - board_build.variant: esp32c3 - board_build.flash_mode: dio - board_build.f_cpu: 160000000L - board_build.f_flash: 80000000L - board_build.flash_size: 4MB - build_flags: -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=1 -DARDUINO_ESP32C3_DEV=1 - upload_speed: 115200 - on_boot: - priority: 600 - then: - - light.turn_on: - id: rgb_light - effect: "Boot Sequence" - red: 100% - green: 100% - blue: 100% - - delay: 2000ms - - light.turn_on: - id: rgb_light - effect: none - - light.turn_off: - id: rgb_light - - lambda: "ld2410_ld2410component_id->set_numbers(distance_range_ld2410,none_duration_ld2410,moving_sensitivity_threshold_ld2410,still_sensitivity_threshold_ld2410);" - - script.execute: config_on_ld2410 - - delay: 50ms - - script.execute: query_params_ld2410 - - delay: 50ms - - script.execute: set_thresholds_ld2410 - - delay: 50ms - - script.execute: config_off_ld2410 - -esp32: - board: esp32-c3-devkitm-1 - variant: esp32c3 - framework: - type: arduino - -dashboard_import: - package_import_url: github://LoopOnCode/UnitySensor/esphome/loopon_unity.yaml@main - import_full_config: false - -external_components: - - source: github://LoopOnCode/UnitySensor@main - components: [ ld2410 ] - -ld2410: - -logger: - -api: - -ota: - platform: esphome - -wifi: - fast_connect: false - enable_on_boot: true - power_save_mode: LIGHT - ap: - on_connect: - - delay: 5s # Gives time for improv results to be transmitted - - ble.disable: - on_disconnect: - - ble.enable: - -captive_portal: - -uart: - id: ld2410_uart - tx_pin: GPIO21 - rx_pin: GPIO20 - baud_rate: 256000 - parity: NONE - stop_bits: 1 - -esp32_improv: - authorizer: none - status_indicator: improv_status - -improv_serial: - -i2c: - sda: GPIO5 - scl: GPIO6 - scan: false - -light: - - platform: neopixelbus - id: rgb_light - type: GRB - variant: WS2812 - pin: GPIO2 - num_leds: 1 - name: "${device_name} Light" - gamma_correct: 0 - restore_mode: RESTORE_DEFAULT_OFF - effects: - - addressable_rainbow: - name: "Boot Sequence" - speed: 50 - width: 1 - -output: - - platform: template - id: improv_status - type: binary - write_action: - - light.control: - id: rgb_light - state: !lambda return state; - -text_sensor: - - platform: template - name: "${device_name} Config Version" - lambda: return {"${sw_version}"}; - icon: "mdi:tag" - entity_category: diagnostic - - platform: wifi_info - ip_address: - id: ip_address - name: "${device_name} IP Address" - icon: "mdi:wan" - -binary_sensor: - - platform: ld2410 - has_target: - name: "${device_name} Has Human Target" - has_moving_target: - name: "${device_name} Has Moving Human Target" - has_still_target: - name: "${device_name} Has Still Human Target" - - platform: gpio - id: boot_button - icon: "mdi:button-pointer" - pin: - number: GPIO9 - inverted: true - mode: - input: true - pullup: true - name: "${device_name} Button" - -sensor: - - platform: template - id: internal_temp - name: "${device_name} Internal Temperature" - icon: "mdi:thermometer" - unit_of_measurement: "°C" - entity_category: diagnostic - disabled_by_default: true - lambda: return temperatureRead(); - - platform: wifi_signal - name: "${device_name} WiFi Signal" - update_interval: 60s - - platform: hdc1080 - temperature: - name: "${device_name} Temperature" - filters: - - median - - lambda: "return x-(abs(id(internal_temp).state-x)/2)+id(temperature_offset).state;" - humidity: - name: "${device_name} Humidity" - filters: - - median - - lambda: "return x+id(humidity_offset).state;" - - clamp: - min_value: 0 - max_value: 100 - update_interval: 12s - - platform: bh1750 - name: "${device_name} Illuminance" - address: ${bh1750_addr} - filters: - - lambda: "return x+id(illuminance_offset).state;" - update_interval: 60s - - platform: ld2410 - moving_distance: - name : "${device_name} Moving Human Distance" - id: moving_target_distance_ld2410 - still_distance: - name: "${device_name} Still Human Distance" - id: still_target_distance_ld2410 - moving_energy: - name: "${device_name} Moving Human Energy" - id: moving_target_energy_ld2410 - still_energy: - name: "${device_name} Still Human Energy" - id: still_target_energy_ld2410 - detection_distance: - name: "${device_name} Human Detection Distance" - id: target_detect_distance_ld2410 - -number: - - platform: template - name: "${device_name} Human Distance Range" - id: distance_range_ld2410 - unit_of_measurement: "m" - icon: "mdi:arrow-left-right" - min_value: 0.75 - max_value: 6 - step: 0.75 - mode: box - update_interval: never - optimistic: true - entity_category: config - set_action: - - script.execute: config_on_ld2410 - - delay: 50ms - - lambda: "ld2410_ld2410component_id->set_max_distances_timeout(x/0.75,id(none_duration_ld2410).state);" - - delay: 50ms - - script.execute: query_params_ld2410 - - delay: 50ms - - script.execute: config_off_ld2410 - - platform: template - name: "${device_name} Human Clear Delay" - id: none_duration_ld2410 - unit_of_measurement: "s" - icon: "mdi:timer" - min_value: 0 - max_value: 900 - step: 1 - mode: box - update_interval: never - optimistic: true - entity_category: config - set_action: - - script.execute: config_on_ld2410 - - delay: 50ms - - lambda: "ld2410_ld2410component_id->set_max_distances_timeout(id(distance_range_ld2410).state/0.75,x);" - - delay: 50ms - - script.execute: query_params_ld2410 - - delay: 50ms - - script.execute: config_off_ld2410 - - platform: template - name: "${device_name} Moving Human Sensitivity Threshold" - id: moving_sensitivity_threshold_ld2410 - unit_of_measurement: "%" - icon: "mdi:car-cruise-control" - min_value: 0 - max_value: 100 - step: 1 - mode: box - update_interval: never - optimistic: true - entity_category: config - set_action: - - script.execute: config_on_ld2410 - - delay: 50ms - - lambda: "ld2410_ld2410component_id->set_thresholds(x,id(still_sensitivity_threshold_ld2410).state);" - - delay: 50ms - - script.execute: query_params_ld2410 - - delay: 50ms - - script.execute: config_off_ld2410 - - platform: template - name: "${device_name} Still Human Sensitivity Threshold" - id: still_sensitivity_threshold_ld2410 - unit_of_measurement: "%" - icon: "mdi:car-cruise-control" - min_value: 0 - max_value: 100 - step: 1 - mode: box - update_interval: never - optimistic: true - entity_category: config - set_action: - - script.execute: config_on_ld2410 - - delay: 50ms - - lambda: "ld2410_ld2410component_id->set_thresholds(id(moving_sensitivity_threshold_ld2410).state,x);" - - delay: 50ms - - script.execute: query_params_ld2410 - - delay: 50ms - - script.execute: config_off_ld2410 - - platform: template - name: "${device_name} Temperature Offset" - id: temperature_offset - unit_of_measurement: "°C" - min_value: -50 - max_value: 50 - step: 0.1 - mode: box - update_interval: never - optimistic: true - restore_value: true - initial_value: -3 - icon: "mdi:thermometer" - entity_category: config - - platform: template - name: "${device_name} Humidity Offset" - id: humidity_offset - unit_of_measurement: "%" - min_value: -50 - max_value: 50 - step: 0.1 - mode: box - update_interval: never - optimistic: true - restore_value: true - initial_value: 0 - icon: "mdi:water-percent" - entity_category: config - - platform: template - name: "${device_name} Illuminance Offset" - id: illuminance_offset - unit_of_measurement: "lx" - min_value: -50 - max_value: 50 - step: 1 - mode: box - update_interval: never - optimistic: true - restore_value: true - initial_value: 0 - icon: "mdi:brightness-5" - entity_category: config - -button: - - platform: restart - name: "${device_name} Restart" - entity_category: diagnostic - - platform: template - name: "${device_name} Restart ${ld2410_name}" - entity_category: diagnostic - icon: "mdi:restart" - on_press: - script.execute: reboot_ld2410 - - platform: template - name: "${device_name} Factory Reset ${ld2410_name}" - icon: "mdi:restart-alert" - entity_category: config - disabled_by_default: true - on_press: - - script.execute: factory_reset_ld2410 - - platform: factory_reset - name: "${device_name} Factory Reset" - icon: "mdi:restart-alert" - entity_category: config - disabled_by_default: true - -script: - - id: config_on_ld2410 - then: - - lambda: "ld2410_ld2410component_id->set_config_mode(true);" - - delay: 50ms - - script.execute: clear_targets_ld2410 - - id: config_off_ld2410 - then: - - lambda: "ld2410_ld2410component_id->set_config_mode(false);" - - id: query_params_ld2410 - then: - - lambda: "ld2410_ld2410component_id->query_parameters();" - - id: get_config_ld2410 - then: - - script.execute: config_on_ld2410 - - delay: 50ms - - script.execute: query_params_ld2410 - - delay: 50ms - - script.execute: config_off_ld2410 - - id: set_thresholds_ld2410 - then: - - lambda: "ld2410_ld2410component_id->set_thresholds(id(moving_sensitivity_threshold_ld2410).state,id(still_sensitivity_threshold_ld2410).state);" - - id: reboot_ld2410 - then: - - script.execute: clear_targets_ld2410 - - lambda: "ld2410_ld2410component_id->reboot();" - - delay: 500ms - - script.execute: get_config_ld2410 - - id: factory_reset_ld2410 - then: - - script.execute: config_on_ld2410 - - delay: 100ms - - lambda: "ld2410_ld2410component_id->factory_reset();" - - delay: 150ms - - lambda: "ld2410_ld2410component_id->reboot();" - - delay: 500ms - - script.execute: config_on_ld2410 - - delay: 50ms - - script.execute: query_params_ld2410 - - delay: 50ms - - script.execute: set_thresholds_ld2410 - - delay: 50ms - - script.execute: config_off_ld2410 - - id: clear_targets_ld2410 - then: - - lambda: |- - id(moving_target_distance_ld2410).publish_state(0); - id(moving_target_energy_ld2410).publish_state(0); - id(still_target_distance_ld2410).publish_state(0); - id(still_target_energy_ld2410).publish_state(0); - id(target_detect_distance_ld2410).publish_state(0); +# Unity by LoopOn +# https://loopon.tech/products/unity-sensor + +substitutions: + name: unity + device_name: Unity + device_make: LoopOn + sw_version: "1.2.17" + bh1750_addr: "0x23" # Addr pad unsoldered=0x23 / soldered=0x5C + ld2410_name: mmWave + +esphome: + name: "${name}" + friendly_name: "${device_name}" + comment: "${device_name} by ${device_make}" + name_add_mac_suffix: true + min_version: "2024.9.2" + project: + name: "${device_make}.${device_name}" + version: "${sw_version}" + platformio_options: + board_build.mcu: esp32c3 + board_build.variant: esp32c3 + board_build.flash_mode: dio + board_build.f_cpu: 160000000L + board_build.f_flash: 80000000L + board_build.flash_size: 4MB + build_flags: -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=1 -DARDUINO_ESP32C3_DEV=1 + upload_speed: 115200 + on_boot: + priority: 600 + then: + - light.turn_on: + id: rgb_light + effect: "Boot Sequence" + red: 100% + green: 100% + blue: 100% + - delay: 2000ms + - light.turn_on: + id: rgb_light + effect: none + - light.turn_off: + id: rgb_light + - lambda: "ld2410_ld2410component_id->set_numbers(distance_range_ld2410,none_duration_ld2410,moving_sensitivity_threshold_ld2410,still_sensitivity_threshold_ld2410);" + - script.execute: config_on_ld2410 + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: set_thresholds_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + +esp32: + board: esp32-c3-devkitm-1 + variant: esp32c3 + framework: + type: arduino + +dashboard_import: + package_import_url: github://LoopOnCode/UnitySensor/esphome/loopon_unity.yaml@main + import_full_config: false + +external_components: + - source: github://LoopOnCode/UnitySensor@main + components: [ ld2410 ] + +ld2410: + +logger: + +api: + +ota: + platform: esphome + +wifi: + fast_connect: false + enable_on_boot: true + power_save_mode: LIGHT + ap: + on_connect: + - delay: 5s # Gives time for improv results to be transmitted + - ble.disable: + on_disconnect: + - ble.enable: + +captive_portal: + +uart: + id: ld2410_uart + tx_pin: GPIO21 + rx_pin: GPIO20 + baud_rate: 256000 + parity: NONE + stop_bits: 1 + +esp32_improv: + authorizer: none + status_indicator: improv_status + +improv_serial: + +i2c: + sda: GPIO5 + scl: GPIO6 + scan: false + +light: + - platform: neopixelbus + id: rgb_light + type: GRB + variant: WS2812 + pin: GPIO2 + num_leds: 1 + name: "${device_name} Light" + gamma_correct: 0 + restore_mode: RESTORE_DEFAULT_OFF + effects: + - addressable_rainbow: + name: "Boot Sequence" + speed: 50 + width: 1 + +output: + - platform: template + id: improv_status + type: binary + write_action: + - light.control: + id: rgb_light + state: !lambda return state; + +text_sensor: + - platform: template + name: "${device_name} Config Version" + lambda: return {"${sw_version}"}; + icon: "mdi:tag" + entity_category: diagnostic + - platform: wifi_info + ip_address: + id: ip_address + name: "${device_name} IP Address" + icon: "mdi:wan" + +binary_sensor: + - platform: ld2410 + has_target: + name: "${device_name} Has Human Target" + has_moving_target: + name: "${device_name} Has Moving Human Target" + has_still_target: + name: "${device_name} Has Still Human Target" + - platform: gpio + id: boot_button + icon: "mdi:button-pointer" + pin: + number: GPIO9 + inverted: true + mode: + input: true + pullup: true + name: "${device_name} Button" + +sensor: + - platform: template + id: internal_temp + name: "${device_name} Internal Temperature" + icon: "mdi:thermometer" + unit_of_measurement: "°C" + entity_category: diagnostic + disabled_by_default: true + lambda: return temperatureRead(); + - platform: wifi_signal + name: "${device_name} WiFi Signal" + update_interval: 60s + - platform: hdc1080 + temperature: + name: "${device_name} Temperature" + filters: + - median + - lambda: "return x-(abs(id(internal_temp).state-x)/2)+id(temperature_offset).state;" + humidity: + name: "${device_name} Humidity" + filters: + - median + - lambda: "return x+id(humidity_offset).state;" + - clamp: + min_value: 0 + max_value: 100 + update_interval: 12s + - platform: bh1750 + name: "${device_name} Illuminance" + address: ${bh1750_addr} + filters: + - lambda: "return x+id(illuminance_offset).state;" + update_interval: 60s + - platform: ld2410 + moving_distance: + name: "${device_name} Moving Human Distance" + id: moving_target_distance_ld2410 + still_distance: + name: "${device_name} Still Human Distance" + id: still_target_distance_ld2410 + moving_energy: + name: "${device_name} Moving Human Energy" + id: moving_target_energy_ld2410 + still_energy: + name: "${device_name} Still Human Energy" + id: still_target_energy_ld2410 + detection_distance: + name: "${device_name} Human Detection Distance" + id: target_detect_distance_ld2410 + +number: + - platform: template + name: "${device_name} Human Distance Range" + id: distance_range_ld2410 + unit_of_measurement: "m" + icon: "mdi:arrow-left-right" + min_value: 0.75 + max_value: 6 + step: 0.75 + mode: box + update_interval: never + optimistic: true + entity_category: config + set_action: + - script.execute: config_on_ld2410 + - delay: 50ms + - lambda: "ld2410_ld2410component_id->set_max_distances_timeout(x/0.75,id(none_duration_ld2410).state);" + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - platform: template + name: "${device_name} Human Clear Delay" + id: none_duration_ld2410 + unit_of_measurement: "s" + icon: "mdi:timer" + min_value: 0 + max_value: 900 + step: 1 + mode: box + update_interval: never + optimistic: true + entity_category: config + set_action: + - script.execute: config_on_ld2410 + - delay: 50ms + - lambda: "ld2410_ld2410component_id->set_max_distances_timeout(id(distance_range_ld2410).state/0.75,x);" + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - platform: template + name: "${device_name} Moving Human Sensitivity Threshold" + id: moving_sensitivity_threshold_ld2410 + unit_of_measurement: "%" + icon: "mdi:car-cruise-control" + min_value: 0 + max_value: 100 + step: 1 + mode: box + update_interval: never + optimistic: true + entity_category: config + set_action: + - script.execute: config_on_ld2410 + - delay: 50ms + - lambda: "ld2410_ld2410component_id->set_thresholds(x,id(still_sensitivity_threshold_ld2410).state);" + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - platform: template + name: "${device_name} Still Human Sensitivity Threshold" + id: still_sensitivity_threshold_ld2410 + unit_of_measurement: "%" + icon: "mdi:car-cruise-control" + min_value: 0 + max_value: 100 + step: 1 + mode: box + update_interval: never + optimistic: true + entity_category: config + set_action: + - script.execute: config_on_ld2410 + - delay: 50ms + - lambda: "ld2410_ld2410component_id->set_thresholds(id(moving_sensitivity_threshold_ld2410).state,x);" + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - platform: template + name: "${device_name} Temperature Offset" + id: temperature_offset + unit_of_measurement: "°C" + min_value: -50 + max_value: 50 + step: 0.1 + mode: box + update_interval: never + optimistic: true + restore_value: true + initial_value: -3 + icon: "mdi:thermometer" + entity_category: config + - platform: template + name: "${device_name} Humidity Offset" + id: humidity_offset + unit_of_measurement: "%" + min_value: -50 + max_value: 50 + step: 0.1 + mode: box + update_interval: never + optimistic: true + restore_value: true + initial_value: 0 + icon: "mdi:water-percent" + entity_category: config + - platform: template + name: "${device_name} Illuminance Offset" + id: illuminance_offset + unit_of_measurement: "lx" + min_value: -50 + max_value: 50 + step: 1 + mode: box + update_interval: never + optimistic: true + restore_value: true + initial_value: 0 + icon: "mdi:brightness-5" + entity_category: config + +button: + - platform: restart + name: "${device_name} Restart" + entity_category: diagnostic + - platform: template + name: "${device_name} Restart ${ld2410_name}" + entity_category: diagnostic + icon: "mdi:restart" + on_press: + script.execute: reboot_ld2410 + - platform: template + name: "${device_name} Factory Reset ${ld2410_name}" + icon: "mdi:restart-alert" + entity_category: config + disabled_by_default: true + on_press: + - script.execute: factory_reset_ld2410 + - platform: factory_reset + name: "${device_name} Factory Reset" + icon: "mdi:restart-alert" + entity_category: config + disabled_by_default: true + +script: + - id: config_on_ld2410 + then: + - lambda: "ld2410_ld2410component_id->set_config_mode(true);" + - delay: 50ms + - script.execute: clear_targets_ld2410 + - id: config_off_ld2410 + then: + - lambda: "ld2410_ld2410component_id->set_config_mode(false);" + - id: query_params_ld2410 + then: + - lambda: "ld2410_ld2410component_id->query_parameters();" + - id: get_config_ld2410 + then: + - script.execute: config_on_ld2410 + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - id: set_thresholds_ld2410 + then: + - lambda: "ld2410_ld2410component_id->set_thresholds(id(moving_sensitivity_threshold_ld2410).state,id(still_sensitivity_threshold_ld2410).state);" + - id: reboot_ld2410 + then: + - script.execute: clear_targets_ld2410 + - lambda: "ld2410_ld2410component_id->reboot();" + - delay: 500ms + - script.execute: get_config_ld2410 + - id: factory_reset_ld2410 + then: + - script.execute: config_on_ld2410 + - delay: 100ms + - lambda: "ld2410_ld2410component_id->factory_reset();" + - delay: 150ms + - lambda: "ld2410_ld2410component_id->reboot();" + - delay: 500ms + - script.execute: config_on_ld2410 + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: set_thresholds_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - id: clear_targets_ld2410 + then: + - lambda: |- + id(moving_target_distance_ld2410).publish_state(0); + id(moving_target_energy_ld2410).publish_state(0); + id(still_target_distance_ld2410).publish_state(0); + id(still_target_energy_ld2410).publish_state(0); + id(target_detect_distance_ld2410).publish_state(0); diff --git a/esphome/loopon_unity_2.yaml b/esphome/loopon_unity_2.yaml index 82a20dd..500a73f 100644 --- a/esphome/loopon_unity_2.yaml +++ b/esphome/loopon_unity_2.yaml @@ -1,417 +1,417 @@ -## Unity by LoopOn -## https://loopon.tech/products/unity-sensor - -substitutions: - name: unity - device_name: Unity - device_make: LoopOn - sw_version: "2.0.5" - bh1750_addr: "0x23" # Addr pad unsoldered=0x23 / soldered=0x5C - ld2410_name: mmWave - -esphome: - name: "${name}" - friendly_name: "${device_name}" - comment: "${device_name} by ${device_make}" - name_add_mac_suffix: true - min_version: "2024.9.2" - project: - name: "${device_make}.${device_name}" - version: "${sw_version}" - platformio_options: - board_build.mcu: esp32c3 - board_build.variant: esp32c3 - board_build.flash_mode: dio - board_build.f_cpu: 160000000L - board_build.f_flash: 80000000L - board_build.flash_size: 4MB - build_flags: -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=1 -DARDUINO_ESP32C3_DEV=1 - upload_speed: 115200 - on_boot: - priority: 600 - then: - - light.turn_on: - id: rgb_light - effect: "Boot Sequence" - red: 100% - green: 100% - blue: 100% - - delay: 2000ms - - light.turn_on: - id: rgb_light - effect: none - - light.turn_off: - id: rgb_light - - lambda: "ld2410_ld2410component_id->set_numbers(distance_range_ld2410,none_duration_ld2410,moving_sensitivity_threshold_ld2410,still_sensitivity_threshold_ld2410);" - - script.execute: config_on_ld2410 - - delay: 50ms - - script.execute: query_params_ld2410 - - delay: 50ms - - script.execute: set_thresholds_ld2410 - - delay: 50ms - - script.execute: config_off_ld2410 - -esp32: - board: esp32-c3-devkitm-1 - variant: esp32c3 - framework: - type: arduino - -dashboard_import: - package_import_url: github://LoopOnCode/UnitySensor/esphome/loopon_unity_2.yaml@main - import_full_config: false - -external_components: - - source: github://LoopOnCode/UnitySensor@main - components: [ ld2410 ] - -ld2410: - -logger: - -api: - -ota: - platform: esphome - -wifi: - fast_connect: false - output_power: 10 - enable_on_boot: true - power_save_mode: LIGHT - ap: - on_connect: - - delay: 5s # Gives time for improv results to be transmitted - - ble.disable: - on_disconnect: - - ble.enable: - -captive_portal: - -uart: - id: ld2410_uart - tx_pin: GPIO21 - rx_pin: GPIO20 - baud_rate: 256000 - parity: NONE - stop_bits: 1 - -esp32_improv: - authorizer: none - status_indicator: improv_status - -improv_serial: - -i2c: - sda: GPIO5 - scl: GPIO6 - scan: false - -light: - - platform: neopixelbus - id: rgb_light - type: GRB - variant: WS2812 - pin: GPIO2 - num_leds: 1 - name: "Light" - gamma_correct: 0 - restore_mode: RESTORE_DEFAULT_OFF - effects: - - addressable_rainbow: - name: "Boot Sequence" - speed: 50 - width: 1 - -output: - - platform: template - id: improv_status - type: binary - write_action: - - light.control: - id: rgb_light - state: !lambda return state; - -text_sensor: - - platform: template - name: "Config Version" - lambda: return {"${sw_version}"}; - icon: "mdi:tag" - entity_category: diagnostic - - platform: wifi_info - ip_address: - id: ip_address - name: "IP Address" - icon: "mdi:wan" - -binary_sensor: - - platform: ld2410 - has_target: - name: "Has Human Target" - has_moving_target: - name: "Has Moving Human Target" - has_still_target: - name: "Has Still Human Target" - - platform: gpio - id: boot_button - icon: "mdi:button-pointer" - pin: - number: GPIO9 - inverted: true - mode: - input: true - pullup: true - name: "Button" - -sensor: - - platform: template - id: internal_temp - name: "Internal Temperature" - icon: "mdi:thermometer" - unit_of_measurement: "°C" - entity_category: diagnostic - disabled_by_default: true - lambda: return temperatureRead(); - - platform: wifi_signal - name: "WiFi Signal" - update_interval: 60s - - platform: hdc1080 - temperature: - name: "Temperature" - filters: - - skip_initial: 3 - - median: - window_size: 15 - send_every: 5 - send_first_at: 1 - - lambda: "return x+id(temperature_offset).state-10;" - humidity: - name: "Humidity" - filters: - - median - - lambda: "return x+id(humidity_offset).state;" - - clamp: - min_value: 0 - max_value: 100 - update_interval: 12s - - platform: bh1750 - name: "Illuminance" - address: ${bh1750_addr} - filters: - - lambda: "return x+id(illuminance_offset).state;" - update_interval: 60s - - platform: ld2410 - moving_distance: - name : "Moving Human Distance" - id: moving_target_distance_ld2410 - still_distance: - name: "Still Human Distance" - id: still_target_distance_ld2410 - moving_energy: - name: "Moving Human Energy" - id: moving_target_energy_ld2410 - still_energy: - name: "Still Human Energy" - id: still_target_energy_ld2410 - detection_distance: - name: "Human Detection Distance" - id: target_detect_distance_ld2410 - -number: - - platform: template - name: "Human Distance Range" - id: distance_range_ld2410 - unit_of_measurement: "m" - icon: "mdi:arrow-left-right" - min_value: 0.75 - max_value: 6 - step: 0.75 - mode: box - update_interval: never - optimistic: true - entity_category: config - set_action: - - script.execute: config_on_ld2410 - - delay: 50ms - - lambda: "ld2410_ld2410component_id->set_max_distances_timeout(x/0.75,id(none_duration_ld2410).state);" - - delay: 50ms - - script.execute: query_params_ld2410 - - delay: 50ms - - script.execute: config_off_ld2410 - - platform: template - name: "Human Clear Delay" - id: none_duration_ld2410 - unit_of_measurement: "s" - icon: "mdi:timer" - min_value: 0 - max_value: 900 - step: 1 - mode: box - update_interval: never - optimistic: true - entity_category: config - set_action: - - script.execute: config_on_ld2410 - - delay: 50ms - - lambda: "ld2410_ld2410component_id->set_max_distances_timeout(id(distance_range_ld2410).state/0.75,x);" - - delay: 50ms - - script.execute: query_params_ld2410 - - delay: 50ms - - script.execute: config_off_ld2410 - - platform: template - name: "Moving Human Sensitivity Threshold" - id: moving_sensitivity_threshold_ld2410 - unit_of_measurement: "%" - icon: "mdi:car-cruise-control" - min_value: 0 - max_value: 100 - step: 1 - mode: box - update_interval: never - optimistic: true - entity_category: config - set_action: - - script.execute: config_on_ld2410 - - delay: 50ms - - lambda: "ld2410_ld2410component_id->set_thresholds(x,id(still_sensitivity_threshold_ld2410).state);" - - delay: 50ms - - script.execute: query_params_ld2410 - - delay: 50ms - - script.execute: config_off_ld2410 - - platform: template - name: "Still Human Sensitivity Threshold" - id: still_sensitivity_threshold_ld2410 - unit_of_measurement: "%" - icon: "mdi:car-cruise-control" - min_value: 0 - max_value: 100 - step: 1 - mode: box - update_interval: never - optimistic: true - entity_category: config - set_action: - - script.execute: config_on_ld2410 - - delay: 50ms - - lambda: "ld2410_ld2410component_id->set_thresholds(id(moving_sensitivity_threshold_ld2410).state,x);" - - delay: 50ms - - script.execute: query_params_ld2410 - - delay: 50ms - - script.execute: config_off_ld2410 - - platform: template - name: "Temperature Offset" - id: temperature_offset - unit_of_measurement: "°C" - min_value: -50 - max_value: 50 - step: 0.1 - mode: box - update_interval: never - optimistic: true - restore_value: true - initial_value: 0 - icon: "mdi:thermometer" - entity_category: config - - platform: template - name: "Humidity Offset" - id: humidity_offset - unit_of_measurement: "%" - min_value: -50 - max_value: 50 - step: 0.1 - mode: box - update_interval: never - optimistic: true - restore_value: true - initial_value: 0 - icon: "mdi:water-percent" - entity_category: config - - platform: template - name: "Illuminance Offset" - id: illuminance_offset - unit_of_measurement: "lx" - min_value: -50 - max_value: 50 - step: 1 - mode: box - update_interval: never - optimistic: true - restore_value: true - initial_value: 0 - icon: "mdi:brightness-5" - entity_category: config - -button: - - platform: restart - name: "Restart" - entity_category: diagnostic - - platform: template - name: "Restart ${ld2410_name}" - entity_category: diagnostic - icon: "mdi:restart" - on_press: - script.execute: reboot_ld2410 - - platform: template - name: "Factory Reset ${ld2410_name}" - icon: "mdi:restart-alert" - entity_category: config - disabled_by_default: true - on_press: - - script.execute: factory_reset_ld2410 - - platform: factory_reset - name: "Factory Reset" - icon: "mdi:restart-alert" - entity_category: config - disabled_by_default: true - -script: - - id: config_on_ld2410 - then: - - lambda: "ld2410_ld2410component_id->set_config_mode(true);" - - delay: 50ms - - script.execute: clear_targets_ld2410 - - id: config_off_ld2410 - then: - - lambda: "ld2410_ld2410component_id->set_config_mode(false);" - - id: query_params_ld2410 - then: - - lambda: "ld2410_ld2410component_id->query_parameters();" - - id: get_config_ld2410 - then: - - script.execute: config_on_ld2410 - - delay: 50ms - - script.execute: query_params_ld2410 - - delay: 50ms - - script.execute: config_off_ld2410 - - id: set_thresholds_ld2410 - then: - - lambda: "ld2410_ld2410component_id->set_thresholds(id(moving_sensitivity_threshold_ld2410).state,id(still_sensitivity_threshold_ld2410).state);" - - id: reboot_ld2410 - then: - - script.execute: clear_targets_ld2410 - - lambda: "ld2410_ld2410component_id->reboot();" - - delay: 500ms - - script.execute: get_config_ld2410 - - id: factory_reset_ld2410 - then: - - script.execute: config_on_ld2410 - - delay: 100ms - - lambda: "ld2410_ld2410component_id->factory_reset();" - - delay: 150ms - - lambda: "ld2410_ld2410component_id->reboot();" - - delay: 500ms - - script.execute: config_on_ld2410 - - delay: 50ms - - script.execute: query_params_ld2410 - - delay: 50ms - - script.execute: set_thresholds_ld2410 - - delay: 50ms - - script.execute: config_off_ld2410 - - id: clear_targets_ld2410 - then: - - lambda: |- - id(moving_target_distance_ld2410).publish_state(0); - id(moving_target_energy_ld2410).publish_state(0); - id(still_target_distance_ld2410).publish_state(0); - id(still_target_energy_ld2410).publish_state(0); - id(target_detect_distance_ld2410).publish_state(0); +## Unity by LoopOn +## https://loopon.tech/products/unity-sensor + +substitutions: + name: unity + device_name: Unity + device_make: LoopOn + sw_version: "2.0.5" + bh1750_addr: "0x23" # Addr pad unsoldered=0x23 / soldered=0x5C + ld2410_name: mmWave + +esphome: + name: "${name}" + friendly_name: "${device_name}" + comment: "${device_name} by ${device_make}" + name_add_mac_suffix: true + min_version: "2024.9.2" + project: + name: "${device_make}.${device_name}" + version: "${sw_version}" + platformio_options: + board_build.mcu: esp32c3 + board_build.variant: esp32c3 + board_build.flash_mode: dio + board_build.f_cpu: 160000000L + board_build.f_flash: 80000000L + board_build.flash_size: 4MB + build_flags: -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=1 -DARDUINO_ESP32C3_DEV=1 + upload_speed: 115200 + on_boot: + priority: 600 + then: + - light.turn_on: + id: rgb_light + effect: "Boot Sequence" + red: 100% + green: 100% + blue: 100% + - delay: 2000ms + - light.turn_on: + id: rgb_light + effect: none + - light.turn_off: + id: rgb_light + - lambda: "ld2410_ld2410component_id->set_numbers(distance_range_ld2410,none_duration_ld2410,moving_sensitivity_threshold_ld2410,still_sensitivity_threshold_ld2410);" + - script.execute: config_on_ld2410 + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: set_thresholds_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + +esp32: + board: esp32-c3-devkitm-1 + variant: esp32c3 + framework: + type: arduino + +dashboard_import: + package_import_url: github://LoopOnCode/UnitySensor/esphome/loopon_unity_2.yaml@main + import_full_config: false + +external_components: + - source: github://LoopOnCode/UnitySensor@main + components: [ ld2410 ] + +ld2410: + +logger: + +api: + +ota: + platform: esphome + +wifi: + fast_connect: false + output_power: 10 + enable_on_boot: true + power_save_mode: LIGHT + ap: + on_connect: + - delay: 5s # Gives time for improv results to be transmitted + - ble.disable: + on_disconnect: + - ble.enable: + +captive_portal: + +uart: + id: ld2410_uart + tx_pin: GPIO21 + rx_pin: GPIO20 + baud_rate: 256000 + parity: NONE + stop_bits: 1 + +esp32_improv: + authorizer: none + status_indicator: improv_status + +improv_serial: + +i2c: + sda: GPIO5 + scl: GPIO6 + scan: false + +light: + - platform: neopixelbus + id: rgb_light + type: GRB + variant: WS2812 + pin: GPIO2 + num_leds: 1 + name: "Light" + gamma_correct: 0 + restore_mode: RESTORE_DEFAULT_OFF + effects: + - addressable_rainbow: + name: "Boot Sequence" + speed: 50 + width: 1 + +output: + - platform: template + id: improv_status + type: binary + write_action: + - light.control: + id: rgb_light + state: !lambda return state; + +text_sensor: + - platform: template + name: "Config Version" + lambda: return {"${sw_version}"}; + icon: "mdi:tag" + entity_category: diagnostic + - platform: wifi_info + ip_address: + id: ip_address + name: "IP Address" + icon: "mdi:wan" + +binary_sensor: + - platform: ld2410 + has_target: + name: "Has Human Target" + has_moving_target: + name: "Has Moving Human Target" + has_still_target: + name: "Has Still Human Target" + - platform: gpio + id: boot_button + icon: "mdi:button-pointer" + pin: + number: GPIO9 + inverted: true + mode: + input: true + pullup: true + name: "Button" + +sensor: + - platform: template + id: internal_temp + name: "Internal Temperature" + icon: "mdi:thermometer" + unit_of_measurement: "°C" + entity_category: diagnostic + disabled_by_default: true + lambda: return temperatureRead(); + - platform: wifi_signal + name: "WiFi Signal" + update_interval: 60s + - platform: hdc1080 + temperature: + name: "Temperature" + filters: + - skip_initial: 3 + - median: + window_size: 15 + send_every: 5 + send_first_at: 1 + - lambda: "return x+id(temperature_offset).state-10;" + humidity: + name: "Humidity" + filters: + - median + - lambda: "return x+id(humidity_offset).state;" + - clamp: + min_value: 0 + max_value: 100 + update_interval: 12s + - platform: bh1750 + name: "Illuminance" + address: ${bh1750_addr} + filters: + - lambda: "return x+id(illuminance_offset).state;" + update_interval: 60s + - platform: ld2410 + moving_distance: + name: "Moving Human Distance" + id: moving_target_distance_ld2410 + still_distance: + name: "Still Human Distance" + id: still_target_distance_ld2410 + moving_energy: + name: "Moving Human Energy" + id: moving_target_energy_ld2410 + still_energy: + name: "Still Human Energy" + id: still_target_energy_ld2410 + detection_distance: + name: "Human Detection Distance" + id: target_detect_distance_ld2410 + +number: + - platform: template + name: "Human Distance Range" + id: distance_range_ld2410 + unit_of_measurement: "m" + icon: "mdi:arrow-left-right" + min_value: 0.75 + max_value: 6 + step: 0.75 + mode: box + update_interval: never + optimistic: true + entity_category: config + set_action: + - script.execute: config_on_ld2410 + - delay: 50ms + - lambda: "ld2410_ld2410component_id->set_max_distances_timeout(x/0.75,id(none_duration_ld2410).state);" + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - platform: template + name: "Human Clear Delay" + id: none_duration_ld2410 + unit_of_measurement: "s" + icon: "mdi:timer" + min_value: 0 + max_value: 900 + step: 1 + mode: box + update_interval: never + optimistic: true + entity_category: config + set_action: + - script.execute: config_on_ld2410 + - delay: 50ms + - lambda: "ld2410_ld2410component_id->set_max_distances_timeout(id(distance_range_ld2410).state/0.75,x);" + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - platform: template + name: "Moving Human Sensitivity Threshold" + id: moving_sensitivity_threshold_ld2410 + unit_of_measurement: "%" + icon: "mdi:car-cruise-control" + min_value: 0 + max_value: 100 + step: 1 + mode: box + update_interval: never + optimistic: true + entity_category: config + set_action: + - script.execute: config_on_ld2410 + - delay: 50ms + - lambda: "ld2410_ld2410component_id->set_thresholds(x,id(still_sensitivity_threshold_ld2410).state);" + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - platform: template + name: "Still Human Sensitivity Threshold" + id: still_sensitivity_threshold_ld2410 + unit_of_measurement: "%" + icon: "mdi:car-cruise-control" + min_value: 0 + max_value: 100 + step: 1 + mode: box + update_interval: never + optimistic: true + entity_category: config + set_action: + - script.execute: config_on_ld2410 + - delay: 50ms + - lambda: "ld2410_ld2410component_id->set_thresholds(id(moving_sensitivity_threshold_ld2410).state,x);" + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - platform: template + name: "Temperature Offset" + id: temperature_offset + unit_of_measurement: "°C" + min_value: -50 + max_value: 50 + step: 0.1 + mode: box + update_interval: never + optimistic: true + restore_value: true + initial_value: 0 + icon: "mdi:thermometer" + entity_category: config + - platform: template + name: "Humidity Offset" + id: humidity_offset + unit_of_measurement: "%" + min_value: -50 + max_value: 50 + step: 0.1 + mode: box + update_interval: never + optimistic: true + restore_value: true + initial_value: 0 + icon: "mdi:water-percent" + entity_category: config + - platform: template + name: "Illuminance Offset" + id: illuminance_offset + unit_of_measurement: "lx" + min_value: -50 + max_value: 50 + step: 1 + mode: box + update_interval: never + optimistic: true + restore_value: true + initial_value: 0 + icon: "mdi:brightness-5" + entity_category: config + +button: + - platform: restart + name: "Restart" + entity_category: diagnostic + - platform: template + name: "Restart ${ld2410_name}" + entity_category: diagnostic + icon: "mdi:restart" + on_press: + script.execute: reboot_ld2410 + - platform: template + name: "Factory Reset ${ld2410_name}" + icon: "mdi:restart-alert" + entity_category: config + disabled_by_default: true + on_press: + - script.execute: factory_reset_ld2410 + - platform: factory_reset + name: "Factory Reset" + icon: "mdi:restart-alert" + entity_category: config + disabled_by_default: true + +script: + - id: config_on_ld2410 + then: + - lambda: "ld2410_ld2410component_id->set_config_mode(true);" + - delay: 50ms + - script.execute: clear_targets_ld2410 + - id: config_off_ld2410 + then: + - lambda: "ld2410_ld2410component_id->set_config_mode(false);" + - id: query_params_ld2410 + then: + - lambda: "ld2410_ld2410component_id->query_parameters();" + - id: get_config_ld2410 + then: + - script.execute: config_on_ld2410 + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - id: set_thresholds_ld2410 + then: + - lambda: "ld2410_ld2410component_id->set_thresholds(id(moving_sensitivity_threshold_ld2410).state,id(still_sensitivity_threshold_ld2410).state);" + - id: reboot_ld2410 + then: + - script.execute: clear_targets_ld2410 + - lambda: "ld2410_ld2410component_id->reboot();" + - delay: 500ms + - script.execute: get_config_ld2410 + - id: factory_reset_ld2410 + then: + - script.execute: config_on_ld2410 + - delay: 100ms + - lambda: "ld2410_ld2410component_id->factory_reset();" + - delay: 150ms + - lambda: "ld2410_ld2410component_id->reboot();" + - delay: 500ms + - script.execute: config_on_ld2410 + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: set_thresholds_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - id: clear_targets_ld2410 + then: + - lambda: |- + id(moving_target_distance_ld2410).publish_state(0); + id(moving_target_energy_ld2410).publish_state(0); + id(still_target_distance_ld2410).publish_state(0); + id(still_target_energy_ld2410).publish_state(0); + id(target_detect_distance_ld2410).publish_state(0); diff --git a/esphome/loopon_unity_esp_idf.yaml b/esphome/loopon_unity_esp_idf.yaml new file mode 100644 index 0000000..ec0913e --- /dev/null +++ b/esphome/loopon_unity_esp_idf.yaml @@ -0,0 +1,405 @@ +# Unity by LoopOn +# https://loopon.tech/products/unity-sensor +# Modified to use ESP-IDF framework to reduce binary size + +substitutions: + name: unity + device_name: Unity + device_make: LoopOn + sw_version: "1.2.17" + bh1750_addr: "0x23" # Addr pad unsoldered=0x23 / soldered=0x5C + ld2410_name: mmWave + +esphome: + name: "${name}" + friendly_name: "${device_name}" + comment: "${device_name} by ${device_make}" + name_add_mac_suffix: true + min_version: "2024.9.2" + project: + name: "${device_make}.${device_name}" + version: "${sw_version}" + platformio_options: + board_build.mcu: esp32c3 + board_build.variant: esp32c3 + board_build.flash_mode: dio + board_build.f_cpu: 160000000L + board_build.f_flash: 80000000L + board_build.flash_size: 4MB + on_boot: + priority: 600 + then: + - light.turn_on: + id: rgb_light + effect: "Boot Sequence" + red: 100% + green: 100% + blue: 100% + - delay: 2000ms + - light.turn_off: + id: rgb_light + - lambda: "ld2410_ld2410component_id->set_numbers(distance_range_ld2410,none_duration_ld2410,moving_sensitivity_threshold_ld2410,still_sensitivity_threshold_ld2410);" + - script.execute: config_on_ld2410 + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: set_thresholds_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + +esp32: + board: esp32-c3-devkitm-1 + variant: esp32c3 + framework: + type: esp-idf # Changed from arduino to esp-idf to reduce flash usage + +dashboard_import: + package_import_url: github://LoopOnCode/UnitySensor/esphome/loopon_unity_esp_idf.yaml@main + import_full_config: false + +external_components: + - source: github://LoopOnCode/UnitySensor@main + components: [ ld2410 ] + +ld2410: + +logger: + +api: + +ota: + platform: esphome + +wifi: + fast_connect: false + enable_on_boot: true + power_save_mode: LIGHT + ap: + on_connect: + - delay: 5s # Gives time for improv results to be transmitted + - ble.disable: + on_disconnect: + - ble.enable: + +captive_portal: + +uart: + id: ld2410_uart + tx_pin: GPIO21 + rx_pin: GPIO20 + baud_rate: 256000 + parity: NONE + stop_bits: 1 + +esp32_improv: + authorizer: none + status_indicator: improv_status + +improv_serial: + +i2c: + sda: GPIO5 + scl: GPIO6 + scan: false + +# Using ESP-IDF compatible light component instead of neopixelbus +light: + - platform: esp32_rmt_led_strip + id: rgb_light + pin: GPIO2 + num_leds: 1 + rgb_order: GRB + chipset: WS2812 + name: "${device_name} Light" + restore_mode: RESTORE_DEFAULT_OFF + effects: + - addressable_rainbow: + name: "Rainbow" + speed: 10 # Slower speed for more visible color transitions + width: 5 # Wider bands of color + - addressable_rainbow: + name: "Fast Rainbow" + speed: 50 + width: 1 + - addressable_rainbow: + name: "Boot Sequence" + speed: 30 + width: 3 + +output: + - platform: template + id: improv_status + type: binary + write_action: + - light.control: + id: rgb_light + state: !lambda return state; + +text_sensor: + - platform: template + name: "${device_name} Config Version" + lambda: return {"${sw_version}"}; + icon: "mdi:tag" + entity_category: diagnostic + - platform: wifi_info + ip_address: + id: ip_address + name: "${device_name} IP Address" + icon: "mdi:wan" + +binary_sensor: + - platform: ld2410 + has_target: + name: "${device_name} Has Human Target" + has_moving_target: + name: "${device_name} Has Moving Human Target" + has_still_target: + name: "${device_name} Has Still Human Target" + - platform: gpio + id: boot_button + icon: "mdi:button-pointer" + pin: + number: GPIO9 + inverted: true + mode: + input: true + pullup: true + name: "${device_name} Button" + +sensor: + - platform: internal_temperature + name: "${device_name} Internal Temperature" + id: internal_temp + icon: "mdi:thermometer" + unit_of_measurement: "°C" + entity_category: diagnostic + disabled_by_default: false + - platform: wifi_signal + name: "${device_name} WiFi Signal" + update_interval: 60s + - platform: hdc1080 + temperature: + name: "${device_name} Temperature" + filters: + - median + - lambda: "return x-(abs(id(internal_temp).state-x)/2)+id(temperature_offset).state;" + humidity: + name: "${device_name} Humidity" + filters: + - median + - lambda: "return x+id(humidity_offset).state;" + - clamp: + min_value: 0 + max_value: 100 + update_interval: 12s + - platform: bh1750 + name: "${device_name} Illuminance" + address: ${bh1750_addr} + filters: + - lambda: "return x+id(illuminance_offset).state;" + update_interval: 60s + - platform: ld2410 + moving_distance: + name: "${device_name} Moving Human Distance" + id: moving_target_distance_ld2410 + still_distance: + name: "${device_name} Still Human Distance" + id: still_target_distance_ld2410 + moving_energy: + name: "${device_name} Moving Human Energy" + id: moving_target_energy_ld2410 + still_energy: + name: "${device_name} Still Human Energy" + id: still_target_energy_ld2410 + detection_distance: + name: "${device_name} Human Detection Distance" + id: target_detect_distance_ld2410 + +number: + - platform: template + name: "${device_name} Human Distance Range" + id: distance_range_ld2410 + unit_of_measurement: "m" + icon: "mdi:arrow-left-right" + min_value: 0.75 + max_value: 6 + step: 0.75 + mode: box + update_interval: never + optimistic: true + entity_category: config + set_action: + - script.execute: config_on_ld2410 + - delay: 50ms + - lambda: "ld2410_ld2410component_id->set_max_distances_timeout(x/0.75,id(none_duration_ld2410).state);" + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - platform: template + name: "${device_name} Human Clear Delay" + id: none_duration_ld2410 + unit_of_measurement: "s" + icon: "mdi:timer" + min_value: 0 + max_value: 900 + step: 1 + mode: box + update_interval: never + optimistic: true + entity_category: config + set_action: + - script.execute: config_on_ld2410 + - delay: 50ms + - lambda: "ld2410_ld2410component_id->set_max_distances_timeout(id(distance_range_ld2410).state/0.75,x);" + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - platform: template + name: "${device_name} Moving Human Sensitivity Threshold" + id: moving_sensitivity_threshold_ld2410 + unit_of_measurement: "%" + icon: "mdi:car-cruise-control" + min_value: 0 + max_value: 100 + step: 1 + mode: box + update_interval: never + optimistic: true + entity_category: config + set_action: + - script.execute: config_on_ld2410 + - delay: 50ms + - lambda: "ld2410_ld2410component_id->set_thresholds(x,id(still_sensitivity_threshold_ld2410).state);" + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - platform: template + name: "${device_name} Still Human Sensitivity Threshold" + id: still_sensitivity_threshold_ld2410 + unit_of_measurement: "%" + icon: "mdi:car-cruise-control" + min_value: 0 + max_value: 100 + step: 1 + mode: box + update_interval: never + optimistic: true + entity_category: config + set_action: + - script.execute: config_on_ld2410 + - delay: 50ms + - lambda: "ld2410_ld2410component_id->set_thresholds(id(moving_sensitivity_threshold_ld2410).state,x);" + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - platform: template + name: "${device_name} Temperature Offset" + id: temperature_offset + unit_of_measurement: "°C" + min_value: -50 + max_value: 50 + step: 0.1 + mode: box + update_interval: never + optimistic: true + restore_value: true + initial_value: -3 + icon: "mdi:thermometer" + entity_category: config + - platform: template + name: "${device_name} Humidity Offset" + id: humidity_offset + unit_of_measurement: "%" + min_value: -50 + max_value: 50 + step: 0.1 + mode: box + update_interval: never + optimistic: true + restore_value: true + initial_value: 0 + icon: "mdi:water-percent" + entity_category: config + - platform: template + name: "${device_name} Illuminance Offset" + id: illuminance_offset + unit_of_measurement: "lx" + min_value: -50 + max_value: 50 + step: 1 + mode: box + update_interval: never + optimistic: true + restore_value: true + initial_value: 0 + icon: "mdi:brightness-5" + entity_category: config + +button: + - platform: restart + name: "${device_name} Restart" + entity_category: diagnostic + - platform: template + name: "${device_name} Restart ${ld2410_name}" + entity_category: diagnostic + icon: "mdi:restart" + on_press: + script.execute: reboot_ld2410 + - platform: template + name: "${device_name} Factory Reset ${ld2410_name}" + icon: "mdi:restart-alert" + entity_category: config + disabled_by_default: true + on_press: + - script.execute: factory_reset_ld2410 + - platform: factory_reset + name: "${device_name} Factory Reset" + icon: "mdi:restart-alert" + entity_category: config + disabled_by_default: true + +script: + - id: config_on_ld2410 + then: + - lambda: "ld2410_ld2410component_id->set_config_mode(true);" + - delay: 100ms + # In ESP-IDF, clear_targets is not available, but a longer delay and subsequent + # operations may help achieve a similar reset effect + - id: config_off_ld2410 + then: + - lambda: "ld2410_ld2410component_id->set_config_mode(false);" + - id: query_params_ld2410 + then: + - lambda: "ld2410_ld2410component_id->query_parameters();" + - id: get_config_ld2410 + then: + - script.execute: config_on_ld2410 + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - id: set_thresholds_ld2410 + then: + - lambda: "ld2410_ld2410component_id->set_thresholds(id(moving_sensitivity_threshold_ld2410).state,id(still_sensitivity_threshold_ld2410).state);" + - id: reboot_ld2410 + then: + # Removed clear_targets_ld2410 script reference as it's not supported in ESP-IDF + - lambda: "ld2410_ld2410component_id->reboot();" + - delay: 500ms + - script.execute: get_config_ld2410 + - id: factory_reset_ld2410 + then: + - script.execute: config_on_ld2410 + - delay: 100ms + - lambda: "ld2410_ld2410component_id->factory_reset();" + - delay: 150ms + - lambda: "ld2410_ld2410component_id->reboot();" + - delay: 500ms + - script.execute: config_on_ld2410 + - delay: 50ms + - script.execute: query_params_ld2410 + # Removed clear_targets_ld2410 script as it's not supported in ESP-IDF diff --git a/esphome/loopon_unity_no_power_save.yaml b/esphome/loopon_unity_no_power_save.yaml index f4301bd..51846d2 100644 --- a/esphome/loopon_unity_no_power_save.yaml +++ b/esphome/loopon_unity_no_power_save.yaml @@ -1,392 +1,392 @@ -## Unity by LoopOn -## https://loopon.tech/products/unity-sensor - -substitutions: - name: unity - device_name: Unity - device_make: LoopOn - sw_version: "1.2.16" - bh1750_addr: "0x23" # Addr pad unsoldered=0x23 / soldered=0x5C - ld2410_name: mmWave - -esphome: - name: "${name}" - friendly_name: "${device_name}" - comment: "${device_name} by ${device_make}" - name_add_mac_suffix: true - min_version: "2024.9.2" - project: - name: "${device_make}.${device_name}" - version: "${sw_version}" - platformio_options: - board_build.mcu: esp32c3 - board_build.variant: esp32c3 - board_build.flash_mode: dio - board_build.f_cpu: 160000000L - board_build.f_flash: 80000000L - board_build.flash_size: 4MB - build_flags: -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=1 -DARDUINO_ESP32C3_DEV=1 - upload_speed: 115200 - on_boot: - priority: 600 - then: - - light.turn_on: - id: rgb_light - effect: "Boot Sequence" - red: 100% - green: 100% - blue: 100% - - delay: 2000ms - - light.turn_on: - id: rgb_light - effect: none - - light.turn_off: - id: rgb_light - - lambda: "ld2410_ld2410component_id->set_numbers(distance_range_ld2410,none_duration_ld2410,moving_sensitivity_threshold_ld2410,still_sensitivity_threshold_ld2410);" - - script.execute: config_on_ld2410 - - delay: 50ms - - script.execute: query_params_ld2410 - - delay: 50ms - - script.execute: set_thresholds_ld2410 - - delay: 50ms - - script.execute: config_off_ld2410 - -esp32: - board: esp32-c3-devkitm-1 - variant: esp32c3 - framework: - type: arduino - -dashboard_import: - package_import_url: github://LoopOnCode/UnitySensor/esphome/loopon_unity_no_power_save.yaml@main - import_full_config: false - -external_components: - - source: github://LoopOnCode/UnitySensor@main - components: [ ld2410 ] - -ld2410: - -logger: - -api: - -ota: - platform: esphome - -wifi: - fast_connect: false - enable_on_boot: true - power_save_mode: none - ap: - -captive_portal: - -uart: - id: ld2410_uart - tx_pin: GPIO21 - rx_pin: GPIO20 - baud_rate: 256000 - parity: NONE - stop_bits: 1 - -i2c: - sda: GPIO5 - scl: GPIO6 - scan: false - -light: - - platform: neopixelbus - id: rgb_light - type: GRB - variant: WS2812 - pin: GPIO2 - num_leds: 1 - name: "${device_name} Light" - gamma_correct: 0 - restore_mode: RESTORE_DEFAULT_OFF - effects: - - addressable_rainbow: - name: "Boot Sequence" - speed: 50 - width: 1 - -text_sensor: - - platform: template - name: "${device_name} Config Version" - lambda: return {"${sw_version}"}; - icon: "mdi:tag" - entity_category: diagnostic - - platform: wifi_info - ip_address: - id: ip_address - name: "${device_name} IP Address" - icon: "mdi:wan" - -binary_sensor: - - platform: ld2410 - has_target: - name: "${device_name} Has Human Target" - has_moving_target: - name: "${device_name} Has Moving Human Target" - has_still_target: - name: "${device_name} Has Still Human Target" - - platform: gpio - id: boot_button - icon: "mdi:button-pointer" - pin: - number: GPIO9 - inverted: true - mode: - input: true - pullup: true - name: "${device_name} Button" - -sensor: - - platform: template - id: internal_temp - name: "${device_name} Internal Temperature" - icon: "mdi:thermometer" - unit_of_measurement: "°C" - entity_category: diagnostic - disabled_by_default: true - lambda: return temperatureRead(); - - platform: wifi_signal - name: "${device_name} WiFi Signal" - update_interval: 60s - - platform: hdc1080 - temperature: - name: "${device_name} Temperature" - filters: - - median - - lambda: "return x-(abs(id(internal_temp).state-x)/2)+id(temperature_offset).state;" - humidity: - name: "${device_name} Humidity" - filters: - - median - - lambda: "return x+id(humidity_offset).state;" - - clamp: - min_value: 0 - max_value: 100 - update_interval: 12s - - platform: bh1750 - name: "${device_name} Illuminance" - address: ${bh1750_addr} - filters: - - lambda: "return x+id(illuminance_offset).state;" - update_interval: 60s - - platform: ld2410 - moving_distance: - name : "${device_name} Moving Human Distance" - id: moving_target_distance_ld2410 - still_distance: - name: "${device_name} Still Human Distance" - id: still_target_distance_ld2410 - moving_energy: - name: "${device_name} Moving Human Energy" - id: moving_target_energy_ld2410 - still_energy: - name: "${device_name} Still Human Energy" - id: still_target_energy_ld2410 - detection_distance: - name: "${device_name} Human Detection Distance" - id: target_detect_distance_ld2410 - -number: - - platform: template - name: "${device_name} Human Distance Range" - id: distance_range_ld2410 - unit_of_measurement: "m" - icon: "mdi:arrow-left-right" - min_value: 0.75 - max_value: 6 - step: 0.75 - mode: box - update_interval: never - optimistic: true - entity_category: config - set_action: - - script.execute: config_on_ld2410 - - delay: 50ms - - lambda: "ld2410_ld2410component_id->set_max_distances_timeout(x/0.75,id(none_duration_ld2410).state);" - - delay: 50ms - - script.execute: query_params_ld2410 - - delay: 50ms - - script.execute: config_off_ld2410 - - platform: template - name: "${device_name} Human Clear Delay" - id: none_duration_ld2410 - unit_of_measurement: "s" - icon: "mdi:timer" - min_value: 0 - max_value: 900 - step: 1 - mode: box - update_interval: never - optimistic: true - entity_category: config - set_action: - - script.execute: config_on_ld2410 - - delay: 50ms - - lambda: "ld2410_ld2410component_id->set_max_distances_timeout(id(distance_range_ld2410).state/0.75,x);" - - delay: 50ms - - script.execute: query_params_ld2410 - - delay: 50ms - - script.execute: config_off_ld2410 - - platform: template - name: "${device_name} Moving Human Sensitivity Threshold" - id: moving_sensitivity_threshold_ld2410 - unit_of_measurement: "%" - icon: "mdi:car-cruise-control" - min_value: 0 - max_value: 100 - step: 1 - mode: box - update_interval: never - optimistic: true - entity_category: config - set_action: - - script.execute: config_on_ld2410 - - delay: 50ms - - lambda: "ld2410_ld2410component_id->set_thresholds(x,id(still_sensitivity_threshold_ld2410).state);" - - delay: 50ms - - script.execute: query_params_ld2410 - - delay: 50ms - - script.execute: config_off_ld2410 - - platform: template - name: "${device_name} Still Human Sensitivity Threshold" - id: still_sensitivity_threshold_ld2410 - unit_of_measurement: "%" - icon: "mdi:car-cruise-control" - min_value: 0 - max_value: 100 - step: 1 - mode: box - update_interval: never - optimistic: true - entity_category: config - set_action: - - script.execute: config_on_ld2410 - - delay: 50ms - - lambda: "ld2410_ld2410component_id->set_thresholds(id(moving_sensitivity_threshold_ld2410).state,x);" - - delay: 50ms - - script.execute: query_params_ld2410 - - delay: 50ms - - script.execute: config_off_ld2410 - - platform: template - name: "${device_name} Temperature Offset" - id: temperature_offset - unit_of_measurement: "°C" - min_value: -50 - max_value: 50 - step: 0.1 - mode: box - update_interval: never - optimistic: true - restore_value: true - initial_value: -3 - icon: "mdi:thermometer" - entity_category: config - - platform: template - name: "${device_name} Humidity Offset" - id: humidity_offset - unit_of_measurement: "%" - min_value: -50 - max_value: 50 - step: 0.1 - mode: box - update_interval: never - optimistic: true - restore_value: true - initial_value: 0 - icon: "mdi:water-percent" - entity_category: config - - platform: template - name: "${device_name} Illuminance Offset" - id: illuminance_offset - unit_of_measurement: "lx" - min_value: -50 - max_value: 50 - step: 1 - mode: box - update_interval: never - optimistic: true - restore_value: true - initial_value: 0 - icon: "mdi:brightness-5" - entity_category: config - -button: - - platform: restart - name: "${device_name} Restart" - entity_category: diagnostic - - platform: template - name: "${device_name} Restart ${ld2410_name}" - entity_category: diagnostic - icon: "mdi:restart" - on_press: - script.execute: reboot_ld2410 - - platform: template - name: "${device_name} Factory Reset ${ld2410_name}" - icon: "mdi:restart-alert" - entity_category: config - disabled_by_default: true - on_press: - - script.execute: factory_reset_ld2410 - - platform: factory_reset - name: "${device_name} Factory Reset" - icon: "mdi:restart-alert" - entity_category: config - disabled_by_default: true - -script: - - id: config_on_ld2410 - then: - - lambda: "ld2410_ld2410component_id->set_config_mode(true);" - - delay: 50ms - - script.execute: clear_targets_ld2410 - - id: config_off_ld2410 - then: - - lambda: "ld2410_ld2410component_id->set_config_mode(false);" - - id: query_params_ld2410 - then: - - lambda: "ld2410_ld2410component_id->query_parameters();" - - id: get_config_ld2410 - then: - - script.execute: config_on_ld2410 - - delay: 50ms - - script.execute: query_params_ld2410 - - delay: 50ms - - script.execute: config_off_ld2410 - - id: set_thresholds_ld2410 - then: - - lambda: "ld2410_ld2410component_id->set_thresholds(id(moving_sensitivity_threshold_ld2410).state,id(still_sensitivity_threshold_ld2410).state);" - - id: reboot_ld2410 - then: - - script.execute: clear_targets_ld2410 - - lambda: "ld2410_ld2410component_id->reboot();" - - delay: 500ms - - script.execute: get_config_ld2410 - - id: factory_reset_ld2410 - then: - - script.execute: config_on_ld2410 - - delay: 100ms - - lambda: "ld2410_ld2410component_id->factory_reset();" - - delay: 150ms - - lambda: "ld2410_ld2410component_id->reboot();" - - delay: 500ms - - script.execute: config_on_ld2410 - - delay: 50ms - - script.execute: query_params_ld2410 - - delay: 50ms - - script.execute: set_thresholds_ld2410 - - delay: 50ms - - script.execute: config_off_ld2410 - - id: clear_targets_ld2410 - then: - - lambda: |- - id(moving_target_distance_ld2410).publish_state(0); - id(moving_target_energy_ld2410).publish_state(0); - id(still_target_distance_ld2410).publish_state(0); - id(still_target_energy_ld2410).publish_state(0); - id(target_detect_distance_ld2410).publish_state(0); +# Unity by LoopOn +# https://loopon.tech/products/unity-sensor + +substitutions: + name: unity + device_name: Unity + device_make: LoopOn + sw_version: "1.2.16" + bh1750_addr: "0x23" # Addr pad unsoldered=0x23 / soldered=0x5C + ld2410_name: mmWave + +esphome: + name: "${name}" + friendly_name: "${device_name}" + comment: "${device_name} by ${device_make}" + name_add_mac_suffix: true + min_version: "2024.9.2" + project: + name: "${device_make}.${device_name}" + version: "${sw_version}" + platformio_options: + board_build.mcu: esp32c3 + board_build.variant: esp32c3 + board_build.flash_mode: dio + board_build.f_cpu: 160000000L + board_build.f_flash: 80000000L + board_build.flash_size: 4MB + build_flags: -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=1 -DARDUINO_ESP32C3_DEV=1 + upload_speed: 115200 + on_boot: + priority: 600 + then: + - light.turn_on: + id: rgb_light + effect: "Boot Sequence" + red: 100% + green: 100% + blue: 100% + - delay: 2000ms + - light.turn_on: + id: rgb_light + effect: none + - light.turn_off: + id: rgb_light + - lambda: "ld2410_ld2410component_id->set_numbers(distance_range_ld2410,none_duration_ld2410,moving_sensitivity_threshold_ld2410,still_sensitivity_threshold_ld2410);" + - script.execute: config_on_ld2410 + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: set_thresholds_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + +esp32: + board: esp32-c3-devkitm-1 + variant: esp32c3 + framework: + type: arduino + +dashboard_import: + package_import_url: github://LoopOnCode/UnitySensor/esphome/loopon_unity_no_power_save.yaml@main + import_full_config: false + +external_components: + - source: github://LoopOnCode/UnitySensor@main + components: [ ld2410 ] + +ld2410: + +logger: + +api: + +ota: + platform: esphome + +wifi: + fast_connect: false + enable_on_boot: true + power_save_mode: none + ap: + +captive_portal: + +uart: + id: ld2410_uart + tx_pin: GPIO21 + rx_pin: GPIO20 + baud_rate: 256000 + parity: NONE + stop_bits: 1 + +i2c: + sda: GPIO5 + scl: GPIO6 + scan: false + +light: + - platform: neopixelbus + id: rgb_light + type: GRB + variant: WS2812 + pin: GPIO2 + num_leds: 1 + name: "${device_name} Light" + gamma_correct: 0 + restore_mode: RESTORE_DEFAULT_OFF + effects: + - addressable_rainbow: + name: "Boot Sequence" + speed: 50 + width: 1 + +text_sensor: + - platform: template + name: "${device_name} Config Version" + lambda: return {"${sw_version}"}; + icon: "mdi:tag" + entity_category: diagnostic + - platform: wifi_info + ip_address: + id: ip_address + name: "${device_name} IP Address" + icon: "mdi:wan" + +binary_sensor: + - platform: ld2410 + has_target: + name: "${device_name} Has Human Target" + has_moving_target: + name: "${device_name} Has Moving Human Target" + has_still_target: + name: "${device_name} Has Still Human Target" + - platform: gpio + id: boot_button + icon: "mdi:button-pointer" + pin: + number: GPIO9 + inverted: true + mode: + input: true + pullup: true + name: "${device_name} Button" + +sensor: + - platform: template + id: internal_temp + name: "${device_name} Internal Temperature" + icon: "mdi:thermometer" + unit_of_measurement: "°C" + entity_category: diagnostic + disabled_by_default: true + lambda: return temperatureRead(); + - platform: wifi_signal + name: "${device_name} WiFi Signal" + update_interval: 60s + - platform: hdc1080 + temperature: + name: "${device_name} Temperature" + filters: + - median + - lambda: "return x-(abs(id(internal_temp).state-x)/2)+id(temperature_offset).state;" + humidity: + name: "${device_name} Humidity" + filters: + - median + - lambda: "return x+id(humidity_offset).state;" + - clamp: + min_value: 0 + max_value: 100 + update_interval: 12s + - platform: bh1750 + name: "${device_name} Illuminance" + address: ${bh1750_addr} + filters: + - lambda: "return x+id(illuminance_offset).state;" + update_interval: 60s + - platform: ld2410 + moving_distance: + name: "${device_name} Moving Human Distance" + id: moving_target_distance_ld2410 + still_distance: + name: "${device_name} Still Human Distance" + id: still_target_distance_ld2410 + moving_energy: + name: "${device_name} Moving Human Energy" + id: moving_target_energy_ld2410 + still_energy: + name: "${device_name} Still Human Energy" + id: still_target_energy_ld2410 + detection_distance: + name: "${device_name} Human Detection Distance" + id: target_detect_distance_ld2410 + +number: + - platform: template + name: "${device_name} Human Distance Range" + id: distance_range_ld2410 + unit_of_measurement: "m" + icon: "mdi:arrow-left-right" + min_value: 0.75 + max_value: 6 + step: 0.75 + mode: box + update_interval: never + optimistic: true + entity_category: config + set_action: + - script.execute: config_on_ld2410 + - delay: 50ms + - lambda: "ld2410_ld2410component_id->set_max_distances_timeout(x/0.75,id(none_duration_ld2410).state);" + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - platform: template + name: "${device_name} Human Clear Delay" + id: none_duration_ld2410 + unit_of_measurement: "s" + icon: "mdi:timer" + min_value: 0 + max_value: 900 + step: 1 + mode: box + update_interval: never + optimistic: true + entity_category: config + set_action: + - script.execute: config_on_ld2410 + - delay: 50ms + - lambda: "ld2410_ld2410component_id->set_max_distances_timeout(id(distance_range_ld2410).state/0.75,x);" + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - platform: template + name: "${device_name} Moving Human Sensitivity Threshold" + id: moving_sensitivity_threshold_ld2410 + unit_of_measurement: "%" + icon: "mdi:car-cruise-control" + min_value: 0 + max_value: 100 + step: 1 + mode: box + update_interval: never + optimistic: true + entity_category: config + set_action: + - script.execute: config_on_ld2410 + - delay: 50ms + - lambda: "ld2410_ld2410component_id->set_thresholds(x,id(still_sensitivity_threshold_ld2410).state);" + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - platform: template + name: "${device_name} Still Human Sensitivity Threshold" + id: still_sensitivity_threshold_ld2410 + unit_of_measurement: "%" + icon: "mdi:car-cruise-control" + min_value: 0 + max_value: 100 + step: 1 + mode: box + update_interval: never + optimistic: true + entity_category: config + set_action: + - script.execute: config_on_ld2410 + - delay: 50ms + - lambda: "ld2410_ld2410component_id->set_thresholds(id(moving_sensitivity_threshold_ld2410).state,x);" + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - platform: template + name: "${device_name} Temperature Offset" + id: temperature_offset + unit_of_measurement: "°C" + min_value: -50 + max_value: 50 + step: 0.1 + mode: box + update_interval: never + optimistic: true + restore_value: true + initial_value: -3 + icon: "mdi:thermometer" + entity_category: config + - platform: template + name: "${device_name} Humidity Offset" + id: humidity_offset + unit_of_measurement: "%" + min_value: -50 + max_value: 50 + step: 0.1 + mode: box + update_interval: never + optimistic: true + restore_value: true + initial_value: 0 + icon: "mdi:water-percent" + entity_category: config + - platform: template + name: "${device_name} Illuminance Offset" + id: illuminance_offset + unit_of_measurement: "lx" + min_value: -50 + max_value: 50 + step: 1 + mode: box + update_interval: never + optimistic: true + restore_value: true + initial_value: 0 + icon: "mdi:brightness-5" + entity_category: config + +button: + - platform: restart + name: "${device_name} Restart" + entity_category: diagnostic + - platform: template + name: "${device_name} Restart ${ld2410_name}" + entity_category: diagnostic + icon: "mdi:restart" + on_press: + script.execute: reboot_ld2410 + - platform: template + name: "${device_name} Factory Reset ${ld2410_name}" + icon: "mdi:restart-alert" + entity_category: config + disabled_by_default: true + on_press: + - script.execute: factory_reset_ld2410 + - platform: factory_reset + name: "${device_name} Factory Reset" + icon: "mdi:restart-alert" + entity_category: config + disabled_by_default: true + +script: + - id: config_on_ld2410 + then: + - lambda: "ld2410_ld2410component_id->set_config_mode(true);" + - delay: 50ms + - script.execute: clear_targets_ld2410 + - id: config_off_ld2410 + then: + - lambda: "ld2410_ld2410component_id->set_config_mode(false);" + - id: query_params_ld2410 + then: + - lambda: "ld2410_ld2410component_id->query_parameters();" + - id: get_config_ld2410 + then: + - script.execute: config_on_ld2410 + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - id: set_thresholds_ld2410 + then: + - lambda: "ld2410_ld2410component_id->set_thresholds(id(moving_sensitivity_threshold_ld2410).state,id(still_sensitivity_threshold_ld2410).state);" + - id: reboot_ld2410 + then: + - script.execute: clear_targets_ld2410 + - lambda: "ld2410_ld2410component_id->reboot();" + - delay: 500ms + - script.execute: get_config_ld2410 + - id: factory_reset_ld2410 + then: + - script.execute: config_on_ld2410 + - delay: 100ms + - lambda: "ld2410_ld2410component_id->factory_reset();" + - delay: 150ms + - lambda: "ld2410_ld2410component_id->reboot();" + - delay: 500ms + - script.execute: config_on_ld2410 + - delay: 50ms + - script.execute: query_params_ld2410 + - delay: 50ms + - script.execute: set_thresholds_ld2410 + - delay: 50ms + - script.execute: config_off_ld2410 + - id: clear_targets_ld2410 + then: + - lambda: |- + id(moving_target_distance_ld2410).publish_state(0); + id(moving_target_energy_ld2410).publish_state(0); + id(still_target_distance_ld2410).publish_state(0); + id(still_target_energy_ld2410).publish_state(0); + id(target_detect_distance_ld2410).publish_state(0);