diff options
author | erg <uinarf@autistici.org> | 2023-02-28 10:12:46 +0100 |
---|---|---|
committer | erg <uinarf@autistici.org> | 2023-02-28 10:12:46 +0100 |
commit | ad96edf8be0e758277f77c521ebb0e8383cda647 (patch) | |
tree | 1b265f4424c6e725bebdb1aeb811d75eeb43bf2a | |
download | Pi_Relay-ad96edf8be0e758277f77c521ebb0e8383cda647.tar.gz Pi_Relay-ad96edf8be0e758277f77c521ebb0e8383cda647.tar.bz2 Pi_Relay-ad96edf8be0e758277f77c521ebb0e8383cda647.zip |
Initial commit
-rw-r--r-- | main.py | 149 | ||||
-rw-r--r-- | shroom_daemon | 29 |
2 files changed, 178 insertions, 0 deletions
@@ -0,0 +1,149 @@ +#!/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 == 1: + retval = 0 + else: + try: + pio.write(HEATER_PIN, 1) + message = f"Turning off, temp: {temp}, {timestamp}" + logger.info(message) + retval = 0 + except: + retval = 1 + # turning it on + else: + if status == 0: + retval = 0 + else: + try: + pio.write(HEATER_PIN, 0) + message = f"Turning on, temp: {temp}, {timestamp}" + logger.info(message) + retval = 0 + except: + 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) diff --git a/shroom_daemon b/shroom_daemon new file mode 100644 index 0000000..708589c --- /dev/null +++ b/shroom_daemon @@ -0,0 +1,29 @@ +#!/sbin/openrc-run +# Copyright 2023 erg_samowzbudnik +# Distributed under the terms of the GNU General Public Licence v2 + +# Set username you want process run with. Should be your regular user +USERNAME="pipi" +GROUP=$(id -g ${USERNAME}) +supervisor="supervise-daemon" +command_args_foreground="--foreground" +# Could also get dir to store pid file from XDG_RUNTIME_DIR +pidfile="/run/${RC_SVCNAME}.pid" +# pidfile="/run/user/${GROUP}/${RC_SVCNAME}.pid" +extra_started_commands="reload" +command_user="${USERNAME}:${USERNAME}" +# command_user="${USER}:${GROUP}" +command="python /usr/local/sbin/pi_relay.py" +description="Daemon for shroombox" + +depend() { + need localmount + use logger +} + +reload() { + ebegin "Reloading ${RC_SVCNAME}configuration" + start-stop-daemon --exec "$command" --signal HUP + ${supervisor} "${RC_SVCNAME}" --signal HUP --pidfile "${pidfile}" + eend $? +} |