aboutsummaryrefslogtreecommitdiff
path: root/ShellyPy/base/relay.py
blob: 42ae19f93db3e61da73657345bd0d9196711963f (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
from abc import ABCMeta, abstractmethod
from datetime import datetime, timedelta
from typing import Optional, Union

from ..utils import property_fetcher

class Relay(metaclass=ABCMeta):

    def __init__(self, device, index, *args, **kwargs):
        self._device = device
        self._index = index

        self._ison = None
        self._timer_start = None
        self._timer_end = None

    def __repr__(self):
        class_name = self.__class__.__name__
        return f"{class_name}{self.index}(on={self.ison})"

    @abstractmethod
    def toggle(self, timer: Optional[int] = None):
        pass

    @abstractmethod
    def on(self, timer: Optional[int] = None):
        pass

    @abstractmethod
    def off(self, timer: Optional[int] = None):
        pass

    def turn(self, value: Union[str, bool], timer: Optional[int] = None):
        
        value_method = {
            "toggle": self.toggle,
            "on": self.on,
            "off": self.off,
            True: self.on,
            False: self.off
        }

        return value_method[value](timer)

    @property
    def index(self) -> int:
        return self._index

    @property
    @property_fetcher()
    def ison(self) -> bool:
        return bool(self._ison)

    @property
    def has_timer(self) -> bool:
        """
        return true when the timer is primed and has not happened yet
        """
        start = self._timer_start
        end = self._timer_end
        if not start or not end:
            return False

        date_now = datetime.now()
        return end > date_now and start < date_now


    @property
    @property_fetcher()
    def timer_started(self) -> Optional[datetime]:
        if self.has_timer:
            return self._timer_start
        return None

    @property
    def timer_duration(self) -> Optional[timedelta]:
        # fetch the start before to populate the implementation values
        if not self.has_timer:
            return None

        start = self.timer_started
        end = self._timer_end

        return end - start

    @abstractmethod
    def update(self) -> None:
        pass