Project skeleton
Some checks failed
HACS Validation / validate (push) Failing after 38s
Validate with hassfest / validate (push) Failing after 41s

This commit is contained in:
Adrian Rumpold
2025-04-07 10:17:40 +02:00
commit 5180992e98
23 changed files with 3302 additions and 0 deletions

View File

@@ -0,0 +1,163 @@
"""API client for PV Microinverter."""
import logging
from dataclasses import dataclass
from datetime import datetime
from enum import StrEnum
from typing import Any
import aiohttp
from pv_microinverter.units import WATT, Dimension
from .const import PVMicroinverterData
_LOGGER = logging.getLogger(__name__)
class ApiEndpoints(StrEnum):
GET_STATION_INFO = "GetStationInfo"
@dataclass
class StationInfoData:
UnitCapacity: str
UnitEToday: str
UnitEMonth: str
UnitEYear: str
UnitETotal: str
Power: float
PowerStr: str
Capacity: float
LoadPower: str
GridPower: str
StrCO2: str
StrTrees: str
StrIncome: str
PwImg: str
StationName: str
InvModel1: str
InvModel2: str | None
Lat: str
Lng: str
TimeZone: str
StrPeakPower: str
Installer: str | None
CreateTime: datetime
CreateYear: int
CreateMonth: int
Etoday: float
InvTotal: int
@dataclass
class StationInfoResponse:
Status: int
Result: Any
Data: StationInfoData
class PVMicroinverterApiClientError(Exception):
"""Exception to indicate an error with the API client."""
class PVMicroinverterApiClient:
"""API client for PV Microinverter."""
def __init__(
self,
session: aiohttp.ClientSession,
station_id: str,
base_url: str = "https://www.envertecportal.com/ApiStations",
) -> None:
"""Initialize the Envertech API client.
Args:
session: The aiohttp client session
station_id: The station identifier
base_url: The base URL for the API
"""
self._session = session
self._station_id = station_id
self._base_url = base_url
async def async_get_data(self) -> PVMicroinverterData:
"""Get data from the API.
Returns:
PVMicroinverterData: The data from the API
Raises:
PVMicroinverterApiClientError: If the API request fails
"""
try:
# Make the request to the API
response = await self._session.post(
f"{self._base_url}/{ApiEndpoints.GET_STATION_INFO}",
json={"stationId": self._station_id},
headers={
"Content-Type": "application/json",
},
)
response.raise_for_status()
data = await response.json()
# Process the response
return self._process_data(data)
except aiohttp.ClientError as error:
_LOGGER.error("Error fetching data: %s", error)
raise PVMicroinverterApiClientError(
"Error fetching data from API"
) from error
except Exception as error:
_LOGGER.exception("Unexpected error: %s", error)
raise PVMicroinverterApiClientError("Unexpected error occurred") from error
def _process_data(self, data: dict[str, Any]) -> PVMicroinverterData:
"""Process the API response data.
Args:
data: The data from the API
Returns:
PVMicroinverterData: The processed data
"""
station_data = StationInfoData(**data.get("Data", {}))
station_info = StationInfoResponse(
Status=data.get("Status"),
Result=data.get("Result"),
Data=station_data,
)
if station_info.Status != "0":
raise PVMicroinverterApiClientError(f"API error: {station_info.Result}")
return PVMicroinverterData(
current_power=Dimension(station_data.Power, WATT),
today_energy=Dimension.parse(station_data.UnitEToday).to_base_unit(),
lifetime_energy=Dimension.parse(station_data.UnitETotal).to_base_unit(),
last_updated=datetime.now().isoformat(),
)
async def async_check_connection(self) -> bool:
"""Test the API connection to verify credentials.
Returns:
bool: True if connection is successful, False otherwise
"""
try:
response = await self._session.post(
f"{self._base_url}/{ApiEndpoints.GET_STATION_INFO}",
headers={
"Content-Type": "application/json",
},
json={"stationId": self._station_id},
)
response.raise_for_status()
return True
except Exception as error:
_LOGGER.error("Connection test failed: %s", error)
return False