mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	Merge remote-tracking branch 'upstream/dev' into ci_impact_analysis
This commit is contained in:
		| @@ -3,6 +3,7 @@ from esphome.components import i2c, sensor | |||||||
| import esphome.config_validation as cv | import esphome.config_validation as cv | ||||||
| from esphome.const import ( | from esphome.const import ( | ||||||
|     CONF_ID, |     CONF_ID, | ||||||
|  |     CONF_OVERSAMPLING, | ||||||
|     CONF_PRESSURE, |     CONF_PRESSURE, | ||||||
|     CONF_TEMPERATURE, |     CONF_TEMPERATURE, | ||||||
|     DEVICE_CLASS_PRESSURE, |     DEVICE_CLASS_PRESSURE, | ||||||
| @@ -18,6 +19,17 @@ CODEOWNERS = ["@gcormier"] | |||||||
| CONF_K_VALUE = "k_value" | CONF_K_VALUE = "k_value" | ||||||
|  |  | ||||||
| xgzp68xx_ns = cg.esphome_ns.namespace("xgzp68xx") | xgzp68xx_ns = cg.esphome_ns.namespace("xgzp68xx") | ||||||
|  | XGZP68XXOversampling = xgzp68xx_ns.enum("XGZP68XXOversampling") | ||||||
|  | OVERSAMPLING_OPTIONS = { | ||||||
|  |     "256X": XGZP68XXOversampling.XGZP68XX_OVERSAMPLING_256X, | ||||||
|  |     "512X": XGZP68XXOversampling.XGZP68XX_OVERSAMPLING_512X, | ||||||
|  |     "1024X": XGZP68XXOversampling.XGZP68XX_OVERSAMPLING_1024X, | ||||||
|  |     "2048X": XGZP68XXOversampling.XGZP68XX_OVERSAMPLING_2048X, | ||||||
|  |     "4096X": XGZP68XXOversampling.XGZP68XX_OVERSAMPLING_4096X, | ||||||
|  |     "8192X": XGZP68XXOversampling.XGZP68XX_OVERSAMPLING_8192X, | ||||||
|  |     "16384X": XGZP68XXOversampling.XGZP68XX_OVERSAMPLING_16384X, | ||||||
|  |     "32768X": XGZP68XXOversampling.XGZP68XX_OVERSAMPLING_32768X, | ||||||
|  | } | ||||||
| XGZP68XXComponent = xgzp68xx_ns.class_( | XGZP68XXComponent = xgzp68xx_ns.class_( | ||||||
|     "XGZP68XXComponent", cg.PollingComponent, i2c.I2CDevice |     "XGZP68XXComponent", cg.PollingComponent, i2c.I2CDevice | ||||||
| ) | ) | ||||||
| @@ -31,6 +43,12 @@ CONFIG_SCHEMA = ( | |||||||
|                 accuracy_decimals=1, |                 accuracy_decimals=1, | ||||||
|                 device_class=DEVICE_CLASS_PRESSURE, |                 device_class=DEVICE_CLASS_PRESSURE, | ||||||
|                 state_class=STATE_CLASS_MEASUREMENT, |                 state_class=STATE_CLASS_MEASUREMENT, | ||||||
|  |             ).extend( | ||||||
|  |                 { | ||||||
|  |                     cv.Optional(CONF_OVERSAMPLING, default="4096X"): cv.enum( | ||||||
|  |                         OVERSAMPLING_OPTIONS, upper=True | ||||||
|  |                     ), | ||||||
|  |                 } | ||||||
|             ), |             ), | ||||||
|             cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema( |             cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema( | ||||||
|                 unit_of_measurement=UNIT_CELSIUS, |                 unit_of_measurement=UNIT_CELSIUS, | ||||||
| @@ -58,5 +76,6 @@ async def to_code(config): | |||||||
|     if pressure_config := config.get(CONF_PRESSURE): |     if pressure_config := config.get(CONF_PRESSURE): | ||||||
|         sens = await sensor.new_sensor(pressure_config) |         sens = await sensor.new_sensor(pressure_config) | ||||||
|         cg.add(var.set_pressure_sensor(sens)) |         cg.add(var.set_pressure_sensor(sens)) | ||||||
|  |         cg.add(var.set_pressure_oversampling(pressure_config[CONF_OVERSAMPLING])) | ||||||
|  |  | ||||||
|     cg.add(var.set_k_value(config[CONF_K_VALUE])) |     cg.add(var.set_k_value(config[CONF_K_VALUE])) | ||||||
|   | |||||||
| @@ -16,16 +16,49 @@ static const uint8_t SYSCONFIG_ADDRESS = 0xA5; | |||||||
| static const uint8_t PCONFIG_ADDRESS = 0xA6; | static const uint8_t PCONFIG_ADDRESS = 0xA6; | ||||||
| static const uint8_t READ_COMMAND = 0x0A; | static const uint8_t READ_COMMAND = 0x0A; | ||||||
|  |  | ||||||
|  | [[maybe_unused]] static const char *oversampling_to_str(XGZP68XXOversampling oversampling) { | ||||||
|  |   switch (oversampling) { | ||||||
|  |     case XGZP68XX_OVERSAMPLING_256X: | ||||||
|  |       return "256x"; | ||||||
|  |     case XGZP68XX_OVERSAMPLING_512X: | ||||||
|  |       return "512x"; | ||||||
|  |     case XGZP68XX_OVERSAMPLING_1024X: | ||||||
|  |       return "1024x"; | ||||||
|  |     case XGZP68XX_OVERSAMPLING_2048X: | ||||||
|  |       return "2048x"; | ||||||
|  |     case XGZP68XX_OVERSAMPLING_4096X: | ||||||
|  |       return "4096x"; | ||||||
|  |     case XGZP68XX_OVERSAMPLING_8192X: | ||||||
|  |       return "8192x"; | ||||||
|  |     case XGZP68XX_OVERSAMPLING_16384X: | ||||||
|  |       return "16384x"; | ||||||
|  |     case XGZP68XX_OVERSAMPLING_32768X: | ||||||
|  |       return "32768x"; | ||||||
|  |     default: | ||||||
|  |       return "UNKNOWN"; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| void XGZP68XXComponent::update() { | void XGZP68XXComponent::update() { | ||||||
|  |   // Do we need to change oversampling? | ||||||
|  |   if (this->last_pressure_oversampling_ != this->pressure_oversampling_) { | ||||||
|  |     uint8_t oldconfig = 0; | ||||||
|  |     this->read_register(PCONFIG_ADDRESS, &oldconfig, 1); | ||||||
|  |     uint8_t newconfig = (oldconfig & 0xf8) | (this->pressure_oversampling_ & 0x7); | ||||||
|  |     this->write_register(PCONFIG_ADDRESS, &newconfig, 1); | ||||||
|  |     ESP_LOGD(TAG, "oversampling to %s: oldconfig = 0x%x newconfig = 0x%x", | ||||||
|  |              oversampling_to_str(this->pressure_oversampling_), oldconfig, newconfig); | ||||||
|  |     this->last_pressure_oversampling_ = this->pressure_oversampling_; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   // Request temp + pressure acquisition |   // Request temp + pressure acquisition | ||||||
|   this->write_register(0x30, &READ_COMMAND, 1); |   this->write_register(0x30, &READ_COMMAND, 1); | ||||||
|  |  | ||||||
|   // Wait 20mS per datasheet |   // Wait 20mS per datasheet | ||||||
|   this->set_timeout("measurement", 20, [this]() { |   this->set_timeout("measurement", 20, [this]() { | ||||||
|     uint8_t data[5]; |     uint8_t data[5] = {}; | ||||||
|     uint32_t pressure_raw; |     uint32_t pressure_raw = 0; | ||||||
|     uint16_t temperature_raw; |     uint16_t temperature_raw = 0; | ||||||
|     float pressure_in_pa, temperature; |  | ||||||
|     int success; |     int success; | ||||||
|  |  | ||||||
|     // Read the sensor data |     // Read the sensor data | ||||||
| @@ -42,23 +75,11 @@ void XGZP68XXComponent::update() { | |||||||
|     ESP_LOGV(TAG, "Got raw pressure=%" PRIu32 ", raw temperature=%u", pressure_raw, temperature_raw); |     ESP_LOGV(TAG, "Got raw pressure=%" PRIu32 ", raw temperature=%u", pressure_raw, temperature_raw); | ||||||
|     ESP_LOGV(TAG, "K value is %u", this->k_value_); |     ESP_LOGV(TAG, "K value is %u", this->k_value_); | ||||||
|  |  | ||||||
|     // The most significant bit of both pressure and temperature will be 1 to indicate a negative value. |     // Sign extend the pressure | ||||||
|     // This is directly from the datasheet, and the calculations below will handle this. |     float pressure_in_pa = (float) (((int32_t) pressure_raw << 8) >> 8); | ||||||
|     if (pressure_raw > pow(2, 23)) { |     pressure_in_pa /= (float) (this->k_value_); | ||||||
|       // Negative pressure |  | ||||||
|       pressure_in_pa = (pressure_raw - pow(2, 24)) / (float) (this->k_value_); |  | ||||||
|     } else { |  | ||||||
|       // Positive pressure |  | ||||||
|       pressure_in_pa = pressure_raw / (float) (this->k_value_); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (temperature_raw > pow(2, 15)) { |     float temperature = ((float) (int16_t) temperature_raw) / 256.0f; | ||||||
|       // Negative temperature |  | ||||||
|       temperature = (float) (temperature_raw - pow(2, 16)) / 256.0f; |  | ||||||
|     } else { |  | ||||||
|       // Positive temperature |  | ||||||
|       temperature = (float) temperature_raw / 256.0f; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (this->pressure_sensor_ != nullptr) |     if (this->pressure_sensor_ != nullptr) | ||||||
|       this->pressure_sensor_->publish_state(pressure_in_pa); |       this->pressure_sensor_->publish_state(pressure_in_pa); | ||||||
| @@ -69,20 +90,27 @@ void XGZP68XXComponent::update() { | |||||||
| } | } | ||||||
|  |  | ||||||
| void XGZP68XXComponent::setup() { | void XGZP68XXComponent::setup() { | ||||||
|   uint8_t config; |   uint8_t config1 = 0, config2 = 0; | ||||||
|  |  | ||||||
|   // Display some sample bits to confirm we are talking to the sensor |   // Display some sample bits to confirm we are talking to the sensor | ||||||
|   this->read_register(SYSCONFIG_ADDRESS, &config, 1); |   if (i2c::ErrorCode::ERROR_OK != this->read_register(SYSCONFIG_ADDRESS, &config1, 1)) { | ||||||
|   ESP_LOGCONFIG(TAG, |     this->mark_failed(); | ||||||
|                 "Gain value is %d\n" |     return; | ||||||
|                 "XGZP68xx started!", |   } | ||||||
|                 (config >> 3) & 0b111); |   if (i2c::ErrorCode::ERROR_OK != this->read_register(PCONFIG_ADDRESS, &config2, 1)) { | ||||||
|  |     this->mark_failed(); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   ESP_LOGD(TAG, "sys_config 0x%x, p_config 0x%x", config1, config2); | ||||||
| } | } | ||||||
|  |  | ||||||
| void XGZP68XXComponent::dump_config() { | void XGZP68XXComponent::dump_config() { | ||||||
|   ESP_LOGCONFIG(TAG, "XGZP68xx:"); |   ESP_LOGCONFIG(TAG, "XGZP68xx:"); | ||||||
|   LOG_SENSOR("  ", "Temperature: ", this->temperature_sensor_); |   LOG_SENSOR("  ", "Temperature: ", this->temperature_sensor_); | ||||||
|   LOG_SENSOR("  ", "Pressure: ", this->pressure_sensor_); |   LOG_SENSOR("  ", "Pressure: ", this->pressure_sensor_); | ||||||
|  |   if (this->pressure_sensor_ != nullptr) { | ||||||
|  |     ESP_LOGCONFIG(TAG, "    Oversampling: %s", oversampling_to_str(this->pressure_oversampling_)); | ||||||
|  |   } | ||||||
|   LOG_I2C_DEVICE(this); |   LOG_I2C_DEVICE(this); | ||||||
|   if (this->is_failed()) { |   if (this->is_failed()) { | ||||||
|     ESP_LOGE(TAG, "  Connection failed"); |     ESP_LOGE(TAG, "  Connection failed"); | ||||||
|   | |||||||
| @@ -7,11 +7,29 @@ | |||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace xgzp68xx { | namespace xgzp68xx { | ||||||
|  |  | ||||||
|  | /// Enum listing all oversampling options for the XGZP68XX. | ||||||
|  | enum XGZP68XXOversampling : uint8_t { | ||||||
|  |   XGZP68XX_OVERSAMPLING_256X = 0b100, | ||||||
|  |   XGZP68XX_OVERSAMPLING_512X = 0b101, | ||||||
|  |   XGZP68XX_OVERSAMPLING_1024X = 0b000, | ||||||
|  |   XGZP68XX_OVERSAMPLING_2048X = 0b001, | ||||||
|  |   XGZP68XX_OVERSAMPLING_4096X = 0b010, | ||||||
|  |   XGZP68XX_OVERSAMPLING_8192X = 0b011, | ||||||
|  |   XGZP68XX_OVERSAMPLING_16384X = 0b110, | ||||||
|  |   XGZP68XX_OVERSAMPLING_32768X = 0b111, | ||||||
|  |  | ||||||
|  |   XGZP68XX_OVERSAMPLING_UNKNOWN = (uint8_t) -1, | ||||||
|  | }; | ||||||
|  |  | ||||||
| class XGZP68XXComponent : public PollingComponent, public sensor::Sensor, public i2c::I2CDevice { | class XGZP68XXComponent : public PollingComponent, public sensor::Sensor, public i2c::I2CDevice { | ||||||
|  public: |  public: | ||||||
|   SUB_SENSOR(temperature) |   SUB_SENSOR(temperature) | ||||||
|   SUB_SENSOR(pressure) |   SUB_SENSOR(pressure) | ||||||
|   void set_k_value(uint16_t k_value) { this->k_value_ = k_value; } |   void set_k_value(uint16_t k_value) { this->k_value_ = k_value; } | ||||||
|  |   /// Set the pressure oversampling value. Defaults to 4096X. | ||||||
|  |   void set_pressure_oversampling(XGZP68XXOversampling pressure_oversampling) { | ||||||
|  |     this->pressure_oversampling_ = pressure_oversampling; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   void update() override; |   void update() override; | ||||||
|   void setup() override; |   void setup() override; | ||||||
| @@ -21,6 +39,8 @@ class XGZP68XXComponent : public PollingComponent, public sensor::Sensor, public | |||||||
|   /// Internal method to read the pressure from the component after it has been scheduled. |   /// Internal method to read the pressure from the component after it has been scheduled. | ||||||
|   void read_pressure_(); |   void read_pressure_(); | ||||||
|   uint16_t k_value_; |   uint16_t k_value_; | ||||||
|  |   XGZP68XXOversampling pressure_oversampling_{XGZP68XX_OVERSAMPLING_4096X}; | ||||||
|  |   XGZP68XXOversampling last_pressure_oversampling_{XGZP68XX_OVERSAMPLING_UNKNOWN}; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace xgzp68xx | }  // namespace xgzp68xx | ||||||
|   | |||||||
| @@ -6,3 +6,4 @@ sensor: | |||||||
|       name: Pressure Temperature |       name: Pressure Temperature | ||||||
|     pressure: |     pressure: | ||||||
|       name: Differential pressure |       name: Differential pressure | ||||||
|  |       oversampling: 1024x | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user