From 4ae4a4ee88d985e53af4e5aaf07950476e2893e2 Mon Sep 17 00:00:00 2001 From: Wojtek Strzalka Date: Thu, 29 Apr 2021 01:49:46 +0200 Subject: [PATCH] Support for TOF10120 distance sensor (#1375) --- CODEOWNERS | 1 + esphome/components/tof10120/__init__.py | 0 esphome/components/tof10120/sensor.py | 26 +++++++++ .../components/tof10120/tof10120_sensor.cpp | 53 +++++++++++++++++++ esphome/components/tof10120/tof10120_sensor.h | 19 +++++++ tests/test3.yaml | 5 +- 6 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 esphome/components/tof10120/__init__.py create mode 100644 esphome/components/tof10120/sensor.py create mode 100644 esphome/components/tof10120/tof10120_sensor.cpp create mode 100644 esphome/components/tof10120/tof10120_sensor.h diff --git a/CODEOWNERS b/CODEOWNERS index 1a6a54a00c..891b24f179 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -108,6 +108,7 @@ esphome/components/thermostat/* @kbx81 esphome/components/time/* @OttoWinter esphome/components/tm1637/* @glmnet esphome/components/tmp102/* @timsavage +esphome/components/tof10120/* @wstrzalka esphome/components/tuya/binary_sensor/* @jesserockz esphome/components/tuya/climate/* @jesserockz esphome/components/tuya/sensor/* @jesserockz diff --git a/esphome/components/tof10120/__init__.py b/esphome/components/tof10120/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/esphome/components/tof10120/sensor.py b/esphome/components/tof10120/sensor.py new file mode 100644 index 0000000000..91a15960b4 --- /dev/null +++ b/esphome/components/tof10120/sensor.py @@ -0,0 +1,26 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import i2c, sensor +from esphome.const import CONF_ID, UNIT_METER, ICON_ARROW_EXPAND_VERTICAL + +CODEOWNERS = ["@wstrzalka"] +DEPENDENCIES = ["i2c"] + +tof10120_ns = cg.esphome_ns.namespace("tof10120") +TOF10120Sensor = tof10120_ns.class_( + "TOF10120Sensor", sensor.Sensor, cg.PollingComponent, i2c.I2CDevice +) + +CONFIG_SCHEMA = ( + sensor.sensor_schema(UNIT_METER, ICON_ARROW_EXPAND_VERTICAL, 3) + .extend({cv.GenerateID(): cv.declare_id(TOF10120Sensor)}) + .extend(cv.polling_component_schema("60s")) + .extend(i2c.i2c_device_schema(0x52)) +) + + +def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + yield cg.register_component(var, config) + yield sensor.register_sensor(var, config) + yield i2c.register_i2c_device(var, config) diff --git a/esphome/components/tof10120/tof10120_sensor.cpp b/esphome/components/tof10120/tof10120_sensor.cpp new file mode 100644 index 0000000000..4e2732bb08 --- /dev/null +++ b/esphome/components/tof10120/tof10120_sensor.cpp @@ -0,0 +1,53 @@ +#include "tof10120_sensor.h" +#include "esphome/core/log.h" + +// Very basic support for TOF10120 distance sensor + +namespace esphome { +namespace tof10120 { + +static const char *TAG = "tof10120"; +static const uint8_t TOF10120_READ_DISTANCE_CMD[] = {0x00}; +static const uint8_t TOF10120_DEFAULT_DELAY = 30; + +static const uint8_t TOF10120_DIR_SEND_REGISTER = 0x0e; +static const uint8_t TOF10120_DISTANCE_REGISTER = 0x00; + +static const uint16_t TOF10120_OUT_OF_RANGE_VALUE = 2000; + +void TOF10120Sensor::dump_config() { + LOG_SENSOR("", "TOF10120", this); + LOG_UPDATE_INTERVAL(this); + LOG_I2C_DEVICE(this); +} + +void TOF10120Sensor::setup() {} + +void TOF10120Sensor::update() { + if (!this->write_bytes(TOF10120_DISTANCE_REGISTER, TOF10120_READ_DISTANCE_CMD, sizeof(TOF10120_READ_DISTANCE_CMD))) { + ESP_LOGE(TAG, "Communication with TOF10120 failed on write"); + this->status_set_warning(); + return; + } + + uint8_t data[2]; + if (!this->read_bytes(TOF10120_DISTANCE_REGISTER, data, 2, TOF10120_DEFAULT_DELAY)) { + ESP_LOGE(TAG, "Communication with TOF10120 failed on read"); + this->status_set_warning(); + return; + } + + uint32_t distance_mm = (data[0] << 8) | data[1]; + ESP_LOGI(TAG, "Data read: %dmm", distance_mm); + + if (distance_mm == TOF10120_OUT_OF_RANGE_VALUE) { + ESP_LOGW(TAG, "Distance measurement out of range"); + this->publish_state(NAN); + } else { + this->publish_state(distance_mm / 1000.0); + } + this->status_clear_warning(); +} + +} // namespace tof10120 +} // namespace esphome diff --git a/esphome/components/tof10120/tof10120_sensor.h b/esphome/components/tof10120/tof10120_sensor.h new file mode 100644 index 0000000000..90bad8ed07 --- /dev/null +++ b/esphome/components/tof10120/tof10120_sensor.h @@ -0,0 +1,19 @@ +#pragma once + +#include "esphome/core/component.h" +#include "esphome/components/sensor/sensor.h" +#include "esphome/components/i2c/i2c.h" + +namespace esphome { +namespace tof10120 { + +class TOF10120Sensor : public sensor::Sensor, public PollingComponent, public i2c::I2CDevice { + public: + void setup() override; + + void dump_config() override; + float get_setup_priority() const override { return setup_priority::DATA; } + void update() override; +}; +} // namespace tof10120 +} // namespace esphome diff --git a/tests/test3.yaml b/tests/test3.yaml index 165a36c015..8781c935a1 100644 --- a/tests/test3.yaml +++ b/tests/test3.yaml @@ -443,7 +443,10 @@ sensor: - platform: ezo id: ph_ezo address: 99 - unit_of_measurement: 'pH' + unit_of_measurement: 'pH' + - platform: tof10120 + name: "Distance sensor" + update_interval: 5s - platform: fingerprint_grow fingerprint_count: name: "Fingerprint Count"