Omar Almatov
Published © GPL3+

MeteoStation + Telegram bot + SQLite3

This is a simple weather station that can measure PM 1.0, PM 2.5, PM 10.0, CO2, TVOC, humidity, pressure, and temperature.

IntermediateShowcase (no instructions)2,627
MeteoStation + Telegram bot + SQLite3

Things used in this project

Hardware components

Seeed Studio HM3301
×1
Adafruit BMP280
×1
SparkFun Air Quality Breakout - CCS811
SparkFun Air Quality Breakout - CCS811
×1
Gravity:SHT1x Humidity and Temperature Sensor
DFRobot Gravity:SHT1x Humidity and Temperature Sensor
×1
Raspberry Pi 3 Model B
Raspberry Pi 3 Model B
×1

Software apps and online services

Raspbian
Raspberry Pi Raspbian

Story

Read more

Code

meteo_sqlite3.cpp

C/C++
A program that collects data from the MeteoStation and saves it to an SQLite database.
#include <getopt.h>
#include <sstream>
#include <ctime>
#include <sqlite3.h>

#include "bmp280.h"
#include "ccs811.h"
#include "hm3301.h"
#include "sht20.h"

using namespace std;

const char*     DB_FILE( "/var/lib/sqlite3/meteo.db" );

static struct option LONGOPTIONS_[] = 
{
    { "reset",          no_argument,    nullptr, 'r' },
    { "environment",    no_argument,    nullptr, 'e' },
    { "help",           no_argument,    nullptr, 'h' },
    { nullptr,          0,              nullptr,  0  }
};

int main( int argc, char* argv[] )
{
    Bmp280      bmp280( "/dev/i2c-1", 0x77 );
    Ccs811      ccs811( "/dev/i2c-1", 0x5A );
    Hm3301      hm3301( "/dev/i2c-0", 0x40 );
    Sht20       sht20( "/dev/i2c-1", 0x40 );
    string      progname( argv[0] );
    int         opt;

    bmp280.readData();
    ccs811.readData();
    hm3301.readData();
    sht20.readData();

    while ( (opt = getopt_long(argc,argv,"reh",LONGOPTIONS_,nullptr)) != -1 )
    {
        switch ( opt )
        {
            case 'r':

                ccs811.reset();

            break;

            case 'e':

                ccs811.setEnvironmentalData( sht20.humidity(), sht20.temperature() );

            break;
            
            case 'h':
            default:

            cout << 
            "Usage: " << progname << " [options]\n"
            "\t-r --reset\t\tReset CCS811\n"
            "\t-e --humidity\t\tSet environmental data\n"
            "\t-h --help \t\tPrint help message\n";

            return EXIT_SUCCESS;
        }
    }

    sqlite3*    db;

    if ( sqlite3_open(DB_FILE, &db) )
    {
        cerr << "Cannot open database" << endl;
    }

    stringstream    sql;

    sql << "INSERT INTO meteo VALUES ("; 
    sql << time(nullptr) << ", "; 
    sql << dec << bmp280.temperature() << ", "; 
    sql << sht20.humidity() << ", "; 
    sql << dec << bmp280.pressure() << ", ";
    sql << ccs811.co2() << ", ";
    sql << ccs811.tvoc() << ", ";
    sql << hm3301.spm010() << ", ";
    sql << hm3301.spm025() << ", ";
    sql << hm3301.spm100() << ");";

    cout << sql.str() << endl;


    sqlite3_exec( db, sql.str().c_str(), nullptr, nullptr, nullptr );

    /*cout << "Temperature: " << dec << bmp280.temperature() << " C" << endl;
    cout << "Pressure: " << dec << bmp280.pressure() << endl; 
    cout << "CO2: " << ccs811.co2() << endl;
    cout << "TVOC: " << ccs811.tvoc() << endl;
    cout << "Humidity: " << sht20.humidity() << "%" << endl;
    cout << "Standard PM1.0\t" << hm3301.spm010() << endl;
    cout << "Standard PM2.5\t" << hm3301.spm025() << endl;
    cout << "Standard PM10\t" << hm3301.spm100() << endl;*/
}

meteo_bot.js

JavaScript
A Telegram bot that outputs data collected from the MeteoStation.
//meteo_bot.js

const Telegraf = require('telegraf')
const Sqlite3 = require('sqlite3-arm')

let bot = new Telegraf(process.env.TELEGRAM_API_TOKEN)

let db = new Sqlite3.Database('/var/lib/sqlite3/meteo.db', (err) => {
    if (err) {
        throw err
    }
    console.log('Connected to database')
})

let sql = 'SELECT * FROM meteo WHERE time = (SELECT MAX(time) FROM meteo)'

var press, humidity, co2, tvoc, pm010, pm025, pm100

var data = new Array(8)

function update_data() {
    db.get(sql, [], (err, row) => {
        if (err) {
            throw err
        }
        data[0] = row.temperature
        data[1] = row.pressure
        data[2] = row.humidity
        data[3] = row.co2
        data[4] = row.tvoc
        data[5] = row.pm010
        data[6] = row.pm025
        data[7] = row.pm100
        console.log(data)
        console.log(row)
    })
}

let help_message = 'This is MeteoStation Bot developed by Omar Almatov.\n\n' + 
                   'Here is a list of all commands:\n\n' +
                   '/help - list of commands\n' +
                   '/temperature - displays temperature\n' +
                   '/pressure - displays pressure\n' +
                   '/humidity - displays humidity\n' +
                   '/co2 - displays CO2\n' +
                   '/tvoc - displays TVOC\n' +
                   '/pm - displays standard particulate matter concentration\n\n' +
                   'All data is only relevant to Almaty, Kazakhstan'

bot.command('/help', (ctx) => ctx.reply(help_message))
bot.command('/start', (ctx) => ctx.reply(help_message))
bot.command('/info', (ctx) => ctx.reply(help_message))
bot.command('/temperature', (ctx) => {
    update_data()
    ctx.reply('Temperature is ' +  data[0] + ' degrees Celcius')
})
bot.command('/pressure', (ctx) => { 
    update_data()
    ctx.reply('Pressure is ' + data[1] + ' hPa')
})
bot.command('/humidity', (ctx) => {
    update_data()
    ctx.reply('humidity is ' + data[2] + ' %')
})
bot.command('/co2', (ctx) => {
    update_data()
    ctx.reply('CO2 levels are ' + data[3] + ' (ppm)')
})
bot.command('/tvoc', (ctx) => {
    update_data()
    ctx.reply('TVOC levels are ' + data[4] + ' (ppm)')
})
bot.command('/pm', (ctx) => {
    update_data()
    ctx.reply('PM 1.0 concentration is ' + data[5] + ' u3/mg\n' +
              'PM 2.5 concentration is ' + data[6] + ' u3/mg\n' +
              'PM 10.0 concentration is ' + data[7] + ' u3/mg\n')
})

update_data()
bot.launch()

BMP280

HM3301

CCS811

SHT20

Credits

Omar Almatov

Omar Almatov

1 project • 0 followers

Comments