From 359e051ec88b4daa1fe5cdb7921e747c4584fc46 Mon Sep 17 00:00:00 2001 From: erg Date: Wed, 1 Mar 2023 09:27:00 +0100 Subject: File rename --- py_relay.py | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 py_relay.py (limited to 'py_relay.py') diff --git a/py_relay.py b/py_relay.py new file mode 100644 index 0000000..d492ab0 --- /dev/null +++ b/py_relay.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +Module managing temperature in an enclosed space via heater, +turning relay on and off. +Gets temperature from one wire sensor. +Attempts to keep temperature between given min and max. +Writes its own log as well as temperature data with timestamps to CSV file. +""" +import os + +import pigpio +from math import isnan +import logging +import time +from csv import writer + +__author__ = "Franek Ɓazarewicz-Muradyan" +__licence__ = "GPL" +__version__ = "0.0.1" +__status__ = "Proof of concept" + +# One wire temperature sensor settings +W1_SENSOR_ID = '28-0517c1b121ff' +W1_SENSOR_F = f'/sys/devices/w1_bus_master1/{W1_SENSOR_ID}/w1_slave' +# Heater settings +HEATER_PIN = 5 +# Other settings +TIMEFORMAT = '%Y-%M-%d %H:%M:%S' +TEMPERATURE_MIN = 20 +TEMPERATURE_MAX = 24 +# TEMPERATURE_MIN = 28 +# TEMPERATURE_MAX = 32 +USERNAME = os.getlogin() +LOGNAME = f'/var/log/{USERNAME}/shroombox.log' +DATA_FILE = f'/var/log/{USERNAME}/shroombox.csv' + +pio = pigpio.pi() + +logging.basicConfig( + filename=LOGNAME, + encoding='utf-8', + filemode='a', + format='%(asctime)s,%(msecs)d %(name)s%(levelname)s %(message)s', datefmt='%H:%M:%S', + level=logging.DEBUG, +) + +logging.info("Starting shroombox") + +logger = logging.getLogger() + + +def read_temp_alt(retry=0) -> float: + """ + Function reading temperature. + :param retry: int + :return: float + """ + # If sensor is physically disconected, opening file will fail + temperature = float('NaN') + if retry > 3: + return temperature + try: + with open(W1_SENSOR_F, 'r') as sensor: + ok = sensor.readline()[-4:].strip('\n') + if ok == 'YES': + try: + temperature = round(int(sensor.readline().split('=')[1])/1000, 1) + except: + return temperature + else: + retry+=1 + read_temp_alt(retry=retry) + except: + return temperature + return temperature + + +def heater_on(temp, on=False) -> bool: + """ + Function turning heater on. + :param temp: int + :param on: bool + :return: bool + """ + status = pio.read(HEATER_PIN) + timestamp = time.strftime(TIMEFORMAT) + # turning it off + if not on: + if status: + retval = 0 + else: + try: + pio.write(HEATER_PIN, 1) + message = f"Turning off, temp: {temp}, {timestamp}" + logger.info(message) + retval = 0 + except Exception as exc: + logger.warning(exc) + retval = 1 + # turning it on + else: + if not status: + retval = 0 + else: + try: + pio.write(HEATER_PIN, 0) + message = f"Turning on, temp: {temp}, {timestamp}" + logger.info(message) + retval = 0 + except Exception as exc: + logger.warning(exc) + retval = 1 + return retval + + +def callback(): + temp = read_temp_alt() + # TODO: Add check ntp is running, else we may go back to the '70-ties + timestamp = time.strftime(TIMEFORMAT) + try: + with open(DATA_FILE, 'a') as _file: + wrtr = writer(_file) + wrtr.writerow((timestamp, temp)) + except OSError as exc: + print(f"Error writing data to file: {exc}") + print(temp) # TODO: Remove this line when done with testing. + if temp <= TEMPERATURE_MIN: + if temp < TEMPERATURE_MIN - 5: + print(f"Temperature below minimum: {temp}. Heater not powerful enough?") + logger.warning(f"Heater doesn't work, battery empty?") + state = heater_on(temp, on=True) + if state != 0: + logger.warning(f"heater_on() method returned {state}, {timestamp}") + elif temp >= TEMPERATURE_MAX: + state = heater_on(temp, on=False) + if state != 0: + logger.warning(f"heater_on() method returned {state} {timestamp}") + # Turn off in case can't get temperature reading: + elif isnan(temp): + state = heater_on(temp, on=False) + if state != 0: + logger.warning(f"heater_on() method returned {state} {timestamp}") + logging.warning(f"Cannot read temperature, check your connections! {timestamp}") + + +if __name__ == '__main__': + while True: + callback() + time.sleep(30) -- cgit v1.2.3-65-gdbad