A Telegram Bot to retrieve data from RuuviTag

Ruuvitag, the new Bluetooth sensor device from Ruuvi, is a flexible, open source platform you can use to develop your own great applications. As an example I am going to show you how to build a simple weather station using a Ruuvitag and a Raspberry Pi. The major feature of this project is the possibility to interact with the weather station using the power of Telegram Messenger Bots.

Ruuvitag: an advanced open-source sensor beacon platform.

In this tutorial I will refer to the use of a Raspberry Pi as a gateway between the RuuviTag and the Internet. Clearly a NodeJS application can be run on any machine with the node framework installed. I use the Raspberry Pi because it is a tiny, single board pc with an integrated Bluetooth module. If you want to use another board with a compatible Bluetooth module you will need to use the appropriate library.

I am including here all the steps you need to set up the device and the Raspberry Pi. If you are familiar with RaspberryPi you can just skip the preliminary sections and jump directly to section n°2.

1. Raspberry Pi setup

Before proceeding with the installation of Raspbian on the Pi, make sure you have:

  • An SD card (a proper installation of Rasbpian OS requires at least 8GB).
  • An HDMI cable and a monitor/TV (needed only for the first configuration).
  • A mouse and a Keyboard (needed only for the first configuration).
  • An Ethernet cable (needed only for the first configuration).
  • A power adapter (output 5V — at least 2A) and a micro-USB cable.
Raspberry Pi.

Download the last Raspbian OS version from the official Raspberry Pi site and use Etcher to burn it into your SD card. Insert the card in your Raspberry Pi. Turn it on connecting the power supply and go through the initial set up (time & date, memory extension on the entire SD, WiFi or Ethernet, keyboard input language; enable SSH).
I suggest you setup a static ip and also use WiFi (instead of Ethernet cable). In this way you can connect to your RPi using your laptop, and you won’t need the Ethernet cable, the HDMI cable, the monitor, the mouse and the keyboard! But I won’t go deep into the details of this configuration.

2. Install all needed packages on the Raspberry

Before installing the NodeJS framework, npm and all other needed libraries, I suggest you run the commands to upgrade and reboot your Raspberry:

sudo apt-get update -y
sudo apt-get upgrade -y
sudo apt-get dist-upgrade -y
sudo apt-get install rpi-update -y
sudo apt-get autoremove -y
sudo apt-get clean -y
sudo reboot

When you are done with the update, you can install NodeJS and the npm packet manager:

curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs

To check that the installations have correctly completed, run the following commands:

node --version
npm --version

You should see node version: v8.9.1 or higher, npm version: 5.5.1 or higher (these are the values I obtained at the time of writing, 26/11/2017).

3. Read data from the Ruuvitag

Now we’ll create a simple node app, using the npm library node-ruuvitag. The app will read all the enviromental measurements from the Ruuvitag nearby using the Raspberry Pi integrated Bluetooth module. 
In a directory of your choice on the Raspberry Pi create a new folder that will contain our node project (I called the new project Ruuvitag_test), and in that folder an index.js file with this code:

const ruuvi = require('node-ruuvitag');

ruuvi.on('found', tag => {
console.log('Found RuuviTag, id: ' + tag.id);
tag.on('updated', data => {
console.log('Got data from RuuviTag ' + tag.id + ':\n' +
JSON.stringify(data, null, '\t'));
});
});

When you run this code, every time a new ruuvi is ‘found’ the Raspberry Pi starts listening for a new ‘update’ message and prints on the console all the retrieved data. Execute the following command from the command line, with your local directory set to your project folder (Ruuvitag_test):

npm install node-ruuvitag --production

This will create a node_modules folder where the node-ruuvitag npm package and all its dependencies will be stored. The command also creates two other files: the most important is the package.json that lists all the dependencies that will installed in our project.
To run our application, run this command (inside your project folder):

sudo node index.js

If one or more Ruuvitags are found in the proximity of your Raspberry Pi, all the corresponding measurements will be printed on the console:

Found RuuviTag, id: XXXXXXXXXXXX
Got data from RuuviTag XXXXXXXXXXXX:
{
"dataFormat": 3,
"rssi": -69,
"humidity": 37.5,
"temperature": 23.36,
"pressure": 97547,
"accelerationX": 398,
"accelerationY": -343,
"accelerationZ": 871,
"battery": 3067
}
Found RuuviTag, id: YYYYYYYYYYYY
Got data from RuuviTag YYYYYYYYYYYY:
{
"dataFormat": 3,
"rssi": -90,
"humidity": 41,
"temperature": 21.72,
"pressure": 97440,
"accelerationX": -7,
"accelerationY": 3,
"accelerationZ": 1027,
"battery": 3073
}

4. Activating a new Telegram Bot

To create a new Bot you need to access the Telegram application (it is available for PC/Mac/Linux/iOS/Android/Web) and start a chat with @BotFather in order to get the token.

”The Botfather”.

All available commands that a Bot can execute start with ‘/’. 
If you start typing ‘/’ the list of commands is shown. 
Now type:

/newbot

Follow all the instructions in order to create your new Bot: you need to choose a name (the name that will be displayed) and a nickname (the name of your Bot that you can find on Telegram: @Botname) and at the end you’ll get the bot token. There are many other options that you can set on your Bot (list of commands, description, profile image…) but I won’t deal with with them here.

Now that you have created your bot, I’ll show you how to build a simple node app (usingn the telebot npm library) that reacts to the ‘/hello’ command. As before, create a new folder for this new project (I named it Telegram_test). In that folder create an index.js file:

const TeleBot = require('telebot');
const bot = new TeleBot({
token: 'YOUR_BOT_TOKEN_HERE',
polling: {
interval: 1000, // How often check updates (in ms).
timeout: 0, // Update polling timeout (0 - short polling).
limit: 100, // Limits the number of updates to be retrieved.
retryTimeout: 5000, // Optional. Reconnecting timeout (in ms).
}
});
// wait for '/hello' command
bot.on('/hello', (msg) => msg.reply.text("Hello! :)"));
// start bot
bot.start();

Replace YOUR_BOT_TOKEN_HERE with the token received from BotFather. Then install all dependencies using the following command (again 2 additional files will be created, and in node_modules you will find all the dependecies):

npm install telebot --save

Run your node application:

node index.js

And you will see as output:

[bot.plugin] loaded ‘regExpMessage’ plugin
[bot.plugin] loaded ‘shortReply’ plugin
[bot.info] bot started

Now open Telegram and write ‘/hello’ to @your_bot_name (that you decided before) and you will receive “Hello! :)” as a response!

When you start writing to the Bot, a ‘/start’ command is automatically sent. You should always implement in your code a response to this command that lists all the commands made available by your Bot, or a description (in my case it is empty, this is why in the picture above you see no response for that command).

5. Set up a Telegram Bot to retrieve data data from RuuviTags

ruuvitag-telegram-bot library ecosystem.

I developed a npm library (ruuvitag-telegram-bot) that lets you manage different Ruuvitags and, using the two npm libraries previously discussed, permits to retrieve environmental data through a Telegram Bot.
You must declare all your Ruuvitags and associate each one with a place where are you going to settle it.

As before, create a new folder for this project (RuuviTelegramBot in my case) and write a new index.js file with this code:

const RuuviTelegramBot = require("ruuvitag-telegram-bot");
//my Ruuvitags
const places = ["place1", "place2"];
const Ruuvitags = {
<ruuvi_uuid_1>: {
"uuid": <ruuvi_uuid_1>,
"ruuviid": <your_ruuvi_id>,
"name": <your_ruuvi_id>,
"location": places[0],
"last_data": ""
},
<ruuvi_uuid_1>: {
"uuid": <ruuvi_uuid_1>,
"ruuviid": <your_ruuvi_id>,
"name": <your_ruuvi_id>,
"location": places[1],
"last_data": ""
}
};
// telegram token
const TELEGRAM_BOT_TOKEN = <your_bot_token>;
let ruuviTelegramBot = new RuuviTelegramBot(places, Ruuvitags, TELEGRAM_BOT_TOKEN);

Of course you must replace all variables inside <> with your values and also associate each place with the corresponding Ruuvitag.
Then execute inside your project folder this code to download my npm module and all needed dependencies:

npm i ruuvitag-telegram-bot --save

My module will create a new Telegram Bot (associated with the token that you provide) and a list of commands, therefore simplifying your work (you don’t need to create a command for each Ruuvitag).
The library automatically creates a ‘/start’ command, a command for each place you declared (each place is associated with a Ruuvitag) and a command that lists all measurements from all your Ruuvitags (‘all_available_ruuvitags’).

For example: if you declared two Ruuvitags and 2 places (Ruuvitag_1 on place_1 and Ruuvitag_2 on place_2), the library will start a Telegram Bot with these 4 predefined commands:

  • ‘/start’: list all available commands you can send to the Bot.
  • ‘/place1': retrieve all evironmental data from Ruuvitag_1 (settled on place_1).
  • ‘/place2': retrieve all evironmental data from Ruuvitag_2 (settled on place_2).
  • ‘/all_available_ruuvitags’: retrieve all evironmental data from all Ruuvitags and list them grouped by places.

If the Raspberry Pi cannot retrieve the data from one or more Ruuvitag (maybe because they are too far) you will see the message “Ruuvitag unreachable!”.

To start your Bot:

sudo node index.js

As before, you should see:

[bot.plugin] loaded ‘regExpMessage’ plugin
[bot.plugin] loaded ‘shortReply’ plugin
[bot.info] bot started

Now if you try this new Bot using Telegram Messenger you will receive all data from the requested Ruuvitag(s).
This is an example after sending the command ‘/place1’ to the Bot:

> Ruuvitag (your_ruuvi_id) @ place1
* Humidity: 39% RH
* Pressure: 978.93 hPa
* Temperature: 22.16 C°
* Battery: 100%

To let the Telegram Bot work in background even after closing the terminal window or SSH connection I suggest you use the screen utility. 
If you don’t use screen the Bot will stop when you close the terminal window.

To install screen utility run this command on your Raspberry Pi:

sudo apt-get install screen

Screen is very easy to use: you must create a new screen ‘session’, give it a name, run the command you want to leave in background and then detach the session. 
Create a new session:

screen -S foo

We want to run our bot in background, so run:

sudo node index.js

Then press ctrl+a and then ctrl+d to detach the session. After doing this you can close your terminal (even if you are on the same machine you run the Bot or you are on SSH) and the Telegram Bot will remain listening to your commands.
If you want to reattach to some detached session, type this command to see all available sessions:

screen -ls

Read the PID of the session you want to reattach to and type:

screen -r pid_number

You are now attached to the session with the pid_number you typed!


Telegram Bots have many other interesting features that can be implemented. You can find more about them reading in the Telegram Bot documentation and the npm library that we used previously: telebot.

For other details, regarding my library, you can find my npm module on npmjs.com and the complete library on github.