eac-dso-portal
Async Python client for the EAC (Electricity Authority of Cyprus) Distribution Web Portal at meterreading-dso.eac.com.cy.
The portal exposes an undocumented JSON API behind a JWT-authenticated session. This package wraps it in a small aiohttp-based client with typed dataclasses.
Install
pip install eac-dso-portal
Requires Python 3.11+.
Usage
import asyncio
from datetime import datetime, timedelta, timezone
import aiohttp
from eac_dso_portal import EacClient
async def main() -> None:
async with aiohttp.ClientSession() as session:
client = EacClient("you@example.com", "password", session=session)
await client.login()
for sp in await client.list_service_points():
if not sp.active:
continue
print(sp.id, sp.address)
# Default channels are the daily totals.
end = datetime.now(timezone.utc)
start = end - timedelta(days=14)
for cr in await client.get_readings(sp.id, start, end):
for r in cr.readings:
print(f" {r.dt.isoformat()} {r.reading} kWh (delta {r.value})")
asyncio.run(main())
What's in the API
| Method | What it does |
|---|---|
login() |
POST /api/portal/login and store the JWT. Auto-refreshed on 401. |
get_user_details() |
Account holder name and admin flag. |
list_service_points() |
All service points on the account, active and historical. |
get_meter_configs(sp_id) |
All meters ever installed at a service point, with their measurement-channel lists. |
get_readings(sp_id, start, end, mc_id=None, chunk_days=14) |
Readings in a date range. Without mc_id you get the default summary channels; pass an explicit mc_id for one channel including the 30-minute load profile. Wide ranges are split into back-to-back requests because the portal caps each response at 1000 rows. |
All return values are immutable dataclasses. Each model also carries a .raw dict so callers can read fields the wrapper has not yet promoted into typed attributes.
The 1000-row response cap
The portal silently truncates any /readings/list response that would exceed 1000 rows. For a 30-minute load profile that hits the limit after about 21 days. get_readings works around this by splitting wide requests into 14-day chunks (configurable via chunk_days) and merging the results, dropping duplicates that appear on chunk boundaries. The public signature is unchanged from earlier versions, so callers do not have to do anything special.
Errors
EacAuthError: login was rejected, or token refresh failed.EacRateLimitError: HTTP 429 from the portal.EacApiError: any other non-2xx response. Carries.status,.message,.path.EacError: base class for all of the above.
Status and scope
A thin wrapper around an undocumented portal API, built primarily to drive the ha-eac Home Assistant integration. The endpoint set and field names follow what the portal's React frontend uses today, and the API may change without notice on EAC's side. Every model carries a .raw payload so consumers can read fields the wrapper has not yet typed.
License
MIT
Metadata
Release files for eac-dso-portal 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| eac_dso_portal-0.2.1.tar.gz | 13.4 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| eac_dso_portal-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.1 kB
Release files / eac_dso_portal-0.2.1.tar.gz
| Download URL | eac_dso_portal-0.2.1.tar.gz |
|---|---|
| Size | 13.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
06c78c820cef0f331a0c684ca6b7b0aae30d3459fac28eecc32aaac0e027f124
|
|
BLAKE2b-256 checksum How to use checksums |
c81a8849b35255e67a7a9c0e9d8f510e063b251e509effe218bd1d735374b2bf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.12 {"installer":{"name":"uv","version":"0.11.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / eac_dso_portal-0.2.1-py3-none-any.whl
| Download URL | eac_dso_portal-0.2.1-py3-none-any.whl |
|---|---|
| Size | 8.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0fcdbc2bf3581ddce54f0adaa579a85318cb12b536ed5d57e02127d354c8c0f8
|
|
BLAKE2b-256 checksum How to use checksums |
0613425408577e555fdb87059451d79aae87f573c4758168ade650f07007f73c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.12 {"installer":{"name":"uv","version":"0.11.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for eac-dso-portal 0.2.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.