From 9283a6f085c010bda39524f4341f88508efe26c6 Mon Sep 17 00:00:00 2001 From: Carson Full Date: Sat, 15 Jan 2022 17:15:40 -0600 Subject: [PATCH 01/30] Allow components to set setup priority --- components/roode/__init__.py | 2 +- components/vl53l1x/__init__.py | 51 +++++++++++++++++++--------------- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/components/roode/__init__.py b/components/roode/__init__.py index bcc738d5..692eed22 100644 --- a/components/roode/__init__.py +++ b/components/roode/__init__.py @@ -82,7 +82,7 @@ } ), } -) +).extend(cv.COMPONENT_SCHEMA) async def to_code(config: Dict): diff --git a/components/vl53l1x/__init__.py b/components/vl53l1x/__init__.py index 9a8b25b9..87be14c5 100644 --- a/components/vl53l1x/__init__.py +++ b/components/vl53l1x/__init__.py @@ -72,28 +72,35 @@ def none_to_empty(value): return cv.Any(cv.Schema(*args, **kwargs), none_to_empty) -CONFIG_SCHEMA = cv.Schema( - { - cv.GenerateID(): cv.declare_id(VL53L1X), - cv.Optional(CONF_PINS, default={}): NullableSchema( - { - cv.Optional(CONF_XSHUT): pins.gpio_output_pin_schema, - cv.Optional(CONF_INTERRUPT): pins.internal_gpio_input_pin_schema, - } - ), - cv.Optional(CONF_CALIBRATION, default={}): NullableSchema( - { - cv.Optional(CONF_RANGING_MODE, default=CONF_AUTO): cv.enum( - RANGING_MODES - ), - cv.Optional(CONF_XTALK): cv.All( - int_with_unit("corrected photon count as cps (counts per second)", "(cps)"), cv.uint16_t - ), - cv.Optional(CONF_OFFSET): cv.All(distance_as_mm, int16_t), - } - ), - } -).extend(i2c.i2c_device_schema(0x29)) +CONFIG_SCHEMA = ( + cv.Schema( + { + cv.GenerateID(): cv.declare_id(VL53L1X), + cv.Optional(CONF_PINS, default={}): NullableSchema( + { + cv.Optional(CONF_XSHUT): pins.gpio_output_pin_schema, + cv.Optional(CONF_INTERRUPT): pins.internal_gpio_input_pin_schema, + } + ), + cv.Optional(CONF_CALIBRATION, default={}): NullableSchema( + { + cv.Optional(CONF_RANGING_MODE, default=CONF_AUTO): cv.enum( + RANGING_MODES + ), + cv.Optional(CONF_XTALK): cv.All( + int_with_unit( + "corrected photon count as cps (counts per second)", "(cps)" + ), + cv.uint16_t, + ), + cv.Optional(CONF_OFFSET): cv.All(distance_as_mm, int16_t), + } + ), + } + ) + .extend(i2c.i2c_device_schema(0x29)) + .extend(cv.COMPONENT_SCHEMA) +) async def to_code(config: Dict): From 1f931531a1bdd8db3a5dd4754b24b99442d994f4 Mon Sep 17 00:00:00 2001 From: Carson Full Date: Sat, 15 Jan 2022 17:18:33 -0600 Subject: [PATCH 02/30] Set default setup priority of Roode to "processor" --- components/roode/roode.h | 2 ++ components/vl53l1x/vl53l1x.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/components/roode/roode.h b/components/roode/roode.h index b4a969f5..bc976998 100644 --- a/components/roode/roode.h +++ b/components/roode/roode.h @@ -58,6 +58,8 @@ class Roode : public PollingComponent { void update() override; void loop() override; void dump_config() override; + /** Roode uses data from sensors */ + float get_setup_priority() const override { return setup_priority::PROCESSOR; }; TofSensor *get_tof_sensor() { return this->distanceSensor; } void set_tof_sensor(TofSensor *sensor) { this->distanceSensor = sensor; } diff --git a/components/vl53l1x/vl53l1x.h b/components/vl53l1x/vl53l1x.h index 70fb0ea8..a8970b65 100644 --- a/components/vl53l1x/vl53l1x.h +++ b/components/vl53l1x/vl53l1x.h @@ -21,7 +21,7 @@ class VL53L1X : public i2c::I2CDevice, public Component { public: void setup() override; void dump_config() override; - // After GPIO, but before default...Is this needed? not sure. + /** This connects directly to a sensor */ float get_setup_priority() const override { return setup_priority::DATA; }; optional read_distance(ROI *roi, VL53L1_Error &error); From 91b170c5c06a2f95c378ea22d417666751f5a975 Mon Sep 17 00:00:00 2001 From: Carson Full Date: Sat, 15 Jan 2022 17:22:48 -0600 Subject: [PATCH 03/30] Tweak sensor setup logs --- components/vl53l1x/vl53l1x.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/components/vl53l1x/vl53l1x.cpp b/components/vl53l1x/vl53l1x.cpp index f1afa940..6c58215a 100644 --- a/components/vl53l1x/vl53l1x.cpp +++ b/components/vl53l1x/vl53l1x.cpp @@ -20,31 +20,34 @@ void VL53L1X::dump_config() { } void VL53L1X::setup() { + ESP_LOGD(TAG, "Beginning setup"); + // TODO use xshut_pin, if given, to change address auto status = this->sensor.Begin(this->address_); + ESP_LOGD(TAG, "VL53L1_ULD begin() returned"); if (status != VL53L1_ERROR_NONE) { // If the sensor could not be initialized print out the error code. -7 is timeout - ESP_LOGE(TAG, "Could not initialize the sensor, error code: %d", status); + ESP_LOGE(TAG, "Could not initialize, error code: %d", status); this->mark_failed(); return; } this->address_ = sensor.GetI2CAddress(); if (this->offset.has_value()) { - ESP_LOGI(TAG, "Setting sensor offset calibration to %d", this->offset.value()); + ESP_LOGI(TAG, "Setting offset calibration to %d", this->offset.value()); status = this->sensor.SetOffsetInMm(this->offset.value()); if (status != VL53L1_ERROR_NONE) { - ESP_LOGE(TAG, "Could not set sensor offset calibration, error code: %d", status); + ESP_LOGE(TAG, "Could not set offset calibration, error code: %d", status); this->mark_failed(); return; } } if (this->xtalk.has_value()) { - ESP_LOGI(TAG, "Setting sensor xtalk calibration to %d", this->xtalk.value()); + ESP_LOGI(TAG, "Setting crosstalk calibration to %d", this->xtalk.value()); status = this->sensor.SetXTalk(this->xtalk.value()); if (status != VL53L1_ERROR_NONE) { - ESP_LOGE(TAG, "Could not set sensor offset calibration, error code: %d", status); + ESP_LOGE(TAG, "Could not set crosstalk calibration, error code: %d", status); this->mark_failed(); return; } From 5b11b0dc1c3a32c6c4bca11cbc1365917f2bc3df Mon Sep 17 00:00:00 2001 From: Carson Full Date: Sat, 15 Jan 2022 19:53:57 -0600 Subject: [PATCH 04/30] Prevent panic restart when sensor initialization times out --- components/roode/roode.cpp | 6 ++++++ components/vl53l1x/vl53l1x.cpp | 17 +++++++++++++++++ components/vl53l1x/vl53l1x.h | 1 + 3 files changed, 24 insertions(+) diff --git a/components/roode/roode.cpp b/components/roode/roode.cpp index f2547d98..aaa0c5ab 100644 --- a/components/roode/roode.cpp +++ b/components/roode/roode.cpp @@ -13,6 +13,12 @@ void Roode::setup() { } ESP_LOGI(SETUP, "Using sampling with sampling size: %d", samples); + if (this->distanceSensor->is_failed()) { + this->mark_failed(); + ESP_LOGE(TAG, "Roode cannot be setup without a valid VL53L1X sensor"); + return; + } + calibrate_zones(); } diff --git a/components/vl53l1x/vl53l1x.cpp b/components/vl53l1x/vl53l1x.cpp index 6c58215a..f917a944 100644 --- a/components/vl53l1x/vl53l1x.cpp +++ b/components/vl53l1x/vl53l1x.cpp @@ -22,6 +22,23 @@ void VL53L1X::dump_config() { void VL53L1X::setup() { ESP_LOGD(TAG, "Beginning setup"); + // Wait for boot while feeding watch dog + // This is the same as what Begin() starts with, but we feed the watch dog + // So that ESPHome doesn't think we've hung and panic restart. + uint8_t isBooted = 0; + uint16_t startTime = millis(); + while (!(isBooted & 1) && (millis() < (startTime + 100))) { + this->sensor.GetBootState(&isBooted); + App.feed_wdt(); + delay(5); + } + + if (isBooted != 1) { + ESP_LOGE(TAG, "Timed out waiting for initialization"); + this->mark_failed(); + return; + } + // TODO use xshut_pin, if given, to change address auto status = this->sensor.Begin(this->address_); ESP_LOGD(TAG, "VL53L1_ULD begin() returned"); diff --git a/components/vl53l1x/vl53l1x.h b/components/vl53l1x/vl53l1x.h index a8970b65..dc88fd7b 100644 --- a/components/vl53l1x/vl53l1x.h +++ b/components/vl53l1x/vl53l1x.h @@ -3,6 +3,7 @@ #include "VL53L1X_ULD.h" #include "esphome/components/i2c/i2c.h" +#include "esphome/core/application.h" #include "esphome/core/component.h" #include "esphome/core/gpio.h" #include "esphome/core/log.h" From f522c0d32c910d6eb37fb751f7b6c4ff9d5c4931 Mon Sep 17 00:00:00 2001 From: Carson Full Date: Sun, 16 Jan 2022 08:10:41 -0600 Subject: [PATCH 05/30] Update dump config --- components/roode/roode.cpp | 4 ++++ components/roode/zone.cpp | 9 +++++++++ components/roode/zone.h | 1 + 3 files changed, 14 insertions(+) diff --git a/components/roode/roode.cpp b/components/roode/roode.cpp index aaa0c5ab..569e5f45 100644 --- a/components/roode/roode.cpp +++ b/components/roode/roode.cpp @@ -4,8 +4,12 @@ namespace esphome { namespace roode { void Roode::dump_config() { ESP_LOGCONFIG(TAG, "Roode:"); + ESP_LOGCONFIG(TAG, " Sample size: %d", samples); LOG_UPDATE_INTERVAL(this); + entry->dump_config(); + exit->dump_config(); } + void Roode::setup() { ESP_LOGI(SETUP, "Booting Roode %s", VERSION); if (version_sensor != nullptr) { diff --git a/components/roode/zone.cpp b/components/roode/zone.cpp index b246ae99..77eaf4f9 100644 --- a/components/roode/zone.cpp +++ b/components/roode/zone.cpp @@ -2,6 +2,15 @@ namespace esphome { namespace roode { + +void Zone::dump_config() const { + ESP_LOGCONFIG(TAG, " %s", id == 0U ? "Entry" : "Exit"); + ESP_LOGCONFIG(TAG, " ROI: { width: %d, height: %d, center: %d }", roi->width, roi->height, roi->center); + ESP_LOGCONFIG(TAG, " Threshold: { min: %dmm (%d%%), max: %dmm (%d%%), idle: %dmm }", threshold->min, + threshold->min_percentage.value_or((threshold->min * 100) / threshold->idle), threshold->max, + threshold->max_percentage.value_or((threshold->max * 100) / threshold->idle), threshold->idle); +} + VL53L1_Error Zone::readDistance(TofSensor *distanceSensor) { last_sensor_status = sensor_status; diff --git a/components/roode/zone.h b/components/roode/zone.h index 0f9d6439..bcb20bb1 100644 --- a/components/roode/zone.h +++ b/components/roode/zone.h @@ -30,6 +30,7 @@ struct Threshold { class Zone { public: explicit Zone(uint8_t id) : id{id} {}; + void dump_config() const; VL53L1_Error readDistance(TofSensor *distanceSensor); void reset_roi(uint8_t default_center); void calibrateThreshold(TofSensor *distanceSensor, int number_attempts); From 09d49f5023d1f8c91a2d20e9a5594a0b4aea7d4a Mon Sep 17 00:00:00 2001 From: Kai Bepperling Date: Sun, 16 Jan 2022 16:28:12 +0100 Subject: [PATCH 06/30] Update CI workflow --- .github/workflows/ci.yml | 48 ++++++++++++++++++++++++++++ .github/workflows/main.yml | 22 ------------- ci/.gitignore | 5 +++ ci/common.yaml | 64 ++++++++++++++++++++++++++++++++++++++ ci/esp32.yaml | 17 ++++++++++ ci/esp32_manual.yaml | 17 ++++++++++ ci/esp8266.yaml | 16 ++++++++++ ci/esp8266_manual.yaml | 17 ++++++++++ 8 files changed, 184 insertions(+), 22 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/main.yml create mode 100644 ci/.gitignore create mode 100644 ci/common.yaml create mode 100644 ci/esp32.yaml create mode 100644 ci/esp32_manual.yaml create mode 100644 ci/esp8266.yaml create mode 100644 ci/esp8266_manual.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..9edc07b6 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,48 @@ +name: Build ESP +on: push +jobs: + validate: + strategy: + matrix: + esp: ["esp32", "esp8266"] + name: Validate ${{ matrix.esp }} config + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Setup Python + uses: actions/setup-python@master + with: + python-version: "3.x" + - name: Install ESPHome + run: | + python -m pip install --upgrade pip + pip install -U esphome + pip install -U pillow + + - name: Validate ${{ matrix.esp }} default Config + run: esphome config ci/${{ matrix.esp }}.yaml + + - name: Validate ${{ matrix.esp }} manual Config + run: esphome config ci/${{ matrix.esp }}_manual.yaml + build: + strategy: + matrix: + esp: ["esp32", "esp8266"] + name: Build ${{ matrix.esp }} firmware + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Setup Python + uses: actions/setup-python@master + with: + python-version: "3.x" + - name: Install ESPHome + run: | + python -m pip install --upgrade pip + pip install -U esphome + pip install -U pillow + - name: Build ${{ matrix.esp }} default config + run: esphome compile ci/${{ matrix.esp }}.yaml + + - name: Build ${{ matrix.esp }} manual config + run: esphome compile ci/${{ matrix.esp }}_manual.yaml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index a9f3b68d..00000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Build ESP -on: push -jobs: - main: - name: Main - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - name: Setup Python - uses: actions/setup-python@master - with: - python-version: '3.x' - - name: Install ESPHome - run: | - python -m pip install --upgrade pip - pip install -U esphome - pip install -U pillow - - name: Validate ESP32 Config - run: esphome config peopleCounter32Dev.yaml - - name: Build ESP32 - run: esphome compile peopleCounter32Dev.yaml - diff --git a/ci/.gitignore b/ci/.gitignore new file mode 100644 index 00000000..d8b4157a --- /dev/null +++ b/ci/.gitignore @@ -0,0 +1,5 @@ +# Gitignore settings for ESPHome +# This is an example and may include too much for your use-case. +# You can modify this file to suit your needs. +/.esphome/ +/secrets.yaml diff --git a/ci/common.yaml b/ci/common.yaml new file mode 100644 index 00000000..70ece37f --- /dev/null +++ b/ci/common.yaml @@ -0,0 +1,64 @@ +substitutions: + devicename: ci + friendly_name: $devicename + +external_components: + refresh: always + source: ../components + +esphome: + name: $devicename + +button: + - platform: restart + name: $friendly_name Restart + entity_category: config + - platform: template + name: $friendly_name Recalibrate + on_press: + - lambda: id(roode_platform)->recalibration(); + entity_category: config + +number: + - platform: roode + people_counter: + name: $friendly_name people counter + +binary_sensor: + - platform: roode + presence_sensor: + name: $friendly_name presence + +sensor: + - platform: roode + id: roode_sensors + distance_entry: + name: $friendly_name distance zone 0 + distance_exit: + name: $friendly_name distance zone 1 + max_threshold_entry: + name: $friendly_name max zone 0 + max_threshold_exit: + name: $friendly_name max zone 1 + min_threshold_entry: + name: $friendly_name min zone 0 + min_threshold_exit: + name: $friendly_name min zone 1 + roi_height_entry: + name: $friendly_name ROI height zone 0 + roi_width_entry: + name: $friendly_name ROI width zone 0 + roi_height_exit: + name: $friendly_name ROI height zone 1 + roi_width_exit: + name: $friendly_name ROI width zone 1 + sensor_status: + name: Sensor Status + +text_sensor: + - platform: roode + version: + name: $friendly_name version + - platform: roode + entry_exit_event: + name: $friendly_name last direction diff --git a/ci/esp32.yaml b/ci/esp32.yaml new file mode 100644 index 00000000..bd9ba973 --- /dev/null +++ b/ci/esp32.yaml @@ -0,0 +1,17 @@ +<<: !include common.yaml + +esp32: + board: wemos_d1_mini32 + framework: + type: arduino + +i2c: + sda: 21 + scl: 22 + +# VL53L1X sensor configuration is separate from Roode people counting algorithm +vl53l1x: + calibration: + +roode: + id: roode_platform diff --git a/ci/esp32_manual.yaml b/ci/esp32_manual.yaml new file mode 100644 index 00000000..16df1bb0 --- /dev/null +++ b/ci/esp32_manual.yaml @@ -0,0 +1,17 @@ +<<: !include esp32.yaml + +vl53l1x: + calibration: + ranging: auto + +roode: + id: roode_platform + sampling: 1 + roi: { height: 16, width: 6 } + detection_thresholds: + max: 85% + zones: + entry: + roi: { height: 15, width: 6 } + detection_thresholds: + max: 80% diff --git a/ci/esp8266.yaml b/ci/esp8266.yaml new file mode 100644 index 00000000..7cd426a5 --- /dev/null +++ b/ci/esp8266.yaml @@ -0,0 +1,16 @@ +<<: !include common.yaml +esphome: + name: $devicename + platform: ESP8266 + board: d1_mini + +i2c: + sda: 4 + scl: 5 + +# VL53L1X sensor configuration is separate from Roode people counting algorithm +vl53l1x: + calibration: + +roode: + id: roode_platform diff --git a/ci/esp8266_manual.yaml b/ci/esp8266_manual.yaml new file mode 100644 index 00000000..90d916b6 --- /dev/null +++ b/ci/esp8266_manual.yaml @@ -0,0 +1,17 @@ +<<: !include esp8266.yaml + +vl53l1x: + calibration: + ranging: auto + +roode: + id: roode_platform + sampling: 1 + roi: { height: 16, width: 6 } + detection_thresholds: + max: 85% + zones: + entry: + roi: { height: 15, width: 6 } + detection_thresholds: + max: 80% From 7cce82fb90092720192b0d19fdf358c01f4dd966 Mon Sep 17 00:00:00 2001 From: Kai Bepperling Date: Sun, 16 Jan 2022 16:28:53 +0100 Subject: [PATCH 07/30] No .gitignore --- ci/.gitignore | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 ci/.gitignore diff --git a/ci/.gitignore b/ci/.gitignore deleted file mode 100644 index d8b4157a..00000000 --- a/ci/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Gitignore settings for ESPHome -# This is an example and may include too much for your use-case. -# You can modify this file to suit your needs. -/.esphome/ -/secrets.yaml From aca0cfaec74b100128c5005acb5ce672eeb34005 Mon Sep 17 00:00:00 2001 From: Kai Bepperling Date: Sun, 16 Jan 2022 16:42:40 +0100 Subject: [PATCH 08/30] Add release workflow --- .github/workflows/release.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..735eeebb --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,30 @@ +name: Release + +on: + push: + # Sequence of patterns matched against refs/tags + tags: + - "[0-9]+.[0-9]+.[0-9]+" +jobs: + master-release: + if: github.ref == 'refs/heads/master' + runs-on: ubuntu-latest + steps: + - name: Create release + uses: "marvinpinto/action-automatic-releases@latest" + with: + repo_token: "${{ secrets.GITHUB_TOKEN }}" + automatic_release_tag: ${{ github.ref }} + prerelease: false + title: ${{ github.ref }} + beta-release: + if: github.ref == 'refs/heads/master' + runs-on: ubuntu-latest + steps: + - name: Create release + uses: "marvinpinto/action-automatic-releases@latest" + with: + repo_token: "${{ secrets.GITHUB_TOKEN }}" + automatic_release_tag: ${{ github.ref }}-beta + prerelease: true + title: ${{ github.ref }}-beta From 4a61cf474a53d3ba29c0b4a081c56d6330adfb16 Mon Sep 17 00:00:00 2001 From: Kai Bepperling Date: Sun, 16 Jan 2022 16:47:04 +0100 Subject: [PATCH 09/30] Only run CI workflow on code changes --- .github/workflows/ci.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9edc07b6..f2bdf50e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,5 +1,11 @@ -name: Build ESP -on: push +name: CI +on: + push: + paths: + - "components" + - "ci" + workflow_dispatch: + jobs: validate: strategy: From 3f1c3c764763b1aafcd9d4cb7430133972eb5e5b Mon Sep 17 00:00:00 2001 From: Kai Bepperling Date: Sun, 16 Jan 2022 16:55:02 +0100 Subject: [PATCH 10/30] Set ranging to a manual ranging mode --- ci/esp32_manual.yaml | 2 +- ci/esp8266_manual.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/esp32_manual.yaml b/ci/esp32_manual.yaml index 16df1bb0..8764952e 100644 --- a/ci/esp32_manual.yaml +++ b/ci/esp32_manual.yaml @@ -2,7 +2,7 @@ vl53l1x: calibration: - ranging: auto + ranging: short roode: id: roode_platform diff --git a/ci/esp8266_manual.yaml b/ci/esp8266_manual.yaml index 90d916b6..eb336387 100644 --- a/ci/esp8266_manual.yaml +++ b/ci/esp8266_manual.yaml @@ -2,7 +2,7 @@ vl53l1x: calibration: - ranging: auto + ranging: short roode: id: roode_platform From 3e4cb77ff784d66942fe999988e080158b9b4b0a Mon Sep 17 00:00:00 2001 From: Kai Bepperling Date: Sun, 16 Jan 2022 16:55:34 +0100 Subject: [PATCH 11/30] Fix paths --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f2bdf50e..7804a627 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,8 +2,8 @@ name: CI on: push: paths: - - "components" - - "ci" + - "components/**" + - "ci/**" workflow_dispatch: jobs: From 00aa66dc390891305b08cbe3d8acd1a6db9a3635 Mon Sep 17 00:00:00 2001 From: Kai Bepperling Date: Sun, 16 Jan 2022 16:56:34 +0100 Subject: [PATCH 12/30] Add more manual overrides --- ci/esp32_manual.yaml | 4 ++++ ci/esp8266_manual.yaml | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/ci/esp32_manual.yaml b/ci/esp32_manual.yaml index 8764952e..f475534c 100644 --- a/ci/esp32_manual.yaml +++ b/ci/esp32_manual.yaml @@ -15,3 +15,7 @@ roode: roi: { height: 15, width: 6 } detection_thresholds: max: 80% + exit: + roi: { height: 14, width: 6 } + detection_thresholds: + max: 75% diff --git a/ci/esp8266_manual.yaml b/ci/esp8266_manual.yaml index eb336387..623c17c1 100644 --- a/ci/esp8266_manual.yaml +++ b/ci/esp8266_manual.yaml @@ -15,3 +15,7 @@ roode: roi: { height: 15, width: 6 } detection_thresholds: max: 80% + exit: + roi: { height: 14, width: 6 } + detection_thresholds: + max: 75% From 29c4bc9595876ea6b921a5dbb855169bf8ae850e Mon Sep 17 00:00:00 2001 From: Kai Bepperling Date: Sun, 16 Jan 2022 16:58:56 +0100 Subject: [PATCH 13/30] Only do master releases --- .github/workflows/release.yml | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 735eeebb..c42b0f0f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,8 +6,7 @@ on: tags: - "[0-9]+.[0-9]+.[0-9]+" jobs: - master-release: - if: github.ref == 'refs/heads/master' + release: runs-on: ubuntu-latest steps: - name: Create release @@ -17,14 +16,3 @@ jobs: automatic_release_tag: ${{ github.ref }} prerelease: false title: ${{ github.ref }} - beta-release: - if: github.ref == 'refs/heads/master' - runs-on: ubuntu-latest - steps: - - name: Create release - uses: "marvinpinto/action-automatic-releases@latest" - with: - repo_token: "${{ secrets.GITHUB_TOKEN }}" - automatic_release_tag: ${{ github.ref }}-beta - prerelease: true - title: ${{ github.ref }}-beta From 5f577cc6bb9ea81eff7756ac6ba0601c09735a49 Mon Sep 17 00:00:00 2001 From: Kai Bepperling Date: Sun, 16 Jan 2022 17:14:31 +0100 Subject: [PATCH 14/30] Fix badges --- README.md | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 0816541b..5855ba8f 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,13 @@ # RooDe -[![Build](https://github.com/Lyr3x/Roode/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/Lyr3x/Roode/blob/master/.github/workflows/main.yml) - -People counter working with any smart home system which supports ESPHome and therefore Home Assistant. All necessary entities are created automatically. +[![GitHub release](https://img.shields.io/github/v/tag/Lyr3x/Roode?style=flat-square)](https://GitHub.com/Lyr3x/Roode/releases/) +[![Build](https://img.shields.io/github/workflow/status/Lyr3x/Roode/CI?style=flat-square)](https://github.com/Lyr3x/Roode/blob/master/.github/workflows/ci.yml) +[![Maintenance](https://img.shields.io/maintenance/yes/2023?style=flat-square)](https://GitHub.com/Lyr3x/Roode/graphs/commit-activity) [![Roode community](https://img.shields.io/discord/879407995837087804.svg?label=Discord&logo=Discord&colorB=7289da&style=for-the-badge)](https://discord.gg/hU9SvSXMHs) +People counter working with any smart home system which supports ESPHome/MQTT like Home Assistant. All necessary entities are created automatically. + - [Hardware Recommendation](#hardware-recommendation) - [Wiring](#wiring) - [ESP32](#esp32) @@ -71,6 +73,7 @@ Ps=0 (when connected to GND): In the IIC mode, the user can operate the chip by Roode is provided as an external_component which means it is easy to setup in any ESPHome sensor configuration file. Other than base ESPHome configuration the only config that's needed for Roode is + ```yaml external_components: - source: github://Lyr3x/Roode @@ -78,9 +81,10 @@ external_components: roode: ``` + This uses the recommended default configuration. -However, we offer a lot of flexibility. Here's the full configuration spelled out. +However, we offer a lot of flexibility. Here's the full configuration spelled out. ```yml external_components: @@ -131,9 +135,9 @@ roode: # The detection thresholds for determining whether a measurement should count as a person crossing. # A reading must be greater than the minimum and less than the maximum to count as a crossing. # These can be given as absolute distances or as percentages. - # Percentages are based on the automatically determined idle or resting distance. + # Percentages are based on the automatically determined idle or resting distance. detection_thresholds: - min: 0% # default minimum is any distance + min: 0% # default minimum is any distance max: 85% # default maximum is 85% # an example of absolute units min: 50mm @@ -145,14 +149,14 @@ roode: # Flip the entry/exit zones. If Roode seems to be counting backwards, set this to true. invert: false - # Entry/Exit zones can set overrides for individual ROI & detection thresholds here. + # Entry/Exit zones can set overrides for individual ROI & detection thresholds here. # If omitted, they use the options configured above. entry: - # Entry zone will automatically configure ROI, regardless of ROI above. + # Entry zone will automatically configure ROI, regardless of ROI above. roi: auto exit: roi: - # Exit zone will have a height of 8 and a width of number set above or default or auto + # Exit zone will have a height of 8 and a width of number set above or default or auto height: 8 # Additionally, zones can manually set their center point. # Usually though, this is left for Roode to automatically determine. @@ -170,12 +174,14 @@ roode: #### People Counter The most important one is the people counter. + ```yaml number: - platform: roode people_counter: name: People Count ``` + Regardless of how close we can get, people counting will never be perfect. This allows the current people count to be adjusted easily via Home Assistant. From bb0f394e50b955d38c0af508859c28e0739e31fe Mon Sep 17 00:00:00 2001 From: Carson Full Date: Sun, 16 Jan 2022 08:20:42 -0600 Subject: [PATCH 15/30] Fix ranging override being overridden --- components/roode/roode.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/roode/roode.cpp b/components/roode/roode.cpp index 569e5f45..c9513630 100644 --- a/components/roode/roode.cpp +++ b/components/roode/roode.cpp @@ -241,6 +241,9 @@ void Roode::calibrateDistance() { entry->calibrateThreshold(distanceSensor, number_attempts); exit->calibrateThreshold(distanceSensor, number_attempts); + if (distanceSensor->get_ranging_mode_override().has_value()) { + return; + } auto *mode = determine_raning_mode(entry->threshold->idle, exit->threshold->idle); if (mode != initial) { distanceSensor->set_ranging_mode(mode); From 83bd95cf4a8bfd7375d47731dc636f21488c0858 Mon Sep 17 00:00:00 2001 From: Carson Full Date: Sun, 16 Jan 2022 12:37:53 -0600 Subject: [PATCH 16/30] Replace VL53L1X_ULD::Begin() with our own - Account for the library shifting address to right - Change wait for boot to have configurable timeout and to call our watch dog - Handle 255 from device state as unknown. - This is an undocumented result and shouldn't be considered a valid boot --- components/vl53l1x/__init__.py | 3 ++ components/vl53l1x/vl53l1x.cpp | 96 ++++++++++++++++++++++++++-------- components/vl53l1x/vl53l1x.h | 6 +++ 3 files changed, 83 insertions(+), 22 deletions(-) diff --git a/components/vl53l1x/__init__.py b/components/vl53l1x/__init__.py index 87be14c5..1422db9d 100644 --- a/components/vl53l1x/__init__.py +++ b/components/vl53l1x/__init__.py @@ -12,6 +12,7 @@ CONF_INTERRUPT, CONF_OFFSET, CONF_PINS, + CONF_TIMEOUT, ) import esphome.pins as pins @@ -76,6 +77,7 @@ def none_to_empty(value): cv.Schema( { cv.GenerateID(): cv.declare_id(VL53L1X), + cv.Optional(CONF_TIMEOUT, default="2s"): cv.positive_time_period_milliseconds, cv.Optional(CONF_PINS, default={}): NullableSchema( { cv.Optional(CONF_XSHUT): pins.gpio_output_pin_schema, @@ -125,6 +127,7 @@ async def to_code(config: Dict): frequency / 1000, ) + cg.add(vl53l1x.set_timeout(config[CONF_TIMEOUT])) await setup_hardware(vl53l1x, config) await setup_calibration(vl53l1x, config[CONF_CALIBRATION]) diff --git a/components/vl53l1x/vl53l1x.cpp b/components/vl53l1x/vl53l1x.cpp index f917a944..e979f535 100644 --- a/components/vl53l1x/vl53l1x.cpp +++ b/components/vl53l1x/vl53l1x.cpp @@ -22,33 +22,13 @@ void VL53L1X::dump_config() { void VL53L1X::setup() { ESP_LOGD(TAG, "Beginning setup"); - // Wait for boot while feeding watch dog - // This is the same as what Begin() starts with, but we feed the watch dog - // So that ESPHome doesn't think we've hung and panic restart. - uint8_t isBooted = 0; - uint16_t startTime = millis(); - while (!(isBooted & 1) && (millis() < (startTime + 100))) { - this->sensor.GetBootState(&isBooted); - App.feed_wdt(); - delay(5); - } - - if (isBooted != 1) { - ESP_LOGE(TAG, "Timed out waiting for initialization"); - this->mark_failed(); - return; - } - // TODO use xshut_pin, if given, to change address - auto status = this->sensor.Begin(this->address_); - ESP_LOGD(TAG, "VL53L1_ULD begin() returned"); + auto status = this->init(); if (status != VL53L1_ERROR_NONE) { - // If the sensor could not be initialized print out the error code. -7 is timeout - ESP_LOGE(TAG, "Could not initialize, error code: %d", status); this->mark_failed(); return; } - this->address_ = sensor.GetI2CAddress(); + ESP_LOGD(TAG, "Device initialized"); if (this->offset.has_value()) { ESP_LOGI(TAG, "Setting offset calibration to %d", this->offset.value()); @@ -73,6 +53,78 @@ void VL53L1X::setup() { ESP_LOGI(TAG, "Setup complete"); } +VL53L1_Error VL53L1X::init() { + ESP_LOGD(TAG, "Trying to initialize"); + + VL53L1_Error status; + + // If address is non-default, set and try again. + if (address_ != (sensor.GetI2CAddress() >> 1)) { + ESP_LOGD(TAG, "Setting different address"); + status = sensor.SetI2CAddress(address_ << 1); + if (status != VL53L1_ERROR_NONE) { + ESP_LOGE(TAG, "Failed to change address. Error: %d", status); + return status; + } + } + + status = wait_for_boot(); + if (status != VL53L1_ERROR_NONE) { + return status; + } + + ESP_LOGD(TAG, "Found device, initializing..."); + status = sensor.Init(); + if (status != VL53L1_ERROR_NONE) { + ESP_LOGE(TAG, "Could not initialize device, error code: %d", status); + return status; + } + + return status; +} + +VL53L1_Error VL53L1X::wait_for_boot() { + // Wait for firmware to copy NVM device_state into registers + delayMicroseconds(1200); + + uint8_t device_state; + VL53L1_Error status; + auto start = millis(); + while ((millis() - start) < this->timeout) { + status = get_device_state(&device_state); + if (status != VL53L1_ERROR_NONE) { + return status; + } + if ((device_state & 0x01) == 0x01) { + ESP_LOGD(TAG, "Finished waiting for boot. Device state: %d", device_state); + return VL53L1_ERROR_NONE; + } + App.feed_wdt(); + } + + ESP_LOGW(TAG, "Timed out waiting for boot. state: %d", device_state); + return VL53L1_ERROR_TIME_OUT; +} + +VL53L1_Error VL53L1X::get_device_state(uint8_t *device_state) { + VL53L1_Error status = sensor.GetBootState(device_state); + if (status != VL53L1_ERROR_NONE) { + ESP_LOGE(TAG, "Failed to read device state. error: %d", status); + return status; + } + + // Our own logic...device_state is 255 when unable to complete read + // Not sure why and why other libraries don't account for this. + // Maybe somehow this is supposed to be 0, and it is getting messed up in I2C layer. + if (*device_state == 255) { + *device_state = 98; // Unknown + } + + ESP_LOGV(TAG, "Device state: %d", *device_state); + + return VL53L1_ERROR_NONE; +} + void VL53L1X::set_ranging_mode(const RangingMode *mode) { if (this->is_failed()) { ESP_LOGE(TAG, "Cannot set ranging mode while component is failed"); diff --git a/components/vl53l1x/vl53l1x.h b/components/vl53l1x/vl53l1x.h index dc88fd7b..60a76d21 100644 --- a/components/vl53l1x/vl53l1x.h +++ b/components/vl53l1x/vl53l1x.h @@ -34,6 +34,7 @@ class VL53L1X : public i2c::I2CDevice, public Component { void set_ranging_mode_override(const RangingMode *mode) { this->ranging_mode_override = {mode}; } void set_offset(int16_t val) { this->offset = val; } void set_xtalk(uint16_t val) { this->xtalk = val; } + void set_timeout(uint16_t val) { this->timeout = val; } protected: VL53L1X_ULD sensor; @@ -44,6 +45,11 @@ class VL53L1X : public i2c::I2CDevice, public Component { optional ranging_mode_override{}; optional offset{}; optional xtalk{}; + uint16_t timeout{}; + + VL53L1_Error init(); + VL53L1_Error wait_for_boot(); + VL53L1_Error get_device_state(uint8_t *device_state); }; } // namespace vl53l1x From 826b0c0bf4f772b5ded9cba7807d8028cecd2ae7 Mon Sep 17 00:00:00 2001 From: Kai Bepperling Date: Sun, 16 Jan 2022 20:50:14 +0100 Subject: [PATCH 17/30] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5855ba8f..4691e5d6 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ Other than base ESPHome configuration the only config that's needed for Roode is external_components: - source: github://Lyr3x/Roode refresh: always - +vl53l1x: roode: ``` @@ -90,6 +90,7 @@ However, we offer a lot of flexibility. Here's the full configuration spelled ou external_components: - source: github://Lyr3x/Roode refresh: always + ref: master # VL53L1X sensor configuration is separate from Roode people counting algorithm vl53l1x: From 3b1d7aa44e0aac9264b001b84268ffd4a0dc8adb Mon Sep 17 00:00:00 2001 From: Carson Full Date: Sun, 16 Jan 2022 19:44:18 -0600 Subject: [PATCH 18/30] Only set ROI to sensor if it's different from before. For several subsequent reads, like in calibration, this call is unnecessary. --- components/vl53l1x/roi.h | 3 +++ components/vl53l1x/vl53l1x.cpp | 13 ++++++++----- components/vl53l1x/vl53l1x.h | 1 + 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/components/vl53l1x/roi.h b/components/vl53l1x/roi.h index c5c6ad4f..6ead8032 100644 --- a/components/vl53l1x/roi.h +++ b/components/vl53l1x/roi.h @@ -10,6 +10,9 @@ struct ROI { void set_width(uint8_t val) { this->width = val; } void set_height(uint8_t val) { this->height = val; } void set_center(uint8_t val) { this->center = val; } + + bool operator==(const ROI &rhs) const { return width == rhs.width && height == rhs.height && center == rhs.center; } + bool operator!=(const ROI &rhs) const { return !(rhs == *this); } }; } // namespace vl53l1x diff --git a/components/vl53l1x/vl53l1x.cpp b/components/vl53l1x/vl53l1x.cpp index e979f535..08b1d2b4 100644 --- a/components/vl53l1x/vl53l1x.cpp +++ b/components/vl53l1x/vl53l1x.cpp @@ -158,11 +158,14 @@ optional VL53L1X::read_distance(ROI *roi, VL53L1_Error &status) { ESP_LOGV(TAG, "Beginning distance read"); - status = this->sensor.SetROI(roi->width, roi->height); - status += this->sensor.SetROICenter(roi->center); - if (status != VL53L1_ERROR_NONE) { - ESP_LOGE(TAG, "Could not set ROI, error code: %d", status); - return {}; + if (last_roi != nullptr && *roi != *last_roi) { + status = this->sensor.SetROI(roi->width, roi->height); + status += this->sensor.SetROICenter(roi->center); + if (status != VL53L1_ERROR_NONE) { + ESP_LOGE(TAG, "Could not set ROI, error code: %d", status); + return {}; + } + last_roi = roi; } status = this->sensor.StartRanging(); diff --git a/components/vl53l1x/vl53l1x.h b/components/vl53l1x/vl53l1x.h index 60a76d21..ee0f7e18 100644 --- a/components/vl53l1x/vl53l1x.h +++ b/components/vl53l1x/vl53l1x.h @@ -46,6 +46,7 @@ class VL53L1X : public i2c::I2CDevice, public Component { optional offset{}; optional xtalk{}; uint16_t timeout{}; + ROI *last_roi{}; VL53L1_Error init(); VL53L1_Error wait_for_boot(); From 5ab6cc34c7ddf89993405aa484390f8a2aa2a24b Mon Sep 17 00:00:00 2001 From: Carson Full Date: Sun, 16 Jan 2022 19:45:07 -0600 Subject: [PATCH 19/30] Small tweaks to distance read logs & code --- components/roode/roode.cpp | 9 +-------- components/roode/roode.h | 1 - components/vl53l1x/vl53l1x.cpp | 11 ++++++----- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/components/roode/roode.cpp b/components/roode/roode.cpp index c9513630..ca0448c6 100644 --- a/components/roode/roode.cpp +++ b/components/roode/roode.cpp @@ -37,7 +37,7 @@ void Roode::update() { void Roode::loop() { // unsigned long start = micros(); - get_alternating_zone_distances(); + this->current_zone->readDistance(distanceSensor); // uint16_t samplingDistance = sampling(this->current_zone); path_tracking(this->current_zone); handle_sensor_status(); @@ -50,7 +50,6 @@ void Roode::loop() { } bool Roode::handle_sensor_status() { - ESP_LOGV(TAG, "Sensor status: %d, Last sensor status: %d", sensor_status, last_sensor_status); bool check_status = false; if (last_sensor_status != sensor_status && sensor_status == VL53L1_ERROR_NONE) { if (status_sensor != nullptr) { @@ -69,12 +68,6 @@ bool Roode::handle_sensor_status() { return check_status; } -VL53L1_Error Roode::get_alternating_zone_distances() { - this->current_zone->readDistance(distanceSensor); - App.feed_wdt(); - return sensor_status; -} - void Roode::path_tracking(Zone *zone) { static int PathTrack[] = {0, 0, 0, 0}; static int PathTrackFillingSize = 1; // init this to 1 as we start from state diff --git a/components/roode/roode.h b/components/roode/roode.h index bc976998..a4d081e1 100644 --- a/components/roode/roode.h +++ b/components/roode/roode.h @@ -120,7 +120,6 @@ class Roode : public PollingComponent { text_sensor::TextSensor *version_sensor; text_sensor::TextSensor *entry_exit_event_sensor; - VL53L1_Error get_alternating_zone_distances(); VL53L1_Error last_sensor_status = VL53L1_ERROR_NONE; VL53L1_Error sensor_status = VL53L1_ERROR_NONE; void path_tracking(Zone *zone); diff --git a/components/vl53l1x/vl53l1x.cpp b/components/vl53l1x/vl53l1x.cpp index 08b1d2b4..ee88f45c 100644 --- a/components/vl53l1x/vl53l1x.cpp +++ b/components/vl53l1x/vl53l1x.cpp @@ -152,11 +152,11 @@ void VL53L1X::set_ranging_mode(const RangingMode *mode) { optional VL53L1X::read_distance(ROI *roi, VL53L1_Error &status) { if (this->is_failed()) { - ESP_LOGE(TAG, "Cannot read distance while component is failed"); + ESP_LOGW(TAG, "Cannot read distance while component is failed"); return {}; } - ESP_LOGV(TAG, "Beginning distance read"); + ESP_LOGVV(TAG, "Beginning distance read"); if (last_roi != nullptr && *roi != *last_roi) { status = this->sensor.SetROI(roi->width, roi->height); @@ -174,17 +174,18 @@ optional VL53L1X::read_distance(ROI *roi, VL53L1_Error &status) { // TODO use interrupt_pin, if given, to await data ready instead of polling uint8_t dataReady = false; while (!dataReady) { - status += this->sensor.CheckForDataReady(&dataReady); + status = this->sensor.CheckForDataReady(&dataReady); if (status != VL53L1_ERROR_NONE) { ESP_LOGE(TAG, "Failed to check if data is ready, error code: %d", status); return {}; } delay(1); + App.feed_wdt(); } // Get the results uint16_t distance; - status += this->sensor.GetDistanceInMm(&distance); + status = this->sensor.GetDistanceInMm(&distance); if (status != VL53L1_ERROR_NONE) { ESP_LOGE(TAG, "Could not get distance, error code: %d", status); return {}; @@ -198,7 +199,7 @@ optional VL53L1X::read_distance(ROI *roi, VL53L1_Error &status) { return {}; } - ESP_LOGV(TAG, "Finished distance read"); + ESP_LOGV(TAG, "Finished distance read: %d", distance); return {distance}; } From 279951a99450290acc737c3f929047d5e37ffff0 Mon Sep 17 00:00:00 2001 From: Carson Full Date: Mon, 17 Jan 2022 13:37:51 -0600 Subject: [PATCH 20/30] Fix last roi null check --- components/vl53l1x/vl53l1x.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/vl53l1x/vl53l1x.cpp b/components/vl53l1x/vl53l1x.cpp index ee88f45c..8b42e663 100644 --- a/components/vl53l1x/vl53l1x.cpp +++ b/components/vl53l1x/vl53l1x.cpp @@ -158,7 +158,7 @@ optional VL53L1X::read_distance(ROI *roi, VL53L1_Error &status) { ESP_LOGVV(TAG, "Beginning distance read"); - if (last_roi != nullptr && *roi != *last_roi) { + if (last_roi == nullptr || *roi != *last_roi) { status = this->sensor.SetROI(roi->width, roi->height); status += this->sensor.SetROICenter(roi->center); if (status != VL53L1_ERROR_NONE) { From 84ac85a825964235177bce8f01c9dfe9672d489b Mon Sep 17 00:00:00 2001 From: Leszek Zalewski Date: Mon, 17 Jan 2022 13:58:46 +0100 Subject: [PATCH 21/30] Make readme more beginner friendly. - Always specify `ref` for external component, otherwise it tries `@None` (from what I saw in logs) which in the end didn't worked in my case - Comment out duplicated entries in "extended" configuration, in order to make it easier to copy/paste without warnings - Add links to real examples --- README.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 4691e5d6..e3923139 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![Roode community](https://img.shields.io/discord/879407995837087804.svg?label=Discord&logo=Discord&colorB=7289da&style=for-the-badge)](https://discord.gg/hU9SvSXMHs) -People counter working with any smart home system which supports ESPHome/MQTT like Home Assistant. All necessary entities are created automatically. +People counter working with any smart home system which supports ESPHome/MQTT like Home Assistant. All necessary entities are created automatically. - [Hardware Recommendation](#hardware-recommendation) - [Wiring](#wiring) @@ -29,6 +29,7 @@ People counter working with any smart home system which supports ESPHome/MQTT li - **Pololu** <-- Recommended - GY-53 - Black PCB chinese sensor + - Pimoroni - 1A Power Supply **Do not use an USB port of your computer!** - Encolsure (see .stl files) - will be updated soon! Pins: @@ -76,7 +77,7 @@ Other than base ESPHome configuration the only config that's needed for Roode is ```yaml external_components: - - source: github://Lyr3x/Roode + - source: github://Lyr3x/Roode@master refresh: always vl53l1x: roode: @@ -129,9 +130,9 @@ roode: # The current default is roi: { height: 16, width: 6 } # We have an experiential automatic mode that can be enabled with - roi: auto + # roi: auto # or only automatic for one dimension - roi: { height: 16, width: auto } + # roi: { height: 16, width: auto } # The detection thresholds for determining whether a measurement should count as a person crossing. # A reading must be greater than the minimum and less than the maximum to count as a crossing. @@ -141,8 +142,8 @@ roode: min: 0% # default minimum is any distance max: 85% # default maximum is 85% # an example of absolute units - min: 50mm - max: 234cm + # min: 50mm + # max: 234cm # The people counting algorithm works by splitting the sensor's capability reading area into two zones. # This allows for detecting whether a crossing is an entry or exit based on which zones was crossed first. @@ -170,6 +171,10 @@ roode: max: 70% ``` +Also feel free to check out running examples for: +- [Wemos D1 mini with ESP32](peopleCounter32.yaml) +- [Wemos D1 mini with ESP8266](peopleCounter8266.yaml) + ### Sensors #### People Counter From be8994952d4a189f84fd4feda3d3e99d996c2f6d Mon Sep 17 00:00:00 2001 From: Carson Full Date: Mon, 17 Jan 2022 15:56:02 -0600 Subject: [PATCH 22/30] More specific logs around setting ROI --- components/roode/zone.cpp | 2 ++ components/vl53l1x/vl53l1x.cpp | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/components/roode/zone.cpp b/components/roode/zone.cpp index 77eaf4f9..02eec2b9 100644 --- a/components/roode/zone.cpp +++ b/components/roode/zone.cpp @@ -37,6 +37,8 @@ void Zone::reset_roi(uint8_t default_center) { roi->width = roi_override->width ?: 6; roi->height = roi_override->height ?: 16; roi->center = roi_override->center ?: default_center; + ESP_LOGD(TAG, "%s ROI reset: { width: %d, height: %d, center: %d }", id == 0U ? "Entry" : "Exit", roi->width, + roi->height, roi->center); } void Zone::calibrateThreshold(TofSensor *distanceSensor, int number_attempts) { diff --git a/components/vl53l1x/vl53l1x.cpp b/components/vl53l1x/vl53l1x.cpp index 8b42e663..e53c280d 100644 --- a/components/vl53l1x/vl53l1x.cpp +++ b/components/vl53l1x/vl53l1x.cpp @@ -159,10 +159,16 @@ optional VL53L1X::read_distance(ROI *roi, VL53L1_Error &status) { ESP_LOGVV(TAG, "Beginning distance read"); if (last_roi == nullptr || *roi != *last_roi) { + ESP_LOGVV(TAG, "Setting new ROI: { width: %d, height: %d, center: %d }", roi->width, roi->height, roi->center); + status = this->sensor.SetROI(roi->width, roi->height); - status += this->sensor.SetROICenter(roi->center); if (status != VL53L1_ERROR_NONE) { - ESP_LOGE(TAG, "Could not set ROI, error code: %d", status); + ESP_LOGE(TAG, "Could not set ROI width/height, error code: %d", status); + return {}; + } + status = this->sensor.SetROICenter(roi->center); + if (status != VL53L1_ERROR_NONE) { + ESP_LOGE(TAG, "Could not set ROI center, error code: %d", status); return {}; } last_roi = roi; @@ -193,7 +199,11 @@ optional VL53L1X::read_distance(ROI *roi, VL53L1_Error &status) { // After reading the results reset the interrupt to be able to take another measurement status = this->sensor.ClearInterrupt(); - status += this->sensor.StopRanging(); + if (status != VL53L1_ERROR_NONE) { + ESP_LOGE(TAG, "Could not clear interrupt, error code: %d", status); + return {}; + } + status = this->sensor.StopRanging(); if (status != VL53L1_ERROR_NONE) { ESP_LOGE(TAG, "Could not stop ranging, error code: %d", status); return {}; From 9123a5d9d5ee0017979eed9db48baf5924e36eeb Mon Sep 17 00:00:00 2001 From: Carson Full Date: Mon, 17 Jan 2022 15:57:44 -0600 Subject: [PATCH 23/30] Black format --- components/vl53l1x/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/vl53l1x/__init__.py b/components/vl53l1x/__init__.py index 1422db9d..fad429ad 100644 --- a/components/vl53l1x/__init__.py +++ b/components/vl53l1x/__init__.py @@ -77,7 +77,9 @@ def none_to_empty(value): cv.Schema( { cv.GenerateID(): cv.declare_id(VL53L1X), - cv.Optional(CONF_TIMEOUT, default="2s"): cv.positive_time_period_milliseconds, + cv.Optional( + CONF_TIMEOUT, default="2s" + ): cv.positive_time_period_milliseconds, cv.Optional(CONF_PINS, default={}): NullableSchema( { cv.Optional(CONF_XSHUT): pins.gpio_output_pin_schema, From bf8006a269ef3993ce3402e5282f29fe5edd243a Mon Sep 17 00:00:00 2001 From: Carson Full Date: Mon, 17 Jan 2022 16:01:44 -0600 Subject: [PATCH 24/30] Remove inaccurate doc about one dimension auto roi --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 4691e5d6..57d9aeac 100644 --- a/README.md +++ b/README.md @@ -130,8 +130,6 @@ roode: roi: { height: 16, width: 6 } # We have an experiential automatic mode that can be enabled with roi: auto - # or only automatic for one dimension - roi: { height: 16, width: auto } # The detection thresholds for determining whether a measurement should count as a person crossing. # A reading must be greater than the minimum and less than the maximum to count as a crossing. From 4dda6b06d37435f344d28775c9b2d1270f7dec17 Mon Sep 17 00:00:00 2001 From: Carson Full Date: Mon, 17 Jan 2022 16:12:56 -0600 Subject: [PATCH 25/30] Base ROI center on _actual_ width used --- components/roode/zone.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/roode/zone.cpp b/components/roode/zone.cpp index 02eec2b9..12524097 100644 --- a/components/roode/zone.cpp +++ b/components/roode/zone.cpp @@ -76,7 +76,7 @@ void Zone::roi_calibration(uint16_t entry_threshold, uint16_t exit_threshold, Or } else { // now we set the position of the center of the two zones if (orientation == Parallel) { - switch (ROI_size) { + switch (this->roi->width) { case 4: this->roi->center = this->id == 0U ? 150 : 247; break; @@ -90,7 +90,7 @@ void Zone::roi_calibration(uint16_t entry_threshold, uint16_t exit_threshold, Or break; } } else { - switch (ROI_size) { + switch (this->roi->width) { case 4: this->roi->center = this->id == 0U ? 193 : 58; break; From 39c9c0a3e58ac7c652ec63f28b8cb70f9a614e30 Mon Sep 17 00:00:00 2001 From: Carson Full Date: Mon, 17 Jan 2022 16:28:09 -0600 Subject: [PATCH 26/30] Format persisted number --- .../persisted_number/persisted_number.cpp | 34 +++++++++---------- .../persisted_number/persisted_number.h | 20 +++++------ 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/components/persisted_number/persisted_number.cpp b/components/persisted_number/persisted_number.cpp index 976507a5..2dd0c97f 100644 --- a/components/persisted_number/persisted_number.cpp +++ b/components/persisted_number/persisted_number.cpp @@ -5,27 +5,27 @@ namespace esphome { namespace number { auto PersistedNumber::control(float newValue) -> void { - this->publish_state(newValue); - if (this->restore_value_) { - this->pref_.save(&newValue); - } + this->publish_state(newValue); + if (this->restore_value_) { + this->pref_.save(&newValue); + } } auto PersistedNumber::setup() -> void { - float value; - if (!this->restore_value_) { - value = this->traits.get_min_value(); + float value; + if (!this->restore_value_) { + value = this->traits.get_min_value(); + } else { + this->pref_ = global_preferences->make_preference(this->get_object_id_hash()); + if (this->pref_.load(&value)) { + ESP_LOGI("number", "'%s': Restored state %f", this->get_name().c_str(), value); } else { - this->pref_ = global_preferences->make_preference(this->get_object_id_hash()); - if (this->pref_.load(&value)) { - ESP_LOGI("number", "'%s': Restored state %f", this->get_name().c_str(), value); - } else { - ESP_LOGI("number", "'%s': No previous state found", this->get_name().c_str()); - value = this->traits.get_min_value(); - } + ESP_LOGI("number", "'%s': No previous state found", this->get_name().c_str()); + value = this->traits.get_min_value(); } - this->publish_state(value); + } + this->publish_state(value); } -} -} +} // namespace number +} // namespace esphome diff --git a/components/persisted_number/persisted_number.h b/components/persisted_number/persisted_number.h index 48a4ebd3..aadbb565 100644 --- a/components/persisted_number/persisted_number.h +++ b/components/persisted_number/persisted_number.h @@ -8,17 +8,17 @@ namespace esphome { namespace number { class PersistedNumber : public number::Number, public Component { -public: - float get_setup_priority() const override { return setup_priority::HARDWARE; } - void set_restore_value(bool restore) { this->restore_value_ = restore; } - void setup() override; + public: + float get_setup_priority() const override { return setup_priority::HARDWARE; } + void set_restore_value(bool restore) { this->restore_value_ = restore; } + void setup() override; -protected: - void control(float value) override; + protected: + void control(float value) override; - bool restore_value_{false}; - ESPPreferenceObject pref_; + bool restore_value_{false}; + ESPPreferenceObject pref_; }; -} // namespace roode -} // namespace esphome +} // namespace number +} // namespace esphome From 8ba3d47f8d455a6a03cd7223e9cf0cc3b7c18c6f Mon Sep 17 00:00:00 2001 From: CI Date: Tue, 18 Jan 2022 14:43:45 +0000 Subject: [PATCH 27/30] Bump to version 1.5.0 --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09f48b4a..26be3440 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ -# Changelog +# Changelog\n +## 1.5.0 + +- Manual ROI configuration fixed +- Sensor initialization fixed +- Fix setup priorities to ensure proper boot up +- Code formatting ## 1.4.1 From 6386193105b82c8c0568115cc9c9aada12d2516b Mon Sep 17 00:00:00 2001 From: CI Date: Tue, 18 Jan 2022 15:02:47 +0000 Subject: [PATCH 28/30] Bump to version 1.6.0 --- CHANGELOG.md | 7 ++++++- components/roode/roode.h | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 26be3440..e572725c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ -# Changelog\n +# Changelog +\n## +- Manual ROI configuration fixed +- Sensor initialization fixed +- Fix setup priorities to ensure proper boot up +- Code formatting ## 1.5.0 - Manual ROI configuration fixed diff --git a/components/roode/roode.h b/components/roode/roode.h index a4d081e1..f4c5435f 100644 --- a/components/roode/roode.h +++ b/components/roode/roode.h @@ -18,7 +18,7 @@ namespace esphome { namespace roode { #define NOBODY 0 #define SOMEONE 1 -#define VERSION "v1.4.1-beta" +#define VERSION "1.6.0" static const char *const TAG = "Roode"; static const char *const SETUP = "Setup"; static const char *const CALIBRATION = "Sensor Calibration"; From e4e067203ae89f652617760e0dfb5cd1dfb9a0f9 Mon Sep 17 00:00:00 2001 From: Kai Bepperling Date: Tue, 18 Jan 2022 16:08:10 +0100 Subject: [PATCH 29/30] Revert test versions --- CHANGELOG.md | 11 ----------- components/roode/roode.h | 2 +- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e572725c..09f48b4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,4 @@ # Changelog -\n## -- Manual ROI configuration fixed -- Sensor initialization fixed -- Fix setup priorities to ensure proper boot up -- Code formatting -## 1.5.0 - -- Manual ROI configuration fixed -- Sensor initialization fixed -- Fix setup priorities to ensure proper boot up -- Code formatting ## 1.4.1 diff --git a/components/roode/roode.h b/components/roode/roode.h index f4c5435f..c09239e8 100644 --- a/components/roode/roode.h +++ b/components/roode/roode.h @@ -18,7 +18,7 @@ namespace esphome { namespace roode { #define NOBODY 0 #define SOMEONE 1 -#define VERSION "1.6.0" +#define VERSION "1.4.1" static const char *const TAG = "Roode"; static const char *const SETUP = "Setup"; static const char *const CALIBRATION = "Sensor Calibration"; From e50afb6595dc1c76591a0200698823a602648595 Mon Sep 17 00:00:00 2001 From: CI Date: Tue, 18 Jan 2022 15:09:34 +0000 Subject: [PATCH 30/30] Bump to version 1.5.0 --- CHANGELOG.md | 8 ++++++++ components/roode/roode.h | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09f48b4a..99a132cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 1.5.0 + +- Manual ROI configuration fixed +- Sensor initialization fixed +- Fix setup priorities to ensure proper boot up +- Code formatting +- Cleanup + ## 1.4.1 - Timing budget test by @Lyr3x in #60 diff --git a/components/roode/roode.h b/components/roode/roode.h index c09239e8..95e9bcd3 100644 --- a/components/roode/roode.h +++ b/components/roode/roode.h @@ -18,7 +18,7 @@ namespace esphome { namespace roode { #define NOBODY 0 #define SOMEONE 1 -#define VERSION "1.4.1" +#define VERSION "1.5.0" static const char *const TAG = "Roode"; static const char *const SETUP = "Setup"; static const char *const CALIBRATION = "Sensor Calibration";