mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-15 08:41:01 +00:00
Merge branch 'master' into axel-usermanagement
This commit is contained in:
commit
dd4a49bcec
5 files changed
+27
-10
No files matched your search
@@ -0,0 +1,16 @@
|
||||
# Big Data - Amount of data processed by the SAP Sailing Analytics
|
||||
|
||||
Amount of data processed by the SAP Sailing Analytics during events.
|
||||
|
||||
## Kieler Woche 2014
|
||||
|
||||
- 13,836,495 GPS fixes with position, speed and course (996,227,640 bytes of memory)
|
||||
- 6,617,218 wind measurements with position, speed, course and heading of the unit, and speed and direction of the wind (370,564,208 bytes of memory)
|
||||
- 286,392 maneuvers analyzed (13,764,816 bytes or memory)
|
||||
|
||||
## 505 Worlds 2014
|
||||
|
||||
- 9,012,271 GPS fixes with position, speed and course (648,883,512 bytes of memory)
|
||||
- 1,036,846 wind measurements with position, speed, course and heading of the unit, and speed and direction of the wind (58,063,376 bytes of memory)
|
||||
- 205,532 maneuvers analyzed (9,865,536 bytes or memory)
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
# Tracking App API v1 Draft
|
||||
|
||||
## General
|
||||
|
||||
This is a design for the REST API to be used by the iOS and Android tracking apps.
|
||||
|
||||
## Event Data
|
||||
|
||||
### Path
|
||||
|
||||
http://sapsailing.com/b964b0
|
||||
|
||||
A shortened URL is used. This URL is embedded in the QR code. In case a user does not have a QR code, she can manually enter the URL into the app.
|
||||
|
||||
Note that a unique URL needs to be defined per competitor and event.
|
||||
|
||||
### Verb
|
||||
|
||||
GET
|
||||
|
||||
### Response
|
||||
|
||||
{
|
||||
"serverUrl" : "http://ec2-54-171-89-140.eu-west-1.compute.amazonaws.com:8888"
|
||||
"event" : {
|
||||
"eventId" : "123",
|
||||
"eventTitle" : "Kieler Woche",
|
||||
"eventStartDate" : 1414414481000,
|
||||
"eventEndDate" : 1414609200000,
|
||||
"eventDays": [
|
||||
{
|
||||
"eventDayStart" : "1414414481000",
|
||||
"eventDayEnd" : "1414436081000"
|
||||
},
|
||||
{
|
||||
"eventDayStart" : "1414497600000",
|
||||
"eventDayEnd" : "1414522800000"
|
||||
},
|
||||
{
|
||||
"eventDayStart" : "1414584000000",
|
||||
"eventDayEnd" : "1414609200000"
|
||||
},
|
||||
]
|
||||
}
|
||||
"competitor" : {
|
||||
"competitorId" : "250cf8b51c773f3f8dc8b4be867a9a02",
|
||||
"competitorName" : "Alster Segel Club",
|
||||
"competitorProfileImageUrl" : "http://s3.amazonaws.com/sapsailing/profile_images/68053af2923e00204c3ca7c6a3150cf7.jpeg"
|
||||
}
|
||||
}
|
||||
|
||||
**serverUrl** This is the endpoint to be used for all following REST requests.
|
||||
|
||||
**eventDays** An event can be held for several days. This array contains all start and end times of an event day. This is used to remind a user to turn tracking on or off (in order to save battery).
|
||||
|
||||
### Push Notifications
|
||||
|
||||
Event data can be updated via push notifications. These are limited on iOS to 256 bytes (not characters). For this reason, on receiving a push notification, the app must GET the event data.
|
||||
|
||||
## Check-In
|
||||
|
||||
After the user has received the event data with the short URL, the smartphone is mapped to a competitor.
|
||||
|
||||
_Question: What should be done if a second device is mapped to competitor?_
|
||||
|
||||
### Path
|
||||
|
||||
/event/{event_id}/competitor/{competitor_id}/device
|
||||
|
||||
### Verb
|
||||
|
||||
POST
|
||||
|
||||
### Request
|
||||
|
||||
{
|
||||
"deviceUdid" : "202cb962ac59075b964b07152d234b70",
|
||||
"deviceType" : "ios",
|
||||
"pushDeviceId" : "0f744707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bbad78"
|
||||
}
|
||||
|
||||
**deviceUdid** A UDID generated by device, generated on first run.
|
||||
|
||||
**deviceType** Either `android` or `ios`. Needed for selecting correct push notification service.
|
||||
|
||||
**pushDeviceId** On Android the GCM regId, on iOS the APNS push token. This is needed for sending push notifications to the device.
|
||||
|
||||
## Upload Profile Image
|
||||
|
||||
An image can be uploaded per competitor and event.
|
||||
|
||||
### Path
|
||||
|
||||
/event/{event_id}/competitor/{competitor_id}/profile_image
|
||||
|
||||
### Verb
|
||||
|
||||
POST
|
||||
|
||||
### Request
|
||||
|
||||
Multipart upload with part `image` containing JPEG image 80%, max dimension 1200px.
|
||||
|
||||
### Response
|
||||
|
||||
{
|
||||
"profileImageUrl" : "http://s3.amazonaws.com/sapsailing/profile_images/68053af2923e00204c3ca7c6a3150cf7.jpeg"
|
||||
}
|
||||
|
||||
**profileImageUrl** URL of uploaded image.
|
||||
|
||||
## Tracking Status
|
||||
|
||||
As general information, the tracking status of the smartphone is sent.
|
||||
|
||||
### Path
|
||||
|
||||
/event/{event_id}/competitor/{competitor_id}/tracking_status
|
||||
|
||||
### Verb
|
||||
|
||||
POST
|
||||
|
||||
### Request
|
||||
|
||||
{
|
||||
"timeStamp" : "14144158370000",
|
||||
"status" : "start"
|
||||
}
|
||||
|
||||
**status** Either `start` or `stop`.
|
||||
|
||||
## Send Location
|
||||
|
||||
The main data sent by the app.
|
||||
|
||||
### Path
|
||||
|
||||
/event/{event_id}/competitor/{competitor_id}/location
|
||||
|
||||
### Verb
|
||||
|
||||
POST
|
||||
|
||||
### Request
|
||||
|
||||
{
|
||||
"timestamp" : "14144160080000",
|
||||
"latitude" : "54.325246",
|
||||
"longitude" : "10.148556",
|
||||
"speed" : "3.61",
|
||||
"course" : "258.11",
|
||||
}
|
||||
|
||||
**speed** Speed over ground in meters per second.
|
||||
|
||||
**course** Heading in degrees.
|
||||
|
||||
### Web Sockets
|
||||
|
||||
Note that locations should be sent via web socket instead of HTTP POST in order to speed up communication. POST requests can be used as a fallback in case web sockets aren't available.
|
||||
|
||||
## Bulk Upload Locations
|
||||
|
||||
Locations should be sent live during an event. In case of missing network, locations are stored to the device and uploaded to the server later for analysis.
|
||||
|
||||
As this could be a lot of data, GZIP compression is a must. Bulk uploads should be chunked, e.g. per day or per 1,000 locations.
|
||||
|
||||
### Path
|
||||
|
||||
/event/{event_id}/competitor/{competitor_id}/location_bulk
|
||||
|
||||
### Verb
|
||||
|
||||
POST
|
||||
|
||||
### Request
|
||||
|
||||
{
|
||||
"locations" : [
|
||||
{
|
||||
"timestamp" : "14144160080000",
|
||||
"latitude" : "54.325246",
|
||||
"longitude" : "10.148556",
|
||||
"speed" : "3.61",
|
||||
"course" : "258.11",
|
||||
},
|
||||
{
|
||||
"timestamp" : "14144168490000",
|
||||
"latitude" : "55.12456",
|
||||
"longitude" : "8.03456",
|
||||
"speed" : "5.1",
|
||||
"course" : "14.2",
|
||||
},
|
||||
...
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,313 @@
|
||||
# Tracking App API
|
||||
This document describes the API used by the tracking smartphone apps.
|
||||
|
||||
## Device Mapping
|
||||
Following POST call maps smartphones to competitors.
|
||||
|
||||
### Verb
|
||||
|
||||
POST
|
||||
|
||||
### Path
|
||||
|
||||
/sailingserver/rc/racelog
|
||||
?leaderboard=Guy%27s+Regatta
|
||||
&raceColumn=M1
|
||||
&fleet=Default
|
||||
&clientuuid=92669a6c-72c9-46d2-a815-f51ff15a4369
|
||||
|
||||
#### Query Parameters
|
||||
|
||||
Query parameters are required and are encoded in QR code.
|
||||
|
||||
`clientuuid` ???
|
||||
|
||||
### Request Body
|
||||
|
||||
{
|
||||
"timestamp": 1413460233257,
|
||||
"id": "c72eabea-f456-4b29-9ba0-dadd06f5a179",
|
||||
"passId": 0, ***IS THIS NEEDED?***
|
||||
"fromMillis": 1413459900000,
|
||||
"@class": "DeviceCompetitorMappingEvent",
|
||||
"createdAt": 1413460233258,
|
||||
"item": {
|
||||
"id": "da815c7f-c935-44f5-b01d-20b750ce75ab",
|
||||
"nationality": "", ***IS THIS NEEDED?***
|
||||
"displayColor": null, ***IS THIS NEEDED?***
|
||||
"idtype": "java.util.UUID",
|
||||
"name": null, ***IS THIS NEEDED?***
|
||||
"nationalityISO3": "", ***IS THIS NEEDED?***
|
||||
"sailID": "", ***IS THIS NEEDED?***
|
||||
"nationalityISO2": "" ***IS THIS NEEDED?***
|
||||
},
|
||||
"authorName": "Tracking App",
|
||||
"competitors": [ ], ***IS THIS NEEDED?***
|
||||
"device": {
|
||||
"stringRepresentation": "147d8230-4db0-11e4-916c-0800200c9a66",
|
||||
"id": "147d8230-4db0-11e4-916c-0800200c9a66",
|
||||
"type": "smartphoneUUID"
|
||||
},
|
||||
"authorPriority": 0, ***IS THIS NEEDED?***
|
||||
"toMillis": 1413460500000
|
||||
}
|
||||
|
||||
### Response Body
|
||||
|
||||
[
|
||||
{
|
||||
"@class": "RaceLogStartProcedureChangedEvent",
|
||||
"id": "1e76925c-6518-434c-8d43-f5abf97154bf",
|
||||
"createdAt": 1413794205930,
|
||||
"timestamp": 1413794205905,
|
||||
"passId": 0,
|
||||
"competitors": [],
|
||||
"authorName": "Shore",
|
||||
"authorPriority": 4,
|
||||
"startProcedureType": "RRS26"
|
||||
},
|
||||
{
|
||||
"@class": "RaceLogStartTimeEvent",
|
||||
"id": "978701be-d087-4ac1-a263-db2d7059e5d8",
|
||||
"createdAt": 1413794205931,
|
||||
"timestamp": 1413794205905,
|
||||
"passId": 0,
|
||||
"competitors": [],
|
||||
"authorName": "Shore",
|
||||
"authorPriority": 4,
|
||||
"nextStatus": "SCHEDULED",
|
||||
"startTime": 1413794160000
|
||||
},
|
||||
{
|
||||
"@class": "DenoteForTrackingEvent",
|
||||
"id": "f332a53b-db8c-4e22-b250-042400e08c9a",
|
||||
"createdAt": 1413460016871,
|
||||
"timestamp": 1413460016869,
|
||||
"passId": 0,
|
||||
"competitors": [],
|
||||
"authorName": "com.sap.sailing.server.RacingEventService",
|
||||
"authorPriority": 1,
|
||||
"raceName": "Guy's Regatta M1 Default",
|
||||
"boatClass": "Small",
|
||||
"raceId": "dee82eb7-4d0f-4d1b-b834-9d1faa6b2517"
|
||||
},
|
||||
{
|
||||
"@class": "RegisterCompetitorEvent",
|
||||
"id": "f381d118-3344-41d3-bd47-4a2beb206d30",
|
||||
"createdAt": 1413460067296,
|
||||
"timestamp": 1413460067294,
|
||||
"passId": 0,
|
||||
"competitors": [
|
||||
{
|
||||
"idtype": "java.util.UUID",
|
||||
"id": "da815c7f-c935-44f5-b01d-20b750ce75ab",
|
||||
"name": "Competitor A",
|
||||
"displayColor": null,
|
||||
"sailID": "A",
|
||||
"nationality": "",
|
||||
"nationalityISO2": "",
|
||||
"nationalityISO3": ""
|
||||
}
|
||||
],
|
||||
"authorName": "com.sap.sailing.server.RacingEventService",
|
||||
"authorPriority": 1
|
||||
},
|
||||
{
|
||||
"@class": "RegisterCompetitorEvent",
|
||||
"id": "f7e6da48-d245-4615-8cbb-f7b4a96c7566",
|
||||
"createdAt": 1413460067298,
|
||||
"timestamp": 1413460067297,
|
||||
"passId": 0,
|
||||
"competitors": [
|
||||
{
|
||||
"idtype": "java.util.UUID",
|
||||
"id": "9c09ad1a-e05c-45d2-8b08-b8a6f4b03004",
|
||||
"name": "Competitor B",
|
||||
"displayColor": null,
|
||||
"sailID": "B",
|
||||
"nationality": "",
|
||||
"nationalityISO2": "",
|
||||
"nationalityISO3": ""
|
||||
}
|
||||
],
|
||||
"authorName": "com.sap.sailing.server.RacingEventService",
|
||||
"authorPriority": 1
|
||||
},
|
||||
{
|
||||
"@class": "DefineMarkEvent",
|
||||
"id": "87b347c8-ad57-47ca-9b67-2fe01ac72e3f",
|
||||
"createdAt": 1413461050887,
|
||||
"timestamp": 1413461050886,
|
||||
"passId": 0,
|
||||
"competitors": [],
|
||||
"authorName": "com.sap.sailing.server.RacingEventService",
|
||||
"authorPriority": 1,
|
||||
"mark": {
|
||||
"@class": "Mark",
|
||||
"name": "Buoy 1",
|
||||
"id": "a8f20289-0246-438f-a4de-9bc1c30b9fc3",
|
||||
"color": "",
|
||||
"pattern": "",
|
||||
"shape": "CONICAL",
|
||||
"type": "BUOY"
|
||||
}
|
||||
},
|
||||
{
|
||||
"@class": "DefineMarkEvent",
|
||||
"id": "d48d2e37-496b-48b8-8fb6-5233638c018b",
|
||||
"createdAt": 1413461060946,
|
||||
"timestamp": 1413461060946,
|
||||
"passId": 0,
|
||||
"competitors": [],
|
||||
"authorName": "com.sap.sailing.server.RacingEventService",
|
||||
"authorPriority": 1,
|
||||
"mark": {
|
||||
"@class": "Mark",
|
||||
"name": "Buoy 2",
|
||||
"id": "a8a84cf8-ad78-4db1-a593-91f43ced523a",
|
||||
"color": "",
|
||||
"pattern": "",
|
||||
"shape": "CONICAL",
|
||||
"type": "BUOY"
|
||||
}
|
||||
},
|
||||
{
|
||||
"@class": "RaceLogCourseDesignChangedEvent",
|
||||
"id": "f4e0d5c6-494c-4492-a09d-1665baf385ca",
|
||||
"createdAt": 1413461086484,
|
||||
"timestamp": 1413461086483,
|
||||
"passId": 0,
|
||||
"competitors": [],
|
||||
"authorName": "com.sap.sailing.server.RacingEventService",
|
||||
"authorPriority": 1,
|
||||
"courseDesign": {
|
||||
"name": "Course for Guy's Regatta - M1 - Default",
|
||||
"waypoints": [
|
||||
{
|
||||
"name": "Buoy 1",
|
||||
"passingInstruction": "None",
|
||||
"controlPoint": {
|
||||
"@class": "Mark",
|
||||
"name": "Buoy 1",
|
||||
"id": "a8f20289-0246-438f-a4de-9bc1c30b9fc3",
|
||||
"color": "",
|
||||
"pattern": "",
|
||||
"shape": "CONICAL",
|
||||
"type": "BUOY"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Buoy 2",
|
||||
"passingInstruction": "None",
|
||||
"controlPoint": {
|
||||
"@class": "Mark",
|
||||
"name": "Buoy 2",
|
||||
"id": "a8a84cf8-ad78-4db1-a593-91f43ced523a",
|
||||
"color": "",
|
||||
"pattern": "",
|
||||
"shape": "CONICAL",
|
||||
"type": "BUOY"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"@class": "DeviceCompetitorMappingEvent",
|
||||
"id": "cf5995a4-6cca-4cca-a6cc-2357a32bb436",
|
||||
"createdAt": 1413463043674,
|
||||
"timestamp": 1413463043674,
|
||||
"passId": 0,
|
||||
"competitors": [],
|
||||
"authorName": "Tracking App",
|
||||
"authorPriority": 0,
|
||||
"fromMillis": 1413461400000,
|
||||
"toMillis": 1413464100000,
|
||||
"item": {
|
||||
"idtype": "java.util.UUID",
|
||||
"id": "da815c7f-c935-44f5-b01d-20b750ce75ab",
|
||||
"name": "Competitor A",
|
||||
"displayColor": null,
|
||||
"sailID": "A",
|
||||
"nationality": "",
|
||||
"nationalityISO2": "",
|
||||
"nationalityISO3": ""
|
||||
},
|
||||
"device": {
|
||||
"type": "smartphoneUUID",
|
||||
"id": "147d8230-4db0-11e4-916c-0800200c9a66",
|
||||
"stringRepresentation": "147d8230-4db0-11e4-916c-0800200c9a66"
|
||||
}
|
||||
},
|
||||
{
|
||||
"@class": "RevokeEvent",
|
||||
"id": "481e710e-9f8d-4222-a4ae-ec4b15b7a8bd",
|
||||
"createdAt": 1413793852767,
|
||||
"timestamp": 1413793852767,
|
||||
"passId": 0,
|
||||
"competitors": [],
|
||||
"authorName": "com.sap.sailing.server.RacingEventService",
|
||||
"authorPriority": 0,
|
||||
"revokedEventId": "f332a53b-db8c-4e22-b250-042400e08c9a"
|
||||
},
|
||||
{
|
||||
"@class": "DenoteForTrackingEvent",
|
||||
"id": "740701f2-639b-4bfb-8f72-06093b0ac1e8",
|
||||
"createdAt": 1413793857143,
|
||||
"timestamp": 1413793857143,
|
||||
"passId": 0,
|
||||
"competitors": [],
|
||||
"authorName": "com.sap.sailing.server.RacingEventService",
|
||||
"authorPriority": 0,
|
||||
"raceName": "Guy's Regatta M1 Default",
|
||||
"boatClass": "Small",
|
||||
"raceId": "8fd69b14-f9bf-46bc-8bda-def5814d8758"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
The response is a JSON array containing all events pertaining to leaderboard.
|
||||
_Is that correct?_
|
||||
|
||||
**@class**
|
||||
|
||||
`RaceLogStartProcedureChangedEvent` ???
|
||||
|
||||
`RaceLogStartTimeEvent` ???
|
||||
|
||||
`DenoteForTrackingEvent` ???
|
||||
|
||||
`RegisterCompetitorEvent` Add new competitor.
|
||||
|
||||
`DefineMarkEvent` Add new mark (e.g. buoy).
|
||||
|
||||
`RaceLogCourseDesignChangedEvent` Called when defining course with marks.
|
||||
|
||||
`DeviceCompetitorMappingEvent` Triggered when device and competitor are mapped.
|
||||
|
||||
`RevokeEvent` Called e.g. when deleting a device / competitor mapping.
|
||||
|
||||
## GPSFix
|
||||
|
||||
### Verb
|
||||
|
||||
POST
|
||||
|
||||
### Path
|
||||
|
||||
/tracking/recordFixesFlatJson
|
||||
|
||||
### Body
|
||||
|
||||
{
|
||||
"bearingDeg":48,
|
||||
"timeMillis":1414504349713,
|
||||
"speedMperS":0,
|
||||
"lonDeg":9.9650613,
|
||||
"deviceUuid":"147d8230-4db0-11e4-916c-0800200c9a66",
|
||||
"latDeg":53.5510491
|
||||
}
|
||||
|
||||
### Response
|
||||
|
||||
200
|
||||
Reference in new issue
Block a user