Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ jobs:
echo "REACT_APP_BACKEND_URL=${{ secrets.REACT_APP_BACKEND_URL }}" > ./recommender-back/.env
echo "MONGO_URI=${{ secrets.MONGO_URI }}" >> ./recommender-back/.env
echo "FLASK_DEBUG=False" >> ./recommender-back/.env
echo "ENVIRONMENT=production" >> ./recommender-back/.env
- name: Build and push frontend
uses: docker/build-push-action@v2
with:
Expand Down
10 changes: 7 additions & 3 deletions recommender-back/src/apis/current.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import copy
import math
import os
from .poi import PointOfInterest
from ..services.data_fetcher import DataFetcher
from ..config import Config

ENVIRONMENT = os.environ.get('ENVIRONMENT')

class Current:
def __init__(self, fetcher: DataFetcher):
self.fetcher = fetcher
self.weather = None
self.aqi = None
self.get_current_weather()
self.get_current_air_quality()

if ENVIRONMENT == "production":
self.get_current_air_quality()

def get_current_weather(self):
'''
Expand Down Expand Up @@ -146,10 +150,10 @@ def find_nearest_stations_weather_data(self, poi: PointOfInterest):
missing_fields.remove(key)
if not missing_fields or not weather:
smallest, nearest = float('inf'), ''
if len(aqi) > 0:
if aqi != None:
nearest = self.find_nearest_stations_aqi(aqi, lat, lon)
returned.setdefault(
'Air quality', aqi[nearest]['Air quality'])
'Air quality', aqi[nearest]['Air quality'])
break
del weather[nearest]
poi.weather['Current'] = returned
Expand Down
10 changes: 7 additions & 3 deletions recommender-back/src/apis/manager.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import json
import os
from requests import Timeout
from .current import Current
from .poi import PointOfInterest
from ..services.data_fetcher import DataFetcher
from ..services.api_fetcher import InternalApiService
from ..db.db import get_collection

ENVIRONMENT = os.environ.get('ENVIRONMENT')

def get_simulated_pois_as_json(air_temperature, wind_speed, humidity,
precipitation, cloud_amount, air_quality, current_time, sunrise, sunset):
"""
Expand Down Expand Up @@ -47,9 +50,10 @@ def get_pois_as_json(category="All"):
weather_fetcher = DataFetcher()
current = Current(weather_fetcher)
forecast_data = InternalApiService.fetch_forecast()
aqi_data = InternalApiService.fetch_aqi()
aqi_data = _replace_datetime_in_aqi_data(forecast_data, aqi_data)
forecast_data = _add_aqi_to_forecast(forecast_data, aqi_data)
if ENVIRONMENT == "production":
aqi_data = InternalApiService.fetch_aqi()
aqi_data = _replace_datetime_in_aqi_data(forecast_data, aqi_data)
forecast_data = _add_aqi_to_forecast(forecast_data, aqi_data)
updated_data = []
for poi in pois:
if category not in poi.categories:
Expand Down
39 changes: 24 additions & 15 deletions recommender-back/src/apis/poi.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,16 @@ def __init__(self, name=None, latitude=None, longitude=None, not_accessible_for=
}

def _extract_weather_data(self, data):
return {
'wind_speed': float(data.get('Wind speed').split(' ')[0]),
'precipitation': float(data.get('Precipitation').split(' ')[0]),
'clouds': float(data.get('Cloud amount').split(' ')[0]) * 0.01,
'temperature': float(data.get('Air temperature').split(' ')[0]),
'humidity': float(data.get('Humidity').split(' ')[0]) * 0.01,
'air_quality': float(data.get('Air quality').split(' ')[0]),
}
extracted_weather = {'wind_speed': float(data.get('Wind speed').split(' ')[0]),
'precipitation': float(data.get('Precipitation').split(' ')[0]),
'clouds': float(data.get('Cloud amount').split(' ')[0]) * 0.01,
'temperature': float(data.get('Air temperature').split(' ')[0]),
'humidity': float(data.get('Humidity').split(' ')[0]) * 0.01}

if data.get('Air quality'):
extracted_weather['air_quality'] = float(data.get('Air quality').split(' ')[0])

return extracted_weather

def calculate_score(self, cur_time=None, sunrise=None, sunset=None):
"""
Expand Down Expand Up @@ -72,12 +74,20 @@ def calculate_score(self, cur_time=None, sunrise=None, sunset=None):
scorer = self.scorers["Indoor"]

if scorer:
data['Score'] = scorer.score(
weather_data['temperature'], weather_data['wind_speed'],
weather_data['humidity'], weather_data['precipitation'],
weather_data['clouds'], weather_data['air_quality'],
sunrise_time, sunset_time, current_time
)
if weather_data.get('air_quality'):
data['Score'] = scorer.score(
weather_data['temperature'], weather_data['wind_speed'],
weather_data['humidity'], weather_data['precipitation'],
weather_data['clouds'], weather_data['air_quality'],
sunrise_time, sunset_time, current_time
)
else:
data['Score'] = scorer.score(
weather_data['temperature'], weather_data['wind_speed'],
weather_data['humidity'], weather_data['precipitation'],
weather_data['clouds'], 0,
sunrise_time, sunset_time, current_time
)
Comment on lines +77 to +90
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's some duplicate code here that could be refactored.
For example:
`temperature = weather_data.get('temperature')
wind_speed = weather_data.get('wind_speed')
humidity = weather_data.get('humidity')
precipitation = weather_data.get('precipitation')
clouds = weather_data.get('clouds')
air_quality = weather_data.get('air_quality', 0)

data['Score'] = scorer.score(
temperature, wind_speed, humidity, precipitation, clouds, air_quality,
sunrise_time, sunset_time, current_time
)`


def set_simulated_weather(self, air_temperature, wind_speed, humidity,
precipitation, cloud_amount, air_quality):
Expand All @@ -95,7 +105,6 @@ def set_simulated_weather(self, air_temperature, wind_speed, humidity,
This method sets simulated weather data for the Point of Interest (POI) to facilitate testing
the score calculation functionality.
"""

self.weather = {
"Weather": {
"Air temperature": f"{air_temperature} °C",
Expand Down
9 changes: 6 additions & 3 deletions recommender-back/src/services/scoring/indoor_scorer.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def temperature_score(temperature):
return 1 - math.exp(-0.04 * (IndoorScorer.OPTIMAL_TEMPERATURE_LOW - temperature))
else:
return 1 - math.exp(0.2 * (IndoorScorer.OPTIMAL_TEMPERATURE_HIGH - temperature))

@staticmethod
def day_time_score(current_time, sunrise_time, sunset_time):
if sunrise_time <= current_time <= sunset_time:
Expand All @@ -40,6 +40,9 @@ def score(self, temperature, wind_speed, humidity, precipitation, clouds, air_qu
self.day_time_score(current_time, sunrise_time, sunset_time) +
IndoorScorer.CLOUDS_WEIGHT * (1 - math.exp(-3 * clouds)) +
IndoorScorer.WIND_SPEED_WEIGHT * (1 - math.exp(-0.3 * wind_speed)) +
self.humidity_score(humidity) +
IndoorScorer.AIR_QUALITY_WEIGHT * math.exp(0.5 * (1 - air_quality)))
self.humidity_score(humidity))

if air_quality != 0:
score += IndoorScorer.AIR_QUALITY_WEIGHT * math.exp(0.5 * (1 - air_quality))

return round(score, 2)
7 changes: 5 additions & 2 deletions recommender-back/src/services/scoring/outdoor_scorer.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ def score(self, temperature, wind_speed, humidity, precipitation, clouds, air_qu
self.day_time_score(current_time, sunrise_time, sunset_time) +
OutdoorScorer.CLOUDS_WEIGHT * math.exp(-clouds) +
OutdoorScorer.WIND_SPEED_WEIGHT * math.exp(-wind_speed) +
self.humidity_score(humidity) +
OutdoorScorer.AIR_QUALITY_WEIGHT * math.exp(1 - air_quality))
self.humidity_score(humidity))

if air_quality != 0:
score += OutdoorScorer.AIR_QUALITY_WEIGHT * math.exp(1 - air_quality)

return round(score, 2)