Change temperature sensor from DHT22 to DS18B20
This commit is contained in:
parent
31c1e9ffb0
commit
77d9054011
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,4 +1,4 @@
|
|||||||
dist/
|
dist/
|
||||||
build/
|
build/
|
||||||
__pycache__
|
__pycache__/
|
||||||
greenhouse.egg-info/
|
greenhouse.egg-info/
|
||||||
|
@ -7,85 +7,44 @@ import threading
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
import RPi.GPIO as gpio
|
import RPi.GPIO as gpio
|
||||||
import paho.mqtt.client as mqtt
|
from w1thermsensor import W1ThermSensor
|
||||||
import Adafruit_DHT
|
|
||||||
|
|
||||||
SWITCH_ON_TEMP = 8.0
|
SWITCH_ON_TEMP = 3.0
|
||||||
SWITCH_OFF_TEMP = 10.0
|
SWITCH_OFF_TEMP = 5.0
|
||||||
|
|
||||||
log_level = logging.INFO
|
log_level = logging.INFO
|
||||||
LOG_FILE = "/var/log/greenhouse.log"
|
LOG_FILE = "/var/log/greenhouse.log"
|
||||||
LOG_FORMAT = "%(asctime)s %(levelname)s %(message)s"
|
LOG_FORMAT = "%(asctime)s %(levelname)s %(message)s"
|
||||||
|
|
||||||
#logging.basicConfig(format=LOG_FORMAT, level=log_level, filename=LOG_FILE)
|
logging.basicConfig(format=LOG_FORMAT, level=log_level, filename=LOG_FILE)
|
||||||
logging.basicConfig(format=LOG_FORMAT, level=log_level)
|
#logging.basicConfig(format=LOG_FORMAT, level=log_level)
|
||||||
log = logging.getLogger('greenhouse')
|
log = logging.getLogger('greenhouse')
|
||||||
|
|
||||||
class EnvData(object):
|
|
||||||
def __init__(self):
|
|
||||||
self.stamp = datetime.datetime.fromtimestamp(0)
|
|
||||||
self.temperature = -273.15
|
|
||||||
self.humidity = -1.0
|
|
||||||
self.is_valid = False
|
|
||||||
|
|
||||||
|
|
||||||
class EnvDataCollector(threading.Thread):
|
class EnvDataCollector(threading.Thread):
|
||||||
def __init__(self, name, dht_pin, update_interval=60):
|
def __init__(self, name, update_interval=60):
|
||||||
super(EnvDataCollector, self).__init__()
|
super(EnvDataCollector, self).__init__()
|
||||||
self.name = name
|
self.name = name
|
||||||
self.sensor = 22
|
self.sensor = W1ThermSensor()
|
||||||
self.dht_pin = dht_pin
|
|
||||||
self.update_interval = update_interval
|
self.update_interval = update_interval
|
||||||
self.run_condition = True
|
self.run_condition = True
|
||||||
self.data = EnvData()
|
self.temperature = self.sensor.get_temperature()
|
||||||
|
self.stamp=datetime.datetime.now()
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
next_update = datetime.datetime.now()
|
next_update = datetime.datetime.now()
|
||||||
while self.run_condition:
|
while self.run_condition:
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
if now >= next_update:
|
if now >= next_update:
|
||||||
humidity, temperature = Adafruit_DHT.read(self.sensor, self.dht_pin)
|
self.temperature = self.sensor.get_temperature()
|
||||||
if humidity is None or temperature is None:
|
self.stamp = now
|
||||||
# log.info("%s: No data read - setting re-read intterval to 1s.", self.name)
|
next_update = now + datetime.timedelta(seconds=self.update_interval)
|
||||||
next_update = now + datetime.timedelta(seconds=10)
|
|
||||||
else:
|
|
||||||
if humidity >= 0.0 and humidity <= 100.0 and temperature >= -273.15:
|
|
||||||
self.data.temperature = temperature
|
|
||||||
self.data.humidity = humidity
|
|
||||||
self.data.stamp = now
|
|
||||||
self.data.is_valid = True
|
|
||||||
next_update = now + datetime.timedelta(seconds=self.update_interval)
|
|
||||||
# log.info("%s: Data read - setting re-read intterval to %ss.",
|
|
||||||
# self.name, self.update_interval)
|
|
||||||
else:
|
|
||||||
# log.info("%s: Invalid data read - setting re-read intterval to 1s.",
|
|
||||||
# self.name)
|
|
||||||
next_update = now + datetime.timedelta(seconds=10)
|
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.run_condition = False
|
self.run_condition = False
|
||||||
self.join()
|
self.join()
|
||||||
|
|
||||||
|
|
||||||
class MqttHandler(object):
|
|
||||||
def __init__(self, url, port, certificate):
|
|
||||||
self.url = url
|
|
||||||
self.port = port
|
|
||||||
self.certificate = certificate
|
|
||||||
self.client = mqtt.Client()
|
|
||||||
self.client.tls_set(certificate)
|
|
||||||
self.client.connect(url, port, 60)
|
|
||||||
self.client.loop_start()
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
self.client.loop_stop()
|
|
||||||
self.client.disconnect()
|
|
||||||
|
|
||||||
def transmit(self, topic, message):
|
|
||||||
self.client.publish(topic, message, qos=2, retain=True)
|
|
||||||
|
|
||||||
|
|
||||||
class Heat(object):
|
class Heat(object):
|
||||||
def __init__(self, pin):
|
def __init__(self, pin):
|
||||||
self.pin = pin
|
self.pin = pin
|
||||||
@ -99,106 +58,38 @@ class Heat(object):
|
|||||||
def off(self):
|
def off(self):
|
||||||
gpio.output(self.pin, 1)
|
gpio.output(self.pin, 1)
|
||||||
|
|
||||||
class Water(object):
|
|
||||||
def __init__(self, water_switch):
|
|
||||||
self.filename = "/var/log/relay_{}.state".format(water_switch)
|
|
||||||
|
|
||||||
def state(self):
|
|
||||||
res = [0, 0, 0]
|
|
||||||
with open(self.filename, "r") as f:
|
|
||||||
ctx = f.read().strip().split(" ")
|
|
||||||
return ctx[0], ctx[1], ctx[2]
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
old_green = EnvDataCollector("Greenhouse one", 17)
|
green = EnvDataCollector("Greenhouse one")
|
||||||
old_heat = Heat(6)
|
heat = Heat(26)
|
||||||
old_heat.off()
|
heat.off()
|
||||||
old_heat_state = "off"
|
heat_state = "off"
|
||||||
old_water = Water(1)
|
green.start()
|
||||||
last_old_water_state = "off"
|
|
||||||
new_green = EnvDataCollector("Greenhouse two", 21)
|
|
||||||
new_water = Water(2)
|
|
||||||
last_new_water_state = "off"
|
|
||||||
old_green.start()
|
|
||||||
new_green.start()
|
|
||||||
|
|
||||||
mqtt_handler = MqttHandler("mqtt.blackfinn.de", 8883, "/etc/ssl/certs/DST_Root_CA_X3.pem")
|
|
||||||
try:
|
try:
|
||||||
# let first temperature/humidity collection happen.
|
|
||||||
time.sleep(5)
|
|
||||||
next_update = datetime.datetime.now()
|
next_update = datetime.datetime.now()
|
||||||
while True:
|
while True:
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
|
|
||||||
# Water state
|
|
||||||
current_old_water_state = old_water.state()
|
|
||||||
if current_old_water_state[2] != last_old_water_state:
|
|
||||||
last_old_water_state = current_old_water_state[2]
|
|
||||||
msg = "{} {} {}".format(current_old_water_state[0], current_old_water_state[1], current_old_water_state[2])
|
|
||||||
mqtt_handler.transmit("outdoor/greenhouse/water", msg)
|
|
||||||
|
|
||||||
current_new_water_state = new_water.state()
|
|
||||||
if current_new_water_state[2] != last_new_water_state:
|
|
||||||
last_new_water_state = current_new_water_state[2]
|
|
||||||
msg = "{} {} {}".format(current_new_water_state[0], current_new_water_state[1], current_new_water_state[2])
|
|
||||||
mqtt_handler.transmit("outdoor/greenhouse-2/water", msg)
|
|
||||||
|
|
||||||
if now >= next_update:
|
if now >= next_update:
|
||||||
|
log.info("Temperature: %.1f", float(green.temperature))
|
||||||
# 1) Check timestamp of last data collection. If data are older
|
if float(green.temperature) < SWITCH_ON_TEMP and heat_state == "off":
|
||||||
# than 5 minutes the sensor isn't working anymore.
|
heat.on()
|
||||||
if old_green.data.is_valid and old_green.data.stamp + datetime.timedelta(minutes=5) >= now:
|
heat_state = "on"
|
||||||
msg = "{} {}".format(datetime.datetime.timestamp(old_green.data.stamp), old_green.data.temperature)
|
log.info("Heat: switch %s", heat_state)
|
||||||
mqtt_handler.transmit("outdoor/greenhouse/temperature", msg)
|
elif float(green.temperature) > SWITCH_OFF_TEMP and heat_state == "on":
|
||||||
log.info("%s: Temperature: %s", old_green.data.stamp.time(), old_green.data.temperature)
|
heat.off()
|
||||||
msg = "{} {}".format(datetime.datetime.timestamp(old_green.data.stamp), old_green.data.humidity)
|
heat_state = "off"
|
||||||
mqtt_handler.transmit("outdoor/greenhouse/humidity", msg)
|
log.info("Heat: switch %s", heat_state)
|
||||||
log.info("%s: Humidity: %s", old_green.data.stamp.time(), old_green.data.humidity)
|
elif heat_state == "on":
|
||||||
if old_green.data.temperature < SWITCH_ON_TEMP and old_heat_state == "off":
|
# Do a power cycle to prevent auto-poweroff
|
||||||
old_heat.on()
|
heat.off()
|
||||||
old_heat_state = "on"
|
time.sleep(5)
|
||||||
msg = "{} {}".format(time.time(), old_heat_state)
|
heat.on()
|
||||||
mqtt_handler.transmit("outdoor/greenhouse/heat", msg)
|
next_update = now + datetime.timedelta(minutes=5)
|
||||||
log.info("%s: Heat: switch %s", time.time(), old_heat_state)
|
|
||||||
elif old_green.data.temperature > SWITCH_OFF_TEMP and old_heat_state == "on":
|
|
||||||
old_heat.off()
|
|
||||||
old_heat_state = "off"
|
|
||||||
msg = "{} {}".format(time.time(), old_heat_state)
|
|
||||||
mqtt_handler.transmit("outdoor/greenhouse/heat", msg)
|
|
||||||
log.info("%s: Heat: switch %s", time.time(), old_heat_state)
|
|
||||||
elif old_heat_state == "on":
|
|
||||||
# Do a power cycle to prevent auto-poweroff
|
|
||||||
log.info("%s: Heat init power cycle.", time.time())
|
|
||||||
old_heat.off()
|
|
||||||
time.sleep(5)
|
|
||||||
old_heat.on()
|
|
||||||
log.info("%s: Heat power cycle done.", time.time())
|
|
||||||
next_update = now + datetime.timedelta(minutes=5)
|
|
||||||
else:
|
|
||||||
msg = "{} Error! Last valid DHT sensor data is from {}.".format(time.time(), old_green.data.stamp)
|
|
||||||
mqtt_handler.transmit("outdoor/greenhouse/status", msg)
|
|
||||||
log.error("%s: Error! Last valid DHT sensor data is from %s", time.time(), old_green.data.stamp)
|
|
||||||
next_update = now + datetime.timedelta(seconds=5)
|
|
||||||
|
|
||||||
if new_green.data.is_valid and new_green.data.stamp + datetime.timedelta(minutes=5) >= now:
|
|
||||||
msg = "{} {}".format(datetime.datetime.timestamp(new_green.data.stamp), new_green.data.temperature)
|
|
||||||
mqtt_handler.transmit("outdoor/greenhouse-2/temperature", msg)
|
|
||||||
log.info("%s: Temperature: %s", new_green.data.stamp.time(), new_green.data.temperature)
|
|
||||||
msg = "{} {}".format(datetime.datetime.timestamp(new_green.data.stamp), new_green.data.humidity)
|
|
||||||
mqtt_handler.transmit("outdoor/greenhouse-2/humidity", msg)
|
|
||||||
log.info("%s: Humidity: %s", new_green.data.stamp.time(), new_green.data.humidity)
|
|
||||||
else:
|
|
||||||
msg = "{} Error! Last valid DHT sensor data is from {}.".format(time.time(), new_green.data.stamp)
|
|
||||||
mqtt_handler.transmit("outdoor/greenhouse-2/status", msg)
|
|
||||||
log.error("%s: Error! Last valid DHT sensor data is from %s", time.time(), new_green.data.stamp)
|
|
||||||
|
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
log.info("Shutting down...")
|
log.info("Shutting down...")
|
||||||
old_green.stop()
|
green.stop()
|
||||||
new_green.stop()
|
log.info("Done")
|
||||||
mqtt_handler.stop()
|
|
||||||
log.info("Exiting...")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
sys.exit(main())
|
sys.exit(main())
|
||||||
|
Loading…
Reference in New Issue
Block a user