File: switch.py

package info (click to toggle)
python-mystrom 2.2.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, trixie
  • size: 188 kB
  • sloc: python: 855; makefile: 3
file content (130 lines) | stat: -rw-r--r-- 4,112 bytes parent folder | download
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
125
126
127
128
129
130
"""Support for communicating with myStrom plugs/switches."""
import aiohttp
from yarl import URL
from typing import Any, Dict, Iterable, List, Optional, Union

from . import _request as request


class MyStromSwitch:
    """A class for a myStrom switch/plug."""

    def __init__(self, host: str, session: aiohttp.client.ClientSession = None) -> None:
        """Initialize the switch."""
        self._close_session = False
        self._host = host
        self._session = session
        self._consumption = 0
        self._consumedWs = 0
        self._state = None
        self._temperature = None
        self._firmware = None
        self._mac = None
        self.uri = URL.build(scheme="http", host=self._host)

    async def turn_on(self) -> None:
        """Turn the relay on."""
        parameters = {"state": "1"}
        url = URL(self.uri).join(URL("relay"))
        await request(self, uri=url, params=parameters)
        await self.get_state()

    async def turn_off(self) -> None:
        """Turn the relay off."""
        parameters = {"state": "0"}
        url = URL(self.uri).join(URL("relay"))
        await request(self, uri=url, params=parameters)
        await self.get_state()

    async def toggle(self) -> None:
        """Toggle the relay."""
        url = URL(self.uri).join(URL("toggle"))
        await request(self, uri=url)
        await self.get_state()

    async def get_state(self) -> None:
        """Get the details from the switch/plug."""
        url = URL(self.uri).join(URL("report"))
        response = await request(self, uri=url)
        try:
            self._consumption = response["power"]
        except KeyError:
            self._consumption = None
        try:
            self._consumedWs = response["Ws"]
        except KeyError:
            self._consumedWs = None
        self._state = response["relay"]
        try:
            self._temperature = response["temperature"]
        except KeyError:
            self._temperature = None

        # Try the new API (Devices with newer firmware)
        url = URL(self.uri).join(URL("api/v1/info"))
        response = await request(self, uri=url)
        if not isinstance(response, dict):
            # Fall back to the old API version if the device runs with old firmware
            url = URL(self.uri).join(URL("info.json"))
            response = await request(self, uri=url)

        self._firmware = response["version"]
        self._mac = response["mac"]

    @property
    def relay(self) -> bool:
        """Return the relay state."""
        return bool(self._state)

    @property
    def consumption(self) -> float:
        """Return the current power consumption in mWh."""
        if self._consumption is not None:
            return round(self._consumption, 1)

        return self._consumption

    @property
    def consumedWs(self) -> float:
        """The average of energy consumed per second since last report call."""
        if self._consumedWs is not None:
            return round(self._consumedWs, 1)

        return self._consumedWs

    @property
    def firmware(self) -> float:
        """Return the current firmware."""
        return self._firmware

    @property
    def mac(self) -> float:
        """Return the MAC address."""
        return self._mac

    @property
    def temperature(self) -> float:
        """Return the current temperature in celsius."""
        if self._temperature is not None:
            return round(self._temperature, 1)

        return self._temperature

    async def get_temperature_full(self) -> str:
        """Get current temperature in celsius."""
        url = URL(self.uri).join(URL("temp"))
        response = await request(self, uri=url)
        return response

    async def close(self) -> None:
        """Close an open client session."""
        if self._session and self._close_session:
            await self._session.close()

    async def __aenter__(self) -> "MyStromSwitch":
        """Async enter."""
        return self

    async def __aexit__(self, *exc_info) -> None:
        """Async exit."""
        await self.close()