aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorerg <uinarf@autistici.org>2023-02-28 10:12:46 +0100
committererg <uinarf@autistici.org>2023-02-28 10:12:46 +0100
commitad96edf8be0e758277f77c521ebb0e8383cda647 (patch)
tree1b265f4424c6e725bebdb1aeb811d75eeb43bf2a
downloadPi_Relay-ad96edf8be0e758277f77c521ebb0e8383cda647.tar.gz
Pi_Relay-ad96edf8be0e758277f77c521ebb0e8383cda647.tar.bz2
Pi_Relay-ad96edf8be0e758277f77c521ebb0e8383cda647.zip
Initial commit
-rw-r--r--main.py149
-rw-r--r--shroom_daemon29
2 files changed, 178 insertions, 0 deletions
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..7a87f35
--- /dev/null
+++ b/main.py
@@ -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 $?
+}