Presence functions created

parent 367b8a7d
......@@ -28,6 +28,7 @@ import bitsd.persistence.query as query
from bitsd.common import LOG, secure_compare
from bitsd.persistence.engine import session_scope, persist
from bitsd.persistence.models import Status, User, MACToUser, LoginAttempt
from bitsd.server.presence_graph.presence import Presence
from .auth import verify, DoSError
from .notifier import MessageNotifier
from .presence import PresenceForecaster
......@@ -439,5 +440,7 @@ class MACUpdateHandler(BaseHandler):
pass
class PresenceGraphHandler(BaseHandler):
PRESENCE = Presence()
def get(self):
self.write("")
\ No newline at end of file
self.write(PresenceGraphHandler.PRESENCE.get_graph().tostring())
\ No newline at end of file
......@@ -45,7 +45,7 @@ class PresenceGraph(Drawing):
position = j / len(self._data[i])
# Calculate the rescaled value on the number of the colors in the gradient
value = round(self._data[i][j] * (NUMBER_COLORS - 1))
value = int(round(self._data[i][j] * (NUMBER_COLORS - 1)))
# Get the hex value of the computed color
color = gradient[value].hex
......
from datetime import datetime, timedelta, time
from datetime import datetime, timedelta, time, date
from pprint import pprint
from typing import Tuple, List
import numpy
from sqlalchemy import asc
from bitsd.persistence.engine import session_scope
from bitsd.persistence.models import Status
from .graph import PresenceGraph
WINDOW_WIDTH = timedelta(weeks=6)
WINDOW_WIDTH = timedelta(weeks=8)
START_TIME = time(hour=8)
END_TIME = time(hour=21)
DELTA_SAMPLE = timedelta(minutes=30)
DELTA_SAMPLE = timedelta(minutes=15)
DATA_WEIGHTS = [100, 50, 30, 15, 10, 7, 3, 2]
class Presence():
def _get_raw_data_from_db(self) -> List[List[List[Tuple[datetime, bool]]]]:
def _get_raw_data_from_db(self) -> List[List[List[Tuple[time, bool]]]]:
"""Return a list of day, each day is a list of week, each week is a list of tuples of timestamp and status"""
window_date = (
......@@ -39,7 +42,7 @@ class Presence():
for row in session.query(Status) \
.filter(Status.timestamp.between(*current_limit)).order_by(asc(Status.timestamp)).all():
day.append((row.timestamp, True if row.value == row.OPEN else False))
day.append((row.timestamp.time(), True if row.value == row.OPEN else False))
data[current_day.weekday()].append(day)
......@@ -47,7 +50,63 @@ class Presence():
return data
def get_data(self) -> List[List[List[int]]]:
# Prepare the final structure for the data
data = [[], [], [], [], [], []]
# Get the raw data from the db
raw_data = self._get_raw_data_from_db()
# For each day of the week
for i in range(6):
# Get the data for the day
day_data = raw_data[i]
# Set the current time to the start of the day
current_time = datetime.combine(date.today(), START_TIME)
# Until the current time is earlier than the end of the day
while current_time.time() <= END_TIME:
# Create a list of weeks' values for a single sample in a single day
status_hour = []
# For each week value
for week in day_data:
# Add to the status_hour list the status for the current time for the current week data
status_hour.append(1 if self._status(week, current_time.time()) else 0)
data[i].append(status_hour)
# Forward to the next time for a sample
current_time = current_time + DELTA_SAMPLE
return data
def get_prevision(self) -> List[List[float]]:
raw_data = self.get_data()
data = [[], [], [], [], [], []]
# For each day of the week
for i in range(6):
day_data = raw_data[i]
for j, _ in enumerate(day_data):
data[i].append(numpy.average(day_data[j], weights=DATA_WEIGHTS[:len(day_data[j])]))
return data
def _status(self, data: List[Tuple[time, bool]], hour: time) -> bool:
status = False
for i in [(time(hour=0),False), *data]:
if i[0] > hour:
return status
status = i[1]
return status
def get_graph(self) -> PresenceGraph:
g = PresenceGraph([[0, 1], [1, .5], [.5, 0], [0, .5, 1, .2], [1, .2], [.2, .6, .1, 1, 0]])
g = PresenceGraph(self.get_prevision())
g.generate()
return g
......@@ -3,7 +3,8 @@ markdown
sqlalchemy>=0.7
tornado==4.*
paho-mqtt
mysqlclient
#mysqlclient
psycopg2
svgwrite~=1.3
colour~=0.1
\ No newline at end of file
colour~=0.1
numpy~=1.17
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment