summaryrefslogtreecommitdiff
path: root/heating.py
blob: d6cb7cf0f10ed4c3198e843b8e8891c3a099e16f (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
120
121
122
123
124
from abc import ABC, abstractmethod
from circular_queue import circular_queue
import time
import os
import dates

# Abstract Class for heating
class heating(ABC):
    def __init__(self, db):
        self.temperature = 0
        self.target = 19
        self.on = False
        self.date = dates.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 (?,?,?,?)",
            (
                self.date.day(),
                self.date.time(),
                self.temperature,
                self.target,
            ),
        )
        self.db.exec(
            "insert into history values (?,?,?)",
            (self.date.day(), self.date.time(), int(self.on)),
        )

    """
        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
        )