aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorerg <uinarf@autistici.org>2023-01-12 16:15:35 +0100
committererg <uinarf@autistici.org>2023-01-12 16:15:35 +0100
commitd6970e81e607f27bee9323d10d1476621de3416c (patch)
tree1c27d765440256468eb24ecafef78a17cbdf72db
downloadPi_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.swpbin0 -> 16384 bytes
-rw-r--r--Responder.db0
-rw-r--r--main.py171
-rw-r--r--shroom_daemon.sh25
4 files changed, 196 insertions, 0 deletions
diff --git a/.main.py.swp b/.main.py.swp
new file mode 100644
index 0000000..fcf7ed4
--- /dev/null
+++ b/.main.py.swp
Binary files differ
diff --git a/Responder.db b/Responder.db
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Responder.db
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..aa80fce
--- /dev/null
+++ b/main.py
@@ -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 $?
+}