-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support Multiple inverter api for inverter type (#96)
* Support Multiple inverter api for inverter type The main problem is that inverters apis are different in two ways: - The api end point to get the data - Some aspects of parsing the non-"data" attributes of the response (like SN, version, etc...) Each single inverter could expose (for example) two end points in general. as in, before version x it exposes an end point with query parameters, but after version x it exposes the end point with params in the request body. The inheritance model in the project is short handed here. As it is based on the assumption that a single inverter will always support a single api end point contract. This patch is basically (and only for now), refactoring in favor of composition (vs. inheritance). Each inverter class is initiated with two dependencies/components: - InverterHttpClient - ResponseParser To support multiple variants for each inverter, we only build the inverter with proper variations of those dependencies. So, After this patch, the discovery process is all about asking the inverter class to build all possible variants this inverter knows it supports. The discovery then goes on, as was before, trying to use that variant to get_data, until one variant is successful. The patch tries as much as possible to continue providing sane and most common defaults for inveter's implementations. At this moment, the patch does not add (or subtract) any feature/support on top of the baseline (before the patch). This is just opening the opportunity to easily add missing variants. Closes #88 WIP * Add a verify script to be run locally This will be helpful for new contributors to check their code against the github workflow checks without back and forth communication with the maintainers to run the pipeline manually for them. Co-authored-by: Robin Wohlers-Reichel <me@robinwr.com>
- Loading branch information
1 parent
cb2ba8d
commit 5c5097e
Showing
19 changed files
with
359 additions
and
213 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
/.vscode | ||
/.idea/** | ||
*.pyc | ||
/dist | ||
/solax.egg-info | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
from enum import Enum | ||
|
||
import aiohttp | ||
|
||
|
||
class Method(Enum): | ||
GET = 1 | ||
POST = 2 | ||
|
||
|
||
class InverterHttpClient: | ||
def __init__(self, url, method: Method = Method.POST, pwd=""): | ||
"""Initialize the Http client.""" | ||
self.url = url | ||
self.method = method | ||
self.pwd = pwd | ||
self.headers = None | ||
self.data = None | ||
self.query = "" | ||
|
||
@classmethod | ||
def build_w_url(cls, url, method: Method = Method.POST): | ||
http_client = cls(url, method, "") | ||
return http_client | ||
|
||
def with_headers(self, headers): | ||
self.headers = headers | ||
return self | ||
|
||
def with_default_data(self): | ||
data = "optType=ReadRealTimeData" | ||
if self.pwd: | ||
data = data + "&pwd=" + self.pwd | ||
return self.with_data(data) | ||
|
||
def with_data(self, data): | ||
self.data = data | ||
return self | ||
|
||
def with_query(self, query): | ||
self.query = query | ||
return self | ||
|
||
def with_default_query(self): | ||
if self.pwd: | ||
base = "optType=ReadRealTimeData&pwd={}&" | ||
query = base.format(self.pwd) | ||
else: | ||
query = "optType=ReadRealTimeData" | ||
|
||
return self.with_query(query) | ||
|
||
async def request(self): | ||
if self.method is Method.POST: | ||
return await self.post() | ||
return await self.get() | ||
|
||
async def get(self): | ||
url = self.url + "?" + self.query if self.query else self.url | ||
async with aiohttp.ClientSession() as session: | ||
async with session.get(url, headers=self.headers) as req: | ||
req.raise_for_status() | ||
resp = await req.read() | ||
return resp | ||
|
||
async def post(self): | ||
url = self.url + "?" + self.query if self.query else self.url | ||
data = self.data.encode("utf-8") if self.data else None | ||
async with aiohttp.ClientSession() as session: | ||
async with session.post(url, headers=self.headers, data=data) as req: | ||
req.raise_for_status() | ||
resp = await req.read() | ||
return resp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.