Raspberry Pi Ant+

Herzfrequenz und Wattwert per Ant+ mit einem Raspberry Pi empfangen und an einen MQTT-Broker senden.

In diesem Beitrag beschreibe ich den Empfang der Herzfrequenz und des Wattwertes und das Senden der Daten an einen MQTT-Broker mit einem Rapberry Pi.

Das Projekt entstand als ich im Winter 2019/2020 mit dem „zwiften“ anfing.

mein Zwift Setup

Ich wollte in erster Linie einen Kühllüfter, in Abhängigkeit der getretenen Leistung auf der Rolle, automatisch ansteuern.
Weiter wird in Abhängigkeit der Herzfrequenz ein LED-Stripe angesteuert.
Der LED-Stripe zeigt in unterschiedlichen Farben an, in welchem Herzfrequenzbereich ich aktuell gerade trainiere.

Der prinzipielle Ablauf der Steuerung des Kühllüfter und des LED-Stripe sieht wie folgt aus:

Der Wattwert wird von dem Wahoo Kickr Snap per Ant+ gesendet.
Die Herzfrequenz wird von dem Bustgrut per Ant+ gesendet.
Die beiden Werte werden von dem Rapberry Pi, an dem einen Ant+ USB-Stick angeschossen ist, empfangen.
Die Node.js Umgebung auf dem Rapberry Pi ermöglicht es ein entsprechendes Javascript laufen zu lassen, dass die Herzfrequenz und den Wattwert entsprechend aufbereitet und dann an einen MQTT-Broker sendet.
Der MQTT-Broker läuft bei mir in einer ioBroker Instanz.
Auf dem ioBroker wird dann mit weiteren Javascripten schliesslich der Kühllüfter und der LED-Stripe angesteuert.

Setup Raspberry Pi:

Hardware: Raspberry Pi Model B Revision 2.0 mit einer 16GB SD-Karte
Betriebssystem: Raspbian Buster Lite
Ant+ USB-Stick: BKOOL ANT+ USB 2.0 Stick
Node Version: v10.15.2
NPM Version: 5.8.0

Wie man eine Grundinstallation auf einem Raspberry Pi macht findet man zu genüge im Internet, daher gehe ich hier nicht weiter darauf ein.

Wenn das Rapberry Pi läuft und per SSH erreichbar ist, geht es per putty auf der Console des Raspberry Pi weiter:

Update des Raspberry Pi:

sudo apt-get update
sudo apt-get upgrade

Nodejs und NPM installieren:

sudo apt-get install nodejs npm

Versionen anzeigen:

pi@powerraspi01:~ $ node -v
v10.15.2

pi@powerraspi01:~ $ npm -v
5.8.0

udev-Regel für den Ant+ USB-Stick einrichten:

idVendor und idProduct des Ant+ USB-Stick anzeigen:

pi@powerraspi01:~ $ lsusb
Bus 001 Device 004: ID 0fcf:1009 Dynastream Innovations, Inc. ANTUSB-m Stick
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp. SMC9512/9514 USB Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

udev-Regel anlegen:

sudo nano /etc/udev/rules.d/ant-usb-m.rules

folgende Zeile in die Datei einfügen, idVendor, idProduct, vendor und product entsprechend anpassen:

SUBSYSTEM=="usb", ATTRS{idVendor}=="0fcf", ATTRS{idProduct}=="1009", RUN+="/sbin/modprobe usbserial vendor=0x0fcf product=0x1009", MODE="0666", OWNER="pi", GROUP="root"

Javascript erstellen um die Ant+ Daten auszuwerten und an einen MQTT-Broker senden:

Ordner erstellen in dem das Script abgelegt wird:

mkdir npm
cd npm 
mkdir zwiftapp
cd zwiftapp

Voraussetzungen für die Libarys schafen:

sudo apt-get install build-essential libudev-dev

benötigte Libarys installiern (mqtt und ant-plus):

npm install
npm install mqtt
npm install ant-plus

Javascript erstellen um die Ant+ Daten auszuwerten und an einen MQTT-Broker senden:

sudo nano heartrate_power_mqtt_V2.js

Inhalt des Scriptes „heartrate_power_mqtt_V2.js“:

/* Wattwert und Herzfrequenz per ANT+ auslesen und 
   an einen MQTT-Broker senden R.R. 21.11.2019

Script: heartrate_power_mqtt_V2.js
Autor: infinityflow.ch
NODE  Verson: v10.15.2
NPM Version: 5.8.0


zusaetzliche Libarys:

ant-plus https://www.npmjs.com/package/ant-plus
mqtt https://www.npmjs.com/package/mqtt

*/

// Variablen fuer mqtt:

var mqtt = require('mqtt')

// IP des MQTT-Broker anpassen
var client = mqtt.connect('mqtt://10.0.0.21')

// Intervall fuer das Senden der Daten an den MQTT-Broker in ms z.B. alle 10s = 10000
var mqttsendeintervall = setInterval(mqttsend, 10000);

// MQTT Topics fuer den Wattwert und die Herzfrequenz
var topic_watt = "fancontroll/power";
var topic_heartrate = "fancontroll/heartrate";

// Hilfsvariablen fuer das Senden per MQTT
var powermqtt = "0";
var heartratemqtt = "0";

// Variablen fuer mqtt Ende


// Wattwert und Herzfrequenz per ant-plus auslesen:

var Ant = require('ant-plus');

function openStick(stick, stickid) {
        var sensor1 = new Ant.HeartRateSensor(stick);

        var dev_id = 0;

        sensor1.on('hbdata', function(data) {
                console.log(stickid, 'sensor 1: ', data.DeviceID, data.ComputedHeartRate);
                heartratemqtt = data.ComputedHeartRate;
        });

        sensor1.on('attached', function() { console.log(stickid, 'sensor1 attached'); });

        var sensor2 = new Ant.BicyclePowerSensor(stick);

        sensor2.on('powerData', function(data) {
                console.log(stickid, 'sensor 2: ', data.DeviceID, data.Power);
                powermqtt = data.Power;
        });

        sensor2.on('attached', function() { console.log(stickid, 'sensor2 attached'); });


        stick.on('startup', function() {
                console.log(stickid, 'startup');

                console.log(stickid, 'Max channels:', stick.maxChannels);

                sensor1.attach(0, 0);

                sensor2.attach(1, 0);
        });


        function tryOpen(stick) {
                let token = stick.openAsync((err) => {
                        token = null;
                        if (err) {
                                console.error(stickid, err);
                        } else {
                                console.log(stickid, 'Stick found');
                        }
                });

                return token;
        }

tryOpen(stick);

}

openStick(new Ant.GarminStick2(), 1);
openStick(new Ant.GarminStick2(), 2);
openStick(new Ant.GarminStick3(), 3);

openStick(new Ant.GarminStick2(), 4);
openStick(new Ant.GarminStick2(), 5);
openStick(new Ant.GarminStick3(), 6);

// Wattwert und die Herzfrequenz per ant-plus auslesen Ende


// Wattwert und die Herzfrequenz per MQTT an den iobroker senden

function mqttsend() {
        var power_string = powermqtt.toString();
        var heartrate_string = heartratemqtt.toString();
        client.publish(topic_heartrate, heartrate_string);
        client.publish(topic_watt, power_string);
        console.log("Wert der Variable heartrate_string:" ,heartrate_string, "Hz");
        console.log("Wert der Variable power_string:" ,power_string, "Watt");
}

mqttsend();

// Wattwert und die Herzfrequenz per MQTT an den iobroker senden Ende

Autostart des Javascript „heartrate_power_mqtt_V2.js“ anlegen:

sudo nano /etc/init.d/power_mqtt

Inhalt des Start-Stop Scriptes:

den Inhalt dieser Init-Script Vorlage in die power_mqtt kopieren

die folgenden Parameter müssen angepasst werden:

dir="/home/pi/npm/zwiftapp"
cmd="node heartrate_power_mqtt_V2.js"
user="root"

Skript ausführbar machen:

sudo chmod 755 /etc/init.d/power_mqtt

Autostart aktivieren:

sudo update-rc.d power_mqtt defaults

manuell kann man das Script wie folgt starten, stopen und neustarten:

sudo /etc/init.d/power_mqtt start
sudo /etc/init.d/power_mqtt stop
sudo /etc/init.d/power_mqtt restart

Somit sollte jetzt der Raspberry Pi automatisch, sobald er gestartet ist, die Ant+ Daten empfangen und alle 10s an einen MQTT-Broker senden.

quick and dirty 🙂

Facebooktwittermail

Kommentar hinterlassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.