-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #33 from utmgdsc/feature/62/energy_metric
[62] Energy Metric
- Loading branch information
Showing
40 changed files
with
1,979 additions
and
438 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
""" | ||
Carbon Model | ||
All classes that store carbon usage must inherit from this abstract class | ||
""" | ||
from __future__ import annotations | ||
import json | ||
from datetime import datetime, timezone | ||
from typing import Union | ||
|
||
from bson import ObjectId | ||
from models.abstract_db_model import DB_MODEL | ||
|
||
|
||
class CARBON_MODEL(DB_MODEL): | ||
|
||
oid: ObjectId | ||
user_id: ObjectId | ||
carbon_emissions: int | ||
date: datetime | ||
|
||
def __init__(self, oid: ObjectId, user_id: ObjectId, carbon_emissions: int, date: Union[str, datetime]) -> None: | ||
super().__init__(oid) | ||
self.user_id = ObjectId(user_id) | ||
self.carbon_emissions = carbon_emissions | ||
if isinstance(date, datetime): | ||
self.date = date | ||
else: | ||
self.date = datetime.fromisoformat(date) | ||
|
||
def to_json(self) -> json: | ||
raise NotImplementedError | ||
|
||
@staticmethod | ||
def from_json(doc: json) -> CARBON_MODEL: | ||
raise NotImplementedError | ||
|
||
def calculate_carbon_emissions(self) -> int: | ||
raise NotImplementedError | ||
|
||
@staticmethod | ||
def get_monthly_view(start: datetime, end: datetime, | ||
carbonEntries: list[CARBON_MODEL]) -> list[dict[str, Union[list[float], str]]]: | ||
monthly_data = [] | ||
|
||
# Make start date offset-aware (assuming UTC for simplicity) | ||
start = start.replace(tzinfo=timezone.utc) | ||
|
||
current_month = start | ||
while current_month <= end: | ||
# Add the current month to the list | ||
monthly_data.append({ | ||
"month": current_month.strftime("%B"), | ||
"year": current_month.strftime("%Y"), | ||
"data": [0, 0, 0, 0] | ||
}) | ||
|
||
# Move to the next month | ||
if current_month.month == 12: | ||
current_month = datetime(current_month.year + 1, 1, 1, tzinfo=timezone.utc) | ||
else: | ||
current_month = datetime(current_month.year, current_month.month + 1, 1, tzinfo=timezone.utc) | ||
|
||
for carbon_entry in carbonEntries: | ||
for monthly_entry in monthly_data: | ||
if carbon_entry.date.strftime("%B") == monthly_entry["month"] \ | ||
and carbon_entry.date.strftime("%Y") == monthly_entry["year"]: | ||
if carbon_entry.date.day < 7: | ||
monthly_entry["data"][0] = carbon_entry.calculate_carbon_emissions() | ||
elif carbon_entry.date.day < 14: | ||
monthly_entry["data"][1] = carbon_entry.calculate_carbon_emissions() | ||
elif carbon_entry.date.day < 21: | ||
monthly_entry["data"][2] = carbon_entry.calculate_carbon_emissions() | ||
elif carbon_entry.date.day < 28: | ||
monthly_entry["data"][3] += carbon_entry.calculate_carbon_emissions() | ||
else: # If a Month has 5 sunday, we add them to the fourth week | ||
monthly_entry["data"][3] += carbon_entry.calculate_carbon_emissions() / 4 | ||
return monthly_data | ||
|
||
def __repr__(self) -> str: | ||
raise NotImplementedError |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
""" | ||
Energy Model | ||
""" | ||
|
||
from __future__ import annotations | ||
from typing import Union | ||
import json | ||
from datetime import datetime | ||
from models.abstract_carbon_model import CARBON_MODEL | ||
from bson import ObjectId | ||
|
||
|
||
class EnergyEntry(CARBON_MODEL): | ||
oid: ObjectId | ||
user_id: ObjectId | ||
carbon_emissions: int # measured in kgs of CO2 | ||
date: datetime | ||
heating_oil: int # measured in L of fuel | ||
natural_gas: int # measured in m3 of gas | ||
electricity: int # measured in kWh | ||
province: str | ||
household: int | ||
|
||
def __init__(self, oid: ObjectId, user_id: ObjectId, carbon_emissions: int, date: Union[str, datetime], | ||
heating_oil: int, natural_gas: int, province: str, household: int, electricity: int) -> None: | ||
super().__init__(oid, user_id, carbon_emissions, date) | ||
self.heating_oil = heating_oil | ||
self.natural_gas = natural_gas | ||
self.electricity = electricity | ||
self.province = province | ||
self.household = household | ||
|
||
def to_json(self) -> json: | ||
return { | ||
'_id': self.oid, | ||
'user_id': self.user_id, | ||
'heating_oil': self.heating_oil, | ||
'natural_gas': self.natural_gas, | ||
'electricity': self.electricity, | ||
'province': self.province, | ||
'household': self.household, | ||
'carbon_emissions': self.calculate_carbon_emissions(), | ||
'date': self.date | ||
} | ||
|
||
@staticmethod | ||
def from_json(doc: json) -> EnergyEntry: | ||
return EnergyEntry( | ||
oid=ObjectId(doc["_id"]), | ||
user_id=doc['user_id'], | ||
heating_oil=doc["heating_oil"], | ||
natural_gas=doc["natural_gas"], | ||
electricity=doc["electricity"], | ||
province=doc["province"], | ||
household=doc["household"], | ||
carbon_emissions=doc["carbon_emissions"], | ||
date=doc["date"] | ||
) | ||
|
||
def calculate_carbon_emissions(self) -> float: | ||
heating_oil_carbon_emissions = self.heating_oil * 2.753 | ||
natural_gas_carbon_emissions = self.natural_gas * 1.96 | ||
|
||
if self.household < 1: | ||
self.household = 1 | ||
|
||
if self.province == "British Columbia": | ||
electricity_carbon_emissions = (self.electricity * 0.015) / self.household | ||
elif self.province == "Alberta": | ||
electricity_carbon_emissions = (self.electricity * 0.54) / self.household | ||
elif self.province == "Saskatchewan": | ||
electricity_carbon_emissions = (self.electricity * 0.73) / self.household | ||
elif self.province == "Manitoba": | ||
electricity_carbon_emissions = (self.electricity * 0.002) / self.household | ||
elif self.province == "Ontario": | ||
electricity_carbon_emissions = (self.electricity * 0.03) / self.household | ||
elif self.province == "Quebec": | ||
electricity_carbon_emissions = (self.electricity * 0.0017) / self.household | ||
elif self.province == "New Brunswick": | ||
electricity_carbon_emissions = (self.electricity * 0.3) / self.household | ||
elif self.province == "Nova Scotia": | ||
electricity_carbon_emissions = (self.electricity * 0.69) / self.household | ||
elif self.province == "PEI": | ||
electricity_carbon_emissions = (self.electricity * 0.3) / self.household | ||
elif self.province == "Newfoundland and Labrador": | ||
electricity_carbon_emissions = (self.electricity * 0.017) / self.household | ||
elif self.province == "Yukon": | ||
electricity_carbon_emissions = (self.electricity * 0.08) / self.household | ||
elif self.province == "Northwest Territories": | ||
electricity_carbon_emissions = (self.electricity * 0.17) / self.household | ||
else: # self.province == "Nunavut" | ||
electricity_carbon_emissions = (self.electricity * 0.84) / self.household | ||
return sum([heating_oil_carbon_emissions, natural_gas_carbon_emissions, electricity_carbon_emissions]) | ||
|
||
def __repr__(self) -> str: | ||
return f'Energy ID: {self.oid.__str__()}' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.