mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	SPI and I2C for ENS160 (#6369)
This commit is contained in:
		| @@ -111,7 +111,10 @@ esphome/components/ee895/* @Stock-M | |||||||
| esphome/components/ektf2232/touchscreen/* @jesserockz | esphome/components/ektf2232/touchscreen/* @jesserockz | ||||||
| esphome/components/emc2101/* @ellull | esphome/components/emc2101/* @ellull | ||||||
| esphome/components/emmeti/* @E440QF | esphome/components/emmeti/* @E440QF | ||||||
| esphome/components/ens160/* @vincentscode | esphome/components/ens160/* @latonita | ||||||
|  | esphome/components/ens160_base/* @latonita @vincentscode | ||||||
|  | esphome/components/ens160_i2c/* @latonita | ||||||
|  | esphome/components/ens160_spi/* @latonita | ||||||
| esphome/components/ens210/* @itn3rd77 | esphome/components/ens210/* @itn3rd77 | ||||||
| esphome/components/esp32/* @esphome/core | esphome/components/esp32/* @esphome/core | ||||||
| esphome/components/esp32_ble/* @Rapsssito @jesserockz | esphome/components/esp32_ble/* @Rapsssito @jesserockz | ||||||
|   | |||||||
| @@ -1 +0,0 @@ | |||||||
| CODEOWNERS = ["@vincentscode"] |  | ||||||
|   | |||||||
| @@ -1,87 +1,7 @@ | |||||||
| import esphome.codegen as cg |  | ||||||
| import esphome.config_validation as cv | import esphome.config_validation as cv | ||||||
| from esphome.components import i2c, sensor |  | ||||||
| from esphome.const import ( | CODEOWNERS = ["@latonita"] | ||||||
|     CONF_COMPENSATION, |  | ||||||
|     CONF_ECO2, | CONFIG_SCHEMA = CONFIG_SCHEMA = cv.invalid( | ||||||
|     CONF_HUMIDITY, |     "The ens160 sensor component has been renamed to ens160_i2c." | ||||||
|     CONF_ID, |  | ||||||
|     CONF_TEMPERATURE, |  | ||||||
|     CONF_TVOC, |  | ||||||
|     DEVICE_CLASS_AQI, |  | ||||||
|     DEVICE_CLASS_CARBON_DIOXIDE, |  | ||||||
|     DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS_PARTS, |  | ||||||
|     ICON_CHEMICAL_WEAPON, |  | ||||||
|     ICON_MOLECULE_CO2, |  | ||||||
|     ICON_RADIATOR, |  | ||||||
|     STATE_CLASS_MEASUREMENT, |  | ||||||
|     UNIT_PARTS_PER_BILLION, |  | ||||||
|     UNIT_PARTS_PER_MILLION, |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| CODEOWNERS = ["@vincentscode"] |  | ||||||
| DEPENDENCIES = ["i2c"] |  | ||||||
|  |  | ||||||
| ens160_ns = cg.esphome_ns.namespace("ens160") |  | ||||||
| ENS160Component = ens160_ns.class_( |  | ||||||
|     "ENS160Component", cg.PollingComponent, i2c.I2CDevice, sensor.Sensor |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| CONF_AQI = "aqi" |  | ||||||
| UNIT_INDEX = "index" |  | ||||||
|  |  | ||||||
| CONFIG_SCHEMA = ( |  | ||||||
|     cv.Schema( |  | ||||||
|         { |  | ||||||
|             cv.GenerateID(): cv.declare_id(ENS160Component), |  | ||||||
|             cv.Required(CONF_ECO2): sensor.sensor_schema( |  | ||||||
|                 unit_of_measurement=UNIT_PARTS_PER_MILLION, |  | ||||||
|                 icon=ICON_MOLECULE_CO2, |  | ||||||
|                 accuracy_decimals=0, |  | ||||||
|                 device_class=DEVICE_CLASS_CARBON_DIOXIDE, |  | ||||||
|                 state_class=STATE_CLASS_MEASUREMENT, |  | ||||||
|             ), |  | ||||||
|             cv.Required(CONF_TVOC): sensor.sensor_schema( |  | ||||||
|                 unit_of_measurement=UNIT_PARTS_PER_BILLION, |  | ||||||
|                 icon=ICON_RADIATOR, |  | ||||||
|                 accuracy_decimals=0, |  | ||||||
|                 device_class=DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS_PARTS, |  | ||||||
|                 state_class=STATE_CLASS_MEASUREMENT, |  | ||||||
|             ), |  | ||||||
|             cv.Required(CONF_AQI): sensor.sensor_schema( |  | ||||||
|                 icon=ICON_CHEMICAL_WEAPON, |  | ||||||
|                 accuracy_decimals=0, |  | ||||||
|                 device_class=DEVICE_CLASS_AQI, |  | ||||||
|                 state_class=STATE_CLASS_MEASUREMENT, |  | ||||||
|             ), |  | ||||||
|             cv.Optional(CONF_COMPENSATION): cv.Schema( |  | ||||||
|                 { |  | ||||||
|                     cv.Required(CONF_TEMPERATURE): cv.use_id(sensor.Sensor), |  | ||||||
|                     cv.Required(CONF_HUMIDITY): cv.use_id(sensor.Sensor), |  | ||||||
|                 } |  | ||||||
|             ), |  | ||||||
|         } |  | ||||||
|     ) |  | ||||||
|     .extend(cv.polling_component_schema("60s")) |  | ||||||
|     .extend(i2c.i2c_device_schema(0x53)) |  | ||||||
| ) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| async def to_code(config): |  | ||||||
|     var = cg.new_Pvariable(config[CONF_ID]) |  | ||||||
|     await cg.register_component(var, config) |  | ||||||
|     await i2c.register_i2c_device(var, config) |  | ||||||
|  |  | ||||||
|     sens = await sensor.new_sensor(config[CONF_ECO2]) |  | ||||||
|     cg.add(var.set_co2(sens)) |  | ||||||
|     sens = await sensor.new_sensor(config[CONF_TVOC]) |  | ||||||
|     cg.add(var.set_tvoc(sens)) |  | ||||||
|     sens = await sensor.new_sensor(config[CONF_AQI]) |  | ||||||
|     cg.add(var.set_aqi(sens)) |  | ||||||
|  |  | ||||||
|     if CONF_COMPENSATION in config: |  | ||||||
|         compensation_config = config[CONF_COMPENSATION] |  | ||||||
|         sens = await cg.get_variable(compensation_config[CONF_TEMPERATURE]) |  | ||||||
|         cg.add(var.set_temperature(sens)) |  | ||||||
|         sens = await cg.get_variable(compensation_config[CONF_HUMIDITY]) |  | ||||||
|         cg.add(var.set_humidity(sens)) |  | ||||||
|   | |||||||
							
								
								
									
										78
									
								
								esphome/components/ens160_base/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								esphome/components/ens160_base/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | |||||||
|  | import esphome.codegen as cg | ||||||
|  | import esphome.config_validation as cv | ||||||
|  | from esphome.components import sensor | ||||||
|  | from esphome.const import ( | ||||||
|  |     CONF_COMPENSATION, | ||||||
|  |     CONF_ECO2, | ||||||
|  |     CONF_HUMIDITY, | ||||||
|  |     CONF_ID, | ||||||
|  |     CONF_TEMPERATURE, | ||||||
|  |     CONF_TVOC, | ||||||
|  |     DEVICE_CLASS_AQI, | ||||||
|  |     DEVICE_CLASS_CARBON_DIOXIDE, | ||||||
|  |     DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS_PARTS, | ||||||
|  |     ICON_CHEMICAL_WEAPON, | ||||||
|  |     ICON_MOLECULE_CO2, | ||||||
|  |     ICON_RADIATOR, | ||||||
|  |     STATE_CLASS_MEASUREMENT, | ||||||
|  |     UNIT_PARTS_PER_BILLION, | ||||||
|  |     UNIT_PARTS_PER_MILLION, | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | CODEOWNERS = ["@vincentscode", "@latonita"] | ||||||
|  |  | ||||||
|  | ens160_ns = cg.esphome_ns.namespace("ens160_base") | ||||||
|  |  | ||||||
|  | CONF_AQI = "aqi" | ||||||
|  | UNIT_INDEX = "index" | ||||||
|  |  | ||||||
|  | CONFIG_SCHEMA_BASE = cv.Schema( | ||||||
|  |     { | ||||||
|  |         cv.Required(CONF_ECO2): sensor.sensor_schema( | ||||||
|  |             unit_of_measurement=UNIT_PARTS_PER_MILLION, | ||||||
|  |             icon=ICON_MOLECULE_CO2, | ||||||
|  |             accuracy_decimals=0, | ||||||
|  |             device_class=DEVICE_CLASS_CARBON_DIOXIDE, | ||||||
|  |             state_class=STATE_CLASS_MEASUREMENT, | ||||||
|  |         ), | ||||||
|  |         cv.Required(CONF_TVOC): sensor.sensor_schema( | ||||||
|  |             unit_of_measurement=UNIT_PARTS_PER_BILLION, | ||||||
|  |             icon=ICON_RADIATOR, | ||||||
|  |             accuracy_decimals=0, | ||||||
|  |             device_class=DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS_PARTS, | ||||||
|  |             state_class=STATE_CLASS_MEASUREMENT, | ||||||
|  |         ), | ||||||
|  |         cv.Required(CONF_AQI): sensor.sensor_schema( | ||||||
|  |             icon=ICON_CHEMICAL_WEAPON, | ||||||
|  |             accuracy_decimals=0, | ||||||
|  |             device_class=DEVICE_CLASS_AQI, | ||||||
|  |             state_class=STATE_CLASS_MEASUREMENT, | ||||||
|  |         ), | ||||||
|  |         cv.Optional(CONF_COMPENSATION): cv.Schema( | ||||||
|  |             { | ||||||
|  |                 cv.Required(CONF_TEMPERATURE): cv.use_id(sensor.Sensor), | ||||||
|  |                 cv.Required(CONF_HUMIDITY): cv.use_id(sensor.Sensor), | ||||||
|  |             } | ||||||
|  |         ), | ||||||
|  |     } | ||||||
|  | ).extend(cv.polling_component_schema("60s")) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | async def to_code_base(config): | ||||||
|  |     var = cg.new_Pvariable(config[CONF_ID]) | ||||||
|  |     await cg.register_component(var, config) | ||||||
|  |  | ||||||
|  |     sens = await sensor.new_sensor(config[CONF_ECO2]) | ||||||
|  |     cg.add(var.set_co2(sens)) | ||||||
|  |     sens = await sensor.new_sensor(config[CONF_TVOC]) | ||||||
|  |     cg.add(var.set_tvoc(sens)) | ||||||
|  |     sens = await sensor.new_sensor(config[CONF_AQI]) | ||||||
|  |     cg.add(var.set_aqi(sens)) | ||||||
|  |  | ||||||
|  |     if compensation_config := config.get(CONF_COMPENSATION): | ||||||
|  |         sens = await cg.get_variable(compensation_config[CONF_TEMPERATURE]) | ||||||
|  |         cg.add(var.set_temperature(sens)) | ||||||
|  |         sens = await cg.get_variable(compensation_config[CONF_HUMIDITY]) | ||||||
|  |         cg.add(var.set_humidity(sens)) | ||||||
|  |  | ||||||
|  |     return var | ||||||
| @@ -5,12 +5,12 @@ | |||||||
| // Implementation based on:
 | // Implementation based on:
 | ||||||
| //   https://github.com/sciosense/ENS160_driver
 | //   https://github.com/sciosense/ENS160_driver
 | ||||||
| 
 | 
 | ||||||
| #include "ens160.h" | #include "ens160_base.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
| #include "esphome/core/hal.h" | #include "esphome/core/hal.h" | ||||||
| 
 | 
 | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace ens160 { | namespace ens160_base { | ||||||
| 
 | 
 | ||||||
| static const char *const TAG = "ens160"; | static const char *const TAG = "ens160"; | ||||||
| 
 | 
 | ||||||
| @@ -303,7 +303,6 @@ void ENS160Component::dump_config() { | |||||||
|   ESP_LOGI(TAG, "Firmware Version: %d.%d.%d", this->firmware_ver_major_, this->firmware_ver_minor_, |   ESP_LOGI(TAG, "Firmware Version: %d.%d.%d", this->firmware_ver_major_, this->firmware_ver_minor_, | ||||||
|            this->firmware_ver_build_); |            this->firmware_ver_build_); | ||||||
| 
 | 
 | ||||||
|   LOG_I2C_DEVICE(this); |  | ||||||
|   LOG_UPDATE_INTERVAL(this); |   LOG_UPDATE_INTERVAL(this); | ||||||
|   LOG_SENSOR("  ", "CO2 Sensor:", this->co2_); |   LOG_SENSOR("  ", "CO2 Sensor:", this->co2_); | ||||||
|   LOG_SENSOR("  ", "TVOC Sensor:", this->tvoc_); |   LOG_SENSOR("  ", "TVOC Sensor:", this->tvoc_); | ||||||
| @@ -317,5 +316,5 @@ void ENS160Component::dump_config() { | |||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| }  // namespace ens160
 | }  // namespace ens160_base
 | ||||||
| }  // namespace esphome
 | }  // namespace esphome
 | ||||||
| @@ -2,12 +2,11 @@ | |||||||
| 
 | 
 | ||||||
| #include "esphome/core/component.h" | #include "esphome/core/component.h" | ||||||
| #include "esphome/components/sensor/sensor.h" | #include "esphome/components/sensor/sensor.h" | ||||||
| #include "esphome/components/i2c/i2c.h" |  | ||||||
| 
 | 
 | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace ens160 { | namespace ens160_base { | ||||||
| 
 | 
 | ||||||
| class ENS160Component : public PollingComponent, public i2c::I2CDevice, public sensor::Sensor { | class ENS160Component : public PollingComponent, public sensor::Sensor { | ||||||
|  public: |  public: | ||||||
|   void set_co2(sensor::Sensor *co2) { co2_ = co2; } |   void set_co2(sensor::Sensor *co2) { co2_ = co2; } | ||||||
|   void set_tvoc(sensor::Sensor *tvoc) { tvoc_ = tvoc; } |   void set_tvoc(sensor::Sensor *tvoc) { tvoc_ = tvoc; } | ||||||
| @@ -44,6 +43,11 @@ class ENS160Component : public PollingComponent, public i2c::I2CDevice, public s | |||||||
|   bool warming_up_{false}; |   bool warming_up_{false}; | ||||||
|   bool initial_startup_{false}; |   bool initial_startup_{false}; | ||||||
| 
 | 
 | ||||||
|  |   virtual bool read_byte(uint8_t a_register, uint8_t *data) = 0; | ||||||
|  |   virtual bool write_byte(uint8_t a_register, uint8_t data) = 0; | ||||||
|  |   virtual bool read_bytes(uint8_t a_register, uint8_t *data, size_t len) = 0; | ||||||
|  |   virtual bool write_bytes(uint8_t a_register, uint8_t *data, size_t len) = 0; | ||||||
|  | 
 | ||||||
|   uint8_t firmware_ver_major_{0}; |   uint8_t firmware_ver_major_{0}; | ||||||
|   uint8_t firmware_ver_minor_{0}; |   uint8_t firmware_ver_minor_{0}; | ||||||
|   uint8_t firmware_ver_build_{0}; |   uint8_t firmware_ver_build_{0}; | ||||||
| @@ -56,5 +60,5 @@ class ENS160Component : public PollingComponent, public i2c::I2CDevice, public s | |||||||
|   sensor::Sensor *temperature_{nullptr}; |   sensor::Sensor *temperature_{nullptr}; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| }  // namespace ens160
 | }  // namespace ens160_base
 | ||||||
| }  // namespace esphome
 | }  // namespace esphome
 | ||||||
							
								
								
									
										0
									
								
								esphome/components/ens160_i2c/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								esphome/components/ens160_i2c/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										32
									
								
								esphome/components/ens160_i2c/ens160_i2c.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								esphome/components/ens160_i2c/ens160_i2c.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | |||||||
|  | #include <cstddef> | ||||||
|  | #include <cstdint> | ||||||
|  |  | ||||||
|  | #include "ens160_i2c.h" | ||||||
|  | #include "esphome/components/i2c/i2c.h" | ||||||
|  | #include "../ens160_base/ens160_base.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace ens160_i2c { | ||||||
|  |  | ||||||
|  | static const char *const TAG = "ens160_i2c.sensor"; | ||||||
|  |  | ||||||
|  | bool ENS160I2CComponent::read_byte(uint8_t a_register, uint8_t *data) { | ||||||
|  |   return I2CDevice::read_byte(a_register, data); | ||||||
|  | }; | ||||||
|  | bool ENS160I2CComponent::write_byte(uint8_t a_register, uint8_t data) { | ||||||
|  |   return I2CDevice::write_byte(a_register, data); | ||||||
|  | }; | ||||||
|  | bool ENS160I2CComponent::read_bytes(uint8_t a_register, uint8_t *data, size_t len) { | ||||||
|  |   return I2CDevice::read_bytes(a_register, data, len); | ||||||
|  | }; | ||||||
|  | bool ENS160I2CComponent::write_bytes(uint8_t a_register, uint8_t *data, size_t len) { | ||||||
|  |   return I2CDevice::write_bytes(a_register, data, len); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | void ENS160I2CComponent::dump_config() { | ||||||
|  |   ENS160Component::dump_config(); | ||||||
|  |   LOG_I2C_DEVICE(this); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace ens160_i2c | ||||||
|  | }  // namespace esphome | ||||||
							
								
								
									
										19
									
								
								esphome/components/ens160_i2c/ens160_i2c.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								esphome/components/ens160_i2c/ens160_i2c.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "esphome/components/ens160_base/ens160_base.h" | ||||||
|  | #include "esphome/components/i2c/i2c.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace ens160_i2c { | ||||||
|  |  | ||||||
|  | class ENS160I2CComponent : public esphome::ens160_base::ENS160Component, public i2c::I2CDevice { | ||||||
|  |   void dump_config() override; | ||||||
|  |  | ||||||
|  |   bool read_byte(uint8_t a_register, uint8_t *data) override; | ||||||
|  |   bool write_byte(uint8_t a_register, uint8_t data) override; | ||||||
|  |   bool read_bytes(uint8_t a_register, uint8_t *data, size_t len) override; | ||||||
|  |   bool write_bytes(uint8_t a_register, uint8_t *data, size_t len) override; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace ens160_i2c | ||||||
|  | }  // namespace esphome | ||||||
							
								
								
									
										22
									
								
								esphome/components/ens160_i2c/sensor.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								esphome/components/ens160_i2c/sensor.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | import esphome.codegen as cg | ||||||
|  | from esphome.components import i2c | ||||||
|  | from ..ens160_base import to_code_base, cv, CONFIG_SCHEMA_BASE | ||||||
|  |  | ||||||
|  | AUTO_LOAD = ["ens160_base"] | ||||||
|  | CODEOWNERS = ["@latonita"] | ||||||
|  | DEPENDENCIES = ["i2c"] | ||||||
|  |  | ||||||
|  | ens160_ns = cg.esphome_ns.namespace("ens160_i2c") | ||||||
|  |  | ||||||
|  | ENS160I2CComponent = ens160_ns.class_( | ||||||
|  |     "ENS160I2CComponent", cg.PollingComponent, i2c.I2CDevice | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | CONFIG_SCHEMA = CONFIG_SCHEMA_BASE.extend( | ||||||
|  |     i2c.i2c_device_schema(default_address=0x52) | ||||||
|  | ).extend({cv.GenerateID(): cv.declare_id(ENS160I2CComponent)}) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | async def to_code(config): | ||||||
|  |     var = await to_code_base(config) | ||||||
|  |     await i2c.register_i2c_device(var, config) | ||||||
							
								
								
									
										0
									
								
								esphome/components/ens160_spi/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								esphome/components/ens160_spi/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										59
									
								
								esphome/components/ens160_spi/ens160_spi.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								esphome/components/ens160_spi/ens160_spi.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | |||||||
|  | #include <cstdint> | ||||||
|  | #include <cstddef> | ||||||
|  |  | ||||||
|  | #include "ens160_spi.h" | ||||||
|  | #include <esphome/components/ens160_base/ens160_base.h> | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace ens160_spi { | ||||||
|  |  | ||||||
|  | static const char *const TAG = "ens160_spi.sensor"; | ||||||
|  |  | ||||||
|  | inline uint8_t reg_read(uint8_t reg) { return (reg << 1) | 0x01; } | ||||||
|  |  | ||||||
|  | inline uint8_t reg_write(uint8_t reg) { return (reg << 1) & 0xFE; } | ||||||
|  |  | ||||||
|  | void ENS160SPIComponent::setup() { | ||||||
|  |   this->spi_setup(); | ||||||
|  |   ENS160Component::setup(); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | void ENS160SPIComponent::dump_config() { | ||||||
|  |   ENS160Component::dump_config(); | ||||||
|  |   LOG_PIN("  CS Pin: ", this->cs_); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool ENS160SPIComponent::read_byte(uint8_t a_register, uint8_t *data) { | ||||||
|  |   this->enable(); | ||||||
|  |   this->transfer_byte(reg_read(a_register)); | ||||||
|  |   *data = this->transfer_byte(0); | ||||||
|  |   this->disable(); | ||||||
|  |   return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool ENS160SPIComponent::write_byte(uint8_t a_register, uint8_t data) { | ||||||
|  |   this->enable(); | ||||||
|  |   this->transfer_byte(reg_write(a_register)); | ||||||
|  |   this->transfer_byte(data); | ||||||
|  |   this->disable(); | ||||||
|  |   return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool ENS160SPIComponent::read_bytes(uint8_t a_register, uint8_t *data, size_t len) { | ||||||
|  |   this->enable(); | ||||||
|  |   this->transfer_byte(reg_read(a_register)); | ||||||
|  |   this->read_array(data, len); | ||||||
|  |   this->disable(); | ||||||
|  |   return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool ENS160SPIComponent::write_bytes(uint8_t a_register, uint8_t *data, size_t len) { | ||||||
|  |   this->enable(); | ||||||
|  |   this->transfer_byte(reg_write(a_register)); | ||||||
|  |   this->transfer_array(data, len); | ||||||
|  |   this->disable(); | ||||||
|  |   return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace ens160_spi | ||||||
|  | }  // namespace esphome | ||||||
							
								
								
									
										22
									
								
								esphome/components/ens160_spi/ens160_spi.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								esphome/components/ens160_spi/ens160_spi.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "esphome/components/ens160_base/ens160_base.h" | ||||||
|  | #include "esphome/components/spi/spi.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace ens160_spi { | ||||||
|  |  | ||||||
|  | class ENS160SPIComponent : public esphome::ens160_base::ENS160Component, | ||||||
|  |                            public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW, | ||||||
|  |                                                  spi::CLOCK_PHASE_LEADING, spi::DATA_RATE_200KHZ> { | ||||||
|  |   void setup() override; | ||||||
|  |   void dump_config() override; | ||||||
|  |  | ||||||
|  |   bool read_byte(uint8_t a_register, uint8_t *data) override; | ||||||
|  |   bool write_byte(uint8_t a_register, uint8_t data) override; | ||||||
|  |   bool read_bytes(uint8_t a_register, uint8_t *data, size_t len) override; | ||||||
|  |   bool write_bytes(uint8_t a_register, uint8_t *data, size_t len) override; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace ens160_spi | ||||||
|  | }  // namespace esphome | ||||||
							
								
								
									
										22
									
								
								esphome/components/ens160_spi/sensor.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								esphome/components/ens160_spi/sensor.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | import esphome.codegen as cg | ||||||
|  | from esphome.components import spi | ||||||
|  | from ..ens160_base import to_code_base, cv, CONFIG_SCHEMA_BASE | ||||||
|  |  | ||||||
|  | AUTO_LOAD = ["ens160_base"] | ||||||
|  | CODEOWNERS = ["@latonita"] | ||||||
|  | DEPENDENCIES = ["spi"] | ||||||
|  |  | ||||||
|  | ens160_spi_ns = cg.esphome_ns.namespace("ens160_spi") | ||||||
|  |  | ||||||
|  | ENS160SPIComponent = ens160_spi_ns.class_( | ||||||
|  |     "ENS160SPIComponent", cg.PollingComponent, spi.SPIDevice | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | CONFIG_SCHEMA = CONFIG_SCHEMA_BASE.extend(spi.spi_device_schema()).extend( | ||||||
|  |     {cv.GenerateID(): cv.declare_id(ENS160SPIComponent)} | ||||||
|  | ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | async def to_code(config): | ||||||
|  |     var = await to_code_base(config) | ||||||
|  |     await spi.register_spi_device(var, config) | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| i2c: |  | ||||||
|   - id: i2c_ens160 |  | ||||||
|     scl: 5 |  | ||||||
|     sda: 4 |  | ||||||
|  |  | ||||||
| sensor: |  | ||||||
|   - platform: ens160 |  | ||||||
|     eco2: |  | ||||||
|       name: ENS160 eCO2 |  | ||||||
|     tvoc: |  | ||||||
|       name: ENS160 Total Volatile Organic Compounds |  | ||||||
|     aqi: |  | ||||||
|       name: ENS160 Air Quality Index |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| i2c: |  | ||||||
|   - id: i2c_ens160 |  | ||||||
|     scl: 5 |  | ||||||
|     sda: 4 |  | ||||||
|  |  | ||||||
| sensor: |  | ||||||
|   - platform: ens160 |  | ||||||
|     eco2: |  | ||||||
|       name: ENS160 eCO2 |  | ||||||
|     tvoc: |  | ||||||
|       name: ENS160 Total Volatile Organic Compounds |  | ||||||
|     aqi: |  | ||||||
|       name: ENS160 Air Quality Index |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| i2c: |  | ||||||
|   - id: i2c_ens160 |  | ||||||
|     scl: 16 |  | ||||||
|     sda: 17 |  | ||||||
|  |  | ||||||
| sensor: |  | ||||||
|   - platform: ens160 |  | ||||||
|     eco2: |  | ||||||
|       name: ENS160 eCO2 |  | ||||||
|     tvoc: |  | ||||||
|       name: ENS160 Total Volatile Organic Compounds |  | ||||||
|     aqi: |  | ||||||
|       name: ENS160 Air Quality Index |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| i2c: |  | ||||||
|   - id: i2c_ens160 |  | ||||||
|     scl: 16 |  | ||||||
|     sda: 17 |  | ||||||
|  |  | ||||||
| sensor: |  | ||||||
|   - platform: ens160 |  | ||||||
|     eco2: |  | ||||||
|       name: ENS160 eCO2 |  | ||||||
|     tvoc: |  | ||||||
|       name: ENS160 Total Volatile Organic Compounds |  | ||||||
|     aqi: |  | ||||||
|       name: ENS160 Air Quality Index |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| i2c: |  | ||||||
|   - id: i2c_ens160 |  | ||||||
|     scl: 5 |  | ||||||
|     sda: 4 |  | ||||||
|  |  | ||||||
| sensor: |  | ||||||
|   - platform: ens160 |  | ||||||
|     eco2: |  | ||||||
|       name: ENS160 eCO2 |  | ||||||
|     tvoc: |  | ||||||
|       name: ENS160 Total Volatile Organic Compounds |  | ||||||
|     aqi: |  | ||||||
|       name: ENS160 Air Quality Index |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| i2c: |  | ||||||
|   - id: i2c_ens160 |  | ||||||
|     scl: 5 |  | ||||||
|     sda: 4 |  | ||||||
|  |  | ||||||
| sensor: |  | ||||||
|   - platform: ens160 |  | ||||||
|     eco2: |  | ||||||
|       name: ENS160 eCO2 |  | ||||||
|     tvoc: |  | ||||||
|       name: ENS160 Total Volatile Organic Compounds |  | ||||||
|     aqi: |  | ||||||
|       name: ENS160 Air Quality Index |  | ||||||
							
								
								
									
										15
									
								
								tests/components/ens160_i2c/common.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								tests/components/ens160_i2c/common.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | i2c: | ||||||
|  |   - id: i2c_ens160 | ||||||
|  |     scl: ${scl_pin} | ||||||
|  |     sda: ${sda_pin} | ||||||
|  |  | ||||||
|  | sensor: | ||||||
|  |   - platform: ens160_i2c | ||||||
|  |     i2c_id: i2c_ens160 | ||||||
|  |     address: 0x53 | ||||||
|  |     eco2: | ||||||
|  |       name: "ENS160 eCO2" | ||||||
|  |     tvoc: | ||||||
|  |       name: "ENS160 Total Volatile Organic Compounds" | ||||||
|  |     aqi: | ||||||
|  |       name: "ENS160 Air Quality Index" | ||||||
							
								
								
									
										5
									
								
								tests/components/ens160_i2c/test.esp32-c3-idf.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/components/ens160_i2c/test.esp32-c3-idf.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | substitutions: | ||||||
|  |   scl_pin: GPIO5 | ||||||
|  |   sda_pin: GPIO4 | ||||||
|  |  | ||||||
|  | <<: !include common.yaml | ||||||
							
								
								
									
										5
									
								
								tests/components/ens160_i2c/test.esp32-c3.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/components/ens160_i2c/test.esp32-c3.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | substitutions: | ||||||
|  |   scl_pin: GPIO5 | ||||||
|  |   sda_pin: GPIO4 | ||||||
|  |  | ||||||
|  | <<: !include common.yaml | ||||||
							
								
								
									
										5
									
								
								tests/components/ens160_i2c/test.esp32-idf.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/components/ens160_i2c/test.esp32-idf.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | substitutions: | ||||||
|  |   scl_pin: GPIO16 | ||||||
|  |   sda_pin: GPIO17 | ||||||
|  |  | ||||||
|  | <<: !include common.yaml | ||||||
							
								
								
									
										5
									
								
								tests/components/ens160_i2c/test.esp32.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/components/ens160_i2c/test.esp32.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | substitutions: | ||||||
|  |   scl_pin: GPIO16 | ||||||
|  |   sda_pin: GPIO17 | ||||||
|  |  | ||||||
|  | <<: !include common.yaml | ||||||
							
								
								
									
										5
									
								
								tests/components/ens160_i2c/test.esp8266.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/components/ens160_i2c/test.esp8266.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | substitutions: | ||||||
|  |   scl_pin: GPIO5 | ||||||
|  |   sda_pin: GPIO4 | ||||||
|  |  | ||||||
|  | <<: !include common.yaml | ||||||
							
								
								
									
										5
									
								
								tests/components/ens160_i2c/test.rp2040.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/components/ens160_i2c/test.rp2040.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | substitutions: | ||||||
|  |   scl_pin: GPIO5 | ||||||
|  |   sda_pin: GPIO4 | ||||||
|  |  | ||||||
|  | <<: !include common.yaml | ||||||
							
								
								
									
										17
									
								
								tests/components/ens160_spi/common.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								tests/components/ens160_spi/common.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | spi: | ||||||
|  |   - id: spi_ens160 | ||||||
|  |     clk_pin: ${clk_pin} | ||||||
|  |     mosi_pin: ${mosi_pin} | ||||||
|  |     miso_pin: ${miso_pin} | ||||||
|  |  | ||||||
|  | sensor: | ||||||
|  |   - platform: ens160_spi | ||||||
|  |     spi_id: spi_ens160 | ||||||
|  |     cs_pin: ${cs_pin} | ||||||
|  |     eco2: | ||||||
|  |       name: "ENS160 eCO2" | ||||||
|  |     tvoc: | ||||||
|  |       name: "ENS160 Total Volatile Organic Compounds" | ||||||
|  |     aqi: | ||||||
|  |       name: "ENS160 Air Quality Index" | ||||||
|  |  | ||||||
							
								
								
									
										7
									
								
								tests/components/ens160_spi/test.esp32-c3-idf.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								tests/components/ens160_spi/test.esp32-c3-idf.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | substitutions: | ||||||
|  |   clk_pin: GPIO6 | ||||||
|  |   mosi_pin: GPIO7 | ||||||
|  |   miso_pin: GPIO5 | ||||||
|  |   cs_pin: GPIO8 | ||||||
|  |  | ||||||
|  | <<: !include common.yaml | ||||||
							
								
								
									
										7
									
								
								tests/components/ens160_spi/test.esp32-c3.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								tests/components/ens160_spi/test.esp32-c3.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | substitutions: | ||||||
|  |   clk_pin: GPIO6 | ||||||
|  |   mosi_pin: GPIO7 | ||||||
|  |   miso_pin: GPIO5 | ||||||
|  |   cs_pin: GPIO8 | ||||||
|  |  | ||||||
|  | <<: !include common.yaml | ||||||
							
								
								
									
										7
									
								
								tests/components/ens160_spi/test.esp32-idf.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								tests/components/ens160_spi/test.esp32-idf.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | substitutions: | ||||||
|  |   clk_pin: GPIO16 | ||||||
|  |   mosi_pin: GPIO17 | ||||||
|  |   miso_pin: GPIO15 | ||||||
|  |   cs_pin: GPIO5 | ||||||
|  |  | ||||||
|  | <<: !include common.yaml | ||||||
							
								
								
									
										7
									
								
								tests/components/ens160_spi/test.esp32.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								tests/components/ens160_spi/test.esp32.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | substitutions: | ||||||
|  |   clk_pin: GPIO16 | ||||||
|  |   mosi_pin: GPIO17 | ||||||
|  |   miso_pin: GPIO15 | ||||||
|  |   cs_pin: GPIO5 | ||||||
|  |  | ||||||
|  | <<: !include common.yaml | ||||||
							
								
								
									
										7
									
								
								tests/components/ens160_spi/test.esp8266.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								tests/components/ens160_spi/test.esp8266.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | substitutions: | ||||||
|  |   clk_pin: GPIO14 | ||||||
|  |   mosi_pin: GPIO13 | ||||||
|  |   miso_pin: GPIO12 | ||||||
|  |   cs_pin: GPIO15 | ||||||
|  |  | ||||||
|  | <<: !include common.yaml | ||||||
							
								
								
									
										7
									
								
								tests/components/ens160_spi/test.rp2040.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								tests/components/ens160_spi/test.rp2040.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | substitutions: | ||||||
|  |   clk_pin: GPIO2 | ||||||
|  |   mosi_pin: GPIO3 | ||||||
|  |   miso_pin: GPIO4 | ||||||
|  |   cs_pin: GPIO5 | ||||||
|  |  | ||||||
|  | <<: !include common.yaml | ||||||
| @@ -245,13 +245,6 @@ sensor: | |||||||
|       name: "ADE7953 Reactive Power B" |       name: "ADE7953 Reactive Power B" | ||||||
|     update_interval: 1s |     update_interval: 1s | ||||||
|  |  | ||||||
|   - platform: ens160 |  | ||||||
|     eco2: |  | ||||||
|       name: "ENS160 eCO2" |  | ||||||
|     tvoc: |  | ||||||
|       name: "ENS160 Total Volatile Organic Compounds" |  | ||||||
|     aqi: |  | ||||||
|       name: "ENS160 Air Quality Index" |  | ||||||
|   - platform: tmp102 |   - platform: tmp102 | ||||||
|     name: TMP102 Temperature |     name: TMP102 Temperature | ||||||
|   - platform: hm3301 |   - platform: hm3301 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user