OAR+ WFL API

New endpoints

Get list of all OAR+ tracks

Gets list of track ids which are OAR+ capable

GET /api/oarplus

Headers:

Response:

[ "31267", "some_other_id" ]

Get OAR+ track details

Gets details of requested OAR+ track

GET /api/oarplus/{id}

Headers:

Response:

Verify OAR+ key

Veridies OAR+ track key

GET /api/oarplus/{id}/authentication

Headers:

Response:

Send OAR+ Catcher Car system checks

Stores OAR+ catcher Car system checks

POST /api/oarplus/{id}/catchercar/systemchecks

Headers:

Request body:

{ "id": "<tarck id>", "gpsChecked": true, "deviceModel": "<device model>", "devicePlatform": "<device platform>", "devicePlatformVersion": "<device platform version>", "beaconsCount": 2, "beaconsScanningCount": 2 }
public string Id { get; set; } public bool GpsChecked { get; set; } public string DeviceModel { get; set; } public string DevicePlatform { get; set; } public string DevicePlatformVersion { get; set; } public uint BeaconsCount { get; set; } public uint BeaconsScanningCount { get; set; } }
id: string; gpsChecked: boolean; deviceModel: string; devicePlatform: string; devicePlatformVersion: string; beaconsCount: number; beaconsScanningCount: number; }

Response:

Send OAR+ Catcher Car positions

Ingests OAR+ Catcher Car positions. Positions with invalid pairs of oarId and key will be discarded.

POST /api/oarplus/catchercar/positions

Headers:

Request body:

{ "location": [ { "coords": { "speed": 1, "longitude": 2, "latitude": 3, "altitude": 4, "accuracy": 5, "altitude_accuracy": 6, "heading": 7 }, "is_moving": true, "event": "motionchange", "odometer": 312.67, "uuid": "7dbda74f-74cf-4072-b958-c0a6f75298ab", "activity": { "type": "on_foot", "confidence": 100 }, "battery": { "level": 100, "is_charging": false }, "timestamp": "2020-01-23T14:16:25.164Z", "extras": { "oarId": "9d7c7c78a37d55fe3073f65a19ce2041846bb383", "key": "32167", "currentDeviation": 2.6 } }, { ... } ] }
public class PositionView { public class LocationData { public class ExtrasData { public string OarId { get; set; } public string Key { get; set; } public double CurrentDeviation { get; set; } } public class Coordinates { public double Speed { get; set; } public double Longitude { get; set; } public double Latitude { get; set; } public double Altitude { get; set; } public double Accuracy { get; set; } [JsonProperty("altitude_accuracy")] public double AltitudeAccuracy { get; set; } public double Heading { get; set; } } public class ActivityType { public string Type { get; set; } public int Confidence { get; set; } } public class BatteryStatus { public double Level { get; set; } [JsonProperty("is_charging")] public bool IsCharging { get; set; } } public Coordinates Coords { get; set; } [JsonProperty("is_moving")] public bool IsMoving { get; set; } public string Event { get; set; } public double Odometer { get; set; } public string Uuid { get; set; } public ActivityType Activity { get; set; } public BatteryStatus Battery { get; set; } public DateTime Timestamp { get; set; } public ExtrasData Extras { get; set; } } public LocationData[] Location { get; set; } }
interface ExtrasData { oarId: string; key: string; currentDeviation: number; } interface Coordinates { speed: number; longitude: number; latitude: number; altitude: number; accuracy: number; altitude_accuracy: number; heading: number; } interface ActivityType { type: string; confidence: number; } interface BatteryStatus { level: number; is_charging: boolean; } interface LocationData { coords: Coordinates; is_moving: boolean; event: string; odometer: number; uuid: string; activity: ActivityType; battery: BatteryStatus; timestamp: Date | string; extras: ExtrasData; } interface PositionView { location: LocationData[]; }

Response:

// 202 Accepted - request passed key validation and was ingested for further processing

Extensions to existing endpoints

Consider following C# class as example ones to which payload is deserialized. All fields can start from lowercase in JSON payload as deserialization rules can cope with that.

Positions

Position view model has been extended with following fields

public class ExtrasData { public string RunId { get; set; } + public string SegmentIdx { get; set; } + public int? SegmentRound { get; set; } + public string BeaconId { get; set; } + public string BeaconMajor { get; set; } + public string BeaconMinor { get; set; } + public string BeaconProximity { get; set; } }

Runs

Run view model was extended in following way:

Run creation request

public class CreateRunView { public string Id { get; set; } public string UserName { get; set; } public DateTime? Created { get; set; } public string Status { get; set; } public bool IsRaceday { get; set; } + public string OarPlusId { get; set; } + public string SegmentIdx { get; set; } + public int? SegmentRound { get; set; } + public double? SegmentGpsAccuracy { get; set; } + public string BeaconId { get; set; } + public string BeaconMajor { get; set; } + public string BeaconMinor { get; set; } + public string BeaconProximity { get; set; } + public string CatchMethod { get; set; } }

Run update/finish request

public class UpdateRunView { public DateTime? Created { get; set; } public DateTime? End { get; set; } public double? Distance { get; set; } public double? MeanSpeed { get; set; } public string Status { get; set; } public bool? IsRaceday { get; set; } public string UserName { get; set; } + public string OarPlusId { get; set; } + public string SegmentIdx { get; set; } + public int? SegmentRound { get; set; } + public double? SegmentGpsAccuracy { get; set; } + public string BeaconId { get; set; } + public string BeaconMajor { get; set; } + public string BeaconMinor { get; set; } + public string BeaconProximity { get; set; } + public string CatchMethod { get; set; } }