Skip to content

Commit 3275262

Browse files
authored
build: merge dev into main (#98)
* chore: add pre-commit config and linting (#70) * chore: add pre-commit config and linting * fix requirements for linting * feat: add test_and_get function (#87) * feat: add test_and_get function * linting * more test coverage * fix: adjust power calculation function (#93) * fix: adjust power calculation function * adjust pylint config * bump version * Update publish-to-pypi.yml * feat: add restart_wifi method to restart wifi module (#97)
1 parent cbe45b9 commit 3275262

File tree

7 files changed

+78
-12
lines changed

7 files changed

+78
-12
lines changed

.github/workflows/publish-to-pypi.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ jobs:
2222
- name: Build
2323
run: >-
2424
python3 setup.py sdist bdist_wheel
25-
- name: Publish release to PyPI
26-
uses: pypa/gh-action-pypi-publish@master
25+
- name: Publish a Python distribution to PyPI
26+
uses: pypa/gh-action-pypi-publish@release/v1
2727
with:
28-
user: __token__
2928
password: ${{ secrets.PYPI_TOKEN }}

openevsehttp/__init__.py

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
AlreadyListening,
1717
AuthenticationError,
1818
MissingMethod,
19+
MissingSerial,
1920
ParseJSONError,
2021
UnknownError,
2122
)
@@ -287,6 +288,28 @@ async def update(self) -> None:
287288
self.url, self._update_status, self._user, self._pwd
288289
)
289290

291+
async def test_and_get(self) -> dict:
292+
"""Test connection.
293+
294+
Return model serial number as dict
295+
"""
296+
url = f"{self.url}config"
297+
data = {}
298+
299+
response = await self.process_request(url, method="get")
300+
if "wifi_serial" in response:
301+
serial = response["wifi_serial"]
302+
else:
303+
_LOGGER.debug("Older firmware detected, missing serial.")
304+
raise MissingSerial
305+
if "buildenv" in response:
306+
model = response["buildenv"]
307+
else:
308+
model = "unknown"
309+
310+
data = {"serial": serial, "model": model}
311+
return data
312+
290313
def ws_start(self):
291314
"""Start the websocket listener."""
292315
if self._ws_listening:
@@ -503,6 +526,14 @@ async def set_current(self, amps: int = 6) -> None:
503526
response = await self.send_command(command)
504527
_LOGGER.debug("Set current response: %s", response[1])
505528

529+
# Restart OpenEVSE WiFi
530+
async def restart_wifi(self) -> None:
531+
"""Restart OpenEVSE Wifi module."""
532+
url = f"{self.url}restart"
533+
534+
response = await self.process_request(url=url, method="get")
535+
_LOGGER.debug("Restart response: %s", response)
536+
506537
@property
507538
def hostname(self) -> str:
508539
"""Return charger hostname."""
@@ -793,14 +824,16 @@ def wifi_serial(self) -> str | None:
793824
return None
794825

795826
@property
796-
def charging_power(self) -> float:
827+
def charging_power(self) -> float | None:
797828
"""Return the charge power.
798829
799830
Calculate Watts base on V*I
800831
"""
801-
assert self._status is not None
802-
value = round(self._status["voltage"] * self._status["amp"], 2)
803-
return value
832+
if self._status is not None and any(
833+
key in self._status for key in ["voltage", "amp"]
834+
):
835+
return round(self._status["voltage"] * self._status["amp"], 2)
836+
return None
804837

805838
# There is currently no min/max amps JSON data
806839
# available via HTTP API methods

openevsehttp/exceptions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,7 @@ class MissingMethod(Exception):
1919

2020
class AlreadyListening(Exception):
2121
"""Exception for already listening websocket."""
22+
23+
24+
class MissingSerial(Exception):
25+
"""Exception for missing serial number."""

pylintrc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ max-attributes=15
1616
# too-few-* - same as too-many-*
1717
# import-outside-toplevel - TODO
1818
disable=
19-
bad-continuation,
2019
duplicate-code,
2120
fixme,
2221
import-outside-toplevel,
@@ -26,7 +25,6 @@ disable=
2625
too-many-public-methods,
2726
too-many-instance-attributes,
2827
too-many-branches,
29-
no-self-use,
3028
too-many-statements
3129

3230
[REPORTS]

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
PROJECT_DIR = Path(__file__).parent.resolve()
77
README_FILE = PROJECT_DIR / "README.md"
8-
VERSION = "0.1.24"
8+
VERSION = "0.1.25"
99

1010
setup(
1111
name="python-openevse-http",

tests/test_init.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@
99
from aiohttp.client_exceptions import ContentTypeError, ServerTimeoutError
1010

1111
import openevsehttp
12+
from tests.common import load_fixture
13+
from openevsehttp.exceptions import MissingSerial
1214

1315
pytestmark = pytest.mark.asyncio
1416

1517
TEST_URL_RAPI = "http://openevse.test.tld/r"
1618
TEST_URL_OVERRIDE = "http://openevse.test.tld/override"
1719
TEST_URL_CONFIG = "http://openevse.test.tld/config"
1820
TEST_URL_DIVERT = "http://openevse.test.tld/divertmode"
21+
TEST_URL_RESTART = "http://openevse.test.tld/restart"
1922

2023

2124
async def test_get_status_auth(test_charger_auth):
@@ -737,3 +740,32 @@ async def test_set_divertmode(test_charger_v2, mock_aioclient, caplog):
737740
await test_charger_v2.divert_mode("normal")
738741
assert "Setting charge mode to normal" in caplog.text
739742
assert "Non JSON response: Divert Mode changed" in caplog.text
743+
744+
745+
async def test_test_and_get(test_charger, test_charger_v2, mock_aioclient, caplog):
746+
"""Test v4 Status reply"""
747+
data = await test_charger.test_and_get()
748+
mock_aioclient.get(
749+
TEST_URL_CONFIG,
750+
status=200,
751+
body=load_fixture("v4_json/config.json"),
752+
)
753+
assert data["serial"] == "1234567890AB"
754+
assert data["model"] == "unknown"
755+
756+
with pytest.raises(MissingSerial):
757+
with caplog.at_level(logging.DEBUG):
758+
data = await test_charger_v2.test_and_get()
759+
assert "Older firmware detected, missing serial." in caplog.text
760+
761+
762+
async def test_restart(test_charger_v2, mock_aioclient, caplog):
763+
"""Test v4 set divert mode."""
764+
mock_aioclient.get(
765+
TEST_URL_RESTART,
766+
status=200,
767+
body="1",
768+
)
769+
with caplog.at_level(logging.DEBUG):
770+
await test_charger_v2.restart_wifi()
771+
assert "Restart response: 1" in caplog.text

tox.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ skip_missing_interpreters = True
44

55
[gh-actions]
66
python =
7-
3.8: py38, lint, mypy
7+
3.8: py38
88
3.9: py39
9-
3.10: py310
9+
3.10: py310, lint, mypy
1010

1111
[testenv]
1212
commands =

0 commit comments

Comments
 (0)