diff --git a/esphome/components/sm300d2/sm300d2.cpp b/esphome/components/sm300d2/sm300d2.cpp index d542582fcb..e41a4855db 100644 --- a/esphome/components/sm300d2/sm300d2.cpp +++ b/esphome/components/sm300d2/sm300d2.cpp @@ -29,8 +29,11 @@ void SM300D2Sensor::update() { } uint16_t calculated_checksum = this->sm300d2_checksum_(response); + // Occasionally the checksum has a +/- 0x80 offset. Negative temperatures are + // responsible for some of these. The rest are unknown/undocumented. if ((calculated_checksum != response[SM300D2_RESPONSE_LENGTH - 1]) && - (calculated_checksum - 0x80 != response[SM300D2_RESPONSE_LENGTH - 1])) { + (calculated_checksum - 0x80 != response[SM300D2_RESPONSE_LENGTH - 1]) && + (calculated_checksum + 0x80 != response[SM300D2_RESPONSE_LENGTH - 1])) { ESP_LOGW(TAG, "SM300D2 Checksum doesn't match: 0x%02X!=0x%02X", response[SM300D2_RESPONSE_LENGTH - 1], calculated_checksum); this->status_set_warning(); @@ -46,7 +49,10 @@ void SM300D2Sensor::update() { const uint16_t tvoc = (response[6] * 256) + response[7]; const uint16_t pm_2_5 = (response[8] * 256) + response[9]; const uint16_t pm_10_0 = (response[10] * 256) + response[11]; - const float temperature = response[12] + (response[13] * 0.1); + // A negative value is indicated by adding 0x80 (128) to the temperature value + const float temperature = ((response[12] + (response[13] * 0.1)) > 128) + ? (((response[12] + (response[13] * 0.1)) - 128) * -1) + : response[12] + (response[13] * 0.1); const float humidity = response[14] + (response[15] * 0.1); ESP_LOGD(TAG, "Received CO₂: %u ppm", co2);