diff options
author | erg <uinarf@autistici.org> | 2023-01-12 16:15:35 +0100 |
---|---|---|
committer | erg <uinarf@autistici.org> | 2023-01-12 16:15:35 +0100 |
commit | d6970e81e607f27bee9323d10d1476621de3416c (patch) | |
tree | 1c27d765440256468eb24ecafef78a17cbdf72db | |
download | Pi_Temp_PID_Control-d6970e81e607f27bee9323d10d1476621de3416c.tar.gz Pi_Temp_PID_Control-d6970e81e607f27bee9323d10d1476621de3416c.tar.bz2 Pi_Temp_PID_Control-d6970e81e607f27bee9323d10d1476621de3416c.zip |
Initial commit
-rw-r--r-- | .main.py.swp | bin | 0 -> 16384 bytes | |||
-rw-r--r-- | Responder.db | 0 | ||||
-rw-r--r-- | main.py | 171 | ||||
-rw-r--r-- | shroom_daemon.sh | 25 |
4 files changed, 196 insertions, 0 deletions
diff --git a/.main.py.swp b/.main.py.swp Binary files differnew file mode 100644 index 0000000..fcf7ed4 --- /dev/null +++ b/.main.py.swp diff --git a/Responder.db b/Responder.db new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Responder.db @@ -0,0 +1,171 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +Module managing temperature in the shroombox. +""" + +from os import getpid +import pigpio +from math import isnan +import logging +import time +from simple_pid import PID + +__author__ = "Franek Ćazarewicz-Muradyan" +__licence__ = "GPL" +__version__ = "0.0.1" +__status__ = "Proof of concept" + +# ********************** +# Hardware Settings +# ********************** + +# 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 +relay_pin = 5 +mosfet_pin = 22 + +# ********************** +# Software Settings +# ********************** + +timeformat = '%Y-%M-%d %H:%M:%S' +temperature_min = 20 +temperature_max = 24 +temperature_target = 20 +read_retry = 3 +logname = '/var/log/pipi/shroombox.log' +data_file = '/var/log/pipi/shroombox.csv' + +# ********************** +# PID Settings +# ********************** +Kp = 1 +Ki = 0.2 +Kd = 0 +sample_time = 10 + +# ********************** +# Code +# ********************** + + +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( + retry: int = 0, +) -> float: + # If sensor is physically disconected, opening file will fail + temperature = float('NaN') + if retry > read_retry: + return temperature + 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 IndexError: # TODO: What other exceptions? + return temperature + else: + retry += 1 + read_temp(retry=retry) + return temperature + + +def heater_on( + temp: float, + on: bool = False, +) -> bool: + status = pio.read(relay_pin) + timestamp = time.strftime(timeformat) + # turning it off + if not on: + if status == 1: + return False + else: + try: + pio.write(relay_pin, 1) + message = f"Turning off, temp: {temp}, {timestamp}" + logger.info(message) + return False + except: # TODO: documentation doesn't talk about exceptions on write + return True + # turning it on + if on: + if status == 0: + return False + else: + try: + pio.write(relay_pin, 0) + message = f"Turning on, temp: {temp}, {timestamp}" + logger.info(message) + return False + except: + return True + + +def temp_control( + current_temperature: float +) -> int: + pid = PID(Kp, Ki, Kd, setpoint=temperature_target) + pid.output_limits = (0, 255) + pid.sample_time = sample_time + return pid(current_temperature) + + +def main_alt(): + temp = read_temp_alt() + timestamp = time.strftime(timeformat) + print(temp) + with open(data_file, 'a') as dat: + dat.write(temp) + frequency = temp_control(temp) + try: + pio.set_PWM_frequency(mosfet_pin, frequency) + except ( + pio.PI_BAD_USER_GPIO, + pio.PI_NOT_PERMITTED, + ) as exc: + logger.warning(f"Failed to set GPIO PWM frequency: {exc} {timestamp}") + + +def main(): + temp = read_temp() + timestamp = time.strftime(timeformat) + print(temp) + if temp <= temperature_min: + # if temp < temperature_min - 5: + # print(f"Heater doesn't work, battery empty?") + # logger.warning(f"Heater doesn't work, battery empty?") + # state = heater_on(temp, on=False) + 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}") + elif isnan(temp): + state = heater_on(temp, on=False) + logging.warning(f"Cannot read temperature, check your connections! {timestamp}") + + +if __name__ == '__main__': + with open('/run/shroombox.pid', 'w') as f: + f.write(str(getpid())) + while True: + pio = pigpio.pi() + main() + time.sleep(30) diff --git a/shroom_daemon.sh b/shroom_daemon.sh new file mode 100644 index 0000000..adf6712 --- /dev/null +++ b/shroom_daemon.sh @@ -0,0 +1,25 @@ +#!/sbin/openrc-run +# Copyright 2023 erg_samowzbudnik +# Distributed under the terms of the GNU General Public Licence v2 + +GROUP=$(id -g) +supervisor="supervise-daemon" +command_args_foreground="--foreground" +# Could also get dir to store pid file from XDG_RUNTIME_DIR +pidfile="/run/user/${UID}/${RC_SVCNAME}.pid" +extra_started_commands="reload" +command_user="${USER}:${GROUP}" +command="python main.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 $? +} |