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 | ||||
| from esphome.const import ( | ||||
|     CONF_ID, | ||||
|     CONF_OVERSAMPLING, | ||||
|     CONF_PRESSURE, | ||||
|     CONF_TEMPERATURE, | ||||
|     DEVICE_CLASS_PRESSURE, | ||||
| @@ -18,6 +19,17 @@ CODEOWNERS = ["@gcormier"] | ||||
| CONF_K_VALUE = "k_value" | ||||
|  | ||||
| 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", cg.PollingComponent, i2c.I2CDevice | ||||
| ) | ||||
| @@ -31,6 +43,12 @@ CONFIG_SCHEMA = ( | ||||
|                 accuracy_decimals=1, | ||||
|                 device_class=DEVICE_CLASS_PRESSURE, | ||||
|                 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( | ||||
|                 unit_of_measurement=UNIT_CELSIUS, | ||||
| @@ -58,5 +76,6 @@ async def to_code(config): | ||||
|     if pressure_config := config.get(CONF_PRESSURE): | ||||
|         sens = await sensor.new_sensor(pressure_config) | ||||
|         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])) | ||||
|   | ||||
| @@ -16,16 +16,49 @@ static const uint8_t SYSCONFIG_ADDRESS = 0xA5; | ||||
| static const uint8_t PCONFIG_ADDRESS = 0xA6; | ||||
| 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() { | ||||
|   // 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 | ||||
|   this->write_register(0x30, &READ_COMMAND, 1); | ||||
|  | ||||
|   // Wait 20mS per datasheet | ||||
|   this->set_timeout("measurement", 20, [this]() { | ||||
|     uint8_t data[5]; | ||||
|     uint32_t pressure_raw; | ||||
|     uint16_t temperature_raw; | ||||
|     float pressure_in_pa, temperature; | ||||
|     uint8_t data[5] = {}; | ||||
|     uint32_t pressure_raw = 0; | ||||
|     uint16_t temperature_raw = 0; | ||||
|     int success; | ||||
|  | ||||
|     // 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, "K value is %u", this->k_value_); | ||||
|  | ||||
|     // The most significant bit of both pressure and temperature will be 1 to indicate a negative value. | ||||
|     // This is directly from the datasheet, and the calculations below will handle this. | ||||
|     if (pressure_raw > pow(2, 23)) { | ||||
|       // 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_); | ||||
|     } | ||||
|     // Sign extend the pressure | ||||
|     float pressure_in_pa = (float) (((int32_t) pressure_raw << 8) >> 8); | ||||
|     pressure_in_pa /= (float) (this->k_value_); | ||||
|  | ||||
|     if (temperature_raw > pow(2, 15)) { | ||||
|       // Negative temperature | ||||
|       temperature = (float) (temperature_raw - pow(2, 16)) / 256.0f; | ||||
|     } else { | ||||
|       // Positive temperature | ||||
|       temperature = (float) temperature_raw / 256.0f; | ||||
|     } | ||||
|     float temperature = ((float) (int16_t) temperature_raw) / 256.0f; | ||||
|  | ||||
|     if (this->pressure_sensor_ != nullptr) | ||||
|       this->pressure_sensor_->publish_state(pressure_in_pa); | ||||
| @@ -69,20 +90,27 @@ void XGZP68XXComponent::update() { | ||||
| } | ||||
|  | ||||
| void XGZP68XXComponent::setup() { | ||||
|   uint8_t config; | ||||
|   uint8_t config1 = 0, config2 = 0; | ||||
|  | ||||
|   // Display some sample bits to confirm we are talking to the sensor | ||||
|   this->read_register(SYSCONFIG_ADDRESS, &config, 1); | ||||
|   ESP_LOGCONFIG(TAG, | ||||
|                 "Gain value is %d\n" | ||||
|                 "XGZP68xx started!", | ||||
|                 (config >> 3) & 0b111); | ||||
|   if (i2c::ErrorCode::ERROR_OK != this->read_register(SYSCONFIG_ADDRESS, &config1, 1)) { | ||||
|     this->mark_failed(); | ||||
|     return; | ||||
|   } | ||||
|   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() { | ||||
|   ESP_LOGCONFIG(TAG, "XGZP68xx:"); | ||||
|   LOG_SENSOR("  ", "Temperature: ", this->temperature_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); | ||||
|   if (this->is_failed()) { | ||||
|     ESP_LOGE(TAG, "  Connection failed"); | ||||
|   | ||||
| @@ -7,11 +7,29 @@ | ||||
| namespace esphome { | ||||
| 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 { | ||||
|  public: | ||||
|   SUB_SENSOR(temperature) | ||||
|   SUB_SENSOR(pressure) | ||||
|   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 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. | ||||
|   void read_pressure_(); | ||||
|   uint16_t k_value_; | ||||
|   XGZP68XXOversampling pressure_oversampling_{XGZP68XX_OVERSAMPLING_4096X}; | ||||
|   XGZP68XXOversampling last_pressure_oversampling_{XGZP68XX_OVERSAMPLING_UNKNOWN}; | ||||
| }; | ||||
|  | ||||
| }  // namespace xgzp68xx | ||||
|   | ||||
| @@ -6,3 +6,4 @@ sensor: | ||||
|       name: Pressure Temperature | ||||
|     pressure: | ||||
|       name: Differential pressure | ||||
|       oversampling: 1024x | ||||
|   | ||||
		Reference in New Issue
	
	Block a user