summaryrefslogtreecommitdiff
path: root/heating.py
blob: 42401ad0d04dd7cbb81ed208920efc157a6187b6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
from abc import ABC, abstractmethod
from circular_queue import circular_queue
import time
import os
import date

# Abstract Class for heating
class heating(ABC):
    def __init__(self, db):
        self.temperature = 0
        self.target = 19
        self.on = False
        self.date = date.date()
        self.db = db
        self.queue = circular_queue(20)

    def up(self, increase=0.5):
        self.target += increase
        self.update()

    def down(self, decrease=0.5):
        self.target -= decrease
        self.update()

    def update(self):
        # rolling average for current temperature
        self.queue.add(self.get_temperature())
        self.temperature = self.queue.average()
        if self.temperature < self.target:
            self.on = True
            self.turn_on()
        else:
            self.on = False
            self.turn_off()
        self.db.exec(
            "insert into temperature values (?,?,?,?)",
            (date.day(), date.time(), self.temperature, self.target),
        )
        self.db.exec(
            "insert into history values (?,?,?)",
            (date.day(), date.time(), heatingon(int)),
        )

    """
        Abstract methods used so that configuration for different
        device types other than a Raspberry Pi is easier in the future
        and all other methods can simply be inherited
    """

    # Method to turn the heating on
    @abstractmethod
    def turn_on(self):
        pass

    # Method to turn the heating off
    @abstractmethod
    def turn_off(self):
        pass

    # Method to get the current actual temperature, can be changed for
    #   different types of temperature sensor when inheriting this
    #   class
    @abstractmethod
    def get_temperature(self):
        pass


# inherited from heating class
# overriding abstract methods from heating class
class rpi_heating(heating):
    def __init__(self, db):
        # https://tutorials-raspberrypi.com/raspberry-pi-control-relay
        #       -switch-via-gpio/
        # https://www.ics.com/blog/gpio-programming-using-sysfs-interface
        # https://medium.com/initial-state/how-to-build-a-raspberry-
        #       pi-temperature-monitor-8c2f70acaea9

        # run init from super class
        super().__init__(db)

        # constant values
        self.RELAY = 17  # relay GPIO pin
        self.SENSORID = "28-0621412f1b5a"  # serial number of sensor

        # setup GPIO for the relay

        os.system(
            "echo {} >/sys/class/gpio/export".format(self.RELAY)
        )
        os.system(
            "echo out >/sys/class/gpio/gpio{}/direction".format(
                self.RELAY
            )
        )
        # file that the temperature gets written t
        self.sensor = "/sys/bus/w1/devices/{}/w1_slave".format(
            self.SENSORID
        )

    def turn_on(self):
        # turn the heating on by triggering the relay
        os.system(
            "echo 1 >/sys/class/gpio/gpio{}/value".format(self.RELAY)
        )

    def turn_off(self):
        # turn the heating off by triggering the relay
        os.system(
            "echo 0 >/sys/class/gpio/gpio{}/value".format(self.RELAY)
        )

    def get_temperature(self):
        with open(self.sensor, "r") as file:
            data = file.read()
        # parse temperature from file
        return (
            float(data.split("\n")[1].split(" ")[9].split("=")[1])
            / 1000
        )