2018-08-30 11:57:01 +00:00
|
|
|
'''
|
|
|
|
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
|
|
|
|
|
2021-11-07 08:35:10 +00:00
|
|
|
LOG_FILE = "/var/log/climate.log"
|
|
|
|
LOG_FORMAT = "%(asctime)s %(filename)s:%(lineno)d %(message)s"
|
|
|
|
LOG_LEVEL = logging.INFO
|
|
|
|
LOG_INTERVAL = 5
|
|
|
|
|
2018-08-30 11:57:01 +00:00
|
|
|
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"
|
|
|
|
|
2021-11-07 08:35:10 +00:00
|
|
|
#logging.basicConfig(format=LOG_FORMAT, level=LOG_LEVEL, filename=LOG_FILE)
|
|
|
|
|
2018-08-30 11:57:01 +00:00
|
|
|
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()
|
2021-11-07 08:35:10 +00:00
|
|
|
logging.info("Temperature: {}\tHumidity: {}".format(temperature, humidity))
|
2018-08-30 11:57:01 +00:00
|
|
|
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()
|
2021-11-07 08:35:10 +00:00
|
|
|
except(ValueError, TypeError, socket.error, ssl.CertificateError) as error:
|
|
|
|
logging.info('unable to publish to mqtt ({})'.format(error))
|
2018-08-30 11:57:01 +00:00
|
|
|
self.__next = self.__now + self.__interval
|
|
|
|
time.sleep(1)
|
|
|
|
|
|
|
|
def stop(self):
|
|
|
|
self.__thread_condition = False
|