Private
Public Access
1
0
Files
rowsandall/rowers/alerts.py
2019-08-14 21:42:30 +02:00

152 lines
4.5 KiB
Python

from rowers.models import Alert, Condition, User, Rower, Workout
from rowers.teams import coach_getcoachees
from rowers.dataprep import getsmallrowdata_db,getrowdata_db
import datetime
## BASIC operations
# create alert
def create_alert(manager, rower, measured,period=7, emailalert=True,
reststrokes=False, workouttype='water',
name='',**kwargs):
# check if manager is coach of rower. If not return 0
if manager.rower != rower:
if rower not in coach_getcoachees(manager.rower):
return 0
m = Condition(
metric = measured['metric'],
value1 = measured['value1'],
value2 = measured['value2'],
condition=measured['condition']
)
m.save()
alert = Alert(name=name,
manager=manager,
rower=rower,
measured=m,
reststrokes=reststrokes,
period=period,
emailalert=emailalert,
workouttype=workouttype
)
alert.save()
if 'filter' in kwargs:
for f in filter:
m = Condition(
metric = f['metric'],
value1 = f['value1'],
value2 = f['value2'],
condition = f['condition']
)
m.save()
alert.filter.add(m)
return 1
# update alert
def alert_add_filters(alert,filter):
for f in alert.filter.all():
alert.filter.remove(f)
f.delete()
for f in filter:
m = Condition(
metric = f['metric'],
value1 = f['value1'],
value2 = f['value2'],
condition = f['condition']
)
m.save()
alert.filter.add(m)
# get alert stats
# nperiod = 0: current period, i.e. next_run - n days to today
# nperiod = 1: 1 period ago , i.e. next_run -2n days to next_run -n days
def alert_get_stats(alert,nperiod=0):
# get strokes
workstrokesonly = not alert.reststrokes
startdate = (alert.next_run - datetime.timedelta(days=(nperiod+1)*alert.period-1))
enddate = alert.next_run - datetime.timedelta(days=(nperiod)*alert.period)
columns = [alert.measured.metric]
for condition in alert.filter.all():
columns += condition.metric
workouts = Workout.objects.filter(date__gte=startdate,date__lte=enddate,user=alert.rower,
workouttype=alert.workouttype)
ids = [w.id for w in workouts]
df = getsmallrowdata_db(columns,ids=ids,doclean=True,workstrokesonly=workstrokesonly)
if df.empty:
return {
'workouts':len(workouts),
'startdate':startdate,
'enddate':enddate,
'nr_strokes':0,
'nr_strokes_qualifying':0,
}
# drop strokes through filter
for condition in alert.filter.all():
if condition.condition == '>':
mask = df[condition.metric] > condition.value1
df.loc[mask,alert.measured.metric] = np.nan
elif condition.condition == '<':
mask = df[condition.metric] < condition.value1
df.loc[mask,alert.measured.metric] = np.nan
elif condition.condition == 'between':
mask = df[condition.metric] > condition.value1
mask2 = df[condition.metric] < condition.value2
df.loc[mask & mask2,alert.measured.metric] = np.nan
elif condition.condition == '=':
mask = df[condition.metric] == condition.value1
df.loc[mask,alert.measured.metric] = np.nan
df.dropna(inplace=True,axis=0)
# count strokes
nr_strokes = len(df)
# count qualifying
if alert.measured.condition == '>':
mask = df[alert.measured.metric] > alert.measured.value1
df2 = df[mask].copy()
elif alert.measured.condition == '<':
mask = df[alert.measured.metric] > alert.measured.value1
df2 = df[mask].copy()
elif alert.measured.condition == 'between':
mask = df[alert.measured.metric] > alert.measured.value1
mask2 = df[alert.measured.metric] < alert.measured.value2
df2 = df[mask & mask2].copy()
else:
mask = df[alert.measured.metric] == alert.measured.value1
df2 = df[mask].copy()
nr_strokes_qualifying = len(df2)
return {
'workouts':len(workouts),
'startdate':startdate,
'enddate':enddate,
'nr_strokes':nr_strokes,
'nr_strokes_qualifying':nr_strokes_qualifying
}
# run alert report