blog

Categories     Timeline     RSS

pm5conv converter for Concept2 PM5 data

I just pushed pm5conv, a converter from Concept2 PM5 binary data to JSON, to my git server and uploaded a release for 64bit Windows to my projects.

Example:

% ./pm5conv /media/alexander/3B89-4EC1/Concept2/Logbook

[
  {
    "Index": 1,
    "Type": "Free Row",
    "Date": "2018-02-27T21:00:00+01:00",
    "UserID": 175,
    "IntervalRestTime": 0,
    "TotalDuration": 96200000000,
    "TotalDistance": 363,
    "TotalRestDistance": 0,
    "PartDuration": 300000000000,
    "PartDistance": 0,
    "PartCalories": 0,
    "Parts": [
      {
        "Duration": 0,
        "Distance": 363,
        "Heartrate": 0,
        "RestHeartrate": 0,
        "SPM": 27,
        "SplitType": 0,
        "IntervalRestTime": 0,
        "IntervalRestDistance": 0
      }
    ]
  },
  {
    "Index": 2,
    "Type": "Free Row",
    "Date": "2018-02-28T20:41:00+01:00",
    "UserID": 175,
    "IntervalRestTime": 0,
    "TotalDuration": 420800000000,
    "TotalDistance": 1559,
    "TotalRestDistance": 0,
    "PartDuration": 300000000000,
    "PartDistance": 0,
    "PartCalories": 0,
    "Parts": [
      {
        "Duration": 0,
        "Distance": 1121,
        "Heartrate": 0,
        "RestHeartrate": 0,
        "SPM": 29,
        "SplitType": 0,
        "IntervalRestTime": 0,
        "IntervalRestDistance": 0
      },
      {
        "Duration": 0,
        "Distance": 438,
        "Heartrate": 0,
        "RestHeartrate": 0,
        "SPM": 26,
        "SplitType": 0,
        "IntervalRestTime": 0,
        "IntervalRestDistance": 0
      }
    ]
  },
]

[Update 06.03.2018: Updated the example to changed JSON format]

Concept2 PM5 logbook data format

(You should find the most recent version of this on my git server )

I recently bought a Concept2 rower and wanted to read the USB logbook data - unfortunately Concept2 neither provides a description of the format nor any Open Source or Unix software. I tried to figure out the data format on my own, then Ryan Moe’s work filled the gaps:

The data is split across two files, LogDataAccessTbl.bin and LogDataStorage.bin. The former provides information about the location of the actual workout data in LogDataStorage.

LogDataAccessTbl.bin

Each entry in LogDataAccessTbl is 32 bytes, multibyte entries are Little Endian:

Byte Meaning
0 Magic 0xF0
1 Workout type
2-3 Interval rest time*
4-5 Workout name*
6-7 N/A
8-9 Timestamp*
10-11 N/A
12-13 No. of Splits*
14-15 Duration/Distance*
16-17 Record offset in LogDataStorage.bin
18-23 N/A
24-25 Size of record in bytes
26-27 Index
28-31 N/A

( * unimportant, because either redundant in actual record or unreliable )

Workout Types

Value Type
0x01 Free Row
0x03 Single Distance
0x05 Single Time
0x06 Timed Interval
0x07 Distance Interval
0x08 Variable Interval
0x0A Single Calorie

LogDataStorage.bin

Each entry in LogDataStorage has a header and a number of splits or intervals. The header size is either 50 bytes (workout types 0x01, 0x03, 0x05, 0x0A) or 52 bytes (others). The size of each split frame is 32 bytes for all workouts except type 0x08, where it is 48 bytes. Multibyte entries are, contrary to LogDataAccessTbl.bin Big Endian(!)

Header (types 0x01 - 0x05, 0x0A)

Byte Meaning
0 Magic 0x95
1 Type of workout
2-3 N/A
4-7 Serial number
8-11 Timestamp
12-13 User ID
14-17 N/A
18 Record ID
19-21 Magic 0x000000
22-23 Total Duration
24-27 Total Distance
28 SPM
29 Split Info
30-31 Split Size
32-49 N/A

Header (Fixed Intervals)

Byte Meaning
0-18 As above
19 Number of splits
20-21 Split size
22-23 Interval rest time
24-27 Total Work Duration
28-29 Total Rest Distance
30-51 N/A

Header (Variable Intervals)

Byte Meaning
0-18 As above
19 Number of splits
20-21 Split size
20-23 Total Work Duration
24-27 Total Work Distance
30-51 N/A

Timestamp format (bytes 8-11)

Bits Meaning
0-6 year after 2000
7-11 day
12-15 month
16-23 hour
24-31 minute

Split Frame (Non-Interval Types)

Byte Meaning
0-1 Split Duration/Distance
2 Heart Rate
3 SPM
4-31 N/A

Interval Frame (Timed Interval, Distance Interval)

Byte Meaning
0-1 Split Duration/Distance
2 Heart Rate
3 Rest Heart Rate
4 SPM
5-31 N/A

Variable Interval Frame

Byte Meaning
0 Split Type
1 SPM
2-5 Work Interval Time
6-9 Work Interval Distance
10 Heart Rate
11 Rest Heart Rate
12-13 Interval Rest Time
14-15 Interval Rest Distance
16-47 N/A

Loglift / borreliosis recovery

Enjoying the refreshing 4 degrees Celsius in my little gym, borreliosis recovery seems to be going reasonably well - loglift up to 87.5 x 5:

picolist - minimal mailing list

I wrote a little program to set up mailing lists and newsletters without too much hassle: picolist

I did not want any additional software written in C or a scripting language on my mailserver, which ruled out all popular solutions. All I wanted was a reflector - one address that spreads the message to members - anyway, so GNU mailman and the like would have been big solutions to a fairly small problem.

picolist will work with mail transfer agents that are able to forward incoming mails to programs via UNIX pipes and which provide the sendmail command. This is the case for sendmail, qmail, postfix, exim and probably most other MTA software running on UNIX and Linux systems.

Freifunk Hochstift - Adressen

Da ich einen Vertrag bei o2 habe und damit seit gut einen Monat ohne DSL bin, habe ich ein Programm geschrieben, das stündlich eine Liste der aktiven Freifunk-Knoten von Freifunk Hochstift mit Adresse aus den vorhandenen Koordinaten-Daten zusammenstellt. Eine Suche auf der Karte macht mit einer gedrosselten UMTS-Verbindung z.B. wenig Spaß, daher die aufbereitete Textdatei.

[Update 16.12.2017: Der Kartenserver von Freifunk Hochstift ist seit Freitag morgen ausgefallen, daher gibt es auch bei mir momentan keine Aktualisierungen.]

< Older

Newer >