environment sensor library for raspberry dependencies to adafruit exist
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import logging
  2. import time
  3. try:
  4. from config import APP_NAME as ROOT_LOGGER_NAME
  5. except ImportError:
  6. ROOT_LOGGER_NAME = 'root'
  7. logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
  8. from . import background_task
  9. try:
  10. import adafruit_dht
  11. except ImportError:
  12. logger.warning("Could not import adafruit_dht. DEBUG set to True")
  13. DEBUG = True
  14. else:
  15. from . import DEBUG
  16. class dht_22(background_task):
  17. RUN_SLEEP_TIME = 4.0
  18. MIN_REFRESH_RATE = RUN_SLEEP_TIME
  19. KEY_TEMPERATURE = 'temperature'
  20. KEY_HUMIDITY = 'humidity'
  21. KEY_TIME = 'time'
  22. def __init__(self, gpio, data_callback=None):
  23. self.__data_callback__ = data_callback
  24. self.__temp_monitor__ = gradient_monitor(.5)
  25. self.__hum_monitor__ = gradient_monitor(5)
  26. self.__monitor__ = dht_22_monitor(300)
  27. # Initial the dht device, with data pin connected to:
  28. if not DEBUG:
  29. self.__dht_device__ = adafruit_dht.DHT22(gpio, use_pulseio=False)
  30. # Initialise background_task
  31. background_task.__init__(self)
  32. def __run__(self):
  33. data = self.__dht_data_transmission__()
  34. if data is not None:
  35. # check data
  36. if self.__temp_monitor__.process(data[self.KEY_TEMPERATURE], data[self.KEY_TIME]) and self.__hum_monitor__.process(data[self.KEY_HUMIDITY], data[self.KEY_TIME]):
  37. #
  38. logger.info('DHT-Communication successful: %s', repr(data))
  39. self.__monitor__.process(data)
  40. if self.__data_callback__ is not None:
  41. self.__data_callback__(**data)
  42. if self.__monitor__.status():
  43. logger.warning("DHT-Communication failed: Measurement stopped caused by suspicious constant values!")
  44. self.close()
  45. else:
  46. logger.debug("DHT-Communication failed: Gradient to high. Ignoring data %s!", repr(data))
  47. def __dht_data_transmission__(self):
  48. if not DEBUG:
  49. while self.__active__:
  50. try:
  51. # Store the values
  52. data = {}
  53. data[self.KEY_TEMPERATURE] = self.__dht_device__.temperature
  54. data[self.KEY_HUMIDITY] = self.__dht_device__.humidity
  55. data[self.KEY_TIME] = int(time.time())
  56. if data[self.KEY_TEMPERATURE] is not None and data[self.KEY_HUMIDITY] is not None:
  57. return data
  58. time.sleep(self.RUN_SLEEP_TIME)
  59. except RuntimeError as error:
  60. # Errors happen fairly often, DHT's are hard to read, just keep going
  61. logger.debug('DHT-Communication failed: ' + error.args[0])
  62. time.sleep(2.0)
  63. except Exception as error:
  64. self.__dht_device__.exit()
  65. raise error
  66. else:
  67. return {
  68. self.KEY_TEMPERATURE: -17.17,
  69. self.KEY_HUMIDITY: 1.7,
  70. self.KEY_TIME: int(time.time()),
  71. }
  72. class gradient_monitor(object):
  73. def __init__(self, max_gradient):
  74. self.__max_gradient__ = max_gradient
  75. #
  76. self.__last_value__ = None
  77. self.__last_time__ = None
  78. def process(self, value, time):
  79. if self.__last_value__ is not None and self.__last_time__ is not None:
  80. # Valid last value exists
  81. gradient = abs((value - self.__last_value__) / (time - self.__last_time__))
  82. if gradient > self.__max_gradient__:
  83. return False
  84. self.__last_value__ = value
  85. self.__last_time__ = time
  86. return True
  87. class dht_22_monitor(object):
  88. def __init__(self, max_const_treshold=250):
  89. self.__max_const_treshold__ = max_const_treshold
  90. self.__fail__ = False
  91. self.__max_const_measurements__ = 0
  92. self.__init_statevars__()
  93. def __init_statevars__(self):
  94. self.__current_const_measurements__ = 0
  95. self.__last_measurements__ = None
  96. def process(self, data):
  97. if self.__last_measurements__ is None:
  98. self.__last_measurements__ = data
  99. else:
  100. data_is_equal = True
  101. for key in [dht_22.KEY_HUMIDITY, dht_22.KEY_TEMPERATURE]:
  102. if data[key] != self.__last_measurements__[key]:
  103. data_is_equal = False
  104. if data_is_equal:
  105. self.__current_const_measurements__ += 1
  106. if self.__current_const_measurements__ > self.__max_const_measurements__:
  107. self.__max_const_measurements__ = self.__current_const_measurements__
  108. else:
  109. self.__init_statevars__()
  110. if self.__max_const_measurements__ > self.__max_const_treshold__:
  111. self.__fail__ = True
  112. def status(self):
  113. if self.__fail__:
  114. self.__fail__ = False
  115. self.__max_const_measurements__ = 0
  116. return True
  117. return False