Integration.
This commit is contained in:
parent
c3be26fa51
commit
840abb6dd8
|
@ -1,4 +1,5 @@
|
||||||
import inspect
|
import inspect
|
||||||
|
import logging
|
||||||
import statistics
|
import statistics
|
||||||
from dataclasses import asdict
|
from dataclasses import asdict
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
@ -7,21 +8,24 @@ from typing import List
|
||||||
import requests_cache
|
import requests_cache
|
||||||
from flask import Flask, jsonify
|
from flask import Flask, jsonify
|
||||||
|
|
||||||
from .strategies import dmi, steam, miloStrats
|
from .strategies import miloStrats, iss, cars_in_traffic, tide_strat, upstairs_neighbour
|
||||||
from .util import Context
|
from .util import Context
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
requests_cache.install_cache("requests_cache.sqlite", expire_after=timedelta(minutes=10))
|
requests_cache.install_cache("requests_cache", expire_after=timedelta(minutes=10))
|
||||||
|
|
||||||
|
|
||||||
strategies = {
|
strategies = {
|
||||||
# name: (weight, probability function)
|
# name: (weight, probability function)
|
||||||
"dmi": (0.5, dmi.probability),
|
"tv2news": miloStrats.tv2newsStrat,
|
||||||
"steam": (1.0, steam.probability),
|
"australia": miloStrats.australiaStrat,
|
||||||
"australia": (1.0, miloStrats.australiaStrat),
|
"camera": miloStrats.camImgStrat,
|
||||||
"camera": (1.0, miloStrats.camImgStrat),
|
"iss": iss.night_on_iss,
|
||||||
"tv2news": (1.0, miloStrats.tv2newsStrat)
|
"cars_in_traffic": cars_in_traffic.cars_in_traffic,
|
||||||
|
"tide": tide_strat.is_tide,
|
||||||
|
"upstairs_neighbour": upstairs_neighbour.check_games,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,17 +35,18 @@ def probabilities():
|
||||||
context = Context(**phone_data)
|
context = Context(**phone_data)
|
||||||
|
|
||||||
predictions: List[dict] = []
|
predictions: List[dict] = []
|
||||||
for name, (weight, strategy) in strategies.items():
|
for name, strategy in strategies.items():
|
||||||
try:
|
try:
|
||||||
prediction = strategy(context)
|
prediction = strategy(context)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Strategy {name} failed: {e}")
|
logger.warning("Strategy %s failed: %s", name, e)
|
||||||
|
logger.exception(e)
|
||||||
continue
|
continue
|
||||||
predictions.append({
|
predictions.append({
|
||||||
"name": name,
|
"name": name,
|
||||||
"description": inspect.getdoc(strategy),
|
"description": inspect.getdoc(strategy),
|
||||||
"weight": weight,
|
"weight": prediction.weight,
|
||||||
"weighted_probability": prediction.probability * weight,
|
"weighted_probability": prediction.probability * prediction.weight,
|
||||||
"night": prediction.probability > 0.5,
|
"night": prediction.probability > 0.5,
|
||||||
**asdict(prediction),
|
**asdict(prediction),
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
from ..util import Context, Prediction
|
|
||||||
|
|
||||||
|
|
||||||
def probability(context: Context) -> Prediction:
|
|
||||||
"""
|
|
||||||
The data from DMI.
|
|
||||||
"""
|
|
||||||
p = Prediction()
|
|
||||||
p.probability = 0.7
|
|
||||||
p.reasons.append("It is raining in Tønder")
|
|
||||||
|
|
||||||
return p
|
|
89
server/nightr/strategies/iss.py
Normal file
89
server/nightr/strategies/iss.py
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
import itertools
|
||||||
|
import logging
|
||||||
|
from datetime import datetime
|
||||||
|
from math import pi, sqrt, sin, cos, atan2
|
||||||
|
|
||||||
|
import pytz
|
||||||
|
import requests
|
||||||
|
from timezonefinder import TimezoneFinder
|
||||||
|
|
||||||
|
from ..util import Context, Prediction
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
tf = TimezoneFinder(in_memory=True)
|
||||||
|
|
||||||
|
|
||||||
|
def night_on_iss(context: Context) -> Prediction:
|
||||||
|
"""
|
||||||
|
It is night if it is night on the ISS and it is currently orbiting above us.
|
||||||
|
"""
|
||||||
|
p = Prediction()
|
||||||
|
|
||||||
|
if not context.flat_earth:
|
||||||
|
iss_position = requests.get("http://api.open-notify.org/iss-now.json").json()["iss_position"]
|
||||||
|
the_iss = "The ISS"
|
||||||
|
iss_position_description = "on board the ISS"
|
||||||
|
else:
|
||||||
|
p.reasons.append("The ISS is (obviously) located in Hollywood")
|
||||||
|
the_iss = "Hollywood"
|
||||||
|
iss_position = {'latitude': 34.092808, 'longitude': -118.328659} # Hollywood
|
||||||
|
iss_position_description = "in the Hollywood studio"
|
||||||
|
|
||||||
|
phone_position = context.position
|
||||||
|
|
||||||
|
# Calculate ratio: a number between 0 and 1 saying how close we are to the ISS
|
||||||
|
distance = haversine(iss_position, phone_position)
|
||||||
|
max_distance = 40075 / 2 # the furthest you can be from any position is half of the earth's circumference
|
||||||
|
ratio = distance / max_distance
|
||||||
|
|
||||||
|
# We're in the same "timezone" as the ISS if we're on the same half of the earth
|
||||||
|
on_iss_time = ratio < 0.5
|
||||||
|
|
||||||
|
side = "same" if on_iss_time else "other"
|
||||||
|
p.reasons.append(f"{the_iss} is {int(distance)} km away, so we are on the {side} side of the earth.")
|
||||||
|
for i in itertools.count(1):
|
||||||
|
iss_tz = tf.closest_timezone_at(lng=float(iss_position["longitude"]),
|
||||||
|
lat=float(iss_position["latitude"]),
|
||||||
|
delta_degree=i)
|
||||||
|
if iss_tz is not None:
|
||||||
|
break
|
||||||
|
iss_time = datetime.now(pytz.timezone(iss_tz))
|
||||||
|
|
||||||
|
iss_night = 6 < iss_time.hour > 22
|
||||||
|
|
||||||
|
# iss_night on_iss_time night
|
||||||
|
# 0 0 1
|
||||||
|
# 0 1 0
|
||||||
|
# 1 0 0
|
||||||
|
# 1 1 1
|
||||||
|
night = iss_night == on_iss_time
|
||||||
|
|
||||||
|
iss_time_description = "nighttime" if iss_night else "daytime"
|
||||||
|
time_description = "nighttime" if night else "daytime"
|
||||||
|
p.probability = float(night)
|
||||||
|
p.reasons.append(f"It is {iss_time_description} {iss_position_description}.")
|
||||||
|
p.reasons.append(f"Therefore, it must be {time_description} where we are.")
|
||||||
|
|
||||||
|
return p
|
||||||
|
|
||||||
|
|
||||||
|
def haversine(pos1, pos2):
|
||||||
|
"""
|
||||||
|
Distance between two GPS coordinates.
|
||||||
|
https://stackoverflow.com/a/18144531
|
||||||
|
"""
|
||||||
|
lat1 = float(pos1["latitude"])
|
||||||
|
long1 = float(pos1["longitude"])
|
||||||
|
lat2 = float(pos2["latitude"])
|
||||||
|
long2 = float(pos2["longitude"])
|
||||||
|
|
||||||
|
degree_to_rad = float(pi / 180.0)
|
||||||
|
|
||||||
|
d_lat = (lat2 - lat1) * degree_to_rad
|
||||||
|
d_long = (long2 - long1) * degree_to_rad
|
||||||
|
|
||||||
|
a = pow(sin(d_lat / 2), 2) + cos(lat1 * degree_to_rad) * cos(lat2 * degree_to_rad) * pow(sin(d_long / 2), 2)
|
||||||
|
c = 2 * atan2(sqrt(a), sqrt(1 - a))
|
||||||
|
km = 6367 * c
|
||||||
|
|
||||||
|
return km
|
|
@ -1,18 +1,18 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from pathlib import Path
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
import cv2
|
import cv2
|
||||||
from pytz import timezone
|
from pytz import timezone
|
||||||
|
|
||||||
from ..util import Context, Prediction
|
from ..util import Context, Prediction
|
||||||
#from server.nightr.util import Context, Prediction
|
|
||||||
|
|
||||||
|
|
||||||
def camImgStrat(context : Context) -> Prediction:
|
def camImgStrat(context : Context) -> Prediction:
|
||||||
"""
|
"""
|
||||||
The contents of the camera image
|
The contents of the camera image
|
||||||
"""
|
"""
|
||||||
img = cv2.imread('night.jpg',0)
|
img = cv2.imread(str(Path(__file__).parent.joinpath("night.jpg")), 0)
|
||||||
average = img.mean(axis=0).mean(axis=0)
|
average = img.mean(axis=0).mean(axis=0)
|
||||||
print(average)
|
print(average)
|
||||||
p = Prediction()
|
p = Prediction()
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
from ..util import Context, Prediction
|
|
||||||
|
|
||||||
|
|
||||||
def probability(context: Context) -> Prediction:
|
|
||||||
"""
|
|
||||||
How many players are currently online on Steam.
|
|
||||||
"""
|
|
||||||
p = Prediction()
|
|
||||||
p.probability = 0.2
|
|
||||||
p.reasons.append("CSGO has more than 10.000 online players")
|
|
||||||
|
|
||||||
return p
|
|
|
@ -15,4 +15,5 @@ class Context:
|
||||||
@dataclass
|
@dataclass
|
||||||
class Prediction:
|
class Prediction:
|
||||||
probability: float = 0.5
|
probability: float = 0.5
|
||||||
|
weight: float = 1.0
|
||||||
reasons: List[str] = field(default_factory=list)
|
reasons: List[str] = field(default_factory=list)
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
Flask==1.0.2
|
Flask
|
||||||
requests==2.21.0
|
requests
|
||||||
requests-cache==0.4.13
|
requests-cache
|
||||||
pytz
|
pytz
|
||||||
beautifulsoup4
|
beautifulsoup4
|
||||||
pandas
|
pandas
|
||||||
opencv-python
|
opencv-python
|
||||||
|
timezonefinder
|
||||||
|
scikit-learn
|
||||||
|
html5lib
|
||||||
|
xlrd
|
||||||
|
|
Loading…
Reference in a new issue