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

Feat: Usage Calculator #102

Merged
merged 14 commits into from
Apr 17, 2024
43 changes: 43 additions & 0 deletions example.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from iec_api.iec_client import IecClient
from iec_api.login import IECLoginError
from iec_api.models.exceptions import IECError
from iec_api.usage_calculator.calculator import UsageCalculator

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -91,6 +92,48 @@ async def main():
finally:
await session.close()

#
# Example of usage of UsageCalculator
#
session = aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=False), timeout=aiohttp.ClientTimeout(total=10))
try:
usage_calculator = UsageCalculator()
await usage_calculator.load_data(session)

# Get kWh Tariff
tariff = usage_calculator.get_kwh_tariff()
print(f"kWh Tariff: {tariff} ILS/kWh")

# Get all device names
device_names = usage_calculator.get_device_names()
print(device_names)

# Select "Air-conditioner"
device_name = device_names[8]
print(f"Selected device: [{device_name}]")

# Get device info by name
device = usage_calculator.get_device_info_by_name(device_name)
print(device)

# Get default utility consumption by time
consumption = usage_calculator.get_consumption_by_device_and_time(device_name, timedelta(days=1), None)
print(consumption)

# You can specify specific power usage of your device:
# e.g. 3.5HP air-conditioner running for 6 hours
consumption = usage_calculator.get_consumption_by_device_and_time(
device_name, timedelta(hours=6), custom_usage_value=3.5
)
print(
f"Running a {consumption.power} {consumption.power_unit.name} {consumption.name} "
f"for {consumption.duration.seconds // (60 * 60)} hours would cost: "
f"{round(consumption.cost, 2)} ILS"
)

finally:
await session.close()


if __name__ == "__main__": # pragma: no cover
asyncio.run(main())
10 changes: 5 additions & 5 deletions iec_api/usage_calculator/calculator.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,31 +52,31 @@ def get_device_info_by_name(self, name: str) -> Optional[ElectricDevice]:
return None

def get_consumption_by_device_and_time(
self, name: str, time_delta: timedelta, custom_unit: Optional[float]
self, name: str, time_delta: timedelta, custom_usage_value: Optional[float]
) -> Optional[Consumption]:
device = self.get_device_info_by_name(name)
if not device:
return None

minutes = time_delta.total_seconds() / 60

consumption = self._convert_to_kwh(device, custom_unit)
consumption = self._convert_to_kwh(device, custom_usage_value)
rate = self.rates.home_rate * (1 + self.rates.vat / 100)

return Consumption(
name=name,
power=custom_unit if custom_unit else device.power,
power=custom_usage_value if custom_usage_value else device.power,
power_unit=device.power_unit,
consumption=consumption,
cost=Decimal.from_float(consumption) * rate,
duration=timedelta(minutes=minutes),
)

@staticmethod
def _convert_to_kwh(device: ElectricDevice, custom_value: Optional[float] = None) -> float:
def _convert_to_kwh(device: ElectricDevice, custom_usage_value: Optional[float] = None) -> float:
# From IEC Logic

power = custom_value if custom_value else device.power
power = custom_usage_value if custom_usage_value else device.power

match device.power_unit:
case PowerUnit.KiloWatt:
Expand Down