diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml new file mode 100644 index 0000000..076ccda --- /dev/null +++ b/.github/workflows/publish.yaml @@ -0,0 +1,21 @@ +name: Upload Python Package to PyPI when a Release is Created + +on: + release: + types: [created] + +jobs: + pypi-publish: + name: Publish release to PyPI + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/derapi + permissions: + id-token: write + contents: read + steps: + - uses: actions/checkout@v4 + - uses: pypa/hatch@install + - run: hatch build + - uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..849ddff --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +dist/ diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..9313eed --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,7 @@ +# changelog + +## [0.1.0] - 2024-11-08 + +### Added + +- Initialized the API client code diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..0ac9ac0 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2024-present Derapi (https://derapi.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..31bd835 --- /dev/null +++ b/README.md @@ -0,0 +1,63 @@ +# derapi + +The `derapi` Python SDK provides access to the Derapi API for Python +applications -- fully typed with async support. + +[![PyPI - Version](https://img.shields.io/pypi/v/derapi.svg)](https://pypi.org/project/derapi) +[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/derapi.svg)](https://pypi.org/project/derapi) + +----- + +## Table of Contents + +- [Installation](#installation) +- [Usage](#usage) +- [License](#license) + +## Installation + +```shell +pip install derapi +``` + +## Usage + +Client initialization: + +```python +import os + +import httpx +from derapi import AuthenticatedClient + +def init_client() -> AuthenticatedClient: + token_resp = httpx.post( + "https://auth.derapi.com/oauth2/token", + auth=(os.environ["DERAPI_CLIENT_ID"], os.environ["DERAPI_CLIENT_SECRET"]), + data={"grant_type": "client_credentials"}, + ) + token_resp.raise_for_status() + token = token_resp.json()["access_token"] + return AuthenticatedClient( + base_url="https//api.derapi.com", + raise_on_unexpected_status=True, + token=token, + ) +``` + +Usage: + +```python +... + +from derapi.api import list_sites + +client = init_client() + +for site in list_sites.sync_depaginated(client=client): + print(site.id) +``` + +## License + +`derapi` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license. diff --git a/derapi/__init__.py b/derapi/__init__.py new file mode 100644 index 0000000..c7d157e --- /dev/null +++ b/derapi/__init__.py @@ -0,0 +1,8 @@ +"""A client library for accessing Derapi API Reference""" + +from .client import AuthenticatedClient, Client + +__all__ = ( + "AuthenticatedClient", + "Client", +) diff --git a/derapi/api/__init__.py b/derapi/api/__init__.py new file mode 100644 index 0000000..81f9fa2 --- /dev/null +++ b/derapi/api/__init__.py @@ -0,0 +1 @@ +"""Contains methods for accessing the API""" diff --git a/derapi/api/batteries/__init__.py b/derapi/api/batteries/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/derapi/api/batteries/get_battery.py b/derapi/api/batteries/get_battery.py new file mode 100644 index 0000000..d641a3d --- /dev/null +++ b/derapi/api/batteries/get_battery.py @@ -0,0 +1,158 @@ +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.get_battery_response import GetBatteryResponse +from ...types import Response + + +def _get_kwargs( + id: str, +) -> Dict[str, Any]: + _kwargs: Dict[str, Any] = { + "method": "get", + "url": f"/batteries/{id}", + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[GetBatteryResponse]: + if response.status_code == 200: + response_200 = GetBatteryResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[GetBatteryResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[GetBatteryResponse]: + """Returns Battery details + + Returns details for a single Battery + + Args: + id (str): Battery id + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetBatteryResponse] + """ + + kwargs = _get_kwargs( + id=id, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Optional[GetBatteryResponse]: + """Returns Battery details + + Returns details for a single Battery + + Args: + id (str): Battery id + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetBatteryResponse + """ + + return sync_detailed( + id=id, + client=client, + ).parsed + + +async def asyncio_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[GetBatteryResponse]: + """Returns Battery details + + Returns details for a single Battery + + Args: + id (str): Battery id + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetBatteryResponse] + """ + + kwargs = _get_kwargs( + id=id, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Optional[GetBatteryResponse]: + """Returns Battery details + + Returns details for a single Battery + + Args: + id (str): Battery id + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetBatteryResponse + """ + + return ( + await asyncio_detailed( + id=id, + client=client, + ) + ).parsed diff --git a/derapi/api/batteries/get_battery_intervals.py b/derapi/api/batteries/get_battery_intervals.py new file mode 100644 index 0000000..389cd06 --- /dev/null +++ b/derapi/api/batteries/get_battery_intervals.py @@ -0,0 +1,393 @@ +import datetime +from http import HTTPStatus +from typing import Any, AsyncIterator, Dict, Iterator, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.battery_interval import BatteryInterval +from ...models.get_battery_intervals_response import GetBatteryIntervalsResponse +from ...models.summary_level import SummaryLevel +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + id: str, + *, + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Dict[str, Any]: + params: Dict[str, Any] = {} + + json_summary_level: Union[Unset, str] = UNSET + if not isinstance(summary_level, Unset): + json_summary_level = summary_level.value + + params["summaryLevel"] = json_summary_level + + json_start = start.isoformat() + params["start"] = json_start + + json_end = end.isoformat() + params["end"] = json_end + + params["pageSize"] = page_size + + params["pageToken"] = page_token + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: Dict[str, Any] = { + "method": "get", + "url": f"/batteries/{id}/intervals", + "params": params, + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[GetBatteryIntervalsResponse]: + if response.status_code == 200: + response_200 = GetBatteryIntervalsResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[GetBatteryIntervalsResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Response[GetBatteryIntervalsResponse]: + """Returns Battery interval data + + Returns individual Battery charge and discharge data aggregated to the specific granularity + requested for a specified start and end date. The energy data intervals are represented in kWh. + Intervals are always aligned with the start of a month, day, or hour. Partial period requests are + expanded to cover the full interval for the requested summary level. For example, a summary-level + request of month with a start date of 12/3 and end date of 1/1 will return data covering the entire + month of December. + + Args: + id (str): Battery id + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetBatteryIntervalsResponse] + """ + + kwargs = _get_kwargs( + id=id, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Optional[GetBatteryIntervalsResponse]: + """Returns Battery interval data + + Returns individual Battery charge and discharge data aggregated to the specific granularity + requested for a specified start and end date. The energy data intervals are represented in kWh. + Intervals are always aligned with the start of a month, day, or hour. Partial period requests are + expanded to cover the full interval for the requested summary level. For example, a summary-level + request of month with a start date of 12/3 and end date of 1/1 will return data covering the entire + month of December. + + Args: + id (str): Battery id + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetBatteryIntervalsResponse + """ + + return sync_detailed( + id=id, + client=client, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ).parsed + + +async def asyncio_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Response[GetBatteryIntervalsResponse]: + """Returns Battery interval data + + Returns individual Battery charge and discharge data aggregated to the specific granularity + requested for a specified start and end date. The energy data intervals are represented in kWh. + Intervals are always aligned with the start of a month, day, or hour. Partial period requests are + expanded to cover the full interval for the requested summary level. For example, a summary-level + request of month with a start date of 12/3 and end date of 1/1 will return data covering the entire + month of December. + + Args: + id (str): Battery id + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetBatteryIntervalsResponse] + """ + + kwargs = _get_kwargs( + id=id, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Optional[GetBatteryIntervalsResponse]: + """Returns Battery interval data + + Returns individual Battery charge and discharge data aggregated to the specific granularity + requested for a specified start and end date. The energy data intervals are represented in kWh. + Intervals are always aligned with the start of a month, day, or hour. Partial period requests are + expanded to cover the full interval for the requested summary level. For example, a summary-level + request of month with a start date of 12/3 and end date of 1/1 will return data covering the entire + month of December. + + Args: + id (str): Battery id + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetBatteryIntervalsResponse + """ + + return ( + await asyncio_detailed( + id=id, + client=client, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) + ).parsed + + +def sync_depaginated( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Iterator[BatteryInterval]: + """Returns Battery interval data + + Returns individual Battery charge and discharge data aggregated to the specific granularity + requested for a specified start and end date. The energy data intervals are represented in kWh. + Intervals are always aligned with the start of a month, day, or hour. Partial period requests are + expanded to cover the full interval for the requested summary level. For example, a summary-level + request of month with a start date of 12/3 and end date of 1/1 will return data covering the entire + month of December. + + Args: + id (str): Battery id + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Iterator[BatteryInterval] + """ + + response = sync( + id=id, + client=client, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) + while response is not None: + yield from response.intervals + + page_token = response.next_page_token + if page_token == UNSET: + response = None + else: + response = sync( + id=id, + client=client, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) + + +async def async_depaginated( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> AsyncIterator[BatteryInterval]: + """Returns Battery interval data + + Returns individual Battery charge and discharge data aggregated to the specific granularity + requested for a specified start and end date. The energy data intervals are represented in kWh. + Intervals are always aligned with the start of a month, day, or hour. Partial period requests are + expanded to cover the full interval for the requested summary level. For example, a summary-level + request of month with a start date of 12/3 and end date of 1/1 will return data covering the entire + month of December. + + Args: + id (str): Battery id + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Iterator[BatteryInterval] + """ + + response = await asyncio( + id=id, + client=client, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) + while response is not None: + for item in response.intervals: + yield item + + page_token = response.next_page_token + if page_token == UNSET: + response = None + else: + response = await asyncio( + id=id, + client=client, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) diff --git a/derapi/api/batteries/list_batteries.py b/derapi/api/batteries/list_batteries.py new file mode 100644 index 0000000..0b4f2bb --- /dev/null +++ b/derapi/api/batteries/list_batteries.py @@ -0,0 +1,345 @@ +from http import HTTPStatus +from typing import Any, AsyncIterator, Dict, Iterator, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.battery_summary import BatterySummary +from ...models.list_batteries_response import ListBatteriesResponse +from ...models.vendor import Vendor +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + *, + vendor: Union[Unset, Vendor] = UNSET, + vendor_id: Union[Unset, str] = UNSET, + vendor_site_id: Union[Unset, str] = UNSET, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Dict[str, Any]: + params: Dict[str, Any] = {} + + json_vendor: Union[Unset, str] = UNSET + if not isinstance(vendor, Unset): + json_vendor = vendor.value + + params["vendor"] = json_vendor + + params["vendorID"] = vendor_id + + params["vendorSiteID"] = vendor_site_id + + params["pageSize"] = page_size + + params["pageToken"] = page_token + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: Dict[str, Any] = { + "method": "get", + "url": "/batteries", + "params": params, + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[ListBatteriesResponse]: + if response.status_code == 200: + response_200 = ListBatteriesResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[ListBatteriesResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: Union[AuthenticatedClient, Client], + vendor: Union[Unset, Vendor] = UNSET, + vendor_id: Union[Unset, str] = UNSET, + vendor_site_id: Union[Unset, str] = UNSET, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Response[ListBatteriesResponse]: + """Returns a list of Batteries + + Returns a list of Batteries. In the case a vendor API request encounters an error details are + provided. + + Args: + vendor (Union[Unset, Vendor]): + vendor_id (Union[Unset, str]): + vendor_site_id (Union[Unset, str]): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[ListBatteriesResponse] + """ + + kwargs = _get_kwargs( + vendor=vendor, + vendor_id=vendor_id, + vendor_site_id=vendor_site_id, + page_size=page_size, + page_token=page_token, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: Union[AuthenticatedClient, Client], + vendor: Union[Unset, Vendor] = UNSET, + vendor_id: Union[Unset, str] = UNSET, + vendor_site_id: Union[Unset, str] = UNSET, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Optional[ListBatteriesResponse]: + """Returns a list of Batteries + + Returns a list of Batteries. In the case a vendor API request encounters an error details are + provided. + + Args: + vendor (Union[Unset, Vendor]): + vendor_id (Union[Unset, str]): + vendor_site_id (Union[Unset, str]): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + ListBatteriesResponse + """ + + return sync_detailed( + client=client, + vendor=vendor, + vendor_id=vendor_id, + vendor_site_id=vendor_site_id, + page_size=page_size, + page_token=page_token, + ).parsed + + +async def asyncio_detailed( + *, + client: Union[AuthenticatedClient, Client], + vendor: Union[Unset, Vendor] = UNSET, + vendor_id: Union[Unset, str] = UNSET, + vendor_site_id: Union[Unset, str] = UNSET, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Response[ListBatteriesResponse]: + """Returns a list of Batteries + + Returns a list of Batteries. In the case a vendor API request encounters an error details are + provided. + + Args: + vendor (Union[Unset, Vendor]): + vendor_id (Union[Unset, str]): + vendor_site_id (Union[Unset, str]): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[ListBatteriesResponse] + """ + + kwargs = _get_kwargs( + vendor=vendor, + vendor_id=vendor_id, + vendor_site_id=vendor_site_id, + page_size=page_size, + page_token=page_token, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: Union[AuthenticatedClient, Client], + vendor: Union[Unset, Vendor] = UNSET, + vendor_id: Union[Unset, str] = UNSET, + vendor_site_id: Union[Unset, str] = UNSET, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Optional[ListBatteriesResponse]: + """Returns a list of Batteries + + Returns a list of Batteries. In the case a vendor API request encounters an error details are + provided. + + Args: + vendor (Union[Unset, Vendor]): + vendor_id (Union[Unset, str]): + vendor_site_id (Union[Unset, str]): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + ListBatteriesResponse + """ + + return ( + await asyncio_detailed( + client=client, + vendor=vendor, + vendor_id=vendor_id, + vendor_site_id=vendor_site_id, + page_size=page_size, + page_token=page_token, + ) + ).parsed + + +def sync_depaginated( + *, + client: Union[AuthenticatedClient, Client], + vendor: Union[Unset, Vendor] = UNSET, + vendor_id: Union[Unset, str] = UNSET, + vendor_site_id: Union[Unset, str] = UNSET, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Iterator[BatterySummary]: + """Returns a list of Batteries + + Returns a list of Batteries. In the case a vendor API request encounters an error details are + provided. + + Args: + vendor (Union[Unset, Vendor]): + vendor_id (Union[Unset, str]): + vendor_site_id (Union[Unset, str]): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Iterator[BatterySummary] + """ + + response = sync( + client=client, + vendor=vendor, + vendor_id=vendor_id, + vendor_site_id=vendor_site_id, + page_size=page_size, + page_token=page_token, + ) + while response is not None: + yield from response.batteries + + page_token = response.next_page_token + if page_token == UNSET: + response = None + else: + response = sync( + client=client, + vendor=vendor, + vendor_id=vendor_id, + vendor_site_id=vendor_site_id, + page_size=page_size, + page_token=page_token, + ) + + +async def async_depaginated( + *, + client: Union[AuthenticatedClient, Client], + vendor: Union[Unset, Vendor] = UNSET, + vendor_id: Union[Unset, str] = UNSET, + vendor_site_id: Union[Unset, str] = UNSET, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> AsyncIterator[BatterySummary]: + """Returns a list of Batteries + + Returns a list of Batteries. In the case a vendor API request encounters an error details are + provided. + + Args: + vendor (Union[Unset, Vendor]): + vendor_id (Union[Unset, str]): + vendor_site_id (Union[Unset, str]): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Iterator[BatterySummary] + """ + + response = await asyncio( + client=client, + vendor=vendor, + vendor_id=vendor_id, + vendor_site_id=vendor_site_id, + page_size=page_size, + page_token=page_token, + ) + while response is not None: + for item in response.batteries: + yield item + + page_token = response.next_page_token + if page_token == UNSET: + response = None + else: + response = await asyncio( + client=client, + vendor=vendor, + vendor_id=vendor_id, + vendor_site_id=vendor_site_id, + page_size=page_size, + page_token=page_token, + ) diff --git a/derapi/api/join/__init__.py b/derapi/api/join/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/derapi/api/join/create_join_session.py b/derapi/api/join/create_join_session.py new file mode 100644 index 0000000..5311b9f --- /dev/null +++ b/derapi/api/join/create_join_session.py @@ -0,0 +1,176 @@ +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.create_join_session_request import CreateJoinSessionRequest +from ...models.create_join_session_response import CreateJoinSessionResponse +from ...types import Response + + +def _get_kwargs( + *, + body: CreateJoinSessionRequest, +) -> Dict[str, Any]: + headers: Dict[str, Any] = {} + + _kwargs: Dict[str, Any] = { + "method": "post", + "url": "/join/session/start", + } + + _body = body.to_dict() + + _kwargs["json"] = _body + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[CreateJoinSessionResponse]: + if response.status_code == 200: + response_200 = CreateJoinSessionResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[CreateJoinSessionResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: Union[AuthenticatedClient, Client], + body: CreateJoinSessionRequest, +) -> Response[CreateJoinSessionResponse]: + """Create a Join session + + Create a Join session and retrieve a session token. Pass this token to the Join JS component + function createJoin(). Add a vendor credential object for each vendor that should appear in the Join + UI. + + Args: + body (CreateJoinSessionRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[CreateJoinSessionResponse] + """ + + kwargs = _get_kwargs( + body=body, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: Union[AuthenticatedClient, Client], + body: CreateJoinSessionRequest, +) -> Optional[CreateJoinSessionResponse]: + """Create a Join session + + Create a Join session and retrieve a session token. Pass this token to the Join JS component + function createJoin(). Add a vendor credential object for each vendor that should appear in the Join + UI. + + Args: + body (CreateJoinSessionRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + CreateJoinSessionResponse + """ + + return sync_detailed( + client=client, + body=body, + ).parsed + + +async def asyncio_detailed( + *, + client: Union[AuthenticatedClient, Client], + body: CreateJoinSessionRequest, +) -> Response[CreateJoinSessionResponse]: + """Create a Join session + + Create a Join session and retrieve a session token. Pass this token to the Join JS component + function createJoin(). Add a vendor credential object for each vendor that should appear in the Join + UI. + + Args: + body (CreateJoinSessionRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[CreateJoinSessionResponse] + """ + + kwargs = _get_kwargs( + body=body, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: Union[AuthenticatedClient, Client], + body: CreateJoinSessionRequest, +) -> Optional[CreateJoinSessionResponse]: + """Create a Join session + + Create a Join session and retrieve a session token. Pass this token to the Join JS component + function createJoin(). Add a vendor credential object for each vendor that should appear in the Join + UI. + + Args: + body (CreateJoinSessionRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + CreateJoinSessionResponse + """ + + return ( + await asyncio_detailed( + client=client, + body=body, + ) + ).parsed diff --git a/derapi/api/join/get_join_session_token.py b/derapi/api/join/get_join_session_token.py new file mode 100644 index 0000000..0d75806 --- /dev/null +++ b/derapi/api/join/get_join_session_token.py @@ -0,0 +1,158 @@ +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.get_join_session_token_response import GetJoinSessionTokenResponse +from ...types import Response + + +def _get_kwargs( + session_id: str, +) -> Dict[str, Any]: + _kwargs: Dict[str, Any] = { + "method": "get", + "url": f"/join/session/{session_id}/fetch-token", + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[GetJoinSessionTokenResponse]: + if response.status_code == 200: + response_200 = GetJoinSessionTokenResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[GetJoinSessionTokenResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + session_id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[GetJoinSessionTokenResponse]: + """Retrieve token(s) from a Join session + + Use this endpoint to retrieve the token generated by an end-customer Join authorization + + Args: + session_id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetJoinSessionTokenResponse] + """ + + kwargs = _get_kwargs( + session_id=session_id, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + session_id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Optional[GetJoinSessionTokenResponse]: + """Retrieve token(s) from a Join session + + Use this endpoint to retrieve the token generated by an end-customer Join authorization + + Args: + session_id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetJoinSessionTokenResponse + """ + + return sync_detailed( + session_id=session_id, + client=client, + ).parsed + + +async def asyncio_detailed( + session_id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[GetJoinSessionTokenResponse]: + """Retrieve token(s) from a Join session + + Use this endpoint to retrieve the token generated by an end-customer Join authorization + + Args: + session_id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetJoinSessionTokenResponse] + """ + + kwargs = _get_kwargs( + session_id=session_id, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + session_id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Optional[GetJoinSessionTokenResponse]: + """Retrieve token(s) from a Join session + + Use this endpoint to retrieve the token generated by an end-customer Join authorization + + Args: + session_id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetJoinSessionTokenResponse + """ + + return ( + await asyncio_detailed( + session_id=session_id, + client=client, + ) + ).parsed diff --git a/derapi/api/sites/__init__.py b/derapi/api/sites/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/derapi/api/sites/get_site.py b/derapi/api/sites/get_site.py new file mode 100644 index 0000000..01ae8f3 --- /dev/null +++ b/derapi/api/sites/get_site.py @@ -0,0 +1,158 @@ +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.get_site_response import GetSiteResponse +from ...types import Response + + +def _get_kwargs( + id: str, +) -> Dict[str, Any]: + _kwargs: Dict[str, Any] = { + "method": "get", + "url": f"/sites/{id}", + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[GetSiteResponse]: + if response.status_code == 200: + response_200 = GetSiteResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[GetSiteResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[GetSiteResponse]: + """Return Site details + + Returns details for a single Site including the list of devices associated with the Site. + + Args: + id (str): the ID for the Site + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetSiteResponse] + """ + + kwargs = _get_kwargs( + id=id, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Optional[GetSiteResponse]: + """Return Site details + + Returns details for a single Site including the list of devices associated with the Site. + + Args: + id (str): the ID for the Site + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetSiteResponse + """ + + return sync_detailed( + id=id, + client=client, + ).parsed + + +async def asyncio_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[GetSiteResponse]: + """Return Site details + + Returns details for a single Site including the list of devices associated with the Site. + + Args: + id (str): the ID for the Site + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetSiteResponse] + """ + + kwargs = _get_kwargs( + id=id, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Optional[GetSiteResponse]: + """Return Site details + + Returns details for a single Site including the list of devices associated with the Site. + + Args: + id (str): the ID for the Site + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetSiteResponse + """ + + return ( + await asyncio_detailed( + id=id, + client=client, + ) + ).parsed diff --git a/derapi/api/sites/get_site_battery_control.py b/derapi/api/sites/get_site_battery_control.py new file mode 100644 index 0000000..aeb35bf --- /dev/null +++ b/derapi/api/sites/get_site_battery_control.py @@ -0,0 +1,158 @@ +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.get_site_battery_control_response import GetSiteBatteryControlResponse +from ...types import Response + + +def _get_kwargs( + id: str, +) -> Dict[str, Any]: + _kwargs: Dict[str, Any] = { + "method": "get", + "url": f"/sites/{id}/battery-control", + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[GetSiteBatteryControlResponse]: + if response.status_code == 200: + response_200 = GetSiteBatteryControlResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[GetSiteBatteryControlResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[GetSiteBatteryControlResponse]: + """Returns Battery control state + + Returns Battery control state + + Args: + id (str): the ID for the Site + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetSiteBatteryControlResponse] + """ + + kwargs = _get_kwargs( + id=id, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Optional[GetSiteBatteryControlResponse]: + """Returns Battery control state + + Returns Battery control state + + Args: + id (str): the ID for the Site + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetSiteBatteryControlResponse + """ + + return sync_detailed( + id=id, + client=client, + ).parsed + + +async def asyncio_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[GetSiteBatteryControlResponse]: + """Returns Battery control state + + Returns Battery control state + + Args: + id (str): the ID for the Site + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetSiteBatteryControlResponse] + """ + + kwargs = _get_kwargs( + id=id, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Optional[GetSiteBatteryControlResponse]: + """Returns Battery control state + + Returns Battery control state + + Args: + id (str): the ID for the Site + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetSiteBatteryControlResponse + """ + + return ( + await asyncio_detailed( + id=id, + client=client, + ) + ).parsed diff --git a/derapi/api/sites/get_site_battery_intervals.py b/derapi/api/sites/get_site_battery_intervals.py new file mode 100644 index 0000000..0682e2f --- /dev/null +++ b/derapi/api/sites/get_site_battery_intervals.py @@ -0,0 +1,393 @@ +import datetime +from http import HTTPStatus +from typing import Any, AsyncIterator, Dict, Iterator, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.get_site_battery_intervals_response import GetSiteBatteryIntervalsResponse +from ...models.site_battery_interval import SiteBatteryInterval +from ...models.summary_level import SummaryLevel +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + id: str, + *, + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Dict[str, Any]: + params: Dict[str, Any] = {} + + json_summary_level: Union[Unset, str] = UNSET + if not isinstance(summary_level, Unset): + json_summary_level = summary_level.value + + params["summaryLevel"] = json_summary_level + + json_start = start.isoformat() + params["start"] = json_start + + json_end = end.isoformat() + params["end"] = json_end + + params["pageSize"] = page_size + + params["pageToken"] = page_token + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: Dict[str, Any] = { + "method": "get", + "url": f"/sites/{id}/battery-intervals", + "params": params, + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[GetSiteBatteryIntervalsResponse]: + if response.status_code == 200: + response_200 = GetSiteBatteryIntervalsResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[GetSiteBatteryIntervalsResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Response[GetSiteBatteryIntervalsResponse]: + """Returns Battery system interval data + + Returns Site-level Battery charge and discharge data aggregated to the specific granularity + requested for a specified start and end date. The energy data intervals are represented in kWh. + Intervals are always aligned with the start of a month, day, or hour. Partial period requests are + expanded to cover the full interval for the requested summary level. For example, a summary-level + request of month with a start date of 12/3 and end date of 1/1 will return data covering the entire + month of December. + + Args: + id (str): the ID for the Site + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetSiteBatteryIntervalsResponse] + """ + + kwargs = _get_kwargs( + id=id, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Optional[GetSiteBatteryIntervalsResponse]: + """Returns Battery system interval data + + Returns Site-level Battery charge and discharge data aggregated to the specific granularity + requested for a specified start and end date. The energy data intervals are represented in kWh. + Intervals are always aligned with the start of a month, day, or hour. Partial period requests are + expanded to cover the full interval for the requested summary level. For example, a summary-level + request of month with a start date of 12/3 and end date of 1/1 will return data covering the entire + month of December. + + Args: + id (str): the ID for the Site + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetSiteBatteryIntervalsResponse + """ + + return sync_detailed( + id=id, + client=client, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ).parsed + + +async def asyncio_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Response[GetSiteBatteryIntervalsResponse]: + """Returns Battery system interval data + + Returns Site-level Battery charge and discharge data aggregated to the specific granularity + requested for a specified start and end date. The energy data intervals are represented in kWh. + Intervals are always aligned with the start of a month, day, or hour. Partial period requests are + expanded to cover the full interval for the requested summary level. For example, a summary-level + request of month with a start date of 12/3 and end date of 1/1 will return data covering the entire + month of December. + + Args: + id (str): the ID for the Site + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetSiteBatteryIntervalsResponse] + """ + + kwargs = _get_kwargs( + id=id, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Optional[GetSiteBatteryIntervalsResponse]: + """Returns Battery system interval data + + Returns Site-level Battery charge and discharge data aggregated to the specific granularity + requested for a specified start and end date. The energy data intervals are represented in kWh. + Intervals are always aligned with the start of a month, day, or hour. Partial period requests are + expanded to cover the full interval for the requested summary level. For example, a summary-level + request of month with a start date of 12/3 and end date of 1/1 will return data covering the entire + month of December. + + Args: + id (str): the ID for the Site + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetSiteBatteryIntervalsResponse + """ + + return ( + await asyncio_detailed( + id=id, + client=client, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) + ).parsed + + +def sync_depaginated( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Iterator[SiteBatteryInterval]: + """Returns Battery system interval data + + Returns Site-level Battery charge and discharge data aggregated to the specific granularity + requested for a specified start and end date. The energy data intervals are represented in kWh. + Intervals are always aligned with the start of a month, day, or hour. Partial period requests are + expanded to cover the full interval for the requested summary level. For example, a summary-level + request of month with a start date of 12/3 and end date of 1/1 will return data covering the entire + month of December. + + Args: + id (str): the ID for the Site + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Iterator[SiteBatteryInterval] + """ + + response = sync( + id=id, + client=client, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) + while response is not None: + yield from response.intervals + + page_token = response.next_page_token + if page_token == UNSET: + response = None + else: + response = sync( + id=id, + client=client, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) + + +async def async_depaginated( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> AsyncIterator[SiteBatteryInterval]: + """Returns Battery system interval data + + Returns Site-level Battery charge and discharge data aggregated to the specific granularity + requested for a specified start and end date. The energy data intervals are represented in kWh. + Intervals are always aligned with the start of a month, day, or hour. Partial period requests are + expanded to cover the full interval for the requested summary level. For example, a summary-level + request of month with a start date of 12/3 and end date of 1/1 will return data covering the entire + month of December. + + Args: + id (str): the ID for the Site + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Iterator[SiteBatteryInterval] + """ + + response = await asyncio( + id=id, + client=client, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) + while response is not None: + for item in response.intervals: + yield item + + page_token = response.next_page_token + if page_token == UNSET: + response = None + else: + response = await asyncio( + id=id, + client=client, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) diff --git a/derapi/api/sites/get_site_solar_inverter_intervals.py b/derapi/api/sites/get_site_solar_inverter_intervals.py new file mode 100644 index 0000000..3c6a965 --- /dev/null +++ b/derapi/api/sites/get_site_solar_inverter_intervals.py @@ -0,0 +1,263 @@ +import datetime +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.get_site_solar_inverter_intervals_response import GetSiteSolarInverterIntervalsResponse +from ...models.summary_level import SummaryLevel +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + id: str, + *, + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Dict[str, Any]: + params: Dict[str, Any] = {} + + json_summary_level: Union[Unset, str] = UNSET + if not isinstance(summary_level, Unset): + json_summary_level = summary_level.value + + params["summaryLevel"] = json_summary_level + + json_start = start.isoformat() + params["start"] = json_start + + json_end = end.isoformat() + params["end"] = json_end + + params["pageSize"] = page_size + + params["pageToken"] = page_token + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: Dict[str, Any] = { + "method": "get", + "url": f"/sites/{id}/solar-intervals", + "params": params, + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[GetSiteSolarInverterIntervalsResponse]: + if response.status_code == 200: + response_200 = GetSiteSolarInverterIntervalsResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[GetSiteSolarInverterIntervalsResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Response[GetSiteSolarInverterIntervalsResponse]: + """Returns Site-level solar production interval data + + Returns Site-level solar production data aggregated to the specific granularity requested for a + specified start and end date. The energy data intervals are represented in kWh. Intervals are always + aligned with the start of a month, day, or hour. Partial period requests are expanded to cover the + full interval for the requested summary level. For example, a summary-level request of month with a + start date of 12/3 and end date of 1/1 will return data covering the entire month of December. + + Args: + id (str): the ID for the Site + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetSiteSolarInverterIntervalsResponse] + """ + + kwargs = _get_kwargs( + id=id, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Optional[GetSiteSolarInverterIntervalsResponse]: + """Returns Site-level solar production interval data + + Returns Site-level solar production data aggregated to the specific granularity requested for a + specified start and end date. The energy data intervals are represented in kWh. Intervals are always + aligned with the start of a month, day, or hour. Partial period requests are expanded to cover the + full interval for the requested summary level. For example, a summary-level request of month with a + start date of 12/3 and end date of 1/1 will return data covering the entire month of December. + + Args: + id (str): the ID for the Site + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetSiteSolarInverterIntervalsResponse + """ + + return sync_detailed( + id=id, + client=client, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ).parsed + + +async def asyncio_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Response[GetSiteSolarInverterIntervalsResponse]: + """Returns Site-level solar production interval data + + Returns Site-level solar production data aggregated to the specific granularity requested for a + specified start and end date. The energy data intervals are represented in kWh. Intervals are always + aligned with the start of a month, day, or hour. Partial period requests are expanded to cover the + full interval for the requested summary level. For example, a summary-level request of month with a + start date of 12/3 and end date of 1/1 will return data covering the entire month of December. + + Args: + id (str): the ID for the Site + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetSiteSolarInverterIntervalsResponse] + """ + + kwargs = _get_kwargs( + id=id, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Optional[GetSiteSolarInverterIntervalsResponse]: + """Returns Site-level solar production interval data + + Returns Site-level solar production data aggregated to the specific granularity requested for a + specified start and end date. The energy data intervals are represented in kWh. Intervals are always + aligned with the start of a month, day, or hour. Partial period requests are expanded to cover the + full interval for the requested summary level. For example, a summary-level request of month with a + start date of 12/3 and end date of 1/1 will return data covering the entire month of December. + + Args: + id (str): the ID for the Site + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetSiteSolarInverterIntervalsResponse + """ + + return ( + await asyncio_detailed( + id=id, + client=client, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) + ).parsed diff --git a/derapi/api/sites/list_sites.py b/derapi/api/sites/list_sites.py new file mode 100644 index 0000000..1f0f481 --- /dev/null +++ b/derapi/api/sites/list_sites.py @@ -0,0 +1,316 @@ +from http import HTTPStatus +from typing import Any, AsyncIterator, Dict, Iterator, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.list_sites_response import ListSitesResponse +from ...models.site_summary import SiteSummary +from ...models.vendor import Vendor +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + *, + vendor: Union[Unset, Vendor] = UNSET, + vendor_id: Union[Unset, str] = UNSET, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Dict[str, Any]: + params: Dict[str, Any] = {} + + json_vendor: Union[Unset, str] = UNSET + if not isinstance(vendor, Unset): + json_vendor = vendor.value + + params["vendor"] = json_vendor + + params["vendorID"] = vendor_id + + params["pageSize"] = page_size + + params["pageToken"] = page_token + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: Dict[str, Any] = { + "method": "get", + "url": "/sites", + "params": params, + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[ListSitesResponse]: + if response.status_code == 200: + response_200 = ListSitesResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[ListSitesResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: Union[AuthenticatedClient, Client], + vendor: Union[Unset, Vendor] = UNSET, + vendor_id: Union[Unset, str] = UNSET, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Response[ListSitesResponse]: + """Returns a list of Sites + + Returns a list of Sites. In the case a vendor API request encounters an error details are provided. + + Args: + vendor (Union[Unset, Vendor]): + vendor_id (Union[Unset, str]): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[ListSitesResponse] + """ + + kwargs = _get_kwargs( + vendor=vendor, + vendor_id=vendor_id, + page_size=page_size, + page_token=page_token, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: Union[AuthenticatedClient, Client], + vendor: Union[Unset, Vendor] = UNSET, + vendor_id: Union[Unset, str] = UNSET, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Optional[ListSitesResponse]: + """Returns a list of Sites + + Returns a list of Sites. In the case a vendor API request encounters an error details are provided. + + Args: + vendor (Union[Unset, Vendor]): + vendor_id (Union[Unset, str]): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + ListSitesResponse + """ + + return sync_detailed( + client=client, + vendor=vendor, + vendor_id=vendor_id, + page_size=page_size, + page_token=page_token, + ).parsed + + +async def asyncio_detailed( + *, + client: Union[AuthenticatedClient, Client], + vendor: Union[Unset, Vendor] = UNSET, + vendor_id: Union[Unset, str] = UNSET, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Response[ListSitesResponse]: + """Returns a list of Sites + + Returns a list of Sites. In the case a vendor API request encounters an error details are provided. + + Args: + vendor (Union[Unset, Vendor]): + vendor_id (Union[Unset, str]): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[ListSitesResponse] + """ + + kwargs = _get_kwargs( + vendor=vendor, + vendor_id=vendor_id, + page_size=page_size, + page_token=page_token, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: Union[AuthenticatedClient, Client], + vendor: Union[Unset, Vendor] = UNSET, + vendor_id: Union[Unset, str] = UNSET, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Optional[ListSitesResponse]: + """Returns a list of Sites + + Returns a list of Sites. In the case a vendor API request encounters an error details are provided. + + Args: + vendor (Union[Unset, Vendor]): + vendor_id (Union[Unset, str]): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + ListSitesResponse + """ + + return ( + await asyncio_detailed( + client=client, + vendor=vendor, + vendor_id=vendor_id, + page_size=page_size, + page_token=page_token, + ) + ).parsed + + +def sync_depaginated( + *, + client: Union[AuthenticatedClient, Client], + vendor: Union[Unset, Vendor] = UNSET, + vendor_id: Union[Unset, str] = UNSET, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Iterator[SiteSummary]: + """Returns a list of Sites + + Returns a list of Sites. In the case a vendor API request encounters an error details are provided. + + Args: + vendor (Union[Unset, Vendor]): + vendor_id (Union[Unset, str]): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Iterator[SiteSummary] + """ + + response = sync( + client=client, + vendor=vendor, + vendor_id=vendor_id, + page_size=page_size, + page_token=page_token, + ) + while response is not None: + yield from response.sites + + page_token = response.next_page_token + if page_token == UNSET: + response = None + else: + response = sync( + client=client, + vendor=vendor, + vendor_id=vendor_id, + page_size=page_size, + page_token=page_token, + ) + + +async def async_depaginated( + *, + client: Union[AuthenticatedClient, Client], + vendor: Union[Unset, Vendor] = UNSET, + vendor_id: Union[Unset, str] = UNSET, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> AsyncIterator[SiteSummary]: + """Returns a list of Sites + + Returns a list of Sites. In the case a vendor API request encounters an error details are provided. + + Args: + vendor (Union[Unset, Vendor]): + vendor_id (Union[Unset, str]): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Iterator[SiteSummary] + """ + + response = await asyncio( + client=client, + vendor=vendor, + vendor_id=vendor_id, + page_size=page_size, + page_token=page_token, + ) + while response is not None: + for item in response.sites: + yield item + + page_token = response.next_page_token + if page_token == UNSET: + response = None + else: + response = await asyncio( + client=client, + vendor=vendor, + vendor_id=vendor_id, + page_size=page_size, + page_token=page_token, + ) diff --git a/derapi/api/sites/put_site_battery_control.py b/derapi/api/sites/put_site_battery_control.py new file mode 100644 index 0000000..f220b25 --- /dev/null +++ b/derapi/api/sites/put_site_battery_control.py @@ -0,0 +1,205 @@ +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.put_site_battery_control_request import PutSiteBatteryControlRequest +from ...models.put_site_battery_control_response import PutSiteBatteryControlResponse +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + id: str, + *, + body: PutSiteBatteryControlRequest, + program_id: Union[Unset, str] = UNSET, +) -> Dict[str, Any]: + headers: Dict[str, Any] = {} + + params: Dict[str, Any] = {} + + params["programID"] = program_id + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: Dict[str, Any] = { + "method": "put", + "url": f"/sites/{id}/battery-control", + "params": params, + } + + _body = body.to_dict() + + _kwargs["json"] = _body + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[PutSiteBatteryControlResponse]: + if response.status_code == 200: + response_200 = PutSiteBatteryControlResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[PutSiteBatteryControlResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], + body: PutSiteBatteryControlRequest, + program_id: Union[Unset, str] = UNSET, +) -> Response[PutSiteBatteryControlResponse]: + """Accepts Battery control signals for an individual Site + + Accepts Battery control signals for individual Sites and translates those to vendor control + commands. + + Args: + id (str): the ID for the Site + program_id (Union[Unset, str]): + body (PutSiteBatteryControlRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[PutSiteBatteryControlResponse] + """ + + kwargs = _get_kwargs( + id=id, + body=body, + program_id=program_id, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + id: str, + *, + client: Union[AuthenticatedClient, Client], + body: PutSiteBatteryControlRequest, + program_id: Union[Unset, str] = UNSET, +) -> Optional[PutSiteBatteryControlResponse]: + """Accepts Battery control signals for an individual Site + + Accepts Battery control signals for individual Sites and translates those to vendor control + commands. + + Args: + id (str): the ID for the Site + program_id (Union[Unset, str]): + body (PutSiteBatteryControlRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + PutSiteBatteryControlResponse + """ + + return sync_detailed( + id=id, + client=client, + body=body, + program_id=program_id, + ).parsed + + +async def asyncio_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], + body: PutSiteBatteryControlRequest, + program_id: Union[Unset, str] = UNSET, +) -> Response[PutSiteBatteryControlResponse]: + """Accepts Battery control signals for an individual Site + + Accepts Battery control signals for individual Sites and translates those to vendor control + commands. + + Args: + id (str): the ID for the Site + program_id (Union[Unset, str]): + body (PutSiteBatteryControlRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[PutSiteBatteryControlResponse] + """ + + kwargs = _get_kwargs( + id=id, + body=body, + program_id=program_id, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + id: str, + *, + client: Union[AuthenticatedClient, Client], + body: PutSiteBatteryControlRequest, + program_id: Union[Unset, str] = UNSET, +) -> Optional[PutSiteBatteryControlResponse]: + """Accepts Battery control signals for an individual Site + + Accepts Battery control signals for individual Sites and translates those to vendor control + commands. + + Args: + id (str): the ID for the Site + program_id (Union[Unset, str]): + body (PutSiteBatteryControlRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + PutSiteBatteryControlResponse + """ + + return ( + await asyncio_detailed( + id=id, + client=client, + body=body, + program_id=program_id, + ) + ).parsed diff --git a/derapi/api/solar_inverters/__init__.py b/derapi/api/solar_inverters/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/derapi/api/solar_inverters/get_solar_inverter.py b/derapi/api/solar_inverters/get_solar_inverter.py new file mode 100644 index 0000000..27697f3 --- /dev/null +++ b/derapi/api/solar_inverters/get_solar_inverter.py @@ -0,0 +1,158 @@ +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.get_solar_inverter_response import GetSolarInverterResponse +from ...types import Response + + +def _get_kwargs( + id: str, +) -> Dict[str, Any]: + _kwargs: Dict[str, Any] = { + "method": "get", + "url": f"/solar-inverters/{id}", + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[GetSolarInverterResponse]: + if response.status_code == 200: + response_200 = GetSolarInverterResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[GetSolarInverterResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[GetSolarInverterResponse]: + """Returns Solar Inverter details + + Returns details for a single Solar Inverter + + Args: + id (str): ID of the solar inverter + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetSolarInverterResponse] + """ + + kwargs = _get_kwargs( + id=id, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Optional[GetSolarInverterResponse]: + """Returns Solar Inverter details + + Returns details for a single Solar Inverter + + Args: + id (str): ID of the solar inverter + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetSolarInverterResponse + """ + + return sync_detailed( + id=id, + client=client, + ).parsed + + +async def asyncio_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[GetSolarInverterResponse]: + """Returns Solar Inverter details + + Returns details for a single Solar Inverter + + Args: + id (str): ID of the solar inverter + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetSolarInverterResponse] + """ + + kwargs = _get_kwargs( + id=id, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Optional[GetSolarInverterResponse]: + """Returns Solar Inverter details + + Returns details for a single Solar Inverter + + Args: + id (str): ID of the solar inverter + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetSolarInverterResponse + """ + + return ( + await asyncio_detailed( + id=id, + client=client, + ) + ).parsed diff --git a/derapi/api/solar_inverters/get_solar_inverter_intervals.py b/derapi/api/solar_inverters/get_solar_inverter_intervals.py new file mode 100644 index 0000000..dd19434 --- /dev/null +++ b/derapi/api/solar_inverters/get_solar_inverter_intervals.py @@ -0,0 +1,387 @@ +import datetime +from http import HTTPStatus +from typing import Any, AsyncIterator, Dict, Iterator, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.get_solar_inverter_intervals_response import GetSolarInverterIntervalsResponse +from ...models.solar_inverter_interval import SolarInverterInterval +from ...models.summary_level import SummaryLevel +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + id: str, + *, + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Dict[str, Any]: + params: Dict[str, Any] = {} + + json_summary_level: Union[Unset, str] = UNSET + if not isinstance(summary_level, Unset): + json_summary_level = summary_level.value + + params["summaryLevel"] = json_summary_level + + json_start = start.isoformat() + params["start"] = json_start + + json_end = end.isoformat() + params["end"] = json_end + + params["pageSize"] = page_size + + params["pageToken"] = page_token + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: Dict[str, Any] = { + "method": "get", + "url": f"/solar-inverters/{id}/intervals", + "params": params, + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[GetSolarInverterIntervalsResponse]: + if response.status_code == 200: + response_200 = GetSolarInverterIntervalsResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[GetSolarInverterIntervalsResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Response[GetSolarInverterIntervalsResponse]: + """Returns solar production data + + Returns solar production data aggregated to the specific granularity requested for a specified start + and end date. The energy data intervals are represented in kWh. Intervals are always aligned with + the start of a month, day, or hour. Partial period requests are expanded to cover the full interval + for the requested summary level. For example, a summary-level request of month with a start date of + 12/3 and end date of 1/1 will return data covering the entire month of December. + + Args: + id (str): ID of the solar inverter + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetSolarInverterIntervalsResponse] + """ + + kwargs = _get_kwargs( + id=id, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Optional[GetSolarInverterIntervalsResponse]: + """Returns solar production data + + Returns solar production data aggregated to the specific granularity requested for a specified start + and end date. The energy data intervals are represented in kWh. Intervals are always aligned with + the start of a month, day, or hour. Partial period requests are expanded to cover the full interval + for the requested summary level. For example, a summary-level request of month with a start date of + 12/3 and end date of 1/1 will return data covering the entire month of December. + + Args: + id (str): ID of the solar inverter + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetSolarInverterIntervalsResponse + """ + + return sync_detailed( + id=id, + client=client, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ).parsed + + +async def asyncio_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Response[GetSolarInverterIntervalsResponse]: + """Returns solar production data + + Returns solar production data aggregated to the specific granularity requested for a specified start + and end date. The energy data intervals are represented in kWh. Intervals are always aligned with + the start of a month, day, or hour. Partial period requests are expanded to cover the full interval + for the requested summary level. For example, a summary-level request of month with a start date of + 12/3 and end date of 1/1 will return data covering the entire month of December. + + Args: + id (str): ID of the solar inverter + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetSolarInverterIntervalsResponse] + """ + + kwargs = _get_kwargs( + id=id, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Optional[GetSolarInverterIntervalsResponse]: + """Returns solar production data + + Returns solar production data aggregated to the specific granularity requested for a specified start + and end date. The energy data intervals are represented in kWh. Intervals are always aligned with + the start of a month, day, or hour. Partial period requests are expanded to cover the full interval + for the requested summary level. For example, a summary-level request of month with a start date of + 12/3 and end date of 1/1 will return data covering the entire month of December. + + Args: + id (str): ID of the solar inverter + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetSolarInverterIntervalsResponse + """ + + return ( + await asyncio_detailed( + id=id, + client=client, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) + ).parsed + + +def sync_depaginated( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Iterator[SolarInverterInterval]: + """Returns solar production data + + Returns solar production data aggregated to the specific granularity requested for a specified start + and end date. The energy data intervals are represented in kWh. Intervals are always aligned with + the start of a month, day, or hour. Partial period requests are expanded to cover the full interval + for the requested summary level. For example, a summary-level request of month with a start date of + 12/3 and end date of 1/1 will return data covering the entire month of December. + + Args: + id (str): ID of the solar inverter + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Iterator[SolarInverterInterval] + """ + + response = sync( + id=id, + client=client, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) + while response is not None: + yield from response.intervals + + page_token = response.next_page_token + if page_token == UNSET: + response = None + else: + response = sync( + id=id, + client=client, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) + + +async def async_depaginated( + id: str, + *, + client: Union[AuthenticatedClient, Client], + summary_level: Union[Unset, SummaryLevel] = UNSET, + start: datetime.datetime, + end: datetime.datetime, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> AsyncIterator[SolarInverterInterval]: + """Returns solar production data + + Returns solar production data aggregated to the specific granularity requested for a specified start + and end date. The energy data intervals are represented in kWh. Intervals are always aligned with + the start of a month, day, or hour. Partial period requests are expanded to cover the full interval + for the requested summary level. For example, a summary-level request of month with a start date of + 12/3 and end date of 1/1 will return data covering the entire month of December. + + Args: + id (str): ID of the solar inverter + summary_level (Union[Unset, SummaryLevel]): + start (datetime.datetime): + end (datetime.datetime): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Iterator[SolarInverterInterval] + """ + + response = await asyncio( + id=id, + client=client, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) + while response is not None: + for item in response.intervals: + yield item + + page_token = response.next_page_token + if page_token == UNSET: + response = None + else: + response = await asyncio( + id=id, + client=client, + summary_level=summary_level, + start=start, + end=end, + page_size=page_size, + page_token=page_token, + ) diff --git a/derapi/api/solar_inverters/list_solar_inverters.py b/derapi/api/solar_inverters/list_solar_inverters.py new file mode 100644 index 0000000..ba1e26f --- /dev/null +++ b/derapi/api/solar_inverters/list_solar_inverters.py @@ -0,0 +1,345 @@ +from http import HTTPStatus +from typing import Any, AsyncIterator, Dict, Iterator, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.list_solar_inverters_response import ListSolarInvertersResponse +from ...models.solar_inverter_summary import SolarInverterSummary +from ...models.vendor import Vendor +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + *, + vendor: Union[Unset, Vendor] = UNSET, + vendor_site_id: Union[Unset, str] = UNSET, + vendor_id: Union[Unset, str] = UNSET, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Dict[str, Any]: + params: Dict[str, Any] = {} + + json_vendor: Union[Unset, str] = UNSET + if not isinstance(vendor, Unset): + json_vendor = vendor.value + + params["vendor"] = json_vendor + + params["vendorSiteID"] = vendor_site_id + + params["vendorID"] = vendor_id + + params["pageSize"] = page_size + + params["pageToken"] = page_token + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: Dict[str, Any] = { + "method": "get", + "url": "/solar-inverters", + "params": params, + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[ListSolarInvertersResponse]: + if response.status_code == 200: + response_200 = ListSolarInvertersResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[ListSolarInvertersResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: Union[AuthenticatedClient, Client], + vendor: Union[Unset, Vendor] = UNSET, + vendor_site_id: Union[Unset, str] = UNSET, + vendor_id: Union[Unset, str] = UNSET, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Response[ListSolarInvertersResponse]: + """Returns a list of Solar Inverters + + Returns a list of Solar Inverters. In the case a vendor API request encounters an erorr details are + provided. + + Args: + vendor (Union[Unset, Vendor]): + vendor_site_id (Union[Unset, str]): + vendor_id (Union[Unset, str]): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[ListSolarInvertersResponse] + """ + + kwargs = _get_kwargs( + vendor=vendor, + vendor_site_id=vendor_site_id, + vendor_id=vendor_id, + page_size=page_size, + page_token=page_token, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: Union[AuthenticatedClient, Client], + vendor: Union[Unset, Vendor] = UNSET, + vendor_site_id: Union[Unset, str] = UNSET, + vendor_id: Union[Unset, str] = UNSET, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Optional[ListSolarInvertersResponse]: + """Returns a list of Solar Inverters + + Returns a list of Solar Inverters. In the case a vendor API request encounters an erorr details are + provided. + + Args: + vendor (Union[Unset, Vendor]): + vendor_site_id (Union[Unset, str]): + vendor_id (Union[Unset, str]): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + ListSolarInvertersResponse + """ + + return sync_detailed( + client=client, + vendor=vendor, + vendor_site_id=vendor_site_id, + vendor_id=vendor_id, + page_size=page_size, + page_token=page_token, + ).parsed + + +async def asyncio_detailed( + *, + client: Union[AuthenticatedClient, Client], + vendor: Union[Unset, Vendor] = UNSET, + vendor_site_id: Union[Unset, str] = UNSET, + vendor_id: Union[Unset, str] = UNSET, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Response[ListSolarInvertersResponse]: + """Returns a list of Solar Inverters + + Returns a list of Solar Inverters. In the case a vendor API request encounters an erorr details are + provided. + + Args: + vendor (Union[Unset, Vendor]): + vendor_site_id (Union[Unset, str]): + vendor_id (Union[Unset, str]): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[ListSolarInvertersResponse] + """ + + kwargs = _get_kwargs( + vendor=vendor, + vendor_site_id=vendor_site_id, + vendor_id=vendor_id, + page_size=page_size, + page_token=page_token, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: Union[AuthenticatedClient, Client], + vendor: Union[Unset, Vendor] = UNSET, + vendor_site_id: Union[Unset, str] = UNSET, + vendor_id: Union[Unset, str] = UNSET, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Optional[ListSolarInvertersResponse]: + """Returns a list of Solar Inverters + + Returns a list of Solar Inverters. In the case a vendor API request encounters an erorr details are + provided. + + Args: + vendor (Union[Unset, Vendor]): + vendor_site_id (Union[Unset, str]): + vendor_id (Union[Unset, str]): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + ListSolarInvertersResponse + """ + + return ( + await asyncio_detailed( + client=client, + vendor=vendor, + vendor_site_id=vendor_site_id, + vendor_id=vendor_id, + page_size=page_size, + page_token=page_token, + ) + ).parsed + + +def sync_depaginated( + *, + client: Union[AuthenticatedClient, Client], + vendor: Union[Unset, Vendor] = UNSET, + vendor_site_id: Union[Unset, str] = UNSET, + vendor_id: Union[Unset, str] = UNSET, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Iterator[SolarInverterSummary]: + """Returns a list of Solar Inverters + + Returns a list of Solar Inverters. In the case a vendor API request encounters an erorr details are + provided. + + Args: + vendor (Union[Unset, Vendor]): + vendor_site_id (Union[Unset, str]): + vendor_id (Union[Unset, str]): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Iterator[SolarInverterSummary] + """ + + response = sync( + client=client, + vendor=vendor, + vendor_site_id=vendor_site_id, + vendor_id=vendor_id, + page_size=page_size, + page_token=page_token, + ) + while response is not None: + yield from response.solar_inverters + + page_token = response.next_page_token + if page_token == UNSET: + response = None + else: + response = sync( + client=client, + vendor=vendor, + vendor_site_id=vendor_site_id, + vendor_id=vendor_id, + page_size=page_size, + page_token=page_token, + ) + + +async def async_depaginated( + *, + client: Union[AuthenticatedClient, Client], + vendor: Union[Unset, Vendor] = UNSET, + vendor_site_id: Union[Unset, str] = UNSET, + vendor_id: Union[Unset, str] = UNSET, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> AsyncIterator[SolarInverterSummary]: + """Returns a list of Solar Inverters + + Returns a list of Solar Inverters. In the case a vendor API request encounters an erorr details are + provided. + + Args: + vendor (Union[Unset, Vendor]): + vendor_site_id (Union[Unset, str]): + vendor_id (Union[Unset, str]): + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Iterator[SolarInverterSummary] + """ + + response = await asyncio( + client=client, + vendor=vendor, + vendor_site_id=vendor_site_id, + vendor_id=vendor_id, + page_size=page_size, + page_token=page_token, + ) + while response is not None: + for item in response.solar_inverters: + yield item + + page_token = response.next_page_token + if page_token == UNSET: + response = None + else: + response = await asyncio( + client=client, + vendor=vendor, + vendor_site_id=vendor_site_id, + vendor_id=vendor_id, + page_size=page_size, + page_token=page_token, + ) diff --git a/derapi/api/vendor_credentials/__init__.py b/derapi/api/vendor_credentials/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/derapi/api/vendor_credentials/create_vendor_credentials.py b/derapi/api/vendor_credentials/create_vendor_credentials.py new file mode 100644 index 0000000..a9fb378 --- /dev/null +++ b/derapi/api/vendor_credentials/create_vendor_credentials.py @@ -0,0 +1,188 @@ +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.create_vendor_credentials_request import CreateVendorCredentialsRequest +from ...models.create_vendor_credentials_response import CreateVendorCredentialsResponse +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + *, + body: CreateVendorCredentialsRequest, + include_secrets: Union[Unset, bool] = False, +) -> Dict[str, Any]: + headers: Dict[str, Any] = {} + + params: Dict[str, Any] = {} + + params["includeSecrets"] = include_secrets + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: Dict[str, Any] = { + "method": "post", + "url": "/vendor-credentials", + "params": params, + } + + _body = body.to_dict() + + _kwargs["json"] = _body + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[CreateVendorCredentialsResponse]: + if response.status_code == 201: + response_201 = CreateVendorCredentialsResponse.from_dict(response.json()) + + return response_201 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[CreateVendorCredentialsResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: Union[AuthenticatedClient, Client], + body: CreateVendorCredentialsRequest, + include_secrets: Union[Unset, bool] = False, +) -> Response[CreateVendorCredentialsResponse]: + """Stores vendor credentials + + Stores vendor credentials as specified. + + Args: + include_secrets (Union[Unset, bool]): Default: False. + body (CreateVendorCredentialsRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[CreateVendorCredentialsResponse] + """ + + kwargs = _get_kwargs( + body=body, + include_secrets=include_secrets, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: Union[AuthenticatedClient, Client], + body: CreateVendorCredentialsRequest, + include_secrets: Union[Unset, bool] = False, +) -> Optional[CreateVendorCredentialsResponse]: + """Stores vendor credentials + + Stores vendor credentials as specified. + + Args: + include_secrets (Union[Unset, bool]): Default: False. + body (CreateVendorCredentialsRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + CreateVendorCredentialsResponse + """ + + return sync_detailed( + client=client, + body=body, + include_secrets=include_secrets, + ).parsed + + +async def asyncio_detailed( + *, + client: Union[AuthenticatedClient, Client], + body: CreateVendorCredentialsRequest, + include_secrets: Union[Unset, bool] = False, +) -> Response[CreateVendorCredentialsResponse]: + """Stores vendor credentials + + Stores vendor credentials as specified. + + Args: + include_secrets (Union[Unset, bool]): Default: False. + body (CreateVendorCredentialsRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[CreateVendorCredentialsResponse] + """ + + kwargs = _get_kwargs( + body=body, + include_secrets=include_secrets, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: Union[AuthenticatedClient, Client], + body: CreateVendorCredentialsRequest, + include_secrets: Union[Unset, bool] = False, +) -> Optional[CreateVendorCredentialsResponse]: + """Stores vendor credentials + + Stores vendor credentials as specified. + + Args: + include_secrets (Union[Unset, bool]): Default: False. + body (CreateVendorCredentialsRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + CreateVendorCredentialsResponse + """ + + return ( + await asyncio_detailed( + client=client, + body=body, + include_secrets=include_secrets, + ) + ).parsed diff --git a/derapi/api/vendor_credentials/delete_vendor_credentials.py b/derapi/api/vendor_credentials/delete_vendor_credentials.py new file mode 100644 index 0000000..5a7327b --- /dev/null +++ b/derapi/api/vendor_credentials/delete_vendor_credentials.py @@ -0,0 +1,112 @@ +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + id: str, + *, + include_secrets: Union[Unset, bool] = False, +) -> Dict[str, Any]: + params: Dict[str, Any] = {} + + params["includeSecrets"] = include_secrets + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: Dict[str, Any] = { + "method": "delete", + "url": f"/vendor-credentials/{id}", + "params": params, + } + + return _kwargs + + +def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[Any]: + if response.status_code == 204: + return None + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[Any]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], + include_secrets: Union[Unset, bool] = False, +) -> Response[Any]: + """Delete stored vendor credentials + + Deletes the stored vendor credentials with this ID + + Args: + id (str): ID for the vendor credentials + include_secrets (Union[Unset, bool]): Default: False. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Any] + """ + + kwargs = _get_kwargs( + id=id, + include_secrets=include_secrets, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +async def asyncio_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], + include_secrets: Union[Unset, bool] = False, +) -> Response[Any]: + """Delete stored vendor credentials + + Deletes the stored vendor credentials with this ID + + Args: + id (str): ID for the vendor credentials + include_secrets (Union[Unset, bool]): Default: False. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Any] + """ + + kwargs = _get_kwargs( + id=id, + include_secrets=include_secrets, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) diff --git a/derapi/api/vendor_credentials/get_vendor_credentials.py b/derapi/api/vendor_credentials/get_vendor_credentials.py new file mode 100644 index 0000000..b8fd246 --- /dev/null +++ b/derapi/api/vendor_credentials/get_vendor_credentials.py @@ -0,0 +1,179 @@ +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.get_vendor_credentials_response import GetVendorCredentialsResponse +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + id: str, + *, + include_secrets: Union[Unset, bool] = False, +) -> Dict[str, Any]: + params: Dict[str, Any] = {} + + params["includeSecrets"] = include_secrets + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: Dict[str, Any] = { + "method": "get", + "url": f"/vendor-credentials/{id}", + "params": params, + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[GetVendorCredentialsResponse]: + if response.status_code == 200: + response_200 = GetVendorCredentialsResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[GetVendorCredentialsResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], + include_secrets: Union[Unset, bool] = False, +) -> Response[GetVendorCredentialsResponse]: + """Fetches specified credentials + + Fetches the Derapi managed credentials for the specified vendor and name + + Args: + id (str): ID for the vendor credentials + include_secrets (Union[Unset, bool]): Default: False. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetVendorCredentialsResponse] + """ + + kwargs = _get_kwargs( + id=id, + include_secrets=include_secrets, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + id: str, + *, + client: Union[AuthenticatedClient, Client], + include_secrets: Union[Unset, bool] = False, +) -> Optional[GetVendorCredentialsResponse]: + """Fetches specified credentials + + Fetches the Derapi managed credentials for the specified vendor and name + + Args: + id (str): ID for the vendor credentials + include_secrets (Union[Unset, bool]): Default: False. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetVendorCredentialsResponse + """ + + return sync_detailed( + id=id, + client=client, + include_secrets=include_secrets, + ).parsed + + +async def asyncio_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], + include_secrets: Union[Unset, bool] = False, +) -> Response[GetVendorCredentialsResponse]: + """Fetches specified credentials + + Fetches the Derapi managed credentials for the specified vendor and name + + Args: + id (str): ID for the vendor credentials + include_secrets (Union[Unset, bool]): Default: False. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetVendorCredentialsResponse] + """ + + kwargs = _get_kwargs( + id=id, + include_secrets=include_secrets, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + id: str, + *, + client: Union[AuthenticatedClient, Client], + include_secrets: Union[Unset, bool] = False, +) -> Optional[GetVendorCredentialsResponse]: + """Fetches specified credentials + + Fetches the Derapi managed credentials for the specified vendor and name + + Args: + id (str): ID for the vendor credentials + include_secrets (Union[Unset, bool]): Default: False. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetVendorCredentialsResponse + """ + + return ( + await asyncio_detailed( + id=id, + client=client, + include_secrets=include_secrets, + ) + ).parsed diff --git a/derapi/api/vendor_credentials/list_vendor_credentials.py b/derapi/api/vendor_credentials/list_vendor_credentials.py new file mode 100644 index 0000000..2c197a2 --- /dev/null +++ b/derapi/api/vendor_credentials/list_vendor_credentials.py @@ -0,0 +1,339 @@ +from http import HTTPStatus +from typing import Any, AsyncIterator, Dict, Iterator, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.list_vendor_credentials_response import ListVendorCredentialsResponse +from ...models.vendor import Vendor +from ...models.vendor_credentials import VendorCredentials +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + *, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, + vendor: Union[Unset, Vendor] = UNSET, + name: Union[Unset, str] = UNSET, + include_secrets: Union[Unset, bool] = False, +) -> Dict[str, Any]: + params: Dict[str, Any] = {} + + params["pageSize"] = page_size + + params["pageToken"] = page_token + + json_vendor: Union[Unset, str] = UNSET + if not isinstance(vendor, Unset): + json_vendor = vendor.value + + params["vendor"] = json_vendor + + params["name"] = name + + params["includeSecrets"] = include_secrets + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: Dict[str, Any] = { + "method": "get", + "url": "/vendor-credentials", + "params": params, + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[ListVendorCredentialsResponse]: + if response.status_code == 200: + response_200 = ListVendorCredentialsResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[ListVendorCredentialsResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, + vendor: Union[Unset, Vendor] = UNSET, + name: Union[Unset, str] = UNSET, + include_secrets: Union[Unset, bool] = False, +) -> Response[ListVendorCredentialsResponse]: + """Lists stored vendor credentials + + Lists stored vendor credentials, paginated and optionally filtered. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + vendor (Union[Unset, Vendor]): + name (Union[Unset, str]): + include_secrets (Union[Unset, bool]): Default: False. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[ListVendorCredentialsResponse] + """ + + kwargs = _get_kwargs( + page_size=page_size, + page_token=page_token, + vendor=vendor, + name=name, + include_secrets=include_secrets, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, + vendor: Union[Unset, Vendor] = UNSET, + name: Union[Unset, str] = UNSET, + include_secrets: Union[Unset, bool] = False, +) -> Optional[ListVendorCredentialsResponse]: + """Lists stored vendor credentials + + Lists stored vendor credentials, paginated and optionally filtered. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + vendor (Union[Unset, Vendor]): + name (Union[Unset, str]): + include_secrets (Union[Unset, bool]): Default: False. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + ListVendorCredentialsResponse + """ + + return sync_detailed( + client=client, + page_size=page_size, + page_token=page_token, + vendor=vendor, + name=name, + include_secrets=include_secrets, + ).parsed + + +async def asyncio_detailed( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, + vendor: Union[Unset, Vendor] = UNSET, + name: Union[Unset, str] = UNSET, + include_secrets: Union[Unset, bool] = False, +) -> Response[ListVendorCredentialsResponse]: + """Lists stored vendor credentials + + Lists stored vendor credentials, paginated and optionally filtered. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + vendor (Union[Unset, Vendor]): + name (Union[Unset, str]): + include_secrets (Union[Unset, bool]): Default: False. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[ListVendorCredentialsResponse] + """ + + kwargs = _get_kwargs( + page_size=page_size, + page_token=page_token, + vendor=vendor, + name=name, + include_secrets=include_secrets, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, + vendor: Union[Unset, Vendor] = UNSET, + name: Union[Unset, str] = UNSET, + include_secrets: Union[Unset, bool] = False, +) -> Optional[ListVendorCredentialsResponse]: + """Lists stored vendor credentials + + Lists stored vendor credentials, paginated and optionally filtered. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + vendor (Union[Unset, Vendor]): + name (Union[Unset, str]): + include_secrets (Union[Unset, bool]): Default: False. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + ListVendorCredentialsResponse + """ + + return ( + await asyncio_detailed( + client=client, + page_size=page_size, + page_token=page_token, + vendor=vendor, + name=name, + include_secrets=include_secrets, + ) + ).parsed + + +def sync_depaginated( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, + vendor: Union[Unset, Vendor] = UNSET, + name: Union[Unset, str] = UNSET, + include_secrets: Union[Unset, bool] = False, +) -> Iterator[VendorCredentials]: + """Lists stored vendor credentials + + Lists stored vendor credentials, paginated and optionally filtered. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + vendor (Union[Unset, Vendor]): + name (Union[Unset, str]): + include_secrets (Union[Unset, bool]): Default: False. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Iterator[VendorCredentials] + """ + + response = sync( + client=client, + page_size=page_size, + page_token=page_token, + vendor=vendor, + name=name, + include_secrets=include_secrets, + ) + while response is not None: + yield from response.vendor_credentials + + page_token = response.next_page_token + if page_token == UNSET: + response = None + else: + response = sync( + client=client, + page_size=page_size, + page_token=page_token, + vendor=vendor, + name=name, + include_secrets=include_secrets, + ) + + +async def async_depaginated( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, + vendor: Union[Unset, Vendor] = UNSET, + name: Union[Unset, str] = UNSET, + include_secrets: Union[Unset, bool] = False, +) -> AsyncIterator[VendorCredentials]: + """Lists stored vendor credentials + + Lists stored vendor credentials, paginated and optionally filtered. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + vendor (Union[Unset, Vendor]): + name (Union[Unset, str]): + include_secrets (Union[Unset, bool]): Default: False. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Iterator[VendorCredentials] + """ + + response = await asyncio( + client=client, + page_size=page_size, + page_token=page_token, + vendor=vendor, + name=name, + include_secrets=include_secrets, + ) + while response is not None: + for item in response.vendor_credentials: + yield item + + page_token = response.next_page_token + if page_token == UNSET: + response = None + else: + response = await asyncio( + client=client, + page_size=page_size, + page_token=page_token, + vendor=vendor, + name=name, + include_secrets=include_secrets, + ) diff --git a/derapi/api/vendor_credentials/update_vendor_credentials.py b/derapi/api/vendor_credentials/update_vendor_credentials.py new file mode 100644 index 0000000..b2842d5 --- /dev/null +++ b/derapi/api/vendor_credentials/update_vendor_credentials.py @@ -0,0 +1,234 @@ +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.update_vendor_credentials_request import UpdateVendorCredentialsRequest +from ...models.update_vendor_credentials_response import UpdateVendorCredentialsResponse +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + id: str, + *, + body: Union[ + UpdateVendorCredentialsRequest, + UpdateVendorCredentialsRequest, + ], + include_secrets: Union[Unset, bool] = False, +) -> Dict[str, Any]: + headers: Dict[str, Any] = {} + + params: Dict[str, Any] = {} + + params["includeSecrets"] = include_secrets + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: Dict[str, Any] = { + "method": "patch", + "url": f"/vendor-credentials/{id}", + "params": params, + } + + if isinstance(body, UpdateVendorCredentialsRequest): + _json_body = body.to_dict() + + _kwargs["json"] = _json_body + headers["Content-Type"] = "application/merge-patch+json" + if isinstance(body, UpdateVendorCredentialsRequest): + _json_body = body.to_dict() + + _kwargs["json"] = _json_body + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[UpdateVendorCredentialsResponse]: + if response.status_code == 200: + response_200 = UpdateVendorCredentialsResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[UpdateVendorCredentialsResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], + body: Union[ + UpdateVendorCredentialsRequest, + UpdateVendorCredentialsRequest, + ], + include_secrets: Union[Unset, bool] = False, +) -> Response[UpdateVendorCredentialsResponse]: + """Updates the stored credentials + + Updates the stored credentials with the given ID. The request body will be interpreted as a [JSON + Merge Patch](https://datatracker.ietf.org/doc/html/rfc7396) against the stored credentials. Note + that updating the 'vendor' or 'type' fields is not supported. + + Args: + id (str): ID for the vendor credentials + include_secrets (Union[Unset, bool]): Default: False. + body (UpdateVendorCredentialsRequest): + body (UpdateVendorCredentialsRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[UpdateVendorCredentialsResponse] + """ + + kwargs = _get_kwargs( + id=id, + body=body, + include_secrets=include_secrets, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + id: str, + *, + client: Union[AuthenticatedClient, Client], + body: Union[ + UpdateVendorCredentialsRequest, + UpdateVendorCredentialsRequest, + ], + include_secrets: Union[Unset, bool] = False, +) -> Optional[UpdateVendorCredentialsResponse]: + """Updates the stored credentials + + Updates the stored credentials with the given ID. The request body will be interpreted as a [JSON + Merge Patch](https://datatracker.ietf.org/doc/html/rfc7396) against the stored credentials. Note + that updating the 'vendor' or 'type' fields is not supported. + + Args: + id (str): ID for the vendor credentials + include_secrets (Union[Unset, bool]): Default: False. + body (UpdateVendorCredentialsRequest): + body (UpdateVendorCredentialsRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + UpdateVendorCredentialsResponse + """ + + return sync_detailed( + id=id, + client=client, + body=body, + include_secrets=include_secrets, + ).parsed + + +async def asyncio_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], + body: Union[ + UpdateVendorCredentialsRequest, + UpdateVendorCredentialsRequest, + ], + include_secrets: Union[Unset, bool] = False, +) -> Response[UpdateVendorCredentialsResponse]: + """Updates the stored credentials + + Updates the stored credentials with the given ID. The request body will be interpreted as a [JSON + Merge Patch](https://datatracker.ietf.org/doc/html/rfc7396) against the stored credentials. Note + that updating the 'vendor' or 'type' fields is not supported. + + Args: + id (str): ID for the vendor credentials + include_secrets (Union[Unset, bool]): Default: False. + body (UpdateVendorCredentialsRequest): + body (UpdateVendorCredentialsRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[UpdateVendorCredentialsResponse] + """ + + kwargs = _get_kwargs( + id=id, + body=body, + include_secrets=include_secrets, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + id: str, + *, + client: Union[AuthenticatedClient, Client], + body: Union[ + UpdateVendorCredentialsRequest, + UpdateVendorCredentialsRequest, + ], + include_secrets: Union[Unset, bool] = False, +) -> Optional[UpdateVendorCredentialsResponse]: + """Updates the stored credentials + + Updates the stored credentials with the given ID. The request body will be interpreted as a [JSON + Merge Patch](https://datatracker.ietf.org/doc/html/rfc7396) against the stored credentials. Note + that updating the 'vendor' or 'type' fields is not supported. + + Args: + id (str): ID for the vendor credentials + include_secrets (Union[Unset, bool]): Default: False. + body (UpdateVendorCredentialsRequest): + body (UpdateVendorCredentialsRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + UpdateVendorCredentialsResponse + """ + + return ( + await asyncio_detailed( + id=id, + client=client, + body=body, + include_secrets=include_secrets, + ) + ).parsed diff --git a/derapi/api/virtual/__init__.py b/derapi/api/virtual/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/derapi/api/virtual/create_virtual_battery.py b/derapi/api/virtual/create_virtual_battery.py new file mode 100644 index 0000000..e2d976c --- /dev/null +++ b/derapi/api/virtual/create_virtual_battery.py @@ -0,0 +1,172 @@ +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.create_virtual_battery_request import CreateVirtualBatteryRequest +from ...models.create_virtual_battery_response import CreateVirtualBatteryResponse +from ...types import Response + + +def _get_kwargs( + *, + body: CreateVirtualBatteryRequest, +) -> Dict[str, Any]: + headers: Dict[str, Any] = {} + + _kwargs: Dict[str, Any] = { + "method": "post", + "url": "/virtual/batteries", + } + + _body = body.to_dict() + + _kwargs["json"] = _body + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[CreateVirtualBatteryResponse]: + if response.status_code == 201: + response_201 = CreateVirtualBatteryResponse.from_dict(response.json()) + + return response_201 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[CreateVirtualBatteryResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: Union[AuthenticatedClient, Client], + body: CreateVirtualBatteryRequest, +) -> Response[CreateVirtualBatteryResponse]: + """Create a Virtual Battery + + Create Virtual Battery test configuration in the current sandbox. + + Args: + body (CreateVirtualBatteryRequest): Fields the user would like to provide. Omitted ones + will be inferred. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[CreateVirtualBatteryResponse] + """ + + kwargs = _get_kwargs( + body=body, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: Union[AuthenticatedClient, Client], + body: CreateVirtualBatteryRequest, +) -> Optional[CreateVirtualBatteryResponse]: + """Create a Virtual Battery + + Create Virtual Battery test configuration in the current sandbox. + + Args: + body (CreateVirtualBatteryRequest): Fields the user would like to provide. Omitted ones + will be inferred. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + CreateVirtualBatteryResponse + """ + + return sync_detailed( + client=client, + body=body, + ).parsed + + +async def asyncio_detailed( + *, + client: Union[AuthenticatedClient, Client], + body: CreateVirtualBatteryRequest, +) -> Response[CreateVirtualBatteryResponse]: + """Create a Virtual Battery + + Create Virtual Battery test configuration in the current sandbox. + + Args: + body (CreateVirtualBatteryRequest): Fields the user would like to provide. Omitted ones + will be inferred. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[CreateVirtualBatteryResponse] + """ + + kwargs = _get_kwargs( + body=body, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: Union[AuthenticatedClient, Client], + body: CreateVirtualBatteryRequest, +) -> Optional[CreateVirtualBatteryResponse]: + """Create a Virtual Battery + + Create Virtual Battery test configuration in the current sandbox. + + Args: + body (CreateVirtualBatteryRequest): Fields the user would like to provide. Omitted ones + will be inferred. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + CreateVirtualBatteryResponse + """ + + return ( + await asyncio_detailed( + client=client, + body=body, + ) + ).parsed diff --git a/derapi/api/virtual/create_virtual_site.py b/derapi/api/virtual/create_virtual_site.py new file mode 100644 index 0000000..adcfbef --- /dev/null +++ b/derapi/api/virtual/create_virtual_site.py @@ -0,0 +1,172 @@ +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.create_virtual_site_request import CreateVirtualSiteRequest +from ...models.create_virtual_site_response import CreateVirtualSiteResponse +from ...types import Response + + +def _get_kwargs( + *, + body: CreateVirtualSiteRequest, +) -> Dict[str, Any]: + headers: Dict[str, Any] = {} + + _kwargs: Dict[str, Any] = { + "method": "post", + "url": "/virtual/sites", + } + + _body = body.to_dict() + + _kwargs["json"] = _body + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[CreateVirtualSiteResponse]: + if response.status_code == 201: + response_201 = CreateVirtualSiteResponse.from_dict(response.json()) + + return response_201 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[CreateVirtualSiteResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: Union[AuthenticatedClient, Client], + body: CreateVirtualSiteRequest, +) -> Response[CreateVirtualSiteResponse]: + """Create a Virtual Site + + Create a Virtual Site test configuration in the current sandbox. + + Args: + body (CreateVirtualSiteRequest): Fields the user would like to provide. Omitted ones will + be inferred. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[CreateVirtualSiteResponse] + """ + + kwargs = _get_kwargs( + body=body, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: Union[AuthenticatedClient, Client], + body: CreateVirtualSiteRequest, +) -> Optional[CreateVirtualSiteResponse]: + """Create a Virtual Site + + Create a Virtual Site test configuration in the current sandbox. + + Args: + body (CreateVirtualSiteRequest): Fields the user would like to provide. Omitted ones will + be inferred. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + CreateVirtualSiteResponse + """ + + return sync_detailed( + client=client, + body=body, + ).parsed + + +async def asyncio_detailed( + *, + client: Union[AuthenticatedClient, Client], + body: CreateVirtualSiteRequest, +) -> Response[CreateVirtualSiteResponse]: + """Create a Virtual Site + + Create a Virtual Site test configuration in the current sandbox. + + Args: + body (CreateVirtualSiteRequest): Fields the user would like to provide. Omitted ones will + be inferred. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[CreateVirtualSiteResponse] + """ + + kwargs = _get_kwargs( + body=body, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: Union[AuthenticatedClient, Client], + body: CreateVirtualSiteRequest, +) -> Optional[CreateVirtualSiteResponse]: + """Create a Virtual Site + + Create a Virtual Site test configuration in the current sandbox. + + Args: + body (CreateVirtualSiteRequest): Fields the user would like to provide. Omitted ones will + be inferred. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + CreateVirtualSiteResponse + """ + + return ( + await asyncio_detailed( + client=client, + body=body, + ) + ).parsed diff --git a/derapi/api/virtual/create_virtual_solar_inverter.py b/derapi/api/virtual/create_virtual_solar_inverter.py new file mode 100644 index 0000000..6ff99af --- /dev/null +++ b/derapi/api/virtual/create_virtual_solar_inverter.py @@ -0,0 +1,168 @@ +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.create_virtual_solar_inverter_request import CreateVirtualSolarInverterRequest +from ...models.create_virtual_solar_inverter_response import CreateVirtualSolarInverterResponse +from ...types import Response + + +def _get_kwargs( + *, + body: CreateVirtualSolarInverterRequest, +) -> Dict[str, Any]: + headers: Dict[str, Any] = {} + + _kwargs: Dict[str, Any] = { + "method": "post", + "url": "/virtual/solar-inverters", + } + + _body = body.to_dict() + + _kwargs["json"] = _body + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[CreateVirtualSolarInverterResponse]: + if response.status_code == 201: + response_201 = CreateVirtualSolarInverterResponse.from_dict(response.json()) + + return response_201 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[CreateVirtualSolarInverterResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: Union[AuthenticatedClient, Client], + body: CreateVirtualSolarInverterRequest, +) -> Response[CreateVirtualSolarInverterResponse]: + """Create a virtual solar inverter + + Create virtual solar inverter test configuration in the current sandbox. + + Args: + body (CreateVirtualSolarInverterRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[CreateVirtualSolarInverterResponse] + """ + + kwargs = _get_kwargs( + body=body, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: Union[AuthenticatedClient, Client], + body: CreateVirtualSolarInverterRequest, +) -> Optional[CreateVirtualSolarInverterResponse]: + """Create a virtual solar inverter + + Create virtual solar inverter test configuration in the current sandbox. + + Args: + body (CreateVirtualSolarInverterRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + CreateVirtualSolarInverterResponse + """ + + return sync_detailed( + client=client, + body=body, + ).parsed + + +async def asyncio_detailed( + *, + client: Union[AuthenticatedClient, Client], + body: CreateVirtualSolarInverterRequest, +) -> Response[CreateVirtualSolarInverterResponse]: + """Create a virtual solar inverter + + Create virtual solar inverter test configuration in the current sandbox. + + Args: + body (CreateVirtualSolarInverterRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[CreateVirtualSolarInverterResponse] + """ + + kwargs = _get_kwargs( + body=body, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: Union[AuthenticatedClient, Client], + body: CreateVirtualSolarInverterRequest, +) -> Optional[CreateVirtualSolarInverterResponse]: + """Create a virtual solar inverter + + Create virtual solar inverter test configuration in the current sandbox. + + Args: + body (CreateVirtualSolarInverterRequest): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + CreateVirtualSolarInverterResponse + """ + + return ( + await asyncio_detailed( + client=client, + body=body, + ) + ).parsed diff --git a/derapi/api/virtual/delete_virtual_battery.py b/derapi/api/virtual/delete_virtual_battery.py new file mode 100644 index 0000000..f18aab0 --- /dev/null +++ b/derapi/api/virtual/delete_virtual_battery.py @@ -0,0 +1,97 @@ +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...types import Response + + +def _get_kwargs( + id: str, +) -> Dict[str, Any]: + _kwargs: Dict[str, Any] = { + "method": "delete", + "url": f"/virtual/batteries/{id}", + } + + return _kwargs + + +def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[Any]: + if response.status_code == 204: + return None + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[Any]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[Any]: + """Delete Virtual Battery + + Delete Virtual Battery test configuration in the current sandbox. + + Args: + id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Any] + """ + + kwargs = _get_kwargs( + id=id, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +async def asyncio_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[Any]: + """Delete Virtual Battery + + Delete Virtual Battery test configuration in the current sandbox. + + Args: + id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Any] + """ + + kwargs = _get_kwargs( + id=id, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) diff --git a/derapi/api/virtual/delete_virtual_site.py b/derapi/api/virtual/delete_virtual_site.py new file mode 100644 index 0000000..b41736b --- /dev/null +++ b/derapi/api/virtual/delete_virtual_site.py @@ -0,0 +1,97 @@ +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...types import Response + + +def _get_kwargs( + id: str, +) -> Dict[str, Any]: + _kwargs: Dict[str, Any] = { + "method": "delete", + "url": f"/virtual/sites/{id}", + } + + return _kwargs + + +def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[Any]: + if response.status_code == 204: + return None + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[Any]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[Any]: + """Delete Virtual Site + + Delete Virtual Site test configuration in the current sandbox. + + Args: + id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Any] + """ + + kwargs = _get_kwargs( + id=id, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +async def asyncio_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[Any]: + """Delete Virtual Site + + Delete Virtual Site test configuration in the current sandbox. + + Args: + id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Any] + """ + + kwargs = _get_kwargs( + id=id, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) diff --git a/derapi/api/virtual/delete_virtual_solar_inverter.py b/derapi/api/virtual/delete_virtual_solar_inverter.py new file mode 100644 index 0000000..ba164cf --- /dev/null +++ b/derapi/api/virtual/delete_virtual_solar_inverter.py @@ -0,0 +1,97 @@ +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...types import Response + + +def _get_kwargs( + id: str, +) -> Dict[str, Any]: + _kwargs: Dict[str, Any] = { + "method": "delete", + "url": f"/virtual/solar-inverters/{id}", + } + + return _kwargs + + +def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[Any]: + if response.status_code == 204: + return None + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[Any]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[Any]: + """Delete virtual solar inverter + + Delete virtual solar inverter test configuration in the current sandbox. + + Args: + id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Any] + """ + + kwargs = _get_kwargs( + id=id, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +async def asyncio_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[Any]: + """Delete virtual solar inverter + + Delete virtual solar inverter test configuration in the current sandbox. + + Args: + id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[Any] + """ + + kwargs = _get_kwargs( + id=id, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) diff --git a/derapi/api/virtual/get_virtual_battery.py b/derapi/api/virtual/get_virtual_battery.py new file mode 100644 index 0000000..5139307 --- /dev/null +++ b/derapi/api/virtual/get_virtual_battery.py @@ -0,0 +1,158 @@ +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.get_virtual_battery_response import GetVirtualBatteryResponse +from ...types import Response + + +def _get_kwargs( + id: str, +) -> Dict[str, Any]: + _kwargs: Dict[str, Any] = { + "method": "get", + "url": f"/virtual/batteries/{id}", + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[GetVirtualBatteryResponse]: + if response.status_code == 200: + response_200 = GetVirtualBatteryResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[GetVirtualBatteryResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[GetVirtualBatteryResponse]: + """Get Virtual Battery + + Get Virtual Battery test configuration in the current sandbox. + + Args: + id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetVirtualBatteryResponse] + """ + + kwargs = _get_kwargs( + id=id, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Optional[GetVirtualBatteryResponse]: + """Get Virtual Battery + + Get Virtual Battery test configuration in the current sandbox. + + Args: + id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetVirtualBatteryResponse + """ + + return sync_detailed( + id=id, + client=client, + ).parsed + + +async def asyncio_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[GetVirtualBatteryResponse]: + """Get Virtual Battery + + Get Virtual Battery test configuration in the current sandbox. + + Args: + id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetVirtualBatteryResponse] + """ + + kwargs = _get_kwargs( + id=id, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Optional[GetVirtualBatteryResponse]: + """Get Virtual Battery + + Get Virtual Battery test configuration in the current sandbox. + + Args: + id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetVirtualBatteryResponse + """ + + return ( + await asyncio_detailed( + id=id, + client=client, + ) + ).parsed diff --git a/derapi/api/virtual/get_virtual_site.py b/derapi/api/virtual/get_virtual_site.py new file mode 100644 index 0000000..ec3ec01 --- /dev/null +++ b/derapi/api/virtual/get_virtual_site.py @@ -0,0 +1,158 @@ +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.get_virtual_site_response import GetVirtualSiteResponse +from ...types import Response + + +def _get_kwargs( + id: str, +) -> Dict[str, Any]: + _kwargs: Dict[str, Any] = { + "method": "get", + "url": f"/virtual/sites/{id}", + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[GetVirtualSiteResponse]: + if response.status_code == 200: + response_200 = GetVirtualSiteResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[GetVirtualSiteResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[GetVirtualSiteResponse]: + """Get Virtual Site + + Get Virtual Site test configuration in the current sandbox. + + Args: + id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetVirtualSiteResponse] + """ + + kwargs = _get_kwargs( + id=id, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Optional[GetVirtualSiteResponse]: + """Get Virtual Site + + Get Virtual Site test configuration in the current sandbox. + + Args: + id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetVirtualSiteResponse + """ + + return sync_detailed( + id=id, + client=client, + ).parsed + + +async def asyncio_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[GetVirtualSiteResponse]: + """Get Virtual Site + + Get Virtual Site test configuration in the current sandbox. + + Args: + id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetVirtualSiteResponse] + """ + + kwargs = _get_kwargs( + id=id, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Optional[GetVirtualSiteResponse]: + """Get Virtual Site + + Get Virtual Site test configuration in the current sandbox. + + Args: + id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetVirtualSiteResponse + """ + + return ( + await asyncio_detailed( + id=id, + client=client, + ) + ).parsed diff --git a/derapi/api/virtual/get_virtual_solar_inverter.py b/derapi/api/virtual/get_virtual_solar_inverter.py new file mode 100644 index 0000000..19bb08e --- /dev/null +++ b/derapi/api/virtual/get_virtual_solar_inverter.py @@ -0,0 +1,158 @@ +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.get_virtual_solar_inverter_response import GetVirtualSolarInverterResponse +from ...types import Response + + +def _get_kwargs( + id: str, +) -> Dict[str, Any]: + _kwargs: Dict[str, Any] = { + "method": "get", + "url": f"/virtual/solar-inverters/{id}", + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[GetVirtualSolarInverterResponse]: + if response.status_code == 200: + response_200 = GetVirtualSolarInverterResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[GetVirtualSolarInverterResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[GetVirtualSolarInverterResponse]: + """Get virtual solar inverter + + Get virtual solar inverter test configuration in the current sandbox. + + Args: + id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetVirtualSolarInverterResponse] + """ + + kwargs = _get_kwargs( + id=id, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Optional[GetVirtualSolarInverterResponse]: + """Get virtual solar inverter + + Get virtual solar inverter test configuration in the current sandbox. + + Args: + id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetVirtualSolarInverterResponse + """ + + return sync_detailed( + id=id, + client=client, + ).parsed + + +async def asyncio_detailed( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Response[GetVirtualSolarInverterResponse]: + """Get virtual solar inverter + + Get virtual solar inverter test configuration in the current sandbox. + + Args: + id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[GetVirtualSolarInverterResponse] + """ + + kwargs = _get_kwargs( + id=id, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + id: str, + *, + client: Union[AuthenticatedClient, Client], +) -> Optional[GetVirtualSolarInverterResponse]: + """Get virtual solar inverter + + Get virtual solar inverter test configuration in the current sandbox. + + Args: + id (str): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + GetVirtualSolarInverterResponse + """ + + return ( + await asyncio_detailed( + id=id, + client=client, + ) + ).parsed diff --git a/derapi/api/virtual/list_virtual_batteries.py b/derapi/api/virtual/list_virtual_batteries.py new file mode 100644 index 0000000..9c55bb1 --- /dev/null +++ b/derapi/api/virtual/list_virtual_batteries.py @@ -0,0 +1,265 @@ +from http import HTTPStatus +from typing import Any, AsyncIterator, Dict, Iterator, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.list_virtual_batteries_response import ListVirtualBatteriesResponse +from ...models.virtual_battery import VirtualBattery +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + *, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Dict[str, Any]: + params: Dict[str, Any] = {} + + params["pageSize"] = page_size + + params["pageToken"] = page_token + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: Dict[str, Any] = { + "method": "get", + "url": "/virtual/batteries", + "params": params, + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[ListVirtualBatteriesResponse]: + if response.status_code == 200: + response_200 = ListVirtualBatteriesResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[ListVirtualBatteriesResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Response[ListVirtualBatteriesResponse]: + """List Virtual Batteries + + List Virtual Battery test configurations in the current sandbox. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[ListVirtualBatteriesResponse] + """ + + kwargs = _get_kwargs( + page_size=page_size, + page_token=page_token, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Optional[ListVirtualBatteriesResponse]: + """List Virtual Batteries + + List Virtual Battery test configurations in the current sandbox. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + ListVirtualBatteriesResponse + """ + + return sync_detailed( + client=client, + page_size=page_size, + page_token=page_token, + ).parsed + + +async def asyncio_detailed( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Response[ListVirtualBatteriesResponse]: + """List Virtual Batteries + + List Virtual Battery test configurations in the current sandbox. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[ListVirtualBatteriesResponse] + """ + + kwargs = _get_kwargs( + page_size=page_size, + page_token=page_token, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Optional[ListVirtualBatteriesResponse]: + """List Virtual Batteries + + List Virtual Battery test configurations in the current sandbox. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + ListVirtualBatteriesResponse + """ + + return ( + await asyncio_detailed( + client=client, + page_size=page_size, + page_token=page_token, + ) + ).parsed + + +def sync_depaginated( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Iterator[VirtualBattery]: + """List Virtual Batteries + + List Virtual Battery test configurations in the current sandbox. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Iterator[VirtualBattery] + """ + + response = sync( + client=client, + page_size=page_size, + page_token=page_token, + ) + while response is not None: + yield from response.virtual_batteries + + page_token = response.next_page_token + if page_token == UNSET: + response = None + else: + response = sync( + client=client, + page_size=page_size, + page_token=page_token, + ) + + +async def async_depaginated( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> AsyncIterator[VirtualBattery]: + """List Virtual Batteries + + List Virtual Battery test configurations in the current sandbox. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Iterator[VirtualBattery] + """ + + response = await asyncio( + client=client, + page_size=page_size, + page_token=page_token, + ) + while response is not None: + for item in response.virtual_batteries: + yield item + + page_token = response.next_page_token + if page_token == UNSET: + response = None + else: + response = await asyncio( + client=client, + page_size=page_size, + page_token=page_token, + ) diff --git a/derapi/api/virtual/list_virtual_sites.py b/derapi/api/virtual/list_virtual_sites.py new file mode 100644 index 0000000..531f985 --- /dev/null +++ b/derapi/api/virtual/list_virtual_sites.py @@ -0,0 +1,265 @@ +from http import HTTPStatus +from typing import Any, AsyncIterator, Dict, Iterator, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.list_virtual_sites_response import ListVirtualSitesResponse +from ...models.virtual_site import VirtualSite +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + *, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Dict[str, Any]: + params: Dict[str, Any] = {} + + params["pageSize"] = page_size + + params["pageToken"] = page_token + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: Dict[str, Any] = { + "method": "get", + "url": "/virtual/sites", + "params": params, + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[ListVirtualSitesResponse]: + if response.status_code == 200: + response_200 = ListVirtualSitesResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[ListVirtualSitesResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Response[ListVirtualSitesResponse]: + """List Virtual Sites + + List Virtual Site test configurations in the current sandbox. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[ListVirtualSitesResponse] + """ + + kwargs = _get_kwargs( + page_size=page_size, + page_token=page_token, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Optional[ListVirtualSitesResponse]: + """List Virtual Sites + + List Virtual Site test configurations in the current sandbox. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + ListVirtualSitesResponse + """ + + return sync_detailed( + client=client, + page_size=page_size, + page_token=page_token, + ).parsed + + +async def asyncio_detailed( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Response[ListVirtualSitesResponse]: + """List Virtual Sites + + List Virtual Site test configurations in the current sandbox. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[ListVirtualSitesResponse] + """ + + kwargs = _get_kwargs( + page_size=page_size, + page_token=page_token, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Optional[ListVirtualSitesResponse]: + """List Virtual Sites + + List Virtual Site test configurations in the current sandbox. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + ListVirtualSitesResponse + """ + + return ( + await asyncio_detailed( + client=client, + page_size=page_size, + page_token=page_token, + ) + ).parsed + + +def sync_depaginated( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Iterator[VirtualSite]: + """List Virtual Sites + + List Virtual Site test configurations in the current sandbox. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Iterator[VirtualSite] + """ + + response = sync( + client=client, + page_size=page_size, + page_token=page_token, + ) + while response is not None: + yield from response.virtual_sites + + page_token = response.next_page_token + if page_token == UNSET: + response = None + else: + response = sync( + client=client, + page_size=page_size, + page_token=page_token, + ) + + +async def async_depaginated( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> AsyncIterator[VirtualSite]: + """List Virtual Sites + + List Virtual Site test configurations in the current sandbox. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Iterator[VirtualSite] + """ + + response = await asyncio( + client=client, + page_size=page_size, + page_token=page_token, + ) + while response is not None: + for item in response.virtual_sites: + yield item + + page_token = response.next_page_token + if page_token == UNSET: + response = None + else: + response = await asyncio( + client=client, + page_size=page_size, + page_token=page_token, + ) diff --git a/derapi/api/virtual/list_virtual_solar_inverters.py b/derapi/api/virtual/list_virtual_solar_inverters.py new file mode 100644 index 0000000..8909322 --- /dev/null +++ b/derapi/api/virtual/list_virtual_solar_inverters.py @@ -0,0 +1,265 @@ +from http import HTTPStatus +from typing import Any, AsyncIterator, Dict, Iterator, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.list_virtual_solar_inverters_response import ListVirtualSolarInvertersResponse +from ...models.virtual_solar_inverter import VirtualSolarInverter +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + *, + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Dict[str, Any]: + params: Dict[str, Any] = {} + + params["pageSize"] = page_size + + params["pageToken"] = page_token + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: Dict[str, Any] = { + "method": "get", + "url": "/virtual/solar-inverters", + "params": params, + } + + return _kwargs + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[ListVirtualSolarInvertersResponse]: + if response.status_code == 200: + response_200 = ListVirtualSolarInvertersResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[ListVirtualSolarInvertersResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Response[ListVirtualSolarInvertersResponse]: + """List virtual solar inverters + + List virtual solar inverter test configurations in the current sandbox. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[ListVirtualSolarInvertersResponse] + """ + + kwargs = _get_kwargs( + page_size=page_size, + page_token=page_token, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Optional[ListVirtualSolarInvertersResponse]: + """List virtual solar inverters + + List virtual solar inverter test configurations in the current sandbox. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + ListVirtualSolarInvertersResponse + """ + + return sync_detailed( + client=client, + page_size=page_size, + page_token=page_token, + ).parsed + + +async def asyncio_detailed( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Response[ListVirtualSolarInvertersResponse]: + """List virtual solar inverters + + List virtual solar inverter test configurations in the current sandbox. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[ListVirtualSolarInvertersResponse] + """ + + kwargs = _get_kwargs( + page_size=page_size, + page_token=page_token, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Optional[ListVirtualSolarInvertersResponse]: + """List virtual solar inverters + + List virtual solar inverter test configurations in the current sandbox. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + ListVirtualSolarInvertersResponse + """ + + return ( + await asyncio_detailed( + client=client, + page_size=page_size, + page_token=page_token, + ) + ).parsed + + +def sync_depaginated( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> Iterator[VirtualSolarInverter]: + """List virtual solar inverters + + List virtual solar inverter test configurations in the current sandbox. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Iterator[VirtualSolarInverter] + """ + + response = sync( + client=client, + page_size=page_size, + page_token=page_token, + ) + while response is not None: + yield from response.virtual_solar_inverters + + page_token = response.next_page_token + if page_token == UNSET: + response = None + else: + response = sync( + client=client, + page_size=page_size, + page_token=page_token, + ) + + +async def async_depaginated( + *, + client: Union[AuthenticatedClient, Client], + page_size: Union[Unset, int] = 50, + page_token: Union[Unset, str] = UNSET, +) -> AsyncIterator[VirtualSolarInverter]: + """List virtual solar inverters + + List virtual solar inverter test configurations in the current sandbox. + + Args: + page_size (Union[Unset, int]): Default: 50. + page_token (Union[Unset, str]): + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Iterator[VirtualSolarInverter] + """ + + response = await asyncio( + client=client, + page_size=page_size, + page_token=page_token, + ) + while response is not None: + for item in response.virtual_solar_inverters: + yield item + + page_token = response.next_page_token + if page_token == UNSET: + response = None + else: + response = await asyncio( + client=client, + page_size=page_size, + page_token=page_token, + ) diff --git a/derapi/client.py b/derapi/client.py new file mode 100644 index 0000000..0f6d15e --- /dev/null +++ b/derapi/client.py @@ -0,0 +1,268 @@ +import ssl +from typing import Any, Dict, Optional, Union + +import httpx +from attrs import define, evolve, field + + +@define +class Client: + """A class for keeping track of data related to the API + + The following are accepted as keyword arguments and will be used to construct httpx Clients internally: + + ``base_url``: The base URL for the API, all requests are made to a relative path to this URL + + ``cookies``: A dictionary of cookies to be sent with every request + + ``headers``: A dictionary of headers to be sent with every request + + ``timeout``: The maximum amount of a time a request can take. API functions will raise + httpx.TimeoutException if this is exceeded. + + ``verify_ssl``: Whether or not to verify the SSL certificate of the API server. This should be True in production, + but can be set to False for testing purposes. + + ``follow_redirects``: Whether or not to follow redirects. Default value is False. + + ``httpx_args``: A dictionary of additional arguments to be passed to the ``httpx.Client`` and ``httpx.AsyncClient`` constructor. + + + Attributes: + raise_on_unexpected_status: Whether or not to raise an errors.UnexpectedStatus if the API returns a + status code that was not documented in the source OpenAPI document. Can also be provided as a keyword + argument to the constructor. + """ + + raise_on_unexpected_status: bool = field(default=False, kw_only=True) + _base_url: str = field(alias="base_url") + _cookies: Dict[str, str] = field(factory=dict, kw_only=True, alias="cookies") + _headers: Dict[str, str] = field(factory=dict, kw_only=True, alias="headers") + _timeout: Optional[httpx.Timeout] = field(default=None, kw_only=True, alias="timeout") + _verify_ssl: Union[str, bool, ssl.SSLContext] = field(default=True, kw_only=True, alias="verify_ssl") + _follow_redirects: bool = field(default=False, kw_only=True, alias="follow_redirects") + _httpx_args: Dict[str, Any] = field(factory=dict, kw_only=True, alias="httpx_args") + _client: Optional[httpx.Client] = field(default=None, init=False) + _async_client: Optional[httpx.AsyncClient] = field(default=None, init=False) + + def with_headers(self, headers: Dict[str, str]) -> "Client": + """Get a new client matching this one with additional headers""" + if self._client is not None: + self._client.headers.update(headers) + if self._async_client is not None: + self._async_client.headers.update(headers) + return evolve(self, headers={**self._headers, **headers}) + + def with_cookies(self, cookies: Dict[str, str]) -> "Client": + """Get a new client matching this one with additional cookies""" + if self._client is not None: + self._client.cookies.update(cookies) + if self._async_client is not None: + self._async_client.cookies.update(cookies) + return evolve(self, cookies={**self._cookies, **cookies}) + + def with_timeout(self, timeout: httpx.Timeout) -> "Client": + """Get a new client matching this one with a new timeout (in seconds)""" + if self._client is not None: + self._client.timeout = timeout + if self._async_client is not None: + self._async_client.timeout = timeout + return evolve(self, timeout=timeout) + + def set_httpx_client(self, client: httpx.Client) -> "Client": + """Manually set the underlying httpx.Client + + **NOTE**: This will override any other settings on the client, including cookies, headers, and timeout. + """ + self._client = client + return self + + def get_httpx_client(self) -> httpx.Client: + """Get the underlying httpx.Client, constructing a new one if not previously set""" + if self._client is None: + self._client = httpx.Client( + base_url=self._base_url, + cookies=self._cookies, + headers=self._headers, + timeout=self._timeout, + verify=self._verify_ssl, + follow_redirects=self._follow_redirects, + **self._httpx_args, + ) + return self._client + + def __enter__(self) -> "Client": + """Enter a context manager for self.client—you cannot enter twice (see httpx docs)""" + self.get_httpx_client().__enter__() + return self + + def __exit__(self, *args: Any, **kwargs: Any) -> None: + """Exit a context manager for internal httpx.Client (see httpx docs)""" + self.get_httpx_client().__exit__(*args, **kwargs) + + def set_async_httpx_client(self, async_client: httpx.AsyncClient) -> "Client": + """Manually the underlying httpx.AsyncClient + + **NOTE**: This will override any other settings on the client, including cookies, headers, and timeout. + """ + self._async_client = async_client + return self + + def get_async_httpx_client(self) -> httpx.AsyncClient: + """Get the underlying httpx.AsyncClient, constructing a new one if not previously set""" + if self._async_client is None: + self._async_client = httpx.AsyncClient( + base_url=self._base_url, + cookies=self._cookies, + headers=self._headers, + timeout=self._timeout, + verify=self._verify_ssl, + follow_redirects=self._follow_redirects, + **self._httpx_args, + ) + return self._async_client + + async def __aenter__(self) -> "Client": + """Enter a context manager for underlying httpx.AsyncClient—you cannot enter twice (see httpx docs)""" + await self.get_async_httpx_client().__aenter__() + return self + + async def __aexit__(self, *args: Any, **kwargs: Any) -> None: + """Exit a context manager for underlying httpx.AsyncClient (see httpx docs)""" + await self.get_async_httpx_client().__aexit__(*args, **kwargs) + + +@define +class AuthenticatedClient: + """A Client which has been authenticated for use on secured endpoints + + The following are accepted as keyword arguments and will be used to construct httpx Clients internally: + + ``base_url``: The base URL for the API, all requests are made to a relative path to this URL + + ``cookies``: A dictionary of cookies to be sent with every request + + ``headers``: A dictionary of headers to be sent with every request + + ``timeout``: The maximum amount of a time a request can take. API functions will raise + httpx.TimeoutException if this is exceeded. + + ``verify_ssl``: Whether or not to verify the SSL certificate of the API server. This should be True in production, + but can be set to False for testing purposes. + + ``follow_redirects``: Whether or not to follow redirects. Default value is False. + + ``httpx_args``: A dictionary of additional arguments to be passed to the ``httpx.Client`` and ``httpx.AsyncClient`` constructor. + + + Attributes: + raise_on_unexpected_status: Whether or not to raise an errors.UnexpectedStatus if the API returns a + status code that was not documented in the source OpenAPI document. Can also be provided as a keyword + argument to the constructor. + token: The token to use for authentication + prefix: The prefix to use for the Authorization header + auth_header_name: The name of the Authorization header + """ + + raise_on_unexpected_status: bool = field(default=False, kw_only=True) + _base_url: str = field(alias="base_url") + _cookies: Dict[str, str] = field(factory=dict, kw_only=True, alias="cookies") + _headers: Dict[str, str] = field(factory=dict, kw_only=True, alias="headers") + _timeout: Optional[httpx.Timeout] = field(default=None, kw_only=True, alias="timeout") + _verify_ssl: Union[str, bool, ssl.SSLContext] = field(default=True, kw_only=True, alias="verify_ssl") + _follow_redirects: bool = field(default=False, kw_only=True, alias="follow_redirects") + _httpx_args: Dict[str, Any] = field(factory=dict, kw_only=True, alias="httpx_args") + _client: Optional[httpx.Client] = field(default=None, init=False) + _async_client: Optional[httpx.AsyncClient] = field(default=None, init=False) + + token: str + prefix: str = "Bearer" + auth_header_name: str = "Authorization" + + def with_headers(self, headers: Dict[str, str]) -> "AuthenticatedClient": + """Get a new client matching this one with additional headers""" + if self._client is not None: + self._client.headers.update(headers) + if self._async_client is not None: + self._async_client.headers.update(headers) + return evolve(self, headers={**self._headers, **headers}) + + def with_cookies(self, cookies: Dict[str, str]) -> "AuthenticatedClient": + """Get a new client matching this one with additional cookies""" + if self._client is not None: + self._client.cookies.update(cookies) + if self._async_client is not None: + self._async_client.cookies.update(cookies) + return evolve(self, cookies={**self._cookies, **cookies}) + + def with_timeout(self, timeout: httpx.Timeout) -> "AuthenticatedClient": + """Get a new client matching this one with a new timeout (in seconds)""" + if self._client is not None: + self._client.timeout = timeout + if self._async_client is not None: + self._async_client.timeout = timeout + return evolve(self, timeout=timeout) + + def set_httpx_client(self, client: httpx.Client) -> "AuthenticatedClient": + """Manually set the underlying httpx.Client + + **NOTE**: This will override any other settings on the client, including cookies, headers, and timeout. + """ + self._client = client + return self + + def get_httpx_client(self) -> httpx.Client: + """Get the underlying httpx.Client, constructing a new one if not previously set""" + if self._client is None: + self._headers[self.auth_header_name] = f"{self.prefix} {self.token}" if self.prefix else self.token + self._client = httpx.Client( + base_url=self._base_url, + cookies=self._cookies, + headers=self._headers, + timeout=self._timeout, + verify=self._verify_ssl, + follow_redirects=self._follow_redirects, + **self._httpx_args, + ) + return self._client + + def __enter__(self) -> "AuthenticatedClient": + """Enter a context manager for self.client—you cannot enter twice (see httpx docs)""" + self.get_httpx_client().__enter__() + return self + + def __exit__(self, *args: Any, **kwargs: Any) -> None: + """Exit a context manager for internal httpx.Client (see httpx docs)""" + self.get_httpx_client().__exit__(*args, **kwargs) + + def set_async_httpx_client(self, async_client: httpx.AsyncClient) -> "AuthenticatedClient": + """Manually the underlying httpx.AsyncClient + + **NOTE**: This will override any other settings on the client, including cookies, headers, and timeout. + """ + self._async_client = async_client + return self + + def get_async_httpx_client(self) -> httpx.AsyncClient: + """Get the underlying httpx.AsyncClient, constructing a new one if not previously set""" + if self._async_client is None: + self._headers[self.auth_header_name] = f"{self.prefix} {self.token}" if self.prefix else self.token + self._async_client = httpx.AsyncClient( + base_url=self._base_url, + cookies=self._cookies, + headers=self._headers, + timeout=self._timeout, + verify=self._verify_ssl, + follow_redirects=self._follow_redirects, + **self._httpx_args, + ) + return self._async_client + + async def __aenter__(self) -> "AuthenticatedClient": + """Enter a context manager for underlying httpx.AsyncClient—you cannot enter twice (see httpx docs)""" + await self.get_async_httpx_client().__aenter__() + return self + + async def __aexit__(self, *args: Any, **kwargs: Any) -> None: + """Exit a context manager for underlying httpx.AsyncClient (see httpx docs)""" + await self.get_async_httpx_client().__aexit__(*args, **kwargs) diff --git a/derapi/errors.py b/derapi/errors.py new file mode 100644 index 0000000..5f92e76 --- /dev/null +++ b/derapi/errors.py @@ -0,0 +1,16 @@ +"""Contains shared errors types that can be raised from API functions""" + + +class UnexpectedStatus(Exception): + """Raised by api functions when the response status an undocumented status and Client.raise_on_unexpected_status is True""" + + def __init__(self, status_code: int, content: bytes): + self.status_code = status_code + self.content = content + + super().__init__( + f"Unexpected status code: {status_code}\n\nResponse content:\n{content.decode(errors='ignore')}" + ) + + +__all__ = ["UnexpectedStatus"] diff --git a/derapi/models/__init__.py b/derapi/models/__init__.py new file mode 100644 index 0000000..25b5efb --- /dev/null +++ b/derapi/models/__init__.py @@ -0,0 +1,221 @@ +"""Contains all the data models used in inputs/outputs""" + +from .battery import Battery +from .battery_interval import BatteryInterval +from .battery_mode import BatteryMode +from .battery_recent_errors_error import BatteryRecentErrorsError +from .battery_recent_errors_info import BatteryRecentErrorsInfo +from .battery_recent_errors_start import BatteryRecentErrorsStart +from .battery_recent_errors_warning import BatteryRecentErrorsWarning +from .battery_summary import BatterySummary +from .create_join_session_request import CreateJoinSessionRequest +from .create_join_session_response import CreateJoinSessionResponse +from .create_vendor_credentials_request import CreateVendorCredentialsRequest +from .create_vendor_credentials_response import CreateVendorCredentialsResponse +from .create_virtual_battery_request import CreateVirtualBatteryRequest +from .create_virtual_battery_response import CreateVirtualBatteryResponse +from .create_virtual_site_request import CreateVirtualSiteRequest +from .create_virtual_site_response import CreateVirtualSiteResponse +from .create_virtual_solar_inverter_request import CreateVirtualSolarInverterRequest +from .create_virtual_solar_inverter_response import CreateVirtualSolarInverterResponse +from .enphase_developer_app_credentials import EnphaseDeveloperAppCredentials +from .enphase_join_config import EnphaseJoinConfig +from .enphase_join_config_inline_credentials import EnphaseJoinConfigInlineCredentials +from .enphase_partner_app_credentials import EnphasePartnerAppCredentials +from .enphase_vpp_credentials import EnphaseVPPCredentials +from .enphase_vpp_join_config import EnphaseVPPJoinConfig +from .enphase_vpp_join_config_inline_credentials import EnphaseVPPJoinConfigInlineCredentials +from .franklin_wh_credentials import FranklinWHCredentials +from .get_battery_intervals_response import GetBatteryIntervalsResponse +from .get_battery_response import GetBatteryResponse +from .get_join_session_token_response import GetJoinSessionTokenResponse +from .get_site_battery_control_response import GetSiteBatteryControlResponse +from .get_site_battery_intervals_response import GetSiteBatteryIntervalsResponse +from .get_site_response import GetSiteResponse +from .get_site_solar_inverter_intervals_response import GetSiteSolarInverterIntervalsResponse +from .get_solar_inverter_intervals_response import GetSolarInverterIntervalsResponse +from .get_solar_inverter_response import GetSolarInverterResponse +from .get_vendor_credentials_response import GetVendorCredentialsResponse +from .get_virtual_battery_response import GetVirtualBatteryResponse +from .get_virtual_site_response import GetVirtualSiteResponse +from .get_virtual_solar_inverter_response import GetVirtualSolarInverterResponse +from .hidden_enphase_developer_app_credentials import HiddenEnphaseDeveloperAppCredentials +from .hidden_enphase_partner_app_credentials import HiddenEnphasePartnerAppCredentials +from .hidden_enphase_vpp_credentials import HiddenEnphaseVPPCredentials +from .hidden_franklin_wh_credentials import HiddenFranklinWHCredentials +from .hidden_sma_custom_grant_credentials import HiddenSMACustomGrantCredentials +from .hidden_sma_sandbox_custom_grant_credentials import HiddenSMASandboxCustomGrantCredentials +from .hidden_sma_sandbox_o_auth_credentials import HiddenSMASandboxOAuthCredentials +from .hidden_smao_auth_credentials import HiddenSMAOAuthCredentials +from .hidden_solar_edge_credentials import HiddenSolarEdgeCredentials +from .hidden_solis_credentials import HiddenSolisCredentials +from .hidden_tesla_app_credentials import HiddenTeslaAppCredentials +from .list_batteries_response import ListBatteriesResponse +from .list_batteries_response_errors import ListBatteriesResponseErrors +from .list_site_response_errors import ListSiteResponseErrors +from .list_sites_response import ListSitesResponse +from .list_solar_inverters_response import ListSolarInvertersResponse +from .list_solar_inverters_response_errors import ListSolarInvertersResponseErrors +from .list_vendor_credentials_response import ListVendorCredentialsResponse +from .list_virtual_batteries_response import ListVirtualBatteriesResponse +from .list_virtual_sites_response import ListVirtualSitesResponse +from .list_virtual_solar_inverters_response import ListVirtualSolarInvertersResponse +from .put_site_battery_control_request import PutSiteBatteryControlRequest +from .put_site_battery_control_request_interval import PutSiteBatteryControlRequestInterval +from .put_site_battery_control_response import PutSiteBatteryControlResponse +from .site import Site +from .site_battery_control_command import SiteBatteryControlCommand +from .site_battery_control_priority import SiteBatteryControlPriority +from .site_battery_control_status import SiteBatteryControlStatus +from .site_battery_control_status_interval import SiteBatteryControlStatusInterval +from .site_battery_control_status_interval_site_battery_control_status_interval_command import ( + SiteBatteryControlStatusIntervalSiteBatteryControlStatusIntervalCommand, +) +from .site_battery_interval import SiteBatteryInterval +from .site_bess import SiteBESS +from .site_location import SiteLocation +from .site_solar_inverter_interval import SiteSolarInverterInterval +from .site_summary import SiteSummary +from .sma_custom_grant_credentials import SMACustomGrantCredentials +from .sma_join_config import SMAJoinConfig +from .sma_join_config_inline_credentials import SMAJoinConfigInlineCredentials +from .sma_sandbox_custom_grant_credentials import SMASandboxCustomGrantCredentials +from .sma_sandbox_join_config import SMASandboxJoinConfig +from .sma_sandbox_join_config_inline_credentials import SMASandboxJoinConfigInlineCredentials +from .sma_sandbox_o_auth_credentials import SMASandboxOAuthCredentials +from .smao_auth_credentials import SMAOAuthCredentials +from .solar_edge_credentials import SolarEdgeCredentials +from .solar_inverter import SolarInverter +from .solar_inverter_interval import SolarInverterInterval +from .solar_inverter_lifetime_production import SolarInverterLifetimeProduction +from .solar_inverter_recent_errors_error import SolarInverterRecentErrorsError +from .solar_inverter_recent_errors_info import SolarInverterRecentErrorsInfo +from .solar_inverter_recent_errors_start import SolarInverterRecentErrorsStart +from .solar_inverter_recent_errors_warning import SolarInverterRecentErrorsWarning +from .solar_inverter_recent_production import SolarInverterRecentProduction +from .solar_inverter_summary import SolarInverterSummary +from .solaredge_join_config import SolaredgeJoinConfig +from .solis_credentials import SolisCredentials +from .solis_join_config import SolisJoinConfig +from .stored_credentials_reference import StoredCredentialsReference +from .summary_level import SummaryLevel +from .telsa_join_config_inline_credentials import TelsaJoinConfigInlineCredentials +from .tesla_app_credentials import TeslaAppCredentials +from .tesla_join_config import TeslaJoinConfig +from .update_vendor_credentials_request import UpdateVendorCredentialsRequest +from .update_vendor_credentials_response import UpdateVendorCredentialsResponse +from .vendor import Vendor +from .vendor_credentials import VendorCredentials +from .virtual_battery import VirtualBattery +from .virtual_site import VirtualSite +from .virtual_solar_inverter import VirtualSolarInverter + +__all__ = ( + "Battery", + "BatteryInterval", + "BatteryMode", + "BatteryRecentErrorsError", + "BatteryRecentErrorsInfo", + "BatteryRecentErrorsStart", + "BatteryRecentErrorsWarning", + "BatterySummary", + "CreateJoinSessionRequest", + "CreateJoinSessionResponse", + "CreateVendorCredentialsRequest", + "CreateVendorCredentialsResponse", + "CreateVirtualBatteryRequest", + "CreateVirtualBatteryResponse", + "CreateVirtualSiteRequest", + "CreateVirtualSiteResponse", + "CreateVirtualSolarInverterRequest", + "CreateVirtualSolarInverterResponse", + "EnphaseDeveloperAppCredentials", + "EnphaseJoinConfig", + "EnphaseJoinConfigInlineCredentials", + "EnphasePartnerAppCredentials", + "EnphaseVPPCredentials", + "EnphaseVPPJoinConfig", + "EnphaseVPPJoinConfigInlineCredentials", + "FranklinWHCredentials", + "GetBatteryIntervalsResponse", + "GetBatteryResponse", + "GetJoinSessionTokenResponse", + "GetSiteBatteryControlResponse", + "GetSiteBatteryIntervalsResponse", + "GetSiteResponse", + "GetSiteSolarInverterIntervalsResponse", + "GetSolarInverterIntervalsResponse", + "GetSolarInverterResponse", + "GetVendorCredentialsResponse", + "GetVirtualBatteryResponse", + "GetVirtualSiteResponse", + "GetVirtualSolarInverterResponse", + "HiddenEnphaseDeveloperAppCredentials", + "HiddenEnphasePartnerAppCredentials", + "HiddenEnphaseVPPCredentials", + "HiddenFranklinWHCredentials", + "HiddenSMACustomGrantCredentials", + "HiddenSMAOAuthCredentials", + "HiddenSMASandboxCustomGrantCredentials", + "HiddenSMASandboxOAuthCredentials", + "HiddenSolarEdgeCredentials", + "HiddenSolisCredentials", + "HiddenTeslaAppCredentials", + "ListBatteriesResponse", + "ListBatteriesResponseErrors", + "ListSiteResponseErrors", + "ListSitesResponse", + "ListSolarInvertersResponse", + "ListSolarInvertersResponseErrors", + "ListVendorCredentialsResponse", + "ListVirtualBatteriesResponse", + "ListVirtualSitesResponse", + "ListVirtualSolarInvertersResponse", + "PutSiteBatteryControlRequest", + "PutSiteBatteryControlRequestInterval", + "PutSiteBatteryControlResponse", + "Site", + "SiteBatteryControlCommand", + "SiteBatteryControlPriority", + "SiteBatteryControlStatus", + "SiteBatteryControlStatusInterval", + "SiteBatteryControlStatusIntervalSiteBatteryControlStatusIntervalCommand", + "SiteBatteryInterval", + "SiteBESS", + "SiteLocation", + "SiteSolarInverterInterval", + "SiteSummary", + "SMACustomGrantCredentials", + "SMAJoinConfig", + "SMAJoinConfigInlineCredentials", + "SMAOAuthCredentials", + "SMASandboxCustomGrantCredentials", + "SMASandboxJoinConfig", + "SMASandboxJoinConfigInlineCredentials", + "SMASandboxOAuthCredentials", + "SolarEdgeCredentials", + "SolaredgeJoinConfig", + "SolarInverter", + "SolarInverterInterval", + "SolarInverterLifetimeProduction", + "SolarInverterRecentErrorsError", + "SolarInverterRecentErrorsInfo", + "SolarInverterRecentErrorsStart", + "SolarInverterRecentErrorsWarning", + "SolarInverterRecentProduction", + "SolarInverterSummary", + "SolisCredentials", + "SolisJoinConfig", + "StoredCredentialsReference", + "SummaryLevel", + "TelsaJoinConfigInlineCredentials", + "TeslaAppCredentials", + "TeslaJoinConfig", + "UpdateVendorCredentialsRequest", + "UpdateVendorCredentialsResponse", + "Vendor", + "VendorCredentials", + "VirtualBattery", + "VirtualSite", + "VirtualSolarInverter", +) diff --git a/derapi/models/battery.py b/derapi/models/battery.py new file mode 100644 index 0000000..6c6120e --- /dev/null +++ b/derapi/models/battery.py @@ -0,0 +1,236 @@ +import datetime +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..models.battery_mode import BatteryMode +from ..models.vendor import Vendor +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.battery_recent_errors_error import BatteryRecentErrorsError + from ..models.battery_recent_errors_info import BatteryRecentErrorsInfo + from ..models.battery_recent_errors_start import BatteryRecentErrorsStart + from ..models.battery_recent_errors_warning import BatteryRecentErrorsWarning + + +T = TypeVar("T", bound="Battery") + + +@_attrs_define +class Battery: + """ + Attributes: + id (str): Battery id + vendor (Vendor): + reported_at (datetime.datetime): Date the request was generated in ISO-8601 format (timezone is always +00:00 + and is always present) + model (str): Model number of Battery + serial_number (str): Manufacturer serial number of the Battery + site_id (str): The Derapi Site ID this Battery is associated with + name (Union[Unset, str]): Customer defined name of the Battery + nameplate_kwh (Union[Unset, float]): The rated storage capacity of the unit + mode (Union[Unset, BatteryMode]): Battery management system mode. Values are Self Consumption - minimize grid + import, Savings - optimizing Battery to save money; usually based on a rate plan, Backup - only use Battery for + grid backup + state_of_charge_percent (Union[Unset, float]): Battery state of charge as a percent of capacity + recent_errors (Union[Unset, List[Union['BatteryRecentErrorsError', 'BatteryRecentErrorsInfo', + 'BatteryRecentErrorsStart', 'BatteryRecentErrorsWarning']]]): Most recent errors, warnings, or info reported by + the manufacturer for this Battery. The key represents the severity level (info/warning/error); the value is a + string description. start is always present and is the last element to be returned. + """ + + id: str + vendor: Vendor + reported_at: datetime.datetime + model: str + serial_number: str + site_id: str + name: Union[Unset, str] = UNSET + nameplate_kwh: Union[Unset, float] = UNSET + mode: Union[Unset, BatteryMode] = UNSET + state_of_charge_percent: Union[Unset, float] = UNSET + recent_errors: Union[ + Unset, + List[ + Union[ + "BatteryRecentErrorsError", + "BatteryRecentErrorsInfo", + "BatteryRecentErrorsStart", + "BatteryRecentErrorsWarning", + ] + ], + ] = UNSET + + def to_dict(self) -> Dict[str, Any]: + from ..models.battery_recent_errors_error import BatteryRecentErrorsError + from ..models.battery_recent_errors_info import BatteryRecentErrorsInfo + from ..models.battery_recent_errors_warning import BatteryRecentErrorsWarning + + id = self.id + + vendor = self.vendor.value + + reported_at = self.reported_at.isoformat() + + model = self.model + + serial_number = self.serial_number + + site_id = self.site_id + + name = self.name + + nameplate_kwh = self.nameplate_kwh + + mode: Union[Unset, str] = UNSET + if not isinstance(self.mode, Unset): + mode = self.mode.value + + state_of_charge_percent = self.state_of_charge_percent + + recent_errors: Union[Unset, List[Dict[str, Any]]] = UNSET + if not isinstance(self.recent_errors, Unset): + recent_errors = [] + for componentsschemas_battery_recent_errors_item_data in self.recent_errors: + componentsschemas_battery_recent_errors_item: Dict[str, Any] + if isinstance(componentsschemas_battery_recent_errors_item_data, BatteryRecentErrorsError): + componentsschemas_battery_recent_errors_item = ( + componentsschemas_battery_recent_errors_item_data.to_dict() + ) + elif isinstance(componentsschemas_battery_recent_errors_item_data, BatteryRecentErrorsWarning): + componentsschemas_battery_recent_errors_item = ( + componentsschemas_battery_recent_errors_item_data.to_dict() + ) + elif isinstance(componentsschemas_battery_recent_errors_item_data, BatteryRecentErrorsInfo): + componentsschemas_battery_recent_errors_item = ( + componentsschemas_battery_recent_errors_item_data.to_dict() + ) + else: + componentsschemas_battery_recent_errors_item = ( + componentsschemas_battery_recent_errors_item_data.to_dict() + ) + + recent_errors.append(componentsschemas_battery_recent_errors_item) + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "vendor": vendor, + "reportedAt": reported_at, + "model": model, + "serialNumber": serial_number, + "siteID": site_id, + } + ) + if name is not UNSET: + field_dict["name"] = name + if nameplate_kwh is not UNSET: + field_dict["nameplateKwh"] = nameplate_kwh + if mode is not UNSET: + field_dict["mode"] = mode + if state_of_charge_percent is not UNSET: + field_dict["stateOfChargePercent"] = state_of_charge_percent + if recent_errors is not UNSET: + field_dict["recentErrors"] = recent_errors + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.battery_recent_errors_error import BatteryRecentErrorsError + from ..models.battery_recent_errors_info import BatteryRecentErrorsInfo + from ..models.battery_recent_errors_start import BatteryRecentErrorsStart + from ..models.battery_recent_errors_warning import BatteryRecentErrorsWarning + + d = src_dict.copy() + id = d.pop("id") + + vendor = Vendor(d.pop("vendor")) + + reported_at = isoparse(d.pop("reportedAt")) + + model = d.pop("model") + + serial_number = d.pop("serialNumber") + + site_id = d.pop("siteID") + + name = d.pop("name", UNSET) + + nameplate_kwh = d.pop("nameplateKwh", UNSET) + + _mode = d.pop("mode", UNSET) + mode: Union[Unset, BatteryMode] + if isinstance(_mode, Unset): + mode = UNSET + else: + mode = BatteryMode(_mode) + + state_of_charge_percent = d.pop("stateOfChargePercent", UNSET) + + recent_errors = [] + _recent_errors = d.pop("recentErrors", UNSET) + for componentsschemas_battery_recent_errors_item_data in _recent_errors or []: + + def _parse_componentsschemas_battery_recent_errors_item( + data: object, + ) -> Union[ + "BatteryRecentErrorsError", + "BatteryRecentErrorsInfo", + "BatteryRecentErrorsStart", + "BatteryRecentErrorsWarning", + ]: + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_battery_recent_errors_item_type_0 = BatteryRecentErrorsError.from_dict(data) + + return componentsschemas_battery_recent_errors_item_type_0 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_battery_recent_errors_item_type_1 = BatteryRecentErrorsWarning.from_dict(data) + + return componentsschemas_battery_recent_errors_item_type_1 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_battery_recent_errors_item_type_2 = BatteryRecentErrorsInfo.from_dict(data) + + return componentsschemas_battery_recent_errors_item_type_2 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + componentsschemas_battery_recent_errors_item_type_3 = BatteryRecentErrorsStart.from_dict(data) + + return componentsschemas_battery_recent_errors_item_type_3 + + componentsschemas_battery_recent_errors_item = _parse_componentsschemas_battery_recent_errors_item( + componentsschemas_battery_recent_errors_item_data + ) + + recent_errors.append(componentsschemas_battery_recent_errors_item) + + battery = cls( + id=id, + vendor=vendor, + reported_at=reported_at, + model=model, + serial_number=serial_number, + site_id=site_id, + name=name, + nameplate_kwh=nameplate_kwh, + mode=mode, + state_of_charge_percent=state_of_charge_percent, + recent_errors=recent_errors, + ) + + return battery diff --git a/derapi/models/battery_interval.py b/derapi/models/battery_interval.py new file mode 100644 index 0000000..b7718db --- /dev/null +++ b/derapi/models/battery_interval.py @@ -0,0 +1,75 @@ +import datetime +from typing import Any, Dict, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="BatteryInterval") + + +@_attrs_define +class BatteryInterval: + """ + Attributes: + charge_kwh (float): kWh into the Battery during the interval + discharge_kwh (float): kWh out of the Battery during the interval + start (datetime.datetime): Interval start in ISO-8601 format + end (datetime.datetime): Interval end in ISO-8601 format + state_of_charge_percent (Union[Unset, float]): average % charge over the interval + """ + + charge_kwh: float + discharge_kwh: float + start: datetime.datetime + end: datetime.datetime + state_of_charge_percent: Union[Unset, float] = UNSET + + def to_dict(self) -> Dict[str, Any]: + charge_kwh = self.charge_kwh + + discharge_kwh = self.discharge_kwh + + start = self.start.isoformat() + + end = self.end.isoformat() + + state_of_charge_percent = self.state_of_charge_percent + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "chargeKwh": charge_kwh, + "dischargeKwh": discharge_kwh, + "start": start, + "end": end, + } + ) + if state_of_charge_percent is not UNSET: + field_dict["stateOfChargePercent"] = state_of_charge_percent + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + charge_kwh = d.pop("chargeKwh") + + discharge_kwh = d.pop("dischargeKwh") + + start = isoparse(d.pop("start")) + + end = isoparse(d.pop("end")) + + state_of_charge_percent = d.pop("stateOfChargePercent", UNSET) + + battery_interval = cls( + charge_kwh=charge_kwh, + discharge_kwh=discharge_kwh, + start=start, + end=end, + state_of_charge_percent=state_of_charge_percent, + ) + + return battery_interval diff --git a/derapi/models/battery_mode.py b/derapi/models/battery_mode.py new file mode 100644 index 0000000..08c5f89 --- /dev/null +++ b/derapi/models/battery_mode.py @@ -0,0 +1,10 @@ +from enum import Enum + + +class BatteryMode(str, Enum): + BACKUP = "Backup" + SAVINGS = "Savings" + SELF_CONSUMPTION = "Self Consumption" + + def __str__(self) -> str: + return str(self.value) diff --git a/derapi/models/battery_recent_errors_error.py b/derapi/models/battery_recent_errors_error.py new file mode 100644 index 0000000..28a40fd --- /dev/null +++ b/derapi/models/battery_recent_errors_error.py @@ -0,0 +1,38 @@ +from typing import Any, Dict, Type, TypeVar + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="BatteryRecentErrorsError") + + +@_attrs_define +class BatteryRecentErrorsError: + """ + Attributes: + error (str): + """ + + error: str + + def to_dict(self) -> Dict[str, Any]: + error = self.error + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "error": error, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + error = d.pop("error") + + battery_recent_errors_error = cls( + error=error, + ) + + return battery_recent_errors_error diff --git a/derapi/models/battery_recent_errors_info.py b/derapi/models/battery_recent_errors_info.py new file mode 100644 index 0000000..1b9ff4f --- /dev/null +++ b/derapi/models/battery_recent_errors_info.py @@ -0,0 +1,38 @@ +from typing import Any, Dict, Type, TypeVar + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="BatteryRecentErrorsInfo") + + +@_attrs_define +class BatteryRecentErrorsInfo: + """ + Attributes: + info (str): + """ + + info: str + + def to_dict(self) -> Dict[str, Any]: + info = self.info + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "info": info, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + info = d.pop("info") + + battery_recent_errors_info = cls( + info=info, + ) + + return battery_recent_errors_info diff --git a/derapi/models/battery_recent_errors_start.py b/derapi/models/battery_recent_errors_start.py new file mode 100644 index 0000000..f4a9d45 --- /dev/null +++ b/derapi/models/battery_recent_errors_start.py @@ -0,0 +1,40 @@ +import datetime +from typing import Any, Dict, Type, TypeVar + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +T = TypeVar("T", bound="BatteryRecentErrorsStart") + + +@_attrs_define +class BatteryRecentErrorsStart: + """ + Attributes: + start (datetime.datetime): The start date of the recent errors log in ISO-8601 format + """ + + start: datetime.datetime + + def to_dict(self) -> Dict[str, Any]: + start = self.start.isoformat() + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "start": start, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + start = isoparse(d.pop("start")) + + battery_recent_errors_start = cls( + start=start, + ) + + return battery_recent_errors_start diff --git a/derapi/models/battery_recent_errors_warning.py b/derapi/models/battery_recent_errors_warning.py new file mode 100644 index 0000000..2c2e485 --- /dev/null +++ b/derapi/models/battery_recent_errors_warning.py @@ -0,0 +1,38 @@ +from typing import Any, Dict, Type, TypeVar + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="BatteryRecentErrorsWarning") + + +@_attrs_define +class BatteryRecentErrorsWarning: + """ + Attributes: + warning (str): + """ + + warning: str + + def to_dict(self) -> Dict[str, Any]: + warning = self.warning + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "warning": warning, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + warning = d.pop("warning") + + battery_recent_errors_warning = cls( + warning=warning, + ) + + return battery_recent_errors_warning diff --git a/derapi/models/battery_summary.py b/derapi/models/battery_summary.py new file mode 100644 index 0000000..b092e8a --- /dev/null +++ b/derapi/models/battery_summary.py @@ -0,0 +1,38 @@ +from typing import Any, Dict, Type, TypeVar + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="BatterySummary") + + +@_attrs_define +class BatterySummary: + """ + Attributes: + id (str): Battery id + """ + + id: str + + def to_dict(self) -> Dict[str, Any]: + id = self.id + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + id = d.pop("id") + + battery_summary = cls( + id=id, + ) + + return battery_summary diff --git a/derapi/models/create_join_session_request.py b/derapi/models/create_join_session_request.py new file mode 100644 index 0000000..908dec4 --- /dev/null +++ b/derapi/models/create_join_session_request.py @@ -0,0 +1,173 @@ +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define + +if TYPE_CHECKING: + from ..models.enphase_join_config import EnphaseJoinConfig + from ..models.enphase_vpp_join_config import EnphaseVPPJoinConfig + from ..models.sma_join_config import SMAJoinConfig + from ..models.sma_sandbox_join_config import SMASandboxJoinConfig + from ..models.solaredge_join_config import SolaredgeJoinConfig + from ..models.solis_join_config import SolisJoinConfig + from ..models.tesla_join_config import TeslaJoinConfig + + +T = TypeVar("T", bound="CreateJoinSessionRequest") + + +@_attrs_define +class CreateJoinSessionRequest: + """ + Attributes: + store_credentials (bool): Whether Derapi should store the credentials received from Join. If enabled, requires + VCM. + vendors (List[Union['EnphaseJoinConfig', 'EnphaseVPPJoinConfig', 'SMAJoinConfig', 'SMASandboxJoinConfig', + 'SolaredgeJoinConfig', 'SolisJoinConfig', 'TeslaJoinConfig']]): Add an object for each vendor that should appear + in the UI + """ + + store_credentials: bool + vendors: List[ + Union[ + "EnphaseJoinConfig", + "EnphaseVPPJoinConfig", + "SMAJoinConfig", + "SMASandboxJoinConfig", + "SolaredgeJoinConfig", + "SolisJoinConfig", + "TeslaJoinConfig", + ] + ] + + def to_dict(self) -> Dict[str, Any]: + from ..models.enphase_join_config import EnphaseJoinConfig + from ..models.enphase_vpp_join_config import EnphaseVPPJoinConfig + from ..models.sma_join_config import SMAJoinConfig + from ..models.sma_sandbox_join_config import SMASandboxJoinConfig + from ..models.solaredge_join_config import SolaredgeJoinConfig + from ..models.solis_join_config import SolisJoinConfig + + store_credentials = self.store_credentials + + vendors = [] + for vendors_item_data in self.vendors: + vendors_item: Dict[str, Any] + if isinstance(vendors_item_data, EnphaseJoinConfig): + vendors_item = vendors_item_data.to_dict() + elif isinstance(vendors_item_data, EnphaseVPPJoinConfig): + vendors_item = vendors_item_data.to_dict() + elif isinstance(vendors_item_data, SMAJoinConfig): + vendors_item = vendors_item_data.to_dict() + elif isinstance(vendors_item_data, SMASandboxJoinConfig): + vendors_item = vendors_item_data.to_dict() + elif isinstance(vendors_item_data, SolaredgeJoinConfig): + vendors_item = vendors_item_data.to_dict() + elif isinstance(vendors_item_data, SolisJoinConfig): + vendors_item = vendors_item_data.to_dict() + else: + vendors_item = vendors_item_data.to_dict() + + vendors.append(vendors_item) + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "storeCredentials": store_credentials, + "vendors": vendors, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.enphase_join_config import EnphaseJoinConfig + from ..models.enphase_vpp_join_config import EnphaseVPPJoinConfig + from ..models.sma_join_config import SMAJoinConfig + from ..models.sma_sandbox_join_config import SMASandboxJoinConfig + from ..models.solaredge_join_config import SolaredgeJoinConfig + from ..models.solis_join_config import SolisJoinConfig + from ..models.tesla_join_config import TeslaJoinConfig + + d = src_dict.copy() + store_credentials = d.pop("storeCredentials") + + vendors = [] + _vendors = d.pop("vendors") + for vendors_item_data in _vendors: + + def _parse_vendors_item( + data: object, + ) -> Union[ + "EnphaseJoinConfig", + "EnphaseVPPJoinConfig", + "SMAJoinConfig", + "SMASandboxJoinConfig", + "SolaredgeJoinConfig", + "SolisJoinConfig", + "TeslaJoinConfig", + ]: + try: + if not isinstance(data, dict): + raise TypeError() + vendors_item_type_0 = EnphaseJoinConfig.from_dict(data) + + return vendors_item_type_0 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + vendors_item_type_1 = EnphaseVPPJoinConfig.from_dict(data) + + return vendors_item_type_1 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + vendors_item_type_2 = SMAJoinConfig.from_dict(data) + + return vendors_item_type_2 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + vendors_item_type_3 = SMASandboxJoinConfig.from_dict(data) + + return vendors_item_type_3 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + vendors_item_type_4 = SolaredgeJoinConfig.from_dict(data) + + return vendors_item_type_4 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + vendors_item_type_5 = SolisJoinConfig.from_dict(data) + + return vendors_item_type_5 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + vendors_item_type_6 = TeslaJoinConfig.from_dict(data) + + return vendors_item_type_6 + + vendors_item = _parse_vendors_item(vendors_item_data) + + vendors.append(vendors_item) + + create_join_session_request = cls( + store_credentials=store_credentials, + vendors=vendors, + ) + + return create_join_session_request diff --git a/derapi/models/create_join_session_response.py b/derapi/models/create_join_session_response.py new file mode 100644 index 0000000..889ac03 --- /dev/null +++ b/derapi/models/create_join_session_response.py @@ -0,0 +1,38 @@ +from typing import Any, Dict, Type, TypeVar + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="CreateJoinSessionResponse") + + +@_attrs_define +class CreateJoinSessionResponse: + """ + Attributes: + session_id (str): session token to pass to Join JS component function createJoin() + """ + + session_id: str + + def to_dict(self) -> Dict[str, Any]: + session_id = self.session_id + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "sessionID": session_id, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + session_id = d.pop("sessionID") + + create_join_session_response = cls( + session_id=session_id, + ) + + return create_join_session_response diff --git a/derapi/models/create_vendor_credentials_request.py b/derapi/models/create_vendor_credentials_request.py new file mode 100644 index 0000000..aa435a7 --- /dev/null +++ b/derapi/models/create_vendor_credentials_request.py @@ -0,0 +1,227 @@ +from typing import TYPE_CHECKING, Any, Dict, Type, TypeVar, Union + +from attrs import define as _attrs_define + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.enphase_developer_app_credentials import EnphaseDeveloperAppCredentials + from ..models.enphase_partner_app_credentials import EnphasePartnerAppCredentials + from ..models.enphase_vpp_credentials import EnphaseVPPCredentials + from ..models.franklin_wh_credentials import FranklinWHCredentials + from ..models.sma_custom_grant_credentials import SMACustomGrantCredentials + from ..models.sma_sandbox_custom_grant_credentials import SMASandboxCustomGrantCredentials + from ..models.sma_sandbox_o_auth_credentials import SMASandboxOAuthCredentials + from ..models.smao_auth_credentials import SMAOAuthCredentials + from ..models.solar_edge_credentials import SolarEdgeCredentials + from ..models.solis_credentials import SolisCredentials + from ..models.tesla_app_credentials import TeslaAppCredentials + + +T = TypeVar("T", bound="CreateVendorCredentialsRequest") + + +@_attrs_define +class CreateVendorCredentialsRequest: + """ + Attributes: + credentials (Union['EnphaseDeveloperAppCredentials', 'EnphasePartnerAppCredentials', 'EnphaseVPPCredentials', + 'FranklinWHCredentials', 'SMACustomGrantCredentials', 'SMAOAuthCredentials', 'SMASandboxCustomGrantCredentials', + 'SMASandboxOAuthCredentials', 'SolarEdgeCredentials', 'SolisCredentials', 'TeslaAppCredentials']): Credentials + for a given vendor. + name (Union[Unset, str]): The name of the vendor credentials; inferred if not provided. + """ + + credentials: Union[ + "EnphaseDeveloperAppCredentials", + "EnphasePartnerAppCredentials", + "EnphaseVPPCredentials", + "FranklinWHCredentials", + "SMACustomGrantCredentials", + "SMAOAuthCredentials", + "SMASandboxCustomGrantCredentials", + "SMASandboxOAuthCredentials", + "SolarEdgeCredentials", + "SolisCredentials", + "TeslaAppCredentials", + ] + name: Union[Unset, str] = UNSET + + def to_dict(self) -> Dict[str, Any]: + from ..models.enphase_developer_app_credentials import EnphaseDeveloperAppCredentials + from ..models.enphase_partner_app_credentials import EnphasePartnerAppCredentials + from ..models.enphase_vpp_credentials import EnphaseVPPCredentials + from ..models.franklin_wh_credentials import FranklinWHCredentials + from ..models.sma_custom_grant_credentials import SMACustomGrantCredentials + from ..models.sma_sandbox_custom_grant_credentials import SMASandboxCustomGrantCredentials + from ..models.sma_sandbox_o_auth_credentials import SMASandboxOAuthCredentials + from ..models.smao_auth_credentials import SMAOAuthCredentials + from ..models.solar_edge_credentials import SolarEdgeCredentials + from ..models.solis_credentials import SolisCredentials + + credentials: Dict[str, Any] + if isinstance(self.credentials, EnphasePartnerAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, EnphaseDeveloperAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, EnphaseVPPCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, FranklinWHCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMACustomGrantCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMAOAuthCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMASandboxCustomGrantCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMASandboxOAuthCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SolarEdgeCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SolisCredentials): + credentials = self.credentials.to_dict() + else: + credentials = self.credentials.to_dict() + + name = self.name + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "credentials": credentials, + } + ) + if name is not UNSET: + field_dict["name"] = name + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.enphase_developer_app_credentials import EnphaseDeveloperAppCredentials + from ..models.enphase_partner_app_credentials import EnphasePartnerAppCredentials + from ..models.enphase_vpp_credentials import EnphaseVPPCredentials + from ..models.franklin_wh_credentials import FranklinWHCredentials + from ..models.sma_custom_grant_credentials import SMACustomGrantCredentials + from ..models.sma_sandbox_custom_grant_credentials import SMASandboxCustomGrantCredentials + from ..models.sma_sandbox_o_auth_credentials import SMASandboxOAuthCredentials + from ..models.smao_auth_credentials import SMAOAuthCredentials + from ..models.solar_edge_credentials import SolarEdgeCredentials + from ..models.solis_credentials import SolisCredentials + from ..models.tesla_app_credentials import TeslaAppCredentials + + d = src_dict.copy() + + def _parse_credentials( + data: object, + ) -> Union[ + "EnphaseDeveloperAppCredentials", + "EnphasePartnerAppCredentials", + "EnphaseVPPCredentials", + "FranklinWHCredentials", + "SMACustomGrantCredentials", + "SMAOAuthCredentials", + "SMASandboxCustomGrantCredentials", + "SMASandboxOAuthCredentials", + "SolarEdgeCredentials", + "SolisCredentials", + "TeslaAppCredentials", + ]: + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_0 = EnphasePartnerAppCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_0 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_1 = EnphaseDeveloperAppCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_1 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_2 = EnphaseVPPCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_2 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_3 = FranklinWHCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_3 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_4 = SMACustomGrantCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_4 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_5 = SMAOAuthCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_5 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_6 = SMASandboxCustomGrantCredentials.from_dict( + data + ) + + return componentsschemas_vendor_credentials_credentials_type_6 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_7 = SMASandboxOAuthCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_7 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_8 = SolarEdgeCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_8 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_9 = SolisCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_9 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_10 = TeslaAppCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_10 + + credentials = _parse_credentials(d.pop("credentials")) + + name = d.pop("name", UNSET) + + create_vendor_credentials_request = cls( + credentials=credentials, + name=name, + ) + + return create_vendor_credentials_request diff --git a/derapi/models/create_vendor_credentials_response.py b/derapi/models/create_vendor_credentials_response.py new file mode 100644 index 0000000..752dd15 --- /dev/null +++ b/derapi/models/create_vendor_credentials_response.py @@ -0,0 +1,420 @@ +from typing import TYPE_CHECKING, Any, Dict, Type, TypeVar, Union + +from attrs import define as _attrs_define + +if TYPE_CHECKING: + from ..models.enphase_developer_app_credentials import EnphaseDeveloperAppCredentials + from ..models.enphase_partner_app_credentials import EnphasePartnerAppCredentials + from ..models.enphase_vpp_credentials import EnphaseVPPCredentials + from ..models.franklin_wh_credentials import FranklinWHCredentials + from ..models.hidden_enphase_developer_app_credentials import HiddenEnphaseDeveloperAppCredentials + from ..models.hidden_enphase_partner_app_credentials import HiddenEnphasePartnerAppCredentials + from ..models.hidden_enphase_vpp_credentials import HiddenEnphaseVPPCredentials + from ..models.hidden_franklin_wh_credentials import HiddenFranklinWHCredentials + from ..models.hidden_sma_custom_grant_credentials import HiddenSMACustomGrantCredentials + from ..models.hidden_sma_sandbox_custom_grant_credentials import HiddenSMASandboxCustomGrantCredentials + from ..models.hidden_sma_sandbox_o_auth_credentials import HiddenSMASandboxOAuthCredentials + from ..models.hidden_smao_auth_credentials import HiddenSMAOAuthCredentials + from ..models.hidden_solar_edge_credentials import HiddenSolarEdgeCredentials + from ..models.hidden_solis_credentials import HiddenSolisCredentials + from ..models.hidden_tesla_app_credentials import HiddenTeslaAppCredentials + from ..models.sma_custom_grant_credentials import SMACustomGrantCredentials + from ..models.sma_sandbox_custom_grant_credentials import SMASandboxCustomGrantCredentials + from ..models.sma_sandbox_o_auth_credentials import SMASandboxOAuthCredentials + from ..models.smao_auth_credentials import SMAOAuthCredentials + from ..models.solar_edge_credentials import SolarEdgeCredentials + from ..models.solis_credentials import SolisCredentials + from ..models.tesla_app_credentials import TeslaAppCredentials + + +T = TypeVar("T", bound="CreateVendorCredentialsResponse") + + +@_attrs_define +class CreateVendorCredentialsResponse: + """Vendor credentials which may or may not be hidden. + + Attributes: + id (str): ID for the vendor credentials + name (str): The name of the vendor credentials; inferred if not provided. + credentials (Union['EnphaseDeveloperAppCredentials', 'EnphasePartnerAppCredentials', 'EnphaseVPPCredentials', + 'FranklinWHCredentials', 'HiddenEnphaseDeveloperAppCredentials', 'HiddenEnphasePartnerAppCredentials', + 'HiddenEnphaseVPPCredentials', 'HiddenFranklinWHCredentials', 'HiddenSMACustomGrantCredentials', + 'HiddenSMAOAuthCredentials', 'HiddenSMASandboxCustomGrantCredentials', 'HiddenSMASandboxOAuthCredentials', + 'HiddenSolarEdgeCredentials', 'HiddenSolisCredentials', 'HiddenTeslaAppCredentials', + 'SMACustomGrantCredentials', 'SMAOAuthCredentials', 'SMASandboxCustomGrantCredentials', + 'SMASandboxOAuthCredentials', 'SolarEdgeCredentials', 'SolisCredentials', 'TeslaAppCredentials']): + """ + + id: str + name: str + credentials: Union[ + "EnphaseDeveloperAppCredentials", + "EnphasePartnerAppCredentials", + "EnphaseVPPCredentials", + "FranklinWHCredentials", + "HiddenEnphaseDeveloperAppCredentials", + "HiddenEnphasePartnerAppCredentials", + "HiddenEnphaseVPPCredentials", + "HiddenFranklinWHCredentials", + "HiddenSMACustomGrantCredentials", + "HiddenSMAOAuthCredentials", + "HiddenSMASandboxCustomGrantCredentials", + "HiddenSMASandboxOAuthCredentials", + "HiddenSolarEdgeCredentials", + "HiddenSolisCredentials", + "HiddenTeslaAppCredentials", + "SMACustomGrantCredentials", + "SMAOAuthCredentials", + "SMASandboxCustomGrantCredentials", + "SMASandboxOAuthCredentials", + "SolarEdgeCredentials", + "SolisCredentials", + "TeslaAppCredentials", + ] + + def to_dict(self) -> Dict[str, Any]: + from ..models.enphase_developer_app_credentials import EnphaseDeveloperAppCredentials + from ..models.enphase_partner_app_credentials import EnphasePartnerAppCredentials + from ..models.enphase_vpp_credentials import EnphaseVPPCredentials + from ..models.franklin_wh_credentials import FranklinWHCredentials + from ..models.hidden_enphase_developer_app_credentials import HiddenEnphaseDeveloperAppCredentials + from ..models.hidden_enphase_partner_app_credentials import HiddenEnphasePartnerAppCredentials + from ..models.hidden_enphase_vpp_credentials import HiddenEnphaseVPPCredentials + from ..models.hidden_franklin_wh_credentials import HiddenFranklinWHCredentials + from ..models.hidden_sma_custom_grant_credentials import HiddenSMACustomGrantCredentials + from ..models.hidden_sma_sandbox_custom_grant_credentials import HiddenSMASandboxCustomGrantCredentials + from ..models.hidden_sma_sandbox_o_auth_credentials import HiddenSMASandboxOAuthCredentials + from ..models.hidden_smao_auth_credentials import HiddenSMAOAuthCredentials + from ..models.hidden_solar_edge_credentials import HiddenSolarEdgeCredentials + from ..models.hidden_solis_credentials import HiddenSolisCredentials + from ..models.hidden_tesla_app_credentials import HiddenTeslaAppCredentials + from ..models.sma_custom_grant_credentials import SMACustomGrantCredentials + from ..models.sma_sandbox_custom_grant_credentials import SMASandboxCustomGrantCredentials + from ..models.sma_sandbox_o_auth_credentials import SMASandboxOAuthCredentials + from ..models.smao_auth_credentials import SMAOAuthCredentials + from ..models.solar_edge_credentials import SolarEdgeCredentials + from ..models.solis_credentials import SolisCredentials + + id = self.id + + name = self.name + + credentials: Dict[str, Any] + if isinstance(self.credentials, HiddenEnphaseDeveloperAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenEnphasePartnerAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenEnphaseVPPCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenFranklinWHCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSMACustomGrantCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSMAOAuthCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSMASandboxCustomGrantCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSMASandboxOAuthCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSolarEdgeCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSolisCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenTeslaAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, EnphasePartnerAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, EnphaseDeveloperAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, EnphaseVPPCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, FranklinWHCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMACustomGrantCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMAOAuthCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMASandboxCustomGrantCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMASandboxOAuthCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SolarEdgeCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SolisCredentials): + credentials = self.credentials.to_dict() + else: + credentials = self.credentials.to_dict() + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "name": name, + "credentials": credentials, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.enphase_developer_app_credentials import EnphaseDeveloperAppCredentials + from ..models.enphase_partner_app_credentials import EnphasePartnerAppCredentials + from ..models.enphase_vpp_credentials import EnphaseVPPCredentials + from ..models.franklin_wh_credentials import FranklinWHCredentials + from ..models.hidden_enphase_developer_app_credentials import HiddenEnphaseDeveloperAppCredentials + from ..models.hidden_enphase_partner_app_credentials import HiddenEnphasePartnerAppCredentials + from ..models.hidden_enphase_vpp_credentials import HiddenEnphaseVPPCredentials + from ..models.hidden_franklin_wh_credentials import HiddenFranklinWHCredentials + from ..models.hidden_sma_custom_grant_credentials import HiddenSMACustomGrantCredentials + from ..models.hidden_sma_sandbox_custom_grant_credentials import HiddenSMASandboxCustomGrantCredentials + from ..models.hidden_sma_sandbox_o_auth_credentials import HiddenSMASandboxOAuthCredentials + from ..models.hidden_smao_auth_credentials import HiddenSMAOAuthCredentials + from ..models.hidden_solar_edge_credentials import HiddenSolarEdgeCredentials + from ..models.hidden_solis_credentials import HiddenSolisCredentials + from ..models.hidden_tesla_app_credentials import HiddenTeslaAppCredentials + from ..models.sma_custom_grant_credentials import SMACustomGrantCredentials + from ..models.sma_sandbox_custom_grant_credentials import SMASandboxCustomGrantCredentials + from ..models.sma_sandbox_o_auth_credentials import SMASandboxOAuthCredentials + from ..models.smao_auth_credentials import SMAOAuthCredentials + from ..models.solar_edge_credentials import SolarEdgeCredentials + from ..models.solis_credentials import SolisCredentials + from ..models.tesla_app_credentials import TeslaAppCredentials + + d = src_dict.copy() + id = d.pop("id") + + name = d.pop("name") + + def _parse_credentials( + data: object, + ) -> Union[ + "EnphaseDeveloperAppCredentials", + "EnphasePartnerAppCredentials", + "EnphaseVPPCredentials", + "FranklinWHCredentials", + "HiddenEnphaseDeveloperAppCredentials", + "HiddenEnphasePartnerAppCredentials", + "HiddenEnphaseVPPCredentials", + "HiddenFranklinWHCredentials", + "HiddenSMACustomGrantCredentials", + "HiddenSMAOAuthCredentials", + "HiddenSMASandboxCustomGrantCredentials", + "HiddenSMASandboxOAuthCredentials", + "HiddenSolarEdgeCredentials", + "HiddenSolisCredentials", + "HiddenTeslaAppCredentials", + "SMACustomGrantCredentials", + "SMAOAuthCredentials", + "SMASandboxCustomGrantCredentials", + "SMASandboxOAuthCredentials", + "SolarEdgeCredentials", + "SolisCredentials", + "TeslaAppCredentials", + ]: + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_0 = ( + HiddenEnphaseDeveloperAppCredentials.from_dict(data) + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_0 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_1 = ( + HiddenEnphasePartnerAppCredentials.from_dict(data) + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_1 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_2 = HiddenEnphaseVPPCredentials.from_dict( + data + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_2 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_3 = HiddenFranklinWHCredentials.from_dict( + data + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_3 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_4 = ( + HiddenSMACustomGrantCredentials.from_dict(data) + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_4 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_5 = HiddenSMAOAuthCredentials.from_dict( + data + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_5 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_6 = ( + HiddenSMASandboxCustomGrantCredentials.from_dict(data) + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_6 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_7 = ( + HiddenSMASandboxOAuthCredentials.from_dict(data) + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_7 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_8 = HiddenSolarEdgeCredentials.from_dict( + data + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_8 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_9 = HiddenSolisCredentials.from_dict(data) + + return componentsschemas_hidden_vendor_credentials_credentials_type_9 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_10 = HiddenTeslaAppCredentials.from_dict( + data + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_10 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_0 = EnphasePartnerAppCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_0 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_1 = EnphaseDeveloperAppCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_1 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_2 = EnphaseVPPCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_2 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_3 = FranklinWHCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_3 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_4 = SMACustomGrantCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_4 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_5 = SMAOAuthCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_5 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_6 = SMASandboxCustomGrantCredentials.from_dict( + data + ) + + return componentsschemas_vendor_credentials_credentials_type_6 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_7 = SMASandboxOAuthCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_7 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_8 = SolarEdgeCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_8 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_9 = SolisCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_9 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_10 = TeslaAppCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_10 + + credentials = _parse_credentials(d.pop("credentials")) + + create_vendor_credentials_response = cls( + id=id, + name=name, + credentials=credentials, + ) + + return create_vendor_credentials_response diff --git a/derapi/models/create_virtual_battery_request.py b/derapi/models/create_virtual_battery_request.py new file mode 100644 index 0000000..841395b --- /dev/null +++ b/derapi/models/create_virtual_battery_request.py @@ -0,0 +1,122 @@ +import datetime +from typing import Any, Dict, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..models.battery_mode import BatteryMode +from ..types import UNSET, Unset + +T = TypeVar("T", bound="CreateVirtualBatteryRequest") + + +@_attrs_define +class CreateVirtualBatteryRequest: + """Fields the user would like to provide. Omitted ones will be inferred. + + Attributes: + name (Union[Unset, str]): Customer defined name of the Battery + site_id (Union[Unset, str]): The Derapi Site ID this Battery is associated with + reported_at (Union[Unset, datetime.datetime]): Date the request was generated in ISO-8601 format (timezone is + always +00:00 and is always present) + model (Union[Unset, str]): Model number of Battery + serial_number (Union[Unset, str]): Manufacturer serial number of the Battery + nameplate_kwh (Union[Unset, float]): The rated storage capacity of the unit + mode (Union[Unset, BatteryMode]): Battery management system mode. Values are Self Consumption - minimize grid + import, Savings - optimizing Battery to save money; usually based on a rate plan, Backup - only use Battery for + grid backup + state_of_charge_percent (Union[Unset, float]): Battery state of charge as a percent of capacity + """ + + name: Union[Unset, str] = UNSET + site_id: Union[Unset, str] = UNSET + reported_at: Union[Unset, datetime.datetime] = UNSET + model: Union[Unset, str] = UNSET + serial_number: Union[Unset, str] = UNSET + nameplate_kwh: Union[Unset, float] = UNSET + mode: Union[Unset, BatteryMode] = UNSET + state_of_charge_percent: Union[Unset, float] = UNSET + + def to_dict(self) -> Dict[str, Any]: + name = self.name + + site_id = self.site_id + + reported_at: Union[Unset, str] = UNSET + if not isinstance(self.reported_at, Unset): + reported_at = self.reported_at.isoformat() + + model = self.model + + serial_number = self.serial_number + + nameplate_kwh = self.nameplate_kwh + + mode: Union[Unset, str] = UNSET + if not isinstance(self.mode, Unset): + mode = self.mode.value + + state_of_charge_percent = self.state_of_charge_percent + + field_dict: Dict[str, Any] = {} + field_dict.update({}) + if name is not UNSET: + field_dict["name"] = name + if site_id is not UNSET: + field_dict["siteID"] = site_id + if reported_at is not UNSET: + field_dict["reportedAt"] = reported_at + if model is not UNSET: + field_dict["model"] = model + if serial_number is not UNSET: + field_dict["serialNumber"] = serial_number + if nameplate_kwh is not UNSET: + field_dict["nameplateKwh"] = nameplate_kwh + if mode is not UNSET: + field_dict["mode"] = mode + if state_of_charge_percent is not UNSET: + field_dict["stateOfChargePercent"] = state_of_charge_percent + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + name = d.pop("name", UNSET) + + site_id = d.pop("siteID", UNSET) + + _reported_at = d.pop("reportedAt", UNSET) + reported_at: Union[Unset, datetime.datetime] + if isinstance(_reported_at, Unset): + reported_at = UNSET + else: + reported_at = isoparse(_reported_at) + + model = d.pop("model", UNSET) + + serial_number = d.pop("serialNumber", UNSET) + + nameplate_kwh = d.pop("nameplateKwh", UNSET) + + _mode = d.pop("mode", UNSET) + mode: Union[Unset, BatteryMode] + if isinstance(_mode, Unset): + mode = UNSET + else: + mode = BatteryMode(_mode) + + state_of_charge_percent = d.pop("stateOfChargePercent", UNSET) + + create_virtual_battery_request = cls( + name=name, + site_id=site_id, + reported_at=reported_at, + model=model, + serial_number=serial_number, + nameplate_kwh=nameplate_kwh, + mode=mode, + state_of_charge_percent=state_of_charge_percent, + ) + + return create_virtual_battery_request diff --git a/derapi/models/create_virtual_battery_response.py b/derapi/models/create_virtual_battery_response.py new file mode 100644 index 0000000..acc95be --- /dev/null +++ b/derapi/models/create_virtual_battery_response.py @@ -0,0 +1,236 @@ +import datetime +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..models.battery_mode import BatteryMode +from ..models.vendor import Vendor +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.battery_recent_errors_error import BatteryRecentErrorsError + from ..models.battery_recent_errors_info import BatteryRecentErrorsInfo + from ..models.battery_recent_errors_start import BatteryRecentErrorsStart + from ..models.battery_recent_errors_warning import BatteryRecentErrorsWarning + + +T = TypeVar("T", bound="CreateVirtualBatteryResponse") + + +@_attrs_define +class CreateVirtualBatteryResponse: + """ + Attributes: + id (str): Battery id + vendor (Vendor): + reported_at (datetime.datetime): Date the request was generated in ISO-8601 format (timezone is always +00:00 + and is always present) + model (str): Model number of Battery + serial_number (str): Manufacturer serial number of the Battery + site_id (str): The Derapi Site ID this Battery is associated with + name (Union[Unset, str]): Customer defined name of the Battery + nameplate_kwh (Union[Unset, float]): The rated storage capacity of the unit + mode (Union[Unset, BatteryMode]): Battery management system mode. Values are Self Consumption - minimize grid + import, Savings - optimizing Battery to save money; usually based on a rate plan, Backup - only use Battery for + grid backup + state_of_charge_percent (Union[Unset, float]): Battery state of charge as a percent of capacity + recent_errors (Union[Unset, List[Union['BatteryRecentErrorsError', 'BatteryRecentErrorsInfo', + 'BatteryRecentErrorsStart', 'BatteryRecentErrorsWarning']]]): Most recent errors, warnings, or info reported by + the manufacturer for this Battery. The key represents the severity level (info/warning/error); the value is a + string description. start is always present and is the last element to be returned. + """ + + id: str + vendor: Vendor + reported_at: datetime.datetime + model: str + serial_number: str + site_id: str + name: Union[Unset, str] = UNSET + nameplate_kwh: Union[Unset, float] = UNSET + mode: Union[Unset, BatteryMode] = UNSET + state_of_charge_percent: Union[Unset, float] = UNSET + recent_errors: Union[ + Unset, + List[ + Union[ + "BatteryRecentErrorsError", + "BatteryRecentErrorsInfo", + "BatteryRecentErrorsStart", + "BatteryRecentErrorsWarning", + ] + ], + ] = UNSET + + def to_dict(self) -> Dict[str, Any]: + from ..models.battery_recent_errors_error import BatteryRecentErrorsError + from ..models.battery_recent_errors_info import BatteryRecentErrorsInfo + from ..models.battery_recent_errors_warning import BatteryRecentErrorsWarning + + id = self.id + + vendor = self.vendor.value + + reported_at = self.reported_at.isoformat() + + model = self.model + + serial_number = self.serial_number + + site_id = self.site_id + + name = self.name + + nameplate_kwh = self.nameplate_kwh + + mode: Union[Unset, str] = UNSET + if not isinstance(self.mode, Unset): + mode = self.mode.value + + state_of_charge_percent = self.state_of_charge_percent + + recent_errors: Union[Unset, List[Dict[str, Any]]] = UNSET + if not isinstance(self.recent_errors, Unset): + recent_errors = [] + for componentsschemas_battery_recent_errors_item_data in self.recent_errors: + componentsschemas_battery_recent_errors_item: Dict[str, Any] + if isinstance(componentsschemas_battery_recent_errors_item_data, BatteryRecentErrorsError): + componentsschemas_battery_recent_errors_item = ( + componentsschemas_battery_recent_errors_item_data.to_dict() + ) + elif isinstance(componentsschemas_battery_recent_errors_item_data, BatteryRecentErrorsWarning): + componentsschemas_battery_recent_errors_item = ( + componentsschemas_battery_recent_errors_item_data.to_dict() + ) + elif isinstance(componentsschemas_battery_recent_errors_item_data, BatteryRecentErrorsInfo): + componentsschemas_battery_recent_errors_item = ( + componentsschemas_battery_recent_errors_item_data.to_dict() + ) + else: + componentsschemas_battery_recent_errors_item = ( + componentsschemas_battery_recent_errors_item_data.to_dict() + ) + + recent_errors.append(componentsschemas_battery_recent_errors_item) + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "vendor": vendor, + "reportedAt": reported_at, + "model": model, + "serialNumber": serial_number, + "siteID": site_id, + } + ) + if name is not UNSET: + field_dict["name"] = name + if nameplate_kwh is not UNSET: + field_dict["nameplateKwh"] = nameplate_kwh + if mode is not UNSET: + field_dict["mode"] = mode + if state_of_charge_percent is not UNSET: + field_dict["stateOfChargePercent"] = state_of_charge_percent + if recent_errors is not UNSET: + field_dict["recentErrors"] = recent_errors + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.battery_recent_errors_error import BatteryRecentErrorsError + from ..models.battery_recent_errors_info import BatteryRecentErrorsInfo + from ..models.battery_recent_errors_start import BatteryRecentErrorsStart + from ..models.battery_recent_errors_warning import BatteryRecentErrorsWarning + + d = src_dict.copy() + id = d.pop("id") + + vendor = Vendor(d.pop("vendor")) + + reported_at = isoparse(d.pop("reportedAt")) + + model = d.pop("model") + + serial_number = d.pop("serialNumber") + + site_id = d.pop("siteID") + + name = d.pop("name", UNSET) + + nameplate_kwh = d.pop("nameplateKwh", UNSET) + + _mode = d.pop("mode", UNSET) + mode: Union[Unset, BatteryMode] + if isinstance(_mode, Unset): + mode = UNSET + else: + mode = BatteryMode(_mode) + + state_of_charge_percent = d.pop("stateOfChargePercent", UNSET) + + recent_errors = [] + _recent_errors = d.pop("recentErrors", UNSET) + for componentsschemas_battery_recent_errors_item_data in _recent_errors or []: + + def _parse_componentsschemas_battery_recent_errors_item( + data: object, + ) -> Union[ + "BatteryRecentErrorsError", + "BatteryRecentErrorsInfo", + "BatteryRecentErrorsStart", + "BatteryRecentErrorsWarning", + ]: + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_battery_recent_errors_item_type_0 = BatteryRecentErrorsError.from_dict(data) + + return componentsschemas_battery_recent_errors_item_type_0 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_battery_recent_errors_item_type_1 = BatteryRecentErrorsWarning.from_dict(data) + + return componentsschemas_battery_recent_errors_item_type_1 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_battery_recent_errors_item_type_2 = BatteryRecentErrorsInfo.from_dict(data) + + return componentsschemas_battery_recent_errors_item_type_2 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + componentsschemas_battery_recent_errors_item_type_3 = BatteryRecentErrorsStart.from_dict(data) + + return componentsschemas_battery_recent_errors_item_type_3 + + componentsschemas_battery_recent_errors_item = _parse_componentsschemas_battery_recent_errors_item( + componentsschemas_battery_recent_errors_item_data + ) + + recent_errors.append(componentsschemas_battery_recent_errors_item) + + create_virtual_battery_response = cls( + id=id, + vendor=vendor, + reported_at=reported_at, + model=model, + serial_number=serial_number, + site_id=site_id, + name=name, + nameplate_kwh=nameplate_kwh, + mode=mode, + state_of_charge_percent=state_of_charge_percent, + recent_errors=recent_errors, + ) + + return create_virtual_battery_response diff --git a/derapi/models/create_virtual_site_request.py b/derapi/models/create_virtual_site_request.py new file mode 100644 index 0000000..9f74509 --- /dev/null +++ b/derapi/models/create_virtual_site_request.py @@ -0,0 +1,90 @@ +import datetime +from typing import TYPE_CHECKING, Any, Dict, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.site_location import SiteLocation + + +T = TypeVar("T", bound="CreateVirtualSiteRequest") + + +@_attrs_define +class CreateVirtualSiteRequest: + """Fields the user would like to provide. Omitted ones will be inferred. + + Attributes: + name (Union[Unset, str]): Customer defined name of the Site + location (Union[Unset, SiteLocation]): The location of this Solar Inverter in lat/lon coordinates + location_utc_offset (Union[Unset, float]): UTC Offset in hours; positive values represent locations East of UTC. + Please note this field will soon be deprecated, please use `timezone` instead. + operational_since (Union[Unset, datetime.datetime]): The date the Site became operational or received permission + to operate. Sometimes absent for Solaredge. + """ + + name: Union[Unset, str] = UNSET + location: Union[Unset, "SiteLocation"] = UNSET + location_utc_offset: Union[Unset, float] = UNSET + operational_since: Union[Unset, datetime.datetime] = UNSET + + def to_dict(self) -> Dict[str, Any]: + name = self.name + + location: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.location, Unset): + location = self.location.to_dict() + + location_utc_offset = self.location_utc_offset + + operational_since: Union[Unset, str] = UNSET + if not isinstance(self.operational_since, Unset): + operational_since = self.operational_since.isoformat() + + field_dict: Dict[str, Any] = {} + field_dict.update({}) + if name is not UNSET: + field_dict["name"] = name + if location is not UNSET: + field_dict["location"] = location + if location_utc_offset is not UNSET: + field_dict["locationUTCOffset"] = location_utc_offset + if operational_since is not UNSET: + field_dict["operationalSince"] = operational_since + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.site_location import SiteLocation + + d = src_dict.copy() + name = d.pop("name", UNSET) + + _location = d.pop("location", UNSET) + location: Union[Unset, SiteLocation] + if isinstance(_location, Unset): + location = UNSET + else: + location = SiteLocation.from_dict(_location) + + location_utc_offset = d.pop("locationUTCOffset", UNSET) + + _operational_since = d.pop("operationalSince", UNSET) + operational_since: Union[Unset, datetime.datetime] + if isinstance(_operational_since, Unset): + operational_since = UNSET + else: + operational_since = isoparse(_operational_since) + + create_virtual_site_request = cls( + name=name, + location=location, + location_utc_offset=location_utc_offset, + operational_since=operational_since, + ) + + return create_virtual_site_request diff --git a/derapi/models/create_virtual_site_response.py b/derapi/models/create_virtual_site_response.py new file mode 100644 index 0000000..992d819 --- /dev/null +++ b/derapi/models/create_virtual_site_response.py @@ -0,0 +1,163 @@ +import datetime +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..models.vendor import Vendor +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.battery_summary import BatterySummary + from ..models.site_bess import SiteBESS + from ..models.site_location import SiteLocation + from ..models.solar_inverter_summary import SolarInverterSummary + + +T = TypeVar("T", bound="CreateVirtualSiteResponse") + + +@_attrs_define +class CreateVirtualSiteResponse: + """ + Attributes: + id (str): the ID for the Site + vendor (Vendor): + name (str): Customer defined name of the Site + location_utc_offset (float): UTC Offset in hours; positive values represent locations East of UTC. Please note + this field will soon be deprecated, please use `timezone` instead. + batteries (List['BatterySummary']): List of Battery IDs associated with this Site + solar_inverters (List['SolarInverterSummary']): List of Solar Inverter IDs associated with this Site + location (Union[Unset, SiteLocation]): The location of this Solar Inverter in lat/lon coordinates + operational_since (Union[Unset, datetime.datetime]): The date the Site became operational or received permission + to operate. Sometimes absent for Solaredge. + bess (Union[Unset, SiteBESS]): For Sites with Batteries this key is present + """ + + id: str + vendor: Vendor + name: str + location_utc_offset: float + batteries: List["BatterySummary"] + solar_inverters: List["SolarInverterSummary"] + location: Union[Unset, "SiteLocation"] = UNSET + operational_since: Union[Unset, datetime.datetime] = UNSET + bess: Union[Unset, "SiteBESS"] = UNSET + + def to_dict(self) -> Dict[str, Any]: + id = self.id + + vendor = self.vendor.value + + name = self.name + + location_utc_offset = self.location_utc_offset + + batteries = [] + for componentsschemas_site_batteries_item_data in self.batteries: + componentsschemas_site_batteries_item = componentsschemas_site_batteries_item_data.to_dict() + batteries.append(componentsschemas_site_batteries_item) + + solar_inverters = [] + for componentsschemas_site_solar_inverters_item_data in self.solar_inverters: + componentsschemas_site_solar_inverters_item = componentsschemas_site_solar_inverters_item_data.to_dict() + solar_inverters.append(componentsschemas_site_solar_inverters_item) + + location: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.location, Unset): + location = self.location.to_dict() + + operational_since: Union[Unset, str] = UNSET + if not isinstance(self.operational_since, Unset): + operational_since = self.operational_since.isoformat() + + bess: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.bess, Unset): + bess = self.bess.to_dict() + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "vendor": vendor, + "name": name, + "locationUTCOffset": location_utc_offset, + "batteries": batteries, + "solarInverters": solar_inverters, + } + ) + if location is not UNSET: + field_dict["location"] = location + if operational_since is not UNSET: + field_dict["operationalSince"] = operational_since + if bess is not UNSET: + field_dict["bess"] = bess + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.battery_summary import BatterySummary + from ..models.site_bess import SiteBESS + from ..models.site_location import SiteLocation + from ..models.solar_inverter_summary import SolarInverterSummary + + d = src_dict.copy() + id = d.pop("id") + + vendor = Vendor(d.pop("vendor")) + + name = d.pop("name") + + location_utc_offset = d.pop("locationUTCOffset") + + batteries = [] + _batteries = d.pop("batteries") + for componentsschemas_site_batteries_item_data in _batteries: + componentsschemas_site_batteries_item = BatterySummary.from_dict(componentsschemas_site_batteries_item_data) + + batteries.append(componentsschemas_site_batteries_item) + + solar_inverters = [] + _solar_inverters = d.pop("solarInverters") + for componentsschemas_site_solar_inverters_item_data in _solar_inverters: + componentsschemas_site_solar_inverters_item = SolarInverterSummary.from_dict( + componentsschemas_site_solar_inverters_item_data + ) + + solar_inverters.append(componentsschemas_site_solar_inverters_item) + + _location = d.pop("location", UNSET) + location: Union[Unset, SiteLocation] + if isinstance(_location, Unset): + location = UNSET + else: + location = SiteLocation.from_dict(_location) + + _operational_since = d.pop("operationalSince", UNSET) + operational_since: Union[Unset, datetime.datetime] + if isinstance(_operational_since, Unset): + operational_since = UNSET + else: + operational_since = isoparse(_operational_since) + + _bess = d.pop("bess", UNSET) + bess: Union[Unset, SiteBESS] + if isinstance(_bess, Unset): + bess = UNSET + else: + bess = SiteBESS.from_dict(_bess) + + create_virtual_site_response = cls( + id=id, + vendor=vendor, + name=name, + location_utc_offset=location_utc_offset, + batteries=batteries, + solar_inverters=solar_inverters, + location=location, + operational_since=operational_since, + bess=bess, + ) + + return create_virtual_site_response diff --git a/derapi/models/create_virtual_solar_inverter_request.py b/derapi/models/create_virtual_solar_inverter_request.py new file mode 100644 index 0000000..d9fe456 --- /dev/null +++ b/derapi/models/create_virtual_solar_inverter_request.py @@ -0,0 +1,123 @@ +import datetime +from typing import TYPE_CHECKING, Any, Dict, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.solar_inverter_lifetime_production import SolarInverterLifetimeProduction + from ..models.solar_inverter_recent_production import SolarInverterRecentProduction + + +T = TypeVar("T", bound="CreateVirtualSolarInverterRequest") + + +@_attrs_define +class CreateVirtualSolarInverterRequest: + """ + Attributes: + site_id (Union[Unset, str]): The Derapi Site ID this Solar Inverter is associated with + reported_at (Union[Unset, datetime.datetime]): Date the request was generated in ISO-8601 format + model (Union[Unset, str]): Model number of this Solar Inverter + serial_number (Union[Unset, str]): Manufacturer serial number of this Solar Inverter + name (Union[Unset, str]): Customer defined name of this Solar Inverter + recent_production (Union[Unset, SolarInverterRecentProduction]): + lifetime_production (Union[Unset, SolarInverterLifetimeProduction]): + """ + + site_id: Union[Unset, str] = UNSET + reported_at: Union[Unset, datetime.datetime] = UNSET + model: Union[Unset, str] = UNSET + serial_number: Union[Unset, str] = UNSET + name: Union[Unset, str] = UNSET + recent_production: Union[Unset, "SolarInverterRecentProduction"] = UNSET + lifetime_production: Union[Unset, "SolarInverterLifetimeProduction"] = UNSET + + def to_dict(self) -> Dict[str, Any]: + site_id = self.site_id + + reported_at: Union[Unset, str] = UNSET + if not isinstance(self.reported_at, Unset): + reported_at = self.reported_at.isoformat() + + model = self.model + + serial_number = self.serial_number + + name = self.name + + recent_production: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.recent_production, Unset): + recent_production = self.recent_production.to_dict() + + lifetime_production: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.lifetime_production, Unset): + lifetime_production = self.lifetime_production.to_dict() + + field_dict: Dict[str, Any] = {} + field_dict.update({}) + if site_id is not UNSET: + field_dict["siteID"] = site_id + if reported_at is not UNSET: + field_dict["reportedAt"] = reported_at + if model is not UNSET: + field_dict["model"] = model + if serial_number is not UNSET: + field_dict["serialNumber"] = serial_number + if name is not UNSET: + field_dict["name"] = name + if recent_production is not UNSET: + field_dict["recentProduction"] = recent_production + if lifetime_production is not UNSET: + field_dict["lifetimeProduction"] = lifetime_production + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.solar_inverter_lifetime_production import SolarInverterLifetimeProduction + from ..models.solar_inverter_recent_production import SolarInverterRecentProduction + + d = src_dict.copy() + site_id = d.pop("siteID", UNSET) + + _reported_at = d.pop("reportedAt", UNSET) + reported_at: Union[Unset, datetime.datetime] + if isinstance(_reported_at, Unset): + reported_at = UNSET + else: + reported_at = isoparse(_reported_at) + + model = d.pop("model", UNSET) + + serial_number = d.pop("serialNumber", UNSET) + + name = d.pop("name", UNSET) + + _recent_production = d.pop("recentProduction", UNSET) + recent_production: Union[Unset, SolarInverterRecentProduction] + if isinstance(_recent_production, Unset): + recent_production = UNSET + else: + recent_production = SolarInverterRecentProduction.from_dict(_recent_production) + + _lifetime_production = d.pop("lifetimeProduction", UNSET) + lifetime_production: Union[Unset, SolarInverterLifetimeProduction] + if isinstance(_lifetime_production, Unset): + lifetime_production = UNSET + else: + lifetime_production = SolarInverterLifetimeProduction.from_dict(_lifetime_production) + + create_virtual_solar_inverter_request = cls( + site_id=site_id, + reported_at=reported_at, + model=model, + serial_number=serial_number, + name=name, + recent_production=recent_production, + lifetime_production=lifetime_production, + ) + + return create_virtual_solar_inverter_request diff --git a/derapi/models/create_virtual_solar_inverter_response.py b/derapi/models/create_virtual_solar_inverter_response.py new file mode 100644 index 0000000..ab9256b --- /dev/null +++ b/derapi/models/create_virtual_solar_inverter_response.py @@ -0,0 +1,249 @@ +import datetime +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..models.vendor import Vendor +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.solar_inverter_lifetime_production import SolarInverterLifetimeProduction + from ..models.solar_inverter_recent_errors_error import SolarInverterRecentErrorsError + from ..models.solar_inverter_recent_errors_info import SolarInverterRecentErrorsInfo + from ..models.solar_inverter_recent_errors_start import SolarInverterRecentErrorsStart + from ..models.solar_inverter_recent_errors_warning import SolarInverterRecentErrorsWarning + from ..models.solar_inverter_recent_production import SolarInverterRecentProduction + + +T = TypeVar("T", bound="CreateVirtualSolarInverterResponse") + + +@_attrs_define +class CreateVirtualSolarInverterResponse: + """ + Attributes: + id (str): ID of the solar inverter + vendor (Vendor): + reported_at (datetime.datetime): Date the request was generated in ISO-8601 format + model (str): Model number of this Solar Inverter + serial_number (str): Manufacturer serial number of this Solar Inverter + site_id (str): The Derapi Site ID this Solar Inverter is associated with + name (Union[Unset, str]): Customer defined name of this Solar Inverter + recent_production (Union[Unset, SolarInverterRecentProduction]): + lifetime_production (Union[Unset, SolarInverterLifetimeProduction]): + recent_errors (Union[Unset, List[Union['SolarInverterRecentErrorsError', 'SolarInverterRecentErrorsInfo', + 'SolarInverterRecentErrorsStart', 'SolarInverterRecentErrorsWarning']]]): Most recent errors, warnings, or info + reported by the manufacturer for this Solar Inverter. The key represents the severity level + (info/warning/error); the value is a string description. start is always present and is the last element to be + returned. + """ + + id: str + vendor: Vendor + reported_at: datetime.datetime + model: str + serial_number: str + site_id: str + name: Union[Unset, str] = UNSET + recent_production: Union[Unset, "SolarInverterRecentProduction"] = UNSET + lifetime_production: Union[Unset, "SolarInverterLifetimeProduction"] = UNSET + recent_errors: Union[ + Unset, + List[ + Union[ + "SolarInverterRecentErrorsError", + "SolarInverterRecentErrorsInfo", + "SolarInverterRecentErrorsStart", + "SolarInverterRecentErrorsWarning", + ] + ], + ] = UNSET + + def to_dict(self) -> Dict[str, Any]: + from ..models.solar_inverter_recent_errors_error import SolarInverterRecentErrorsError + from ..models.solar_inverter_recent_errors_info import SolarInverterRecentErrorsInfo + from ..models.solar_inverter_recent_errors_warning import SolarInverterRecentErrorsWarning + + id = self.id + + vendor = self.vendor.value + + reported_at = self.reported_at.isoformat() + + model = self.model + + serial_number = self.serial_number + + site_id = self.site_id + + name = self.name + + recent_production: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.recent_production, Unset): + recent_production = self.recent_production.to_dict() + + lifetime_production: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.lifetime_production, Unset): + lifetime_production = self.lifetime_production.to_dict() + + recent_errors: Union[Unset, List[Dict[str, Any]]] = UNSET + if not isinstance(self.recent_errors, Unset): + recent_errors = [] + for componentsschemas_solar_inverter_recent_errors_item_data in self.recent_errors: + componentsschemas_solar_inverter_recent_errors_item: Dict[str, Any] + if isinstance(componentsschemas_solar_inverter_recent_errors_item_data, SolarInverterRecentErrorsError): + componentsschemas_solar_inverter_recent_errors_item = ( + componentsschemas_solar_inverter_recent_errors_item_data.to_dict() + ) + elif isinstance( + componentsschemas_solar_inverter_recent_errors_item_data, SolarInverterRecentErrorsWarning + ): + componentsschemas_solar_inverter_recent_errors_item = ( + componentsschemas_solar_inverter_recent_errors_item_data.to_dict() + ) + elif isinstance( + componentsschemas_solar_inverter_recent_errors_item_data, SolarInverterRecentErrorsInfo + ): + componentsschemas_solar_inverter_recent_errors_item = ( + componentsschemas_solar_inverter_recent_errors_item_data.to_dict() + ) + else: + componentsschemas_solar_inverter_recent_errors_item = ( + componentsschemas_solar_inverter_recent_errors_item_data.to_dict() + ) + + recent_errors.append(componentsschemas_solar_inverter_recent_errors_item) + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "vendor": vendor, + "reportedAt": reported_at, + "model": model, + "serialNumber": serial_number, + "siteID": site_id, + } + ) + if name is not UNSET: + field_dict["name"] = name + if recent_production is not UNSET: + field_dict["recentProduction"] = recent_production + if lifetime_production is not UNSET: + field_dict["lifetimeProduction"] = lifetime_production + if recent_errors is not UNSET: + field_dict["recentErrors"] = recent_errors + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.solar_inverter_lifetime_production import SolarInverterLifetimeProduction + from ..models.solar_inverter_recent_errors_error import SolarInverterRecentErrorsError + from ..models.solar_inverter_recent_errors_info import SolarInverterRecentErrorsInfo + from ..models.solar_inverter_recent_errors_start import SolarInverterRecentErrorsStart + from ..models.solar_inverter_recent_errors_warning import SolarInverterRecentErrorsWarning + from ..models.solar_inverter_recent_production import SolarInverterRecentProduction + + d = src_dict.copy() + id = d.pop("id") + + vendor = Vendor(d.pop("vendor")) + + reported_at = isoparse(d.pop("reportedAt")) + + model = d.pop("model") + + serial_number = d.pop("serialNumber") + + site_id = d.pop("siteID") + + name = d.pop("name", UNSET) + + _recent_production = d.pop("recentProduction", UNSET) + recent_production: Union[Unset, SolarInverterRecentProduction] + if isinstance(_recent_production, Unset): + recent_production = UNSET + else: + recent_production = SolarInverterRecentProduction.from_dict(_recent_production) + + _lifetime_production = d.pop("lifetimeProduction", UNSET) + lifetime_production: Union[Unset, SolarInverterLifetimeProduction] + if isinstance(_lifetime_production, Unset): + lifetime_production = UNSET + else: + lifetime_production = SolarInverterLifetimeProduction.from_dict(_lifetime_production) + + recent_errors = [] + _recent_errors = d.pop("recentErrors", UNSET) + for componentsschemas_solar_inverter_recent_errors_item_data in _recent_errors or []: + + def _parse_componentsschemas_solar_inverter_recent_errors_item( + data: object, + ) -> Union[ + "SolarInverterRecentErrorsError", + "SolarInverterRecentErrorsInfo", + "SolarInverterRecentErrorsStart", + "SolarInverterRecentErrorsWarning", + ]: + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_solar_inverter_recent_errors_item_type_0 = ( + SolarInverterRecentErrorsError.from_dict(data) + ) + + return componentsschemas_solar_inverter_recent_errors_item_type_0 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_solar_inverter_recent_errors_item_type_1 = ( + SolarInverterRecentErrorsWarning.from_dict(data) + ) + + return componentsschemas_solar_inverter_recent_errors_item_type_1 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_solar_inverter_recent_errors_item_type_2 = ( + SolarInverterRecentErrorsInfo.from_dict(data) + ) + + return componentsschemas_solar_inverter_recent_errors_item_type_2 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + componentsschemas_solar_inverter_recent_errors_item_type_3 = SolarInverterRecentErrorsStart.from_dict( + data + ) + + return componentsschemas_solar_inverter_recent_errors_item_type_3 + + componentsschemas_solar_inverter_recent_errors_item = ( + _parse_componentsschemas_solar_inverter_recent_errors_item( + componentsschemas_solar_inverter_recent_errors_item_data + ) + ) + + recent_errors.append(componentsschemas_solar_inverter_recent_errors_item) + + create_virtual_solar_inverter_response = cls( + id=id, + vendor=vendor, + reported_at=reported_at, + model=model, + serial_number=serial_number, + site_id=site_id, + name=name, + recent_production=recent_production, + lifetime_production=lifetime_production, + recent_errors=recent_errors, + ) + + return create_virtual_solar_inverter_response diff --git a/derapi/models/enphase_developer_app_credentials.py b/derapi/models/enphase_developer_app_credentials.py new file mode 100644 index 0000000..a7253ae --- /dev/null +++ b/derapi/models/enphase_developer_app_credentials.py @@ -0,0 +1,75 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="EnphaseDeveloperAppCredentials") + + +@_attrs_define +class EnphaseDeveloperAppCredentials: + """Credentials for an Enphase developer app + + Attributes: + vendor (Literal['enphase']): Default: 'enphase'. + type (Literal['developerapp']): Default: 'developerapp'. + client_id (str): Enphase Client ID + client_secret (str): Enphase Client Secret + api_key (str): Enphase API key of the application + """ + + client_id: str + client_secret: str + api_key: str + vendor: Literal["enphase"] = "enphase" + type: Literal["developerapp"] = "developerapp" + + def to_dict(self) -> Dict[str, Any]: + vendor = self.vendor + + type = self.type + + client_id = self.client_id + + client_secret = self.client_secret + + api_key = self.api_key + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "vendor": vendor, + "type": type, + "clientID": client_id, + "clientSecret": client_secret, + "apiKey": api_key, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + vendor = cast(Literal["enphase"], d.pop("vendor")) + if vendor != "enphase": + raise ValueError(f"vendor must match const 'enphase', got '{vendor}'") + + type = cast(Literal["developerapp"], d.pop("type")) + if type != "developerapp": + raise ValueError(f"type must match const 'developerapp', got '{type}'") + + client_id = d.pop("clientID") + + client_secret = d.pop("clientSecret") + + api_key = d.pop("apiKey") + + enphase_developer_app_credentials = cls( + vendor=vendor, + type=type, + client_id=client_id, + client_secret=client_secret, + api_key=api_key, + ) + + return enphase_developer_app_credentials diff --git a/derapi/models/enphase_join_config.py b/derapi/models/enphase_join_config.py new file mode 100644 index 0000000..a7f44bf --- /dev/null +++ b/derapi/models/enphase_join_config.py @@ -0,0 +1,81 @@ +from typing import TYPE_CHECKING, Any, Dict, Literal, Type, TypeVar, Union, cast + +from attrs import define as _attrs_define + +if TYPE_CHECKING: + from ..models.enphase_join_config_inline_credentials import EnphaseJoinConfigInlineCredentials + from ..models.stored_credentials_reference import StoredCredentialsReference + + +T = TypeVar("T", bound="EnphaseJoinConfig") + + +@_attrs_define +class EnphaseJoinConfig: + """ + Attributes: + vendor (Literal['enphase']): + credentials (Union['EnphaseJoinConfigInlineCredentials', 'StoredCredentialsReference']): + """ + + vendor: Literal["enphase"] + credentials: Union["EnphaseJoinConfigInlineCredentials", "StoredCredentialsReference"] + + def to_dict(self) -> Dict[str, Any]: + from ..models.enphase_join_config_inline_credentials import EnphaseJoinConfigInlineCredentials + + vendor = self.vendor + + credentials: Dict[str, Any] + if isinstance(self.credentials, EnphaseJoinConfigInlineCredentials): + credentials = self.credentials.to_dict() + else: + credentials = self.credentials.to_dict() + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "vendor": vendor, + "credentials": credentials, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.enphase_join_config_inline_credentials import EnphaseJoinConfigInlineCredentials + from ..models.stored_credentials_reference import StoredCredentialsReference + + d = src_dict.copy() + vendor = cast(Literal["enphase"], d.pop("vendor")) + if vendor != "enphase": + raise ValueError(f"vendor must match const 'enphase', got '{vendor}'") + + def _parse_credentials( + data: object, + ) -> Union["EnphaseJoinConfigInlineCredentials", "StoredCredentialsReference"]: + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_enphase_join_config_credentials_type_0 = EnphaseJoinConfigInlineCredentials.from_dict( + data + ) + + return componentsschemas_enphase_join_config_credentials_type_0 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + componentsschemas_enphase_join_config_credentials_type_1 = StoredCredentialsReference.from_dict(data) + + return componentsschemas_enphase_join_config_credentials_type_1 + + credentials = _parse_credentials(d.pop("credentials")) + + enphase_join_config = cls( + vendor=vendor, + credentials=credentials, + ) + + return enphase_join_config diff --git a/derapi/models/enphase_join_config_inline_credentials.py b/derapi/models/enphase_join_config_inline_credentials.py new file mode 100644 index 0000000..005141b --- /dev/null +++ b/derapi/models/enphase_join_config_inline_credentials.py @@ -0,0 +1,54 @@ +from typing import Any, Dict, Type, TypeVar + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="EnphaseJoinConfigInlineCredentials") + + +@_attrs_define +class EnphaseJoinConfigInlineCredentials: + """ + Attributes: + client_id (str): Enphase Client ID + client_secret (str): Enphase Client Secret + api_key (str): Enphase API key of the application + """ + + client_id: str + client_secret: str + api_key: str + + def to_dict(self) -> Dict[str, Any]: + client_id = self.client_id + + client_secret = self.client_secret + + api_key = self.api_key + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "clientID": client_id, + "clientSecret": client_secret, + "apiKey": api_key, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + client_id = d.pop("clientID") + + client_secret = d.pop("clientSecret") + + api_key = d.pop("apiKey") + + enphase_join_config_inline_credentials = cls( + client_id=client_id, + client_secret=client_secret, + api_key=api_key, + ) + + return enphase_join_config_inline_credentials diff --git a/derapi/models/enphase_partner_app_credentials.py b/derapi/models/enphase_partner_app_credentials.py new file mode 100644 index 0000000..5f08f0a --- /dev/null +++ b/derapi/models/enphase_partner_app_credentials.py @@ -0,0 +1,75 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="EnphasePartnerAppCredentials") + + +@_attrs_define +class EnphasePartnerAppCredentials: + """Credentials for an Enphase partner app + + Attributes: + vendor (Literal['enphase']): Default: 'enphase'. + type (Literal['partnerapp']): Default: 'partnerapp'. + client_id (str): Enphase Client ID + client_secret (str): Enphase Client Secret + api_key (str): Enphase API key of the application + """ + + client_id: str + client_secret: str + api_key: str + vendor: Literal["enphase"] = "enphase" + type: Literal["partnerapp"] = "partnerapp" + + def to_dict(self) -> Dict[str, Any]: + vendor = self.vendor + + type = self.type + + client_id = self.client_id + + client_secret = self.client_secret + + api_key = self.api_key + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "vendor": vendor, + "type": type, + "clientID": client_id, + "clientSecret": client_secret, + "apiKey": api_key, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + vendor = cast(Literal["enphase"], d.pop("vendor")) + if vendor != "enphase": + raise ValueError(f"vendor must match const 'enphase', got '{vendor}'") + + type = cast(Literal["partnerapp"], d.pop("type")) + if type != "partnerapp": + raise ValueError(f"type must match const 'partnerapp', got '{type}'") + + client_id = d.pop("clientID") + + client_secret = d.pop("clientSecret") + + api_key = d.pop("apiKey") + + enphase_partner_app_credentials = cls( + vendor=vendor, + type=type, + client_id=client_id, + client_secret=client_secret, + api_key=api_key, + ) + + return enphase_partner_app_credentials diff --git a/derapi/models/enphase_vpp_credentials.py b/derapi/models/enphase_vpp_credentials.py new file mode 100644 index 0000000..44f04bf --- /dev/null +++ b/derapi/models/enphase_vpp_credentials.py @@ -0,0 +1,74 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="EnphaseVPPCredentials") + + +@_attrs_define +class EnphaseVPPCredentials: + """ + Attributes: + vendor (Literal['enphasevpp']): Default: 'enphasevpp'. + type (Literal['vpp']): Default: 'vpp'. + client_id (str): Enphase VPP Client ID + client_secret (str): Enphase VPP Client Secret + api_key (str): Enphase VPP API Key + """ + + client_id: str + client_secret: str + api_key: str + vendor: Literal["enphasevpp"] = "enphasevpp" + type: Literal["vpp"] = "vpp" + + def to_dict(self) -> Dict[str, Any]: + vendor = self.vendor + + type = self.type + + client_id = self.client_id + + client_secret = self.client_secret + + api_key = self.api_key + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "vendor": vendor, + "type": type, + "clientID": client_id, + "clientSecret": client_secret, + "apiKey": api_key, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + vendor = cast(Literal["enphasevpp"], d.pop("vendor")) + if vendor != "enphasevpp": + raise ValueError(f"vendor must match const 'enphasevpp', got '{vendor}'") + + type = cast(Literal["vpp"], d.pop("type")) + if type != "vpp": + raise ValueError(f"type must match const 'vpp', got '{type}'") + + client_id = d.pop("clientID") + + client_secret = d.pop("clientSecret") + + api_key = d.pop("apiKey") + + enphase_vpp_credentials = cls( + vendor=vendor, + type=type, + client_id=client_id, + client_secret=client_secret, + api_key=api_key, + ) + + return enphase_vpp_credentials diff --git a/derapi/models/enphase_vpp_join_config.py b/derapi/models/enphase_vpp_join_config.py new file mode 100644 index 0000000..f798830 --- /dev/null +++ b/derapi/models/enphase_vpp_join_config.py @@ -0,0 +1,121 @@ +from typing import TYPE_CHECKING, Any, Dict, Literal, Type, TypeVar, Union, cast + +from attrs import define as _attrs_define + +if TYPE_CHECKING: + from ..models.enphase_join_config_inline_credentials import EnphaseJoinConfigInlineCredentials + from ..models.enphase_vpp_join_config_inline_credentials import EnphaseVPPJoinConfigInlineCredentials + from ..models.stored_credentials_reference import StoredCredentialsReference + + +T = TypeVar("T", bound="EnphaseVPPJoinConfig") + + +@_attrs_define +class EnphaseVPPJoinConfig: + """ + Attributes: + vendor (Literal['enphasevpp']): + credentials (Union['EnphaseVPPJoinConfigInlineCredentials', 'StoredCredentialsReference']): + partner_app_credentials (Union['EnphaseJoinConfigInlineCredentials', 'StoredCredentialsReference']): + program_id (str): + """ + + vendor: Literal["enphasevpp"] + credentials: Union["EnphaseVPPJoinConfigInlineCredentials", "StoredCredentialsReference"] + partner_app_credentials: Union["EnphaseJoinConfigInlineCredentials", "StoredCredentialsReference"] + program_id: str + + def to_dict(self) -> Dict[str, Any]: + from ..models.enphase_join_config_inline_credentials import EnphaseJoinConfigInlineCredentials + from ..models.enphase_vpp_join_config_inline_credentials import EnphaseVPPJoinConfigInlineCredentials + + vendor = self.vendor + + credentials: Dict[str, Any] + if isinstance(self.credentials, EnphaseVPPJoinConfigInlineCredentials): + credentials = self.credentials.to_dict() + else: + credentials = self.credentials.to_dict() + + partner_app_credentials: Dict[str, Any] + if isinstance(self.partner_app_credentials, EnphaseJoinConfigInlineCredentials): + partner_app_credentials = self.partner_app_credentials.to_dict() + else: + partner_app_credentials = self.partner_app_credentials.to_dict() + + program_id = self.program_id + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "vendor": vendor, + "credentials": credentials, + "partnerAppCredentials": partner_app_credentials, + "programID": program_id, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.enphase_join_config_inline_credentials import EnphaseJoinConfigInlineCredentials + from ..models.enphase_vpp_join_config_inline_credentials import EnphaseVPPJoinConfigInlineCredentials + from ..models.stored_credentials_reference import StoredCredentialsReference + + d = src_dict.copy() + vendor = cast(Literal["enphasevpp"], d.pop("vendor")) + if vendor != "enphasevpp": + raise ValueError(f"vendor must match const 'enphasevpp', got '{vendor}'") + + def _parse_credentials( + data: object, + ) -> Union["EnphaseVPPJoinConfigInlineCredentials", "StoredCredentialsReference"]: + try: + if not isinstance(data, dict): + raise TypeError() + credentials_type_0 = EnphaseVPPJoinConfigInlineCredentials.from_dict(data) + + return credentials_type_0 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + credentials_type_1 = StoredCredentialsReference.from_dict(data) + + return credentials_type_1 + + credentials = _parse_credentials(d.pop("credentials")) + + def _parse_partner_app_credentials( + data: object, + ) -> Union["EnphaseJoinConfigInlineCredentials", "StoredCredentialsReference"]: + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_enphase_join_config_credentials_type_0 = EnphaseJoinConfigInlineCredentials.from_dict( + data + ) + + return componentsschemas_enphase_join_config_credentials_type_0 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + componentsschemas_enphase_join_config_credentials_type_1 = StoredCredentialsReference.from_dict(data) + + return componentsschemas_enphase_join_config_credentials_type_1 + + partner_app_credentials = _parse_partner_app_credentials(d.pop("partnerAppCredentials")) + + program_id = d.pop("programID") + + enphase_vpp_join_config = cls( + vendor=vendor, + credentials=credentials, + partner_app_credentials=partner_app_credentials, + program_id=program_id, + ) + + return enphase_vpp_join_config diff --git a/derapi/models/enphase_vpp_join_config_inline_credentials.py b/derapi/models/enphase_vpp_join_config_inline_credentials.py new file mode 100644 index 0000000..2de98ea --- /dev/null +++ b/derapi/models/enphase_vpp_join_config_inline_credentials.py @@ -0,0 +1,54 @@ +from typing import Any, Dict, Type, TypeVar + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="EnphaseVPPJoinConfigInlineCredentials") + + +@_attrs_define +class EnphaseVPPJoinConfigInlineCredentials: + """ + Attributes: + client_id (str): Enphase VPP Client ID + client_secret (str): Enphase VPP Client Secret + api_key (str): Enphase VPP API Key + """ + + client_id: str + client_secret: str + api_key: str + + def to_dict(self) -> Dict[str, Any]: + client_id = self.client_id + + client_secret = self.client_secret + + api_key = self.api_key + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "clientID": client_id, + "clientSecret": client_secret, + "apiKey": api_key, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + client_id = d.pop("clientID") + + client_secret = d.pop("clientSecret") + + api_key = d.pop("apiKey") + + enphase_vpp_join_config_inline_credentials = cls( + client_id=client_id, + client_secret=client_secret, + api_key=api_key, + ) + + return enphase_vpp_join_config_inline_credentials diff --git a/derapi/models/franklin_wh_credentials.py b/derapi/models/franklin_wh_credentials.py new file mode 100644 index 0000000..e78db5c --- /dev/null +++ b/derapi/models/franklin_wh_credentials.py @@ -0,0 +1,66 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="FranklinWHCredentials") + + +@_attrs_define +class FranklinWHCredentials: + """ + Attributes: + vendor (Literal['franklinwh']): Default: 'franklinwh'. + type (Literal['partner']): Default: 'partner'. + client_id (str): FranklinWH Client ID + client_secret (str): FranklinWH Client Secret + """ + + client_id: str + client_secret: str + vendor: Literal["franklinwh"] = "franklinwh" + type: Literal["partner"] = "partner" + + def to_dict(self) -> Dict[str, Any]: + vendor = self.vendor + + type = self.type + + client_id = self.client_id + + client_secret = self.client_secret + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "vendor": vendor, + "type": type, + "clientID": client_id, + "clientSecret": client_secret, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + vendor = cast(Literal["franklinwh"], d.pop("vendor")) + if vendor != "franklinwh": + raise ValueError(f"vendor must match const 'franklinwh', got '{vendor}'") + + type = cast(Literal["partner"], d.pop("type")) + if type != "partner": + raise ValueError(f"type must match const 'partner', got '{type}'") + + client_id = d.pop("clientID") + + client_secret = d.pop("clientSecret") + + franklin_wh_credentials = cls( + vendor=vendor, + type=type, + client_id=client_id, + client_secret=client_secret, + ) + + return franklin_wh_credentials diff --git a/derapi/models/get_battery_intervals_response.py b/derapi/models/get_battery_intervals_response.py new file mode 100644 index 0000000..240c366 --- /dev/null +++ b/derapi/models/get_battery_intervals_response.py @@ -0,0 +1,81 @@ +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define + +from ..models.summary_level import SummaryLevel +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.battery_interval import BatteryInterval + + +T = TypeVar("T", bound="GetBatteryIntervalsResponse") + + +@_attrs_define +class GetBatteryIntervalsResponse: + """ + Attributes: + id (str): Battery id + summary_level (SummaryLevel): + intervals (List['BatteryInterval']): + next_page_token (Union[Unset, str]): A token to request the next page, if any. If absent, there are no more + pages. + """ + + id: str + summary_level: SummaryLevel + intervals: List["BatteryInterval"] + next_page_token: Union[Unset, str] = UNSET + + def to_dict(self) -> Dict[str, Any]: + id = self.id + + summary_level = self.summary_level.value + + intervals = [] + for intervals_item_data in self.intervals: + intervals_item = intervals_item_data.to_dict() + intervals.append(intervals_item) + + next_page_token = self.next_page_token + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "summaryLevel": summary_level, + "intervals": intervals, + } + ) + if next_page_token is not UNSET: + field_dict["nextPageToken"] = next_page_token + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.battery_interval import BatteryInterval + + d = src_dict.copy() + id = d.pop("id") + + summary_level = SummaryLevel(d.pop("summaryLevel")) + + intervals = [] + _intervals = d.pop("intervals") + for intervals_item_data in _intervals: + intervals_item = BatteryInterval.from_dict(intervals_item_data) + + intervals.append(intervals_item) + + next_page_token = d.pop("nextPageToken", UNSET) + + get_battery_intervals_response = cls( + id=id, + summary_level=summary_level, + intervals=intervals, + next_page_token=next_page_token, + ) + + return get_battery_intervals_response diff --git a/derapi/models/get_battery_response.py b/derapi/models/get_battery_response.py new file mode 100644 index 0000000..bd8d5bf --- /dev/null +++ b/derapi/models/get_battery_response.py @@ -0,0 +1,236 @@ +import datetime +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..models.battery_mode import BatteryMode +from ..models.vendor import Vendor +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.battery_recent_errors_error import BatteryRecentErrorsError + from ..models.battery_recent_errors_info import BatteryRecentErrorsInfo + from ..models.battery_recent_errors_start import BatteryRecentErrorsStart + from ..models.battery_recent_errors_warning import BatteryRecentErrorsWarning + + +T = TypeVar("T", bound="GetBatteryResponse") + + +@_attrs_define +class GetBatteryResponse: + """ + Attributes: + id (str): Battery id + vendor (Vendor): + reported_at (datetime.datetime): Date the request was generated in ISO-8601 format (timezone is always +00:00 + and is always present) + model (str): Model number of Battery + serial_number (str): Manufacturer serial number of the Battery + site_id (str): The Derapi Site ID this Battery is associated with + name (Union[Unset, str]): Customer defined name of the Battery + nameplate_kwh (Union[Unset, float]): The rated storage capacity of the unit + mode (Union[Unset, BatteryMode]): Battery management system mode. Values are Self Consumption - minimize grid + import, Savings - optimizing Battery to save money; usually based on a rate plan, Backup - only use Battery for + grid backup + state_of_charge_percent (Union[Unset, float]): Battery state of charge as a percent of capacity + recent_errors (Union[Unset, List[Union['BatteryRecentErrorsError', 'BatteryRecentErrorsInfo', + 'BatteryRecentErrorsStart', 'BatteryRecentErrorsWarning']]]): Most recent errors, warnings, or info reported by + the manufacturer for this Battery. The key represents the severity level (info/warning/error); the value is a + string description. start is always present and is the last element to be returned. + """ + + id: str + vendor: Vendor + reported_at: datetime.datetime + model: str + serial_number: str + site_id: str + name: Union[Unset, str] = UNSET + nameplate_kwh: Union[Unset, float] = UNSET + mode: Union[Unset, BatteryMode] = UNSET + state_of_charge_percent: Union[Unset, float] = UNSET + recent_errors: Union[ + Unset, + List[ + Union[ + "BatteryRecentErrorsError", + "BatteryRecentErrorsInfo", + "BatteryRecentErrorsStart", + "BatteryRecentErrorsWarning", + ] + ], + ] = UNSET + + def to_dict(self) -> Dict[str, Any]: + from ..models.battery_recent_errors_error import BatteryRecentErrorsError + from ..models.battery_recent_errors_info import BatteryRecentErrorsInfo + from ..models.battery_recent_errors_warning import BatteryRecentErrorsWarning + + id = self.id + + vendor = self.vendor.value + + reported_at = self.reported_at.isoformat() + + model = self.model + + serial_number = self.serial_number + + site_id = self.site_id + + name = self.name + + nameplate_kwh = self.nameplate_kwh + + mode: Union[Unset, str] = UNSET + if not isinstance(self.mode, Unset): + mode = self.mode.value + + state_of_charge_percent = self.state_of_charge_percent + + recent_errors: Union[Unset, List[Dict[str, Any]]] = UNSET + if not isinstance(self.recent_errors, Unset): + recent_errors = [] + for componentsschemas_battery_recent_errors_item_data in self.recent_errors: + componentsschemas_battery_recent_errors_item: Dict[str, Any] + if isinstance(componentsschemas_battery_recent_errors_item_data, BatteryRecentErrorsError): + componentsschemas_battery_recent_errors_item = ( + componentsschemas_battery_recent_errors_item_data.to_dict() + ) + elif isinstance(componentsschemas_battery_recent_errors_item_data, BatteryRecentErrorsWarning): + componentsschemas_battery_recent_errors_item = ( + componentsschemas_battery_recent_errors_item_data.to_dict() + ) + elif isinstance(componentsschemas_battery_recent_errors_item_data, BatteryRecentErrorsInfo): + componentsschemas_battery_recent_errors_item = ( + componentsschemas_battery_recent_errors_item_data.to_dict() + ) + else: + componentsschemas_battery_recent_errors_item = ( + componentsschemas_battery_recent_errors_item_data.to_dict() + ) + + recent_errors.append(componentsschemas_battery_recent_errors_item) + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "vendor": vendor, + "reportedAt": reported_at, + "model": model, + "serialNumber": serial_number, + "siteID": site_id, + } + ) + if name is not UNSET: + field_dict["name"] = name + if nameplate_kwh is not UNSET: + field_dict["nameplateKwh"] = nameplate_kwh + if mode is not UNSET: + field_dict["mode"] = mode + if state_of_charge_percent is not UNSET: + field_dict["stateOfChargePercent"] = state_of_charge_percent + if recent_errors is not UNSET: + field_dict["recentErrors"] = recent_errors + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.battery_recent_errors_error import BatteryRecentErrorsError + from ..models.battery_recent_errors_info import BatteryRecentErrorsInfo + from ..models.battery_recent_errors_start import BatteryRecentErrorsStart + from ..models.battery_recent_errors_warning import BatteryRecentErrorsWarning + + d = src_dict.copy() + id = d.pop("id") + + vendor = Vendor(d.pop("vendor")) + + reported_at = isoparse(d.pop("reportedAt")) + + model = d.pop("model") + + serial_number = d.pop("serialNumber") + + site_id = d.pop("siteID") + + name = d.pop("name", UNSET) + + nameplate_kwh = d.pop("nameplateKwh", UNSET) + + _mode = d.pop("mode", UNSET) + mode: Union[Unset, BatteryMode] + if isinstance(_mode, Unset): + mode = UNSET + else: + mode = BatteryMode(_mode) + + state_of_charge_percent = d.pop("stateOfChargePercent", UNSET) + + recent_errors = [] + _recent_errors = d.pop("recentErrors", UNSET) + for componentsschemas_battery_recent_errors_item_data in _recent_errors or []: + + def _parse_componentsschemas_battery_recent_errors_item( + data: object, + ) -> Union[ + "BatteryRecentErrorsError", + "BatteryRecentErrorsInfo", + "BatteryRecentErrorsStart", + "BatteryRecentErrorsWarning", + ]: + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_battery_recent_errors_item_type_0 = BatteryRecentErrorsError.from_dict(data) + + return componentsschemas_battery_recent_errors_item_type_0 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_battery_recent_errors_item_type_1 = BatteryRecentErrorsWarning.from_dict(data) + + return componentsschemas_battery_recent_errors_item_type_1 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_battery_recent_errors_item_type_2 = BatteryRecentErrorsInfo.from_dict(data) + + return componentsschemas_battery_recent_errors_item_type_2 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + componentsschemas_battery_recent_errors_item_type_3 = BatteryRecentErrorsStart.from_dict(data) + + return componentsschemas_battery_recent_errors_item_type_3 + + componentsschemas_battery_recent_errors_item = _parse_componentsschemas_battery_recent_errors_item( + componentsschemas_battery_recent_errors_item_data + ) + + recent_errors.append(componentsschemas_battery_recent_errors_item) + + get_battery_response = cls( + id=id, + vendor=vendor, + reported_at=reported_at, + model=model, + serial_number=serial_number, + site_id=site_id, + name=name, + nameplate_kwh=nameplate_kwh, + mode=mode, + state_of_charge_percent=state_of_charge_percent, + recent_errors=recent_errors, + ) + + return get_battery_response diff --git a/derapi/models/get_join_session_token_response.py b/derapi/models/get_join_session_token_response.py new file mode 100644 index 0000000..347029a --- /dev/null +++ b/derapi/models/get_join_session_token_response.py @@ -0,0 +1,73 @@ +from typing import Any, Dict, Type, TypeVar, Union + +from attrs import define as _attrs_define + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="GetJoinSessionTokenResponse") + + +@_attrs_define +class GetJoinSessionTokenResponse: + """ + Attributes: + vendor (str): The vendor that the client authorized (sma, enphase, solis, solaredge, enphasevpp, tesla) + access_token (str): The public access token to use when requesting data for clients system + refresh_token (str): The refresh token to use when requesting a new token for clients system + expires_in (str): Amount of time the accessToken is valid (in seconds) + site_id (Union[Unset, str]): Only for enphasevpp, the siteID for the clients system + """ + + vendor: str + access_token: str + refresh_token: str + expires_in: str + site_id: Union[Unset, str] = UNSET + + def to_dict(self) -> Dict[str, Any]: + vendor = self.vendor + + access_token = self.access_token + + refresh_token = self.refresh_token + + expires_in = self.expires_in + + site_id = self.site_id + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "vendor": vendor, + "accessToken": access_token, + "refreshToken": refresh_token, + "expiresIn": expires_in, + } + ) + if site_id is not UNSET: + field_dict["siteID"] = site_id + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + vendor = d.pop("vendor") + + access_token = d.pop("accessToken") + + refresh_token = d.pop("refreshToken") + + expires_in = d.pop("expiresIn") + + site_id = d.pop("siteID", UNSET) + + get_join_session_token_response = cls( + vendor=vendor, + access_token=access_token, + refresh_token=refresh_token, + expires_in=expires_in, + site_id=site_id, + ) + + return get_join_session_token_response diff --git a/derapi/models/get_site_battery_control_response.py b/derapi/models/get_site_battery_control_response.py new file mode 100644 index 0000000..3c471de --- /dev/null +++ b/derapi/models/get_site_battery_control_response.py @@ -0,0 +1,60 @@ +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar + +from attrs import define as _attrs_define + +if TYPE_CHECKING: + from ..models.site_battery_control_status_interval import SiteBatteryControlStatusInterval + + +T = TypeVar("T", bound="GetSiteBatteryControlResponse") + + +@_attrs_define +class GetSiteBatteryControlResponse: + """ + Attributes: + id (str): the ID for the Site + intervals (List['SiteBatteryControlStatusInterval']): + """ + + id: str + intervals: List["SiteBatteryControlStatusInterval"] + + def to_dict(self) -> Dict[str, Any]: + id = self.id + + intervals = [] + for intervals_item_data in self.intervals: + intervals_item = intervals_item_data.to_dict() + intervals.append(intervals_item) + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "intervals": intervals, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.site_battery_control_status_interval import SiteBatteryControlStatusInterval + + d = src_dict.copy() + id = d.pop("id") + + intervals = [] + _intervals = d.pop("intervals") + for intervals_item_data in _intervals: + intervals_item = SiteBatteryControlStatusInterval.from_dict(intervals_item_data) + + intervals.append(intervals_item) + + get_site_battery_control_response = cls( + id=id, + intervals=intervals, + ) + + return get_site_battery_control_response diff --git a/derapi/models/get_site_battery_intervals_response.py b/derapi/models/get_site_battery_intervals_response.py new file mode 100644 index 0000000..07d55fd --- /dev/null +++ b/derapi/models/get_site_battery_intervals_response.py @@ -0,0 +1,81 @@ +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define + +from ..models.summary_level import SummaryLevel +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.site_battery_interval import SiteBatteryInterval + + +T = TypeVar("T", bound="GetSiteBatteryIntervalsResponse") + + +@_attrs_define +class GetSiteBatteryIntervalsResponse: + """ + Attributes: + id (str): the ID for the Site + summary_level (SummaryLevel): + intervals (List['SiteBatteryInterval']): + next_page_token (Union[Unset, str]): A token to request the next page, if any. If absent, there are no more + pages. + """ + + id: str + summary_level: SummaryLevel + intervals: List["SiteBatteryInterval"] + next_page_token: Union[Unset, str] = UNSET + + def to_dict(self) -> Dict[str, Any]: + id = self.id + + summary_level = self.summary_level.value + + intervals = [] + for intervals_item_data in self.intervals: + intervals_item = intervals_item_data.to_dict() + intervals.append(intervals_item) + + next_page_token = self.next_page_token + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "summaryLevel": summary_level, + "intervals": intervals, + } + ) + if next_page_token is not UNSET: + field_dict["nextPageToken"] = next_page_token + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.site_battery_interval import SiteBatteryInterval + + d = src_dict.copy() + id = d.pop("id") + + summary_level = SummaryLevel(d.pop("summaryLevel")) + + intervals = [] + _intervals = d.pop("intervals") + for intervals_item_data in _intervals: + intervals_item = SiteBatteryInterval.from_dict(intervals_item_data) + + intervals.append(intervals_item) + + next_page_token = d.pop("nextPageToken", UNSET) + + get_site_battery_intervals_response = cls( + id=id, + summary_level=summary_level, + intervals=intervals, + next_page_token=next_page_token, + ) + + return get_site_battery_intervals_response diff --git a/derapi/models/get_site_response.py b/derapi/models/get_site_response.py new file mode 100644 index 0000000..8ee6139 --- /dev/null +++ b/derapi/models/get_site_response.py @@ -0,0 +1,163 @@ +import datetime +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..models.vendor import Vendor +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.battery_summary import BatterySummary + from ..models.site_bess import SiteBESS + from ..models.site_location import SiteLocation + from ..models.solar_inverter_summary import SolarInverterSummary + + +T = TypeVar("T", bound="GetSiteResponse") + + +@_attrs_define +class GetSiteResponse: + """ + Attributes: + id (str): the ID for the Site + vendor (Vendor): + name (str): Customer defined name of the Site + location_utc_offset (float): UTC Offset in hours; positive values represent locations East of UTC. Please note + this field will soon be deprecated, please use `timezone` instead. + batteries (List['BatterySummary']): List of Battery IDs associated with this Site + solar_inverters (List['SolarInverterSummary']): List of Solar Inverter IDs associated with this Site + location (Union[Unset, SiteLocation]): The location of this Solar Inverter in lat/lon coordinates + operational_since (Union[Unset, datetime.datetime]): The date the Site became operational or received permission + to operate. Sometimes absent for Solaredge. + bess (Union[Unset, SiteBESS]): For Sites with Batteries this key is present + """ + + id: str + vendor: Vendor + name: str + location_utc_offset: float + batteries: List["BatterySummary"] + solar_inverters: List["SolarInverterSummary"] + location: Union[Unset, "SiteLocation"] = UNSET + operational_since: Union[Unset, datetime.datetime] = UNSET + bess: Union[Unset, "SiteBESS"] = UNSET + + def to_dict(self) -> Dict[str, Any]: + id = self.id + + vendor = self.vendor.value + + name = self.name + + location_utc_offset = self.location_utc_offset + + batteries = [] + for componentsschemas_site_batteries_item_data in self.batteries: + componentsschemas_site_batteries_item = componentsschemas_site_batteries_item_data.to_dict() + batteries.append(componentsschemas_site_batteries_item) + + solar_inverters = [] + for componentsschemas_site_solar_inverters_item_data in self.solar_inverters: + componentsschemas_site_solar_inverters_item = componentsschemas_site_solar_inverters_item_data.to_dict() + solar_inverters.append(componentsschemas_site_solar_inverters_item) + + location: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.location, Unset): + location = self.location.to_dict() + + operational_since: Union[Unset, str] = UNSET + if not isinstance(self.operational_since, Unset): + operational_since = self.operational_since.isoformat() + + bess: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.bess, Unset): + bess = self.bess.to_dict() + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "vendor": vendor, + "name": name, + "locationUTCOffset": location_utc_offset, + "batteries": batteries, + "solarInverters": solar_inverters, + } + ) + if location is not UNSET: + field_dict["location"] = location + if operational_since is not UNSET: + field_dict["operationalSince"] = operational_since + if bess is not UNSET: + field_dict["bess"] = bess + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.battery_summary import BatterySummary + from ..models.site_bess import SiteBESS + from ..models.site_location import SiteLocation + from ..models.solar_inverter_summary import SolarInverterSummary + + d = src_dict.copy() + id = d.pop("id") + + vendor = Vendor(d.pop("vendor")) + + name = d.pop("name") + + location_utc_offset = d.pop("locationUTCOffset") + + batteries = [] + _batteries = d.pop("batteries") + for componentsschemas_site_batteries_item_data in _batteries: + componentsschemas_site_batteries_item = BatterySummary.from_dict(componentsschemas_site_batteries_item_data) + + batteries.append(componentsschemas_site_batteries_item) + + solar_inverters = [] + _solar_inverters = d.pop("solarInverters") + for componentsschemas_site_solar_inverters_item_data in _solar_inverters: + componentsschemas_site_solar_inverters_item = SolarInverterSummary.from_dict( + componentsschemas_site_solar_inverters_item_data + ) + + solar_inverters.append(componentsschemas_site_solar_inverters_item) + + _location = d.pop("location", UNSET) + location: Union[Unset, SiteLocation] + if isinstance(_location, Unset): + location = UNSET + else: + location = SiteLocation.from_dict(_location) + + _operational_since = d.pop("operationalSince", UNSET) + operational_since: Union[Unset, datetime.datetime] + if isinstance(_operational_since, Unset): + operational_since = UNSET + else: + operational_since = isoparse(_operational_since) + + _bess = d.pop("bess", UNSET) + bess: Union[Unset, SiteBESS] + if isinstance(_bess, Unset): + bess = UNSET + else: + bess = SiteBESS.from_dict(_bess) + + get_site_response = cls( + id=id, + vendor=vendor, + name=name, + location_utc_offset=location_utc_offset, + batteries=batteries, + solar_inverters=solar_inverters, + location=location, + operational_since=operational_since, + bess=bess, + ) + + return get_site_response diff --git a/derapi/models/get_site_solar_inverter_intervals_response.py b/derapi/models/get_site_solar_inverter_intervals_response.py new file mode 100644 index 0000000..156b362 --- /dev/null +++ b/derapi/models/get_site_solar_inverter_intervals_response.py @@ -0,0 +1,81 @@ +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define + +from ..models.summary_level import SummaryLevel +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.site_solar_inverter_interval import SiteSolarInverterInterval + + +T = TypeVar("T", bound="GetSiteSolarInverterIntervalsResponse") + + +@_attrs_define +class GetSiteSolarInverterIntervalsResponse: + """ + Attributes: + id (str): the ID for the Site + summary_level (SummaryLevel): + intervals (List['SiteSolarInverterInterval']): + next_page_token (Union[Unset, str]): A token to request the next page, if any. If absent, there are no more + pages. + """ + + id: str + summary_level: SummaryLevel + intervals: List["SiteSolarInverterInterval"] + next_page_token: Union[Unset, str] = UNSET + + def to_dict(self) -> Dict[str, Any]: + id = self.id + + summary_level = self.summary_level.value + + intervals = [] + for intervals_item_data in self.intervals: + intervals_item = intervals_item_data.to_dict() + intervals.append(intervals_item) + + next_page_token = self.next_page_token + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "summaryLevel": summary_level, + "intervals": intervals, + } + ) + if next_page_token is not UNSET: + field_dict["nextPageToken"] = next_page_token + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.site_solar_inverter_interval import SiteSolarInverterInterval + + d = src_dict.copy() + id = d.pop("id") + + summary_level = SummaryLevel(d.pop("summaryLevel")) + + intervals = [] + _intervals = d.pop("intervals") + for intervals_item_data in _intervals: + intervals_item = SiteSolarInverterInterval.from_dict(intervals_item_data) + + intervals.append(intervals_item) + + next_page_token = d.pop("nextPageToken", UNSET) + + get_site_solar_inverter_intervals_response = cls( + id=id, + summary_level=summary_level, + intervals=intervals, + next_page_token=next_page_token, + ) + + return get_site_solar_inverter_intervals_response diff --git a/derapi/models/get_solar_inverter_intervals_response.py b/derapi/models/get_solar_inverter_intervals_response.py new file mode 100644 index 0000000..a3108a2 --- /dev/null +++ b/derapi/models/get_solar_inverter_intervals_response.py @@ -0,0 +1,81 @@ +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define + +from ..models.summary_level import SummaryLevel +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.solar_inverter_interval import SolarInverterInterval + + +T = TypeVar("T", bound="GetSolarInverterIntervalsResponse") + + +@_attrs_define +class GetSolarInverterIntervalsResponse: + """ + Attributes: + id (str): ID of the solar inverter + summary_level (SummaryLevel): + intervals (List['SolarInverterInterval']): + next_page_token (Union[Unset, str]): A token to request the next page, if any. If absent, there are no more + pages. + """ + + id: str + summary_level: SummaryLevel + intervals: List["SolarInverterInterval"] + next_page_token: Union[Unset, str] = UNSET + + def to_dict(self) -> Dict[str, Any]: + id = self.id + + summary_level = self.summary_level.value + + intervals = [] + for intervals_item_data in self.intervals: + intervals_item = intervals_item_data.to_dict() + intervals.append(intervals_item) + + next_page_token = self.next_page_token + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "summaryLevel": summary_level, + "intervals": intervals, + } + ) + if next_page_token is not UNSET: + field_dict["nextPageToken"] = next_page_token + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.solar_inverter_interval import SolarInverterInterval + + d = src_dict.copy() + id = d.pop("id") + + summary_level = SummaryLevel(d.pop("summaryLevel")) + + intervals = [] + _intervals = d.pop("intervals") + for intervals_item_data in _intervals: + intervals_item = SolarInverterInterval.from_dict(intervals_item_data) + + intervals.append(intervals_item) + + next_page_token = d.pop("nextPageToken", UNSET) + + get_solar_inverter_intervals_response = cls( + id=id, + summary_level=summary_level, + intervals=intervals, + next_page_token=next_page_token, + ) + + return get_solar_inverter_intervals_response diff --git a/derapi/models/get_solar_inverter_response.py b/derapi/models/get_solar_inverter_response.py new file mode 100644 index 0000000..e413686 --- /dev/null +++ b/derapi/models/get_solar_inverter_response.py @@ -0,0 +1,249 @@ +import datetime +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..models.vendor import Vendor +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.solar_inverter_lifetime_production import SolarInverterLifetimeProduction + from ..models.solar_inverter_recent_errors_error import SolarInverterRecentErrorsError + from ..models.solar_inverter_recent_errors_info import SolarInverterRecentErrorsInfo + from ..models.solar_inverter_recent_errors_start import SolarInverterRecentErrorsStart + from ..models.solar_inverter_recent_errors_warning import SolarInverterRecentErrorsWarning + from ..models.solar_inverter_recent_production import SolarInverterRecentProduction + + +T = TypeVar("T", bound="GetSolarInverterResponse") + + +@_attrs_define +class GetSolarInverterResponse: + """ + Attributes: + id (str): ID of the solar inverter + vendor (Vendor): + reported_at (datetime.datetime): Date the request was generated in ISO-8601 format + model (str): Model number of this Solar Inverter + serial_number (str): Manufacturer serial number of this Solar Inverter + site_id (str): The Derapi Site ID this Solar Inverter is associated with + name (Union[Unset, str]): Customer defined name of this Solar Inverter + recent_production (Union[Unset, SolarInverterRecentProduction]): + lifetime_production (Union[Unset, SolarInverterLifetimeProduction]): + recent_errors (Union[Unset, List[Union['SolarInverterRecentErrorsError', 'SolarInverterRecentErrorsInfo', + 'SolarInverterRecentErrorsStart', 'SolarInverterRecentErrorsWarning']]]): Most recent errors, warnings, or info + reported by the manufacturer for this Solar Inverter. The key represents the severity level + (info/warning/error); the value is a string description. start is always present and is the last element to be + returned. + """ + + id: str + vendor: Vendor + reported_at: datetime.datetime + model: str + serial_number: str + site_id: str + name: Union[Unset, str] = UNSET + recent_production: Union[Unset, "SolarInverterRecentProduction"] = UNSET + lifetime_production: Union[Unset, "SolarInverterLifetimeProduction"] = UNSET + recent_errors: Union[ + Unset, + List[ + Union[ + "SolarInverterRecentErrorsError", + "SolarInverterRecentErrorsInfo", + "SolarInverterRecentErrorsStart", + "SolarInverterRecentErrorsWarning", + ] + ], + ] = UNSET + + def to_dict(self) -> Dict[str, Any]: + from ..models.solar_inverter_recent_errors_error import SolarInverterRecentErrorsError + from ..models.solar_inverter_recent_errors_info import SolarInverterRecentErrorsInfo + from ..models.solar_inverter_recent_errors_warning import SolarInverterRecentErrorsWarning + + id = self.id + + vendor = self.vendor.value + + reported_at = self.reported_at.isoformat() + + model = self.model + + serial_number = self.serial_number + + site_id = self.site_id + + name = self.name + + recent_production: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.recent_production, Unset): + recent_production = self.recent_production.to_dict() + + lifetime_production: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.lifetime_production, Unset): + lifetime_production = self.lifetime_production.to_dict() + + recent_errors: Union[Unset, List[Dict[str, Any]]] = UNSET + if not isinstance(self.recent_errors, Unset): + recent_errors = [] + for componentsschemas_solar_inverter_recent_errors_item_data in self.recent_errors: + componentsschemas_solar_inverter_recent_errors_item: Dict[str, Any] + if isinstance(componentsschemas_solar_inverter_recent_errors_item_data, SolarInverterRecentErrorsError): + componentsschemas_solar_inverter_recent_errors_item = ( + componentsschemas_solar_inverter_recent_errors_item_data.to_dict() + ) + elif isinstance( + componentsschemas_solar_inverter_recent_errors_item_data, SolarInverterRecentErrorsWarning + ): + componentsschemas_solar_inverter_recent_errors_item = ( + componentsschemas_solar_inverter_recent_errors_item_data.to_dict() + ) + elif isinstance( + componentsschemas_solar_inverter_recent_errors_item_data, SolarInverterRecentErrorsInfo + ): + componentsschemas_solar_inverter_recent_errors_item = ( + componentsschemas_solar_inverter_recent_errors_item_data.to_dict() + ) + else: + componentsschemas_solar_inverter_recent_errors_item = ( + componentsschemas_solar_inverter_recent_errors_item_data.to_dict() + ) + + recent_errors.append(componentsschemas_solar_inverter_recent_errors_item) + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "vendor": vendor, + "reportedAt": reported_at, + "model": model, + "serialNumber": serial_number, + "siteID": site_id, + } + ) + if name is not UNSET: + field_dict["name"] = name + if recent_production is not UNSET: + field_dict["recentProduction"] = recent_production + if lifetime_production is not UNSET: + field_dict["lifetimeProduction"] = lifetime_production + if recent_errors is not UNSET: + field_dict["recentErrors"] = recent_errors + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.solar_inverter_lifetime_production import SolarInverterLifetimeProduction + from ..models.solar_inverter_recent_errors_error import SolarInverterRecentErrorsError + from ..models.solar_inverter_recent_errors_info import SolarInverterRecentErrorsInfo + from ..models.solar_inverter_recent_errors_start import SolarInverterRecentErrorsStart + from ..models.solar_inverter_recent_errors_warning import SolarInverterRecentErrorsWarning + from ..models.solar_inverter_recent_production import SolarInverterRecentProduction + + d = src_dict.copy() + id = d.pop("id") + + vendor = Vendor(d.pop("vendor")) + + reported_at = isoparse(d.pop("reportedAt")) + + model = d.pop("model") + + serial_number = d.pop("serialNumber") + + site_id = d.pop("siteID") + + name = d.pop("name", UNSET) + + _recent_production = d.pop("recentProduction", UNSET) + recent_production: Union[Unset, SolarInverterRecentProduction] + if isinstance(_recent_production, Unset): + recent_production = UNSET + else: + recent_production = SolarInverterRecentProduction.from_dict(_recent_production) + + _lifetime_production = d.pop("lifetimeProduction", UNSET) + lifetime_production: Union[Unset, SolarInverterLifetimeProduction] + if isinstance(_lifetime_production, Unset): + lifetime_production = UNSET + else: + lifetime_production = SolarInverterLifetimeProduction.from_dict(_lifetime_production) + + recent_errors = [] + _recent_errors = d.pop("recentErrors", UNSET) + for componentsschemas_solar_inverter_recent_errors_item_data in _recent_errors or []: + + def _parse_componentsschemas_solar_inverter_recent_errors_item( + data: object, + ) -> Union[ + "SolarInverterRecentErrorsError", + "SolarInverterRecentErrorsInfo", + "SolarInverterRecentErrorsStart", + "SolarInverterRecentErrorsWarning", + ]: + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_solar_inverter_recent_errors_item_type_0 = ( + SolarInverterRecentErrorsError.from_dict(data) + ) + + return componentsschemas_solar_inverter_recent_errors_item_type_0 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_solar_inverter_recent_errors_item_type_1 = ( + SolarInverterRecentErrorsWarning.from_dict(data) + ) + + return componentsschemas_solar_inverter_recent_errors_item_type_1 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_solar_inverter_recent_errors_item_type_2 = ( + SolarInverterRecentErrorsInfo.from_dict(data) + ) + + return componentsschemas_solar_inverter_recent_errors_item_type_2 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + componentsschemas_solar_inverter_recent_errors_item_type_3 = SolarInverterRecentErrorsStart.from_dict( + data + ) + + return componentsschemas_solar_inverter_recent_errors_item_type_3 + + componentsschemas_solar_inverter_recent_errors_item = ( + _parse_componentsschemas_solar_inverter_recent_errors_item( + componentsschemas_solar_inverter_recent_errors_item_data + ) + ) + + recent_errors.append(componentsschemas_solar_inverter_recent_errors_item) + + get_solar_inverter_response = cls( + id=id, + vendor=vendor, + reported_at=reported_at, + model=model, + serial_number=serial_number, + site_id=site_id, + name=name, + recent_production=recent_production, + lifetime_production=lifetime_production, + recent_errors=recent_errors, + ) + + return get_solar_inverter_response diff --git a/derapi/models/get_vendor_credentials_response.py b/derapi/models/get_vendor_credentials_response.py new file mode 100644 index 0000000..905dedf --- /dev/null +++ b/derapi/models/get_vendor_credentials_response.py @@ -0,0 +1,420 @@ +from typing import TYPE_CHECKING, Any, Dict, Type, TypeVar, Union + +from attrs import define as _attrs_define + +if TYPE_CHECKING: + from ..models.enphase_developer_app_credentials import EnphaseDeveloperAppCredentials + from ..models.enphase_partner_app_credentials import EnphasePartnerAppCredentials + from ..models.enphase_vpp_credentials import EnphaseVPPCredentials + from ..models.franklin_wh_credentials import FranklinWHCredentials + from ..models.hidden_enphase_developer_app_credentials import HiddenEnphaseDeveloperAppCredentials + from ..models.hidden_enphase_partner_app_credentials import HiddenEnphasePartnerAppCredentials + from ..models.hidden_enphase_vpp_credentials import HiddenEnphaseVPPCredentials + from ..models.hidden_franklin_wh_credentials import HiddenFranklinWHCredentials + from ..models.hidden_sma_custom_grant_credentials import HiddenSMACustomGrantCredentials + from ..models.hidden_sma_sandbox_custom_grant_credentials import HiddenSMASandboxCustomGrantCredentials + from ..models.hidden_sma_sandbox_o_auth_credentials import HiddenSMASandboxOAuthCredentials + from ..models.hidden_smao_auth_credentials import HiddenSMAOAuthCredentials + from ..models.hidden_solar_edge_credentials import HiddenSolarEdgeCredentials + from ..models.hidden_solis_credentials import HiddenSolisCredentials + from ..models.hidden_tesla_app_credentials import HiddenTeslaAppCredentials + from ..models.sma_custom_grant_credentials import SMACustomGrantCredentials + from ..models.sma_sandbox_custom_grant_credentials import SMASandboxCustomGrantCredentials + from ..models.sma_sandbox_o_auth_credentials import SMASandboxOAuthCredentials + from ..models.smao_auth_credentials import SMAOAuthCredentials + from ..models.solar_edge_credentials import SolarEdgeCredentials + from ..models.solis_credentials import SolisCredentials + from ..models.tesla_app_credentials import TeslaAppCredentials + + +T = TypeVar("T", bound="GetVendorCredentialsResponse") + + +@_attrs_define +class GetVendorCredentialsResponse: + """Vendor credentials which may or may not be hidden. + + Attributes: + id (str): ID for the vendor credentials + name (str): The name of the vendor credentials; inferred if not provided. + credentials (Union['EnphaseDeveloperAppCredentials', 'EnphasePartnerAppCredentials', 'EnphaseVPPCredentials', + 'FranklinWHCredentials', 'HiddenEnphaseDeveloperAppCredentials', 'HiddenEnphasePartnerAppCredentials', + 'HiddenEnphaseVPPCredentials', 'HiddenFranklinWHCredentials', 'HiddenSMACustomGrantCredentials', + 'HiddenSMAOAuthCredentials', 'HiddenSMASandboxCustomGrantCredentials', 'HiddenSMASandboxOAuthCredentials', + 'HiddenSolarEdgeCredentials', 'HiddenSolisCredentials', 'HiddenTeslaAppCredentials', + 'SMACustomGrantCredentials', 'SMAOAuthCredentials', 'SMASandboxCustomGrantCredentials', + 'SMASandboxOAuthCredentials', 'SolarEdgeCredentials', 'SolisCredentials', 'TeslaAppCredentials']): + """ + + id: str + name: str + credentials: Union[ + "EnphaseDeveloperAppCredentials", + "EnphasePartnerAppCredentials", + "EnphaseVPPCredentials", + "FranklinWHCredentials", + "HiddenEnphaseDeveloperAppCredentials", + "HiddenEnphasePartnerAppCredentials", + "HiddenEnphaseVPPCredentials", + "HiddenFranklinWHCredentials", + "HiddenSMACustomGrantCredentials", + "HiddenSMAOAuthCredentials", + "HiddenSMASandboxCustomGrantCredentials", + "HiddenSMASandboxOAuthCredentials", + "HiddenSolarEdgeCredentials", + "HiddenSolisCredentials", + "HiddenTeslaAppCredentials", + "SMACustomGrantCredentials", + "SMAOAuthCredentials", + "SMASandboxCustomGrantCredentials", + "SMASandboxOAuthCredentials", + "SolarEdgeCredentials", + "SolisCredentials", + "TeslaAppCredentials", + ] + + def to_dict(self) -> Dict[str, Any]: + from ..models.enphase_developer_app_credentials import EnphaseDeveloperAppCredentials + from ..models.enphase_partner_app_credentials import EnphasePartnerAppCredentials + from ..models.enphase_vpp_credentials import EnphaseVPPCredentials + from ..models.franklin_wh_credentials import FranklinWHCredentials + from ..models.hidden_enphase_developer_app_credentials import HiddenEnphaseDeveloperAppCredentials + from ..models.hidden_enphase_partner_app_credentials import HiddenEnphasePartnerAppCredentials + from ..models.hidden_enphase_vpp_credentials import HiddenEnphaseVPPCredentials + from ..models.hidden_franklin_wh_credentials import HiddenFranklinWHCredentials + from ..models.hidden_sma_custom_grant_credentials import HiddenSMACustomGrantCredentials + from ..models.hidden_sma_sandbox_custom_grant_credentials import HiddenSMASandboxCustomGrantCredentials + from ..models.hidden_sma_sandbox_o_auth_credentials import HiddenSMASandboxOAuthCredentials + from ..models.hidden_smao_auth_credentials import HiddenSMAOAuthCredentials + from ..models.hidden_solar_edge_credentials import HiddenSolarEdgeCredentials + from ..models.hidden_solis_credentials import HiddenSolisCredentials + from ..models.hidden_tesla_app_credentials import HiddenTeslaAppCredentials + from ..models.sma_custom_grant_credentials import SMACustomGrantCredentials + from ..models.sma_sandbox_custom_grant_credentials import SMASandboxCustomGrantCredentials + from ..models.sma_sandbox_o_auth_credentials import SMASandboxOAuthCredentials + from ..models.smao_auth_credentials import SMAOAuthCredentials + from ..models.solar_edge_credentials import SolarEdgeCredentials + from ..models.solis_credentials import SolisCredentials + + id = self.id + + name = self.name + + credentials: Dict[str, Any] + if isinstance(self.credentials, HiddenEnphaseDeveloperAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenEnphasePartnerAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenEnphaseVPPCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenFranklinWHCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSMACustomGrantCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSMAOAuthCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSMASandboxCustomGrantCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSMASandboxOAuthCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSolarEdgeCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSolisCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenTeslaAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, EnphasePartnerAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, EnphaseDeveloperAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, EnphaseVPPCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, FranklinWHCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMACustomGrantCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMAOAuthCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMASandboxCustomGrantCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMASandboxOAuthCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SolarEdgeCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SolisCredentials): + credentials = self.credentials.to_dict() + else: + credentials = self.credentials.to_dict() + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "name": name, + "credentials": credentials, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.enphase_developer_app_credentials import EnphaseDeveloperAppCredentials + from ..models.enphase_partner_app_credentials import EnphasePartnerAppCredentials + from ..models.enphase_vpp_credentials import EnphaseVPPCredentials + from ..models.franklin_wh_credentials import FranklinWHCredentials + from ..models.hidden_enphase_developer_app_credentials import HiddenEnphaseDeveloperAppCredentials + from ..models.hidden_enphase_partner_app_credentials import HiddenEnphasePartnerAppCredentials + from ..models.hidden_enphase_vpp_credentials import HiddenEnphaseVPPCredentials + from ..models.hidden_franklin_wh_credentials import HiddenFranklinWHCredentials + from ..models.hidden_sma_custom_grant_credentials import HiddenSMACustomGrantCredentials + from ..models.hidden_sma_sandbox_custom_grant_credentials import HiddenSMASandboxCustomGrantCredentials + from ..models.hidden_sma_sandbox_o_auth_credentials import HiddenSMASandboxOAuthCredentials + from ..models.hidden_smao_auth_credentials import HiddenSMAOAuthCredentials + from ..models.hidden_solar_edge_credentials import HiddenSolarEdgeCredentials + from ..models.hidden_solis_credentials import HiddenSolisCredentials + from ..models.hidden_tesla_app_credentials import HiddenTeslaAppCredentials + from ..models.sma_custom_grant_credentials import SMACustomGrantCredentials + from ..models.sma_sandbox_custom_grant_credentials import SMASandboxCustomGrantCredentials + from ..models.sma_sandbox_o_auth_credentials import SMASandboxOAuthCredentials + from ..models.smao_auth_credentials import SMAOAuthCredentials + from ..models.solar_edge_credentials import SolarEdgeCredentials + from ..models.solis_credentials import SolisCredentials + from ..models.tesla_app_credentials import TeslaAppCredentials + + d = src_dict.copy() + id = d.pop("id") + + name = d.pop("name") + + def _parse_credentials( + data: object, + ) -> Union[ + "EnphaseDeveloperAppCredentials", + "EnphasePartnerAppCredentials", + "EnphaseVPPCredentials", + "FranklinWHCredentials", + "HiddenEnphaseDeveloperAppCredentials", + "HiddenEnphasePartnerAppCredentials", + "HiddenEnphaseVPPCredentials", + "HiddenFranklinWHCredentials", + "HiddenSMACustomGrantCredentials", + "HiddenSMAOAuthCredentials", + "HiddenSMASandboxCustomGrantCredentials", + "HiddenSMASandboxOAuthCredentials", + "HiddenSolarEdgeCredentials", + "HiddenSolisCredentials", + "HiddenTeslaAppCredentials", + "SMACustomGrantCredentials", + "SMAOAuthCredentials", + "SMASandboxCustomGrantCredentials", + "SMASandboxOAuthCredentials", + "SolarEdgeCredentials", + "SolisCredentials", + "TeslaAppCredentials", + ]: + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_0 = ( + HiddenEnphaseDeveloperAppCredentials.from_dict(data) + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_0 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_1 = ( + HiddenEnphasePartnerAppCredentials.from_dict(data) + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_1 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_2 = HiddenEnphaseVPPCredentials.from_dict( + data + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_2 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_3 = HiddenFranklinWHCredentials.from_dict( + data + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_3 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_4 = ( + HiddenSMACustomGrantCredentials.from_dict(data) + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_4 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_5 = HiddenSMAOAuthCredentials.from_dict( + data + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_5 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_6 = ( + HiddenSMASandboxCustomGrantCredentials.from_dict(data) + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_6 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_7 = ( + HiddenSMASandboxOAuthCredentials.from_dict(data) + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_7 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_8 = HiddenSolarEdgeCredentials.from_dict( + data + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_8 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_9 = HiddenSolisCredentials.from_dict(data) + + return componentsschemas_hidden_vendor_credentials_credentials_type_9 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_10 = HiddenTeslaAppCredentials.from_dict( + data + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_10 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_0 = EnphasePartnerAppCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_0 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_1 = EnphaseDeveloperAppCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_1 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_2 = EnphaseVPPCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_2 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_3 = FranklinWHCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_3 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_4 = SMACustomGrantCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_4 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_5 = SMAOAuthCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_5 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_6 = SMASandboxCustomGrantCredentials.from_dict( + data + ) + + return componentsschemas_vendor_credentials_credentials_type_6 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_7 = SMASandboxOAuthCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_7 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_8 = SolarEdgeCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_8 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_9 = SolisCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_9 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_10 = TeslaAppCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_10 + + credentials = _parse_credentials(d.pop("credentials")) + + get_vendor_credentials_response = cls( + id=id, + name=name, + credentials=credentials, + ) + + return get_vendor_credentials_response diff --git a/derapi/models/get_virtual_battery_response.py b/derapi/models/get_virtual_battery_response.py new file mode 100644 index 0000000..559076d --- /dev/null +++ b/derapi/models/get_virtual_battery_response.py @@ -0,0 +1,236 @@ +import datetime +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..models.battery_mode import BatteryMode +from ..models.vendor import Vendor +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.battery_recent_errors_error import BatteryRecentErrorsError + from ..models.battery_recent_errors_info import BatteryRecentErrorsInfo + from ..models.battery_recent_errors_start import BatteryRecentErrorsStart + from ..models.battery_recent_errors_warning import BatteryRecentErrorsWarning + + +T = TypeVar("T", bound="GetVirtualBatteryResponse") + + +@_attrs_define +class GetVirtualBatteryResponse: + """ + Attributes: + id (str): Battery id + vendor (Vendor): + reported_at (datetime.datetime): Date the request was generated in ISO-8601 format (timezone is always +00:00 + and is always present) + model (str): Model number of Battery + serial_number (str): Manufacturer serial number of the Battery + site_id (str): The Derapi Site ID this Battery is associated with + name (Union[Unset, str]): Customer defined name of the Battery + nameplate_kwh (Union[Unset, float]): The rated storage capacity of the unit + mode (Union[Unset, BatteryMode]): Battery management system mode. Values are Self Consumption - minimize grid + import, Savings - optimizing Battery to save money; usually based on a rate plan, Backup - only use Battery for + grid backup + state_of_charge_percent (Union[Unset, float]): Battery state of charge as a percent of capacity + recent_errors (Union[Unset, List[Union['BatteryRecentErrorsError', 'BatteryRecentErrorsInfo', + 'BatteryRecentErrorsStart', 'BatteryRecentErrorsWarning']]]): Most recent errors, warnings, or info reported by + the manufacturer for this Battery. The key represents the severity level (info/warning/error); the value is a + string description. start is always present and is the last element to be returned. + """ + + id: str + vendor: Vendor + reported_at: datetime.datetime + model: str + serial_number: str + site_id: str + name: Union[Unset, str] = UNSET + nameplate_kwh: Union[Unset, float] = UNSET + mode: Union[Unset, BatteryMode] = UNSET + state_of_charge_percent: Union[Unset, float] = UNSET + recent_errors: Union[ + Unset, + List[ + Union[ + "BatteryRecentErrorsError", + "BatteryRecentErrorsInfo", + "BatteryRecentErrorsStart", + "BatteryRecentErrorsWarning", + ] + ], + ] = UNSET + + def to_dict(self) -> Dict[str, Any]: + from ..models.battery_recent_errors_error import BatteryRecentErrorsError + from ..models.battery_recent_errors_info import BatteryRecentErrorsInfo + from ..models.battery_recent_errors_warning import BatteryRecentErrorsWarning + + id = self.id + + vendor = self.vendor.value + + reported_at = self.reported_at.isoformat() + + model = self.model + + serial_number = self.serial_number + + site_id = self.site_id + + name = self.name + + nameplate_kwh = self.nameplate_kwh + + mode: Union[Unset, str] = UNSET + if not isinstance(self.mode, Unset): + mode = self.mode.value + + state_of_charge_percent = self.state_of_charge_percent + + recent_errors: Union[Unset, List[Dict[str, Any]]] = UNSET + if not isinstance(self.recent_errors, Unset): + recent_errors = [] + for componentsschemas_battery_recent_errors_item_data in self.recent_errors: + componentsschemas_battery_recent_errors_item: Dict[str, Any] + if isinstance(componentsschemas_battery_recent_errors_item_data, BatteryRecentErrorsError): + componentsschemas_battery_recent_errors_item = ( + componentsschemas_battery_recent_errors_item_data.to_dict() + ) + elif isinstance(componentsschemas_battery_recent_errors_item_data, BatteryRecentErrorsWarning): + componentsschemas_battery_recent_errors_item = ( + componentsschemas_battery_recent_errors_item_data.to_dict() + ) + elif isinstance(componentsschemas_battery_recent_errors_item_data, BatteryRecentErrorsInfo): + componentsschemas_battery_recent_errors_item = ( + componentsschemas_battery_recent_errors_item_data.to_dict() + ) + else: + componentsschemas_battery_recent_errors_item = ( + componentsschemas_battery_recent_errors_item_data.to_dict() + ) + + recent_errors.append(componentsschemas_battery_recent_errors_item) + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "vendor": vendor, + "reportedAt": reported_at, + "model": model, + "serialNumber": serial_number, + "siteID": site_id, + } + ) + if name is not UNSET: + field_dict["name"] = name + if nameplate_kwh is not UNSET: + field_dict["nameplateKwh"] = nameplate_kwh + if mode is not UNSET: + field_dict["mode"] = mode + if state_of_charge_percent is not UNSET: + field_dict["stateOfChargePercent"] = state_of_charge_percent + if recent_errors is not UNSET: + field_dict["recentErrors"] = recent_errors + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.battery_recent_errors_error import BatteryRecentErrorsError + from ..models.battery_recent_errors_info import BatteryRecentErrorsInfo + from ..models.battery_recent_errors_start import BatteryRecentErrorsStart + from ..models.battery_recent_errors_warning import BatteryRecentErrorsWarning + + d = src_dict.copy() + id = d.pop("id") + + vendor = Vendor(d.pop("vendor")) + + reported_at = isoparse(d.pop("reportedAt")) + + model = d.pop("model") + + serial_number = d.pop("serialNumber") + + site_id = d.pop("siteID") + + name = d.pop("name", UNSET) + + nameplate_kwh = d.pop("nameplateKwh", UNSET) + + _mode = d.pop("mode", UNSET) + mode: Union[Unset, BatteryMode] + if isinstance(_mode, Unset): + mode = UNSET + else: + mode = BatteryMode(_mode) + + state_of_charge_percent = d.pop("stateOfChargePercent", UNSET) + + recent_errors = [] + _recent_errors = d.pop("recentErrors", UNSET) + for componentsschemas_battery_recent_errors_item_data in _recent_errors or []: + + def _parse_componentsschemas_battery_recent_errors_item( + data: object, + ) -> Union[ + "BatteryRecentErrorsError", + "BatteryRecentErrorsInfo", + "BatteryRecentErrorsStart", + "BatteryRecentErrorsWarning", + ]: + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_battery_recent_errors_item_type_0 = BatteryRecentErrorsError.from_dict(data) + + return componentsschemas_battery_recent_errors_item_type_0 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_battery_recent_errors_item_type_1 = BatteryRecentErrorsWarning.from_dict(data) + + return componentsschemas_battery_recent_errors_item_type_1 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_battery_recent_errors_item_type_2 = BatteryRecentErrorsInfo.from_dict(data) + + return componentsschemas_battery_recent_errors_item_type_2 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + componentsschemas_battery_recent_errors_item_type_3 = BatteryRecentErrorsStart.from_dict(data) + + return componentsschemas_battery_recent_errors_item_type_3 + + componentsschemas_battery_recent_errors_item = _parse_componentsschemas_battery_recent_errors_item( + componentsschemas_battery_recent_errors_item_data + ) + + recent_errors.append(componentsschemas_battery_recent_errors_item) + + get_virtual_battery_response = cls( + id=id, + vendor=vendor, + reported_at=reported_at, + model=model, + serial_number=serial_number, + site_id=site_id, + name=name, + nameplate_kwh=nameplate_kwh, + mode=mode, + state_of_charge_percent=state_of_charge_percent, + recent_errors=recent_errors, + ) + + return get_virtual_battery_response diff --git a/derapi/models/get_virtual_site_response.py b/derapi/models/get_virtual_site_response.py new file mode 100644 index 0000000..9b058f3 --- /dev/null +++ b/derapi/models/get_virtual_site_response.py @@ -0,0 +1,163 @@ +import datetime +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..models.vendor import Vendor +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.battery_summary import BatterySummary + from ..models.site_bess import SiteBESS + from ..models.site_location import SiteLocation + from ..models.solar_inverter_summary import SolarInverterSummary + + +T = TypeVar("T", bound="GetVirtualSiteResponse") + + +@_attrs_define +class GetVirtualSiteResponse: + """ + Attributes: + id (str): the ID for the Site + vendor (Vendor): + name (str): Customer defined name of the Site + location_utc_offset (float): UTC Offset in hours; positive values represent locations East of UTC. Please note + this field will soon be deprecated, please use `timezone` instead. + batteries (List['BatterySummary']): List of Battery IDs associated with this Site + solar_inverters (List['SolarInverterSummary']): List of Solar Inverter IDs associated with this Site + location (Union[Unset, SiteLocation]): The location of this Solar Inverter in lat/lon coordinates + operational_since (Union[Unset, datetime.datetime]): The date the Site became operational or received permission + to operate. Sometimes absent for Solaredge. + bess (Union[Unset, SiteBESS]): For Sites with Batteries this key is present + """ + + id: str + vendor: Vendor + name: str + location_utc_offset: float + batteries: List["BatterySummary"] + solar_inverters: List["SolarInverterSummary"] + location: Union[Unset, "SiteLocation"] = UNSET + operational_since: Union[Unset, datetime.datetime] = UNSET + bess: Union[Unset, "SiteBESS"] = UNSET + + def to_dict(self) -> Dict[str, Any]: + id = self.id + + vendor = self.vendor.value + + name = self.name + + location_utc_offset = self.location_utc_offset + + batteries = [] + for componentsschemas_site_batteries_item_data in self.batteries: + componentsschemas_site_batteries_item = componentsschemas_site_batteries_item_data.to_dict() + batteries.append(componentsschemas_site_batteries_item) + + solar_inverters = [] + for componentsschemas_site_solar_inverters_item_data in self.solar_inverters: + componentsschemas_site_solar_inverters_item = componentsschemas_site_solar_inverters_item_data.to_dict() + solar_inverters.append(componentsschemas_site_solar_inverters_item) + + location: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.location, Unset): + location = self.location.to_dict() + + operational_since: Union[Unset, str] = UNSET + if not isinstance(self.operational_since, Unset): + operational_since = self.operational_since.isoformat() + + bess: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.bess, Unset): + bess = self.bess.to_dict() + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "vendor": vendor, + "name": name, + "locationUTCOffset": location_utc_offset, + "batteries": batteries, + "solarInverters": solar_inverters, + } + ) + if location is not UNSET: + field_dict["location"] = location + if operational_since is not UNSET: + field_dict["operationalSince"] = operational_since + if bess is not UNSET: + field_dict["bess"] = bess + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.battery_summary import BatterySummary + from ..models.site_bess import SiteBESS + from ..models.site_location import SiteLocation + from ..models.solar_inverter_summary import SolarInverterSummary + + d = src_dict.copy() + id = d.pop("id") + + vendor = Vendor(d.pop("vendor")) + + name = d.pop("name") + + location_utc_offset = d.pop("locationUTCOffset") + + batteries = [] + _batteries = d.pop("batteries") + for componentsschemas_site_batteries_item_data in _batteries: + componentsschemas_site_batteries_item = BatterySummary.from_dict(componentsschemas_site_batteries_item_data) + + batteries.append(componentsschemas_site_batteries_item) + + solar_inverters = [] + _solar_inverters = d.pop("solarInverters") + for componentsschemas_site_solar_inverters_item_data in _solar_inverters: + componentsschemas_site_solar_inverters_item = SolarInverterSummary.from_dict( + componentsschemas_site_solar_inverters_item_data + ) + + solar_inverters.append(componentsschemas_site_solar_inverters_item) + + _location = d.pop("location", UNSET) + location: Union[Unset, SiteLocation] + if isinstance(_location, Unset): + location = UNSET + else: + location = SiteLocation.from_dict(_location) + + _operational_since = d.pop("operationalSince", UNSET) + operational_since: Union[Unset, datetime.datetime] + if isinstance(_operational_since, Unset): + operational_since = UNSET + else: + operational_since = isoparse(_operational_since) + + _bess = d.pop("bess", UNSET) + bess: Union[Unset, SiteBESS] + if isinstance(_bess, Unset): + bess = UNSET + else: + bess = SiteBESS.from_dict(_bess) + + get_virtual_site_response = cls( + id=id, + vendor=vendor, + name=name, + location_utc_offset=location_utc_offset, + batteries=batteries, + solar_inverters=solar_inverters, + location=location, + operational_since=operational_since, + bess=bess, + ) + + return get_virtual_site_response diff --git a/derapi/models/get_virtual_solar_inverter_response.py b/derapi/models/get_virtual_solar_inverter_response.py new file mode 100644 index 0000000..f9f5465 --- /dev/null +++ b/derapi/models/get_virtual_solar_inverter_response.py @@ -0,0 +1,249 @@ +import datetime +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..models.vendor import Vendor +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.solar_inverter_lifetime_production import SolarInverterLifetimeProduction + from ..models.solar_inverter_recent_errors_error import SolarInverterRecentErrorsError + from ..models.solar_inverter_recent_errors_info import SolarInverterRecentErrorsInfo + from ..models.solar_inverter_recent_errors_start import SolarInverterRecentErrorsStart + from ..models.solar_inverter_recent_errors_warning import SolarInverterRecentErrorsWarning + from ..models.solar_inverter_recent_production import SolarInverterRecentProduction + + +T = TypeVar("T", bound="GetVirtualSolarInverterResponse") + + +@_attrs_define +class GetVirtualSolarInverterResponse: + """ + Attributes: + id (str): ID of the solar inverter + vendor (Vendor): + reported_at (datetime.datetime): Date the request was generated in ISO-8601 format + model (str): Model number of this Solar Inverter + serial_number (str): Manufacturer serial number of this Solar Inverter + site_id (str): The Derapi Site ID this Solar Inverter is associated with + name (Union[Unset, str]): Customer defined name of this Solar Inverter + recent_production (Union[Unset, SolarInverterRecentProduction]): + lifetime_production (Union[Unset, SolarInverterLifetimeProduction]): + recent_errors (Union[Unset, List[Union['SolarInverterRecentErrorsError', 'SolarInverterRecentErrorsInfo', + 'SolarInverterRecentErrorsStart', 'SolarInverterRecentErrorsWarning']]]): Most recent errors, warnings, or info + reported by the manufacturer for this Solar Inverter. The key represents the severity level + (info/warning/error); the value is a string description. start is always present and is the last element to be + returned. + """ + + id: str + vendor: Vendor + reported_at: datetime.datetime + model: str + serial_number: str + site_id: str + name: Union[Unset, str] = UNSET + recent_production: Union[Unset, "SolarInverterRecentProduction"] = UNSET + lifetime_production: Union[Unset, "SolarInverterLifetimeProduction"] = UNSET + recent_errors: Union[ + Unset, + List[ + Union[ + "SolarInverterRecentErrorsError", + "SolarInverterRecentErrorsInfo", + "SolarInverterRecentErrorsStart", + "SolarInverterRecentErrorsWarning", + ] + ], + ] = UNSET + + def to_dict(self) -> Dict[str, Any]: + from ..models.solar_inverter_recent_errors_error import SolarInverterRecentErrorsError + from ..models.solar_inverter_recent_errors_info import SolarInverterRecentErrorsInfo + from ..models.solar_inverter_recent_errors_warning import SolarInverterRecentErrorsWarning + + id = self.id + + vendor = self.vendor.value + + reported_at = self.reported_at.isoformat() + + model = self.model + + serial_number = self.serial_number + + site_id = self.site_id + + name = self.name + + recent_production: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.recent_production, Unset): + recent_production = self.recent_production.to_dict() + + lifetime_production: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.lifetime_production, Unset): + lifetime_production = self.lifetime_production.to_dict() + + recent_errors: Union[Unset, List[Dict[str, Any]]] = UNSET + if not isinstance(self.recent_errors, Unset): + recent_errors = [] + for componentsschemas_solar_inverter_recent_errors_item_data in self.recent_errors: + componentsschemas_solar_inverter_recent_errors_item: Dict[str, Any] + if isinstance(componentsschemas_solar_inverter_recent_errors_item_data, SolarInverterRecentErrorsError): + componentsschemas_solar_inverter_recent_errors_item = ( + componentsschemas_solar_inverter_recent_errors_item_data.to_dict() + ) + elif isinstance( + componentsschemas_solar_inverter_recent_errors_item_data, SolarInverterRecentErrorsWarning + ): + componentsschemas_solar_inverter_recent_errors_item = ( + componentsschemas_solar_inverter_recent_errors_item_data.to_dict() + ) + elif isinstance( + componentsschemas_solar_inverter_recent_errors_item_data, SolarInverterRecentErrorsInfo + ): + componentsschemas_solar_inverter_recent_errors_item = ( + componentsschemas_solar_inverter_recent_errors_item_data.to_dict() + ) + else: + componentsschemas_solar_inverter_recent_errors_item = ( + componentsschemas_solar_inverter_recent_errors_item_data.to_dict() + ) + + recent_errors.append(componentsschemas_solar_inverter_recent_errors_item) + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "vendor": vendor, + "reportedAt": reported_at, + "model": model, + "serialNumber": serial_number, + "siteID": site_id, + } + ) + if name is not UNSET: + field_dict["name"] = name + if recent_production is not UNSET: + field_dict["recentProduction"] = recent_production + if lifetime_production is not UNSET: + field_dict["lifetimeProduction"] = lifetime_production + if recent_errors is not UNSET: + field_dict["recentErrors"] = recent_errors + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.solar_inverter_lifetime_production import SolarInverterLifetimeProduction + from ..models.solar_inverter_recent_errors_error import SolarInverterRecentErrorsError + from ..models.solar_inverter_recent_errors_info import SolarInverterRecentErrorsInfo + from ..models.solar_inverter_recent_errors_start import SolarInverterRecentErrorsStart + from ..models.solar_inverter_recent_errors_warning import SolarInverterRecentErrorsWarning + from ..models.solar_inverter_recent_production import SolarInverterRecentProduction + + d = src_dict.copy() + id = d.pop("id") + + vendor = Vendor(d.pop("vendor")) + + reported_at = isoparse(d.pop("reportedAt")) + + model = d.pop("model") + + serial_number = d.pop("serialNumber") + + site_id = d.pop("siteID") + + name = d.pop("name", UNSET) + + _recent_production = d.pop("recentProduction", UNSET) + recent_production: Union[Unset, SolarInverterRecentProduction] + if isinstance(_recent_production, Unset): + recent_production = UNSET + else: + recent_production = SolarInverterRecentProduction.from_dict(_recent_production) + + _lifetime_production = d.pop("lifetimeProduction", UNSET) + lifetime_production: Union[Unset, SolarInverterLifetimeProduction] + if isinstance(_lifetime_production, Unset): + lifetime_production = UNSET + else: + lifetime_production = SolarInverterLifetimeProduction.from_dict(_lifetime_production) + + recent_errors = [] + _recent_errors = d.pop("recentErrors", UNSET) + for componentsschemas_solar_inverter_recent_errors_item_data in _recent_errors or []: + + def _parse_componentsschemas_solar_inverter_recent_errors_item( + data: object, + ) -> Union[ + "SolarInverterRecentErrorsError", + "SolarInverterRecentErrorsInfo", + "SolarInverterRecentErrorsStart", + "SolarInverterRecentErrorsWarning", + ]: + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_solar_inverter_recent_errors_item_type_0 = ( + SolarInverterRecentErrorsError.from_dict(data) + ) + + return componentsschemas_solar_inverter_recent_errors_item_type_0 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_solar_inverter_recent_errors_item_type_1 = ( + SolarInverterRecentErrorsWarning.from_dict(data) + ) + + return componentsschemas_solar_inverter_recent_errors_item_type_1 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_solar_inverter_recent_errors_item_type_2 = ( + SolarInverterRecentErrorsInfo.from_dict(data) + ) + + return componentsschemas_solar_inverter_recent_errors_item_type_2 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + componentsschemas_solar_inverter_recent_errors_item_type_3 = SolarInverterRecentErrorsStart.from_dict( + data + ) + + return componentsschemas_solar_inverter_recent_errors_item_type_3 + + componentsschemas_solar_inverter_recent_errors_item = ( + _parse_componentsschemas_solar_inverter_recent_errors_item( + componentsschemas_solar_inverter_recent_errors_item_data + ) + ) + + recent_errors.append(componentsschemas_solar_inverter_recent_errors_item) + + get_virtual_solar_inverter_response = cls( + id=id, + vendor=vendor, + reported_at=reported_at, + model=model, + serial_number=serial_number, + site_id=site_id, + name=name, + recent_production=recent_production, + lifetime_production=lifetime_production, + recent_errors=recent_errors, + ) + + return get_virtual_solar_inverter_response diff --git a/derapi/models/hidden_enphase_developer_app_credentials.py b/derapi/models/hidden_enphase_developer_app_credentials.py new file mode 100644 index 0000000..ed966eb --- /dev/null +++ b/derapi/models/hidden_enphase_developer_app_credentials.py @@ -0,0 +1,50 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="HiddenEnphaseDeveloperAppCredentials") + + +@_attrs_define +class HiddenEnphaseDeveloperAppCredentials: + """ + Attributes: + type (Literal['developerapp']): Default: 'developerapp'. + vendor (Literal['enphase']): Default: 'enphase'. + """ + + type: Literal["developerapp"] = "developerapp" + vendor: Literal["enphase"] = "enphase" + + def to_dict(self) -> Dict[str, Any]: + type = self.type + + vendor = self.vendor + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "type": type, + "vendor": vendor, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + type = cast(Literal["developerapp"], d.pop("type")) + if type != "developerapp": + raise ValueError(f"type must match const 'developerapp', got '{type}'") + + vendor = cast(Literal["enphase"], d.pop("vendor")) + if vendor != "enphase": + raise ValueError(f"vendor must match const 'enphase', got '{vendor}'") + + hidden_enphase_developer_app_credentials = cls( + type=type, + vendor=vendor, + ) + + return hidden_enphase_developer_app_credentials diff --git a/derapi/models/hidden_enphase_partner_app_credentials.py b/derapi/models/hidden_enphase_partner_app_credentials.py new file mode 100644 index 0000000..4fec65d --- /dev/null +++ b/derapi/models/hidden_enphase_partner_app_credentials.py @@ -0,0 +1,51 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="HiddenEnphasePartnerAppCredentials") + + +@_attrs_define +class HiddenEnphasePartnerAppCredentials: + """Credentials for an Enphase partner app + + Attributes: + type (Literal['partnerapp']): Default: 'partnerapp'. + vendor (Literal['enphase']): Default: 'enphase'. + """ + + type: Literal["partnerapp"] = "partnerapp" + vendor: Literal["enphase"] = "enphase" + + def to_dict(self) -> Dict[str, Any]: + type = self.type + + vendor = self.vendor + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "type": type, + "vendor": vendor, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + type = cast(Literal["partnerapp"], d.pop("type")) + if type != "partnerapp": + raise ValueError(f"type must match const 'partnerapp', got '{type}'") + + vendor = cast(Literal["enphase"], d.pop("vendor")) + if vendor != "enphase": + raise ValueError(f"vendor must match const 'enphase', got '{vendor}'") + + hidden_enphase_partner_app_credentials = cls( + type=type, + vendor=vendor, + ) + + return hidden_enphase_partner_app_credentials diff --git a/derapi/models/hidden_enphase_vpp_credentials.py b/derapi/models/hidden_enphase_vpp_credentials.py new file mode 100644 index 0000000..c932830 --- /dev/null +++ b/derapi/models/hidden_enphase_vpp_credentials.py @@ -0,0 +1,50 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="HiddenEnphaseVPPCredentials") + + +@_attrs_define +class HiddenEnphaseVPPCredentials: + """ + Attributes: + type (Literal['vpp']): Default: 'vpp'. + vendor (Literal['enphasevpp']): Default: 'enphasevpp'. + """ + + type: Literal["vpp"] = "vpp" + vendor: Literal["enphasevpp"] = "enphasevpp" + + def to_dict(self) -> Dict[str, Any]: + type = self.type + + vendor = self.vendor + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "type": type, + "vendor": vendor, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + type = cast(Literal["vpp"], d.pop("type")) + if type != "vpp": + raise ValueError(f"type must match const 'vpp', got '{type}'") + + vendor = cast(Literal["enphasevpp"], d.pop("vendor")) + if vendor != "enphasevpp": + raise ValueError(f"vendor must match const 'enphasevpp', got '{vendor}'") + + hidden_enphase_vpp_credentials = cls( + type=type, + vendor=vendor, + ) + + return hidden_enphase_vpp_credentials diff --git a/derapi/models/hidden_franklin_wh_credentials.py b/derapi/models/hidden_franklin_wh_credentials.py new file mode 100644 index 0000000..289bcf6 --- /dev/null +++ b/derapi/models/hidden_franklin_wh_credentials.py @@ -0,0 +1,50 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="HiddenFranklinWHCredentials") + + +@_attrs_define +class HiddenFranklinWHCredentials: + """ + Attributes: + type (Literal['partner']): Default: 'partner'. + vendor (Literal['franklinwh']): Default: 'franklinwh'. + """ + + type: Literal["partner"] = "partner" + vendor: Literal["franklinwh"] = "franklinwh" + + def to_dict(self) -> Dict[str, Any]: + type = self.type + + vendor = self.vendor + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "type": type, + "vendor": vendor, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + type = cast(Literal["partner"], d.pop("type")) + if type != "partner": + raise ValueError(f"type must match const 'partner', got '{type}'") + + vendor = cast(Literal["franklinwh"], d.pop("vendor")) + if vendor != "franklinwh": + raise ValueError(f"vendor must match const 'franklinwh', got '{vendor}'") + + hidden_franklin_wh_credentials = cls( + type=type, + vendor=vendor, + ) + + return hidden_franklin_wh_credentials diff --git a/derapi/models/hidden_sma_custom_grant_credentials.py b/derapi/models/hidden_sma_custom_grant_credentials.py new file mode 100644 index 0000000..f7cefd5 --- /dev/null +++ b/derapi/models/hidden_sma_custom_grant_credentials.py @@ -0,0 +1,51 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="HiddenSMACustomGrantCredentials") + + +@_attrs_define +class HiddenSMACustomGrantCredentials: + """Credentials from the SMA custom grant oauth flow + + Attributes: + type (Literal['customgrant']): Default: 'customgrant'. + vendor (Literal['sma']): Default: 'sma'. + """ + + type: Literal["customgrant"] = "customgrant" + vendor: Literal["sma"] = "sma" + + def to_dict(self) -> Dict[str, Any]: + type = self.type + + vendor = self.vendor + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "type": type, + "vendor": vendor, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + type = cast(Literal["customgrant"], d.pop("type")) + if type != "customgrant": + raise ValueError(f"type must match const 'customgrant', got '{type}'") + + vendor = cast(Literal["sma"], d.pop("vendor")) + if vendor != "sma": + raise ValueError(f"vendor must match const 'sma', got '{vendor}'") + + hidden_sma_custom_grant_credentials = cls( + type=type, + vendor=vendor, + ) + + return hidden_sma_custom_grant_credentials diff --git a/derapi/models/hidden_sma_sandbox_custom_grant_credentials.py b/derapi/models/hidden_sma_sandbox_custom_grant_credentials.py new file mode 100644 index 0000000..fc3070c --- /dev/null +++ b/derapi/models/hidden_sma_sandbox_custom_grant_credentials.py @@ -0,0 +1,51 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="HiddenSMASandboxCustomGrantCredentials") + + +@_attrs_define +class HiddenSMASandboxCustomGrantCredentials: + """Credentials from the SMA Sandbox custom grant oauth flow + + Attributes: + type (Literal['customgrant']): Default: 'customgrant'. + vendor (Literal['smasbox']): Default: 'smasbox'. + """ + + type: Literal["customgrant"] = "customgrant" + vendor: Literal["smasbox"] = "smasbox" + + def to_dict(self) -> Dict[str, Any]: + type = self.type + + vendor = self.vendor + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "type": type, + "vendor": vendor, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + type = cast(Literal["customgrant"], d.pop("type")) + if type != "customgrant": + raise ValueError(f"type must match const 'customgrant', got '{type}'") + + vendor = cast(Literal["smasbox"], d.pop("vendor")) + if vendor != "smasbox": + raise ValueError(f"vendor must match const 'smasbox', got '{vendor}'") + + hidden_sma_sandbox_custom_grant_credentials = cls( + type=type, + vendor=vendor, + ) + + return hidden_sma_sandbox_custom_grant_credentials diff --git a/derapi/models/hidden_sma_sandbox_o_auth_credentials.py b/derapi/models/hidden_sma_sandbox_o_auth_credentials.py new file mode 100644 index 0000000..04b807a --- /dev/null +++ b/derapi/models/hidden_sma_sandbox_o_auth_credentials.py @@ -0,0 +1,51 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="HiddenSMASandboxOAuthCredentials") + + +@_attrs_define +class HiddenSMASandboxOAuthCredentials: + """Credentials from the SMA Sandbox OAuth code grant flow + + Attributes: + type (Literal['oauthclient']): Default: 'oauthclient'. + vendor (Literal['smasbox']): Default: 'smasbox'. + """ + + type: Literal["oauthclient"] = "oauthclient" + vendor: Literal["smasbox"] = "smasbox" + + def to_dict(self) -> Dict[str, Any]: + type = self.type + + vendor = self.vendor + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "type": type, + "vendor": vendor, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + type = cast(Literal["oauthclient"], d.pop("type")) + if type != "oauthclient": + raise ValueError(f"type must match const 'oauthclient', got '{type}'") + + vendor = cast(Literal["smasbox"], d.pop("vendor")) + if vendor != "smasbox": + raise ValueError(f"vendor must match const 'smasbox', got '{vendor}'") + + hidden_sma_sandbox_o_auth_credentials = cls( + type=type, + vendor=vendor, + ) + + return hidden_sma_sandbox_o_auth_credentials diff --git a/derapi/models/hidden_smao_auth_credentials.py b/derapi/models/hidden_smao_auth_credentials.py new file mode 100644 index 0000000..15a4d08 --- /dev/null +++ b/derapi/models/hidden_smao_auth_credentials.py @@ -0,0 +1,51 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="HiddenSMAOAuthCredentials") + + +@_attrs_define +class HiddenSMAOAuthCredentials: + """Credentials from the SMA OAuth code grant flow + + Attributes: + type (Literal['oauthclient']): Default: 'oauthclient'. + vendor (Literal['sma']): Default: 'sma'. + """ + + type: Literal["oauthclient"] = "oauthclient" + vendor: Literal["sma"] = "sma" + + def to_dict(self) -> Dict[str, Any]: + type = self.type + + vendor = self.vendor + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "type": type, + "vendor": vendor, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + type = cast(Literal["oauthclient"], d.pop("type")) + if type != "oauthclient": + raise ValueError(f"type must match const 'oauthclient', got '{type}'") + + vendor = cast(Literal["sma"], d.pop("vendor")) + if vendor != "sma": + raise ValueError(f"vendor must match const 'sma', got '{vendor}'") + + hidden_smao_auth_credentials = cls( + type=type, + vendor=vendor, + ) + + return hidden_smao_auth_credentials diff --git a/derapi/models/hidden_solar_edge_credentials.py b/derapi/models/hidden_solar_edge_credentials.py new file mode 100644 index 0000000..2baf87a --- /dev/null +++ b/derapi/models/hidden_solar_edge_credentials.py @@ -0,0 +1,50 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="HiddenSolarEdgeCredentials") + + +@_attrs_define +class HiddenSolarEdgeCredentials: + """ + Attributes: + type (Literal['apikey']): Default: 'apikey'. + vendor (Literal['solaredge']): Default: 'solaredge'. + """ + + type: Literal["apikey"] = "apikey" + vendor: Literal["solaredge"] = "solaredge" + + def to_dict(self) -> Dict[str, Any]: + type = self.type + + vendor = self.vendor + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "type": type, + "vendor": vendor, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + type = cast(Literal["apikey"], d.pop("type")) + if type != "apikey": + raise ValueError(f"type must match const 'apikey', got '{type}'") + + vendor = cast(Literal["solaredge"], d.pop("vendor")) + if vendor != "solaredge": + raise ValueError(f"vendor must match const 'solaredge', got '{vendor}'") + + hidden_solar_edge_credentials = cls( + type=type, + vendor=vendor, + ) + + return hidden_solar_edge_credentials diff --git a/derapi/models/hidden_solis_credentials.py b/derapi/models/hidden_solis_credentials.py new file mode 100644 index 0000000..6735407 --- /dev/null +++ b/derapi/models/hidden_solis_credentials.py @@ -0,0 +1,50 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="HiddenSolisCredentials") + + +@_attrs_define +class HiddenSolisCredentials: + """ + Attributes: + type (Literal['apikeysecret']): Default: 'apikeysecret'. + vendor (Literal['solis']): Default: 'solis'. + """ + + type: Literal["apikeysecret"] = "apikeysecret" + vendor: Literal["solis"] = "solis" + + def to_dict(self) -> Dict[str, Any]: + type = self.type + + vendor = self.vendor + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "type": type, + "vendor": vendor, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + type = cast(Literal["apikeysecret"], d.pop("type")) + if type != "apikeysecret": + raise ValueError(f"type must match const 'apikeysecret', got '{type}'") + + vendor = cast(Literal["solis"], d.pop("vendor")) + if vendor != "solis": + raise ValueError(f"vendor must match const 'solis', got '{vendor}'") + + hidden_solis_credentials = cls( + type=type, + vendor=vendor, + ) + + return hidden_solis_credentials diff --git a/derapi/models/hidden_tesla_app_credentials.py b/derapi/models/hidden_tesla_app_credentials.py new file mode 100644 index 0000000..3d28cc5 --- /dev/null +++ b/derapi/models/hidden_tesla_app_credentials.py @@ -0,0 +1,50 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="HiddenTeslaAppCredentials") + + +@_attrs_define +class HiddenTeslaAppCredentials: + """ + Attributes: + type (Literal['app']): Default: 'app'. + vendor (Literal['tesla']): Default: 'tesla'. + """ + + type: Literal["app"] = "app" + vendor: Literal["tesla"] = "tesla" + + def to_dict(self) -> Dict[str, Any]: + type = self.type + + vendor = self.vendor + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "type": type, + "vendor": vendor, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + type = cast(Literal["app"], d.pop("type")) + if type != "app": + raise ValueError(f"type must match const 'app', got '{type}'") + + vendor = cast(Literal["tesla"], d.pop("vendor")) + if vendor != "tesla": + raise ValueError(f"vendor must match const 'tesla', got '{vendor}'") + + hidden_tesla_app_credentials = cls( + type=type, + vendor=vendor, + ) + + return hidden_tesla_app_credentials diff --git a/derapi/models/list_batteries_response.py b/derapi/models/list_batteries_response.py new file mode 100644 index 0000000..2bc1521 --- /dev/null +++ b/derapi/models/list_batteries_response.py @@ -0,0 +1,75 @@ +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.battery_summary import BatterySummary + from ..models.list_batteries_response_errors import ListBatteriesResponseErrors + + +T = TypeVar("T", bound="ListBatteriesResponse") + + +@_attrs_define +class ListBatteriesResponse: + """ + Attributes: + batteries (List['BatterySummary']): List of Batteries + errors (ListBatteriesResponseErrors): If there is an error accessing a vendor API then error details are + provided + next_page_token (Union[Unset, str]): A token to request the next page, if any. If absent, there are no more + pages. + """ + + batteries: List["BatterySummary"] + errors: "ListBatteriesResponseErrors" + next_page_token: Union[Unset, str] = UNSET + + def to_dict(self) -> Dict[str, Any]: + batteries = [] + for batteries_item_data in self.batteries: + batteries_item = batteries_item_data.to_dict() + batteries.append(batteries_item) + + errors = self.errors.to_dict() + + next_page_token = self.next_page_token + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "batteries": batteries, + "errors": errors, + } + ) + if next_page_token is not UNSET: + field_dict["nextPageToken"] = next_page_token + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.battery_summary import BatterySummary + from ..models.list_batteries_response_errors import ListBatteriesResponseErrors + + d = src_dict.copy() + batteries = [] + _batteries = d.pop("batteries") + for batteries_item_data in _batteries: + batteries_item = BatterySummary.from_dict(batteries_item_data) + + batteries.append(batteries_item) + + errors = ListBatteriesResponseErrors.from_dict(d.pop("errors")) + + next_page_token = d.pop("nextPageToken", UNSET) + + list_batteries_response = cls( + batteries=batteries, + errors=errors, + next_page_token=next_page_token, + ) + + return list_batteries_response diff --git a/derapi/models/list_batteries_response_errors.py b/derapi/models/list_batteries_response_errors.py new file mode 100644 index 0000000..a4c23de --- /dev/null +++ b/derapi/models/list_batteries_response_errors.py @@ -0,0 +1,43 @@ +from typing import Any, Dict, List, Type, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="ListBatteriesResponseErrors") + + +@_attrs_define +class ListBatteriesResponseErrors: + """If there is an error accessing a vendor API then error details are provided""" + + additional_properties: Dict[str, str] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + list_batteries_response_errors = cls() + + list_batteries_response_errors.additional_properties = d + return list_batteries_response_errors + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> str: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: str) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/derapi/models/list_site_response_errors.py b/derapi/models/list_site_response_errors.py new file mode 100644 index 0000000..6a93948 --- /dev/null +++ b/derapi/models/list_site_response_errors.py @@ -0,0 +1,43 @@ +from typing import Any, Dict, List, Type, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="ListSiteResponseErrors") + + +@_attrs_define +class ListSiteResponseErrors: + """If there is an error accessing a vendor API then error details are provided""" + + additional_properties: Dict[str, str] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + list_site_response_errors = cls() + + list_site_response_errors.additional_properties = d + return list_site_response_errors + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> str: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: str) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/derapi/models/list_sites_response.py b/derapi/models/list_sites_response.py new file mode 100644 index 0000000..c5a2dc4 --- /dev/null +++ b/derapi/models/list_sites_response.py @@ -0,0 +1,74 @@ +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.list_site_response_errors import ListSiteResponseErrors + from ..models.site_summary import SiteSummary + + +T = TypeVar("T", bound="ListSitesResponse") + + +@_attrs_define +class ListSitesResponse: + """ + Attributes: + sites (List['SiteSummary']): List of Sites + errors (ListSiteResponseErrors): If there is an error accessing a vendor API then error details are provided + next_page_token (Union[Unset, str]): A token to request the next page, if any. If absent, there are no more + pages. + """ + + sites: List["SiteSummary"] + errors: "ListSiteResponseErrors" + next_page_token: Union[Unset, str] = UNSET + + def to_dict(self) -> Dict[str, Any]: + sites = [] + for sites_item_data in self.sites: + sites_item = sites_item_data.to_dict() + sites.append(sites_item) + + errors = self.errors.to_dict() + + next_page_token = self.next_page_token + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "sites": sites, + "errors": errors, + } + ) + if next_page_token is not UNSET: + field_dict["nextPageToken"] = next_page_token + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.list_site_response_errors import ListSiteResponseErrors + from ..models.site_summary import SiteSummary + + d = src_dict.copy() + sites = [] + _sites = d.pop("sites") + for sites_item_data in _sites: + sites_item = SiteSummary.from_dict(sites_item_data) + + sites.append(sites_item) + + errors = ListSiteResponseErrors.from_dict(d.pop("errors")) + + next_page_token = d.pop("nextPageToken", UNSET) + + list_sites_response = cls( + sites=sites, + errors=errors, + next_page_token=next_page_token, + ) + + return list_sites_response diff --git a/derapi/models/list_solar_inverters_response.py b/derapi/models/list_solar_inverters_response.py new file mode 100644 index 0000000..cf99569 --- /dev/null +++ b/derapi/models/list_solar_inverters_response.py @@ -0,0 +1,75 @@ +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.list_solar_inverters_response_errors import ListSolarInvertersResponseErrors + from ..models.solar_inverter_summary import SolarInverterSummary + + +T = TypeVar("T", bound="ListSolarInvertersResponse") + + +@_attrs_define +class ListSolarInvertersResponse: + """ + Attributes: + solar_inverters (List['SolarInverterSummary']): List of Solar Inverters + errors (ListSolarInvertersResponseErrors): If there is an error accessing a vendor API then error details are + provided + next_page_token (Union[Unset, str]): A token to request the next page, if any. If absent, there are no more + pages. + """ + + solar_inverters: List["SolarInverterSummary"] + errors: "ListSolarInvertersResponseErrors" + next_page_token: Union[Unset, str] = UNSET + + def to_dict(self) -> Dict[str, Any]: + solar_inverters = [] + for solar_inverters_item_data in self.solar_inverters: + solar_inverters_item = solar_inverters_item_data.to_dict() + solar_inverters.append(solar_inverters_item) + + errors = self.errors.to_dict() + + next_page_token = self.next_page_token + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "solarInverters": solar_inverters, + "errors": errors, + } + ) + if next_page_token is not UNSET: + field_dict["nextPageToken"] = next_page_token + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.list_solar_inverters_response_errors import ListSolarInvertersResponseErrors + from ..models.solar_inverter_summary import SolarInverterSummary + + d = src_dict.copy() + solar_inverters = [] + _solar_inverters = d.pop("solarInverters") + for solar_inverters_item_data in _solar_inverters: + solar_inverters_item = SolarInverterSummary.from_dict(solar_inverters_item_data) + + solar_inverters.append(solar_inverters_item) + + errors = ListSolarInvertersResponseErrors.from_dict(d.pop("errors")) + + next_page_token = d.pop("nextPageToken", UNSET) + + list_solar_inverters_response = cls( + solar_inverters=solar_inverters, + errors=errors, + next_page_token=next_page_token, + ) + + return list_solar_inverters_response diff --git a/derapi/models/list_solar_inverters_response_errors.py b/derapi/models/list_solar_inverters_response_errors.py new file mode 100644 index 0000000..c88a31f --- /dev/null +++ b/derapi/models/list_solar_inverters_response_errors.py @@ -0,0 +1,43 @@ +from typing import Any, Dict, List, Type, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="ListSolarInvertersResponseErrors") + + +@_attrs_define +class ListSolarInvertersResponseErrors: + """If there is an error accessing a vendor API then error details are provided""" + + additional_properties: Dict[str, str] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + list_solar_inverters_response_errors = cls() + + list_solar_inverters_response_errors.additional_properties = d + return list_solar_inverters_response_errors + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> str: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: str) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/derapi/models/list_vendor_credentials_response.py b/derapi/models/list_vendor_credentials_response.py new file mode 100644 index 0000000..d4e95ae --- /dev/null +++ b/derapi/models/list_vendor_credentials_response.py @@ -0,0 +1,64 @@ +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.vendor_credentials import VendorCredentials + + +T = TypeVar("T", bound="ListVendorCredentialsResponse") + + +@_attrs_define +class ListVendorCredentialsResponse: + """ + Attributes: + vendor_credentials (List['VendorCredentials']): + next_page_token (Union[Unset, str]): A token to request the next page, if any. If absent, there are no more + pages. + """ + + vendor_credentials: List["VendorCredentials"] + next_page_token: Union[Unset, str] = UNSET + + def to_dict(self) -> Dict[str, Any]: + vendor_credentials = [] + for vendor_credentials_item_data in self.vendor_credentials: + vendor_credentials_item = vendor_credentials_item_data.to_dict() + vendor_credentials.append(vendor_credentials_item) + + next_page_token = self.next_page_token + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "vendorCredentials": vendor_credentials, + } + ) + if next_page_token is not UNSET: + field_dict["nextPageToken"] = next_page_token + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.vendor_credentials import VendorCredentials + + d = src_dict.copy() + vendor_credentials = [] + _vendor_credentials = d.pop("vendorCredentials") + for vendor_credentials_item_data in _vendor_credentials: + vendor_credentials_item = VendorCredentials.from_dict(vendor_credentials_item_data) + + vendor_credentials.append(vendor_credentials_item) + + next_page_token = d.pop("nextPageToken", UNSET) + + list_vendor_credentials_response = cls( + vendor_credentials=vendor_credentials, + next_page_token=next_page_token, + ) + + return list_vendor_credentials_response diff --git a/derapi/models/list_virtual_batteries_response.py b/derapi/models/list_virtual_batteries_response.py new file mode 100644 index 0000000..ab8275c --- /dev/null +++ b/derapi/models/list_virtual_batteries_response.py @@ -0,0 +1,64 @@ +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.virtual_battery import VirtualBattery + + +T = TypeVar("T", bound="ListVirtualBatteriesResponse") + + +@_attrs_define +class ListVirtualBatteriesResponse: + """ + Attributes: + virtual_batteries (List['VirtualBattery']): + next_page_token (Union[Unset, str]): A token to request the next page, if any. If absent, there are no more + pages. + """ + + virtual_batteries: List["VirtualBattery"] + next_page_token: Union[Unset, str] = UNSET + + def to_dict(self) -> Dict[str, Any]: + virtual_batteries = [] + for virtual_batteries_item_data in self.virtual_batteries: + virtual_batteries_item = virtual_batteries_item_data.to_dict() + virtual_batteries.append(virtual_batteries_item) + + next_page_token = self.next_page_token + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "virtualBatteries": virtual_batteries, + } + ) + if next_page_token is not UNSET: + field_dict["nextPageToken"] = next_page_token + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.virtual_battery import VirtualBattery + + d = src_dict.copy() + virtual_batteries = [] + _virtual_batteries = d.pop("virtualBatteries") + for virtual_batteries_item_data in _virtual_batteries: + virtual_batteries_item = VirtualBattery.from_dict(virtual_batteries_item_data) + + virtual_batteries.append(virtual_batteries_item) + + next_page_token = d.pop("nextPageToken", UNSET) + + list_virtual_batteries_response = cls( + virtual_batteries=virtual_batteries, + next_page_token=next_page_token, + ) + + return list_virtual_batteries_response diff --git a/derapi/models/list_virtual_sites_response.py b/derapi/models/list_virtual_sites_response.py new file mode 100644 index 0000000..39dd1d8 --- /dev/null +++ b/derapi/models/list_virtual_sites_response.py @@ -0,0 +1,64 @@ +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.virtual_site import VirtualSite + + +T = TypeVar("T", bound="ListVirtualSitesResponse") + + +@_attrs_define +class ListVirtualSitesResponse: + """ + Attributes: + virtual_sites (List['VirtualSite']): + next_page_token (Union[Unset, str]): A token to request the next page, if any. If absent, there are no more + pages. + """ + + virtual_sites: List["VirtualSite"] + next_page_token: Union[Unset, str] = UNSET + + def to_dict(self) -> Dict[str, Any]: + virtual_sites = [] + for virtual_sites_item_data in self.virtual_sites: + virtual_sites_item = virtual_sites_item_data.to_dict() + virtual_sites.append(virtual_sites_item) + + next_page_token = self.next_page_token + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "virtualSites": virtual_sites, + } + ) + if next_page_token is not UNSET: + field_dict["nextPageToken"] = next_page_token + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.virtual_site import VirtualSite + + d = src_dict.copy() + virtual_sites = [] + _virtual_sites = d.pop("virtualSites") + for virtual_sites_item_data in _virtual_sites: + virtual_sites_item = VirtualSite.from_dict(virtual_sites_item_data) + + virtual_sites.append(virtual_sites_item) + + next_page_token = d.pop("nextPageToken", UNSET) + + list_virtual_sites_response = cls( + virtual_sites=virtual_sites, + next_page_token=next_page_token, + ) + + return list_virtual_sites_response diff --git a/derapi/models/list_virtual_solar_inverters_response.py b/derapi/models/list_virtual_solar_inverters_response.py new file mode 100644 index 0000000..4c1ad5b --- /dev/null +++ b/derapi/models/list_virtual_solar_inverters_response.py @@ -0,0 +1,64 @@ +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.virtual_solar_inverter import VirtualSolarInverter + + +T = TypeVar("T", bound="ListVirtualSolarInvertersResponse") + + +@_attrs_define +class ListVirtualSolarInvertersResponse: + """ + Attributes: + virtual_solar_inverters (List['VirtualSolarInverter']): + next_page_token (Union[Unset, str]): A token to request the next page, if any. If absent, there are no more + pages. + """ + + virtual_solar_inverters: List["VirtualSolarInverter"] + next_page_token: Union[Unset, str] = UNSET + + def to_dict(self) -> Dict[str, Any]: + virtual_solar_inverters = [] + for virtual_solar_inverters_item_data in self.virtual_solar_inverters: + virtual_solar_inverters_item = virtual_solar_inverters_item_data.to_dict() + virtual_solar_inverters.append(virtual_solar_inverters_item) + + next_page_token = self.next_page_token + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "virtualSolarInverters": virtual_solar_inverters, + } + ) + if next_page_token is not UNSET: + field_dict["nextPageToken"] = next_page_token + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.virtual_solar_inverter import VirtualSolarInverter + + d = src_dict.copy() + virtual_solar_inverters = [] + _virtual_solar_inverters = d.pop("virtualSolarInverters") + for virtual_solar_inverters_item_data in _virtual_solar_inverters: + virtual_solar_inverters_item = VirtualSolarInverter.from_dict(virtual_solar_inverters_item_data) + + virtual_solar_inverters.append(virtual_solar_inverters_item) + + next_page_token = d.pop("nextPageToken", UNSET) + + list_virtual_solar_inverters_response = cls( + virtual_solar_inverters=virtual_solar_inverters, + next_page_token=next_page_token, + ) + + return list_virtual_solar_inverters_response diff --git a/derapi/models/put_site_battery_control_request.py b/derapi/models/put_site_battery_control_request.py new file mode 100644 index 0000000..efceb71 --- /dev/null +++ b/derapi/models/put_site_battery_control_request.py @@ -0,0 +1,52 @@ +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar + +from attrs import define as _attrs_define + +if TYPE_CHECKING: + from ..models.put_site_battery_control_request_interval import PutSiteBatteryControlRequestInterval + + +T = TypeVar("T", bound="PutSiteBatteryControlRequest") + + +@_attrs_define +class PutSiteBatteryControlRequest: + """ + Attributes: + intervals (List['PutSiteBatteryControlRequestInterval']): + """ + + intervals: List["PutSiteBatteryControlRequestInterval"] + + def to_dict(self) -> Dict[str, Any]: + intervals = [] + for intervals_item_data in self.intervals: + intervals_item = intervals_item_data.to_dict() + intervals.append(intervals_item) + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "intervals": intervals, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.put_site_battery_control_request_interval import PutSiteBatteryControlRequestInterval + + d = src_dict.copy() + intervals = [] + _intervals = d.pop("intervals") + for intervals_item_data in _intervals: + intervals_item = PutSiteBatteryControlRequestInterval.from_dict(intervals_item_data) + + intervals.append(intervals_item) + + put_site_battery_control_request = cls( + intervals=intervals, + ) + + return put_site_battery_control_request diff --git a/derapi/models/put_site_battery_control_request_interval.py b/derapi/models/put_site_battery_control_request_interval.py new file mode 100644 index 0000000..b175973 --- /dev/null +++ b/derapi/models/put_site_battery_control_request_interval.py @@ -0,0 +1,107 @@ +import datetime +from typing import Any, Dict, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..models.site_battery_control_command import SiteBatteryControlCommand +from ..models.site_battery_control_priority import SiteBatteryControlPriority +from ..types import UNSET, Unset + +T = TypeVar("T", bound="PutSiteBatteryControlRequestInterval") + + +@_attrs_define +class PutSiteBatteryControlRequestInterval: + """ + Attributes: + command (SiteBatteryControlCommand): discharge, charge, or idle + start (datetime.datetime): Interval start in ISO-8601 format + end (datetime.datetime): Interval end in ISO-8601 format + kw (Union[Unset, float]): discharge rate in kilowatts + state_of_charge_limit_percent (Union[Unset, float]): the minimum/maximum state of charge, expressed as a + percent, the Battery can be charged/discharged to + priority (Union[Unset, SiteBatteryControlPriority]): PV = Prioritize charging the Battery with PV production or, + for discharge, prioritize using PV production to meet Site loads first first
B = Prioritize using Battery + discharge to meet Site loads first
Load = Prioritize using PV production for Sites loads first, then use + excess to charge the Battery
Grid = Prioritize charing with Battery with grid import first + allow_export (Union[Unset, bool]): True or False + """ + + command: SiteBatteryControlCommand + start: datetime.datetime + end: datetime.datetime + kw: Union[Unset, float] = UNSET + state_of_charge_limit_percent: Union[Unset, float] = UNSET + priority: Union[Unset, SiteBatteryControlPriority] = UNSET + allow_export: Union[Unset, bool] = UNSET + + def to_dict(self) -> Dict[str, Any]: + command = self.command.value + + start = self.start.isoformat() + + end = self.end.isoformat() + + kw = self.kw + + state_of_charge_limit_percent = self.state_of_charge_limit_percent + + priority: Union[Unset, str] = UNSET + if not isinstance(self.priority, Unset): + priority = self.priority.value + + allow_export = self.allow_export + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "command": command, + "start": start, + "end": end, + } + ) + if kw is not UNSET: + field_dict["kw"] = kw + if state_of_charge_limit_percent is not UNSET: + field_dict["stateOfChargeLimitPercent"] = state_of_charge_limit_percent + if priority is not UNSET: + field_dict["priority"] = priority + if allow_export is not UNSET: + field_dict["allowExport"] = allow_export + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + command = SiteBatteryControlCommand(d.pop("command")) + + start = isoparse(d.pop("start")) + + end = isoparse(d.pop("end")) + + kw = d.pop("kw", UNSET) + + state_of_charge_limit_percent = d.pop("stateOfChargeLimitPercent", UNSET) + + _priority = d.pop("priority", UNSET) + priority: Union[Unset, SiteBatteryControlPriority] + if isinstance(_priority, Unset): + priority = UNSET + else: + priority = SiteBatteryControlPriority(_priority) + + allow_export = d.pop("allowExport", UNSET) + + put_site_battery_control_request_interval = cls( + command=command, + start=start, + end=end, + kw=kw, + state_of_charge_limit_percent=state_of_charge_limit_percent, + priority=priority, + allow_export=allow_export, + ) + + return put_site_battery_control_request_interval diff --git a/derapi/models/put_site_battery_control_response.py b/derapi/models/put_site_battery_control_response.py new file mode 100644 index 0000000..01e8cf1 --- /dev/null +++ b/derapi/models/put_site_battery_control_response.py @@ -0,0 +1,60 @@ +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar + +from attrs import define as _attrs_define + +if TYPE_CHECKING: + from ..models.site_battery_control_status_interval import SiteBatteryControlStatusInterval + + +T = TypeVar("T", bound="PutSiteBatteryControlResponse") + + +@_attrs_define +class PutSiteBatteryControlResponse: + """ + Attributes: + id (str): the ID for the Site + intervals (List['SiteBatteryControlStatusInterval']): + """ + + id: str + intervals: List["SiteBatteryControlStatusInterval"] + + def to_dict(self) -> Dict[str, Any]: + id = self.id + + intervals = [] + for intervals_item_data in self.intervals: + intervals_item = intervals_item_data.to_dict() + intervals.append(intervals_item) + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "intervals": intervals, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.site_battery_control_status_interval import SiteBatteryControlStatusInterval + + d = src_dict.copy() + id = d.pop("id") + + intervals = [] + _intervals = d.pop("intervals") + for intervals_item_data in _intervals: + intervals_item = SiteBatteryControlStatusInterval.from_dict(intervals_item_data) + + intervals.append(intervals_item) + + put_site_battery_control_response = cls( + id=id, + intervals=intervals, + ) + + return put_site_battery_control_response diff --git a/derapi/models/site.py b/derapi/models/site.py new file mode 100644 index 0000000..85736c5 --- /dev/null +++ b/derapi/models/site.py @@ -0,0 +1,163 @@ +import datetime +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..models.vendor import Vendor +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.battery_summary import BatterySummary + from ..models.site_bess import SiteBESS + from ..models.site_location import SiteLocation + from ..models.solar_inverter_summary import SolarInverterSummary + + +T = TypeVar("T", bound="Site") + + +@_attrs_define +class Site: + """ + Attributes: + id (str): the ID for the Site + vendor (Vendor): + name (str): Customer defined name of the Site + location_utc_offset (float): UTC Offset in hours; positive values represent locations East of UTC. Please note + this field will soon be deprecated, please use `timezone` instead. + batteries (List['BatterySummary']): List of Battery IDs associated with this Site + solar_inverters (List['SolarInverterSummary']): List of Solar Inverter IDs associated with this Site + location (Union[Unset, SiteLocation]): The location of this Solar Inverter in lat/lon coordinates + operational_since (Union[Unset, datetime.datetime]): The date the Site became operational or received permission + to operate. Sometimes absent for Solaredge. + bess (Union[Unset, SiteBESS]): For Sites with Batteries this key is present + """ + + id: str + vendor: Vendor + name: str + location_utc_offset: float + batteries: List["BatterySummary"] + solar_inverters: List["SolarInverterSummary"] + location: Union[Unset, "SiteLocation"] = UNSET + operational_since: Union[Unset, datetime.datetime] = UNSET + bess: Union[Unset, "SiteBESS"] = UNSET + + def to_dict(self) -> Dict[str, Any]: + id = self.id + + vendor = self.vendor.value + + name = self.name + + location_utc_offset = self.location_utc_offset + + batteries = [] + for componentsschemas_site_batteries_item_data in self.batteries: + componentsschemas_site_batteries_item = componentsschemas_site_batteries_item_data.to_dict() + batteries.append(componentsschemas_site_batteries_item) + + solar_inverters = [] + for componentsschemas_site_solar_inverters_item_data in self.solar_inverters: + componentsschemas_site_solar_inverters_item = componentsschemas_site_solar_inverters_item_data.to_dict() + solar_inverters.append(componentsschemas_site_solar_inverters_item) + + location: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.location, Unset): + location = self.location.to_dict() + + operational_since: Union[Unset, str] = UNSET + if not isinstance(self.operational_since, Unset): + operational_since = self.operational_since.isoformat() + + bess: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.bess, Unset): + bess = self.bess.to_dict() + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "vendor": vendor, + "name": name, + "locationUTCOffset": location_utc_offset, + "batteries": batteries, + "solarInverters": solar_inverters, + } + ) + if location is not UNSET: + field_dict["location"] = location + if operational_since is not UNSET: + field_dict["operationalSince"] = operational_since + if bess is not UNSET: + field_dict["bess"] = bess + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.battery_summary import BatterySummary + from ..models.site_bess import SiteBESS + from ..models.site_location import SiteLocation + from ..models.solar_inverter_summary import SolarInverterSummary + + d = src_dict.copy() + id = d.pop("id") + + vendor = Vendor(d.pop("vendor")) + + name = d.pop("name") + + location_utc_offset = d.pop("locationUTCOffset") + + batteries = [] + _batteries = d.pop("batteries") + for componentsschemas_site_batteries_item_data in _batteries: + componentsschemas_site_batteries_item = BatterySummary.from_dict(componentsschemas_site_batteries_item_data) + + batteries.append(componentsschemas_site_batteries_item) + + solar_inverters = [] + _solar_inverters = d.pop("solarInverters") + for componentsschemas_site_solar_inverters_item_data in _solar_inverters: + componentsschemas_site_solar_inverters_item = SolarInverterSummary.from_dict( + componentsschemas_site_solar_inverters_item_data + ) + + solar_inverters.append(componentsschemas_site_solar_inverters_item) + + _location = d.pop("location", UNSET) + location: Union[Unset, SiteLocation] + if isinstance(_location, Unset): + location = UNSET + else: + location = SiteLocation.from_dict(_location) + + _operational_since = d.pop("operationalSince", UNSET) + operational_since: Union[Unset, datetime.datetime] + if isinstance(_operational_since, Unset): + operational_since = UNSET + else: + operational_since = isoparse(_operational_since) + + _bess = d.pop("bess", UNSET) + bess: Union[Unset, SiteBESS] + if isinstance(_bess, Unset): + bess = UNSET + else: + bess = SiteBESS.from_dict(_bess) + + site = cls( + id=id, + vendor=vendor, + name=name, + location_utc_offset=location_utc_offset, + batteries=batteries, + solar_inverters=solar_inverters, + location=location, + operational_since=operational_since, + bess=bess, + ) + + return site diff --git a/derapi/models/site_battery_control_command.py b/derapi/models/site_battery_control_command.py new file mode 100644 index 0000000..f67de5c --- /dev/null +++ b/derapi/models/site_battery_control_command.py @@ -0,0 +1,10 @@ +from enum import Enum + + +class SiteBatteryControlCommand(str, Enum): + CHARGE = "charge" + DISCHARGE = "discharge" + IDLE = "idle" + + def __str__(self) -> str: + return str(self.value) diff --git a/derapi/models/site_battery_control_priority.py b/derapi/models/site_battery_control_priority.py new file mode 100644 index 0000000..e7efc7c --- /dev/null +++ b/derapi/models/site_battery_control_priority.py @@ -0,0 +1,11 @@ +from enum import Enum + + +class SiteBatteryControlPriority(str, Enum): + B = "B" + GRID = "Grid" + LOAD = "Load" + PV = "PV" + + def __str__(self) -> str: + return str(self.value) diff --git a/derapi/models/site_battery_control_status.py b/derapi/models/site_battery_control_status.py new file mode 100644 index 0000000..a5b1dff --- /dev/null +++ b/derapi/models/site_battery_control_status.py @@ -0,0 +1,60 @@ +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar + +from attrs import define as _attrs_define + +if TYPE_CHECKING: + from ..models.site_battery_control_status_interval import SiteBatteryControlStatusInterval + + +T = TypeVar("T", bound="SiteBatteryControlStatus") + + +@_attrs_define +class SiteBatteryControlStatus: + """ + Attributes: + id (str): the ID for the Site + intervals (List['SiteBatteryControlStatusInterval']): + """ + + id: str + intervals: List["SiteBatteryControlStatusInterval"] + + def to_dict(self) -> Dict[str, Any]: + id = self.id + + intervals = [] + for intervals_item_data in self.intervals: + intervals_item = intervals_item_data.to_dict() + intervals.append(intervals_item) + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "intervals": intervals, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.site_battery_control_status_interval import SiteBatteryControlStatusInterval + + d = src_dict.copy() + id = d.pop("id") + + intervals = [] + _intervals = d.pop("intervals") + for intervals_item_data in _intervals: + intervals_item = SiteBatteryControlStatusInterval.from_dict(intervals_item_data) + + intervals.append(intervals_item) + + site_battery_control_status = cls( + id=id, + intervals=intervals, + ) + + return site_battery_control_status diff --git a/derapi/models/site_battery_control_status_interval.py b/derapi/models/site_battery_control_status_interval.py new file mode 100644 index 0000000..55fa08d --- /dev/null +++ b/derapi/models/site_battery_control_status_interval.py @@ -0,0 +1,128 @@ +import datetime +from typing import Any, Dict, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..models.site_battery_control_priority import SiteBatteryControlPriority +from ..models.site_battery_control_status_interval_site_battery_control_status_interval_command import ( + SiteBatteryControlStatusIntervalSiteBatteryControlStatusIntervalCommand, +) +from ..types import UNSET, Unset + +T = TypeVar("T", bound="SiteBatteryControlStatusInterval") + + +@_attrs_define +class SiteBatteryControlStatusInterval: + """ + Attributes: + command (SiteBatteryControlStatusIntervalSiteBatteryControlStatusIntervalCommand): discharge, charge, or idle + Default: SiteBatteryControlStatusIntervalSiteBatteryControlStatusIntervalCommand.DISCHARGE. + start (datetime.datetime): Interval start in ISO-8601 format + end (datetime.datetime): Interval end in ISO-8601 format + status (str): Vendor provided command status + reported_at (datetime.datetime): The date this control status update is provided + kw (Union[Unset, float]): discharge rate in kilowatts + state_of_charge_limit_percent (Union[Unset, float]): the minimum/maximum state of charge, expressed as a + percent, the Battery can be charged/discharged to + priority (Union[Unset, SiteBatteryControlPriority]): PV = Prioritize charging the Battery with PV production or, + for discharge, prioritize using PV production to meet Site loads first first
B = Prioritize using Battery + discharge to meet Site loads first
Load = Prioritize using PV production for Sites loads first, then use + excess to charge the Battery
Grid = Prioritize charing with Battery with grid import first + allow_export (Union[Unset, bool]): True or False + """ + + start: datetime.datetime + end: datetime.datetime + status: str + reported_at: datetime.datetime + command: SiteBatteryControlStatusIntervalSiteBatteryControlStatusIntervalCommand = ( + SiteBatteryControlStatusIntervalSiteBatteryControlStatusIntervalCommand.DISCHARGE + ) + kw: Union[Unset, float] = UNSET + state_of_charge_limit_percent: Union[Unset, float] = UNSET + priority: Union[Unset, SiteBatteryControlPriority] = UNSET + allow_export: Union[Unset, bool] = UNSET + + def to_dict(self) -> Dict[str, Any]: + command = self.command.value + + start = self.start.isoformat() + + end = self.end.isoformat() + + status = self.status + + reported_at = self.reported_at.isoformat() + + kw = self.kw + + state_of_charge_limit_percent = self.state_of_charge_limit_percent + + priority: Union[Unset, str] = UNSET + if not isinstance(self.priority, Unset): + priority = self.priority.value + + allow_export = self.allow_export + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "command": command, + "start": start, + "end": end, + "status": status, + "reportedAt": reported_at, + } + ) + if kw is not UNSET: + field_dict["kw"] = kw + if state_of_charge_limit_percent is not UNSET: + field_dict["stateOfChargeLimitPercent"] = state_of_charge_limit_percent + if priority is not UNSET: + field_dict["priority"] = priority + if allow_export is not UNSET: + field_dict["allowExport"] = allow_export + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + command = SiteBatteryControlStatusIntervalSiteBatteryControlStatusIntervalCommand(d.pop("command")) + + start = isoparse(d.pop("start")) + + end = isoparse(d.pop("end")) + + status = d.pop("status") + + reported_at = isoparse(d.pop("reportedAt")) + + kw = d.pop("kw", UNSET) + + state_of_charge_limit_percent = d.pop("stateOfChargeLimitPercent", UNSET) + + _priority = d.pop("priority", UNSET) + priority: Union[Unset, SiteBatteryControlPriority] + if isinstance(_priority, Unset): + priority = UNSET + else: + priority = SiteBatteryControlPriority(_priority) + + allow_export = d.pop("allowExport", UNSET) + + site_battery_control_status_interval = cls( + command=command, + start=start, + end=end, + status=status, + reported_at=reported_at, + kw=kw, + state_of_charge_limit_percent=state_of_charge_limit_percent, + priority=priority, + allow_export=allow_export, + ) + + return site_battery_control_status_interval diff --git a/derapi/models/site_battery_control_status_interval_site_battery_control_status_interval_command.py b/derapi/models/site_battery_control_status_interval_site_battery_control_status_interval_command.py new file mode 100644 index 0000000..5c000dd --- /dev/null +++ b/derapi/models/site_battery_control_status_interval_site_battery_control_status_interval_command.py @@ -0,0 +1,10 @@ +from enum import Enum + + +class SiteBatteryControlStatusIntervalSiteBatteryControlStatusIntervalCommand(str, Enum): + CHARGE = "charge" + DISCHARGE = "discharge" + IDLE = "idle" + + def __str__(self) -> str: + return str(self.value) diff --git a/derapi/models/site_battery_interval.py b/derapi/models/site_battery_interval.py new file mode 100644 index 0000000..dea6fab --- /dev/null +++ b/derapi/models/site_battery_interval.py @@ -0,0 +1,78 @@ +import datetime +from typing import Any, Dict, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="SiteBatteryInterval") + + +@_attrs_define +class SiteBatteryInterval: + """ + Attributes: + charge_kwh (float): kWh into the Battery system (i.e. energy into all the Batteries in the system) during the + interval + discharge_kwh (float): kWh out of the Battery system (i.e. energy discharged from all the Batteries in the + system) during the interval + start (datetime.datetime): Interval start in ISO-8601 format + end (datetime.datetime): Interval end in ISO-8601 format + state_of_charge_percent (Union[Unset, float]): average % charge over the interval for all Batteries in the + system + """ + + charge_kwh: float + discharge_kwh: float + start: datetime.datetime + end: datetime.datetime + state_of_charge_percent: Union[Unset, float] = UNSET + + def to_dict(self) -> Dict[str, Any]: + charge_kwh = self.charge_kwh + + discharge_kwh = self.discharge_kwh + + start = self.start.isoformat() + + end = self.end.isoformat() + + state_of_charge_percent = self.state_of_charge_percent + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "chargeKwh": charge_kwh, + "dischargeKwh": discharge_kwh, + "start": start, + "end": end, + } + ) + if state_of_charge_percent is not UNSET: + field_dict["stateOfChargePercent"] = state_of_charge_percent + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + charge_kwh = d.pop("chargeKwh") + + discharge_kwh = d.pop("dischargeKwh") + + start = isoparse(d.pop("start")) + + end = isoparse(d.pop("end")) + + state_of_charge_percent = d.pop("stateOfChargePercent", UNSET) + + site_battery_interval = cls( + charge_kwh=charge_kwh, + discharge_kwh=discharge_kwh, + start=start, + end=end, + state_of_charge_percent=state_of_charge_percent, + ) + + return site_battery_interval diff --git a/derapi/models/site_bess.py b/derapi/models/site_bess.py new file mode 100644 index 0000000..924d966 --- /dev/null +++ b/derapi/models/site_bess.py @@ -0,0 +1,57 @@ +from typing import Any, Dict, Type, TypeVar, Union + +from attrs import define as _attrs_define + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="SiteBESS") + + +@_attrs_define +class SiteBESS: + """For Sites with Batteries this key is present + + Attributes: + nameplate_kwh (Union[Unset, float]): The rated storage capacity of the system in kWh + mode (Union[Unset, str]): Battery management system mode + state_of_charge_percent (Union[Unset, float]): Battery system state of charge as a percent of capacity + """ + + nameplate_kwh: Union[Unset, float] = UNSET + mode: Union[Unset, str] = UNSET + state_of_charge_percent: Union[Unset, float] = UNSET + + def to_dict(self) -> Dict[str, Any]: + nameplate_kwh = self.nameplate_kwh + + mode = self.mode + + state_of_charge_percent = self.state_of_charge_percent + + field_dict: Dict[str, Any] = {} + field_dict.update({}) + if nameplate_kwh is not UNSET: + field_dict["nameplateKwh"] = nameplate_kwh + if mode is not UNSET: + field_dict["mode"] = mode + if state_of_charge_percent is not UNSET: + field_dict["stateOfChargePercent"] = state_of_charge_percent + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + nameplate_kwh = d.pop("nameplateKwh", UNSET) + + mode = d.pop("mode", UNSET) + + state_of_charge_percent = d.pop("stateOfChargePercent", UNSET) + + site_bess = cls( + nameplate_kwh=nameplate_kwh, + mode=mode, + state_of_charge_percent=state_of_charge_percent, + ) + + return site_bess diff --git a/derapi/models/site_location.py b/derapi/models/site_location.py new file mode 100644 index 0000000..88d72a9 --- /dev/null +++ b/derapi/models/site_location.py @@ -0,0 +1,69 @@ +from typing import Any, Dict, Type, TypeVar, Union + +from attrs import define as _attrs_define + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="SiteLocation") + + +@_attrs_define +class SiteLocation: + """The location of this Solar Inverter in lat/lon coordinates + + Attributes: + current_utc_offset (float): UTC Offset in (possibly fractional) hours; positive values represent locations East + of UTC + lat (Union[Unset, float]): Latitude coordinate of the inverter + lon (Union[Unset, float]): Longitude coordinate of the inverter + timezone (Union[Unset, str]): IANA timezone string + """ + + current_utc_offset: float + lat: Union[Unset, float] = UNSET + lon: Union[Unset, float] = UNSET + timezone: Union[Unset, str] = UNSET + + def to_dict(self) -> Dict[str, Any]: + current_utc_offset = self.current_utc_offset + + lat = self.lat + + lon = self.lon + + timezone = self.timezone + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "currentUTCOffset": current_utc_offset, + } + ) + if lat is not UNSET: + field_dict["lat"] = lat + if lon is not UNSET: + field_dict["lon"] = lon + if timezone is not UNSET: + field_dict["timezone"] = timezone + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + current_utc_offset = d.pop("currentUTCOffset") + + lat = d.pop("lat", UNSET) + + lon = d.pop("lon", UNSET) + + timezone = d.pop("timezone", UNSET) + + site_location = cls( + current_utc_offset=current_utc_offset, + lat=lat, + lon=lon, + timezone=timezone, + ) + + return site_location diff --git a/derapi/models/site_solar_inverter_interval.py b/derapi/models/site_solar_inverter_interval.py new file mode 100644 index 0000000..39b7caf --- /dev/null +++ b/derapi/models/site_solar_inverter_interval.py @@ -0,0 +1,56 @@ +import datetime +from typing import Any, Dict, Type, TypeVar + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +T = TypeVar("T", bound="SiteSolarInverterInterval") + + +@_attrs_define +class SiteSolarInverterInterval: + """ + Attributes: + kwh (float): Solar energy production in kWh + start (datetime.datetime): Interval start in ISO-8601 format + end (datetime.datetime): Interval end in ISO-8601 format + """ + + kwh: float + start: datetime.datetime + end: datetime.datetime + + def to_dict(self) -> Dict[str, Any]: + kwh = self.kwh + + start = self.start.isoformat() + + end = self.end.isoformat() + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "kwh": kwh, + "start": start, + "end": end, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + kwh = d.pop("kwh") + + start = isoparse(d.pop("start")) + + end = isoparse(d.pop("end")) + + site_solar_inverter_interval = cls( + kwh=kwh, + start=start, + end=end, + ) + + return site_solar_inverter_interval diff --git a/derapi/models/site_summary.py b/derapi/models/site_summary.py new file mode 100644 index 0000000..3012a28 --- /dev/null +++ b/derapi/models/site_summary.py @@ -0,0 +1,38 @@ +from typing import Any, Dict, Type, TypeVar + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="SiteSummary") + + +@_attrs_define +class SiteSummary: + """ + Attributes: + id (str): the ID for the Site + """ + + id: str + + def to_dict(self) -> Dict[str, Any]: + id = self.id + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + id = d.pop("id") + + site_summary = cls( + id=id, + ) + + return site_summary diff --git a/derapi/models/sma_custom_grant_credentials.py b/derapi/models/sma_custom_grant_credentials.py new file mode 100644 index 0000000..17d637e --- /dev/null +++ b/derapi/models/sma_custom_grant_credentials.py @@ -0,0 +1,67 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="SMACustomGrantCredentials") + + +@_attrs_define +class SMACustomGrantCredentials: + """Credentials from the SMA custom grant oauth flow + + Attributes: + vendor (Literal['sma']): Default: 'sma'. + type (Literal['customgrant']): Default: 'customgrant'. + client_id (str): SMA Client ID + client_secret (str): SMA Client Secret + """ + + client_id: str + client_secret: str + vendor: Literal["sma"] = "sma" + type: Literal["customgrant"] = "customgrant" + + def to_dict(self) -> Dict[str, Any]: + vendor = self.vendor + + type = self.type + + client_id = self.client_id + + client_secret = self.client_secret + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "vendor": vendor, + "type": type, + "clientID": client_id, + "clientSecret": client_secret, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + vendor = cast(Literal["sma"], d.pop("vendor")) + if vendor != "sma": + raise ValueError(f"vendor must match const 'sma', got '{vendor}'") + + type = cast(Literal["customgrant"], d.pop("type")) + if type != "customgrant": + raise ValueError(f"type must match const 'customgrant', got '{type}'") + + client_id = d.pop("clientID") + + client_secret = d.pop("clientSecret") + + sma_custom_grant_credentials = cls( + vendor=vendor, + type=type, + client_id=client_id, + client_secret=client_secret, + ) + + return sma_custom_grant_credentials diff --git a/derapi/models/sma_join_config.py b/derapi/models/sma_join_config.py new file mode 100644 index 0000000..d57c63f --- /dev/null +++ b/derapi/models/sma_join_config.py @@ -0,0 +1,77 @@ +from typing import TYPE_CHECKING, Any, Dict, Literal, Type, TypeVar, Union, cast + +from attrs import define as _attrs_define + +if TYPE_CHECKING: + from ..models.sma_join_config_inline_credentials import SMAJoinConfigInlineCredentials + from ..models.stored_credentials_reference import StoredCredentialsReference + + +T = TypeVar("T", bound="SMAJoinConfig") + + +@_attrs_define +class SMAJoinConfig: + """ + Attributes: + vendor (Literal['sma']): + credentials (Union['SMAJoinConfigInlineCredentials', 'StoredCredentialsReference']): + """ + + vendor: Literal["sma"] + credentials: Union["SMAJoinConfigInlineCredentials", "StoredCredentialsReference"] + + def to_dict(self) -> Dict[str, Any]: + from ..models.sma_join_config_inline_credentials import SMAJoinConfigInlineCredentials + + vendor = self.vendor + + credentials: Dict[str, Any] + if isinstance(self.credentials, SMAJoinConfigInlineCredentials): + credentials = self.credentials.to_dict() + else: + credentials = self.credentials.to_dict() + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "vendor": vendor, + "credentials": credentials, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.sma_join_config_inline_credentials import SMAJoinConfigInlineCredentials + from ..models.stored_credentials_reference import StoredCredentialsReference + + d = src_dict.copy() + vendor = cast(Literal["sma"], d.pop("vendor")) + if vendor != "sma": + raise ValueError(f"vendor must match const 'sma', got '{vendor}'") + + def _parse_credentials(data: object) -> Union["SMAJoinConfigInlineCredentials", "StoredCredentialsReference"]: + try: + if not isinstance(data, dict): + raise TypeError() + credentials_type_0 = SMAJoinConfigInlineCredentials.from_dict(data) + + return credentials_type_0 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + credentials_type_1 = StoredCredentialsReference.from_dict(data) + + return credentials_type_1 + + credentials = _parse_credentials(d.pop("credentials")) + + sma_join_config = cls( + vendor=vendor, + credentials=credentials, + ) + + return sma_join_config diff --git a/derapi/models/sma_join_config_inline_credentials.py b/derapi/models/sma_join_config_inline_credentials.py new file mode 100644 index 0000000..837db9c --- /dev/null +++ b/derapi/models/sma_join_config_inline_credentials.py @@ -0,0 +1,46 @@ +from typing import Any, Dict, Type, TypeVar + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="SMAJoinConfigInlineCredentials") + + +@_attrs_define +class SMAJoinConfigInlineCredentials: + """ + Attributes: + client_id (str): SMA Client ID + client_secret (str): SMA Client Secret + """ + + client_id: str + client_secret: str + + def to_dict(self) -> Dict[str, Any]: + client_id = self.client_id + + client_secret = self.client_secret + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "clientID": client_id, + "clientSecret": client_secret, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + client_id = d.pop("clientID") + + client_secret = d.pop("clientSecret") + + sma_join_config_inline_credentials = cls( + client_id=client_id, + client_secret=client_secret, + ) + + return sma_join_config_inline_credentials diff --git a/derapi/models/sma_sandbox_custom_grant_credentials.py b/derapi/models/sma_sandbox_custom_grant_credentials.py new file mode 100644 index 0000000..0c6d5cf --- /dev/null +++ b/derapi/models/sma_sandbox_custom_grant_credentials.py @@ -0,0 +1,67 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="SMASandboxCustomGrantCredentials") + + +@_attrs_define +class SMASandboxCustomGrantCredentials: + """Credentials from the SMA Sandbox custom grant oauth flow + + Attributes: + vendor (Literal['smasbox']): Default: 'smasbox'. + type (Literal['customgrant']): Default: 'customgrant'. + client_id (str): SMA Sandbox Client ID + client_secret (str): SMA Sandbox Client Secret + """ + + client_id: str + client_secret: str + vendor: Literal["smasbox"] = "smasbox" + type: Literal["customgrant"] = "customgrant" + + def to_dict(self) -> Dict[str, Any]: + vendor = self.vendor + + type = self.type + + client_id = self.client_id + + client_secret = self.client_secret + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "vendor": vendor, + "type": type, + "clientID": client_id, + "clientSecret": client_secret, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + vendor = cast(Literal["smasbox"], d.pop("vendor")) + if vendor != "smasbox": + raise ValueError(f"vendor must match const 'smasbox', got '{vendor}'") + + type = cast(Literal["customgrant"], d.pop("type")) + if type != "customgrant": + raise ValueError(f"type must match const 'customgrant', got '{type}'") + + client_id = d.pop("clientID") + + client_secret = d.pop("clientSecret") + + sma_sandbox_custom_grant_credentials = cls( + vendor=vendor, + type=type, + client_id=client_id, + client_secret=client_secret, + ) + + return sma_sandbox_custom_grant_credentials diff --git a/derapi/models/sma_sandbox_join_config.py b/derapi/models/sma_sandbox_join_config.py new file mode 100644 index 0000000..ad0e7a1 --- /dev/null +++ b/derapi/models/sma_sandbox_join_config.py @@ -0,0 +1,79 @@ +from typing import TYPE_CHECKING, Any, Dict, Literal, Type, TypeVar, Union, cast + +from attrs import define as _attrs_define + +if TYPE_CHECKING: + from ..models.sma_sandbox_join_config_inline_credentials import SMASandboxJoinConfigInlineCredentials + from ..models.stored_credentials_reference import StoredCredentialsReference + + +T = TypeVar("T", bound="SMASandboxJoinConfig") + + +@_attrs_define +class SMASandboxJoinConfig: + """ + Attributes: + vendor (Literal['smasbox']): + credentials (Union['SMASandboxJoinConfigInlineCredentials', 'StoredCredentialsReference']): + """ + + vendor: Literal["smasbox"] + credentials: Union["SMASandboxJoinConfigInlineCredentials", "StoredCredentialsReference"] + + def to_dict(self) -> Dict[str, Any]: + from ..models.sma_sandbox_join_config_inline_credentials import SMASandboxJoinConfigInlineCredentials + + vendor = self.vendor + + credentials: Dict[str, Any] + if isinstance(self.credentials, SMASandboxJoinConfigInlineCredentials): + credentials = self.credentials.to_dict() + else: + credentials = self.credentials.to_dict() + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "vendor": vendor, + "credentials": credentials, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.sma_sandbox_join_config_inline_credentials import SMASandboxJoinConfigInlineCredentials + from ..models.stored_credentials_reference import StoredCredentialsReference + + d = src_dict.copy() + vendor = cast(Literal["smasbox"], d.pop("vendor")) + if vendor != "smasbox": + raise ValueError(f"vendor must match const 'smasbox', got '{vendor}'") + + def _parse_credentials( + data: object, + ) -> Union["SMASandboxJoinConfigInlineCredentials", "StoredCredentialsReference"]: + try: + if not isinstance(data, dict): + raise TypeError() + credentials_type_0 = SMASandboxJoinConfigInlineCredentials.from_dict(data) + + return credentials_type_0 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + credentials_type_1 = StoredCredentialsReference.from_dict(data) + + return credentials_type_1 + + credentials = _parse_credentials(d.pop("credentials")) + + sma_sandbox_join_config = cls( + vendor=vendor, + credentials=credentials, + ) + + return sma_sandbox_join_config diff --git a/derapi/models/sma_sandbox_join_config_inline_credentials.py b/derapi/models/sma_sandbox_join_config_inline_credentials.py new file mode 100644 index 0000000..06a8556 --- /dev/null +++ b/derapi/models/sma_sandbox_join_config_inline_credentials.py @@ -0,0 +1,46 @@ +from typing import Any, Dict, Type, TypeVar + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="SMASandboxJoinConfigInlineCredentials") + + +@_attrs_define +class SMASandboxJoinConfigInlineCredentials: + """ + Attributes: + client_id (str): SMA Sandbox Client ID + client_secret (str): SMA Sandbox Client Secret + """ + + client_id: str + client_secret: str + + def to_dict(self) -> Dict[str, Any]: + client_id = self.client_id + + client_secret = self.client_secret + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "clientID": client_id, + "clientSecret": client_secret, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + client_id = d.pop("clientID") + + client_secret = d.pop("clientSecret") + + sma_sandbox_join_config_inline_credentials = cls( + client_id=client_id, + client_secret=client_secret, + ) + + return sma_sandbox_join_config_inline_credentials diff --git a/derapi/models/sma_sandbox_o_auth_credentials.py b/derapi/models/sma_sandbox_o_auth_credentials.py new file mode 100644 index 0000000..e3eff68 --- /dev/null +++ b/derapi/models/sma_sandbox_o_auth_credentials.py @@ -0,0 +1,67 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="SMASandboxOAuthCredentials") + + +@_attrs_define +class SMASandboxOAuthCredentials: + """Credentials from the SMA Sandbox OAuth code grant flow + + Attributes: + vendor (Literal['smasbox']): Default: 'smasbox'. + type (Literal['oauthclient']): Default: 'oauthclient'. + client_id (str): SMA Sandbox Client ID + client_secret (str): SMA Sandbox Client Secret + """ + + client_id: str + client_secret: str + vendor: Literal["smasbox"] = "smasbox" + type: Literal["oauthclient"] = "oauthclient" + + def to_dict(self) -> Dict[str, Any]: + vendor = self.vendor + + type = self.type + + client_id = self.client_id + + client_secret = self.client_secret + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "vendor": vendor, + "type": type, + "clientID": client_id, + "clientSecret": client_secret, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + vendor = cast(Literal["smasbox"], d.pop("vendor")) + if vendor != "smasbox": + raise ValueError(f"vendor must match const 'smasbox', got '{vendor}'") + + type = cast(Literal["oauthclient"], d.pop("type")) + if type != "oauthclient": + raise ValueError(f"type must match const 'oauthclient', got '{type}'") + + client_id = d.pop("clientID") + + client_secret = d.pop("clientSecret") + + sma_sandbox_o_auth_credentials = cls( + vendor=vendor, + type=type, + client_id=client_id, + client_secret=client_secret, + ) + + return sma_sandbox_o_auth_credentials diff --git a/derapi/models/smao_auth_credentials.py b/derapi/models/smao_auth_credentials.py new file mode 100644 index 0000000..febf861 --- /dev/null +++ b/derapi/models/smao_auth_credentials.py @@ -0,0 +1,67 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="SMAOAuthCredentials") + + +@_attrs_define +class SMAOAuthCredentials: + """Credentials from the SMA OAuth code grant flow + + Attributes: + vendor (Literal['sma']): Default: 'sma'. + type (Literal['oauthclient']): Default: 'oauthclient'. + client_id (str): SMA Client ID + client_secret (str): SMA Client Secret + """ + + client_id: str + client_secret: str + vendor: Literal["sma"] = "sma" + type: Literal["oauthclient"] = "oauthclient" + + def to_dict(self) -> Dict[str, Any]: + vendor = self.vendor + + type = self.type + + client_id = self.client_id + + client_secret = self.client_secret + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "vendor": vendor, + "type": type, + "clientID": client_id, + "clientSecret": client_secret, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + vendor = cast(Literal["sma"], d.pop("vendor")) + if vendor != "sma": + raise ValueError(f"vendor must match const 'sma', got '{vendor}'") + + type = cast(Literal["oauthclient"], d.pop("type")) + if type != "oauthclient": + raise ValueError(f"type must match const 'oauthclient', got '{type}'") + + client_id = d.pop("clientID") + + client_secret = d.pop("clientSecret") + + smao_auth_credentials = cls( + vendor=vendor, + type=type, + client_id=client_id, + client_secret=client_secret, + ) + + return smao_auth_credentials diff --git a/derapi/models/solar_edge_credentials.py b/derapi/models/solar_edge_credentials.py new file mode 100644 index 0000000..d06d9c8 --- /dev/null +++ b/derapi/models/solar_edge_credentials.py @@ -0,0 +1,58 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="SolarEdgeCredentials") + + +@_attrs_define +class SolarEdgeCredentials: + """ + Attributes: + vendor (Literal['solaredge']): Default: 'solaredge'. + type (Literal['apikey']): Default: 'apikey'. + api_key (str): SolarEdge API Key + """ + + api_key: str + vendor: Literal["solaredge"] = "solaredge" + type: Literal["apikey"] = "apikey" + + def to_dict(self) -> Dict[str, Any]: + vendor = self.vendor + + type = self.type + + api_key = self.api_key + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "vendor": vendor, + "type": type, + "apiKey": api_key, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + vendor = cast(Literal["solaredge"], d.pop("vendor")) + if vendor != "solaredge": + raise ValueError(f"vendor must match const 'solaredge', got '{vendor}'") + + type = cast(Literal["apikey"], d.pop("type")) + if type != "apikey": + raise ValueError(f"type must match const 'apikey', got '{type}'") + + api_key = d.pop("apiKey") + + solar_edge_credentials = cls( + vendor=vendor, + type=type, + api_key=api_key, + ) + + return solar_edge_credentials diff --git a/derapi/models/solar_inverter.py b/derapi/models/solar_inverter.py new file mode 100644 index 0000000..7296aab --- /dev/null +++ b/derapi/models/solar_inverter.py @@ -0,0 +1,249 @@ +import datetime +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..models.vendor import Vendor +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.solar_inverter_lifetime_production import SolarInverterLifetimeProduction + from ..models.solar_inverter_recent_errors_error import SolarInverterRecentErrorsError + from ..models.solar_inverter_recent_errors_info import SolarInverterRecentErrorsInfo + from ..models.solar_inverter_recent_errors_start import SolarInverterRecentErrorsStart + from ..models.solar_inverter_recent_errors_warning import SolarInverterRecentErrorsWarning + from ..models.solar_inverter_recent_production import SolarInverterRecentProduction + + +T = TypeVar("T", bound="SolarInverter") + + +@_attrs_define +class SolarInverter: + """ + Attributes: + id (str): ID of the solar inverter + vendor (Vendor): + reported_at (datetime.datetime): Date the request was generated in ISO-8601 format + model (str): Model number of this Solar Inverter + serial_number (str): Manufacturer serial number of this Solar Inverter + site_id (str): The Derapi Site ID this Solar Inverter is associated with + name (Union[Unset, str]): Customer defined name of this Solar Inverter + recent_production (Union[Unset, SolarInverterRecentProduction]): + lifetime_production (Union[Unset, SolarInverterLifetimeProduction]): + recent_errors (Union[Unset, List[Union['SolarInverterRecentErrorsError', 'SolarInverterRecentErrorsInfo', + 'SolarInverterRecentErrorsStart', 'SolarInverterRecentErrorsWarning']]]): Most recent errors, warnings, or info + reported by the manufacturer for this Solar Inverter. The key represents the severity level + (info/warning/error); the value is a string description. start is always present and is the last element to be + returned. + """ + + id: str + vendor: Vendor + reported_at: datetime.datetime + model: str + serial_number: str + site_id: str + name: Union[Unset, str] = UNSET + recent_production: Union[Unset, "SolarInverterRecentProduction"] = UNSET + lifetime_production: Union[Unset, "SolarInverterLifetimeProduction"] = UNSET + recent_errors: Union[ + Unset, + List[ + Union[ + "SolarInverterRecentErrorsError", + "SolarInverterRecentErrorsInfo", + "SolarInverterRecentErrorsStart", + "SolarInverterRecentErrorsWarning", + ] + ], + ] = UNSET + + def to_dict(self) -> Dict[str, Any]: + from ..models.solar_inverter_recent_errors_error import SolarInverterRecentErrorsError + from ..models.solar_inverter_recent_errors_info import SolarInverterRecentErrorsInfo + from ..models.solar_inverter_recent_errors_warning import SolarInverterRecentErrorsWarning + + id = self.id + + vendor = self.vendor.value + + reported_at = self.reported_at.isoformat() + + model = self.model + + serial_number = self.serial_number + + site_id = self.site_id + + name = self.name + + recent_production: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.recent_production, Unset): + recent_production = self.recent_production.to_dict() + + lifetime_production: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.lifetime_production, Unset): + lifetime_production = self.lifetime_production.to_dict() + + recent_errors: Union[Unset, List[Dict[str, Any]]] = UNSET + if not isinstance(self.recent_errors, Unset): + recent_errors = [] + for componentsschemas_solar_inverter_recent_errors_item_data in self.recent_errors: + componentsschemas_solar_inverter_recent_errors_item: Dict[str, Any] + if isinstance(componentsschemas_solar_inverter_recent_errors_item_data, SolarInverterRecentErrorsError): + componentsschemas_solar_inverter_recent_errors_item = ( + componentsschemas_solar_inverter_recent_errors_item_data.to_dict() + ) + elif isinstance( + componentsschemas_solar_inverter_recent_errors_item_data, SolarInverterRecentErrorsWarning + ): + componentsschemas_solar_inverter_recent_errors_item = ( + componentsschemas_solar_inverter_recent_errors_item_data.to_dict() + ) + elif isinstance( + componentsschemas_solar_inverter_recent_errors_item_data, SolarInverterRecentErrorsInfo + ): + componentsschemas_solar_inverter_recent_errors_item = ( + componentsschemas_solar_inverter_recent_errors_item_data.to_dict() + ) + else: + componentsschemas_solar_inverter_recent_errors_item = ( + componentsschemas_solar_inverter_recent_errors_item_data.to_dict() + ) + + recent_errors.append(componentsschemas_solar_inverter_recent_errors_item) + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "vendor": vendor, + "reportedAt": reported_at, + "model": model, + "serialNumber": serial_number, + "siteID": site_id, + } + ) + if name is not UNSET: + field_dict["name"] = name + if recent_production is not UNSET: + field_dict["recentProduction"] = recent_production + if lifetime_production is not UNSET: + field_dict["lifetimeProduction"] = lifetime_production + if recent_errors is not UNSET: + field_dict["recentErrors"] = recent_errors + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.solar_inverter_lifetime_production import SolarInverterLifetimeProduction + from ..models.solar_inverter_recent_errors_error import SolarInverterRecentErrorsError + from ..models.solar_inverter_recent_errors_info import SolarInverterRecentErrorsInfo + from ..models.solar_inverter_recent_errors_start import SolarInverterRecentErrorsStart + from ..models.solar_inverter_recent_errors_warning import SolarInverterRecentErrorsWarning + from ..models.solar_inverter_recent_production import SolarInverterRecentProduction + + d = src_dict.copy() + id = d.pop("id") + + vendor = Vendor(d.pop("vendor")) + + reported_at = isoparse(d.pop("reportedAt")) + + model = d.pop("model") + + serial_number = d.pop("serialNumber") + + site_id = d.pop("siteID") + + name = d.pop("name", UNSET) + + _recent_production = d.pop("recentProduction", UNSET) + recent_production: Union[Unset, SolarInverterRecentProduction] + if isinstance(_recent_production, Unset): + recent_production = UNSET + else: + recent_production = SolarInverterRecentProduction.from_dict(_recent_production) + + _lifetime_production = d.pop("lifetimeProduction", UNSET) + lifetime_production: Union[Unset, SolarInverterLifetimeProduction] + if isinstance(_lifetime_production, Unset): + lifetime_production = UNSET + else: + lifetime_production = SolarInverterLifetimeProduction.from_dict(_lifetime_production) + + recent_errors = [] + _recent_errors = d.pop("recentErrors", UNSET) + for componentsschemas_solar_inverter_recent_errors_item_data in _recent_errors or []: + + def _parse_componentsschemas_solar_inverter_recent_errors_item( + data: object, + ) -> Union[ + "SolarInverterRecentErrorsError", + "SolarInverterRecentErrorsInfo", + "SolarInverterRecentErrorsStart", + "SolarInverterRecentErrorsWarning", + ]: + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_solar_inverter_recent_errors_item_type_0 = ( + SolarInverterRecentErrorsError.from_dict(data) + ) + + return componentsschemas_solar_inverter_recent_errors_item_type_0 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_solar_inverter_recent_errors_item_type_1 = ( + SolarInverterRecentErrorsWarning.from_dict(data) + ) + + return componentsschemas_solar_inverter_recent_errors_item_type_1 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_solar_inverter_recent_errors_item_type_2 = ( + SolarInverterRecentErrorsInfo.from_dict(data) + ) + + return componentsschemas_solar_inverter_recent_errors_item_type_2 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + componentsschemas_solar_inverter_recent_errors_item_type_3 = SolarInverterRecentErrorsStart.from_dict( + data + ) + + return componentsschemas_solar_inverter_recent_errors_item_type_3 + + componentsschemas_solar_inverter_recent_errors_item = ( + _parse_componentsschemas_solar_inverter_recent_errors_item( + componentsschemas_solar_inverter_recent_errors_item_data + ) + ) + + recent_errors.append(componentsschemas_solar_inverter_recent_errors_item) + + solar_inverter = cls( + id=id, + vendor=vendor, + reported_at=reported_at, + model=model, + serial_number=serial_number, + site_id=site_id, + name=name, + recent_production=recent_production, + lifetime_production=lifetime_production, + recent_errors=recent_errors, + ) + + return solar_inverter diff --git a/derapi/models/solar_inverter_interval.py b/derapi/models/solar_inverter_interval.py new file mode 100644 index 0000000..45994a6 --- /dev/null +++ b/derapi/models/solar_inverter_interval.py @@ -0,0 +1,56 @@ +import datetime +from typing import Any, Dict, Type, TypeVar + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +T = TypeVar("T", bound="SolarInverterInterval") + + +@_attrs_define +class SolarInverterInterval: + """ + Attributes: + kwh (float): Solar energy production in kWh + start (datetime.datetime): Interval start in ISO-8601 format + end (datetime.datetime): Interval end in ISO-8601 format + """ + + kwh: float + start: datetime.datetime + end: datetime.datetime + + def to_dict(self) -> Dict[str, Any]: + kwh = self.kwh + + start = self.start.isoformat() + + end = self.end.isoformat() + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "kwh": kwh, + "start": start, + "end": end, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + kwh = d.pop("kwh") + + start = isoparse(d.pop("start")) + + end = isoparse(d.pop("end")) + + solar_inverter_interval = cls( + kwh=kwh, + start=start, + end=end, + ) + + return solar_inverter_interval diff --git a/derapi/models/solar_inverter_lifetime_production.py b/derapi/models/solar_inverter_lifetime_production.py new file mode 100644 index 0000000..31033c0 --- /dev/null +++ b/derapi/models/solar_inverter_lifetime_production.py @@ -0,0 +1,65 @@ +import datetime +from typing import Any, Dict, Type, TypeVar, Union, cast + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +T = TypeVar("T", bound="SolarInverterLifetimeProduction") + + +@_attrs_define +class SolarInverterLifetimeProduction: + """ + Attributes: + kwh (float): Lifetime production value in kWh + start (Union[None, datetime.datetime]): The start date of the lifetime production period in ISO-8601 format + """ + + kwh: float + start: Union[None, datetime.datetime] + + def to_dict(self) -> Dict[str, Any]: + kwh = self.kwh + + start: Union[None, str] + if isinstance(self.start, datetime.datetime): + start = self.start.isoformat() + else: + start = self.start + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "kwh": kwh, + "start": start, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + kwh = d.pop("kwh") + + def _parse_start(data: object) -> Union[None, datetime.datetime]: + if data is None: + return data + try: + if not isinstance(data, str): + raise TypeError() + start_type_0 = isoparse(data) + + return start_type_0 + except: # noqa: E722 + pass + return cast(Union[None, datetime.datetime], data) + + start = _parse_start(d.pop("start")) + + solar_inverter_lifetime_production = cls( + kwh=kwh, + start=start, + ) + + return solar_inverter_lifetime_production diff --git a/derapi/models/solar_inverter_recent_errors_error.py b/derapi/models/solar_inverter_recent_errors_error.py new file mode 100644 index 0000000..b7e7255 --- /dev/null +++ b/derapi/models/solar_inverter_recent_errors_error.py @@ -0,0 +1,38 @@ +from typing import Any, Dict, Type, TypeVar + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="SolarInverterRecentErrorsError") + + +@_attrs_define +class SolarInverterRecentErrorsError: + """ + Attributes: + error (str): + """ + + error: str + + def to_dict(self) -> Dict[str, Any]: + error = self.error + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "error": error, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + error = d.pop("error") + + solar_inverter_recent_errors_error = cls( + error=error, + ) + + return solar_inverter_recent_errors_error diff --git a/derapi/models/solar_inverter_recent_errors_info.py b/derapi/models/solar_inverter_recent_errors_info.py new file mode 100644 index 0000000..3be40d3 --- /dev/null +++ b/derapi/models/solar_inverter_recent_errors_info.py @@ -0,0 +1,38 @@ +from typing import Any, Dict, Type, TypeVar + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="SolarInverterRecentErrorsInfo") + + +@_attrs_define +class SolarInverterRecentErrorsInfo: + """ + Attributes: + info (str): + """ + + info: str + + def to_dict(self) -> Dict[str, Any]: + info = self.info + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "info": info, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + info = d.pop("info") + + solar_inverter_recent_errors_info = cls( + info=info, + ) + + return solar_inverter_recent_errors_info diff --git a/derapi/models/solar_inverter_recent_errors_start.py b/derapi/models/solar_inverter_recent_errors_start.py new file mode 100644 index 0000000..8897b9c --- /dev/null +++ b/derapi/models/solar_inverter_recent_errors_start.py @@ -0,0 +1,40 @@ +import datetime +from typing import Any, Dict, Type, TypeVar + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +T = TypeVar("T", bound="SolarInverterRecentErrorsStart") + + +@_attrs_define +class SolarInverterRecentErrorsStart: + """ + Attributes: + start (datetime.datetime): The start date of the recent errors log in ISO-8601 format + """ + + start: datetime.datetime + + def to_dict(self) -> Dict[str, Any]: + start = self.start.isoformat() + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "start": start, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + start = isoparse(d.pop("start")) + + solar_inverter_recent_errors_start = cls( + start=start, + ) + + return solar_inverter_recent_errors_start diff --git a/derapi/models/solar_inverter_recent_errors_warning.py b/derapi/models/solar_inverter_recent_errors_warning.py new file mode 100644 index 0000000..303cbda --- /dev/null +++ b/derapi/models/solar_inverter_recent_errors_warning.py @@ -0,0 +1,38 @@ +from typing import Any, Dict, Type, TypeVar + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="SolarInverterRecentErrorsWarning") + + +@_attrs_define +class SolarInverterRecentErrorsWarning: + """ + Attributes: + warning (str): + """ + + warning: str + + def to_dict(self) -> Dict[str, Any]: + warning = self.warning + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "warning": warning, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + warning = d.pop("warning") + + solar_inverter_recent_errors_warning = cls( + warning=warning, + ) + + return solar_inverter_recent_errors_warning diff --git a/derapi/models/solar_inverter_recent_production.py b/derapi/models/solar_inverter_recent_production.py new file mode 100644 index 0000000..bfa2029 --- /dev/null +++ b/derapi/models/solar_inverter_recent_production.py @@ -0,0 +1,48 @@ +import datetime +from typing import Any, Dict, Type, TypeVar + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +T = TypeVar("T", bound="SolarInverterRecentProduction") + + +@_attrs_define +class SolarInverterRecentProduction: + """ + Attributes: + kwh (float): Recent production value in kWh + start (datetime.datetime): The start date of the recent production period in ISO-8601 format + """ + + kwh: float + start: datetime.datetime + + def to_dict(self) -> Dict[str, Any]: + kwh = self.kwh + + start = self.start.isoformat() + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "kwh": kwh, + "start": start, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + kwh = d.pop("kwh") + + start = isoparse(d.pop("start")) + + solar_inverter_recent_production = cls( + kwh=kwh, + start=start, + ) + + return solar_inverter_recent_production diff --git a/derapi/models/solar_inverter_summary.py b/derapi/models/solar_inverter_summary.py new file mode 100644 index 0000000..ce3986f --- /dev/null +++ b/derapi/models/solar_inverter_summary.py @@ -0,0 +1,38 @@ +from typing import Any, Dict, Type, TypeVar + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="SolarInverterSummary") + + +@_attrs_define +class SolarInverterSummary: + """ + Attributes: + id (str): ID of the solar inverter + """ + + id: str + + def to_dict(self) -> Dict[str, Any]: + id = self.id + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + id = d.pop("id") + + solar_inverter_summary = cls( + id=id, + ) + + return solar_inverter_summary diff --git a/derapi/models/solaredge_join_config.py b/derapi/models/solaredge_join_config.py new file mode 100644 index 0000000..ff84c5a --- /dev/null +++ b/derapi/models/solaredge_join_config.py @@ -0,0 +1,40 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="SolaredgeJoinConfig") + + +@_attrs_define +class SolaredgeJoinConfig: + """ + Attributes: + vendor (Literal['solaredge']): + """ + + vendor: Literal["solaredge"] + + def to_dict(self) -> Dict[str, Any]: + vendor = self.vendor + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "vendor": vendor, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + vendor = cast(Literal["solaredge"], d.pop("vendor")) + if vendor != "solaredge": + raise ValueError(f"vendor must match const 'solaredge', got '{vendor}'") + + solaredge_join_config = cls( + vendor=vendor, + ) + + return solaredge_join_config diff --git a/derapi/models/solis_credentials.py b/derapi/models/solis_credentials.py new file mode 100644 index 0000000..1a12ac0 --- /dev/null +++ b/derapi/models/solis_credentials.py @@ -0,0 +1,66 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="SolisCredentials") + + +@_attrs_define +class SolisCredentials: + """ + Attributes: + vendor (Literal['solis']): Default: 'solis'. + type (Literal['apikeysecret']): Default: 'apikeysecret'. + key_id (str): Solis Key ID + key_secret (str): Solis Secret + """ + + key_id: str + key_secret: str + vendor: Literal["solis"] = "solis" + type: Literal["apikeysecret"] = "apikeysecret" + + def to_dict(self) -> Dict[str, Any]: + vendor = self.vendor + + type = self.type + + key_id = self.key_id + + key_secret = self.key_secret + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "vendor": vendor, + "type": type, + "keyID": key_id, + "keySecret": key_secret, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + vendor = cast(Literal["solis"], d.pop("vendor")) + if vendor != "solis": + raise ValueError(f"vendor must match const 'solis', got '{vendor}'") + + type = cast(Literal["apikeysecret"], d.pop("type")) + if type != "apikeysecret": + raise ValueError(f"type must match const 'apikeysecret', got '{type}'") + + key_id = d.pop("keyID") + + key_secret = d.pop("keySecret") + + solis_credentials = cls( + vendor=vendor, + type=type, + key_id=key_id, + key_secret=key_secret, + ) + + return solis_credentials diff --git a/derapi/models/solis_join_config.py b/derapi/models/solis_join_config.py new file mode 100644 index 0000000..9212f0e --- /dev/null +++ b/derapi/models/solis_join_config.py @@ -0,0 +1,40 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="SolisJoinConfig") + + +@_attrs_define +class SolisJoinConfig: + """ + Attributes: + vendor (Literal['solis']): + """ + + vendor: Literal["solis"] + + def to_dict(self) -> Dict[str, Any]: + vendor = self.vendor + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "vendor": vendor, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + vendor = cast(Literal["solis"], d.pop("vendor")) + if vendor != "solis": + raise ValueError(f"vendor must match const 'solis', got '{vendor}'") + + solis_join_config = cls( + vendor=vendor, + ) + + return solis_join_config diff --git a/derapi/models/stored_credentials_reference.py b/derapi/models/stored_credentials_reference.py new file mode 100644 index 0000000..05aa753 --- /dev/null +++ b/derapi/models/stored_credentials_reference.py @@ -0,0 +1,38 @@ +from typing import Any, Dict, Type, TypeVar + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="StoredCredentialsReference") + + +@_attrs_define +class StoredCredentialsReference: + """ + Attributes: + credentials_id (str): ID for the vendor credentials + """ + + credentials_id: str + + def to_dict(self) -> Dict[str, Any]: + credentials_id = self.credentials_id + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "credentialsID": credentials_id, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + credentials_id = d.pop("credentialsID") + + stored_credentials_reference = cls( + credentials_id=credentials_id, + ) + + return stored_credentials_reference diff --git a/derapi/models/summary_level.py b/derapi/models/summary_level.py new file mode 100644 index 0000000..1dcffaa --- /dev/null +++ b/derapi/models/summary_level.py @@ -0,0 +1,11 @@ +from enum import Enum + + +class SummaryLevel(str, Enum): + DAY = "day" + HOUR = "hour" + MONTH = "month" + VALUE_3 = "15mins" + + def __str__(self) -> str: + return str(self.value) diff --git a/derapi/models/telsa_join_config_inline_credentials.py b/derapi/models/telsa_join_config_inline_credentials.py new file mode 100644 index 0000000..77efd80 --- /dev/null +++ b/derapi/models/telsa_join_config_inline_credentials.py @@ -0,0 +1,46 @@ +from typing import Any, Dict, Type, TypeVar + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="TelsaJoinConfigInlineCredentials") + + +@_attrs_define +class TelsaJoinConfigInlineCredentials: + """ + Attributes: + client_id (str): Client ID for a Tesla App + client_secret (str): Client secret for a Tesla App + """ + + client_id: str + client_secret: str + + def to_dict(self) -> Dict[str, Any]: + client_id = self.client_id + + client_secret = self.client_secret + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "clientID": client_id, + "clientSecret": client_secret, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + client_id = d.pop("clientID") + + client_secret = d.pop("clientSecret") + + telsa_join_config_inline_credentials = cls( + client_id=client_id, + client_secret=client_secret, + ) + + return telsa_join_config_inline_credentials diff --git a/derapi/models/tesla_app_credentials.py b/derapi/models/tesla_app_credentials.py new file mode 100644 index 0000000..69b883a --- /dev/null +++ b/derapi/models/tesla_app_credentials.py @@ -0,0 +1,66 @@ +from typing import Any, Dict, Literal, Type, TypeVar, cast + +from attrs import define as _attrs_define + +T = TypeVar("T", bound="TeslaAppCredentials") + + +@_attrs_define +class TeslaAppCredentials: + """ + Attributes: + vendor (Literal['tesla']): Default: 'tesla'. + type (Literal['app']): Default: 'app'. + client_id (str): Client ID for a Tesla App + client_secret (str): Client secret for a Tesla App + """ + + client_id: str + client_secret: str + vendor: Literal["tesla"] = "tesla" + type: Literal["app"] = "app" + + def to_dict(self) -> Dict[str, Any]: + vendor = self.vendor + + type = self.type + + client_id = self.client_id + + client_secret = self.client_secret + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "vendor": vendor, + "type": type, + "clientID": client_id, + "clientSecret": client_secret, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + vendor = cast(Literal["tesla"], d.pop("vendor")) + if vendor != "tesla": + raise ValueError(f"vendor must match const 'tesla', got '{vendor}'") + + type = cast(Literal["app"], d.pop("type")) + if type != "app": + raise ValueError(f"type must match const 'app', got '{type}'") + + client_id = d.pop("clientID") + + client_secret = d.pop("clientSecret") + + tesla_app_credentials = cls( + vendor=vendor, + type=type, + client_id=client_id, + client_secret=client_secret, + ) + + return tesla_app_credentials diff --git a/derapi/models/tesla_join_config.py b/derapi/models/tesla_join_config.py new file mode 100644 index 0000000..011b7c6 --- /dev/null +++ b/derapi/models/tesla_join_config.py @@ -0,0 +1,77 @@ +from typing import TYPE_CHECKING, Any, Dict, Literal, Type, TypeVar, Union, cast + +from attrs import define as _attrs_define + +if TYPE_CHECKING: + from ..models.stored_credentials_reference import StoredCredentialsReference + from ..models.telsa_join_config_inline_credentials import TelsaJoinConfigInlineCredentials + + +T = TypeVar("T", bound="TeslaJoinConfig") + + +@_attrs_define +class TeslaJoinConfig: + """ + Attributes: + vendor (Literal['tesla']): + credentials (Union['StoredCredentialsReference', 'TelsaJoinConfigInlineCredentials']): + """ + + vendor: Literal["tesla"] + credentials: Union["StoredCredentialsReference", "TelsaJoinConfigInlineCredentials"] + + def to_dict(self) -> Dict[str, Any]: + from ..models.telsa_join_config_inline_credentials import TelsaJoinConfigInlineCredentials + + vendor = self.vendor + + credentials: Dict[str, Any] + if isinstance(self.credentials, TelsaJoinConfigInlineCredentials): + credentials = self.credentials.to_dict() + else: + credentials = self.credentials.to_dict() + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "vendor": vendor, + "credentials": credentials, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.stored_credentials_reference import StoredCredentialsReference + from ..models.telsa_join_config_inline_credentials import TelsaJoinConfigInlineCredentials + + d = src_dict.copy() + vendor = cast(Literal["tesla"], d.pop("vendor")) + if vendor != "tesla": + raise ValueError(f"vendor must match const 'tesla', got '{vendor}'") + + def _parse_credentials(data: object) -> Union["StoredCredentialsReference", "TelsaJoinConfigInlineCredentials"]: + try: + if not isinstance(data, dict): + raise TypeError() + credentials_type_0 = TelsaJoinConfigInlineCredentials.from_dict(data) + + return credentials_type_0 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + credentials_type_1 = StoredCredentialsReference.from_dict(data) + + return credentials_type_1 + + credentials = _parse_credentials(d.pop("credentials")) + + tesla_join_config = cls( + vendor=vendor, + credentials=credentials, + ) + + return tesla_join_config diff --git a/derapi/models/update_vendor_credentials_request.py b/derapi/models/update_vendor_credentials_request.py new file mode 100644 index 0000000..0438bc4 --- /dev/null +++ b/derapi/models/update_vendor_credentials_request.py @@ -0,0 +1,242 @@ +from typing import TYPE_CHECKING, Any, Dict, Type, TypeVar, Union, cast + +from attrs import define as _attrs_define + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.enphase_developer_app_credentials import EnphaseDeveloperAppCredentials + from ..models.enphase_partner_app_credentials import EnphasePartnerAppCredentials + from ..models.enphase_vpp_credentials import EnphaseVPPCredentials + from ..models.franklin_wh_credentials import FranklinWHCredentials + from ..models.sma_custom_grant_credentials import SMACustomGrantCredentials + from ..models.sma_sandbox_custom_grant_credentials import SMASandboxCustomGrantCredentials + from ..models.sma_sandbox_o_auth_credentials import SMASandboxOAuthCredentials + from ..models.smao_auth_credentials import SMAOAuthCredentials + from ..models.solar_edge_credentials import SolarEdgeCredentials + from ..models.solis_credentials import SolisCredentials + from ..models.tesla_app_credentials import TeslaAppCredentials + + +T = TypeVar("T", bound="UpdateVendorCredentialsRequest") + + +@_attrs_define +class UpdateVendorCredentialsRequest: + """ + Attributes: + name (Union[None, Unset, str]): The name of the vendor credentials; if null, the value will be unset. + credentials (Union['EnphaseDeveloperAppCredentials', 'EnphasePartnerAppCredentials', 'EnphaseVPPCredentials', + 'FranklinWHCredentials', 'SMACustomGrantCredentials', 'SMAOAuthCredentials', 'SMASandboxCustomGrantCredentials', + 'SMASandboxOAuthCredentials', 'SolarEdgeCredentials', 'SolisCredentials', 'TeslaAppCredentials', Unset]): + Credentials for a given vendor. + """ + + name: Union[None, Unset, str] = UNSET + credentials: Union[ + "EnphaseDeveloperAppCredentials", + "EnphasePartnerAppCredentials", + "EnphaseVPPCredentials", + "FranklinWHCredentials", + "SMACustomGrantCredentials", + "SMAOAuthCredentials", + "SMASandboxCustomGrantCredentials", + "SMASandboxOAuthCredentials", + "SolarEdgeCredentials", + "SolisCredentials", + "TeslaAppCredentials", + Unset, + ] = UNSET + + def to_dict(self) -> Dict[str, Any]: + from ..models.enphase_developer_app_credentials import EnphaseDeveloperAppCredentials + from ..models.enphase_partner_app_credentials import EnphasePartnerAppCredentials + from ..models.enphase_vpp_credentials import EnphaseVPPCredentials + from ..models.franklin_wh_credentials import FranklinWHCredentials + from ..models.sma_custom_grant_credentials import SMACustomGrantCredentials + from ..models.sma_sandbox_custom_grant_credentials import SMASandboxCustomGrantCredentials + from ..models.sma_sandbox_o_auth_credentials import SMASandboxOAuthCredentials + from ..models.smao_auth_credentials import SMAOAuthCredentials + from ..models.solar_edge_credentials import SolarEdgeCredentials + from ..models.solis_credentials import SolisCredentials + + name: Union[None, Unset, str] + if isinstance(self.name, Unset): + name = UNSET + else: + name = self.name + + credentials: Union[Dict[str, Any], Unset] + if isinstance(self.credentials, Unset): + credentials = UNSET + elif isinstance(self.credentials, EnphasePartnerAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, EnphaseDeveloperAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, EnphaseVPPCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, FranklinWHCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMACustomGrantCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMAOAuthCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMASandboxCustomGrantCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMASandboxOAuthCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SolarEdgeCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SolisCredentials): + credentials = self.credentials.to_dict() + else: + credentials = self.credentials.to_dict() + + field_dict: Dict[str, Any] = {} + field_dict.update({}) + if name is not UNSET: + field_dict["name"] = name + if credentials is not UNSET: + field_dict["credentials"] = credentials + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.enphase_developer_app_credentials import EnphaseDeveloperAppCredentials + from ..models.enphase_partner_app_credentials import EnphasePartnerAppCredentials + from ..models.enphase_vpp_credentials import EnphaseVPPCredentials + from ..models.franklin_wh_credentials import FranklinWHCredentials + from ..models.sma_custom_grant_credentials import SMACustomGrantCredentials + from ..models.sma_sandbox_custom_grant_credentials import SMASandboxCustomGrantCredentials + from ..models.sma_sandbox_o_auth_credentials import SMASandboxOAuthCredentials + from ..models.smao_auth_credentials import SMAOAuthCredentials + from ..models.solar_edge_credentials import SolarEdgeCredentials + from ..models.solis_credentials import SolisCredentials + from ..models.tesla_app_credentials import TeslaAppCredentials + + d = src_dict.copy() + + def _parse_name(data: object) -> Union[None, Unset, str]: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(Union[None, Unset, str], data) + + name = _parse_name(d.pop("name", UNSET)) + + def _parse_credentials( + data: object, + ) -> Union[ + "EnphaseDeveloperAppCredentials", + "EnphasePartnerAppCredentials", + "EnphaseVPPCredentials", + "FranklinWHCredentials", + "SMACustomGrantCredentials", + "SMAOAuthCredentials", + "SMASandboxCustomGrantCredentials", + "SMASandboxOAuthCredentials", + "SolarEdgeCredentials", + "SolisCredentials", + "TeslaAppCredentials", + Unset, + ]: + if isinstance(data, Unset): + return data + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_0 = EnphasePartnerAppCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_0 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_1 = EnphaseDeveloperAppCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_1 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_2 = EnphaseVPPCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_2 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_3 = FranklinWHCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_3 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_4 = SMACustomGrantCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_4 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_5 = SMAOAuthCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_5 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_6 = SMASandboxCustomGrantCredentials.from_dict( + data + ) + + return componentsschemas_vendor_credentials_credentials_type_6 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_7 = SMASandboxOAuthCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_7 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_8 = SolarEdgeCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_8 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_9 = SolisCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_9 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_10 = TeslaAppCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_10 + + credentials = _parse_credentials(d.pop("credentials", UNSET)) + + update_vendor_credentials_request = cls( + name=name, + credentials=credentials, + ) + + return update_vendor_credentials_request diff --git a/derapi/models/update_vendor_credentials_response.py b/derapi/models/update_vendor_credentials_response.py new file mode 100644 index 0000000..841d794 --- /dev/null +++ b/derapi/models/update_vendor_credentials_response.py @@ -0,0 +1,420 @@ +from typing import TYPE_CHECKING, Any, Dict, Type, TypeVar, Union + +from attrs import define as _attrs_define + +if TYPE_CHECKING: + from ..models.enphase_developer_app_credentials import EnphaseDeveloperAppCredentials + from ..models.enphase_partner_app_credentials import EnphasePartnerAppCredentials + from ..models.enphase_vpp_credentials import EnphaseVPPCredentials + from ..models.franklin_wh_credentials import FranklinWHCredentials + from ..models.hidden_enphase_developer_app_credentials import HiddenEnphaseDeveloperAppCredentials + from ..models.hidden_enphase_partner_app_credentials import HiddenEnphasePartnerAppCredentials + from ..models.hidden_enphase_vpp_credentials import HiddenEnphaseVPPCredentials + from ..models.hidden_franklin_wh_credentials import HiddenFranklinWHCredentials + from ..models.hidden_sma_custom_grant_credentials import HiddenSMACustomGrantCredentials + from ..models.hidden_sma_sandbox_custom_grant_credentials import HiddenSMASandboxCustomGrantCredentials + from ..models.hidden_sma_sandbox_o_auth_credentials import HiddenSMASandboxOAuthCredentials + from ..models.hidden_smao_auth_credentials import HiddenSMAOAuthCredentials + from ..models.hidden_solar_edge_credentials import HiddenSolarEdgeCredentials + from ..models.hidden_solis_credentials import HiddenSolisCredentials + from ..models.hidden_tesla_app_credentials import HiddenTeslaAppCredentials + from ..models.sma_custom_grant_credentials import SMACustomGrantCredentials + from ..models.sma_sandbox_custom_grant_credentials import SMASandboxCustomGrantCredentials + from ..models.sma_sandbox_o_auth_credentials import SMASandboxOAuthCredentials + from ..models.smao_auth_credentials import SMAOAuthCredentials + from ..models.solar_edge_credentials import SolarEdgeCredentials + from ..models.solis_credentials import SolisCredentials + from ..models.tesla_app_credentials import TeslaAppCredentials + + +T = TypeVar("T", bound="UpdateVendorCredentialsResponse") + + +@_attrs_define +class UpdateVendorCredentialsResponse: + """Vendor credentials which may or may not be hidden. + + Attributes: + id (str): ID for the vendor credentials + name (str): The name of the vendor credentials; inferred if not provided. + credentials (Union['EnphaseDeveloperAppCredentials', 'EnphasePartnerAppCredentials', 'EnphaseVPPCredentials', + 'FranklinWHCredentials', 'HiddenEnphaseDeveloperAppCredentials', 'HiddenEnphasePartnerAppCredentials', + 'HiddenEnphaseVPPCredentials', 'HiddenFranklinWHCredentials', 'HiddenSMACustomGrantCredentials', + 'HiddenSMAOAuthCredentials', 'HiddenSMASandboxCustomGrantCredentials', 'HiddenSMASandboxOAuthCredentials', + 'HiddenSolarEdgeCredentials', 'HiddenSolisCredentials', 'HiddenTeslaAppCredentials', + 'SMACustomGrantCredentials', 'SMAOAuthCredentials', 'SMASandboxCustomGrantCredentials', + 'SMASandboxOAuthCredentials', 'SolarEdgeCredentials', 'SolisCredentials', 'TeslaAppCredentials']): + """ + + id: str + name: str + credentials: Union[ + "EnphaseDeveloperAppCredentials", + "EnphasePartnerAppCredentials", + "EnphaseVPPCredentials", + "FranklinWHCredentials", + "HiddenEnphaseDeveloperAppCredentials", + "HiddenEnphasePartnerAppCredentials", + "HiddenEnphaseVPPCredentials", + "HiddenFranklinWHCredentials", + "HiddenSMACustomGrantCredentials", + "HiddenSMAOAuthCredentials", + "HiddenSMASandboxCustomGrantCredentials", + "HiddenSMASandboxOAuthCredentials", + "HiddenSolarEdgeCredentials", + "HiddenSolisCredentials", + "HiddenTeslaAppCredentials", + "SMACustomGrantCredentials", + "SMAOAuthCredentials", + "SMASandboxCustomGrantCredentials", + "SMASandboxOAuthCredentials", + "SolarEdgeCredentials", + "SolisCredentials", + "TeslaAppCredentials", + ] + + def to_dict(self) -> Dict[str, Any]: + from ..models.enphase_developer_app_credentials import EnphaseDeveloperAppCredentials + from ..models.enphase_partner_app_credentials import EnphasePartnerAppCredentials + from ..models.enphase_vpp_credentials import EnphaseVPPCredentials + from ..models.franklin_wh_credentials import FranklinWHCredentials + from ..models.hidden_enphase_developer_app_credentials import HiddenEnphaseDeveloperAppCredentials + from ..models.hidden_enphase_partner_app_credentials import HiddenEnphasePartnerAppCredentials + from ..models.hidden_enphase_vpp_credentials import HiddenEnphaseVPPCredentials + from ..models.hidden_franklin_wh_credentials import HiddenFranklinWHCredentials + from ..models.hidden_sma_custom_grant_credentials import HiddenSMACustomGrantCredentials + from ..models.hidden_sma_sandbox_custom_grant_credentials import HiddenSMASandboxCustomGrantCredentials + from ..models.hidden_sma_sandbox_o_auth_credentials import HiddenSMASandboxOAuthCredentials + from ..models.hidden_smao_auth_credentials import HiddenSMAOAuthCredentials + from ..models.hidden_solar_edge_credentials import HiddenSolarEdgeCredentials + from ..models.hidden_solis_credentials import HiddenSolisCredentials + from ..models.hidden_tesla_app_credentials import HiddenTeslaAppCredentials + from ..models.sma_custom_grant_credentials import SMACustomGrantCredentials + from ..models.sma_sandbox_custom_grant_credentials import SMASandboxCustomGrantCredentials + from ..models.sma_sandbox_o_auth_credentials import SMASandboxOAuthCredentials + from ..models.smao_auth_credentials import SMAOAuthCredentials + from ..models.solar_edge_credentials import SolarEdgeCredentials + from ..models.solis_credentials import SolisCredentials + + id = self.id + + name = self.name + + credentials: Dict[str, Any] + if isinstance(self.credentials, HiddenEnphaseDeveloperAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenEnphasePartnerAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenEnphaseVPPCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenFranklinWHCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSMACustomGrantCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSMAOAuthCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSMASandboxCustomGrantCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSMASandboxOAuthCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSolarEdgeCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSolisCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenTeslaAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, EnphasePartnerAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, EnphaseDeveloperAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, EnphaseVPPCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, FranklinWHCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMACustomGrantCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMAOAuthCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMASandboxCustomGrantCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMASandboxOAuthCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SolarEdgeCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SolisCredentials): + credentials = self.credentials.to_dict() + else: + credentials = self.credentials.to_dict() + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "name": name, + "credentials": credentials, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.enphase_developer_app_credentials import EnphaseDeveloperAppCredentials + from ..models.enphase_partner_app_credentials import EnphasePartnerAppCredentials + from ..models.enphase_vpp_credentials import EnphaseVPPCredentials + from ..models.franklin_wh_credentials import FranklinWHCredentials + from ..models.hidden_enphase_developer_app_credentials import HiddenEnphaseDeveloperAppCredentials + from ..models.hidden_enphase_partner_app_credentials import HiddenEnphasePartnerAppCredentials + from ..models.hidden_enphase_vpp_credentials import HiddenEnphaseVPPCredentials + from ..models.hidden_franklin_wh_credentials import HiddenFranklinWHCredentials + from ..models.hidden_sma_custom_grant_credentials import HiddenSMACustomGrantCredentials + from ..models.hidden_sma_sandbox_custom_grant_credentials import HiddenSMASandboxCustomGrantCredentials + from ..models.hidden_sma_sandbox_o_auth_credentials import HiddenSMASandboxOAuthCredentials + from ..models.hidden_smao_auth_credentials import HiddenSMAOAuthCredentials + from ..models.hidden_solar_edge_credentials import HiddenSolarEdgeCredentials + from ..models.hidden_solis_credentials import HiddenSolisCredentials + from ..models.hidden_tesla_app_credentials import HiddenTeslaAppCredentials + from ..models.sma_custom_grant_credentials import SMACustomGrantCredentials + from ..models.sma_sandbox_custom_grant_credentials import SMASandboxCustomGrantCredentials + from ..models.sma_sandbox_o_auth_credentials import SMASandboxOAuthCredentials + from ..models.smao_auth_credentials import SMAOAuthCredentials + from ..models.solar_edge_credentials import SolarEdgeCredentials + from ..models.solis_credentials import SolisCredentials + from ..models.tesla_app_credentials import TeslaAppCredentials + + d = src_dict.copy() + id = d.pop("id") + + name = d.pop("name") + + def _parse_credentials( + data: object, + ) -> Union[ + "EnphaseDeveloperAppCredentials", + "EnphasePartnerAppCredentials", + "EnphaseVPPCredentials", + "FranklinWHCredentials", + "HiddenEnphaseDeveloperAppCredentials", + "HiddenEnphasePartnerAppCredentials", + "HiddenEnphaseVPPCredentials", + "HiddenFranklinWHCredentials", + "HiddenSMACustomGrantCredentials", + "HiddenSMAOAuthCredentials", + "HiddenSMASandboxCustomGrantCredentials", + "HiddenSMASandboxOAuthCredentials", + "HiddenSolarEdgeCredentials", + "HiddenSolisCredentials", + "HiddenTeslaAppCredentials", + "SMACustomGrantCredentials", + "SMAOAuthCredentials", + "SMASandboxCustomGrantCredentials", + "SMASandboxOAuthCredentials", + "SolarEdgeCredentials", + "SolisCredentials", + "TeslaAppCredentials", + ]: + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_0 = ( + HiddenEnphaseDeveloperAppCredentials.from_dict(data) + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_0 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_1 = ( + HiddenEnphasePartnerAppCredentials.from_dict(data) + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_1 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_2 = HiddenEnphaseVPPCredentials.from_dict( + data + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_2 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_3 = HiddenFranklinWHCredentials.from_dict( + data + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_3 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_4 = ( + HiddenSMACustomGrantCredentials.from_dict(data) + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_4 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_5 = HiddenSMAOAuthCredentials.from_dict( + data + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_5 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_6 = ( + HiddenSMASandboxCustomGrantCredentials.from_dict(data) + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_6 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_7 = ( + HiddenSMASandboxOAuthCredentials.from_dict(data) + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_7 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_8 = HiddenSolarEdgeCredentials.from_dict( + data + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_8 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_9 = HiddenSolisCredentials.from_dict(data) + + return componentsschemas_hidden_vendor_credentials_credentials_type_9 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_10 = HiddenTeslaAppCredentials.from_dict( + data + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_10 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_0 = EnphasePartnerAppCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_0 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_1 = EnphaseDeveloperAppCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_1 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_2 = EnphaseVPPCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_2 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_3 = FranklinWHCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_3 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_4 = SMACustomGrantCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_4 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_5 = SMAOAuthCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_5 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_6 = SMASandboxCustomGrantCredentials.from_dict( + data + ) + + return componentsschemas_vendor_credentials_credentials_type_6 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_7 = SMASandboxOAuthCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_7 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_8 = SolarEdgeCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_8 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_9 = SolisCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_9 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_10 = TeslaAppCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_10 + + credentials = _parse_credentials(d.pop("credentials")) + + update_vendor_credentials_response = cls( + id=id, + name=name, + credentials=credentials, + ) + + return update_vendor_credentials_response diff --git a/derapi/models/vendor.py b/derapi/models/vendor.py new file mode 100644 index 0000000..dce9b97 --- /dev/null +++ b/derapi/models/vendor.py @@ -0,0 +1,15 @@ +from enum import Enum + + +class Vendor(str, Enum): + ENPHASE = "enphase" + ENPHASEVPP = "enphasevpp" + SMA = "sma" + SMASBOX = "smasbox" + SOLAREDGE = "solaredge" + SOLIS = "solis" + TESLA = "tesla" + VIRTUAL = "virtual" + + def __str__(self) -> str: + return str(self.value) diff --git a/derapi/models/vendor_credentials.py b/derapi/models/vendor_credentials.py new file mode 100644 index 0000000..eca052b --- /dev/null +++ b/derapi/models/vendor_credentials.py @@ -0,0 +1,420 @@ +from typing import TYPE_CHECKING, Any, Dict, Type, TypeVar, Union + +from attrs import define as _attrs_define + +if TYPE_CHECKING: + from ..models.enphase_developer_app_credentials import EnphaseDeveloperAppCredentials + from ..models.enphase_partner_app_credentials import EnphasePartnerAppCredentials + from ..models.enphase_vpp_credentials import EnphaseVPPCredentials + from ..models.franklin_wh_credentials import FranklinWHCredentials + from ..models.hidden_enphase_developer_app_credentials import HiddenEnphaseDeveloperAppCredentials + from ..models.hidden_enphase_partner_app_credentials import HiddenEnphasePartnerAppCredentials + from ..models.hidden_enphase_vpp_credentials import HiddenEnphaseVPPCredentials + from ..models.hidden_franklin_wh_credentials import HiddenFranklinWHCredentials + from ..models.hidden_sma_custom_grant_credentials import HiddenSMACustomGrantCredentials + from ..models.hidden_sma_sandbox_custom_grant_credentials import HiddenSMASandboxCustomGrantCredentials + from ..models.hidden_sma_sandbox_o_auth_credentials import HiddenSMASandboxOAuthCredentials + from ..models.hidden_smao_auth_credentials import HiddenSMAOAuthCredentials + from ..models.hidden_solar_edge_credentials import HiddenSolarEdgeCredentials + from ..models.hidden_solis_credentials import HiddenSolisCredentials + from ..models.hidden_tesla_app_credentials import HiddenTeslaAppCredentials + from ..models.sma_custom_grant_credentials import SMACustomGrantCredentials + from ..models.sma_sandbox_custom_grant_credentials import SMASandboxCustomGrantCredentials + from ..models.sma_sandbox_o_auth_credentials import SMASandboxOAuthCredentials + from ..models.smao_auth_credentials import SMAOAuthCredentials + from ..models.solar_edge_credentials import SolarEdgeCredentials + from ..models.solis_credentials import SolisCredentials + from ..models.tesla_app_credentials import TeslaAppCredentials + + +T = TypeVar("T", bound="VendorCredentials") + + +@_attrs_define +class VendorCredentials: + """Vendor credentials which may or may not be hidden. + + Attributes: + id (str): ID for the vendor credentials + name (str): The name of the vendor credentials; inferred if not provided. + credentials (Union['EnphaseDeveloperAppCredentials', 'EnphasePartnerAppCredentials', 'EnphaseVPPCredentials', + 'FranklinWHCredentials', 'HiddenEnphaseDeveloperAppCredentials', 'HiddenEnphasePartnerAppCredentials', + 'HiddenEnphaseVPPCredentials', 'HiddenFranklinWHCredentials', 'HiddenSMACustomGrantCredentials', + 'HiddenSMAOAuthCredentials', 'HiddenSMASandboxCustomGrantCredentials', 'HiddenSMASandboxOAuthCredentials', + 'HiddenSolarEdgeCredentials', 'HiddenSolisCredentials', 'HiddenTeslaAppCredentials', + 'SMACustomGrantCredentials', 'SMAOAuthCredentials', 'SMASandboxCustomGrantCredentials', + 'SMASandboxOAuthCredentials', 'SolarEdgeCredentials', 'SolisCredentials', 'TeslaAppCredentials']): + """ + + id: str + name: str + credentials: Union[ + "EnphaseDeveloperAppCredentials", + "EnphasePartnerAppCredentials", + "EnphaseVPPCredentials", + "FranklinWHCredentials", + "HiddenEnphaseDeveloperAppCredentials", + "HiddenEnphasePartnerAppCredentials", + "HiddenEnphaseVPPCredentials", + "HiddenFranklinWHCredentials", + "HiddenSMACustomGrantCredentials", + "HiddenSMAOAuthCredentials", + "HiddenSMASandboxCustomGrantCredentials", + "HiddenSMASandboxOAuthCredentials", + "HiddenSolarEdgeCredentials", + "HiddenSolisCredentials", + "HiddenTeslaAppCredentials", + "SMACustomGrantCredentials", + "SMAOAuthCredentials", + "SMASandboxCustomGrantCredentials", + "SMASandboxOAuthCredentials", + "SolarEdgeCredentials", + "SolisCredentials", + "TeslaAppCredentials", + ] + + def to_dict(self) -> Dict[str, Any]: + from ..models.enphase_developer_app_credentials import EnphaseDeveloperAppCredentials + from ..models.enphase_partner_app_credentials import EnphasePartnerAppCredentials + from ..models.enphase_vpp_credentials import EnphaseVPPCredentials + from ..models.franklin_wh_credentials import FranklinWHCredentials + from ..models.hidden_enphase_developer_app_credentials import HiddenEnphaseDeveloperAppCredentials + from ..models.hidden_enphase_partner_app_credentials import HiddenEnphasePartnerAppCredentials + from ..models.hidden_enphase_vpp_credentials import HiddenEnphaseVPPCredentials + from ..models.hidden_franklin_wh_credentials import HiddenFranklinWHCredentials + from ..models.hidden_sma_custom_grant_credentials import HiddenSMACustomGrantCredentials + from ..models.hidden_sma_sandbox_custom_grant_credentials import HiddenSMASandboxCustomGrantCredentials + from ..models.hidden_sma_sandbox_o_auth_credentials import HiddenSMASandboxOAuthCredentials + from ..models.hidden_smao_auth_credentials import HiddenSMAOAuthCredentials + from ..models.hidden_solar_edge_credentials import HiddenSolarEdgeCredentials + from ..models.hidden_solis_credentials import HiddenSolisCredentials + from ..models.hidden_tesla_app_credentials import HiddenTeslaAppCredentials + from ..models.sma_custom_grant_credentials import SMACustomGrantCredentials + from ..models.sma_sandbox_custom_grant_credentials import SMASandboxCustomGrantCredentials + from ..models.sma_sandbox_o_auth_credentials import SMASandboxOAuthCredentials + from ..models.smao_auth_credentials import SMAOAuthCredentials + from ..models.solar_edge_credentials import SolarEdgeCredentials + from ..models.solis_credentials import SolisCredentials + + id = self.id + + name = self.name + + credentials: Dict[str, Any] + if isinstance(self.credentials, HiddenEnphaseDeveloperAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenEnphasePartnerAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenEnphaseVPPCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenFranklinWHCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSMACustomGrantCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSMAOAuthCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSMASandboxCustomGrantCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSMASandboxOAuthCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSolarEdgeCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenSolisCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, HiddenTeslaAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, EnphasePartnerAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, EnphaseDeveloperAppCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, EnphaseVPPCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, FranklinWHCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMACustomGrantCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMAOAuthCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMASandboxCustomGrantCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SMASandboxOAuthCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SolarEdgeCredentials): + credentials = self.credentials.to_dict() + elif isinstance(self.credentials, SolisCredentials): + credentials = self.credentials.to_dict() + else: + credentials = self.credentials.to_dict() + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "name": name, + "credentials": credentials, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.enphase_developer_app_credentials import EnphaseDeveloperAppCredentials + from ..models.enphase_partner_app_credentials import EnphasePartnerAppCredentials + from ..models.enphase_vpp_credentials import EnphaseVPPCredentials + from ..models.franklin_wh_credentials import FranklinWHCredentials + from ..models.hidden_enphase_developer_app_credentials import HiddenEnphaseDeveloperAppCredentials + from ..models.hidden_enphase_partner_app_credentials import HiddenEnphasePartnerAppCredentials + from ..models.hidden_enphase_vpp_credentials import HiddenEnphaseVPPCredentials + from ..models.hidden_franklin_wh_credentials import HiddenFranklinWHCredentials + from ..models.hidden_sma_custom_grant_credentials import HiddenSMACustomGrantCredentials + from ..models.hidden_sma_sandbox_custom_grant_credentials import HiddenSMASandboxCustomGrantCredentials + from ..models.hidden_sma_sandbox_o_auth_credentials import HiddenSMASandboxOAuthCredentials + from ..models.hidden_smao_auth_credentials import HiddenSMAOAuthCredentials + from ..models.hidden_solar_edge_credentials import HiddenSolarEdgeCredentials + from ..models.hidden_solis_credentials import HiddenSolisCredentials + from ..models.hidden_tesla_app_credentials import HiddenTeslaAppCredentials + from ..models.sma_custom_grant_credentials import SMACustomGrantCredentials + from ..models.sma_sandbox_custom_grant_credentials import SMASandboxCustomGrantCredentials + from ..models.sma_sandbox_o_auth_credentials import SMASandboxOAuthCredentials + from ..models.smao_auth_credentials import SMAOAuthCredentials + from ..models.solar_edge_credentials import SolarEdgeCredentials + from ..models.solis_credentials import SolisCredentials + from ..models.tesla_app_credentials import TeslaAppCredentials + + d = src_dict.copy() + id = d.pop("id") + + name = d.pop("name") + + def _parse_credentials( + data: object, + ) -> Union[ + "EnphaseDeveloperAppCredentials", + "EnphasePartnerAppCredentials", + "EnphaseVPPCredentials", + "FranklinWHCredentials", + "HiddenEnphaseDeveloperAppCredentials", + "HiddenEnphasePartnerAppCredentials", + "HiddenEnphaseVPPCredentials", + "HiddenFranklinWHCredentials", + "HiddenSMACustomGrantCredentials", + "HiddenSMAOAuthCredentials", + "HiddenSMASandboxCustomGrantCredentials", + "HiddenSMASandboxOAuthCredentials", + "HiddenSolarEdgeCredentials", + "HiddenSolisCredentials", + "HiddenTeslaAppCredentials", + "SMACustomGrantCredentials", + "SMAOAuthCredentials", + "SMASandboxCustomGrantCredentials", + "SMASandboxOAuthCredentials", + "SolarEdgeCredentials", + "SolisCredentials", + "TeslaAppCredentials", + ]: + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_0 = ( + HiddenEnphaseDeveloperAppCredentials.from_dict(data) + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_0 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_1 = ( + HiddenEnphasePartnerAppCredentials.from_dict(data) + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_1 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_2 = HiddenEnphaseVPPCredentials.from_dict( + data + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_2 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_3 = HiddenFranklinWHCredentials.from_dict( + data + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_3 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_4 = ( + HiddenSMACustomGrantCredentials.from_dict(data) + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_4 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_5 = HiddenSMAOAuthCredentials.from_dict( + data + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_5 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_6 = ( + HiddenSMASandboxCustomGrantCredentials.from_dict(data) + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_6 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_7 = ( + HiddenSMASandboxOAuthCredentials.from_dict(data) + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_7 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_8 = HiddenSolarEdgeCredentials.from_dict( + data + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_8 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_9 = HiddenSolisCredentials.from_dict(data) + + return componentsschemas_hidden_vendor_credentials_credentials_type_9 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_hidden_vendor_credentials_credentials_type_10 = HiddenTeslaAppCredentials.from_dict( + data + ) + + return componentsschemas_hidden_vendor_credentials_credentials_type_10 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_0 = EnphasePartnerAppCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_0 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_1 = EnphaseDeveloperAppCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_1 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_2 = EnphaseVPPCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_2 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_3 = FranklinWHCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_3 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_4 = SMACustomGrantCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_4 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_5 = SMAOAuthCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_5 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_6 = SMASandboxCustomGrantCredentials.from_dict( + data + ) + + return componentsschemas_vendor_credentials_credentials_type_6 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_7 = SMASandboxOAuthCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_7 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_8 = SolarEdgeCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_8 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_9 = SolisCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_9 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + componentsschemas_vendor_credentials_credentials_type_10 = TeslaAppCredentials.from_dict(data) + + return componentsschemas_vendor_credentials_credentials_type_10 + + credentials = _parse_credentials(d.pop("credentials")) + + vendor_credentials = cls( + id=id, + name=name, + credentials=credentials, + ) + + return vendor_credentials diff --git a/derapi/models/virtual_battery.py b/derapi/models/virtual_battery.py new file mode 100644 index 0000000..0a452bf --- /dev/null +++ b/derapi/models/virtual_battery.py @@ -0,0 +1,236 @@ +import datetime +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..models.battery_mode import BatteryMode +from ..models.vendor import Vendor +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.battery_recent_errors_error import BatteryRecentErrorsError + from ..models.battery_recent_errors_info import BatteryRecentErrorsInfo + from ..models.battery_recent_errors_start import BatteryRecentErrorsStart + from ..models.battery_recent_errors_warning import BatteryRecentErrorsWarning + + +T = TypeVar("T", bound="VirtualBattery") + + +@_attrs_define +class VirtualBattery: + """ + Attributes: + id (str): Battery id + vendor (Vendor): + reported_at (datetime.datetime): Date the request was generated in ISO-8601 format (timezone is always +00:00 + and is always present) + model (str): Model number of Battery + serial_number (str): Manufacturer serial number of the Battery + site_id (str): The Derapi Site ID this Battery is associated with + name (Union[Unset, str]): Customer defined name of the Battery + nameplate_kwh (Union[Unset, float]): The rated storage capacity of the unit + mode (Union[Unset, BatteryMode]): Battery management system mode. Values are Self Consumption - minimize grid + import, Savings - optimizing Battery to save money; usually based on a rate plan, Backup - only use Battery for + grid backup + state_of_charge_percent (Union[Unset, float]): Battery state of charge as a percent of capacity + recent_errors (Union[Unset, List[Union['BatteryRecentErrorsError', 'BatteryRecentErrorsInfo', + 'BatteryRecentErrorsStart', 'BatteryRecentErrorsWarning']]]): Most recent errors, warnings, or info reported by + the manufacturer for this Battery. The key represents the severity level (info/warning/error); the value is a + string description. start is always present and is the last element to be returned. + """ + + id: str + vendor: Vendor + reported_at: datetime.datetime + model: str + serial_number: str + site_id: str + name: Union[Unset, str] = UNSET + nameplate_kwh: Union[Unset, float] = UNSET + mode: Union[Unset, BatteryMode] = UNSET + state_of_charge_percent: Union[Unset, float] = UNSET + recent_errors: Union[ + Unset, + List[ + Union[ + "BatteryRecentErrorsError", + "BatteryRecentErrorsInfo", + "BatteryRecentErrorsStart", + "BatteryRecentErrorsWarning", + ] + ], + ] = UNSET + + def to_dict(self) -> Dict[str, Any]: + from ..models.battery_recent_errors_error import BatteryRecentErrorsError + from ..models.battery_recent_errors_info import BatteryRecentErrorsInfo + from ..models.battery_recent_errors_warning import BatteryRecentErrorsWarning + + id = self.id + + vendor = self.vendor.value + + reported_at = self.reported_at.isoformat() + + model = self.model + + serial_number = self.serial_number + + site_id = self.site_id + + name = self.name + + nameplate_kwh = self.nameplate_kwh + + mode: Union[Unset, str] = UNSET + if not isinstance(self.mode, Unset): + mode = self.mode.value + + state_of_charge_percent = self.state_of_charge_percent + + recent_errors: Union[Unset, List[Dict[str, Any]]] = UNSET + if not isinstance(self.recent_errors, Unset): + recent_errors = [] + for componentsschemas_battery_recent_errors_item_data in self.recent_errors: + componentsschemas_battery_recent_errors_item: Dict[str, Any] + if isinstance(componentsschemas_battery_recent_errors_item_data, BatteryRecentErrorsError): + componentsschemas_battery_recent_errors_item = ( + componentsschemas_battery_recent_errors_item_data.to_dict() + ) + elif isinstance(componentsschemas_battery_recent_errors_item_data, BatteryRecentErrorsWarning): + componentsschemas_battery_recent_errors_item = ( + componentsschemas_battery_recent_errors_item_data.to_dict() + ) + elif isinstance(componentsschemas_battery_recent_errors_item_data, BatteryRecentErrorsInfo): + componentsschemas_battery_recent_errors_item = ( + componentsschemas_battery_recent_errors_item_data.to_dict() + ) + else: + componentsschemas_battery_recent_errors_item = ( + componentsschemas_battery_recent_errors_item_data.to_dict() + ) + + recent_errors.append(componentsschemas_battery_recent_errors_item) + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "vendor": vendor, + "reportedAt": reported_at, + "model": model, + "serialNumber": serial_number, + "siteID": site_id, + } + ) + if name is not UNSET: + field_dict["name"] = name + if nameplate_kwh is not UNSET: + field_dict["nameplateKwh"] = nameplate_kwh + if mode is not UNSET: + field_dict["mode"] = mode + if state_of_charge_percent is not UNSET: + field_dict["stateOfChargePercent"] = state_of_charge_percent + if recent_errors is not UNSET: + field_dict["recentErrors"] = recent_errors + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.battery_recent_errors_error import BatteryRecentErrorsError + from ..models.battery_recent_errors_info import BatteryRecentErrorsInfo + from ..models.battery_recent_errors_start import BatteryRecentErrorsStart + from ..models.battery_recent_errors_warning import BatteryRecentErrorsWarning + + d = src_dict.copy() + id = d.pop("id") + + vendor = Vendor(d.pop("vendor")) + + reported_at = isoparse(d.pop("reportedAt")) + + model = d.pop("model") + + serial_number = d.pop("serialNumber") + + site_id = d.pop("siteID") + + name = d.pop("name", UNSET) + + nameplate_kwh = d.pop("nameplateKwh", UNSET) + + _mode = d.pop("mode", UNSET) + mode: Union[Unset, BatteryMode] + if isinstance(_mode, Unset): + mode = UNSET + else: + mode = BatteryMode(_mode) + + state_of_charge_percent = d.pop("stateOfChargePercent", UNSET) + + recent_errors = [] + _recent_errors = d.pop("recentErrors", UNSET) + for componentsschemas_battery_recent_errors_item_data in _recent_errors or []: + + def _parse_componentsschemas_battery_recent_errors_item( + data: object, + ) -> Union[ + "BatteryRecentErrorsError", + "BatteryRecentErrorsInfo", + "BatteryRecentErrorsStart", + "BatteryRecentErrorsWarning", + ]: + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_battery_recent_errors_item_type_0 = BatteryRecentErrorsError.from_dict(data) + + return componentsschemas_battery_recent_errors_item_type_0 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_battery_recent_errors_item_type_1 = BatteryRecentErrorsWarning.from_dict(data) + + return componentsschemas_battery_recent_errors_item_type_1 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_battery_recent_errors_item_type_2 = BatteryRecentErrorsInfo.from_dict(data) + + return componentsschemas_battery_recent_errors_item_type_2 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + componentsschemas_battery_recent_errors_item_type_3 = BatteryRecentErrorsStart.from_dict(data) + + return componentsschemas_battery_recent_errors_item_type_3 + + componentsschemas_battery_recent_errors_item = _parse_componentsschemas_battery_recent_errors_item( + componentsschemas_battery_recent_errors_item_data + ) + + recent_errors.append(componentsschemas_battery_recent_errors_item) + + virtual_battery = cls( + id=id, + vendor=vendor, + reported_at=reported_at, + model=model, + serial_number=serial_number, + site_id=site_id, + name=name, + nameplate_kwh=nameplate_kwh, + mode=mode, + state_of_charge_percent=state_of_charge_percent, + recent_errors=recent_errors, + ) + + return virtual_battery diff --git a/derapi/models/virtual_site.py b/derapi/models/virtual_site.py new file mode 100644 index 0000000..673e7ea --- /dev/null +++ b/derapi/models/virtual_site.py @@ -0,0 +1,163 @@ +import datetime +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..models.vendor import Vendor +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.battery_summary import BatterySummary + from ..models.site_bess import SiteBESS + from ..models.site_location import SiteLocation + from ..models.solar_inverter_summary import SolarInverterSummary + + +T = TypeVar("T", bound="VirtualSite") + + +@_attrs_define +class VirtualSite: + """ + Attributes: + id (str): the ID for the Site + vendor (Vendor): + name (str): Customer defined name of the Site + location_utc_offset (float): UTC Offset in hours; positive values represent locations East of UTC. Please note + this field will soon be deprecated, please use `timezone` instead. + batteries (List['BatterySummary']): List of Battery IDs associated with this Site + solar_inverters (List['SolarInverterSummary']): List of Solar Inverter IDs associated with this Site + location (Union[Unset, SiteLocation]): The location of this Solar Inverter in lat/lon coordinates + operational_since (Union[Unset, datetime.datetime]): The date the Site became operational or received permission + to operate. Sometimes absent for Solaredge. + bess (Union[Unset, SiteBESS]): For Sites with Batteries this key is present + """ + + id: str + vendor: Vendor + name: str + location_utc_offset: float + batteries: List["BatterySummary"] + solar_inverters: List["SolarInverterSummary"] + location: Union[Unset, "SiteLocation"] = UNSET + operational_since: Union[Unset, datetime.datetime] = UNSET + bess: Union[Unset, "SiteBESS"] = UNSET + + def to_dict(self) -> Dict[str, Any]: + id = self.id + + vendor = self.vendor.value + + name = self.name + + location_utc_offset = self.location_utc_offset + + batteries = [] + for componentsschemas_site_batteries_item_data in self.batteries: + componentsschemas_site_batteries_item = componentsschemas_site_batteries_item_data.to_dict() + batteries.append(componentsschemas_site_batteries_item) + + solar_inverters = [] + for componentsschemas_site_solar_inverters_item_data in self.solar_inverters: + componentsschemas_site_solar_inverters_item = componentsschemas_site_solar_inverters_item_data.to_dict() + solar_inverters.append(componentsschemas_site_solar_inverters_item) + + location: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.location, Unset): + location = self.location.to_dict() + + operational_since: Union[Unset, str] = UNSET + if not isinstance(self.operational_since, Unset): + operational_since = self.operational_since.isoformat() + + bess: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.bess, Unset): + bess = self.bess.to_dict() + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "vendor": vendor, + "name": name, + "locationUTCOffset": location_utc_offset, + "batteries": batteries, + "solarInverters": solar_inverters, + } + ) + if location is not UNSET: + field_dict["location"] = location + if operational_since is not UNSET: + field_dict["operationalSince"] = operational_since + if bess is not UNSET: + field_dict["bess"] = bess + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.battery_summary import BatterySummary + from ..models.site_bess import SiteBESS + from ..models.site_location import SiteLocation + from ..models.solar_inverter_summary import SolarInverterSummary + + d = src_dict.copy() + id = d.pop("id") + + vendor = Vendor(d.pop("vendor")) + + name = d.pop("name") + + location_utc_offset = d.pop("locationUTCOffset") + + batteries = [] + _batteries = d.pop("batteries") + for componentsschemas_site_batteries_item_data in _batteries: + componentsschemas_site_batteries_item = BatterySummary.from_dict(componentsschemas_site_batteries_item_data) + + batteries.append(componentsschemas_site_batteries_item) + + solar_inverters = [] + _solar_inverters = d.pop("solarInverters") + for componentsschemas_site_solar_inverters_item_data in _solar_inverters: + componentsschemas_site_solar_inverters_item = SolarInverterSummary.from_dict( + componentsschemas_site_solar_inverters_item_data + ) + + solar_inverters.append(componentsschemas_site_solar_inverters_item) + + _location = d.pop("location", UNSET) + location: Union[Unset, SiteLocation] + if isinstance(_location, Unset): + location = UNSET + else: + location = SiteLocation.from_dict(_location) + + _operational_since = d.pop("operationalSince", UNSET) + operational_since: Union[Unset, datetime.datetime] + if isinstance(_operational_since, Unset): + operational_since = UNSET + else: + operational_since = isoparse(_operational_since) + + _bess = d.pop("bess", UNSET) + bess: Union[Unset, SiteBESS] + if isinstance(_bess, Unset): + bess = UNSET + else: + bess = SiteBESS.from_dict(_bess) + + virtual_site = cls( + id=id, + vendor=vendor, + name=name, + location_utc_offset=location_utc_offset, + batteries=batteries, + solar_inverters=solar_inverters, + location=location, + operational_since=operational_since, + bess=bess, + ) + + return virtual_site diff --git a/derapi/models/virtual_solar_inverter.py b/derapi/models/virtual_solar_inverter.py new file mode 100644 index 0000000..5649d61 --- /dev/null +++ b/derapi/models/virtual_solar_inverter.py @@ -0,0 +1,249 @@ +import datetime +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union + +from attrs import define as _attrs_define +from dateutil.parser import isoparse + +from ..models.vendor import Vendor +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.solar_inverter_lifetime_production import SolarInverterLifetimeProduction + from ..models.solar_inverter_recent_errors_error import SolarInverterRecentErrorsError + from ..models.solar_inverter_recent_errors_info import SolarInverterRecentErrorsInfo + from ..models.solar_inverter_recent_errors_start import SolarInverterRecentErrorsStart + from ..models.solar_inverter_recent_errors_warning import SolarInverterRecentErrorsWarning + from ..models.solar_inverter_recent_production import SolarInverterRecentProduction + + +T = TypeVar("T", bound="VirtualSolarInverter") + + +@_attrs_define +class VirtualSolarInverter: + """ + Attributes: + id (str): ID of the solar inverter + vendor (Vendor): + reported_at (datetime.datetime): Date the request was generated in ISO-8601 format + model (str): Model number of this Solar Inverter + serial_number (str): Manufacturer serial number of this Solar Inverter + site_id (str): The Derapi Site ID this Solar Inverter is associated with + name (Union[Unset, str]): Customer defined name of this Solar Inverter + recent_production (Union[Unset, SolarInverterRecentProduction]): + lifetime_production (Union[Unset, SolarInverterLifetimeProduction]): + recent_errors (Union[Unset, List[Union['SolarInverterRecentErrorsError', 'SolarInverterRecentErrorsInfo', + 'SolarInverterRecentErrorsStart', 'SolarInverterRecentErrorsWarning']]]): Most recent errors, warnings, or info + reported by the manufacturer for this Solar Inverter. The key represents the severity level + (info/warning/error); the value is a string description. start is always present and is the last element to be + returned. + """ + + id: str + vendor: Vendor + reported_at: datetime.datetime + model: str + serial_number: str + site_id: str + name: Union[Unset, str] = UNSET + recent_production: Union[Unset, "SolarInverterRecentProduction"] = UNSET + lifetime_production: Union[Unset, "SolarInverterLifetimeProduction"] = UNSET + recent_errors: Union[ + Unset, + List[ + Union[ + "SolarInverterRecentErrorsError", + "SolarInverterRecentErrorsInfo", + "SolarInverterRecentErrorsStart", + "SolarInverterRecentErrorsWarning", + ] + ], + ] = UNSET + + def to_dict(self) -> Dict[str, Any]: + from ..models.solar_inverter_recent_errors_error import SolarInverterRecentErrorsError + from ..models.solar_inverter_recent_errors_info import SolarInverterRecentErrorsInfo + from ..models.solar_inverter_recent_errors_warning import SolarInverterRecentErrorsWarning + + id = self.id + + vendor = self.vendor.value + + reported_at = self.reported_at.isoformat() + + model = self.model + + serial_number = self.serial_number + + site_id = self.site_id + + name = self.name + + recent_production: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.recent_production, Unset): + recent_production = self.recent_production.to_dict() + + lifetime_production: Union[Unset, Dict[str, Any]] = UNSET + if not isinstance(self.lifetime_production, Unset): + lifetime_production = self.lifetime_production.to_dict() + + recent_errors: Union[Unset, List[Dict[str, Any]]] = UNSET + if not isinstance(self.recent_errors, Unset): + recent_errors = [] + for componentsschemas_solar_inverter_recent_errors_item_data in self.recent_errors: + componentsschemas_solar_inverter_recent_errors_item: Dict[str, Any] + if isinstance(componentsschemas_solar_inverter_recent_errors_item_data, SolarInverterRecentErrorsError): + componentsschemas_solar_inverter_recent_errors_item = ( + componentsschemas_solar_inverter_recent_errors_item_data.to_dict() + ) + elif isinstance( + componentsschemas_solar_inverter_recent_errors_item_data, SolarInverterRecentErrorsWarning + ): + componentsschemas_solar_inverter_recent_errors_item = ( + componentsschemas_solar_inverter_recent_errors_item_data.to_dict() + ) + elif isinstance( + componentsschemas_solar_inverter_recent_errors_item_data, SolarInverterRecentErrorsInfo + ): + componentsschemas_solar_inverter_recent_errors_item = ( + componentsschemas_solar_inverter_recent_errors_item_data.to_dict() + ) + else: + componentsschemas_solar_inverter_recent_errors_item = ( + componentsschemas_solar_inverter_recent_errors_item_data.to_dict() + ) + + recent_errors.append(componentsschemas_solar_inverter_recent_errors_item) + + field_dict: Dict[str, Any] = {} + field_dict.update( + { + "id": id, + "vendor": vendor, + "reportedAt": reported_at, + "model": model, + "serialNumber": serial_number, + "siteID": site_id, + } + ) + if name is not UNSET: + field_dict["name"] = name + if recent_production is not UNSET: + field_dict["recentProduction"] = recent_production + if lifetime_production is not UNSET: + field_dict["lifetimeProduction"] = lifetime_production + if recent_errors is not UNSET: + field_dict["recentErrors"] = recent_errors + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.solar_inverter_lifetime_production import SolarInverterLifetimeProduction + from ..models.solar_inverter_recent_errors_error import SolarInverterRecentErrorsError + from ..models.solar_inverter_recent_errors_info import SolarInverterRecentErrorsInfo + from ..models.solar_inverter_recent_errors_start import SolarInverterRecentErrorsStart + from ..models.solar_inverter_recent_errors_warning import SolarInverterRecentErrorsWarning + from ..models.solar_inverter_recent_production import SolarInverterRecentProduction + + d = src_dict.copy() + id = d.pop("id") + + vendor = Vendor(d.pop("vendor")) + + reported_at = isoparse(d.pop("reportedAt")) + + model = d.pop("model") + + serial_number = d.pop("serialNumber") + + site_id = d.pop("siteID") + + name = d.pop("name", UNSET) + + _recent_production = d.pop("recentProduction", UNSET) + recent_production: Union[Unset, SolarInverterRecentProduction] + if isinstance(_recent_production, Unset): + recent_production = UNSET + else: + recent_production = SolarInverterRecentProduction.from_dict(_recent_production) + + _lifetime_production = d.pop("lifetimeProduction", UNSET) + lifetime_production: Union[Unset, SolarInverterLifetimeProduction] + if isinstance(_lifetime_production, Unset): + lifetime_production = UNSET + else: + lifetime_production = SolarInverterLifetimeProduction.from_dict(_lifetime_production) + + recent_errors = [] + _recent_errors = d.pop("recentErrors", UNSET) + for componentsschemas_solar_inverter_recent_errors_item_data in _recent_errors or []: + + def _parse_componentsschemas_solar_inverter_recent_errors_item( + data: object, + ) -> Union[ + "SolarInverterRecentErrorsError", + "SolarInverterRecentErrorsInfo", + "SolarInverterRecentErrorsStart", + "SolarInverterRecentErrorsWarning", + ]: + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_solar_inverter_recent_errors_item_type_0 = ( + SolarInverterRecentErrorsError.from_dict(data) + ) + + return componentsschemas_solar_inverter_recent_errors_item_type_0 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_solar_inverter_recent_errors_item_type_1 = ( + SolarInverterRecentErrorsWarning.from_dict(data) + ) + + return componentsschemas_solar_inverter_recent_errors_item_type_1 + except: # noqa: E722 + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_solar_inverter_recent_errors_item_type_2 = ( + SolarInverterRecentErrorsInfo.from_dict(data) + ) + + return componentsschemas_solar_inverter_recent_errors_item_type_2 + except: # noqa: E722 + pass + if not isinstance(data, dict): + raise TypeError() + componentsschemas_solar_inverter_recent_errors_item_type_3 = SolarInverterRecentErrorsStart.from_dict( + data + ) + + return componentsschemas_solar_inverter_recent_errors_item_type_3 + + componentsschemas_solar_inverter_recent_errors_item = ( + _parse_componentsschemas_solar_inverter_recent_errors_item( + componentsschemas_solar_inverter_recent_errors_item_data + ) + ) + + recent_errors.append(componentsschemas_solar_inverter_recent_errors_item) + + virtual_solar_inverter = cls( + id=id, + vendor=vendor, + reported_at=reported_at, + model=model, + serial_number=serial_number, + site_id=site_id, + name=name, + recent_production=recent_production, + lifetime_production=lifetime_production, + recent_errors=recent_errors, + ) + + return virtual_solar_inverter diff --git a/derapi/types.py b/derapi/types.py new file mode 100644 index 0000000..21fac10 --- /dev/null +++ b/derapi/types.py @@ -0,0 +1,45 @@ +"""Contains some shared types for properties""" + +from http import HTTPStatus +from typing import BinaryIO, Generic, Literal, MutableMapping, Optional, Tuple, TypeVar + +from attrs import define + + +class Unset: + def __bool__(self) -> Literal[False]: + return False + + +UNSET: Unset = Unset() + +FileJsonType = Tuple[Optional[str], BinaryIO, Optional[str]] + + +@define +class File: + """Contains information for file uploads""" + + payload: BinaryIO + file_name: Optional[str] = None + mime_type: Optional[str] = None + + def to_tuple(self) -> FileJsonType: + """Return a tuple representation that httpx will accept for multipart/form-data""" + return self.file_name, self.payload, self.mime_type + + +T = TypeVar("T") + + +@define +class Response(Generic[T]): + """A response from an endpoint""" + + status_code: HTTPStatus + content: bytes + headers: MutableMapping[str, str] + parsed: Optional[T] + + +__all__ = ["File", "Response", "FileJsonType", "Unset", "UNSET"] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..462c01d --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,61 @@ +[build-system] +requires = ["hatchling", "hatch-vcs"] +build-backend = "hatchling.build" + +[project] +name = "derapi" +dynamic = ["version"] +requires-python = ">=3.8" +classifiers = [ + "Development Status :: 4 - Beta", + "Programming Language :: Python", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", +] +dependencies = [ + "httpx>=0.20.0,<0.28.0", + "attrs>=21.3.0", + "python-dateutil==2.8.0" +] +readme = "README.md" + +[project.optional-dependencies] +dev = [ + "pyright==v1.1.388", +] + +[tool.hatch.envs.hatch-test] +features = ["dev"] + +[tool.hatch.build.targets.sdist] +packages = ["derapi"] + +[tool.hatch.build.targets.wheel] +packages = ["derapi"] + +[tool.hatch.version] +source = "vcs" +fallback-version = "0.0.0" + +[tool.pytest.ini_options] +pythonpath = "." + +[tool.ruff] +line-length = 120 + +[tool.ruff.lint] +select = ["F", "I", "UP"] + +[tool.hatch.envs.typing] +template = "hatch-test" + +scripts.check = "pyright {args}" + +[tool.pyright] +typeCheckingMode = "strict" +include = ["tests/"] diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..2176a54 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,52 @@ +import os + +import httpx +import pytest + +from derapi import AuthenticatedClient + + +@pytest.fixture(scope="session") +def client(): + token = _request_token( + os.environ["DERAPI_TOKEN_URL"], + os.environ["DERAPI_CLIENT_ID"], + os.environ["DERAPI_CLIENT_SECRET"], + ) + return AuthenticatedClient( + os.environ["DERAPI_URL"], + headers={"api-version": "v2024-09-01"}, + raise_on_unexpected_status=True, + token=token, + ) + + +@pytest.fixture(scope="session") +def virtual_client(): + token = _request_token( + os.environ["DERAPI_TOKEN_URL"], + os.environ["DERAPI_VIRTUAL_CLIENT_ID"], + os.environ["DERAPI_VIRTUAL_CLIENT_SECRET"], + ) + client = AuthenticatedClient( + os.environ["DERAPI_URL"], + headers={"api-version": "v2024-09-01"}, + raise_on_unexpected_status=True, + token=token, + ) + + def log_request(r: httpx.Request): + print(f"Request: {r.method} {r.url} {r.headers}") + + client.get_httpx_client().event_hooks["request"].append(log_request) + return client + + +def _request_token(token_url: str, client_id: str, client_secret: str) -> str: + resp = httpx.post( + token_url, + auth=(client_id, client_secret), + data={"grant_type": "client_credentials"}, + ) + resp.raise_for_status() + return resp.json()["access_token"] diff --git a/tests/test_batteries.py b/tests/test_batteries.py new file mode 100644 index 0000000..553a861 --- /dev/null +++ b/tests/test_batteries.py @@ -0,0 +1,58 @@ +from datetime import datetime, timedelta, timezone +from typing import Iterator + +import pytest + +from derapi.api.batteries import get_battery, get_battery_intervals, list_batteries +from derapi.api.virtual import create_virtual_battery, delete_virtual_battery +from derapi.client import Client +from derapi.models.create_virtual_battery_request import ( + CreateVirtualBatteryRequest, +) +from derapi.models.create_virtual_battery_response import ( + CreateVirtualBatteryResponse, +) +from derapi.models.vendor import Vendor +from derapi.models.virtual_battery import VirtualBattery + + +@pytest.fixture(scope="module") +def virtual_battery(virtual_client: Client) -> Iterator[CreateVirtualBatteryResponse]: + virtual_battery = create_virtual_battery.sync( + client=virtual_client, + body=CreateVirtualBatteryRequest(name="My test battery"), + ) + assert virtual_battery is not None + + yield virtual_battery + + delete_virtual_battery.sync_detailed(virtual_battery.id, client=virtual_client) + + +def test_get_battery(virtual_client: Client, virtual_battery: VirtualBattery) -> None: + battery = get_battery.sync(virtual_battery.id, client=virtual_client) + assert battery is not None + + assert battery.name == "My test battery" + assert battery.vendor == Vendor.VIRTUAL + + +def test_list_batteries(virtual_client: Client, virtual_battery: VirtualBattery) -> None: + batteries = list_batteries.sync_depaginated(client=virtual_client) + assert any(battery.id == virtual_battery.id for battery in batteries) + + +def test_list_battery_intervals( + virtual_client: Client, + virtual_battery: VirtualBattery, +) -> None: + intervals = get_battery_intervals.sync( + virtual_battery.id, + start=datetime.now(timezone.utc) - timedelta(hours=25), + end=datetime.now(timezone.utc) - timedelta(hours=1), + client=virtual_client, + ) + assert intervals is not None + + assert len(intervals.intervals) > 0 + assert intervals.intervals[0].start.tzinfo is not None diff --git a/tests/test_credentials.py b/tests/test_credentials.py new file mode 100644 index 0000000..b67b8ed --- /dev/null +++ b/tests/test_credentials.py @@ -0,0 +1,25 @@ +import random + +from derapi.api.vendor_credentials import create_vendor_credentials, delete_vendor_credentials +from derapi.client import Client +from derapi.models.create_vendor_credentials_request import CreateVendorCredentialsRequest +from derapi.models.enphase_partner_app_credentials import EnphasePartnerAppCredentials +from derapi.models.hidden_enphase_partner_app_credentials import HiddenEnphasePartnerAppCredentials + + +def test_create_credentials(client: Client): + credentials = create_vendor_credentials.sync( + client=client, + body=CreateVendorCredentialsRequest( + name="hi", + credentials=EnphasePartnerAppCredentials( + client_id="client_id", + client_secret="".join(random.sample("abcdefghijklmnopqrstuvwxyz", 10)), + api_key="api_key", + ), + ), + ) + assert credentials is not None + assert isinstance(credentials.credentials, HiddenEnphasePartnerAppCredentials) + + delete_vendor_credentials.sync_detailed(credentials.id, client=client) diff --git a/tests/test_sites.py b/tests/test_sites.py new file mode 100644 index 0000000..65bffeb --- /dev/null +++ b/tests/test_sites.py @@ -0,0 +1,36 @@ +from typing import Any, Generator + +import pytest + +from derapi import Client +from derapi.api.sites import get_site, list_sites +from derapi.api.virtual import create_virtual_site, delete_virtual_site +from derapi.models.create_virtual_site_request import CreateVirtualSiteRequest +from derapi.models.create_virtual_site_response import CreateVirtualSiteResponse +from derapi.models.vendor import Vendor + + +@pytest.fixture(scope="module") +def virtual_site(virtual_client: Client) -> Generator[CreateVirtualSiteResponse, Any, Any]: + virtual_site = create_virtual_site.sync( + client=virtual_client, + body=CreateVirtualSiteRequest(name="My test site"), + ) + assert virtual_site is not None + + yield virtual_site + + delete_virtual_site.sync_detailed(virtual_site.id, client=virtual_client) + + +def test_get_site(virtual_client: Client, virtual_site: CreateVirtualSiteResponse) -> None: + site = get_site.sync(virtual_site.id, client=virtual_client) + assert site is not None + + assert site.name == "My test site" + assert site.vendor == Vendor.VIRTUAL + + +def test_list_sites(virtual_client: Client, virtual_site: CreateVirtualSiteResponse) -> None: + sites = list_sites.sync_depaginated(client=virtual_client) + assert any(site.id == virtual_site.id for site in sites) diff --git a/tests/test_solar_inverters.py b/tests/test_solar_inverters.py new file mode 100644 index 0000000..5913831 --- /dev/null +++ b/tests/test_solar_inverters.py @@ -0,0 +1,73 @@ +from datetime import datetime, timedelta, timezone +from typing import Iterator + +import pytest + +from derapi.api.solar_inverters import ( + get_solar_inverter, + get_solar_inverter_intervals, + list_solar_inverters, +) +from derapi.api.virtual import ( + create_virtual_solar_inverter, + delete_virtual_solar_inverter, +) +from derapi.client import Client +from derapi.models.create_virtual_solar_inverter_request import ( + CreateVirtualSolarInverterRequest, +) +from derapi.models.create_virtual_solar_inverter_response import ( + CreateVirtualSolarInverterResponse, +) +from derapi.models.vendor import Vendor +from derapi.models.virtual_solar_inverter import VirtualSolarInverter + + +@pytest.fixture(scope="module") +def virtual_inverter(virtual_client: Client) -> Iterator[CreateVirtualSolarInverterResponse]: + virtual_inverter = create_virtual_solar_inverter.sync( + client=virtual_client, + body=CreateVirtualSolarInverterRequest(name="My test inverter"), + ) + assert virtual_inverter is not None + + yield virtual_inverter + + delete_virtual_solar_inverter.sync_detailed(virtual_inverter.id, client=virtual_client) + + +def test_get_solar_inverter( + virtual_client: Client, + virtual_inverter: VirtualSolarInverter, +) -> None: + inverter = get_solar_inverter.sync(virtual_inverter.id, client=virtual_client) + assert inverter is not None + + assert inverter.name == "My test inverter" + assert inverter.vendor == Vendor.VIRTUAL + + +def test_list_solar_inverters( + virtual_client: Client, + virtual_inverter: CreateVirtualSolarInverterResponse, +) -> None: + inverters = list_solar_inverters.sync_depaginated(client=virtual_client) + assert inverters is not None + + assert any(inverter.id == virtual_inverter.id for inverter in inverters) + + +def test_list_solar_inverter_intervals( + virtual_client: Client, + virtual_inverter: CreateVirtualSolarInverterResponse, +) -> None: + intervals = get_solar_inverter_intervals.sync( + virtual_inverter.id, + start=datetime.now(timezone.utc) - timedelta(hours=25), + end=datetime.now(timezone.utc) - timedelta(hours=1), + client=virtual_client, + ) + assert intervals is not None + + assert len(intervals.intervals) > 0 + assert intervals.intervals[0].start.tzinfo is not None