Name | velotrain JSON |
Version |
1.0.3
JSON |
| download |
home_page | None |
Summary | Velodrome transponder training timing |
upload_time | 2025-07-23 01:59:47 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.11 |
license | None |
keywords |
velodrome
transponder
timing
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# velotrain
velotrain reads raw transponder passing information from a set
of up to 9 measurement points, filters the messages according
to track configuration parameters and then emits valid timing
measurements as JSON-encoded objects to MQTT.
## Operation
The velodrome is divided into a closed loop of timing sectors
by measurement points at each of the interesting offsets, for example:
- Finish line
- 200m Start
- Pursuit B
- Pursuit A
A rider is considered to be in a 'run' if their speed over any
configured sector (eg Finish line to 200m start) is between
configured values (default: 30 km/h to 90 km/h).
Passings emitted for a rider in a run will include any available
lap, half-lap, quarter-lap, 100 m, and 50 m splits.
Rider passings slower or faster than the configured limits are
considered isolated, and will be reported without splits.
Where possible, valid raw passings received out of order will be
corrected and re-ordered before being emitted. In the case that
an isolated raw passing violates the configured track ordering and
speed limits, it may be reported out of order.
For a Protime active/passive dual loop configuration, riders
will not be registered at all until they are moving faster than
about 30 km/h, no matter what software limits have been configured.
## Configuration
Track layout, system transponder ids and speed limits are configured
using a metarace jsonconfig entry with the section 'velotrain' and the
following keys:
- authkey: (string) reset authorisation string, default: null
- gate: (string) transponder ID for start gate, default: null
- gatedelay: (string) trigger delay for start gate, default: '0.075' _[1]_
- gatesrc: (string) channel start gate reports to eg 'C2', default: null
- laplen: (float) lap length in metres, default: 250.0
- maxspeed: (float) maximum sector speed in km/d, default: 90.0
- minspeed: (float) minimum sector speed in km/h, default: 38.0
- moto: (list) list of transponder IDs attached to motos, default: []
- trig: (string) transponder ID of sync trigger messages, default: '255'
- passlevel: (integer) minimum accepted passing level, default 40 _[2]_
- uaddr: (string) UDP host listen address, default ''
- uport: (integer) UDP host port, default: 2008
- bcast: (string) broadcast address for timing LAN,
default: '255.255.255.255'
- basetopic: (string) base topic for telegraph interface,
default: 'velotrain'
- sync: (string) channel of synchronisation master unit, default: null
- mingate: (float) minimum accepted speed in km/h over the
start gate sector, default: 9.0
- maxgate: (float) maximum accepted speed in km/h over the
start gate sector, default: 22.5
- dhi: (list) ['address', port] DHI port for Caprica scoreboard,
default: null
- dhiencoding: (string) text encoding for DHI messages, default: 'utf-8'
- mpseq: (list) ordering of channels on the track,
default: ['C1', 'C9', 'C4', 'C6', 'C3', 'C5', 'C7', 'C8', 'C2'] _[3]_
- mps: (dict) mapping of channel IDs to measurement point configs,
default: {} _[4]_
Configured measurement points divide the track into a closed loop of
timing sectors, with a set of splits at each measurement point.
Measurement point config entries have the following options, omitted keys
receive a default value:
- name: (string) visible name of the measurement point,
default: channel ID
- ip: (string) IP address of connected Protime decoder,
default: null _[4]_
- offset: (float) distance in metres from finish line to measurement
point, default: null
- half: (string) channel ID corresponding to a half lap before this unit,
default: null
- qtr: (string) channel ID corresponding to quarter lap before this unit,
default: null
- 200: (string) channel ID corresponding to 200 m before this unit,
default: null
- 100: (string) channel ID corresponding to 100 m before this unit,
default: null
- 50: (string) channel ID corresponding to 50 m before this unit,
default: null
Notes:
1. 0.075 seconds is LS transponder delay when triggered by
start gate release
2. Sets the 'level' option in all attached Protime decoder units
3. Default channel ordering matches trackmeet, all configured units
must appear once in this sequence, however the sequence may contain
more channels than are configured.
4. Measurement points require a non-null IP entry to be configured.
For use with foreign timers, set the IP to be an empty string: ''.
Refer to the sample velomon.json for an example setting
## Telegraph (MQTT) Interface
The topics below are relative to the configured basetopic (default:
'velotrain'), from the perspective of the velotrain process. For
all JSON encoded objects, invalid or unavailable properties will be
reported as null.
### passing (publish)
Issue filtered and accepted passing records. Passing records
are JSON encoded objects with the following properties:
- index : (integer) index of the passing record (reset to 0 each day)
- date: (string) Date of the passing formatted YYYY-MM-DD
- time: (string) Time of day of the passing formatted HH:MM:SS.dcm
- mpid: (integer) Measurement point ID 0 - 9
- refid: (string) Transponder ID or system passing ID 'gate', 'moto'
or 'marker'
- env: (list) [temperature, humidity, pressure] where each value
is a float value in units degrees Celsius, %rh, and hPa respectively
- moto: (string) Proximity to moto in seconds if drafted
- elap: (string) Elapsed time since last start gate or start of run
formatted HH:MM:SS.dc
- lap: (string) Time for the last full lap to the measurement point
- half: (string) Time for the last half lap to the measurement point
- qtr: (string) Time for the last quarter lap to the measurement point
- 200: (string) Time for the last 200m to the measurement point
- 100: (string) Time for the last 100m to the measurement point
- 50: (string) Time for the last 50m to the measurement point
- text: (string) Name of measurement point, or user-supplied text
for markers
Example: A moto passing over the 100m split at about 4:18pm
Topic: velotrain/passing
Payload: {"index": 108, "date": "2022-07-06",
"time": "16:18:32.300", "mpid": 5,
"refid": "moto", "env": [16.3, 55.0, 1015.0],
"moto": "0.00", "elap": "2:10.51",
"lap": "22.95", "half": null, "qtr": null,
"200": "18.32", "100": "9.07", "50": "4.52",
"text": "100m Split"}
### rawpass (publish)
Issue raw, unprocessed passing records as received from decoders. Raw
passing records are JSON encoded objects with the following properties:
- date: (string) Date of the raw passing formatted YYYY-MM-DD
- time: (string) Time of day of the passing formatted HH:MM:SS.dc
- rcv: (string) Time of day passing was received by host system,
formatted HH:MM:SS.dcm
- mpid: (integer) Measurement point ID 0 - 9
- refid: (string) Raw transponder ID
- env: (list) [temperature, humidity, pressure] where each value
is a float value in units degrees Celsius, %rh, and hPa respectively
- name: (string) Name of measurement point
- info: (string) Extra information provided by decoder
Example: The raw passing that might have generated the above moto passing
Topic: velotrain/rawpass
Payload: {"date": "2022-07-06", "env": [16.3, 55.0, 1015.0],
"refid": "125328", "mpid": 5,
"name": "100m Split", "time": "16:18:32.303",
"rcv": "16:18:32.459"}
### status (publish)
Issue system and measurement point status records at the top of each
minute. Status records are JSON encoded objects with the following properties:
- date: (string) Date of the status record formatted YYYY-MM-DD
- time: (string) Time of day status was issued formatted HH:MM:SS.dc
- offset: (string) Rough offset of system clock to UTC
- count: (integer) Count of passing records
- env: (list) [temperature, humidity, pressure] where each value
is a float value in units degrees Celsius, %rh, and hPa respectively
- gate: (string) Time of day of last gate trigger HH:MM:SS.dc
- battery: (list) List of transponder refids that have reported a low
battery warning since the last system reset
- info: (string) Status info, one of: 'running', 'resetting',
'error', 'offline' _[1]_
- units: (list) List of JSON encoded objects, each containing a measurement
point status:
- mpid: (integer) Measurement point ID
- name: (string) Measurement point name
- noise: (integer) Interference noise value 0 - 100. Values under
40 indicate normal operation. Larger values indicate interference.
- offset: (string) Unit clock offset from system time in seconds
formatted as [-]s.dcm
Notes:
1. Status info strings:
- running: Normal operation
- resetting: System reset in progress
- offline: velotrain was shutdown (date and time fields
indicate when shutdown ocurred)
- error: Network connection lost, server status temporarily
unavailable
Example: Status update
Topic: velotrain/status
Payload: {"date": "2022-07-07", "time": "23:04:00.15",
"offset": "0.211", "env": [13.1, 62.0, 1013.0],
"count": 123, "gate": null, "battery": ["123876"],
"info": "running",
"units": [
{"mpid": 1, "name": "Finish",
"noise": 20, "offset": "0.000"},
{"mpid": 2, "name": "Pursuit A",
"noise": 32, "offset": "0.025"},
{"mpid": 3, "name": "Pursuit B",
"noise": 15, "offset": "0.005"},
{"mpid": 4, "name": "200m Start",
"noise": 32, "offset": "0.005"},
{"mpid": 5, "name": "100m Split",
"noise": 14, "offset": "-0.008"},
{"mpid": 6, "name": "50m Split",
"noise": 27, "offset": "0.064"},
{"mpid": 8, "name": "150m Split",
"noise": 18, "offset": "-0.020"}
]}
### request (subscribe)
Receive requests for replay of passing records to the nominated serial,
filtered according to the JSON encoded request object:
- serial (string) optional request serial, appended to replay topic
- index (list) optional [first, last] limit response to include
passings from index first to index last.
- time (list) optional [starttime, endtime] limit response to
passings between starttime and endtime strings formatted HH:MM:SS.dc
- mpid (list) optional [mpid, ...] include only the nominated
mpids in replay
- refid (list) optional [refid, ...] include only nominated
transponder ids in response
- marker (list) optional [marker, ...] include only passings
following the nominated marker strings
Example: Request all passings, publish to default topic
Topic: velotrain/request
Payload: b''
Reply topic: velotrain/replay
Payload: [{"index":0, ...}, {"index":1, ...}, ...]
Request a replay of passing 254 to 'xxfd'
Topic: velotrain/request
Payload: {"serial": "xxfd", "index": 254}
Reply topic: velotrain/replay/xxfd
Payload: [{"index": 254, ... }]
Replay passings from transponder '123456' and start gate after midday
before index 10000 and that occur following manual markers 'one' and 'two'
Topic: velotrain/request
Payload: {"refid": ["123456", "gate"],
"time": ["12:00:00", null],
"index": [null, 10000],
"marker": ["one", "two"]}
Reply topic: velotrain/replay
Payload: [{"index":12, "text":"one","mpid":0, ...}, ...]
### replay[/serial] (publish)
Issues a JSON encoded list of passing objects, filtered according
to a provided request.
### marker (subscribe)
Insert the provided utf-8 encoded unicode payload as a manual marker
passing. If the supplied payload is empty, 'marker' is used.
Example: Insert an emoticon '🤷' (U+1F937) at the current time of day
Topic: velotrain/marker
Payload: b'\xf0\x9f\xa4\xb7'
Reply topic: velotrain/passing
Payload: {"index": 143, "date": "2022-07-06",
"time": "12:09:13.33", "mpid": 0,
"refid": "marker", "env": null, "moto": null,
"elap": null, "lap": null, "half": null,
"qtr": null, "200": null, "100": null,
"50": null, "text": "\ud83e\udd37"}
### reset (subscribe)
Start a reset process, authorised by the provided utf-8 encoded
authkey (config option 'authkey'). For a Tag Heuer Protime decoder network,
this process may take up to three minutes to complete. For systems
with foreign timers, this request will just clear passing records.
Example: Request reset process using authkey 'qwertyuiop'
Topic: velotrain/reset
Payload: b'qwertyuiop'
### timer (subscribe)
Receive raw passing data from a foreign timing device. Foreign timing
records are utf-8 encoded unicode strings in the format:
INDEX;SOURCE;CHANNEL;REFID;TOD
Where the fields are as follows:
- INDEX: ignored
- SOURCE: measurement point id as a metarace timing channel
eg: 'C1', 'C2', 'C3', ... 'C9'
- CHANNEL: ignored
- REFID: transponder ID eg '123456'
- TOD: time of day of passing as string eg: '1:23.456', 'now', '12:34:56.789'
Note: velotrain expects each attached decoder to be triggered from a
reference clock at the top of each minute, and to report a passing with
refid matching config option 'trig' (default: '255').
For systems that maintain synchronisation via a
different mechanism, a fake top of minute trigger can be sent
with the channel of the configured sync source (config key 'sync')
at any time using the trig refid and a TOD of '0'.
Example: Insert a passing for transponder '123456' on mpid 3 at the current time
Topic: velotrain/timer
Payload: b';C3;;123456;now'
Reply topic: velotrain/rawpass
Payload: {"date": "2022-07-06", "env": null,
"refid": "123456", "mpid": 3, "name": "Pursuit B",
"time": "12:23:35.879", "rcv": "12:23:35.879"}
Fake a top-of-minute message to mpid 1, using the default trig:
Topic: velotrain/timer
Payload: b';C1;;255;0'
Reply topic: velotrain/rawpass
Payload: {"date": "2022-07-06", "env": null,
"refid": "255", "mpid": 1, "name": "Finish",
"time": "00:00:00.000", "rcv": "12:25:06.090"}
Insert a passing for transponder '123456' on mpid 4, 10.2345 seconds after 2 pm:
Topic: velotrain/timer
Payload: b';C4;;123456;14:00:10.2345'
Reply topic: velotrain/rawpass
Payload: {"date": "2022-07-06", "env": null,
"refid": "123456", "mpid": 4, "name": "200m Start",
"time": "14:00:10.234", "rcv": "12:27:38.988"}
### resetunit (subscribe)
Attempt to stop, start and re-synchronise the single measurement
point unit specified in the message body. Note that the synchronisation
master may not be re-started this way.
Example: Reset unit "C4"
Topic: velotrain/resetunit
Payload: b'C4'
## Requirements
- metarace (>= 2.1.14)
- ypmeteo
## Installation
$ pip3 install velotrain
To use as a systemd service, edit the provided unit file
and copy to /etc/systemd/system, then enable with:
# systemctl enable velotrain
# systemctl start velotrain
Raw data
{
"_id": null,
"home_page": null,
"name": "velotrain",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.11",
"maintainer_email": null,
"keywords": "velodrome, transponder, timing",
"author": null,
"author_email": "Nathan Fraser <ndf-zz@6-v.org>",
"download_url": "https://files.pythonhosted.org/packages/d3/d2/7d4157b28b5ddaef88234868c877c06154d58c50cccb905345d9c28dc72d/velotrain-1.0.3.tar.gz",
"platform": null,
"description": "# velotrain\n\nvelotrain reads raw transponder passing information from a set\nof up to 9 measurement points, filters the messages according\nto track configuration parameters and then emits valid timing\nmeasurements as JSON-encoded objects to MQTT.\n\n\n## Operation\n\nThe velodrome is divided into a closed loop of timing sectors\nby measurement points at each of the interesting offsets, for example:\n\n - Finish line\n - 200m Start\n - Pursuit B\n - Pursuit A\n\nA rider is considered to be in a 'run' if their speed over any\nconfigured sector (eg Finish line to 200m start) is between\nconfigured values (default: 30 km/h to 90 km/h).\nPassings emitted for a rider in a run will include any available\nlap, half-lap, quarter-lap, 100 m, and 50 m splits.\nRider passings slower or faster than the configured limits are\nconsidered isolated, and will be reported without splits.\n\nWhere possible, valid raw passings received out of order will be\ncorrected and re-ordered before being emitted. In the case that\nan isolated raw passing violates the configured track ordering and \nspeed limits, it may be reported out of order.\n\nFor a Protime active/passive dual loop configuration, riders\nwill not be registered at all until they are moving faster than\nabout 30 km/h, no matter what software limits have been configured.\n\n\n## Configuration\n\nTrack layout, system transponder ids and speed limits are configured\nusing a metarace jsonconfig entry with the section 'velotrain' and the\nfollowing keys:\n\n - authkey: (string) reset authorisation string, default: null\n - gate: (string) transponder ID for start gate, default: null\n - gatedelay: (string) trigger delay for start gate, default: '0.075' _[1]_\n - gatesrc: (string) channel start gate reports to eg 'C2', default: null\n - laplen: (float) lap length in metres, default: 250.0\n - maxspeed: (float) maximum sector speed in km/d, default: 90.0\n - minspeed: (float) minimum sector speed in km/h, default: 38.0\n - moto: (list) list of transponder IDs attached to motos, default: []\n - trig: (string) transponder ID of sync trigger messages, default: '255'\n - passlevel: (integer) minimum accepted passing level, default 40 _[2]_\n - uaddr: (string) UDP host listen address, default ''\n - uport: (integer) UDP host port, default: 2008\n - bcast: (string) broadcast address for timing LAN,\n default: '255.255.255.255'\n - basetopic: (string) base topic for telegraph interface,\n default: 'velotrain'\n - sync: (string) channel of synchronisation master unit, default: null\n - mingate: (float) minimum accepted speed in km/h over the\n start gate sector, default: 9.0\n - maxgate: (float) maximum accepted speed in km/h over the\n start gate sector, default: 22.5\n - dhi: (list) ['address', port] DHI port for Caprica scoreboard,\n default: null\n - dhiencoding: (string) text encoding for DHI messages, default: 'utf-8'\n - mpseq: (list) ordering of channels on the track,\n default: ['C1', 'C9', 'C4', 'C6', 'C3', 'C5', 'C7', 'C8', 'C2'] _[3]_\n - mps: (dict) mapping of channel IDs to measurement point configs,\n default: {} _[4]_\n\nConfigured measurement points divide the track into a closed loop of\ntiming sectors, with a set of splits at each measurement point.\nMeasurement point config entries have the following options, omitted keys\nreceive a default value:\n\n - name: (string) visible name of the measurement point,\n default: channel ID\n - ip: (string) IP address of connected Protime decoder,\n default: null _[4]_\n - offset: (float) distance in metres from finish line to measurement \n point, default: null\n - half: (string) channel ID corresponding to a half lap before this unit,\n default: null\n - qtr: (string) channel ID corresponding to quarter lap before this unit,\n default: null\n - 200: (string) channel ID corresponding to 200 m before this unit,\n default: null\n - 100: (string) channel ID corresponding to 100 m before this unit,\n default: null\n - 50: (string) channel ID corresponding to 50 m before this unit,\n default: null\n\nNotes:\n\n 1. 0.075 seconds is LS transponder delay when triggered by\n start gate release\n 2. Sets the 'level' option in all attached Protime decoder units\n 3. Default channel ordering matches trackmeet, all configured units\n must appear once in this sequence, however the sequence may contain\n more channels than are configured.\n 4. Measurement points require a non-null IP entry to be configured.\n For use with foreign timers, set the IP to be an empty string: ''.\n Refer to the sample velomon.json for an example setting\n\n\n## Telegraph (MQTT) Interface\n\nThe topics below are relative to the configured basetopic (default:\n'velotrain'), from the perspective of the velotrain process. For\nall JSON encoded objects, invalid or unavailable properties will be\nreported as null.\n\n\n### passing (publish)\n\nIssue filtered and accepted passing records. Passing records\nare JSON encoded objects with the following properties:\n\n - index : (integer) index of the passing record (reset to 0 each day)\n - date: (string) Date of the passing formatted YYYY-MM-DD\n - time: (string) Time of day of the passing formatted HH:MM:SS.dcm\n - mpid: (integer) Measurement point ID 0 - 9\n - refid: (string) Transponder ID or system passing ID 'gate', 'moto'\n or 'marker'\n - env: (list) [temperature, humidity, pressure] where each value\n is a float value in units degrees Celsius, %rh, and hPa respectively\n - moto: (string) Proximity to moto in seconds if drafted\n - elap: (string) Elapsed time since last start gate or start of run\n formatted HH:MM:SS.dc\n - lap: (string) Time for the last full lap to the measurement point\n - half: (string) Time for the last half lap to the measurement point\n - qtr: (string) Time for the last quarter lap to the measurement point\n - 200: (string) Time for the last 200m to the measurement point\n - 100: (string) Time for the last 100m to the measurement point\n - 50: (string) Time for the last 50m to the measurement point\n - text: (string) Name of measurement point, or user-supplied text\n for markers\n\nExample: A moto passing over the 100m split at about 4:18pm\n\n\tTopic:\t\tvelotrain/passing\n\tPayload:\t{\"index\": 108, \"date\": \"2022-07-06\",\n\t\t\t \"time\": \"16:18:32.300\", \"mpid\": 5,\n\t\t\t \"refid\": \"moto\", \"env\": [16.3, 55.0, 1015.0],\n\t\t\t \"moto\": \"0.00\", \"elap\": \"2:10.51\",\n\t\t\t \"lap\": \"22.95\", \"half\": null, \"qtr\": null,\n\t\t\t \"200\": \"18.32\", \"100\": \"9.07\", \"50\": \"4.52\",\n\t\t\t \"text\": \"100m Split\"}\n\n### rawpass (publish)\n\nIssue raw, unprocessed passing records as received from decoders. Raw\npassing records are JSON encoded objects with the following properties:\n\n - date: (string) Date of the raw passing formatted YYYY-MM-DD\n - time: (string) Time of day of the passing formatted HH:MM:SS.dc\n - rcv: (string) Time of day passing was received by host system,\n formatted HH:MM:SS.dcm\n - mpid: (integer) Measurement point ID 0 - 9\n - refid: (string) Raw transponder ID\n - env: (list) [temperature, humidity, pressure] where each value\n is a float value in units degrees Celsius, %rh, and hPa respectively\n - name: (string) Name of measurement point\n - info: (string) Extra information provided by decoder\n\nExample: The raw passing that might have generated the above moto passing\n\n\tTopic:\t\tvelotrain/rawpass\n\tPayload:\t{\"date\": \"2022-07-06\", \"env\": [16.3, 55.0, 1015.0],\n\t\t\t \"refid\": \"125328\", \"mpid\": 5,\n\t\t\t \"name\": \"100m Split\", \"time\": \"16:18:32.303\",\n\t\t\t \"rcv\": \"16:18:32.459\"}\n\n### status (publish)\n\nIssue system and measurement point status records at the top of each\nminute. Status records are JSON encoded objects with the following properties:\n\n - date: (string) Date of the status record formatted YYYY-MM-DD\n - time: (string) Time of day status was issued formatted HH:MM:SS.dc\n - offset: (string) Rough offset of system clock to UTC\n - count: (integer) Count of passing records\n - env: (list) [temperature, humidity, pressure] where each value\n is a float value in units degrees Celsius, %rh, and hPa respectively\n - gate: (string) Time of day of last gate trigger HH:MM:SS.dc\n - battery: (list) List of transponder refids that have reported a low\n battery warning since the last system reset\n - info: (string) Status info, one of: 'running', 'resetting',\n 'error', 'offline' _[1]_\n - units: (list) List of JSON encoded objects, each containing a measurement\n point status:\n - mpid: (integer) Measurement point ID\n - name: (string) Measurement point name\n - noise: (integer) Interference noise value 0 - 100. Values under\n 40 indicate normal operation. Larger values indicate interference.\n - offset: (string) Unit clock offset from system time in seconds\n formatted as [-]s.dcm\n\nNotes:\n\n 1. Status info strings:\n - running: Normal operation\n - resetting: System reset in progress\n - offline: velotrain was shutdown (date and time fields\n indicate when shutdown ocurred)\n - error: Network connection lost, server status temporarily\n unavailable\n\nExample: Status update\n\n\tTopic:\t\tvelotrain/status\n\tPayload:\t{\"date\": \"2022-07-07\", \"time\": \"23:04:00.15\",\n\t\t\t \"offset\": \"0.211\", \"env\": [13.1, 62.0, 1013.0],\n\t\t\t \"count\": 123, \"gate\": null, \"battery\": [\"123876\"],\n\t\t\t \"info\": \"running\",\n\t\t\t \"units\": [\n\t\t\t {\"mpid\": 1, \"name\": \"Finish\",\n\t\t\t \"noise\": 20, \"offset\": \"0.000\"},\n\t\t\t {\"mpid\": 2, \"name\": \"Pursuit A\",\n\t\t\t \"noise\": 32, \"offset\": \"0.025\"},\n\t\t\t {\"mpid\": 3, \"name\": \"Pursuit B\",\n\t\t\t \"noise\": 15, \"offset\": \"0.005\"},\n\t\t\t {\"mpid\": 4, \"name\": \"200m Start\",\n\t\t\t \"noise\": 32, \"offset\": \"0.005\"},\n\t\t\t {\"mpid\": 5, \"name\": \"100m Split\",\n\t\t\t \"noise\": 14, \"offset\": \"-0.008\"},\n\t\t\t {\"mpid\": 6, \"name\": \"50m Split\",\n\t\t\t \"noise\": 27, \"offset\": \"0.064\"},\n\t\t\t {\"mpid\": 8, \"name\": \"150m Split\",\n\t\t\t \"noise\": 18, \"offset\": \"-0.020\"}\n\t\t\t ]}\n\n\n### request (subscribe)\n\nReceive requests for replay of passing records to the nominated serial,\nfiltered according to the JSON encoded request object:\n\n - serial (string) optional request serial, appended to replay topic\n - index (list) optional [first, last] limit response to include\n passings from index first to index last.\n - time (list) optional [starttime, endtime] limit response to\n passings between starttime and endtime strings formatted HH:MM:SS.dc\n - mpid (list) optional [mpid, ...] include only the nominated\n mpids in replay\n - refid (list) optional [refid, ...] include only nominated\n transponder ids in response\n - marker (list) optional [marker, ...] include only passings\n following the nominated marker strings\n\nExample: Request all passings, publish to default topic\n\n\tTopic:\t\tvelotrain/request\n\tPayload:\tb''\n\t\n\tReply topic:\tvelotrain/replay\n\tPayload:\t[{\"index\":0, ...}, {\"index\":1, ...}, ...]\n\nRequest a replay of passing 254 to 'xxfd'\n\n\tTopic:\t\tvelotrain/request\n\tPayload:\t{\"serial\": \"xxfd\", \"index\": 254}\n\t\n\tReply topic:\tvelotrain/replay/xxfd\n\tPayload:\t[{\"index\": 254, ... }]\n\nReplay passings from transponder '123456' and start gate after midday\nbefore index 10000 and that occur following manual markers 'one' and 'two'\n\n\tTopic:\t\tvelotrain/request\n\tPayload:\t{\"refid\": [\"123456\", \"gate\"],\n\t\t\t \"time\": [\"12:00:00\", null],\n\t\t\t \"index\": [null, 10000],\n\t\t\t \"marker\": [\"one\", \"two\"]}\n\t\n\tReply topic:\tvelotrain/replay\n\tPayload:\t[{\"index\":12, \"text\":\"one\",\"mpid\":0, ...}, ...]\n\n\n### replay[/serial] (publish)\n\nIssues a JSON encoded list of passing objects, filtered according\nto a provided request.\n\n\n### marker (subscribe)\n\nInsert the provided utf-8 encoded unicode payload as a manual marker\npassing. If the supplied payload is empty, 'marker' is used.\n\nExample: Insert an emoticon '\ud83e\udd37' (U+1F937) at the current time of day\n\n\tTopic:\t\tvelotrain/marker\n\tPayload:\tb'\\xf0\\x9f\\xa4\\xb7'\n\t\n\tReply topic:\tvelotrain/passing\n\tPayload:\t{\"index\": 143, \"date\": \"2022-07-06\",\n\t\t\t \"time\": \"12:09:13.33\", \"mpid\": 0,\n\t\t\t \"refid\": \"marker\", \"env\": null, \"moto\": null,\n\t\t\t \"elap\": null, \"lap\": null, \"half\": null,\n\t\t\t \"qtr\": null, \"200\": null, \"100\": null,\n\t\t\t \"50\": null, \"text\": \"\\ud83e\\udd37\"}\n\n### reset (subscribe)\n\nStart a reset process, authorised by the provided utf-8 encoded \nauthkey (config option 'authkey'). For a Tag Heuer Protime decoder network,\nthis process may take up to three minutes to complete. For systems\nwith foreign timers, this request will just clear passing records.\n\nExample: Request reset process using authkey 'qwertyuiop'\n\n\tTopic:\t\tvelotrain/reset\n\tPayload:\tb'qwertyuiop'\n\n\n### timer (subscribe)\n\nReceive raw passing data from a foreign timing device. Foreign timing\nrecords are utf-8 encoded unicode strings in the format:\n\n\tINDEX;SOURCE;CHANNEL;REFID;TOD\n\nWhere the fields are as follows:\n\n - INDEX: ignored\n - SOURCE: measurement point id as a metarace timing channel\n eg: 'C1', 'C2', 'C3', ... 'C9'\n - CHANNEL: ignored\n - REFID: transponder ID eg '123456'\n - TOD: time of day of passing as string eg: '1:23.456', 'now', '12:34:56.789'\n\nNote: velotrain expects each attached decoder to be triggered from a\nreference clock at the top of each minute, and to report a passing with\nrefid matching config option 'trig' (default: '255').\nFor systems that maintain synchronisation via a\ndifferent mechanism, a fake top of minute trigger can be sent\nwith the channel of the configured sync source (config key 'sync')\nat any time using the trig refid and a TOD of '0'.\n\nExample: Insert a passing for transponder '123456' on mpid 3 at the current time\n\n\tTopic:\t\tvelotrain/timer\n\tPayload:\tb';C3;;123456;now'\n\t\n\tReply topic:\tvelotrain/rawpass\n\tPayload:\t{\"date\": \"2022-07-06\", \"env\": null,\n\t\t\t \"refid\": \"123456\", \"mpid\": 3, \"name\": \"Pursuit B\",\n\t\t\t \"time\": \"12:23:35.879\", \"rcv\": \"12:23:35.879\"}\n\nFake a top-of-minute message to mpid 1, using the default trig:\n\n\tTopic:\t\tvelotrain/timer\n\tPayload:\tb';C1;;255;0'\n\n\tReply topic:\tvelotrain/rawpass\n\tPayload:\t{\"date\": \"2022-07-06\", \"env\": null,\n\t\t\t \"refid\": \"255\", \"mpid\": 1, \"name\": \"Finish\",\n\t\t\t \"time\": \"00:00:00.000\", \"rcv\": \"12:25:06.090\"}\n\nInsert a passing for transponder '123456' on mpid 4, 10.2345 seconds after 2 pm:\n\n\tTopic:\t\tvelotrain/timer\n\tPayload:\tb';C4;;123456;14:00:10.2345'\n\n\tReply topic:\tvelotrain/rawpass\n\tPayload:\t{\"date\": \"2022-07-06\", \"env\": null,\n\t\t\t \"refid\": \"123456\", \"mpid\": 4, \"name\": \"200m Start\",\n\t\t\t \"time\": \"14:00:10.234\", \"rcv\": \"12:27:38.988\"}\n\n\n### resetunit (subscribe)\n\nAttempt to stop, start and re-synchronise the single measurement\npoint unit specified in the message body. Note that the synchronisation\nmaster may not be re-started this way.\n\nExample: Reset unit \"C4\"\n\n\tTopic:\t\tvelotrain/resetunit\n\tPayload:\tb'C4'\n\n\n## Requirements\n\n - metarace (>= 2.1.14)\n - ypmeteo\n\n\n## Installation\n\n\t$ pip3 install velotrain\n\nTo use as a systemd service, edit the provided unit file\nand copy to /etc/systemd/system, then enable with:\n\n\t# systemctl enable velotrain\n\t# systemctl start velotrain\n",
"bugtrack_url": null,
"license": null,
"summary": "Velodrome transponder training timing",
"version": "1.0.3",
"project_urls": {
"homepage": "https://github.com/ndf-zz/velotrain",
"repository": "https://github.com/ndf-zz/velotrain"
},
"split_keywords": [
"velodrome",
" transponder",
" timing"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "117d006a417866a0e1971fe656e6938e5e3336e99f5cb5d2e598090ca22f8ad3",
"md5": "3afb294ce636912a353fade338e47c87",
"sha256": "f506cf5c6af973dc6c2027746b4471954d9347da98ea5f4761707ffa6755ddef"
},
"downloads": -1,
"filename": "velotrain-1.0.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "3afb294ce636912a353fade338e47c87",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.11",
"size": 24499,
"upload_time": "2025-07-23T01:59:45",
"upload_time_iso_8601": "2025-07-23T01:59:45.566756Z",
"url": "https://files.pythonhosted.org/packages/11/7d/006a417866a0e1971fe656e6938e5e3336e99f5cb5d2e598090ca22f8ad3/velotrain-1.0.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "d3d27d4157b28b5ddaef88234868c877c06154d58c50cccb905345d9c28dc72d",
"md5": "f2ecaff7b4cb6823bf3df16b11f475cd",
"sha256": "ef8b8adf06ca79158c2e291074d67266d1903dc9a089432cb23630aebefdd0a2"
},
"downloads": -1,
"filename": "velotrain-1.0.3.tar.gz",
"has_sig": false,
"md5_digest": "f2ecaff7b4cb6823bf3df16b11f475cd",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.11",
"size": 24338,
"upload_time": "2025-07-23T01:59:47",
"upload_time_iso_8601": "2025-07-23T01:59:47.068040Z",
"url": "https://files.pythonhosted.org/packages/d3/d2/7d4157b28b5ddaef88234868c877c06154d58c50cccb905345d9c28dc72d/velotrain-1.0.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-23 01:59:47",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "ndf-zz",
"github_project": "velotrain",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "velotrain"
}