This documentation is intended to help designing applications for the Velobox' vmkstationd3
that include communication with Velometrik's controller for pressure mats.

Introduction


The new Velobox WS/HTTP-server supports "applications" that work largely independent from each other on top of a "kernel". We could also talk about "application servers" but "application" is shorter. You start an application with
ws://<velobox-name>.local:8080/apps/<application-name>
Once having created a websocket connection the client can send commands and will asyncronously get responses or other useful information from the application. Depending on the application there may be additional HTTP-URLs to deliver special data. While commands are in a simple commandline mode the responses are JSON strings.

Although more than one client can connect to the same application, they won't work independently from each other.

Overview



Generel commands


Info

  • record {[-force] <duration> [1|2]} | cancel
    • Start recording 1 or 2 rsp. for <duration> seconds
    • Use the -force option to override unstored recordings. Without -force an unstored recording will cause an error.
    • After recording the results will be sent. If no recording is specified 1 is the default.
    • cancel running recording. This is the preferred method to avoid an "unstored" error.
  • set mask {nomask|standard|large|custom|<name>}|{[-store [<name>]] <pattern>}
    • Select one of the predefined masks or specify a new mask
    • <pattern> is an sequence with a length of 448 for each senorpoint. 1 is off and 0 is on
    • The new mask will be stored with the name specified by the -store option where "custom" is the default
    • The predefined masks 'nomask', 'standard' and 'large' cannot be overridden
    • A mask name may only consist of alphanumeric characters and may not begin with a digit
  • set jpeg colorcontrast 0-7
    • Set color contrast for all three images
    • Changing the color contrast will affect the other Apps too
  • set jpeg bgcolor <#HEX value>
    • Set background color for all three images
    • Changing the color contrast will affect the other Apps too
  • set jpeg 0|1|2|3 grid no|dotted|solid
    • Shows or doesn't show the grid that separates the measuring points
  • set jpeg 0|1|2|3 resolution 1-n
    • Sets the number of pixels generated per measuring point
    • Although there is no upper limit, a large number will probabely knock out the Velobox
  • set jpeg 0|1|2|3 frame 0-n
    • Draws a black frame around the generated image of the width (0-n pixels) specified
  • set jpeg 0|1|2|3 quality 0-100
    • Sets quality for JPEG compression
  • set jpeg 0|1|2|3 mask show|hide
    • Shows or hides the mask
  • set compare on|off
    • Switch compare mode on or off
  • get mask <name>
    • Fetch mask specified by <name>
    • This will cause the wsevent 'mask' with the keys 'name' and 'values'
    • The mask can be used a starting point for a mask editor
  • get appquestions [<lang>]1)
    • Fetch questions whose answers will be recorded for a client during a fitting session
    • They correspond to the questions ask by the Velometrik® product selection webservice
  • get appsettings
    • Fetch all settings done by a set command (or config) as a single JSON Object
    • Details are explained below
  • config n_update_live|n_update_int 1-n
    • Configure application behavior
    • Update every n_update_live-th live image
    • Update every n_update_int-th integrated image
    • Affects only JPEG-Generation
  • switch create_jpeg on|off
    • Switch the creation of JPEG pressure images on or off rsp
  • switch create_norm on|off
    • Switch the creation of normalized pressure value on or off rsp
  • status <what>
    • Returns status information. <what> may be:
      channel{1|2} recording status of that channel
      finished true|false
      recording_id (0 if not stored)
      imagespeed number of pressure images received during 1s 1)
      temp CPU temperature in degrees centigrade
      1)Images without any pressure will not be counted
  • version2)
    • Query Version
    • The versions of vmkstationd (key vmkstationd) and of the application (key app) will be returned

Bluetooth commands



Database commands


The Velobox has a database for storing the results of the saddle fittings. It can be accessed by SQL. Extra commands ease the handling of images by creating JPEG images with the current JPEG setting from the stored pressure values and the mask. Together they support a reasonable workflow.

[The database tables]
clients
client_id INT NOT NULL PK
email VARCHAR(129)
forename VARCHAR(40)
surname VARCHAR(40)
first_contactCHAR(19) NOT NULL YYYY-MM-DD hh:mm:ss
sessions
session_id INT NOT NULL PK
client_id INT NOT NULL FK to clients
date CHAR(10) NOT NULL
restart CHAR(10) YYYY-MM-DD
notes TEXT YYYY-MM-DD
recordings
recording_id INT NOT NULL PK
session_id INT NOT NULL FK to sessions
analysis INT NOT NULL 1 sitbones 1)
2 saddlepressure
3 anamnesis 1)
finished CHAR(19) NOT NULL YYYY-MM-DD hh:mm:ss
product VARCHAR(40)
product_label VARCHAR(40)
n_pressure_rows INT
n_pressure_cols INT
pressure_values TEXT space char separated integers
max_pressure INT
mask TEXT space char separated 0 and 1
results TEXTJSON object
notes TEXT
1) for future version
masks
mask_id INT NOT NULL PK
name CHAR(20) NOT NULL alphanumerical chars only
standard INT NOT NULL 0 or 1
n_rows INT NOT NULL
n_cols INT NOT NULL
mask TEXT NOT NULL space char separated 0 and 1
nextids
table_name VARCHAR NOT NULL PK
id_name VARCHAR NOT NULL
next_id INT NOT NULL 1)
1)This value must be used for the next INSERT into this table. After that is must be increased by 1.
It's a good idea to do this together with the INSERT inside a transaction.


The recording results


Recording ends with wsevent result1 or result2 rsp. It may end with wsevent error (msg "Insufficient data") if no pressure images have arrived during recording. Remember that non of these values has overall meaning. That means you can compare only values captured during the same bike fitting session to find an improvement or a change for the worse. The result values are:
Key Value
pelvisrotationarea in which the center of pressure moved during recording
(details below)
veloscoreVelometrik®s measure of pressure distribution
(explanation below)
front_rear (front:rear)pressure ratio between front and rear half in % relative to whole pressure
left_right (left:right)pressure ratio between left and right rear quarter in % relative to whole pressure in the rear half
center_left (x,y)center of pressure inside left half
center_right (x,y)center of pressure inside right half
center (x,y)overall center of pressure
(situated on the tie line between center_left and center_right)

Pelvis rotation


There are several ways how to graphically present the pelvet rotation area. The simplest way is to draw a rectangle. The most advanced way would be to draw 4 splines. The result object defines a kind of oval represented of 4 splines embedded inside a parallelogram. The easiest way to present a numerical result is using "width" and "height" which describes the size of a surrounding rectangle.
                    v-Secondary axis
                    | c1               | front                  | c2
                   -+------------------+------------------------+- Front tangent
                    |                  |                        |
                    |                  |                        |
                    |                  |                        |
                    | left             | center                 | right
                   -+------------------+------------------------+- <-Principal axis
                    |                  |                        |
                    |                  |                        |
                    | c4               | rear                   | c3
                   -+------------------+------------------------+- Rear tangent
                    |                  |                        |
                    Left tangent                                Right tangent
                

Veloscore


The "veloscore" is a measure of pressure distribution. Values are from 0 to 100 where 0 means "All pressure is on a single point." and 100 means "All points have the same pressure.".

JSON responses


Every JSON response has the key "wsevent" which classifies the JSON message. Depending on the message class there may be more keys specific for that message class. Until now there are the following definitions:
WSEvent Detail keys Notes
errorclassinternal|client|user errors
nrerror number (user errors only)
sourceerror source
msgtext message
max_valuevalueNew pressure maximum
sda_liveA new live image is available.s. Fetching JPEG-Images
sda_int1An integrated image for the left side is available. s. Fetching JPEG-Images
sda_int2An integrated image for the right side is available.s. Fetching JPEG-Images
sda_int3A retrieved image in "session compare mode".
sattelnormNormalized pressure values
imagetypesda_live, sda_int1, sda_int2, sda_int3 corresponding to the "image available" WSEvents
n_rowsnumber of rows
n_colsnumber of columns
valuespressure values 0...255 (The maximum (if any) is always 255.)
result1Result for the left side.
pelvisrotationsee schema above
Values in cm scale=1
veloscoreVelometriks measure of the pressure distribution
Values 0...100 scale=1
front_rearpressure distribution between front and rear in percent
Format <left>:<right>
Values 0...100 scale=0
left_rightpressure distribution between left and right in percent
Format <left>:<right>
Values 0...100 scale=0
centercenter of pressure
Object with keys x, y
Values in cm scale=1
center_leftcenter of pressure on left half
Object with keys x, y
Values in cm scale=1
center_rightcenter of pressure on right half
Object with keys x, y
Values in cm scale=1
result2Result for the right side.
result3Result from a retrieved recording.
pelvisrotation(like record1)
veloscore...
...
ttychangechangeplugged|unplugged
startstarted reading (ok|error if plugged)
typemat type MT_SAT*
driver(used as identifier)
ttystatestateactive|inactive
driver(used as identifier)
overloadsourcewhere overload comes from
totaltotal number of requests
rejectednumber of requests rejected
tempCPU temperature
freq_maxmaximum CPU frequency
freq_curcurrent CPU frequency
bteventbteventBluetooth event
(Detail keys see next table)

Error classes and numbers:

class number notes
internelError in the application server
This should never happen and therefore must be reported to Velometrik
client Error in the client application
This must be fixed by the client (GUI) developer.
user Handling error by client application user
These errors should be reported to the application user.
1 Insufficient data for analysis
2 A recording started before is still running.
3 There are unstored recording(s) that must be stored or cancelled before.
4 There is no session. (It must be create before.)
5 There is no recording (to store) or the recording is not finished yet.


BTEvent Detail key Class Number Meaning
disconnected Regular disconnect
ambiguity devices Array with all device names
data Data are available
error class disconnected Unexpected disconnect
fail Connection fails
Pair failed
Start notify failed
Device not found
No device found
Expected device not found
Connection timeout
comm Stop notify failed
client Command/syntax errors
1
2 disconnect while trying connect (ignored)
internal Unexpected error, btagent restarted
msg The error message
debug Debug message

Stored settings


A series of the commands documented above apply to settings that define the appearance of pressure images. These settings will be stored in the Velobox when disconnecting from the application and they will be retrieved at the next application start. The client application developer may want to offer menu like graphical elements to the user to let him set everything according to his own flavor. To initialize them the current settings can be obtained using the command get appsettings. The application responds with a wsevent "appsettings" with a settings object as value of the key appsettings. This object has the keys listed as "Settings" in the following table. If a setting applies to different displays (0 live image; 1, 2 integrated images; 3 other images) there are subkeys 0...3.
Setting Command
Setting Command
maskname set mask ...
compare set compare ...
contrast set jpegcontrast ...
bgcolor set jpeg {0|1|2|3} bgcolor ...
grid set jpeg {0|1|2|3} grid ...
resolution set jpeg {0|1|2|3} resolution ...
frame set jpeg {0|1|2|3} frame ...
jpegquality set jpeg {0|1|2|3} quality ...
showmask set jpeg {0|1|2|3} mask ...
imageupdatesconfig n_update_...

Fetching JPEG-Images


An image announced by a wsevent must be either fetched by a HTTP-request or it can be ignored. The URL for fetching is
/sattelbild?image=<imagetype>

Hints to client application developers


Creating JPEG images is the most CPU power consuming part of the whole application. Therefore you should choose your JPEG settings in a way that minimizes power consumption. It is very easy to create an overload situation by setting 'set jpeg 0 resolution 50' for example. You will see a delayed live image and after a few seconds an overload wsevent will arrive. Among the additional information is the temperature. This is because the cpu slows down at high temperatures1). If at overload the current frequency is lower than the maximum frequency a high temperature might be the reason. It could a good idea to send a warning to your user in this case.
1)It also slows down at low load which would contradict the overload condition.
The pelvis rotation area in real life is very small. (The fitting goal is a minimized area.) Showing the shape with four splines usually only makes sense in a magnified representation.
Bluetooth connection handling is managed by only two commands, btconnect and btdisconnect. In case of an error it's sufficient to rety btconnect after giving an appropriate to the user. In case of ambiguity a menu with all choices should be offered.

1)
Questions are subdivided in an array of sections. Each section object has a code, a text for display and an array of questions (named fragen). Each question has a code (equal to the code in Velometrik®s product selection webservice), a response type (antworttyp), a text for display and, depending on the response type, an array of defaults. The respond types are:
Questions with response type 3 or 4 have a non empty array with defaults (vorgaben). Each default object has a code (which is the value to be stored, i.e. the answer), a boolean value standard and a text for display. "standard is true" means, this value can be used as the proposed default value. Moreover there is an empty string named antwort (answer) in every question to make GUI programmers live a little bit easier.

2)
Versioning follows the rule: <main>.<minor>.<revision>. A new revision contains corrections only. A new minor version is compatible with the previous minor version. A new main version may not be compatible with the previous one. The version string may have one of the following appendices (seperated by underscore '_'):
Appendix Meaning Remark
AAlphaDevelopers current (pre beta) version
X<date>eXperimental<date>: YYYYMMDD
B<nr>[U]Beta <nr>
P<nr>[U]Prerelease <nr>
The character "U" marks the version as "unfinished".