diff --git a/build.bat b/build.bat
index 2417ac8..bd2e187 100644
--- a/build.bat
+++ b/build.bat
@@ -68,6 +68,7 @@ if %errorlevel% neq 0 (
)
rmdir /S /Q mongo
+rmdir /S /Q sessions
cd ..
rmdir /S /Q venv
diff --git a/scripts/odroid-c.sh b/scripts/odroid-c.sh
index cb6b0d9..092f000 100644
--- a/scripts/odroid-c.sh
+++ b/scripts/odroid-c.sh
@@ -23,8 +23,9 @@ cd "$(dirname "$0")"
sudo rm /etc/localtime
sudo ln -s /usr/share/zoneinfo/US/Eastern /etc/localtime
- # Turn off fstab fsck (potentially dangerous)
+ # Turn off startup fsck (potentially dangerous)
sudo sed -i 's/1$/0/g' /etc/fstab
+ sudo tune2fs -c 0 -i 0 -l /dev/mmcblk0p2
# ODROID C1/C2 LCD
if [ "$(systemctl | grep odroid-lcd35)" == "" ]; then
diff --git a/sharkscout/mongo.py b/sharkscout/mongo.py
index 1d0d31b..3f7e453 100644
--- a/sharkscout/mongo.py
+++ b/sharkscout/mongo.py
@@ -233,7 +233,7 @@ def events_update(self, year):
# TBA update an individual event
def event_update(self, event_key):
- event = self.tba_api.event(event_key)
+ event = self.tba_api.event(event_key, True)
if event:
# Info that can be known before an event starts
event.update({k:v for k, v in {
@@ -601,7 +601,7 @@ def team(self, team_key, year=None):
# TBA update an individual team
def team_update(self, team_key):
- team = self.tba_api.team(team_key)
+ team = self.tba_api.team(team_key, True)
if team:
team.update({k:v for k, v in {
'awards': self.tba_api.team_history_awards(team_key),
diff --git a/sharkscout/thebluealliance.py b/sharkscout/thebluealliance.py
index 6a9d325..6fec3e0 100644
--- a/sharkscout/thebluealliance.py
+++ b/sharkscout/thebluealliance.py
@@ -38,7 +38,11 @@ def _get(self, endpoint, ignore_cache=False):
if response.status_code == 304:
return {}
- content = response.json()
+ try:
+ content = response.json()
+ except json.JSONDecodeError as e:
+ print(endpoint, response.status_code, response.text)
+ raise e
content = self._tba3_clean(content)
content = self._tba3_to_tba2(content)
@@ -211,9 +215,7 @@ def event_rankings_raw(self, event_key, ignore_cache=False):
def event_rankings_v2(self, event_key, ignore_cache=False):
rankings = self.event_rankings_raw(event_key, ignore_cache)
- if rankings is None:
- return rankings
- if 'rankings' in rankings and rankings['rankings']:
+ if rankings and 'rankings' in rankings and rankings['rankings']:
for idx, ranking in enumerate(rankings['rankings']):
rankings['rankings'][idx] = [
ranking['rank'],
@@ -223,7 +225,8 @@ def event_rankings_v2(self, event_key, ignore_cache=False):
ranking['matches_played']
]
rankings['rankings'].insert(0, ['Rank', 'Team'] + [i['name'] for i in rankings['sort_order_info']] + ['Record (W-L-T)', 'Played'])
- return rankings['rankings']
+ return rankings['rankings']
+ return []
def event_rankings(self, event_key, ignore_cache=False):
rankings = self.event_rankings_v2(event_key, ignore_cache)
diff --git a/sharkscout/webserver.py b/sharkscout/webserver.py
index 8f8abd2..4da6d95 100644
--- a/sharkscout/webserver.py
+++ b/sharkscout/webserver.py
@@ -477,7 +477,7 @@ def _csv(self, prefix, items):
filename = tempfile.gettempdir() + '/' + prefix + datetime.now().strftime('%Y%m%d-%H%M%S') + '.csv'
with open(filename, 'w', newline='') as temp:
writer = csv.DictWriter(temp, fieldnames=keys)
- writer.writerow({k: re.sub(r'^[0-9]+_+', '', k) for k in keys})
+ writer.writerow({k: k.lstrip('0123456789').strip(' _') for k in keys})
# Write each row
for item in items:
row = {}
@@ -543,14 +543,14 @@ def received_message(self, message):
self.send({
'dequeue': {'scouting_match': data},
'toast': {
- 'message': 'You Match Scouted ' + data['match_key'] + ' ' + data['team_key'],
+ 'message': 'You match scouted ' + data['match_key'] + ' ' + data['team_key'],
'type': 'success'
}
})
self.broadcast({'show': '.match-listing .' + data['match_key'] + ' .' + data['team_key'] + ' .fa-check'})
self.broadcast_others({
'toast': {
- 'message': data['scouter'] + ' Match Scouted ' + data['match_key'] + ' ' + data['team_key'],
+ 'message': data['scouter'] + ' match scouted ' + data['match_key'] + ' ' + data['team_key'],
'type': 'success',
'mobile': False
}
@@ -563,14 +563,14 @@ def received_message(self, message):
self.send({
'dequeue': {'scouting_pit': data},
'toast': {
- 'message': 'You Pit Scouted ' + data['event_key'] + ' ' + data['team_key'],
+ 'message': 'You pit scouted ' + data['event_key'] + ' ' + data['team_key'],
'type': 'success'
}
})
self.broadcast({'show': '.team-listing .' + data['team_key'] + ' .fa-check'})
self.broadcast_others({
'toast': {
- 'message': data['scouter'] + ' Pit Scouted ' + data['event_key'] + ' ' + data['team_key'],
+ 'message': data['scouter'] + ' pit scouted ' + data['event_key'] + ' ' + data['team_key'],
'type': 'success',
'mobile': False
}
diff --git a/stats/2018.json b/stats/2018.json
index f21e5b5..3cbb801 100644
--- a/stats/2018.json
+++ b/stats/2018.json
@@ -37,6 +37,45 @@
"matches.cubes_scale": {"$ifNull": ["$matches.cubes_scale", "$pit.avg_cubes_scale"]}
}},
+ // Change some strings to ints
+ {"$addFields": {
+ "matches.auton_crossed_baseline_int": {"$cond": {
+ "if": {"$eq": ["$matches.auton_crossed_baseline", "Y"]},
+ "then": 5,
+ "else": 0
+ }},
+ "matches.auton_exchange": {"$cond": {
+ "if": {"$eq": ["$matches.auton_cube_position", "exchange"]},
+ "then": 5,
+ "else": 0
+ }},
+ "matches.auton_switch": {"$cond": {
+ "if": {"$eq": ["$matches.auton_cube_position", "switch"]},
+ "then": 10,
+ "else": 0
+ }},
+ "matches.auton_scale": {"$cond": {
+ "if": {"$eq": ["$matches.auton_cube_position", "scale"]},
+ "then": 10,
+ "else": 0
+ }},
+ "matches.parked": {"$cond": {
+ "if": {"$eq": ["$matches.end_position", "parked"]},
+ "then": 5,
+ "else": 0
+ }},
+ "matches.picked_up": {"$cond": {
+ "if": {"$eq": ["$matches.end_position", "picked_up"]},
+ "then": 30,
+ "else": 0
+ }},
+ "matches.climbed": {"$cond": {
+ "if": {"$eq": ["$matches.end_position", "climbed"]},
+ "then": 30,
+ "else": 0
+ }}
+ }},
+
// So $in operations can succeed
{"$addFields": {
"pit.cube_scoring_location": {"$ifNull": ["$pit.cube_scoring_location", []]}
@@ -56,7 +95,7 @@
{"$cond": {
"if": {"$ne": ["$pit.drivetrain", ""]},
"then": {"$concat": [
- "- ",
+ "• ",
{"$substr": ["$pit.drivetrain", 0, -1]}
]},
"else": ""
@@ -64,7 +103,7 @@
{"$cond": {
"if": {"$ne": ["$pit.robot_height", ""]},
"then": {"$concat": [
- "
- ",
+ "
• ",
{"$substr": ["$pit.robot_height", 0, -1]},
" in"
]},
@@ -73,7 +112,7 @@
{"$cond": {
"if": {"$ne": ["$pit.robot_weight", ""]},
"then": {"$concat": [
- "
- ",
+ "
• ",
{"$substr": ["$pit.robot_weight", 0, -1]},
" lb"
]},
@@ -82,7 +121,7 @@
{"$cond": {
"if": {"$ne": ["$pit.cube_lifter", ""]},
"then": {"$concat": [
- "
- ",
+ "
• ",
{"$substr": ["$pit.cube_lifter", 0, -1]},
" + ",
{"$substr": ["$pit.cube_intake", 0, -1]}
@@ -91,27 +130,27 @@
}},
{"$cond": {
"if": {"$in": ["exchange", "$pit.cube_scoring_location"]},
- "then": "
- can do exchange",
+ "then": "
• can do exchange",
"else": ""
}},
{"$cond": {
"if": {"$in": ["switch", "$pit.cube_scoring_location"]},
- "then": "
- can do switch",
+ "then": "
• can do switch",
"else": ""
}},
{"$cond": {
"if": {"$in": ["scale", "$pit.cube_scoring_location"]},
- "then": "
- can do scale",
+ "then": "
• can do scale",
"else": ""
}},
{"$cond": {
"if": {"$eq": ["$pit.climber", "Y"]},
- "then": "
- has climber",
+ "then": "
• has climber",
"else": ""
}},
{"$cond": {
"if": {"$eq": ["$pit.can_lift", "Y"]},
- "then": "
- can lift others",
+ "then": "
• can lift others",
"else": ""
}}
]}},
@@ -120,74 +159,118 @@
"$concat": [
"$matches.number",
" ",
- "$matches.auton_strategy"
- ]
- }},
- "201_auton_baseline": {"$push": {
- "$cond": {
- "if": {"$eq": ["$matches.auton_crossed_baseline", "Y"]},
- "then": 1,
- "else": 0
- }
- }},
- "202_auton_cube_pos": {"$push": {
- "$concat": [
- "$matches.number",
- " ",
- "$matches.auton_cube_position"
+ {"$substr": ["$matches.auton_strategy", 0, -1]}
]
}},
+ "_auton_crossed_baseline": {"$push": "$matches.auton_crossed_baseline_int"},
+ "_auton_crossed_baseline_avg": {"$avg": {"$cond": {
+ "if": {"$eq": ["$matches.auton_crossed_baseline", "Y"]},
+ "then": 1,
+ "else": 0
+ }}},
+ "_auton_exchange": {"$push": {"$add": [
+ "$matches.auton_crossed_baseline_int",
+ "$matches.auton_exchange"
+ ]}},
+ "_auton_exchange_avg": {"$avg": {"$cond": {
+ "if": {"$eq": ["$matches.auton_cube_position", "exchange"]},
+ "then": 1,
+ "else": 0
+ }}},
+ "_auton_switch": {"$push": {"$add": [
+ "$matches.auton_crossed_baseline_int",
+ "$matches.auton_exchange",
+ "$matches.auton_switch"
+ ]}},
+ "_auton_switch_avg": {"$avg": {"$cond": {
+ "if": {"$eq": ["$matches.auton_cube_position", "switch"]},
+ "then": 1,
+ "else": 0
+ }}},
+ "_auton_scale": {"$push": {"$add": [
+ "$matches.auton_crossed_baseline_int",
+ "$matches.auton_exchange",
+ "$matches.auton_switch",
+ "$matches.auton_scale"
+ ]}},
+ "_auton_scale_avg": {"$avg": {"$cond": {
+ "if": {"$eq": ["$matches.auton_cube_position", "scale"]},
+ "then": 1,
+ "else": 0
+ }}},
+ "_auton_avg": {"$avg": {"$add": [
+ "$matches.auton_crossed_baseline_int",
+ "$matches.auton_exchange",
+ "$matches.auton_switch",
+ "$matches.auton_scale"
+ ]}},
// Teleop
"300_teleop_strat": {"$push": {
"$concat": [
"$matches.number",
" ",
- "$matches.teleop_strategy"
+ {"$substr": ["$matches.teleop_strategy", 0, -1]}
]
}},
"_exchange": {"$push": "$matches.cubes_exchange"},
- "_switch_own": {"$push": "$matches.cubes_switch_own"},
- "_scale": {"$push": "$matches.cubes_scale"},
- "_switch_opponent": {"$push": "$matches.cubes_switch_opponent"},
- "_cube_min": {"$min": {"$add": ["$matches.cubes_exchange", "$matches.cubes_switch_own", "$matches.cubes_scale", "$matches.cubes_switch_opponent"]}},
- "_cube_max": {"$max": {"$add": ["$matches.cubes_exchange", "$matches.cubes_switch_own", "$matches.cubes_scale", "$matches.cubes_switch_opponent"]}},
- "_cube_avg": {"$avg": {"$add": ["$matches.cubes_exchange", "$matches.cubes_switch_own", "$matches.cubes_scale", "$matches.cubes_switch_opponent"]}},
+ "_switch_own": {"$push": {"$add": [
+ "$matches.cubes_exchange",
+ "$matches.cubes_switch_own"
+ ]}},
+ "_scale": {"$push": {"$add": [
+ "$matches.cubes_exchange",
+ "$matches.cubes_switch_own",
+ "$matches.cubes_scale"
+ ]}},
+ "_switch_opponent": {"$push": {"$add": [
+ "$matches.cubes_exchange",
+ "$matches.cubes_switch_own",
+ "$matches.cubes_scale",
+ "$matches.cubes_switch_opponent"
+ ]}},
+ "_cube_min": {"$min": {"$add": [
+ "$matches.cubes_exchange",
+ "$matches.cubes_switch_own",
+ "$matches.cubes_scale",
+ "$matches.cubes_switch_opponent"
+ ]}},
+ "_cube_max": {"$max": {"$add": [
+ "$matches.cubes_exchange",
+ "$matches.cubes_switch_own",
+ "$matches.cubes_scale",
+ "$matches.cubes_switch_opponent"
+ ]}},
+ "_cube_avg": {"$avg": {"$add": [
+ "$matches.cubes_exchange",
+ "$matches.cubes_switch_own",
+ "$matches.cubes_scale",
+ "$matches.cubes_switch_opponent"
+ ]}},
// End Game
- "_park": {"$push": {
- "$cond": {
- "if": {"$eq": ["$matches.end_position", "parked"]},
- "then": 1,
- "else": 0
- }
- }},
- "_park_avg": {"$avg": {
- "$cond": {
- "if": {"$eq": ["$matches.end_position", "parked"]},
- "then": 1,
- "else": 0
- }
- }},
- "_climb": {"$push": {
- "$cond": {
- "if": {"$eq": ["$matches.end_position", "climbed"]},
- "then": 1,
- "else": 0
- }
- }},
- "_climb_avg": {"$avg": {
- "$cond": {
- "if": {"$eq": ["$matches.end_position", "climbed"]},
- "then": 1,
- "else": 0
- }
- }},
- "_picked_up": {"$push": {
- "$cond": {
- "if": {"$eq": ["$matches.end_position", "picked_up"]},
- "then": 1,
- "else": 0
- }
- }},
+ "_park": {"$push": "$matches.parked"},
+ "_park_avg": {"$avg": {"$cond": {
+ "if": {"$eq": ["$matches.end_position", "parked"]},
+ "then": 1,
+ "else": 0
+ }}},
+ "_picked_up": {"$push": {"$add": [
+ "$matches.parked",
+ "$matches.picked_up"
+ ]}},
+ "_climb": {"$push": {"$add": [
+ "$matches.parked",
+ "$matches.picked_up",
+ "$matches.climbed"
+ ]}},
+ "_climb_avg": {"$avg": {"$cond": {
+ "if": {"$eq": ["$matches.end_position", "climbed"]},
+ "then": 1,
+ "else": 0
+ }}},
+ "_end_position_avg": {"$avg": {"$add": [
+ "$matches.parked",
+ "$matches.climbed"
+ ]}},
// Comments
"600_off_comments": {"$push": {
"$cond": {
@@ -215,27 +298,54 @@
// Combine some fields
{"$addFields": {
+ "201_auton": {
+ "_sort": "$_auton_avg",
+ // Graph properties
+ "_name": "auton",
+ "_min": 0,
+ "_max": 15,
+ // Lines
+ "1 Baseline": "$_auton_crossed_baseline",
+ "2 Exchange": "$_auton_exchange",
+ "3 Switch": "$_auton_switch",
+ "4 Scale": "$_auton_scale",
+ // Strings
+ "1 Average Score": "$_auton_avg",
+ "2 Baseline %": "$_auton_crossed_baseline_avg",
+ "3 Exchange %": "$_auton_exchange_avg",
+ "4 Switch %": "$_auton_switch_avg",
+ "5 Scale %": "$_auton_scale_avg"
+ },
"301_cubes": {
"_sort": "$_cube_avg",
+ // Graph properties
+ "_name": "cubes",
+ "_min": 0,
+ "_max": "$_cube_max",
// Lines
- "Exchange": "$_exchange",
- "Own Switch": "$_switch_own",
- "Opp Switch": "$_switch_opponent",
- "Scale": "$_scale",
+ "1 Exchange": "$_exchange",
+ "2 Own Switch": "$_switch_own",
+ "3 Scale": "$_scale",
+ "4 Opp Switch": "$_switch_opponent",
// Strings
- "Minimum": "$_cube_min",
- "Average": "$_cube_avg",
- "Maximum": "$_cube_max"
+ "1 Cubes Minimum": "$_cube_min",
+ "2 Cubes Average": "$_cube_avg",
+ "3 Cubes Maximum": "$_cube_max"
},
"500_end_game": {
- "_sort": "$_climb_avg",
+ "_sort": "$_end_position_avg",
+ // Graph properties
+ "_name": "end_game",
+ "_min": 0,
+ "_max": 30,
// Lines
- "Park": "$_park",
- "Climb": "$_climb",
- "Picked Up": "$_picked_up",
+ "1 Park": "$_park",
+ "2 Picked Up": "$_picked_up",
+ "3 Climb": "$_climb",
// Stirngs
- "Park Average": "$_park_avg",
- "Climb Average": "$_climb_avg"
+ "1 Average Score": "$_end_position_avg",
+ "2 Park %": "$_park_avg",
+ "3 Climb %": "$_climb_avg"
}
}}
]
diff --git a/www/macros.html b/www/macros.html
index b8ece94..14e6252 100644
--- a/www/macros.html
+++ b/www/macros.html
@@ -215,14 +215,13 @@