99 lines
4.2 KiB
Python
Executable File
99 lines
4.2 KiB
Python
Executable File
# Copyright (c) 2014 Adafruit Industries
|
|
# Author: Tony DiCola
|
|
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
# of this software and associated documentation files (the "Software"), to deal
|
|
# in the Software without restriction, including without limitation the rights
|
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
# copies of the Software, and to permit persons to whom the Software is
|
|
# furnished to do so, subject to the following conditions:
|
|
|
|
# The above copyright notice and this permission notice shall be included in all
|
|
# copies or substantial portions of the Software.
|
|
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
# SOFTWARE.
|
|
import time
|
|
|
|
from . import platform_detect
|
|
|
|
|
|
# Define error constants.
|
|
DHT_SUCCESS = 0
|
|
DHT_ERROR_TIMEOUT = -1
|
|
DHT_ERROR_CHECKSUM = -2
|
|
DHT_ERROR_ARGUMENT = -3
|
|
DHT_ERROR_GPIO = -4
|
|
TRANSIENT_ERRORS = [DHT_ERROR_CHECKSUM, DHT_ERROR_TIMEOUT]
|
|
|
|
# Define sensor type constants.
|
|
DHT11 = 11
|
|
DHT22 = 22
|
|
AM2302 = 22
|
|
SENSORS = [DHT11, DHT22, AM2302]
|
|
|
|
|
|
def get_platform():
|
|
"""Return a DHT platform interface for the currently detected platform."""
|
|
plat = platform_detect.platform_detect()
|
|
if plat == platform_detect.RASPBERRY_PI:
|
|
# Check for version 1 or 2 of the pi.
|
|
version = platform_detect.pi_version()
|
|
if version == 1:
|
|
from . import Raspberry_Pi
|
|
return Raspberry_Pi
|
|
elif version == 2:
|
|
from . import Raspberry_Pi_2
|
|
return Raspberry_Pi_2
|
|
elif version == 3:
|
|
"""Use Pi 2 driver even though running on Pi 3"""
|
|
from . import Raspberry_Pi_2
|
|
return Raspberry_Pi_2
|
|
else:
|
|
raise RuntimeError('No driver for detected Raspberry Pi version available!')
|
|
elif plat == platform_detect.BEAGLEBONE_BLACK:
|
|
from . import Beaglebone_Black
|
|
return Beaglebone_Black
|
|
else:
|
|
raise RuntimeError('Unknown platform.')
|
|
|
|
def read(sensor, pin, platform=None):
|
|
"""Read DHT sensor of specified sensor type (DHT11, DHT22, or AM2302) on
|
|
specified pin and return a tuple of humidity (as a floating point value
|
|
in percent) and temperature (as a floating point value in Celsius). Note that
|
|
because the sensor requires strict timing to read and Linux is not a real
|
|
time OS, a result is not guaranteed to be returned! In some cases this will
|
|
return the tuple (None, None) which indicates the function should be retried.
|
|
Also note the DHT sensor cannot be read faster than about once every 2 seconds.
|
|
Platform is an optional parameter which allows you to override the detected
|
|
platform interface--ignore this parameter unless you receive unknown platform
|
|
errors and want to override the detection.
|
|
"""
|
|
if sensor not in SENSORS:
|
|
raise ValueError('Expected DHT11, DHT22, or AM2302 sensor value.')
|
|
if platform is None:
|
|
platform = get_platform()
|
|
return platform.read(sensor, pin)
|
|
|
|
def read_retry(sensor, pin, retries=15, delay_seconds=2, platform=None):
|
|
"""Read DHT sensor of specified sensor type (DHT11, DHT22, or AM2302) on
|
|
specified pin and return a tuple of humidity (as a floating point value
|
|
in percent) and temperature (as a floating point value in Celsius).
|
|
Unlike the read function, this read_retry function will attempt to read
|
|
multiple times (up to the specified max retries) until a good reading can be
|
|
found. If a good reading cannot be found after the amount of retries, a tuple
|
|
of (None, None) is returned. The delay between retries is by default 2
|
|
seconds, but can be overridden.
|
|
"""
|
|
for i in range(retries):
|
|
humidity, temperature = read(sensor, pin, platform)
|
|
if humidity is not None and temperature is not None:
|
|
return (humidity, temperature)
|
|
time.sleep(delay_seconds)
|
|
return (None, None)
|