From 1833318bde1138203a453d2c0f1d2edc10ed0e56 Mon Sep 17 00:00:00 2001 From: Michael Lass Date: Tue, 28 Jan 2020 21:13:37 +0100 Subject: [PATCH 1/3] Do not update sensor values on error Currently, we update self._temperature and self._humidity, even if it turns out that the data returned by the sensor was bogus. If the user queries the data within two seconds after an error, they will actually get wrong data. Fix this by updating _temperature and _humidity attributes only if no error was detected. --- adafruit_dht.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/adafruit_dht.py b/adafruit_dht.py index 4c9083f..2f3c473 100644 --- a/adafruit_dht.py +++ b/adafruit_dht.py @@ -180,6 +180,9 @@ def measure(self): ): self._last_called = time.monotonic() + new_temperature = 0 + new_humidity = 0 + if _USE_PULSEIO: pulses = self._get_pulses_pulseio() else: @@ -195,19 +198,19 @@ def measure(self): if self._dht11: # humidity is 1 byte - self._humidity = buf[0] + new_humidity = buf[0] # temperature is 1 byte - self._temperature = buf[2] + new_temperature = buf[2] else: # humidity is 2 bytes - self._humidity = ((buf[0] << 8) | buf[1]) / 10 + new_humidity = ((buf[0] << 8) | buf[1]) / 10 # temperature is 2 bytes # MSB is sign, bits 0-14 are magnitude) raw_temperature = (((buf[2] & 0x7F) << 8) | buf[3]) / 10 # set sign if buf[2] & 0x80: raw_temperature = -raw_temperature - self._temperature = raw_temperature + new_temperature = raw_temperature # calc checksum chk_sum = 0 for b in buf[0:4]: @@ -220,11 +223,14 @@ def measure(self): elif len(pulses) >= 10: # We got *some* data just not 81 bits - raise RuntimeError("A full buffer was not returned. Try again.") + raise RuntimeError("A full buffer was not returned. Try again.") else: # Probably a connection issue! raise RuntimeError("DHT sensor not found, check wiring") + self._temperature = new_temperature + self._humidity = new_humidity + @property def temperature(self): """ temperature current reading. It makes sure a reading is available From e6880d74f633e72d3588eb62402117e5c266c7b4 Mon Sep 17 00:00:00 2001 From: Michael Lass Date: Tue, 28 Jan 2020 21:19:30 +0100 Subject: [PATCH 2/3] Reject humidity outside of range (0, 100) as unplausible --- adafruit_dht.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/adafruit_dht.py b/adafruit_dht.py index 2f3c473..6f40d54 100644 --- a/adafruit_dht.py +++ b/adafruit_dht.py @@ -221,6 +221,10 @@ def measure(self): # check sum failed to validate raise RuntimeError("Checksum did not validate. Try again.") + if new_humidity < 0 or new_humidity > 100: + # We received unplausible data + raise RuntimeError("Received unplausible data. Try again.") + elif len(pulses) >= 10: # We got *some* data just not 81 bits raise RuntimeError("A full buffer was not returned. Try again.") From efda9b8e9d4dae0e85c0b0854e9edbf0ce77fe1c Mon Sep 17 00:00:00 2001 From: Michael Lass Date: Sun, 2 Feb 2020 20:35:37 +0100 Subject: [PATCH 3/3] Reduce number of branches to make pylint happy --- adafruit_dht.py | 75 ++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/adafruit_dht.py b/adafruit_dht.py index 6f40d54..fb2b188 100644 --- a/adafruit_dht.py +++ b/adafruit_dht.py @@ -189,48 +189,45 @@ def measure(self): pulses = self._get_pulses_bitbang() # print(len(pulses), "pulses:", [x for x in pulses]) - if len(pulses) >= 80: - buf = array.array("B") - for byte_start in range(0, 80, 16): - buf.append( - self._pulses_to_binary(pulses, byte_start, byte_start + 16) - ) - - if self._dht11: - # humidity is 1 byte - new_humidity = buf[0] - # temperature is 1 byte - new_temperature = buf[2] - else: - # humidity is 2 bytes - new_humidity = ((buf[0] << 8) | buf[1]) / 10 - # temperature is 2 bytes - # MSB is sign, bits 0-14 are magnitude) - raw_temperature = (((buf[2] & 0x7F) << 8) | buf[3]) / 10 - # set sign - if buf[2] & 0x80: - raw_temperature = -raw_temperature - new_temperature = raw_temperature - # calc checksum - chk_sum = 0 - for b in buf[0:4]: - chk_sum += b - - # checksum is the last byte - if chk_sum & 0xFF != buf[4]: - # check sum failed to validate - raise RuntimeError("Checksum did not validate. Try again.") - - if new_humidity < 0 or new_humidity > 100: - # We received unplausible data - raise RuntimeError("Received unplausible data. Try again.") - - elif len(pulses) >= 10: + if len(pulses) < 10: + # Probably a connection issue! + raise RuntimeError("DHT sensor not found, check wiring") + + if len(pulses) < 80: # We got *some* data just not 81 bits raise RuntimeError("A full buffer was not returned. Try again.") + + buf = array.array("B") + for byte_start in range(0, 80, 16): + buf.append(self._pulses_to_binary(pulses, byte_start, byte_start + 16)) + + if self._dht11: + # humidity is 1 byte + new_humidity = buf[0] + # temperature is 1 byte + new_temperature = buf[2] else: - # Probably a connection issue! - raise RuntimeError("DHT sensor not found, check wiring") + # humidity is 2 bytes + new_humidity = ((buf[0] << 8) | buf[1]) / 10 + # temperature is 2 bytes + # MSB is sign, bits 0-14 are magnitude) + new_temperature = (((buf[2] & 0x7F) << 8) | buf[3]) / 10 + # set sign + if buf[2] & 0x80: + new_temperature = -new_temperature + # calc checksum + chk_sum = 0 + for b in buf[0:4]: + chk_sum += b + + # checksum is the last byte + if chk_sum & 0xFF != buf[4]: + # check sum failed to validate + raise RuntimeError("Checksum did not validate. Try again.") + + if new_humidity < 0 or new_humidity > 100: + # We received unplausible data + raise RuntimeError("Received unplausible data. Try again.") self._temperature = new_temperature self._humidity = new_humidity