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

Add OVO Plan API #70

Merged
merged 2 commits into from
Nov 14, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
78 changes: 0 additions & 78 deletions ovoenergy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,80 +1,2 @@
"""Initialize the package."""
from __future__ import annotations

from datetime import datetime
from typing import Optional

from pydantic import BaseModel, Extra, Field # pylint: disable=no-name-in-module


class OVOBase(BaseModel):
"""Base class for all OVO models."""

class Config:
"""Pydantic config."""

extra = Extra.allow


class OVOInterval(OVOBase):
"""Interval model."""

start: datetime = Field(..., alias="start")
end: datetime = Field(..., alias="end")


class OVOMeterReadings(OVOBase):
"""Meter readings model."""

start: float = Field(..., alias="start")
end: float = Field(..., alias="end")


class OVOCost(OVOBase):
"""Cost model."""

amount: Optional[float] = Field(None, alias="amount")
currency_unit: Optional[str] = Field(None, alias="currencyUnit")


class OVODailyElectricity(OVOBase):
"""Daily electricity model."""

consumption: Optional[float] = Field(None, alias="consumption")
interval: Optional[OVOInterval] = Field(None, alias="interval")
meter_readings: Optional[OVOMeterReadings] = Field(None, alias="meterReadings")
has_half_hour_data: Optional[bool] = Field(None, alias="hasHalfHourData")
cost: Optional[OVOCost] = Field(None, alias="cost")


class OVODailyGas(OVOBase):
"""Daily gas model."""

consumption: Optional[float] = Field(None, alias="consumption")
volume: Optional[float] = Field(None, alias="volume")
interval: Optional[OVOInterval] = Field(None, alias="interval")
meter_readings: Optional[OVOMeterReadings] = Field(None, alias="meterReadings")
has_half_hour_data: Optional[bool] = Field(None, alias="hasHalfHourData")
cost: Optional[OVOCost] = Field(None, alias="cost")


class OVOHalfHour(OVOBase):
"""Half hour model."""

consumption: float = Field(None, alias="consumption")
interval: OVOInterval = Field(None, alias="interval")
unit: str = Field(None, alias="unit")


class OVODailyUsage(OVOBase):
"""Daily usage model."""

electricity: Optional[list[OVODailyElectricity]] = Field(None, alias="electricity")
gas: Optional[list[OVODailyGas]] = Field(None, alias="gas")


class OVOHalfHourUsage(OVOBase):
"""Half hour usage model."""

electricity: Optional[list[OVOHalfHour]] = Field(None, alias="electricity")
gas: Optional[list[OVOHalfHour]] = Field(None, alias="gas")
25 changes: 24 additions & 1 deletion ovoenergy/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@

import typer

from . import OVODailyUsage, OVOHalfHourUsage
from ._version import __version__
from .models import OVODailyUsage, OVOHalfHourUsage
from .models.plan import OVOPlan
from .ovoenergy import OVOEnergy

app = typer.Typer()
Expand Down Expand Up @@ -71,6 +72,28 @@ def half_hourly(
)


@app.command(name="plan", short_help="Get plan from OVO Energy")
def plan(
username: str = typer.Option(..., help="OVO Energy username"),
password: str = typer.Option(..., help="OVO Energy password"),
account: str = typer.Option(None, help="OVO Energy account number"),
) -> None:
"""Get rates from OVO Energy."""
ovo_plan: Optional[OVOPlan] = None

client = OVOEnergy()
authenticated = loop.run_until_complete(
client.authenticate(username, password, account)
)
if authenticated:
ovo_plan = loop.run_until_complete(client.get_plan())

typer.secho(
ovo_plan.json() if ovo_plan is not None else '{"message": "No data"}',
fg=typer.colors.GREEN,
)


@app.command(name="version", short_help="Module Version")
def version() -> None:
"""Module Version"""
Expand Down
88 changes: 88 additions & 0 deletions ovoenergy/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
"""OVO Energy: Models."""
from __future__ import annotations

from datetime import datetime
from typing import Optional

from pydantic import BaseModel, Extra, Field # pylint: disable=no-name-in-module


class OVOBase(BaseModel):
"""Base class for all OVO models."""

class Config:
"""Pydantic config."""

extra = Extra.allow


class OVOInterval(OVOBase):
"""Interval model."""

start: datetime = Field(None, alias="start")
end: datetime = Field(None, alias="end")


class OVOMeterReadings(OVOBase):
"""Meter readings model."""

start: float = Field(None, alias="start")
end: float = Field(None, alias="end")


class OVOCost(OVOBase):
"""Cost model."""

amount: Optional[float] = Field(None, alias="amount")
currency_unit: Optional[str] = Field(None, alias="currencyUnit")


class OVODailyElectricity(OVOBase):
"""Daily electricity model."""

consumption: Optional[float] = Field(None, alias="consumption")
interval: Optional[OVOInterval] = Field(None, alias="interval")
meter_readings: Optional[OVOMeterReadings] = Field(None, alias="meterReadings")
has_half_hour_data: Optional[bool] = Field(None, alias="hasHalfHourData")
cost: Optional[OVOCost] = Field(None, alias="cost")


class OVODailyGas(OVOBase):
"""Daily gas model."""

consumption: Optional[float] = Field(None, alias="consumption")
volume: Optional[float] = Field(None, alias="volume")
interval: Optional[OVOInterval] = Field(None, alias="interval")
meter_readings: Optional[OVOMeterReadings] = Field(None, alias="meterReadings")
has_half_hour_data: Optional[bool] = Field(None, alias="hasHalfHourData")
cost: Optional[OVOCost] = Field(None, alias="cost")


class OVOHalfHour(OVOBase):
"""Half hour model."""

consumption: float = Field(None, alias="consumption")
interval: OVOInterval = Field(None, alias="interval")
unit: str = Field(None, alias="unit")


class OVODailyUsage(OVOBase):
"""Daily usage model."""

electricity: Optional[list[OVODailyElectricity]] = Field(None, alias="electricity")
gas: Optional[list[OVODailyGas]] = Field(None, alias="gas")


class OVOHalfHourUsage(OVOBase):
"""Half hour usage model."""

electricity: Optional[list[OVOHalfHour]] = Field(None, alias="electricity")
gas: Optional[list[OVOHalfHour]] = Field(None, alias="gas")


class OVOPlan(OVOBase):
"""Plan model."""

standing_charge: Optional[float] = Field(None, alias="standingCharge")
unit_rate: Optional[float] = Field(None, alias="unitRate")
tariff: Optional[str] = Field(None, alias="tariff")
73 changes: 73 additions & 0 deletions ovoenergy/models/plan.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"""OVO Energy: Plan Models."""
from __future__ import annotations

from typing import Any

from pydantic import Field

from . import OVOBase


class OVOPlanRate(OVOBase):
"""Plan rate model."""

amount: float = Field(None, alias="amount")
currency_unit: str = Field(None, alias="currencyUnit")


class OVOPlanStatus(OVOBase):
"""Plan status model."""

active: bool
in_renewal: bool = Field(None, alias="inRenewal")
in_loss: bool = Field(None, alias="inLoss")
loss_complete: bool = Field(None, alias="lossComplete")
has_future_contracts: bool = Field(None, alias="hasFutureContracts")


class OVOPlanUnitRate(OVOBase):
"""Unit rate model."""

name: str = Field(None, alias="name")
unit_rate: OVOPlanRate = Field(None, alias="unitRate")


class OVOPlanElectricity(OVOBase):
"""Plan electricity model."""

name: str = Field(None, alias="name")
exit_fee: OVOPlanRate = Field(None, alias="exitFee")
contract_start_date: str = Field(None, alias="contractStartDate")
contract_end_date: Any = Field(None, alias="contractEndDate")
contract_type: str = Field(None, alias="contractType")
is_in_renewal: bool = Field(None, alias="isInRenewal")
has_future_contracts: bool = Field(None, alias="hasFutureContracts")
mpxn: str = Field(None, alias="mpxn")
msn: str = Field(None, alias="msn")
personal_projection: float = Field(None, alias="personalProjection")
standing_charge: OVOPlanRate = Field(None, alias="standingCharge")
unit_rates: list[OVOPlanUnitRate] = Field(None, alias="unitRates")


class OVOPlanGas(OVOBase):
"""Plan gas model."""

name: str = Field(None, alias="name")
exit_fee: OVOPlanRate = Field(None, alias="exitFee")
contract_start_date: str = Field(None, alias="contractStartDate")
contract_end_date: Any = Field(None, alias="contractEndDate")
contract_type: str = Field(None, alias="contractType")
is_in_renewal: bool = Field(None, alias="isInRenewal")
has_future_contracts: bool = Field(None, alias="hasFutureContracts")
mpxn: str = Field(None, alias="mpxn")
msn: str = Field(None, alias="msn")
personal_projection: float = Field(None, alias="personalProjection")
standing_charge: OVOPlanRate = Field(None, alias="standingCharge")
unit_rates: list[OVOPlanUnitRate] = Field(None, alias="unitRates")


class OVOPlan(OVOBase):
"""Plan model."""

electricity: OVOPlanElectricity = Field(None, alias="electricity")
gas: OVOPlanGas = Field(None, alias="gas")
14 changes: 13 additions & 1 deletion ovoenergy/ovoenergy.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@

import aiohttp

from ovoenergy import (
from .models import (
OVODailyElectricity,
OVODailyGas,
OVODailyUsage,
OVOHalfHour,
OVOHalfHourUsage,
)
from .models.plan import OVOPlan


class OVOEnergy:
Expand Down Expand Up @@ -170,3 +171,14 @@ async def get_half_hourly_usage(
ovo_usage.gas.append(OVOHalfHour(**usage))

return ovo_usage

async def get_plan(self) -> OVOPlan:
"""Get plan."""
async with aiohttp.ClientSession() as session:
response = await session.get(
f"https://smartpaymapi.ovoenergy.com/orex/api/plans/{self._account_id}",
cookies=self._cookies,
)
json_response = await response.json()

return OVOPlan(**json_response)