Introduction
The bluetooth communication between the Velometrik controller and an application API of the Velobox runs through several layers:
- The BlueZ Bluetooth protocol stack for Linux
- The Bluetooth Low Energy platform Agnostic Klient "Bleak" library for Python
- The Bluetooth Agent of the vmkstationd3 of the Velobox (a Python script named btagent.py)
- A TCL Interface to btagent.py. (A kernel module, named ::kernel::BTSattel for saddle pressure mats)
- The Application module that defines the applications API
For program design it is useful to know some internals starting from the bluetooth agent upwards.
The bluetooth agent
The bluetooth agent arranges the bluetooth communication between Velometrik's controller
and the vmkstationd3 daemon of the Velobox.
After invocation the agent expects commands from stdin that control what happens.
Responses go to stdout.
Pressure values go as comma seperated (ASCII) integer values
(one line per pressure image) to stdout too.
The data delivered can be grouped as follows:
- as Array
- as JSON with the key "btevent"
- as Number
Commands
The bluetooth agent has two nested command loops, an inner and an outer command loop.
The inner loop has a very limited command set and runs while data will be transferred.
outer command loop :
| Command |
description |
result |
| scan |
Scan for bluetooth devices named "SmartCov*" |
Array with one JSON for each device found |
| status |
Result of the last scan |
Todo Siegmar |
| notify <device-name> |
Start reading data from (Start connection to) <device-name>.<device-name> must have been found by a previous scan. If the device isn't paired yet it will be paired before. |
Todo Siegmar |
| set nonulls on|off |
Switch suppression of NULL pressure images (images without any pressure).The initial setting (default) is off unless btagent was started with the Option '-n'. |
Todo Siegmar |
| stop Dummy command |
If in the inner loop the connection ends unexpectedly,
btagent continues waiting for a command to exit this loop.
So when trying to connect again
a 'stop' to the inner loop must be sent before.
Having this dummy command in the outer loop too the client doesn't have to care about
unexpected disconnection.
He can simply send a 'stop' before every try to connect.
|
None |
| version |
Query bluetooth agents version. |
Todo Siegmar |
| quit |
Exit bluetooth agent.1) |
None |
inner command loop
| Command |
description |
result |
| stop |
Stop reading data (stop connection) and exit to outer command loop. |
None |
| quit |
Stop reading data (stop connection) and exit bluetooth agent.1) |
None |
1)Bluetooth agent will exit on receipt of EOF (Ctrl-D) on stdin too.
The TCL bluetooth interface
On startup of the vmkstationd3 loading the kernel module ::kernel::BTSattel this
module starts the bluetooth agent. It hides the communication details by offering
interface procedure calls.
To get informations about the connection status and to get the pressure pressure
data the application regsisters a connection change handler and a data handler rsp.
Commands (TCL-procedures)
::kernel::BTSattel::tryConnect [<device-name>] Try to connect to the only controller available or to the controller with <device-name>.
::kernel::BTSattel::disconnect Stop the current connection.
::kernel::BTSattel::agentVersion Query the blutooth agents version.
Callbacks for connection changes
To register a callback for connection changes call
::kernel::BTSattel::addConnectionHandler <handler-proc-name>
(Working with namespaces it's a good idea to set the complete namespace path for <handler-proc-name>.)
The connection handler must handle a JSON with the key "btevent".
Depending on that key's value there may be more keys fore the details.
In addition to the message object passed from the bluetooth agent the TCL interface
sends the following btevents:
| btevent |
detail-key |
class (error) |
value |
| status |
devices |
|
Array of device objects (Keys see btagent command scan) |
| error |
class |
|
The error class |
|
|
fail |
Expected device not found |
|
|
|
No device found |
|
|
client |
disconnect while trying connect (ignored) |
|
msg |
|
The error message |
| ambiguity |
devices |
|
Array with all device names |
| data |
|
|
Data are available |
To remove a callback for connection changes use ::kernel::BTSattel::removeConnectionHandler <handler-proc-name>
Callbacks for pressure data
To register a callback for pressure data call ::kernel::BTSattel::addDataHandler <handler-proc-name>
(Working with namespaces it's a good idea to set the complete namespace path for <handler-proc-name>.)
The data handler must accept the three arguments "values" (list of pressure values), "n_cols" (number of columns) and "n_rows" (number of rows).
To remove a callback for pressure data use ::kernel::BTSattel::removeDataHandler <handler-proc-name>