python-openevse-http 0.3.3__py3-none-any.whl → 0.3.5__py3-none-any.whl
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.
- openevsehttp/client.py +7 -27
- openevsehttp/commands.py +24 -42
- openevsehttp/const.py +2 -0
- openevsehttp/properties.py +3 -4
- openevsehttp/utils.py +29 -0
- {python_openevse_http-0.3.3.dist-info → python_openevse_http-0.3.5.dist-info}/METADATA +1 -1
- python_openevse_http-0.3.5.dist-info/RECORD +16 -0
- {python_openevse_http-0.3.3.dist-info → python_openevse_http-0.3.5.dist-info}/WHEEL +1 -1
- python_openevse_http-0.3.3.dist-info/RECORD +0 -15
- {python_openevse_http-0.3.3.dist-info → python_openevse_http-0.3.5.dist-info}/licenses/LICENSE +0 -0
- {python_openevse_http-0.3.3.dist-info → python_openevse_http-0.3.5.dist-info}/top_level.txt +0 -0
openevsehttp/client.py
CHANGED
|
@@ -6,7 +6,6 @@ import asyncio
|
|
|
6
6
|
import inspect
|
|
7
7
|
import json
|
|
8
8
|
import logging
|
|
9
|
-
import re
|
|
10
9
|
import threading
|
|
11
10
|
from collections.abc import Callable, Mapping
|
|
12
11
|
from typing import Any
|
|
@@ -31,6 +30,7 @@ from .exceptions import (
|
|
|
31
30
|
from .managers import ManagersMixin
|
|
32
31
|
from .properties import PropertiesMixin
|
|
33
32
|
from .sensors import SensorsMixin
|
|
33
|
+
from .utils import get_awesome_version
|
|
34
34
|
from .websocket import (
|
|
35
35
|
SIGNAL_CONNECTION_STATE,
|
|
36
36
|
STATE_CONNECTED,
|
|
@@ -438,41 +438,21 @@ class OpenEVSE(CommandsMixin, ManagersMixin, SensorsMixin, PropertiesMixin):
|
|
|
438
438
|
"""Return bool if minimum version is met."""
|
|
439
439
|
if "version" not in self._config:
|
|
440
440
|
# Throw warning if we can't find the version
|
|
441
|
-
_LOGGER.
|
|
441
|
+
_LOGGER.debug("Unable to find firmware version.")
|
|
442
442
|
return False
|
|
443
443
|
cutoff = AwesomeVersion(min_version)
|
|
444
|
-
current = ""
|
|
445
444
|
limit = ""
|
|
446
445
|
if max_version != "":
|
|
447
446
|
limit = AwesomeVersion(max_version)
|
|
448
447
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
if firmware_filtered is None:
|
|
455
|
-
_LOGGER.warning(
|
|
456
|
-
"Non-standard versioning string: %s", self._config["version"]
|
|
448
|
+
current = get_awesome_version(self._config["version"])
|
|
449
|
+
if current.strategy == "unknown":
|
|
450
|
+
_LOGGER.debug(
|
|
451
|
+
"Non-semver firmware version detected: %s",
|
|
452
|
+
self._config["version"],
|
|
457
453
|
)
|
|
458
|
-
_LOGGER.debug("Non-semver firmware version detected.")
|
|
459
454
|
return False
|
|
460
455
|
|
|
461
|
-
_LOGGER.debug("Detected firmware: %s", self._config["version"])
|
|
462
|
-
_LOGGER.debug("Filtered firmware: %s", firmware_filtered)
|
|
463
|
-
|
|
464
|
-
if "dev" in self._config["version"]:
|
|
465
|
-
value = self._config["version"]
|
|
466
|
-
_LOGGER.debug("Stripping 'dev' from version.")
|
|
467
|
-
value = value.split(".")
|
|
468
|
-
value = ".".join(value[0:3])
|
|
469
|
-
elif "master" in self._config["version"]:
|
|
470
|
-
value = "dev"
|
|
471
|
-
else:
|
|
472
|
-
value = firmware_filtered
|
|
473
|
-
|
|
474
|
-
current = AwesomeVersion(value)
|
|
475
|
-
|
|
476
456
|
if limit:
|
|
477
457
|
try:
|
|
478
458
|
if cutoff <= current < limit:
|
openevsehttp/commands.py
CHANGED
|
@@ -12,8 +12,9 @@ from aiohttp.client_exceptions import ContentTypeError, ServerTimeoutError
|
|
|
12
12
|
from awesomeversion import AwesomeVersion
|
|
13
13
|
from awesomeversion.exceptions import AwesomeVersionCompareException
|
|
14
14
|
|
|
15
|
-
from .const import MAX_AMPS, MIN_AMPS, RAPI_ERRORS, divert_mode
|
|
15
|
+
from .const import MAX_AMPS, MIN_AMPS, RAPI_ERRORS, SUCCESS_ANSWERS, divert_mode
|
|
16
16
|
from .exceptions import UnknownError, UnsupportedFeature
|
|
17
|
+
from .utils import get_awesome_version
|
|
17
18
|
|
|
18
19
|
_LOGGER = logging.getLogger(__name__)
|
|
19
20
|
|
|
@@ -67,7 +68,7 @@ class CommandsMixin:
|
|
|
67
68
|
response = await self.process_request(url=url, method="post", data=data)
|
|
68
69
|
response = self._normalize_response(response)
|
|
69
70
|
msg = response.get("msg") if isinstance(response, Mapping) else None
|
|
70
|
-
if msg not in
|
|
71
|
+
if msg not in SUCCESS_ANSWERS:
|
|
71
72
|
_LOGGER.error("Problem issuing command: %s", response)
|
|
72
73
|
raise UnknownError
|
|
73
74
|
|
|
@@ -94,11 +95,10 @@ class CommandsMixin:
|
|
|
94
95
|
response = await self.process_request(url=url, method="post", data=data)
|
|
95
96
|
_LOGGER.debug("divert_mode response: %s", response)
|
|
96
97
|
normalized_response = self._normalize_response(response)
|
|
97
|
-
if
|
|
98
|
-
|
|
99
|
-
"
|
|
100
|
-
|
|
101
|
-
]:
|
|
98
|
+
if (
|
|
99
|
+
isinstance(normalized_response, dict)
|
|
100
|
+
and normalized_response.get("msg") in SUCCESS_ANSWERS
|
|
101
|
+
):
|
|
102
102
|
self._config["divert_enabled"] = mode
|
|
103
103
|
return normalized_response
|
|
104
104
|
|
|
@@ -171,11 +171,10 @@ class CommandsMixin:
|
|
|
171
171
|
response = await self.process_request(url=url, method="patch")
|
|
172
172
|
response = self._normalize_response(response)
|
|
173
173
|
_LOGGER.debug("Toggle response: %s", response)
|
|
174
|
-
if
|
|
175
|
-
|
|
176
|
-
"
|
|
177
|
-
|
|
178
|
-
]:
|
|
174
|
+
if (
|
|
175
|
+
not isinstance(response, Mapping)
|
|
176
|
+
or response.get("msg") not in SUCCESS_ANSWERS
|
|
177
|
+
):
|
|
179
178
|
_LOGGER.error("Problem toggling override: %s", response)
|
|
180
179
|
raise RuntimeError(f"Failed to toggle override: {response}")
|
|
181
180
|
else:
|
|
@@ -209,7 +208,7 @@ class CommandsMixin:
|
|
|
209
208
|
response = self._normalize_response(response)
|
|
210
209
|
msg = response.get("msg") if isinstance(response, Mapping) else None
|
|
211
210
|
_LOGGER.debug("Clear override response: %s", msg)
|
|
212
|
-
if msg not in
|
|
211
|
+
if msg not in SUCCESS_ANSWERS:
|
|
213
212
|
_LOGGER.error("Problem clearing override: %s", response)
|
|
214
213
|
raise RuntimeError(f"Failed to clear override: {response}")
|
|
215
214
|
|
|
@@ -235,11 +234,10 @@ class CommandsMixin:
|
|
|
235
234
|
_LOGGER.debug("Setting current limit to %s", amps)
|
|
236
235
|
response = await self.set_override(charge_current=amps)
|
|
237
236
|
_LOGGER.debug("Set current response: %s", response)
|
|
238
|
-
if
|
|
239
|
-
|
|
240
|
-
"
|
|
241
|
-
|
|
242
|
-
]:
|
|
237
|
+
if (
|
|
238
|
+
not isinstance(response, Mapping)
|
|
239
|
+
or response.get("msg") not in SUCCESS_ANSWERS
|
|
240
|
+
):
|
|
243
241
|
_LOGGER.error("Problem setting current limit: %s", response)
|
|
244
242
|
raise UnknownError
|
|
245
243
|
|
|
@@ -274,7 +272,7 @@ class CommandsMixin:
|
|
|
274
272
|
response = self._normalize_response(response)
|
|
275
273
|
_LOGGER.debug("service response: %s", response)
|
|
276
274
|
msg = response.get("msg") if isinstance(response, Mapping) else None
|
|
277
|
-
if msg not in
|
|
275
|
+
if msg not in SUCCESS_ANSWERS:
|
|
278
276
|
_LOGGER.error("Problem issuing command: %s", response)
|
|
279
277
|
raise UnknownError
|
|
280
278
|
|
|
@@ -357,29 +355,17 @@ class CommandsMixin:
|
|
|
357
355
|
"""Return the latest firmware version."""
|
|
358
356
|
if "version" not in self._config:
|
|
359
357
|
# Throw warning if we can't find the version
|
|
360
|
-
_LOGGER.
|
|
358
|
+
_LOGGER.debug("Unable to find firmware version.")
|
|
361
359
|
return None
|
|
362
360
|
base_url = "https://api.github.com/repos/OpenEVSE/"
|
|
363
361
|
url = None
|
|
364
362
|
method = "get"
|
|
365
363
|
|
|
366
364
|
cutoff = AwesomeVersion("3.0.0")
|
|
367
|
-
current = ""
|
|
368
|
-
|
|
369
365
|
_LOGGER.debug("Detected firmware: %s", self._config["version"])
|
|
370
366
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
_LOGGER.debug("Stripping 'dev' from version.")
|
|
374
|
-
value = value.split(".")
|
|
375
|
-
value = ".".join(value[0:3])
|
|
376
|
-
elif "master" in self._config["version"]:
|
|
377
|
-
value = "dev"
|
|
378
|
-
else:
|
|
379
|
-
value = self._config["version"]
|
|
380
|
-
|
|
381
|
-
_LOGGER.debug("Using version: %s", value)
|
|
382
|
-
current = AwesomeVersion(value)
|
|
367
|
+
current = get_awesome_version(self._config["version"])
|
|
368
|
+
_LOGGER.debug("Using version: %s", current)
|
|
383
369
|
|
|
384
370
|
try:
|
|
385
371
|
if current >= cutoff:
|
|
@@ -387,7 +373,7 @@ class CommandsMixin:
|
|
|
387
373
|
else:
|
|
388
374
|
url = f"{base_url}ESP8266_WiFi_v2.x/releases/latest"
|
|
389
375
|
except AwesomeVersionCompareException:
|
|
390
|
-
_LOGGER.
|
|
376
|
+
_LOGGER.debug("Non-semver firmware version detected.")
|
|
391
377
|
return None
|
|
392
378
|
|
|
393
379
|
try:
|
|
@@ -459,7 +445,7 @@ class CommandsMixin:
|
|
|
459
445
|
response = await self.process_request(url=url, method="post", data=data)
|
|
460
446
|
response = self._normalize_response(response)
|
|
461
447
|
msg = response.get("msg") if isinstance(response, Mapping) else None
|
|
462
|
-
if msg not in
|
|
448
|
+
if msg not in SUCCESS_ANSWERS:
|
|
463
449
|
_LOGGER.error("Problem issuing command: %s", response)
|
|
464
450
|
raise UnknownError
|
|
465
451
|
|
|
@@ -481,11 +467,7 @@ class CommandsMixin:
|
|
|
481
467
|
res_lower = response.lower()
|
|
482
468
|
if "divert" in res_lower and "changed" in res_lower:
|
|
483
469
|
success = True
|
|
484
|
-
elif isinstance(response, dict) and response.get("msg") in
|
|
485
|
-
"OK",
|
|
486
|
-
"done",
|
|
487
|
-
"no change",
|
|
488
|
-
]:
|
|
470
|
+
elif isinstance(response, dict) and response.get("msg") in SUCCESS_ANSWERS:
|
|
489
471
|
success = True
|
|
490
472
|
|
|
491
473
|
if not success:
|
|
@@ -508,7 +490,7 @@ class CommandsMixin:
|
|
|
508
490
|
response = await self.process_request(url=url, method="post", rapi=data)
|
|
509
491
|
response = self._normalize_response(response)
|
|
510
492
|
msg = response.get("msg") if isinstance(response, Mapping) else None
|
|
511
|
-
if msg not in
|
|
493
|
+
if msg not in SUCCESS_ANSWERS and msg != "Current Shaper state changed":
|
|
512
494
|
_LOGGER.error("Problem issuing command: %s", response)
|
|
513
495
|
raise UnknownError
|
|
514
496
|
|
openevsehttp/const.py
CHANGED
openevsehttp/properties.py
CHANGED
|
@@ -9,6 +9,7 @@ from typing import Any
|
|
|
9
9
|
|
|
10
10
|
from .const import MAX_AMPS, MIN_AMPS, states
|
|
11
11
|
from .exceptions import UnsupportedFeature
|
|
12
|
+
from .utils import normalize_version
|
|
12
13
|
|
|
13
14
|
_LOGGER = logging.getLogger(__name__)
|
|
14
15
|
|
|
@@ -130,10 +131,8 @@ class PropertiesMixin:
|
|
|
130
131
|
def wifi_firmware(self) -> str | None:
|
|
131
132
|
"""Return the ESP firmware version."""
|
|
132
133
|
value = self._config.get("version")
|
|
133
|
-
if value is not None
|
|
134
|
-
|
|
135
|
-
value = value.split(".")
|
|
136
|
-
value = ".".join(value[0:3])
|
|
134
|
+
if value is not None:
|
|
135
|
+
value = normalize_version(value)
|
|
137
136
|
return value
|
|
138
137
|
|
|
139
138
|
@property
|
openevsehttp/utils.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Utility functions for python-openevse-http."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import re
|
|
5
|
+
|
|
6
|
+
from awesomeversion import AwesomeVersion
|
|
7
|
+
|
|
8
|
+
_LOGGER = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def normalize_version(version: str) -> str:
|
|
12
|
+
"""Normalize the version string to strip 'dev' tag."""
|
|
13
|
+
if "dev" in version:
|
|
14
|
+
_LOGGER.debug("Stripping 'dev' from version.")
|
|
15
|
+
value = version.split(".")
|
|
16
|
+
return ".".join(value[0:3])
|
|
17
|
+
return version
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def get_awesome_version(version: str) -> AwesomeVersion:
|
|
21
|
+
"""Parse and normalize the version string, returning an AwesomeVersion."""
|
|
22
|
+
if "master" in version:
|
|
23
|
+
version = "dev"
|
|
24
|
+
value = normalize_version(version)
|
|
25
|
+
if "dev" not in version:
|
|
26
|
+
firmware_search = re.search(r"\d+\.\d+\.\d+", value)
|
|
27
|
+
if firmware_search:
|
|
28
|
+
value = firmware_search.group(0)
|
|
29
|
+
return AwesomeVersion(value)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
openevsehttp/__init__.py,sha256=I6a1mjOZHYiWb_qfCuDuFLOOncrkkB_7uwybtOIujfY,1165
|
|
2
|
+
openevsehttp/__main__.py,sha256=EHmSdT7GjAVvHQxvLBTjZXsj_V5SB6B2_kpgUAT7mPM,146
|
|
3
|
+
openevsehttp/client.py,sha256=JBAC1jJGdzOabVAqHv8x6EJDVjhaW4t7Iwqn4lDWhwE,17502
|
|
4
|
+
openevsehttp/commands.py,sha256=lANhgVhtJJlQxLwFlMrxk3DrmnY2bXK5h4z3o9o6ZEk,20617
|
|
5
|
+
openevsehttp/const.py,sha256=y-2hGv_PCal_-VCSGC7IIyzQYtfeVdq3MjOhBWIdZvc,1440
|
|
6
|
+
openevsehttp/exceptions.py,sha256=bqz-tHTW1AYJMKcm0s5M6z5tA6XZgjnCiBLW1XrZ_70,672
|
|
7
|
+
openevsehttp/managers.py,sha256=kEX1ZD9u-FY0UEZJsxeFEGBSGzSlkbBc0kmxCiMJtJw,5373
|
|
8
|
+
openevsehttp/properties.py,sha256=QVSyn_5a7vI1b4TdnnToRdw6veVCfnp7a19VYit95hg,17107
|
|
9
|
+
openevsehttp/sensors.py,sha256=sJP2FPnU1Lk5S3VUyFT14JM1nKEBQPsjl-DiZI-pZrs,4673
|
|
10
|
+
openevsehttp/utils.py,sha256=e3HH_jwZgb1iBWJgIoMOM0JPrQNwXyVdOx5vTWOh4T0,858
|
|
11
|
+
openevsehttp/websocket.py,sha256=Mi_WFmlT3-9i6bbHIN6ua09SD8CpIle2vRXB3HyWzmM,10066
|
|
12
|
+
python_openevse_http-0.3.5.dist-info/licenses/LICENSE,sha256=hSB6TOQ7rmwSGb6XzqRjDGMvmUj5_GlacqQin3tegtA,11341
|
|
13
|
+
python_openevse_http-0.3.5.dist-info/METADATA,sha256=3VxDib4FCHGZ3QODauCoWzXQiPggRx_7q8yRvCwa7G8,4363
|
|
14
|
+
python_openevse_http-0.3.5.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
15
|
+
python_openevse_http-0.3.5.dist-info/top_level.txt,sha256=u8RUkoEIE33Cjn6gmqiEoVpZ0VZ59WJ3FXBwwOg0CPE,13
|
|
16
|
+
python_openevse_http-0.3.5.dist-info/RECORD,,
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
openevsehttp/__init__.py,sha256=I6a1mjOZHYiWb_qfCuDuFLOOncrkkB_7uwybtOIujfY,1165
|
|
2
|
-
openevsehttp/__main__.py,sha256=EHmSdT7GjAVvHQxvLBTjZXsj_V5SB6B2_kpgUAT7mPM,146
|
|
3
|
-
openevsehttp/client.py,sha256=JYReKIJLbQbymq_o19-oZgxMyxHwZB6Sc-M6unVfMOo,18208
|
|
4
|
-
openevsehttp/commands.py,sha256=yQMsDHTxPJpwzYB9V4LXhzmKIhFF7zFv0NtpxivBn94,21109
|
|
5
|
-
openevsehttp/const.py,sha256=VSc5Xt-KFenft0rT6ql9whCD7J9g_YvjLYU_PX706eE,1360
|
|
6
|
-
openevsehttp/exceptions.py,sha256=bqz-tHTW1AYJMKcm0s5M6z5tA6XZgjnCiBLW1XrZ_70,672
|
|
7
|
-
openevsehttp/managers.py,sha256=kEX1ZD9u-FY0UEZJsxeFEGBSGzSlkbBc0kmxCiMJtJw,5373
|
|
8
|
-
openevsehttp/properties.py,sha256=Lo2p6WfPuhpaEcIZ0OeAxinHSa0G8Sv2wLZ-dPe7rjo,17181
|
|
9
|
-
openevsehttp/sensors.py,sha256=sJP2FPnU1Lk5S3VUyFT14JM1nKEBQPsjl-DiZI-pZrs,4673
|
|
10
|
-
openevsehttp/websocket.py,sha256=Mi_WFmlT3-9i6bbHIN6ua09SD8CpIle2vRXB3HyWzmM,10066
|
|
11
|
-
python_openevse_http-0.3.3.dist-info/licenses/LICENSE,sha256=hSB6TOQ7rmwSGb6XzqRjDGMvmUj5_GlacqQin3tegtA,11341
|
|
12
|
-
python_openevse_http-0.3.3.dist-info/METADATA,sha256=jRmVpNx2qlkUs3Py45EPGjwZHT89vzWJzVB3grOl8Iw,4363
|
|
13
|
-
python_openevse_http-0.3.3.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
|
|
14
|
-
python_openevse_http-0.3.3.dist-info/top_level.txt,sha256=u8RUkoEIE33Cjn6gmqiEoVpZ0VZ59WJ3FXBwwOg0CPE,13
|
|
15
|
-
python_openevse_http-0.3.3.dist-info/RECORD,,
|
{python_openevse_http-0.3.3.dist-info → python_openevse_http-0.3.5.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|