Skip to content

Commit

Permalink
implemented backend of energy metric feature
Browse files Browse the repository at this point in the history
  • Loading branch information
IshavSohal committed Nov 24, 2023
1 parent a53d2b3 commit c24ca95
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 3 deletions.
2 changes: 2 additions & 0 deletions backend/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
# Imports
from routes.users import users
from routes.transportation import transportation_service
from routes.energy import energy_service


app = Flask(__name__)

# Services
app.register_blueprint(users, url_prefix="/users")
app.register_blueprint(transportation_service, url_prefix="/transportation")
app.register_blueprint(energy_service, url_prefix="/energy")
CORS(app)


Expand Down
98 changes: 98 additions & 0 deletions backend/models/energy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
"""
Energy Model
"""

from __future__ import annotations
import json
from datetime import datetime
from models.abstract_db_model import DB_MODEL
from bson import ObjectId
from bson import json_util

class EnergyEntry(DB_MODEL):
oid: ObjectId
user_id: ObjectId
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
carbon_emissions: float # measured in kgs of CO2
date: datetime

def __init__(self, oid: ObjectId, user_id: ObjectId, heating_oil: int, natural_gas: int, province: str,
household: int, electricity: int, carbon_emissions: float, date: datetime) -> None:
super().__init__(oid)
self.user_id = ObjectId(user_id)
self.heating_oil = heating_oil
self.natural_gas = natural_gas
self.electricity = electricity
self.province = province
self.household = household
self.carbon_emissions = carbon_emissions
self.date = date

def to_json(self, for_mongodb: bool = False) -> json:
res = {
'_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
}
if for_mongodb:
return res
return json.loads(json_util.dumps(res))

@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.province == "British Colombia":
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 == "Nortwest 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__()}'
14 changes: 11 additions & 3 deletions backend/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@ class User(DB_MODEL):
badges: list[str]
friends: list[str]
score: int
province: str
household: int

def __init__(self, oid: ObjectId, full_name: str, email: str, badges: list[str], friends: list[str], score:int) -> None:
def __init__(self, oid: ObjectId, full_name: str, email: str, badges: list[str], friends: list[str], score:int, province:str, household:int) -> None:
super().__init__(oid)
self.full_name = str(full_name)
self.email = str(email)
self.badges = badges
self.friends = friends
self.score = score
self.province = province
self.household = household

def to_json(self, for_mongodb: bool = False) -> json:
res = {
Expand All @@ -32,7 +36,9 @@ def to_json(self, for_mongodb: bool = False) -> json:
'email': self.email,
'badges': self.badges,
'friends': self.friends,
'score': self.score
'score': self.score,
'province': self.province,
'household': self.household
}
if for_mongodb:
return res
Expand All @@ -46,7 +52,9 @@ def from_json(doc: json) -> User:
email=doc["email"],
badges=doc["badges"],
friends=doc["friends"],
score=doc["score"]
score=doc["score"],
province=doc["province"],
household=doc["household"]
)

def __repr__(self) -> str:
Expand Down
1 change: 1 addition & 0 deletions backend/mongodb_api/carbon_track_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@
class CarbonTrackDB:
users_coll: Collection = carbonTrackDB.get_collection("users")
transportation_coll: Collection = carbonTrackDB.get_collection("transportation")
energy_coll: Collection = carbonTrackDB.get_collection("energy")
55 changes: 55 additions & 0 deletions backend/routes/energy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Python Imports
from datetime import datetime
from bson import ObjectId
from flask import Blueprint, Response, jsonify, request

from models.energy import EnergyEntry
from mongodb_api.carbon_track_db import CarbonTrackDB
from routes import carbon_auth
from utils.metric_resets import weekly_metric_reset, get_1_day_range

energy_service = Blueprint('/energy', __name__)


@energy_service.route("/energy/<oid>", methods=['GET'])
@carbon_auth.auth.login_required
def get_energy(oid: str) -> Response:
query = {"_id": ObjectId(oid)}
item = CarbonTrackDB.energy_coll.find_one(query)
item = EnergyEntry.from_json(item).to_json()
return jsonify({'energy': item})


@energy_service.route("/get_energy_metric_for_today/<user_id>", methods=['GET'])
@carbon_auth.auth.login_required
def get_energy_metric_for_today(user_id: str) -> Response:
start_of_day, end_of_day = get_1_day_range(datetime.now())
query = {"user_id": ObjectId(user_id), "date": {"$gte": start_of_day, "$lte": end_of_day}}
item = CarbonTrackDB.energy_coll.find_one(query)
if item is None:
create_energy(ObjectId(user_id))
return get_energy_metric_for_today(user_id=user_id)
else:
item = EnergyEntry.from_json(item).to_json()
return jsonify({'energy': item})


@carbon_auth.auth.login_required
def create_energy(user_id: ObjectId) -> Response:
energy = EnergyEntry(oid=ObjectId(), user_id=user_id, heating_oil = 0, natural_gas = 0, province = "Ontario",
household = 4, electricity = 0, carbon_emissions=0.0, date=weekly_metric_reset(datetime.today()))
energy = energy.to_json(for_mongodb=True)
inserted_id = CarbonTrackDB.energy_coll.insert_one(energy).inserted_id
energy = EnergyEntry.from_json(CarbonTrackDB.energy_coll.find_one({"_id": inserted_id})).to_json()
return energy


@energy_service.route("/energy/<oid>", methods=["PATCH"])
@carbon_auth.auth.login_required
def update_energy(oid: str) -> Response:
query = {"_id": ObjectId(oid)}
energy = EnergyEntry.from_json(request.get_json()['energy']).to_json(for_mongodb=True)
CarbonTrackDB.energy_coll.update_one(query, {'$set': energy})
item = CarbonTrackDB.energy_coll.find_one(query)
item = EnergyEntry.from_json(item).to_json()
return jsonify({'updated_energy': item})

0 comments on commit c24ca95

Please sign in to comment.