bwt-api 0.2.0__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {bwt_api-0.2.0 → bwt_api-0.3.0}/PKG-INFO +1 -1
- {bwt_api-0.2.0 → bwt_api-0.3.0}/src/bwt_api/api.py +15 -8
- {bwt_api-0.2.0 → bwt_api-0.3.0}/src/bwt_api/data.py +5 -4
- {bwt_api-0.2.0 → bwt_api-0.3.0}/src/bwt_api.egg-info/PKG-INFO +2 -2
- {bwt_api-0.2.0 → bwt_api-0.3.0}/tests/test_api.py +76 -4
- {bwt_api-0.2.0 → bwt_api-0.3.0}/.coveragerc +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/.github/workflows/python-package.yml +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/.github/workflows/python-publish.yml +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/.gitignore +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/AUTHORS.rst +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/CHANGELOG.rst +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/CONTRIBUTING.rst +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/LICENSE.txt +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/README.rst +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/pyproject.toml +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/setup.cfg +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/setup.py +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/src/bwt_api/__init__.py +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/src/bwt_api/error.py +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/src/bwt_api/exception.py +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/src/bwt_api/skeleton.py +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/src/bwt_api.egg-info/SOURCES.txt +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/src/bwt_api.egg-info/dependency_links.txt +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/src/bwt_api.egg-info/entry_points.txt +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/src/bwt_api.egg-info/not-zip-safe +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/src/bwt_api.egg-info/requires.txt +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/src/bwt_api.egg-info/top_level.txt +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/tests/conftest.py +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/tests/pytest.ini +0 -0
- {bwt_api-0.2.0 → bwt_api-0.3.0}/tox.ini +0 -0
|
@@ -5,6 +5,8 @@ from tokenize import String
|
|
|
5
5
|
import aiohttp
|
|
6
6
|
import base64
|
|
7
7
|
import logging
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
from zoneinfo import ZoneInfo
|
|
8
10
|
|
|
9
11
|
from bwt_api.error import BwtError
|
|
10
12
|
from bwt_api.exception import ApiException, ConnectException, WrongCodeException
|
|
@@ -60,13 +62,18 @@ class BwtApi:
|
|
|
60
62
|
except aiohttp.ClientConnectorError as e:
|
|
61
63
|
raise ConnectException from e
|
|
62
64
|
|
|
65
|
+
def _convert_datetime(self, input: str) -> datetime:
|
|
66
|
+
# It looks like the device even shows everything in UTC
|
|
67
|
+
return datetime.strptime(
|
|
68
|
+
input, "%Y-%m-%d %H:%M:%S"
|
|
69
|
+
).replace(tzinfo=ZoneInfo("UTC"))
|
|
70
|
+
|
|
63
71
|
async def get_current_data(self) -> CurrentResponse:
|
|
64
72
|
"""Get the current state of the BWT."""
|
|
65
73
|
_logger.debug(f"Fetching current data from {self._host}")
|
|
66
74
|
raw = await self.__get_data("GetCurrentData")
|
|
67
|
-
errors =
|
|
68
|
-
|
|
69
|
-
)
|
|
75
|
+
errors = [BwtError(int(error)) for error in raw["ActiveErrorIDs"].split(",") if error]
|
|
76
|
+
|
|
70
77
|
in_hardness = Hardness(
|
|
71
78
|
raw["HardnessIN_CaCO3"],
|
|
72
79
|
raw["HardnessIN_dH"],
|
|
@@ -80,7 +87,7 @@ class BwtApi:
|
|
|
80
87
|
raw["HardnessOUT_mmol_l"],
|
|
81
88
|
)
|
|
82
89
|
return CurrentResponse(
|
|
83
|
-
|
|
90
|
+
errors,
|
|
84
91
|
raw["BlendedWaterSinceSetup_l"],
|
|
85
92
|
raw["CapacityColumn1_ml_dH"],
|
|
86
93
|
raw["CapacityColumn2_ml_dH"],
|
|
@@ -90,10 +97,10 @@ class BwtApi:
|
|
|
90
97
|
in_hardness,
|
|
91
98
|
out_hardness,
|
|
92
99
|
raw["HolidayModeStartTime"],
|
|
93
|
-
raw["LastRegenerationColumn1"],
|
|
94
|
-
raw["LastRegenerationColumn2"],
|
|
95
|
-
raw["LastServiceCustomer"],
|
|
96
|
-
raw["LastServiceTechnican"],
|
|
100
|
+
self._convert_datetime(raw["LastRegenerationColumn1"]),
|
|
101
|
+
self._convert_datetime(raw["LastRegenerationColumn2"]),
|
|
102
|
+
self._convert_datetime(raw["LastServiceCustomer"]),
|
|
103
|
+
self._convert_datetime(raw["LastServiceTechnican"]),
|
|
97
104
|
raw["OutOfService"],
|
|
98
105
|
raw["RegenerationCounterColumn1"],
|
|
99
106
|
raw["RegenerationCounterColumn2"],
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
from dataclasses import dataclass
|
|
5
|
+
from datetime import datetime
|
|
5
6
|
from bwt_api.error import BwtError
|
|
6
7
|
|
|
7
8
|
|
|
@@ -25,10 +26,10 @@ class CurrentResponse:
|
|
|
25
26
|
in_hardness: Hardness
|
|
26
27
|
out_hardness: Hardness
|
|
27
28
|
holiday_mode: int # -1 or 0: inactive, 1: active, unix timestamp: start in future
|
|
28
|
-
regeneration_last_1:
|
|
29
|
-
regeneration_last_2:
|
|
30
|
-
service_customer:
|
|
31
|
-
service_technician:
|
|
29
|
+
regeneration_last_1: datetime
|
|
30
|
+
regeneration_last_2: datetime
|
|
31
|
+
service_customer: datetime
|
|
32
|
+
service_technician: datetime
|
|
32
33
|
out_of_service: int
|
|
33
34
|
regeneration_count_1: int
|
|
34
35
|
regeneration_count_2: int
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from zoneinfo import ZoneInfo
|
|
1
3
|
import pytest
|
|
2
4
|
|
|
3
5
|
from bwt_api.api import BwtApi
|
|
@@ -49,6 +51,42 @@ current_json = """
|
|
|
49
51
|
}
|
|
50
52
|
"""
|
|
51
53
|
|
|
54
|
+
current_json_empty_errors = """
|
|
55
|
+
{
|
|
56
|
+
"ActiveErrorIDs" : "",
|
|
57
|
+
"BlendedWaterSinceSetup_l" : 318383,
|
|
58
|
+
"CapacityColumn1_ml_dH" : 5485275,
|
|
59
|
+
"CapacityColumn2_ml_dH" : 3833994,
|
|
60
|
+
"CurrentFlowrate_l_h" : 0,
|
|
61
|
+
"DosingSinceSetup_ml" : 0,
|
|
62
|
+
"FirmwareVersion" : "2.0207",
|
|
63
|
+
"HardnessIN_CaCO3" : 374,
|
|
64
|
+
"HardnessIN_dH" : 21,
|
|
65
|
+
"HardnessIN_fH" : 37,
|
|
66
|
+
"HardnessIN_mmol_l" : 4,
|
|
67
|
+
"HardnessOUT_CaCO3" : 71,
|
|
68
|
+
"HardnessOUT_dH" : 4,
|
|
69
|
+
"HardnessOUT_fH" : 7,
|
|
70
|
+
"HardnessOUT_mmol_l" : 1,
|
|
71
|
+
"HolidayModeStartTime" : 0,
|
|
72
|
+
"LastRegenerationColumn1" : "2023-11-16 04:42:15",
|
|
73
|
+
"LastRegenerationColumn2" : "2023-11-15 04:41:48",
|
|
74
|
+
"LastServiceCustomer" : "2023-05-18 10:51:07",
|
|
75
|
+
"LastServiceTechnican" : "2021-01-25 13:14:06",
|
|
76
|
+
"OutOfService" : 0,
|
|
77
|
+
"RegenerationCountSinceSetup" : 1505,
|
|
78
|
+
"RegenerationCounterColumn1" : 754,
|
|
79
|
+
"RegenerationCounterColumn2" : 751,
|
|
80
|
+
"RegenerativLevel" : 20,
|
|
81
|
+
"RegenerativRemainingDays" : 26,
|
|
82
|
+
"RegenerativSinceSetup_g" : 245846,
|
|
83
|
+
"ShowError" : 1,
|
|
84
|
+
"WaterSinceSetup_l" : 261633,
|
|
85
|
+
"WaterTreatedCurrentDay_l" : 181,
|
|
86
|
+
"WaterTreatedCurrentMonth_l" : 3137,
|
|
87
|
+
"WaterTreatedCurrentYear_l" : 80700
|
|
88
|
+
}
|
|
89
|
+
"""
|
|
52
90
|
|
|
53
91
|
async def test_wrong_code():
|
|
54
92
|
with aioresponses() as mocked:
|
|
@@ -92,10 +130,44 @@ async def test_current_data():
|
|
|
92
130
|
in_hardness=Hardness(caco3=374, dH=21, fH=37, mmol=4),
|
|
93
131
|
out_hardness=Hardness(caco3=71, dH=4, fH=7, mmol=1),
|
|
94
132
|
holiday_mode=0,
|
|
95
|
-
regeneration_last_1=
|
|
96
|
-
regeneration_last_2=
|
|
97
|
-
service_customer=
|
|
98
|
-
service_technician=
|
|
133
|
+
regeneration_last_1=datetime(2023, 11, 16, 4, 42,15,0,ZoneInfo("UTC")),
|
|
134
|
+
regeneration_last_2=datetime(2023, 11, 15, 4, 41,48,0,ZoneInfo("UTC")),
|
|
135
|
+
service_customer=datetime(2023, 5, 18, 10, 51,7,0,ZoneInfo("UTC")),
|
|
136
|
+
service_technician=datetime(2021, 1, 25, 13, 14,6,0,ZoneInfo("UTC")),
|
|
137
|
+
out_of_service=0,
|
|
138
|
+
regeneration_count_1=754,
|
|
139
|
+
regeneration_count_2=751,
|
|
140
|
+
regeneration_count=1505,
|
|
141
|
+
regenerativ_level=20,
|
|
142
|
+
regenerativ_days=26,
|
|
143
|
+
regenerativ_total=245846,
|
|
144
|
+
show_error=1,
|
|
145
|
+
treated_day=181,
|
|
146
|
+
treated_month=3137,
|
|
147
|
+
treated_year=80700,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
async def test_empty_errors():
|
|
152
|
+
with aioresponses() as mocked:
|
|
153
|
+
mocked.get("http://host:8080/api/GetCurrentData", status=200, body=current_json_empty_errors)
|
|
154
|
+
async with BwtApi("host", "code") as api:
|
|
155
|
+
result = await api.get_current_data()
|
|
156
|
+
assert result == CurrentResponse(
|
|
157
|
+
errors=[],
|
|
158
|
+
blended_total=318383,
|
|
159
|
+
capacity_1=5485275,
|
|
160
|
+
capacity_2=3833994,
|
|
161
|
+
current_flow=0,
|
|
162
|
+
dosing_total=0,
|
|
163
|
+
firmware_version="2.0207",
|
|
164
|
+
in_hardness=Hardness(caco3=374, dH=21, fH=37, mmol=4),
|
|
165
|
+
out_hardness=Hardness(caco3=71, dH=4, fH=7, mmol=1),
|
|
166
|
+
holiday_mode=0,
|
|
167
|
+
regeneration_last_1=datetime(2023, 11, 16, 4, 42,15,0,ZoneInfo("UTC")),
|
|
168
|
+
regeneration_last_2=datetime(2023, 11, 15, 4, 41,48,0,ZoneInfo("UTC")),
|
|
169
|
+
service_customer=datetime(2023, 5, 18, 10, 51,7,0,ZoneInfo("UTC")),
|
|
170
|
+
service_technician=datetime(2021, 1, 25, 13, 14,6,0,ZoneInfo("UTC")),
|
|
99
171
|
out_of_service=0,
|
|
100
172
|
regeneration_count_1=754,
|
|
101
173
|
regeneration_count_2=751,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|