Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor the package for Account / Location data #437

Merged
merged 3 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 26 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
[![Maintainability][maintainability-shield]][maintainability-url]
[![Code Coverage][codecov-shield]][codecov-url]

Asynchronous Python client for the Autarco Inverters.
Asynchronous Python client for the Autarco Inverters (External API).

## About

Expand All @@ -32,8 +32,7 @@ The data on the platform is updated every 5 minutes.
You can find this in the url after logging in,
example: `https://my.autarco.com/site/{public_key}`

Or by using the `get_public_key` method, that will
return your key.
Or by using the `get_account` function, and use the `public_key` attribute.

## Installation

Expand All @@ -55,11 +54,11 @@ async def main():
email="test@autarco.com",
password="password",
) as client:
public_key = await client.get_public_key()
account = await client.get_account()

inverters = await client.all_inverters(public_key)
solar = await client.solar(public_key)
account = await client.account(public_key)
inverters = await client.get_inverters(account.public_key)
solar = await client.get_solar(account.public_key)
location = await client.get_location(account.public_key)
print(inverters)
print(solar)
print(account)
Expand All @@ -69,15 +68,25 @@ if __name__ == "__main__":
asyncio.run(main())
```

More examples can be found in the [examples folder](./examples/).

## Data

You can read the following data with this package:

### Account

- Public Key
- System Name
- Retailer Name
- Health Status

### Inverter(s)

- Serial Number
- Current Power Production (W)
- Total Energy Production (kWh)
- Out AC - Power (W)
- Out AC - Energy Total (kWh)
- Grid Turned Off (bool)
- Health Status

### Solar
Expand All @@ -87,16 +96,16 @@ You can read the following data with this package:
- Energy Production - Month (kWh)
- Energy Production - Total (kWh)

### Account
### Location

- Public Key (str)
- Name (str)
- Public Key
- Name
- Address (dict)
- Street (str)
- Zip Code (str)
- City (str)
- Country (str)
- Timezone (str)
- Street
- Zip Code
- City
- Country
- Timezone
- Created At (date)
- Has consumption meter (bool)
- Has battery (bool)
Expand Down
5 changes: 2 additions & 3 deletions examples/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import asyncio

from autarco import Autarco
from autarco import Account, Autarco


async def main() -> None:
Expand All @@ -11,8 +11,7 @@ async def main() -> None:
email="test@autarco.com",
password="password",
) as client:
public_key = await client.get_public_key()
account = await client.get_account(public_key)
account: Account = await client.get_account()
print(account)


Expand Down
32 changes: 19 additions & 13 deletions examples/all_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import asyncio

from autarco import Account, Autarco, Inverter, Solar
from autarco import Account, Autarco, Inverter, Location, Solar


async def main() -> None:
Expand All @@ -11,19 +11,25 @@ async def main() -> None:
email="test@autarco.com",
password="password",
) as autarco:
public_key = await autarco.get_public_key()
account: Account = await autarco.get_account()

inverters: dict[str, Inverter] = await autarco.get_inverters(public_key)
solar: Solar = await autarco.get_solar(public_key)
account: Account = await autarco.get_account(public_key)
inverters: dict[str, Inverter] = await autarco.get_inverters(account.public_key)
solar: Solar = await autarco.get_solar(account.public_key)
location: Location = await autarco.get_location(account.public_key)

print(f"Public key: {public_key}")
print("--- ACCOUNT ---")
print(account)
print()
print(f"Public Key: {account.public_key}")
print(f"Name: {account.system_name}")
print(f"Retailer: {account.retailer}")
print(f"Health: {account.health}")

print("--- INVERTER(S) ---")
print(inverters)
print()
for item in inverters.values():
print(f"Serial Number: {item.serial_number}")
print(item)
print()

Expand All @@ -36,14 +42,14 @@ async def main() -> None:
print(f"Energy Production - Total: {solar.energy_production_total}")
print()

print("--- ACCOUNT ---")
print(account)
print("--- LOCATION ---")
print(location)
print()
print(f"Public Key: {account.public_key}")
print(f"Name: {account.name}")
print(f"Timezone: {account.timezone}")
print(f"City: {account.address.city}")
print(f"Country: {account.address.country}")
print(f"Address: {location.address}")
print(f"Timezone: {location.timezone}")
print(f"Created At: {location.created_at}")
print(f"Consumption Meter: {location.has_consumption_meter}")
print(f"Has Battery: {location.has_battery}")


if __name__ == "__main__":
Expand Down
6 changes: 3 additions & 3 deletions examples/inverters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import asyncio

from autarco import Autarco
from autarco import Account, Autarco


async def main() -> None:
Expand All @@ -11,8 +11,8 @@ async def main() -> None:
email="test@autarco.com",
password="password",
) as client:
public_key = await client.get_public_key()
inverters = await client.get_inverters(public_key)
account: Account = await client.get_account()
inverters = await client.get_inverters(account.public_key)
print(inverters)


Expand Down
20 changes: 20 additions & 0 deletions examples/location.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""Asynchronous Python client for the Autarco API."""

import asyncio

from autarco import Account, Autarco


async def main() -> None:
"""Show example on getting Autarco - location data."""
async with Autarco(
email="test@autarco.com",
password="password",
) as client:
account: Account = await client.get_account()
location = await client.get_location(account.public_key)
print(location)


if __name__ == "__main__":
asyncio.run(main())
6 changes: 3 additions & 3 deletions examples/solar.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import asyncio

from autarco import Autarco
from autarco import Account, Autarco


async def main() -> None:
Expand All @@ -11,8 +11,8 @@ async def main() -> None:
email="test@autarco.com",
password="password",
) as client:
public_key = await client.get_public_key()
solar = await client.get_solar(public_key)
account: Account = await client.get_account()
solar = await client.get_solar(account.public_key)
print(solar)


Expand Down
3 changes: 2 additions & 1 deletion src/autarco/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
AutarcoConnectionError,
AutarcoError,
)
from .models import Account, DateStrategy, Inverter, Solar
from .models import Account, DateStrategy, Inverter, Location, Solar

__all__ = [
"Account",
Expand All @@ -16,5 +16,6 @@
"AutarcoError",
"DateStrategy",
"Inverter",
"Location",
"Solar",
]
29 changes: 17 additions & 12 deletions src/autarco/autarco.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from __future__ import annotations

import asyncio
import json
import socket
from dataclasses import dataclass
from importlib import metadata
Expand All @@ -18,7 +17,15 @@
AutarcoConnectionError,
AutarcoError,
)
from .models import Account, EnergyResponse, Inverter, PowerResponse, Solar
from .models import (
Account,
AccountResponse,
EnergyResponse,
Inverter,
Location,
PowerResponse,
Solar,
)

VERSION = metadata.version(__package__)

Expand Down Expand Up @@ -121,18 +128,16 @@ async def _request(

return text

async def get_public_key(self) -> str:
"""Get the public key.
async def get_account(self) -> Account:
"""Get information about the account.

Returns
-------
The public key as string.
An Account object. Note: it returns the first account found.

"""
response = await self._request("")
data = json.loads(response)
public_key: str = data[0]["public_key"]
return public_key
return AccountResponse.from_json(response).data[0]

async def get_inverters(self, public_key: str) -> dict[str, Inverter]:
"""Get a list of all used inverters.
Expand Down Expand Up @@ -169,20 +174,20 @@ async def get_solar(self, public_key: str) -> Solar:
combined = {**power_class.stats["kpis"], **energy_class.stats["kpis"]}
return Solar.from_dict(combined)

async def get_account(self, public_key: str) -> Account:
"""Get information about your account.
async def get_location(self, public_key: str) -> Location:
"""Get information about your system location.

Args:
----
public_key: The public key from your account.

Returns:
-------
An Account object.
An Location object.

"""
response = await self._request(f"{public_key}/")
return Account.from_json(response)
return Location.from_json(response)

async def close(self) -> None:
"""Close open client session."""
Expand Down
25 changes: 21 additions & 4 deletions src/autarco/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,26 @@ def deserialize(self, value: str) -> date:

@dataclass
class PowerResponse(DataClassORJSONMixin):
"""Object representing an Inverter model response from the API."""
"""Object representing an Power Response model from the API."""

inverters: dict[str, Inverter]
stats: dict[str, dict[str, int]]
stats: dict[str, dict[str, Any]]


@dataclass
class EnergyResponse(DataClassORJSONMixin):
"""Object representing an Inverter model response from the API."""
"""Object representing an Energy Response model response from the API."""

stats: dict[str, dict[str, Any]]


@dataclass
class AccountResponse(DataClassORJSONMixin):
"""Object representing an Account model response from the API."""

data: list[Account]


@dataclass
class Inverter(DataClassORJSONMixin):
"""Object representing an Inverter model response from the API."""
Expand All @@ -62,7 +69,17 @@ class Solar(DataClassDictMixin):

@dataclass
class Account(DataClassORJSONMixin):
"""Object representing an Account model response from the API."""
"""Object representing a Account model response from the API."""

public_key: str
system_name: str = field(metadata=field_options(alias="name"))
retailer: str = field(metadata=field_options(alias="name_retailer"))
health: str


@dataclass
class Location(DataClassORJSONMixin):
"""Object representing an Location model response from the API."""

# pylint: disable-next=too-few-public-methods
class Config(BaseConfig):
Expand Down
6 changes: 3 additions & 3 deletions tests/__snapshots__/test_models.ambr
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# serializer version: 1
# name: test_get_account
Account(public_key='sd6fv516', name='My Autarco solar installation', address=Address(street='Streetname 00', zip_code='1111 AA', city='Valkenswaard', country='Nederland'), timezone='Europe/Amsterdam', created_at=datetime.date(2023, 5, 15), has_consumption_meter=False, has_battery=False)
Account(public_key='blabla', system_name='Mijn Autarco', retailer='Klaas Schoute', health='OK')
# ---
# name: test_get_inverters
dict({
'123456789876': Inverter(serial_number='123456789876', out_ac_power=100, out_ac_energy_total=6605, grid_turned_off=False, health='OK'),
'987654321234': Inverter(serial_number='987654321234', out_ac_power=100, out_ac_energy_total=3607, grid_turned_off=False, health='OK'),
})
# ---
# name: test_get_public_key
'sd6fv516'
# name: test_get_location
Location(public_key='blabla', name='My Autarco solar installation', address=Address(street='Streetname 00', zip_code='1111 AA', city='Valkenswaard', country='Nederland'), timezone='Europe/Amsterdam', created_at=datetime.date(2023, 5, 15), has_consumption_meter=False, has_battery=False)
# ---
# name: test_get_solar
Solar(power_production=200, energy_production_today=4, energy_production_month=58, energy_production_total=10379)
Expand Down
Loading