217 lines
8.8 KiB
JSON
217 lines
8.8 KiB
JSON
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"$id": "https://github.com/bincio-activity/bincio/blob/main/schema/bas-v1.schema.json",
|
|
"title": "BincioActivity Schema v1.0",
|
|
"description": "Schema for BincioActivity (BAS) data files.",
|
|
"$defs": {
|
|
"sport": {
|
|
"type": "string",
|
|
"enum": ["cycling", "running", "hiking", "walking", "swimming", "skiing", "other"]
|
|
},
|
|
"sub_sport": {
|
|
"type": ["string", "null"],
|
|
"enum": ["road", "mountain", "gravel", "indoor", "trail", "track", "nordic", "alpine", "open_water", "pool", null]
|
|
},
|
|
"privacy": {
|
|
"type": "string",
|
|
"enum": ["public", "blur_start", "no_gps", "private"]
|
|
},
|
|
"source": {
|
|
"type": ["string", "null"],
|
|
"enum": [
|
|
"strava_export", "garmin_connect", "wahoo", "komoot",
|
|
"gpx_file", "fit_file", "tcx_file", "karoo", "manual", null
|
|
]
|
|
},
|
|
"latlng": {
|
|
"type": ["array", "null"],
|
|
"items": { "type": "number" },
|
|
"minItems": 2,
|
|
"maxItems": 2
|
|
},
|
|
"bbox": {
|
|
"type": ["array", "null"],
|
|
"items": { "type": "number" },
|
|
"minItems": 4,
|
|
"maxItems": 4,
|
|
"description": "[min_lon, min_lat, max_lon, max_lat]"
|
|
},
|
|
"mmp": {
|
|
"type": ["array", "null"],
|
|
"description": "Mean Maximal Power curve — [[duration_s, avg_watts], ...]",
|
|
"items": {
|
|
"type": "array",
|
|
"items": { "type": "integer" },
|
|
"minItems": 2,
|
|
"maxItems": 2
|
|
}
|
|
},
|
|
"best_efforts": {
|
|
"type": ["array", "null"],
|
|
"description": "Best efforts by distance — [[distance_km, time_s], ...]",
|
|
"items": {
|
|
"type": "array",
|
|
"items": { "type": "number" },
|
|
"minItems": 2,
|
|
"maxItems": 2
|
|
}
|
|
},
|
|
"lap": {
|
|
"type": "object",
|
|
"required": ["index", "started_at", "duration_s"],
|
|
"properties": {
|
|
"index": { "type": "integer", "minimum": 0 },
|
|
"started_at": { "type": "string", "format": "date-time" },
|
|
"duration_s": { "type": ["integer", "null"] },
|
|
"distance_m": { "type": ["number", "null"] },
|
|
"elevation_gain_m": { "type": ["number", "null"] },
|
|
"avg_speed_kmh": { "type": ["number", "null"] },
|
|
"avg_hr_bpm": { "type": ["integer", "null"] },
|
|
"avg_power_w": { "type": ["integer", "null"] }
|
|
},
|
|
"additionalProperties": false
|
|
},
|
|
"timeseries": {
|
|
"type": "object",
|
|
"required": ["t"],
|
|
"properties": {
|
|
"t": { "type": "array", "items": { "type": "integer" } },
|
|
"lat": { "type": ["array", "null"], "items": { "type": ["number", "null"] } },
|
|
"lon": { "type": ["array", "null"], "items": { "type": ["number", "null"] } },
|
|
"elevation_m": { "type": "array", "items": { "type": ["number", "null"] } },
|
|
"speed_kmh": { "type": "array", "items": { "type": ["number", "null"] } },
|
|
"hr_bpm": { "type": "array", "items": { "type": ["integer", "null"] } },
|
|
"cadence_rpm": { "type": "array", "items": { "type": ["integer", "null"] } },
|
|
"power_w": { "type": "array", "items": { "type": ["integer", "null"] } },
|
|
"temperature_c": { "type": "array", "items": { "type": ["number", "null"] } }
|
|
},
|
|
"additionalProperties": false
|
|
},
|
|
"activity_summary": {
|
|
"type": "object",
|
|
"required": ["id", "title", "sport", "started_at", "privacy"],
|
|
"properties": {
|
|
"id": { "type": "string", "minLength": 1 },
|
|
"title": { "type": "string" },
|
|
"sport": { "$ref": "#/$defs/sport" },
|
|
"sub_sport": { "$ref": "#/$defs/sub_sport" },
|
|
"started_at": { "type": "string", "format": "date-time" },
|
|
"distance_m": { "type": ["number", "null"] },
|
|
"duration_s": { "type": ["integer", "null"] },
|
|
"moving_time_s": { "type": ["integer", "null"] },
|
|
"elevation_gain_m": { "type": ["number", "null"] },
|
|
"avg_speed_kmh": { "type": ["number", "null"] },
|
|
"max_speed_kmh": { "type": ["number", "null"] },
|
|
"avg_hr_bpm": { "type": ["integer", "null"] },
|
|
"max_hr_bpm": { "type": ["integer", "null"] },
|
|
"avg_cadence_rpm": { "type": ["integer", "null"] },
|
|
"avg_power_w": { "type": ["integer", "null"] },
|
|
"mmp": { "$ref": "#/$defs/mmp" },
|
|
"best_efforts": { "$ref": "#/$defs/best_efforts" },
|
|
"best_climb_m": { "type": ["number", "null"] },
|
|
"source": { "$ref": "#/$defs/source" },
|
|
"privacy": { "$ref": "#/$defs/privacy" },
|
|
"detail_url": { "type": ["string", "null"] },
|
|
"track_url": { "type": ["string", "null"] },
|
|
"preview_coords": {
|
|
"type": ["array", "null"],
|
|
"description": "Simplified track preview — [[lon, lat], ...] for card thumbnails",
|
|
"items": {
|
|
"type": "array",
|
|
"items": { "type": "number" },
|
|
"minItems": 2,
|
|
"maxItems": 2
|
|
}
|
|
}
|
|
},
|
|
"additionalProperties": false
|
|
}
|
|
},
|
|
"oneOf": [
|
|
{
|
|
"title": "index.json",
|
|
"type": "object",
|
|
"required": ["bas_version", "owner", "generated_at", "activities"],
|
|
"properties": {
|
|
"bas_version": { "type": "string", "const": "1.0" },
|
|
"owner": {
|
|
"type": "object",
|
|
"required": ["handle", "display_name"],
|
|
"properties": {
|
|
"handle": { "type": "string", "minLength": 1 },
|
|
"display_name": { "type": "string" },
|
|
"avatar_url": { "type": ["string", "null"] }
|
|
},
|
|
"additionalProperties": false
|
|
},
|
|
"generated_at": { "type": "string", "format": "date-time" },
|
|
"shards": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"required": ["year", "url", "count"],
|
|
"properties": {
|
|
"year": { "type": "integer" },
|
|
"url": { "type": "string" },
|
|
"count": { "type": "integer" }
|
|
},
|
|
"additionalProperties": false
|
|
}
|
|
},
|
|
"activities": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/$defs/activity_summary" }
|
|
}
|
|
},
|
|
"additionalProperties": false
|
|
},
|
|
{
|
|
"title": "activities/{id}.json",
|
|
"type": "object",
|
|
"required": [
|
|
"bas_version", "id", "title", "sport", "started_at",
|
|
"privacy", "laps", "timeseries", "custom"
|
|
],
|
|
"properties": {
|
|
"bas_version": { "type": "string", "const": "1.0" },
|
|
"id": { "type": "string", "minLength": 1 },
|
|
"title": { "type": "string" },
|
|
"description": { "type": ["string", "null"] },
|
|
"sport": { "$ref": "#/$defs/sport" },
|
|
"sub_sport": { "$ref": "#/$defs/sub_sport" },
|
|
"started_at": { "type": "string", "format": "date-time" },
|
|
"distance_m": { "type": ["number", "null"] },
|
|
"duration_s": { "type": ["integer", "null"] },
|
|
"moving_time_s": { "type": ["integer", "null"] },
|
|
"elevation_gain_m": { "type": ["number", "null"] },
|
|
"elevation_loss_m": { "type": ["number", "null"] },
|
|
"avg_speed_kmh": { "type": ["number", "null"] },
|
|
"max_speed_kmh": { "type": ["number", "null"] },
|
|
"avg_hr_bpm": { "type": ["integer", "null"] },
|
|
"max_hr_bpm": { "type": ["integer", "null"] },
|
|
"avg_cadence_rpm": { "type": ["integer", "null"] },
|
|
"avg_power_w": { "type": ["integer", "null"] },
|
|
"max_power_w": { "type": ["integer", "null"] },
|
|
"gear": { "type": ["string", "null"] },
|
|
"device": { "type": ["string", "null"] },
|
|
"bbox": { "$ref": "#/$defs/bbox" },
|
|
"start_latlng": { "$ref": "#/$defs/latlng" },
|
|
"end_latlng": { "$ref": "#/$defs/latlng" },
|
|
"mmp": { "$ref": "#/$defs/mmp" },
|
|
"best_efforts": { "$ref": "#/$defs/best_efforts" },
|
|
"best_climb_m": { "type": ["number", "null"] },
|
|
"laps": { "type": "array", "items": { "$ref": "#/$defs/lap" } },
|
|
"timeseries": { "$ref": "#/$defs/timeseries" },
|
|
"source": { "$ref": "#/$defs/source" },
|
|
"source_file": { "type": ["string", "null"] },
|
|
"source_hash": { "type": ["string", "null"] },
|
|
"strava_id": { "type": ["string", "null"] },
|
|
"duplicate_of": { "type": ["string", "null"] },
|
|
"privacy": { "$ref": "#/$defs/privacy" },
|
|
"custom": { "type": "object" }
|
|
},
|
|
"additionalProperties": false
|
|
}
|
|
]
|
|
}
|