Repository: jrester/tesla_powerwall (language: python)

Issue:
Reduce CPU usage with orjson
Use orjson for parsing json.

See:   https://github.com/bdraco/nexia/blob/ee3253ab8cf1f128b700e59bb09354e21612851e/nexia/home.py#L244


Discussion / hints:

Fix patch:
diff --git a/.gitignore b/.gitignore
index 2ea6a99..7d435d4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -127,4 +127,4 @@ dmypy.json
 .direnv
 
 # MacOS finder stuff
-.DS_Store
\ No newline at end of file
+.DS_Store
diff --git a/CHANGELOG b/CHANGELOG
index 4a9bcc4..ec03f2a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,9 @@
 # Changelog
 
+## [0.5.1]
+
+- Use orjson for parsing json
+
 ## [0.5.0]
 
 - BREAKING: The API is now async by default (by @bubonicbob)
diff --git a/LICENSE b/LICENSE
index 53f8e84..5b3026f 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 MIT License
 
-Copyright (c) 2023 Jrester
+Copyright (c) 2024 Jrester
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 0a43852..1d2d8aa 100644
--- a/README.md
+++ b/README.md
@@ -36,6 +36,7 @@ Powerwall Software versions from 1.47.0 to 1.50.1 as well as 20.40 to 22.9.2 are
     - [Gateway DIN](#gateway-din)
     - [VIN](#vin)
     - [Off-grid status](#off-grid-status-set-island-mode)
+- [Development](#development)
 
 ## Installation
 
@@ -389,6 +390,18 @@ await powerwall.set_island_mode(IslandMode.ONGRID)
 
 # Development
 
+## pre-commit
+
+This project uses pre-commit to run linters, formatters and type checking. You can easily run those checks locally:
+
+```sh
+# Install the pre-commit hooks
+$ pre-commit install
+pre-commit installed at .git/hooks/pre-commit
+```
+
+Now those checks will be execute on every `git commit`. You can also execute all checks manually with `pre-commit run --all-files`.
+
 ## Building
 
 ```sh
@@ -397,6 +410,9 @@ $ python -m build
 
 ## Testing
 
+The tests are split in unit and integration tests.
+The unit tests are self-contained and can simply be run locally by executing `tox -e unit`, whereas the integration test, run against a real powerwall.
+
 ### Unit-Tests
 
 To run unit tests use tox:
@@ -407,6 +423,12 @@ $ tox -e unit
 
 ### Integration-Tests
 
+To execute the integration tests you need to first provide some information about your powerwall:
+
 ```sh
+$ export POWERWALL_IP=<ip of your powerwall>
+$ export POWERWALL_PASSWORD=<password for your powerwall>
 $ tox -e integration
 ```
+
+> The integration tests might take your powerwall off grid and bring it back online. Before running the tests, make sure that you know what you are doing!
diff --git a/pyproject.toml b/pyproject.toml
index d8c066e..718da04 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -16,6 +16,7 @@ keywords = ["api", "tesla", "powerwall", "tesla_powerwall"]
 dependencies = [
   "aiohttp>=3.7.4",
   "urllib3>=1.26.18",
+  "orjson>=3.9.0"
 ]
 
 [project.urls]
diff --git a/tesla_powerwall/api.py b/tesla_powerwall/api.py
index a862691..27f40c9 100644
--- a/tesla_powerwall/api.py
+++ b/tesla_powerwall/api.py
@@ -1,10 +1,11 @@
-import aiohttp
 from http.client import responses
 from json.decoder import JSONDecodeError
 from types import TracebackType
 from typing import Any, List, Optional, Type
 from urllib.parse import urljoin
 
+import aiohttp
+import orjson
 from urllib3 import disable_warnings
 from urllib3.exceptions import InsecureRequestWarning
 
@@ -68,7 +69,7 @@ async def _handle_error(response: aiohttp.ClientResponse) -> None:
         if response.status == 401 or response.status == 403:
             response_json = None
             try:
-                response_json = await response.json()
+                response_json = await response.json(loads=orjson.loads)
             except Exception:
                 raise AccessDeniedError(str(response.real_url))
             else:
@@ -104,7 +105,7 @@ async def _process_response(self, response: aiohttp.ClientResponse) -> dict:
             return {}
 
         try:
-            response_json = await response.json(content_type=None)
+            response_json = await response.json(content_type=None, loads=orjson.loads)
         except JSONDecodeError:
             raise ApiError(
                 "Error while decoding json of response: {}".format(response.text)
diff --git a/tesla_powerwall/powerwall.py b/tesla_powerwall/powerwall.py
index 99a9a00..d77e9cc 100644
--- a/tesla_powerwall/powerwall.py
+++ b/tesla_powerwall/powerwall.py
@@ -1,5 +1,5 @@
 from types import TracebackType
-from typing import List, Union, Optional, Type
+from typing import List, Optional, Type, Union
 
 import aiohttp
 
diff --git a/tox.ini b/tox.ini
index fd89342..fe92d15 100644
--- a/tox.ini
+++ b/tox.ini
@@ -10,4 +10,4 @@ commands = python -m unittest discover tests/unit
 
 [testenv:integration]
 passenv = POWERWALL_IP,POWERWALL_PASSWORD
-commands = python -m unittest discover tests/integration
\ No newline at end of file
+commands = python -m unittest discover tests/integration


Test patch:
diff --git a/tests/integration/test_powerwall.py b/tests/integration/test_powerwall.py
index e1dc035..1c11568 100644
--- a/tests/integration/test_powerwall.py
+++ b/tests/integration/test_powerwall.py
@@ -1,4 +1,3 @@
-import aiohttp
 import asyncio
 import unittest
 
diff --git a/tests/unit/test_api.py b/tests/unit/test_api.py
index 4da39b7..c796ea1 100644
--- a/tests/unit/test_api.py
+++ b/tests/unit/test_api.py
@@ -1,16 +1,12 @@
+import json
 import unittest
 
 import aiohttp
 import aresponses
-import json
 
-from tesla_powerwall import API, AccessDeniedError, ApiError, PowerwallUnreachableError
+from tesla_powerwall import API, AccessDeniedError, ApiError
 from tesla_powerwall.const import User
-from tests.unit import (
-    ENDPOINT_HOST,
-    ENDPOINT_PATH,
-    ENDPOINT,
-)
+from tests.unit import ENDPOINT, ENDPOINT_HOST, ENDPOINT_PATH
 
 
 class TestAPI(unittest.IsolatedAsyncioTestCase):
diff --git a/tests/unit/test_powerwall.py b/tests/unit/test_powerwall.py
index a8ce631..5a79eb3 100644
--- a/tests/unit/test_powerwall.py
+++ b/tests/unit/test_powerwall.py
@@ -1,9 +1,10 @@
-import aiohttp
-import aresponses
 import datetime
 import json
-from typing import Optional, Union
 import unittest
+from typing import Optional, Union
+
+import aiohttp
+import aresponses
 
 from tesla_powerwall import (
     API,
@@ -24,9 +25,9 @@
 )
 from tesla_powerwall.const import OperationMode
 from tests.unit import (
+    ENDPOINT,
     ENDPOINT_HOST,
     ENDPOINT_PATH,
-    ENDPOINT,
     GRID_STATUS_RESPONSE,
     ISLANDING_MODE_OFFGRID_RESPONSE,
     ISLANDING_MODE_ONGRID_RESPONSE,