chickenhouse: add climate control

Signed-off-by: Thomas Klaehn <thomas.klaehn@u-blox.com>
This commit is contained in:
Thomas Klaehn
2018-08-30 13:57:01 +02:00
parent 35d1aa796c
commit ef2582dfa7
7 changed files with 177 additions and 28 deletions

View File

@@ -0,0 +1,95 @@
'''
Created on Aug 30, 2018
@author: tkl
'''
import logging
import socket
import ssl
import threading
import time
import paho.mqtt.client as mqtt
from climate_control.sensors import Dht22
from climate_control.heat import Heat
MQTT_BROKER = "mqtt.blackfinn.de"
MQTT_PORT = 8883
MQTT_CERT = "/etc/ssl/certs/DST_Root_CA_X3.pem"
MQTT_TEMPERATURE_TOPIC = "outdoor/chickenhouse/temperature"
MQTT_HUMIDITY_TOPIC = "outdoor/chickenhouse/humidity"
MQTT_ROOM_HEAT_TOPIC = "outdoor/chickenhouse/heat/room"
MQTT_WATER_HEAT_TOPIC = "outdoor/chickenhouse/heat/water"
WATER_HEAT_THRESHOLD = {"on": 1.0, "off": 2.0}
ROOM_HEAT_THRESHOLD = {"on": 1.0, "off": 2.0}
STATE_OFF = "off"
STATE_ON = "ON"
class ClimateControl(threading.Thread):
__water_heat = Heat(20)
__room_heat = Heat(21)
__climate = Dht22(26)
__thread_condition = True
__now = time.time()
__interval = 15 * 60
__next = time.time()
__water_heat_state = STATE_OFF
__room_heat_state = STATE_OFF
def __init__(self):
super(ClimateControl, self).__init__()
def __check_switch_water_heat(self, temperature):
ret = False
if temperature >= WATER_HEAT_THRESHOLD["off"] and self.__water_heat_state == STATE_ON:
self.__water_heat.off()
self.__water_heat_state = STATE_OFF
ret = True
elif temperature <= WATER_HEAT_THRESHOLD["on"] and self.__water_heat_state == STATE_OFF:
self.__water_heat.on()
self.__water_heat_state = STATE_ON
ret = True
return ret
def __check_switch_room_heat(self, temperature):
ret = False
if temperature >= ROOM_HEAT_THRESHOLD["off"] and self.__room_heat_state == STATE_ON:
self.__room_heat.off()
self.__room_heat_state = STATE_OFF
ret = True
elif temperature <= ROOM_HEAT_THRESHOLD["on"] and self.__room_heat_state == STATE_OFF:
self.__room_heat.on()
self.__room_heat_state = STATE_ON
ret = True
return ret
def run(self):
while self.__thread_condition:
self.__now = time.time()
if self.__next <= self.__now:
humidity, temperature = self.__climate.read()
try:
client = mqtt.Client()
client.tls_set(MQTT_CERT)
client.connect(MQTT_BROKER, MQTT_PORT, 60)
client.loop_start()
msg = "{} {}".format(self.__now, temperature)
client.publish(MQTT_TEMPERATURE_TOPIC, msg, qos=2, retain=True)
msg = "{} {}".format(self.__now, humidity)
client.publish(MQTT_HUMIDITY_TOPIC, msg, qos=2, retain=True)
if self.__check_switch_water_heat(temperature):
msg = "{} {}".format(self.__now, self.__water_heat_state)
client.publish(MQTT_WATER_HEAT_TOPIC, msg, qos=2, retain=True)
if self.__check_switch_room_heat(temperature):
msg = "{} {}".format(self.__now, self.__room_heat_state)
client.publish(MQTT_ROOM_HEAT_TOPIC, msg, qos=2, retain=True)
client.loop_stop()
client.disconnect()
except(ValueError, TypeError, socket.error, ssl.CertificateError):
logging.info('unable to publish to mqtt')
self.__next = self.__now + self.__interval
time.sleep(1)
def stop(self):
self.__thread_condition = False

19
climate_control/heat.py Normal file
View File

@@ -0,0 +1,19 @@
try:
import gpio
except ImportError:
raise ImportError("gpio not found.")
class Heat(object):
def __init__(self, pin):
self.pin = gpio.Gpio(pin)
self.pin.export()
self.pin.direction(gpio.Gpio.DIRECTION_OUT)
self.pin.write(0)
def on(self):
self.pin.write(1)
def off(self):
self.pin.write(0)

View File

@@ -0,0 +1,28 @@
'''Module for sensor implementations'''
try:
import Adafruit_DHT
except ImportError:
raise ImportError('Adafruit_DHT library not found.')
def is_valid(temperature, humidity):
'''Check if temperature and humidity are valid.'''
return True if humidity <= 100.0 and humidity >= 0.0 and \
temperature <= 100.0 and temperature >= -50.0 else False
class Dht22(object):
'''DHT 22 temperature and Humidity sensor class.'''
sensor = 22
pin = int()
def __init__(self, pin):
self.pin = pin
def read(self):
'''Read temperature and humidity.'''
temperature = -200.0
humidity = -1.0
valid = False
while valid is False:
temperature, humidity = Adafruit_DHT.read_retry(self.sensor, self.pin)
valid = is_valid(temperature, humidity)
return temperature, humidity