In questo mio primo maggio 2020 trascorso dentro casa, ho cercato di “cucinare” qualcosa di creativo a base di Raspberry Pi, Bot Telegram , Display LCD e Relè.
L’idea alla base della “ricetta” è quella di realizzare un sistema tale per cui, attraverso un Bot Telegram sia possibile inviare messaggi di comando, questi saranno ricevuti dal Raspberry Pi che provvedrà ad interpretare ed eseguire.
La figura mostra l’architettura ad alto livello della soluzione che ho implementato nella giornata del primo maggio e che vorrei discutere passo dopo passo insieme a voi nel corso di questo di articolo.
L’idea di base prevede che un utente, tramite l’applicazione Telegram (sia desktop sia mobile), effettui la registrazione ad un nostro Bot e successivamente possa attivare delle azioni sul Raspberry Pi attraverso un set di comandi inviati al Bot.
Il diagramma mostra la sequenza degli eventi , da 1 uno a quattro, su quest’ultimo, i messaggi o comandi inviati, sono elaborati dal Raspberry Telegram Bot, programma scritto in Python. Il Bot frutta le Telegram Bot API per recepire i comandi inviati dall’utente e interagisce poi con la parte hardware (relè e display LCD).
Il relè è il nostro attuatore su cui sono “riversate” le azioni che l’utente compie attraverso l’uso dei comandi, quest’ultimi sono visualizzati dal display LCD.
Figura 1 – Schema dell’architettura del Raspberry Pi Telegram Bot
1. Requisiti
Per raggiungere questo nostro obiettivo abbiamo bisogno di raccogliere un pochino di materiale, dobbiamo fare una sorta di lista della spesa, sia in termini hardware, sia in termini software. Partiamo dal basso, con la lista dell’hardware.
- Raspberry Pi: ho utilizzato la versione 3 Model B+ che sarà il riferimento di questo articolo. Per coloro che hanno a disposizione il Raspberry Pi 2 o il Raspberry Pi 4, non dovrebbe essere un problema;
- Modulo Relè: ho utilizzato il modello Elegoo 4 Channel DC 5V Modulo Relay con Accoppiatore Ottico. A quanto pare è difficile trovare questo modello, al suo posto, anche su Amazon, è stato sostituito con il modulo da otto. In ogni caso per questo esperimento va benissimo anche il modulo con due o al peggio un solo Relè;
- Display LCD: ho utilizzato un display LCD I2C 1602 16X2;
- Breadboard, GPIO Extender e Cavi Maschio a Femmina Dupont utilizzati per realizzare i collegamenti tra il Raspberry Pi, il modulo LCD e il modulo Relè.
Tutti i componenti hardware possono essere acquisitati separatamente, però, se l’argomento vi appassiona, consiglio l’acquisito dello Starter Kit Freenove RFID per Raspberry Pi. All’interno del kit sono inclusi gli ultimi elementi della nostra lista, oltre ad altri numerosi componenti. La figura a seguire mostra ogni componente hardware indicato dalla nostra lista.
Figura 2 – Vista dei componenti hardware utilizzati dal progetto
Per quanto riguarda il software abbiamo bisogno di:
- Raspbian OS: a meno di applicazioni particolari, questo sistema operativo basato su Debian è ottimizzato per la piattaforma Raspberry Pi. L’ultima versione disponibile è Raspbian Buster. Sul mio Raspberry Pi 3 B+ ho installato quest’ultima release. Per maggiori informazioni sull’installazione del sistema operativo, fare riferimento alla guida ufficiale (Installing operating system images). Questo sarà comunque il sistema operativo di riferimento;
- Python 3.x : sul mio Raspberry Pi ho installato sia la versione 2.7 (quella di default) sia la versione 3.7, quest’ultima disponibile OOTB con l’ultima versione di Raspbian OS;
- pyTelegramBotAPI: ho deciso d’utilizzare queste API che implementano le Telegram Bot API per la semplicità d’installazione e uso, oltre al fatto che tra le tante disponibili per Python, quest’implementazione è quella con la community più attiva e numerosa;
- Moduli software display LCD : moduli Python per utilizzare il display LCD. Utilizzeremo il moduli scritti da Freenove e reperibili dal loro repository GitHub.
Possiamo verificare che il software attualmente installato sia conforme ai requisiti accedendo alla console del Raspberry Pi ed eseguendo i comandi a seguire.
# Verifica della Release del Sistema Operativo $ cat /etc/os-release# Verifica della Release del Kernel$ uname -a
A seguire è mostrato l’output dei comandi precedenti eseguiti sul mio Raspberry Pi.
# Output del comando cat /etc/os-releasePRETTY\_NAME="Raspbian GNU/Linux 10 (buster)"NAME="Raspbian GNU/Linux"VERSION\_ID="10"VERSION="10 (buster)"VERSION\_CODENAME=busterID=raspbianID\_LIKE=debianHOME\_URL="http://www.raspbian.org/"SUPPORT\_URL="http://www.raspbian.org/RaspbianForums"BUG\_REPORT\_URL="http://www.raspbian.org/RaspbianBugs"# Output del comando uname -aLinux amusarra-rpi 4.19.97-v7+ #1294 SMP Thu Jan 30 13:15:58 GMT 2020 armv7l GNU/Linux
Per quanto concerne la versione di Python, a meno di casi particolari, su Raspbian OS dovrebbero essere installate due release di Python, la 2.x e la 3.x. La specifica minor version dipende dalla versione del sistema operativo. Nel caso di Raspbian OS Buster le versioni esatte sono:
- Python 2.7.16 (attiva per default)
- Python 3.7.3
Sul mio Raspberry Pi ho reso di default la versione 3.7.3 di Python, visto che questa è la versione richiesta per il corretto funzionamento del Bot che andremo a realizzare. Per rendere l’ultima versione di Python di default, è più che sufficiente aggiungere i seguenti alias su file ~/.bashrc
alias python='/usr/bin/python3'alias pip=pip3
1.1 Creazione del Bot Telegram
Dettaglio Bot Telegram @amusarra-rpi vista App Mobile
Prima di procedere oltre è necessario creare il Bot Telegram. Si tratta di chatbot automatici che possono essere programmati per rispondere a messaggi inviati da utenti.
L’articolo Creazione di un Bot Telegram, di Ludovico Russo, spiega in modo semplice ed efficace come creare il proprio Bot e non solo. In ogni caso esiste la documentazione ufficiale How do I create a bot.
Per questo esperimento ho creato il Bot Telegram @amusarra-rpi. Quando creerete il vostro Bot Telegram, fate attenzione a conservare con cura il token assegnato al vostro account collegato al Bot. Il token è necessario per comunicare con le API di Telegram Bot.
2. Installazione e test di pyTelegramBotAPI
Molto bene! Adesso che abbiamo ottenuto il nostro Bot Telegram, possiamo procedere con l’installazione dell’implementazione dell’ API Telegram Bot sul nostro Raspberry Pi. La procedura è veramente semplice e indicata sul README del progetto.
Per l’installazione utilizziamo pip (Python package manager) con il comando mostrato a seguire. L’attuale versione 3.7.1 implementa la versione 3.4 dell’API Telegram Bot. Ricordiamo di collegare il Raspberry Pi alla rete internet, via ethernet o WiFi.
$ pip install pyTelegramBotAPI
A seguire l’esempio di output del processo d’installazione. Con il fatto di aver reso Python 3 di default, pyTelegramBotAPI sarà installato per questa versione.
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simpleCollecting pyTelegramBotAPI Downloading https://www.piwheels.org/simple/pytelegrambotapi/pyTelegramBotAPI-3.7.1-py3-none-any.whl (50kB) 100% |████████████████████████████████| 51kB 161kB/sRequirement already satisfied: requests in /usr/lib/python3/dist-packages (from pyTelegramBotAPI) (2.12.4)Requirement already satisfied: six in /usr/lib/python3/dist-packages (from pyTelegramBotAPI) (1.12.0)Installing collected packages: pyTelegramBotAPISuccessfully installed pyTelegramBotAPI-3.7.1
Adesso che abbiamo installato pyTelegramBotAPI, è possibile eseguire un veloce test con lo scopo di accertare che l’installazione del software sia andata a buon fine e che il Bot Telegram funzioni correttamente. L’evidenziazione in rosso sulla figura è il token rilasciato in fase di creazione del Bot Telegram, mentre in giallo, sono evidenziati i due messaggi che sono stati inviati.
Figura 3 – Test Bot Telegram e pyTelegramBotAPI
Direttamente dall’interprete Python siamo stati in grado di verificare velocemente la corretta creazione del Bot Telegram e del funzionamento delle API pyTelegramBotAPI.
3. Configurazione del Raspberry Pi
Dando per scontato che il Raspberry Pi sia connesso correttamente alla rete internet e che opzionalmente sia abilitato l’accesso alla console via SSH, possiamo procedere con l’abilitazione del modulo I2C. Per fare quest’operazione è sufficiente avviare il software di configurazione raspi-config da avviare con il comando sudo.
Il Bus I2C (Inter-Integrated Circuit) è progettato per consentire le comunicazioni tra diversi circuiti integrati (IC). Nel caso del Raspberry Pi, uno di questi circuiti integrati è il processo Broadcom BCM2835 SoC, che costituisce il cuore del sistema. La particolarità dei pin associati all’I2C, è che includono l’accesso alle resistenze di pull-up del Raspberry Pi, questo si traduce nel fatto che non sono richieste resistenze esterne per accedere alle funzionalità del bus I2C.
Le figure a seguire mostrano gli step necessari all’abilitazione di I2C.
Figura 4 – Configurazione I2C tramite il tool di configurazione raspi-config
Figura 5 – Configurazione I2C tramite il tool di configurazione raspi-config
Figura 6 – Configurazione I2C tramite il tool di configurazione raspi-config
Figura 7 – Configurazione I2C tramite il tool di configurazione raspi-config
È possibile configurare I2C agendo direttamente sul file /boot/config.txt aggiungendo o modificando la riga indicata a seguire.
- dtparam=i2c_arm=on
A modifica effettuata, riavviamo il Raspberry Pi affinché renda attivo il bus I2C.
4. Schema elettrico della soluzione
Dando per scontato che abbiate tutto il materiale hardware a vostra disposizione, possiamo disporre tutti collegamenti tra i vari componenti hardware che compongono la soluzione, così come indicato dallo schema elettrico mostrato a seguire.
Al fine di facilitare i collegamenti ho indicato nelle note quali sono i pin (BCM) che ogni componente utilizzerà. Per quanto riguarda il layout del connettore J8 del Raspberry PI, fate riferimento alla documentazione ufficiale su GPIO (general-purpose input/output).
Figura 8 – Schema elettrico del Raspberry Pi Telegram Bot
Il display LCD è collegato all’interfaccia I2C. Grazie a quest’interfaccia abbiamo una riduzione nell’uso di pin, da ben sedici a quattro pin, di cui:
- Due Pin di alimentazione. VCC e GND. Questo display LCD richiede l’alimentazione a 5V, per cui dovrà essere collegato al pin 2 o 4 del connettore J8 del Raspberry Pi. Per GND in uno degli otto pin a disposizione;
- Due Pin per i dati
- SCL (Serial Clock): la prima connessione tra i dispositivi avviene tramite questo questo canale e impostata dal master per sincronizzare il trasferimento dei dati. Pin 5 (#3 BMC) del connettore J8 del Raspberry Pi;
- SDA (Serial Data): è la linea che trasferisce i dati avanti e indietro tra tutti i dispositivi sul bus I2C. Pin 3 (#2 BMC) del connettore J8 del Raspberry Pi.
Questo display LCD è in grado di funzionare tramite I2C grazie al modulo PCF8547T, quest’ultimo implementa il cosiddetto Remote 8-Bit I/O Expander for I2C Bus , che in questo caso specifico è prodotto dalla NXP Semiconductors ma non solo. In figura è mostrato il modulo montato dietro al (mio) display LCD.
Per maggiori informazioni di dettaglio sul modulo PCF8547 consiglio la lettura dell’articolo Modulo Expander bus I2C per Display LCD a matrice di caratteri.
Figura 9 – Modulo Expander bus I2C per Display LCD a matrice di caratteri
Il modulo Relè, nel mio caso costituito da quattro elementi, è collegato, oltre che all’alimentazione (sempre 5V), anche alle porte GPIO secondo lo schema seguente.
- Relè 1 IN1 => GPIO #23 (BMC) Pin 16
- Relè 2 IN2 => GPIO #24 (BMC) Pin 18
- Relè 3 IN3 => GPIO #25 (BMC) Pin 22
- Relè 4 IN4 => GPIO #16 (BMC) Pin 36
Figura 10 – Raspberry Pi GPIO BCM Pin number
Per maggiori dettagli sulle funzionalità avanzate dei pin GPIO consultare il diagramma di pinout interattivo di gadgetoid.
Credo che dal punto di vista dell’hardware che utilizzeremo per questa soluzione sia tutto abbastanza chiaro. Molto bene. Procediamo da questo punto in avanti con la parte software.
5. Progettazione del Bot Telegram
Fin qui abbiamo visto tutto quello che concerne la configurazione hardware della nostra soluzione. Adesso è arrivato il momento di concentrarsi sulle funzionalità che vogliamo implementare per il Bot Telegram. A seguire la lista delle macro funzionalità richieste.
- All’avvio del Bot mostrare sul display LCD un messaggio che indichi che il Bot è pronto;
- Alla registrazione degli utenti inviare un messaggio di benvenuto;
- Alla ricezione dei messaggi scrivere l’informazione sul display LCD (come per esempio l’invio di comandi)
- Gestire i seguenti comandi:
- /start : questo comando invia il messaggio di benvenuto e mostra sul display LCD il nuovo arrivato;
- /help : questo comando invia un messaggio di help circa l’uso del Bot;
- /get_relay_status : questo comando restituisce lo stato di ogni relè, se attivo o no;
- /set_relay_status : questo comando agisce sullo stato di ogni relè, presentando all’utente una sorta di “pulsantiera”;
- /get_schema_design : questo comando restituisce lo schema elettrico della soluzione.
Certamente non voglio annoiarvi con righe e righe di codice Python (anche se non superiamo le 270 righe), mostrerò solo il blocchi fondamentali per l’implementazione delle funzionalità descritte nel precedente elenco. Con calma guarderete poi il codice sorgente disponibile sul mio repository GitHub e che indicherò alla fine, quando arriverà il momento dell’avvio del Raspberry Pi Telegram Bot.
Per la creazione del Bot abbiamo già anticipato l’utilizzo di pyTelegramBotAPI e di queste API utilizzeremo pesantemente message handler e _ callback query handler _ che consentono una semplice gestione dei messaggi e in particolare dei comandi inviati dagli utenti. Quindi, per ogni comando avremo il relativo message handler e callback query handler per i messaggi che prevedono l’interazione con l’utente.
- start_command : Message Handler per la gestione del comando /start che visualizza il messaggio di benvenuto ai nuovi utenti che si registrano al Bot;
- help_command : Message Handler per la gestione del comando /help che mostra una descrizione del Bot e quali sono i comandi disponibili per l’utente;
- set_relay_status_command : Message Handler per la gestione del comando /set_relay_status_command. Questo è responsabile della gestione della “pulsantiera” che consentirà all’utente di agire sullo stato di ogni relè;
- get_relay_status_command : Message Handler per la gestione del comando /get_relay_status_command. Questo è responsabile di mostrare all’utente lo stato di ogni relè (che in questo caso sono quattro);
- get_schema_design_command : Message Handler per la gestione del comando /get_schema_design_command. Questo è responsabile di mostrare all’utente lo schema elettrico del soluzione del Bot;
- inline_query_callback : Callback Query Handler per la gestione dei comandi inviati dall’utente (tramite gli inline keyboard button) che agiscono direttamente sullo stato dei relè.
A seguire sono mostrati nell’ordine, i blocchi di codice Python che implementato i message handler _e _callback query handler indicati nel precedente elenco.
Il message handler che gestisce il comando start mostra sul display LCD il nome e cognome dell’utente che si connette al Bot (vedi le ultime tre righe di codice).
@bot.message\_handler(commands=['start'])def start\_command(message): bot.reply\_to(message, 'Hi! I am the Raspberry Pi 3 Model B+ Telegram Bot made by Antonio Musarra\'s Blog.\n' 'If you want more information on how to use this bot, use the /help command and\n' 'if you want to learn more, read the article https://www.dontesta.it') lcd.clear() lcd.message('Welcome on Bot!\n') lcd.message(message.from\_user.first\_name + ' ' + message.from\_user.last\_name)
Il message handler che gestisce il comando help oltre a mostrare un messaggio di aiuto all’utente, scrive sul display LCD il nome del comando richiesto (vedi le ultime tre righe di codice).
# /help command handler@bot.message\_handler(commands=['help'])def help\_command(message): keyboard = telebot.types.InlineKeyboardMarkup() keyboard.add( telebot.types.InlineKeyboardButton( 'Go to the developer article', url='https://www.dontesta.it') ) bot.send\_message( message.chat.id, 'This bot implements the architecture shown in the figure https://bit.ly/ArchitetturaRaspberryPiTelegramBot\n' 'Through this bot it is possible:\n\n' '\t1) Activate and Deactivate one of the four relays using the command /set\_relay\_status\n' '\t2) Check the status of the four relays using the command /get\_relay\_status\n' '\t3) View schema design using the command /get\_schema\_design\n\n', reply\_markup=keyboard ) lcd.clear() lcd.message('Request Command\n') lcd.message('/help')
Nel messaggio visualizzato all’utente è presente anche un bottone (via inline keyboard button) la cui azione di click riporta l’utente sul link indicato.
Il message handler che gestisce il comando set_relay_status visualizza all’utente la pulsantiera con cui può agire direttamente sullo stato di ogni relè. Fare attenzione all’attributo callback_data e relativo valore dell’inline keyboard button. Questo dato sarà poi gestito dall’ inline callback query con lo scopo d’identificare su quale relè deve essere effettuato il cambio di stato.
# /set\_relay\_status command handler@bot.message\_handler(commands=['set\_relay\_status'])def set\_relay\_status\_command(message): keyboard = telebot.types.InlineKeyboardMarkup() keyboard.row( telebot.types.InlineKeyboardButton(f'{em\_bulb} Relay 1', callback\_data='relay-1'), telebot.types.InlineKeyboardButton(f'{em\_bulb} Relay 2', callback\_data='relay-2') ) keyboard.row( telebot.types.InlineKeyboardButton(f'{em\_bulb} Relay 3', callback\_data='relay-3'), telebot.types.InlineKeyboardButton(f'{em\_bulb} Relay 4', callback\_data='relay-4') ) bot.send\_message(message.chat.id, 'Select one of the Relays for which to change state.\n' + 'After change state you can view the new state with \n' + 'the command /get\_relay\_status', reply\_markup=keyboard) lcd.clear() lcd.message('Request Command\n') lcd.message('/set\_relay\_status')
Il message handler che gestisce il comando get_relay_status visualizza all’utente lo stato di ogni relè connesso al sistema. Il Bot invia un messaggio diverso per ogni relè. In questo caso invierà quindi quattro messaggi, perchè il relè collegati sono perr l’appunto quattro.
# /get\_relay\_status command handler@bot.message\_handler(commands=['get\_relay\_status'])def get\_relay\_status\_command(message): for relay\_id, bcm\_value in dict\_relay\_bcm.items(): if GPIO.input(bcm\_value): logger.info(f'Input on GPIO {bcm\_value} is HIGH') bot.send\_message(message.chat.id, f'Status of the RelayId {relay\_id:d} {em\_status\_off}') else: logger.info(f'Input on GPIO {bcm\_value} is LOW') bot.send\_message(message.chat.id, f'Status of the RelayId {relay\_id:d} {em\_status\_on}') lcd.clear() lcd.message('Request Command\n') lcd.message('/get\_relay\_status')
Il message handler che gestisce il comando get_schema_design visualizza all’utente lo schema elettrico della soluzione di questo Bot. Non serve inviare in modo esplicito un messaggio con l’immagine dello schema, anche se possibile farlo; il dispositivo del destinatario risolverà la URL e visualizzerà la risorsa, in questo caso l’immagine dello schema elettrico.
# /get\_schema\_design command handler@bot.message\_handler(commands=['get\_schema\_design'])def get\_schema\_design\_command(message): bot.reply\_to(message, 'This is the wiring diagram behind this Telegram bot' ' https://bit.ly/SchemaElettricoRaspberryPiTelegramBot') lcd.clear() lcd.message('Request Command\n') lcd.message('/get\_schema\_design')
Questo callback query handler risponde alle azioni che l’utente esegue attraverso la pulsantiera che abbiamo visto in precedenza e renderizzata dal message handler set_relay_status. *Nel caso i cui l’azione sia scatenata esattamente da uno dei quattro pulsanti, allora richiama la funzione di gestione dello stato dei relè * set_relay_status_callback.
# An inline button click handler@bot.callback\_query\_handler(func=lambda call: True)def inline\_query\_callback(query): data = query.data if data.startswith('relay-'): set\_relay\_status\_callback(query)
La funzione set_relay_status_callback** **(richiamata dal callback query handler) è responsabile del cambio stato dei relè (attraverso la libreria RPi.GPIO), invio del messaggio del cambio stato sul display LCD e per ultimo dell’invio del messaggio del cambio stato all’utente.
# Implement the relay status callbackdef set\_relay\_status\_callback(query): relay\_id = int(query.data[6:]) active = False logger.info(f'Changing status for Relay {relay\_id:d}') logger.info(f'BCM Pin for Relay {relay\_id:d} is {dict\_relay\_bcm[relay\_id]:d}') if GPIO.input(dict\_relay\_bcm[relay\_id]): logger.info(f'Input on GPIO {dict\_relay\_bcm[relay\_id]} is HIGH...setting to LOW') GPIO.output(dict\_relay\_bcm[relay\_id], GPIO.LOW) lcd.clear() lcd.message(f'Act. Relay {relay\_id:d}\n') lcd.message('In listening...') active = True else: logger.info(f'Input on GPIO {dict\_relay\_bcm[relay\_id]} is LOW...setting to HIGH') lcd.clear() lcd.message(f'De Act. Relay {relay\_id:d}\n') lcd.message('In listening...') GPIO.output(dict\_relay\_bcm[relay\_id], GPIO.HIGH) bot.answer\_callback\_query(query.id) send\_set\_relay\_status\_result(query.message, relay\_id, active)
La funzione send_set_relay_status_result invia all’utente il messaggio dell’avvenuto cambio di stato, informando lo stesso circa il nuovo stato e l’identificativo del relè (così come indicato dallo schema elettrico).
# Construct and send message status of the relay to userdef send\_set\_relay\_status\_result(message, relay\_id, active): if active: emoji = em\_status\_on else: emoji = em\_status\_off bot.send\_message(message.chat.id, f'{emoji} Changed status of the RelayId {relay\_id:d} {em\_status\_changed}')
Spero che fino a qui ci siate ancora tutti. Abbiamo visto le parti salienti del software che implementa il nostro Bot. I blocchi di codice a seguire mostrano le funzioni di inizializzazione del bus GPIO, del display LCD e del clean up delle risorse quando il Bot viene terminato.
# Check I2C address via command i2cdetect -y 1PCF8574\_address = 0x27 # I2C address of the PCF8574 chip.PCF8574A\_address = 0x3F # I2C address of the PCF8574A chip.# Create PCF8574 GPIO adapter.try: mcp = PCF8574\_GPIO(PCF8574\_address)except: try: mcp = PCF8574\_GPIO(PCF8574A\_address) except: print('I2C Address Error !') exit(1)# Create LCD, passing in MCP GPIO adapter.lcd = Adafruit\_CharLCD(pin\_rs=0, pin\_e=2, pins\_db=[4, 5, 6, 7], GPIO=mcp)# Initialize the GPIO for the relay moduledef initialize\_relay(): GPIO.setmode(GPIO.BCM) GPIO.setup(23, GPIO.OUT, initial=GPIO.HIGH) GPIO.setup(24, GPIO.OUT, initial=GPIO.HIGH) GPIO.setup(25, GPIO.OUT, initial=GPIO.HIGH) GPIO.setup(16, GPIO.OUT, initial=GPIO.HIGH)# Initialize the I2C LCD 1602 Displaydef initialize\_lcd(): mcp.output(3, 1) # turn on LCD backlight lcd.begin(16, 2) # set number of LCD lines and columns lcd.message('Rasp-Pi Telegram\n') lcd.message('Bot in action...')# Resource CleanUpdef destroy(): print('Raspberry Pi Telegram Bot is shutdown... ') print('GPIO CleanUp... ') GPIO.cleanup() lcd.clear() lcd.message('Shutdown...\n') lcd.message('I\'m not active') lcd.backlight = False
Il bus I2C utilizza uno schema d’indirizzamento, dove ogni dispositivo viene attestato. Le prime righe di codice del blocco precedente impostano l’indirizzo del modulo PCF8574. In questo caso ho previsto due casi, quelli più comuni. Prima di far partire il Bot, è necessario verificare che l’indirizzo sia corretto. Per condurre la verifica è sufficiente eseguire in console il comando i2cdetect -y 1 che in questo caso mostra l’indirizzo di attestazione a 0x27.
Figura 11 – Esito del comando i2cdetect -y 1
Tranquilli, non mi son dimenticato del Token per accedere alle Telegram Bot API. Il codice mostrato a seguire imposta il Token da utilizzare per la connessione al Bot.
Non ho l’abitudine di “cablare cose” sul codice , ho previsto quindi il passaggio del Token come argomento da passare al nostro Bot. È possibile inoltre impostare il livello di log desiderato attraverso il parametro –debug. Il livello di default è INFO.
parser = argparse.ArgumentParser(description='Raspberry Pi Telegram Bot.')parser.add\_argument("--token", help='Telegram Bot API Token', required=True)parser.add\_argument("--debug", help='Enable debug log in console', required=False)args = parser.parse\_args()# Get the Telegram Bot API Token from program argumentsTOKEN = args.token# Setting the log levellogger = telebot.loggerif args.debug: telebot.logger.setLevel(logging.DEBUG)else: telebot.logger.setLevel(logging.INFO)# Initialize the TeleBotbot = telebot.TeleBot(TOKEN)
Abbiamo fatto un bel pezzo di strada e adesso siamo pronti per andare oltre, ovvero, avviare il nostro Raspberry Pi Telegram Bot e verificare che il risultato sia quello atteso.
6. Il Raspberry Pi Telegram Bot in Action
Supponendo che abbiate montato tutto secondo lo schema elettrico indicato nel corso dell’articolo e che il vostro Raspberry Pi sia connesso alla rete, possiamo procedere con i seguenti step.
- Accesso al Raspberry Pi via SSH o direttamente dal console. Consiglio di accedere con utenza diversa da root;
- Clonazione del repository amusarra/raspberry-pi-telegram-bot;
- Installazione del modulo Python emoji (perchè ho utilizzato delle emoji per i messaggi inviati all’utente);
- Start del Raspberry Pi Telegram Bot
All’interno del repository sono presenti tre programmi Python:
- raspberry_pi_telegram_bot.py : è l’implementazione del Raspberry Pi Telegram Bot;
- PCF8574.py : è il modulo Python per l’uso del modulo di estensione collegato al display LCD;
- Adafruit_LCD1602.py : è il modulo Python d’interfaccia verso il display LCD.
La sequenza di comandi a seguire ripete quanto indicato nel precedente elenco degli step di quick start. Nell’ultimo comando riportato fate attenzione a sostituire $MY_BOT_TOKEN con il vostro Token, quello che Telegram ha comunicato dopo la creazione del Bot.
$ ssh pi@amusarra-pi.local $ pip install emoji --upgrade$ git clone https://github.com/amusarra/raspberry-pi-telegram-bot.git$ cd raspberry-pi-telegram-bot$ ./raspberry\_pi\_telegram\_bot.py --token $MY\_BOT\_TOKEN
Il video pubblicato sul mio canale YouTube mostra il Raspberry Pi Telegram Bot in azione.
La figura a seguire mostra tutti gli step eseguiti sul Raspberry Pi, compreso lo start del Bot (ultimo comando). Nel caso dovreste avere problemi allo start, verificate che lo script Python abbia i permessi di esecuzione.
Le due successive figure mostrano attraverso il log le attività condotte dagli utenti. Nella fase iniziale tutti i relè vengono disattivati (vedi funzione initialize_relay).
Figura 12 – Quick Start del Raspberry Pi Telegram Bot
Una volta partito, il nostro Raspberry Pi Telegram Bot è pronto per ricevere i messaggi inviati sul canale e processarli di conseguenza nel modo opportuno. Se volessimo terminare il Bot basterebbe premere la combinazione di tasti CTRL+C.
Figura 12 – Quick Start del Raspberry Pi Telegram Bot
I log (a livello INFO) mostrano in console le azioni che l’utente del Bot sta compiendo. Sono tutte informazioni esaurienti. Com’è possibile notare sono riportati anche i cambi di stato sul pin (BCM) che di conseguenza comportano il cambio di stato del relè. Nel caso in cui volessimo vedere la corrispondenza tra pin BCM e pin fisico del connettore J8, basta eseguire sul Raspberry Pi il comando pinout o fare riferimento alla figura del connettore J8 mostrata in precedenza.
Il messaggio visualizzato sul display LCD una volta che il Bot è partito, è gestito dalla funzione initialize_lcd.
Figura 13 – Primo start del Raspberry Pi Telegram Bot
Il messaggio di benvenuto è mostrato quando l’utente si registra al Bot @amusarra-pi o quando invia il comando /start.
Figura 14 – Messaggio di benvenuto mostrato nel momento in cui l’utente si registra al Bot
Se siete curiosi di verificare ciò che succede con un livello di dettaglio maggiore, è possibile avviare il Bot con il flag –debug. In questo modo dovreste ottenere un output simile a quello mostrato dalla figura a seguire. Come potete notare ci sono parecchie informazioni aggiunte, come per esempio: le chiamate alle Telegram Bot API, i messaggi JSON ricevuti e tutte altre informazioni che potrebbero essere utili in caso di problemi.
Figura 15 – Quick Start del Raspberry Pi Telegram Bot
Quando un utente invia il comando di attivazione o disattivazione del relè, quest’informazione è visualizzata sul display, così come mostrato nella figura a seguire. In questo caso il messaggio fa riferimento alla disattivazione del relè 2. Ricordo che la funzione responsabile del cambio di stato è set_realy_status_callback.
Figura 16 – Messaggio di disattivazione relè inviato dall’utente
Dire che a questo punto possiamo ritenerci soddisfatti del risultato ottenuto. È stato implementato quando discusso all’inizio dell’articolo.
7. Cosa ne pensate?
Dopo essere arrivati qui, cosa ne pensate di quest’idea e dell’approccio per realizzare la stessa? Con l’avvento delle Single-board computer o SBC, è divenuto davvero semplice e immediato mettere in pratica le proprie idee, anche a persone non altamente specializzate nel settore elettronico e informatico.
Ci sono SBC di ogni tipo, forma e per ogni esigenza. Fatto non trascurabile, che ha favorito la diffusione e lo sviluppo delle SBC, è l’ampia disponibilità di documentazione ma in particolare modo la disponibilità di piattaforme software open source che consentono lo sviluppo semplice e veloce.
Questo progetto è l’esempio di com’è stato possibile in poco tempo, realizzare il progetto dal punto di hardware e software. In questo caso è stato scelto Python come linguaggio per realizzare il software, avremmo potuto benissimo optare per C/C++, Java, Go, etc., ampia libertà quindi sulla piattaforma di sviluppo, la cui scelta può essere fatta sulla base delle esigenze specifiche che ogni progetto ha.
Personalmente ho iniziato l’accoppiata elettronica/informatica, intorno agli anni ’94/95, programmando nel proprio linguaggio assembly, micro controllori della serie ST6 (della SGS Thomson e di cui ho ancora la board) e PIC (della Microchip).
Un esempio lampante di questa evoluzione è il progetto Espruino, programmabile utilizzando il linguaggio Javascript.
8. Conclusioni
In questo articolo mi son divertito a raccontare la mia esperienza nello strano primo maggio 2020 trascorso non fuori casa e lontano dalla mia famiglia, esperienza di cui ho dato qualche anticipazione sul mio canale LinkedIn, con la promessa di pubblicare poi tutti i dettagli con un post sul mio blog.
La cosa è stata molto divertente, non c’è stato nulla di pianificato, ho semplicemente visto il mio Raspberry Pi sulla scrivania e la mia testa ha iniziato a fantasticare su cosa poter fare con il Raspberry Pi e il resto del materiale hardware a disposizione in giro per casa.
Credetemi, scrivere questo articolo, cercando di rispettare la qualità da voi attesa, ha richiesto molto più tempo che realizzare fisicamente il progetto. Spero che i contenuti trattati siano stati di vostro interesse. Non esitate a inviare i vostri commenti e/o feedback.
9. Risorse
Come di consueto, vi lascio una serie di risorse disponibili sul web e non che potrebbero essere utili come approfondimento degli argomenti tratti nel corso di questo articolo e magari per scatenare la vostra fantasia creativa.
Due libri su Raspberry Pi e Attuatori per Maker utili da leggere come approfondimento
Aver dei libri fisici accanto di riferimento è sempre confortante, almeno per me, per questo vi lascio questi due testi come risorse da leggere.
A seguire le risorse sul web, non cartacee.
- Moreware Blog Il link porta ad articoli che riguardano il Raspberry Pi ma il blog tratta tanti altri argomenti interessanti circa la coppia elettronica e informatica;
- Raspberry Italia
- Fare Elettronica
- Elettronica Open Source
- Raspberry PI Sense HAT: Come pubblicare i dati su CloudAMQP via MQTT
- SeedStudio Blog
- Using an I2C LCD Display with a Raspberry Pi
L'articolo Un primo maggio 2020 a base di Raspberry Pi, Bot Telegram, Display LCD e Relè sembra essere il primo su Antonio Musarra's Blog.
Top comments (0)