Skip to content

Commit

Permalink
Merge pull request #1 from tonymyatt/feature/zwifit-incline-tracker
Browse files Browse the repository at this point in the history
Feature/zwifit incline tracker
  • Loading branch information
tonymyatt authored Apr 22, 2020
2 parents bc8bb9f + 63ebfcd commit be3390d
Show file tree
Hide file tree
Showing 16 changed files with 9,756 additions and 1,407 deletions.
75 changes: 63 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
# Zwifit

Welcome to the cryptically named Zwifit! This NodeJS app joins Zwift with treadmills running iFit® with Wi-Fi.
Welcome to the cryptically named Zwifit! This NodeJS app joins Zwift with treadmills running iFit® with Wi-Fi/Bluetooth.

**Disclaimer:** I'm not associated with either company. Their trademarks and content are their own.
Heck, they might force me to take this down! But let's enjoy the *run* before they do.

## How This Works

This software connects to your iFit® treadmill over Wi-Fi to observe its speed and incline. It then
This software connects to your iFit® treadmill over Wi-Fi/Bluetooth to observe its speed and incline. It then
broadcasts that information over Bluetooth in a standard protocol that apps like Zwift are able to
understand.

## What Treadmills Are Compatible?

At the moment it seems hit or miss on which iFit treadmills with Wi-Fi work, but we are building a spreadsheet
At the moment it seems hit or miss on which iFit treadmills with Wi-Fi/Bluetooth work, but we are building a spreadsheet
over at the following URL. Look through that. You may also be interested in the TreadSync app, which has a similar
goal to this project, but runs in a slightly different way (on iOS devices).

http://bit.ly/TS-compat

## Minimum Requirements

1. A Wi-Fi connected iFit® treadmill; those treadmills that use Bluetooth instead of Wi-Fi likely will *not* work
1. A Wi-Fi/Bluetooth connected iFit® treadmill
2. Zwift running on your favorite device
3. A Raspberry Pi ZeroW or 3B running this software (this software works on versions of Mac OS X before Mojave, but our Bluetooth dependency is presently borked on Mojave -- Windows requires an external Bluetooth LE dongle be properly configured).
4. Know the IP address of your treadmill. (I recommend reserving this IP in your router so it doesn't change.)
4. For Wi-Fi connected treadmills: Know the IP address of your treadmill. (I recommend reserving this IP in your router so it doesn't change.)
5. You need to be minimally comfortable with a command line / terminal. Or have a nerdy friend!

Raspberry Pi Zero W: https://www.amazon.com/CanaKit-Raspberry-Wireless-Complete-Starter/dp/B072N3X39J/ref=sr_1_4?ie=UTF8&qid=1546535245&sr=8-4&keywords=raspberry+pi+zero+w
Expand All @@ -35,15 +35,22 @@ Note: the above is NOT an affiliate link, I don't get anything from you clicking

### Raspbian (Raspberry Pi)

This software works great on a **Raspberry Pi 3b+** or a **Zero W**. Follow all of these steps on your Pi itself, not on
This software works great on a **Raspberry Pi 3b+** or a **Raspberry Pi Zero W**. Follow all of these steps on your Pi itself, not on
your laptop or desktop! The easiest way to do this is to plug a monitor, keyboard and mouse in to your
Pi. Or, if you've set up SSH, you can `ssh` in to your Pi to follow these steps (hint: this option is in the configuration UI).

1. `sudo apt-get update`
2. Install the dependencies we need: `sudo apt-get install nodejs npm git bluetooth bluez libbluetooth-dev libudev-dev`
3. Turn off the system Bluetooth daemon so we can control it: `sudo systemctl disable bluetooth` (to reverse this, change `disable` to `enable`)
4. Turn the Bluetooth chip back on: `sudo hciconfig hci0 up`
5. Give NodeJS access to Bluetooth without sudo: ```sudo setcap cap_net_raw+eip $(eval readlink -f `which node`)```
2. Install the dependencies we need: `sudo apt-get install git bluetooth bluez libbluetooth-dev libudev-dev`
3. Install NodeJS 13.x
1. For **Raspberry Pi 3b+** run `curl -sL https://deb.nodesource.com/setup_13.x | sudo -E bash -` and `sudo apt install -y nodejs`
2. For **Raspberry Pi Zero W** use the [unofficial builds](https://github.com/nodejs/unofficial-builds/), because armv61 is not part of the official builds any more. Download the binaries, run
* `mkdir /opt`
* `tar -C /opt -xzvf node-v13.8.0-linux-armv61.tar.gz`
* `echo "export PATH=\$PATH:/opt/node-v13.8.0-linux-armv6l/bin" >> ~/.bashrc`
* exit and re-open terminal to activate changes
4. Turn off the system Bluetooth daemon so we can control it: `sudo systemctl disable bluetooth` (to reverse this, change `disable` to `enable`)
5. Turn the Bluetooth chip back on: `sudo hciconfig hci0 up`
6. Give NodeJS access to Bluetooth without sudo: ``sudo setcap cap_net_raw+eip $(eval readlink -f `which node`)``

### Windows

Expand All @@ -70,15 +77,17 @@ With the software requirements out of the way, you can run the following command
git clone https://github.com/dawsontoth/zwifit.git
cd zwifit
npm install
node app.js
npm start
```

The last command will guide you through connecting to your treadmill. It will save your answers, and
won't ask you in the future. Your answers are saved in the settings.conf file. To change them, simply
edit settings.conf (or delete it and run `node app.js` again).
edit settings.conf (or delete it and run `npm start` again).

## Automatic Startup

### Using PM2

Do you want this script to run in the background, even when you restart your computer? There are many
ways to accomplish this. Personally, I use a program called PM2.

Expand Down Expand Up @@ -113,6 +122,44 @@ git pull
pm2 restart all
```

### Using cron with automatic shutdown

If you use a Raspberry Pi it is crucial to shutdown using

```bash
sudo poweroff
```

to avoid damaging the SD card (google for it to find more information). To perform this action after every workout
in a convenient way there is the run-script `raspberrypi.sh` which can be used.

*Details:* If the environment variable `SHUTDOWN_ONDISCONNECT=1` is set for the Zwifit process then Zwifit stops after
loosing the Wifi/Bluetooth connection what is usually caused by switching off the treadmill. This situation is
detected by the run-script `raspberrypi.sh` to shutdown your Raspberry Pi properly.

Since the shutdown procedure requires `sudo` it is advisable to start the shell script using the root cron.
The run-script switches to the user `pi` for running Zwifit, so the root user is only used for shutdown.

To run Zwifit on startup edit the crontab by using

```bash
sudo crontab -e
```

and add this line at the end of the file:

```bash
@reboot nohup /home/pi/zwifit/raspberrypi.sh
```
(where you have to replace the path `/home/pi/zwifit` by the installation path of Zwifit at your system)

*Once applied steps for using the system are:*
1. Plug in your Raspberry Pi.
1. Wait until your treadmill enlights the connection led (or the control page http://raspberrypi.local:1337 is available and the ifit symbol is green) which takes 70 seconds using a Raspberry Pi ZeroW.
1. Do your workouts with Zwift and connect or disconnect to the simulated treadmill as often you need to.
1. Once you retire simple switch of your treadmill.
1. About 10 seconds later it is save to plugin off your Raspberry Pi.

## Calibration

Zwifit will report your treadmill's exact speed, as measured by the machine itself. You can use the calibration
Expand All @@ -125,6 +172,10 @@ The app runs a local web server that displays information from your treadmill, a

If you have a monitor or touch screen connected to your Pi, you can run it in Kiosk mode. It can launch the Zwifit UI automatically. Follow the steps in this article to get started: https://pimylifeup.com/raspberry-pi-kiosk/

## Set the incline according to your current Zwift session

Zwift does not send the current gain of your running session to the treadmill. However, you can use the software [zwifit-incline-tracker](https://github.com/RasPelikan/zwifit-incline-tracker) to achieve this regardless. These automatic updates are only processed if the treadmill is in the active status.

## Contributing

Pull requests are welcome! Do your best to emulate the code around what you are editing.
Expand Down
18 changes: 14 additions & 4 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
#!/usr/bin/env node
let oneTime = require('./src/oneTimeSetup');
const settings = require('./src/settings');

oneTime.setup(() => {

let ifit = require('./src/ifit'),
api = require('./src/api'),
let api = require('./src/api'),
bluetooth = require('./src/bluetooth'),
onDeath = require('death');

/*
Initialization.
*/
api.start();
bluetooth.start();
ifit.connect();
let ifit = undefined;
if (settings.ble) {
ifit = require('./src/ble/ifit');
} else {
ifit = require('./src/ifit');
}
if (process.env['SHUTDOWN_ONDISCONNECT']) {
ifit.connect(() => process.exit(99));
} else {
ifit.connect();
}
api.start(bluetooth, ifit);
onDeath(cleanUp);

/*
Expand Down
Loading

0 comments on commit be3390d

Please sign in to comment.