Skip to main content

How to automatically create a website with your newest komoot tour

How to automatically create a website with your newest komoot tour

I wanted to include a komoot tour into a website. For this use case komoot offers to embed a tour as an iframe. Since I don't feel like updating the iframe-link on the website every time there is a new tour I decided to write a small script to automate this task. There are still some details I want to improve in the future that you can find at the end of this post. But for now this script works as intended.

Prerequisite

For this tutorial you should have:
- a linux server with its own IPV4 address
- a domain name under your control

Depending on where you want to embed your iframe it might be enought to have an IPV6 address with no domain name.

Installing

First you have to install some packages:

sudo apt install python3 python3-pip nginx snapd
sudo snap install certbot --classic

Then install the PyPi package komootgpx. This tool is used to get a list of all your planned tours. You can install it either in a python virtual environment or system wide like I did:

pip3 install --break-system-packages komootgpx

Then add komootgpx to your PATH so you can call the command from any directory. To do this check the output from the last command. This should show you where the package was installed to. In my case it was "/home/ubuntu/.local/bin", so I added this path to /etc/environment and sourced it:

sudoedit /etc/environment
. /etc/environment

Configure HTTPS

Next up configure HTTPS for your domain so the connection between the user and the server is encrypted.

Leaving out this step might give you trouble when defining the link in the iframe (some web hosters demand an HTTPS-Link).

  1. Point your domain name to your IPV4 address
  2. Add a dummy nginx config with your domain name as the server_name. Restart nginx with sudo systemctl restart nginx.service
  3. Enable HTTPS for this domain with sudo certbot --nginx

Now you should be able to access your server over you domain name with HTTPS.

The script

Create a new file in your desired directory and change the permission:

touch my-script.sh
chmod +x my-script.sh

Then add the following content to your script:

#!/bin/bash

OUTPUT=$(komootgpx --mail=your-kommot-mail-adress@example.com --pass=your-komoot-password -a -t=planned -l --start-date=$(date -I --date="1 day ago") | tail -1 | cut -c1-10)
re='^[0-9]+$'
if [[ $OUTPUT =~ $re ]]
then
    sudo rm /etc/nginx/sites-available/forward
    echo "server {
        server_name your-website.example.com;
        add_header Cache-Control \"no-store, no-cache\";
    if_modified_since off;
    expires off;
    etag off;
        location / {
            return 301 https://www.komoot.com/tour/$OUTPUT/embed;
        }
        listen 443 ssl; # managed by Certbot
        ssl_certificate /etc/letsencrypt/live/your-website.example.com/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/your-website.example.com/privkey.pem; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    }
server {
    if (\$host = your-website.example.com) {
        return 301 https://\$host\$request_uri;
    } # managed by Certbot
        listen 80;
        server_name your-website.example.com;
    return 404; # managed by Certbot
}" | sudo tee /etc/nginx/sites-available/forward > /dev/null
    sudo systemctl restart nginx.service
else
    exit 0;
fi

Don't forget to change the login information to your komoot account (--mail and --pass) and the domain name of your website (replace your-website.example.com with your actual domain).

This script does the following:

  1. Get all komoot tours of the specified user that were planned today or yesterday. Only use the last line (the oldest tour) and the first 10 characters (unique id of a komoot tour). Write this to the variable OUTPUT.
  2. Test if OUTPUT is a number. If yes, then:
    1. Remove the current nginx config in /etc/nginx/sites-availabe/ that is called 'forward'
    2. Write a new config in the same place using your new OUTPUT
    3. Restart nginx.service
  3. If there is no new tour (so OUTPUT is not a number), then do nothing and exit script.

To test the script create a new komoot tour and execute the script. It should replace/create your nginx config and reload nginx. If you visit your website you now get redirected to your komoot-tour.

Cronjob

If the last step worked you can add the script as a cron job:

crontab -e

Then add the following line after specifying the script's location:

15 1 * * * /home/ubuntu/my-script.sh

This executes the script at 1:15 in the night every day. You can tweak this value to your likings.

Website integration

On your website add an iframe with the following content (replace the domain with your own):

<iframe src="https://my-website.example.com" width="100%" height="600" frameborder="0" scrolling="no"></iframe>

Your website now redirects you to the komoot-website of your newest tour.

To do

These are things I want to improve in my script in the future:
- [ ] Don't just use the last line of the planned tours list, but use the first with the 10 digit code as this is the most current tour (was out of scope for this project since there's only one new tour every month)
- [ ] Make the domain name a variable in the script
- [ ] Follow best practices for using sudo in a script
- [ ] Install the komootgpx package in virtual env instead of system wide
- [ ] Maybe use a more sophisticated way to find the newest tour instead of just choosing one from the last 1-2 days
- [ ] Private Tours might lead to an error because non-logged in users can't see them. Maybe there is a way to filter them.

How good is the Garmin Forerunner 265's heart rate sensor?

I recently bought the Garmin Forerunner 265 after I did a lot of research on what the best fitness watch is for my use case. On my way I found The Quantified Scientist, a YouTuber that does a lot of testing on fitness gadgets in a scientific way. Unfortunately he hasn't done a video on the Forerunner 265 yet, so I decided to make some tests on my own to validate how good the watch's heart rate sensor really is. These tests and the representation of the results were heavily inspired by him. To see the technical background on how I did the testing and the data analysis, take a look at the end of this post.
To sum it up I wore a really accurate heart rate chest strap and the watch at the same time and compared the measured values. For each sport I created two types of diagrams:

  1. A scatter plot. Every point represents the sensors' readings at a time. A point's x-value shows what the chest strap measured and its y-value shows what the watch measured at this point in time. If they measure the same value (so the watch is 100% accurate) the point is on the red line. If the watch measures a heart rate lower than the actual heart rate the point is to the right of the red line and if it's higher then it's to its left. So the more points are close to the red line, the more accurate the watch's sensor is. The points are also transparent so the more points there are the darker the spot gets.
    I also added the correlation (the R-Value) to the top left. To put it in simple words: The higher the value, the more accurate is the sensor. 1 is the maximum and 0 would mean that the readings are completely random.
  2. A line diagram. This diagram shows the heart rate (y-value) over the time (x-value). There are two lines: The red line is the watch's measured heart rate and the blue line is the reference heart rate from the chest strap. The more these two lines match, the better is the watch's accuracy. With this type of diagram you can see if the watch lags behind the real heart rate or if it misses spikes

I did tests with the following sports:
- Badminton
- Longboarding
- ...

Badminton

I recorded a 2 hour session of badminton.
image1
The scatter plot looks pretty good. Most of the points are really close to the red line. Some of the points are below the line, which indicates that the watch underestimated the heart rate. Those seem to be rare outliers since those aren't many points. The correlation of 0.91 is pretty decent but in comparison to other watches it's on the lower end. This YouTube-video from the Quantified Scientist shows the correlation of all the other watches he tested to have a reference. It's really not bad but there are many models that perform better.

image2
The line diagram gives us some insight on why and at which points the watch got inaccurate. This diagram is only a snapshot of the two hour session since you can't see the fine differences on such a large scale. As you can see the watch often lagged behind a little bit. This isn't too bad for this kind of sport since I'm interested in the time I spend in the heart rate zones which isn't affected by this lag. The watch had some trouble picking up some smaller changes in heart rate and measured a higher heart rate than it should have. Apart from the outliers you can see in the scatter plot (that isn't part of this snapshot) the watch's heart rate was never really lower than the chest strap's one.

I'm pretty happy with these result for badminton. I only need the heart rate in this sport for the Garmin to determine my acute load and training effect to get insight on the effects on my total training load. For this purpose the sensor is accurate enough. Especially in badminton my top priority is having fun.

To be continued

I will expand and update this post with more data on different types of sports like longboarding, cycling, running, swimming and more in the future.

Technical background

How to get the measurements

In my tests I did different types of sports while wearing both the Garmin Forerunner 265 and the Polar H10 heart rate chest strap. These measurements were recorded simultaneously using the ANT+ HRM Heart Rate Monitor data field from the Garmin Connect IQ Store. You just add it to an activity as a data field and it will record both the watch's and your chest strap's data. If you want to do this yourself, you should take a look at the app's manual. I also decided to disable the heart rate alarm that made a sound everytime my heart rate drops under zone 1 (go the app in your Connect IQ store, go to "Settings" and put a "0" in the "Low HR Alert" field of every user). After you added your data field and adjusted the settings you just record an activity like you usually would. When you finished the activity you can see a new diagram in you Garmin Connect (Web-)App: ANT Heart rate (bpm). This is your cheast strap's measured heart rate. It might be tempting to use Garmin's built in overlay feature that lays one measurement over the other. But if the minimal and maximal measurements weren't the exact same the scale will be different. So the ANT Heart Rate has a scale from 100 to 200 and the watch has one from 80 to 200. This cannnot be used to compare.

How to use the data

To use the data in an external program you can download it in the .FIT file format. Then I used the FIT SDK to convert the FIT file to a CSV file. Just download the SDK, extract it, go into the java directory, open a terminal and execute this command where the last argument is your downloded .FIT file:

java -jar FitCSVTool.jar ./19434511632_ACTIVITY.fit.

Now you have a .CSV file with a bunch of values. You could write a script that deletes all the unneccessary and invalid data. But since I won't be doing this very often I manually edited the file in LibreOffice Calc. I removed all columns except the time stamp, the watch's and the chest strap's heart rate readings. I also removed every line that has no heart rate (0bpm) or an extremely low heart rate (like every value under 40). For the scatter plot I had to use MICRO$OFT Excel since LibreOffice doesn't have an option to make the data points transparent. For the line diagram I could use LibreOffice Calc. I needed to do some fine tuning to get the diagrams just the way I wanted. To get the correlation you can use this document.

How to add Eglo smart light to the app and remote controller simultaneously

I had to do a lot of research to connect my Eglo smart light (the model ECeil_G30, not sold anymore) to both the AwoX Smart CONTROL app and the physical remote controller. To save you from the hassle to find it out yourself I wrote this short tutorial. In the end you will have all your lights inside the app and you will also be able to control them seperately with their dedicated phyiscal controller.

  1. Reset the light bulb to factory default (https://www.youtube.com/watch?v=xeEryXGCfKA&t=6)
  2. Add a new device in the app (Go to "My devices", press the plus in the top right corner and set up your lamp)
  3. Reset your remote controller (simultaneously press "On" and "color cycle" for three seconds) (https://awox.support.awox.group/kb/article/1255-06-reset-the-remote-control/)
  4. Change your remote controller into the smartphone mode (simultaneously press "On" and "blue" for three seconds) (https://youtu.be/VIYTRmc6a3s?feature=shared&t=27)
  5. Add the remote controller inside the app (Go to "My Controller", press the plus in the top right corner and set up your controller)