Una delle mie recenti esperienze lavorative mi ha portato a realizzare un sms gateway per l’inoltro di alcune centinaia di messaggi al giorno. Ho scelto di utilizzare l’ormai noto Raspberry Pi come piattaforma hardware e ho scritto uno script in python per gestire l’invio degli sms.
Perchè il Raspberry
Ci sono davvero tanti motivi per scegliere un prodotto di questo tipo:
- nessun alimentatore classico da pc, quindi nessun problema dipendente da esso
- nessun supporto magnetico, il sistema operativo è su una SD da 4GB, quindi si riduce drasticamente il rischio di perdita di dati o rottura dell’hard disk
- il processore è un ARM e il costo dell’intero dispositivo completo di SD e alimentatore esterno non arriva a 40 euro
- la dimensione del dispositivo è di poco più grande di un pacchetto di sigarette, quindi posizionabile ovunque
Ma come funziona
La distribuzione linux che ho utilizzato è Debian Wheezy, ho creato una cartella condivisa con samba per depositare da un pc in rete gli elenchi dei contatti a cui il dispositivo deve inviare giornalmente gli avvisi e ho creato una regola per cron (gestore delle operazioni pianificate su linux) in modo da far richiamare lo script python, addetto alla verifica dei file dei contatti e all’inoltro dei messaggi, ogni ora.
Per il collegamento alla rete GSM ho utilizzato una pennina HUAWEI di quelle che si utilizzano per navigare, ma è possibile utilizzare anche un semplice telefonino.
Il codice
Di seguito ho postato il codice sorgente della classe Sms della mia soluzione che si occupa proprio di inoltrare il messaggio predefinito inserendo al posto giusto il nome del destinatario.
# -*- coding: utf-8 -*-
import time
import datetime
import serial
class Sms:
# template message to use to send sms
__message = "Avviso per l'utente <user> ..."
# timing
__waitrw = 0.3 # seconds between sends
__readtout = 3 # read timeout in seconds
__eachstep = 20 # number of sends to wait more time
__bigwait = 8000 # seconds between sends
__comport = "/dev/ttyACM0" # com port to exchange data with phone
__baudrate = 9600 # serial speed
__readBuff = 1024 # read buffer size
__smscenter = "+393916263900" # FASTWEB SMS Center
# object to manage phone/sim card communication
__phone = None
# function to read data from buffer using timeout
def ReadData(self, readTimeOut):
endtime = datetime.datetime.now() + datetime.timedelta(0, readTimeOut)
actual = datetime.datetime.now()
tmpmsg = ""
# loop until timeout
while (actual < endtime):
toRead = self.__phone.inWaiting()
# try to read on serial port
if toRead > 0:
tmpmsg = self.__phone.read(toRead)
break
# update actual time
actual = datetime.datetime.now()
# if buffer is empty, exit
if len(tmpmsg) == 0:
return ""
# append to output message
outmsg = tmpmsg
# if there are bytes to read, read it
while self.__phone.inWaiting() > 0:
# try to read on serial port
tmpmsg = self.__phone.read(self.__readBuff)
outmsg += tmpmsg
# return readed bytes
return outmsg
# init phone/modem communication
def Init(self):
# open communication
self.__phone = serial.Serial(self.__comport, self.__baudrate, timeout=self.__readtout)
try:
time.sleep(self.__waitrw)
# send ack
self.__phone.write(b'AT\r')
datain = self.ReadData(self.__readtout)
if datain[-4:] != "OK\r\n":
return "init error: " + datain
# send sms center
self.__phone.write(b'AT+CSCA="' + self.__smscenter + '"\r')
datain = self.ReadData(self.__readtout)
if datain[-4:] != "OK\r\n":
return "init error: sms center error: " + datain
except Exception as e:
# error detected
return "init error: [exception] " + e.message
# return empty
return ""
# send message
def Send(self, user, number):
# update message to send
smsmsg = self.__message.replace('<user>', user).encode() + b"\r"
try:
# check for message len
if len(smsmsg) > 120:
return "send error: message is too long"
# send ack
self.__phone.write(b'AT\r')
datain = self.ReadData(self.__readtout)
if datain[-4:] != "OK\r\n":
return "send error: [1] " + datain
# set communication for text messages
self.__phone.write(b'AT+CMGF=1\r')
datain = self.ReadData(self.__readtout)
if datain[-4:] != "OK\r\n":
return "send error: [2] " + datain
# set phone number
self.__phone.write(b'AT+CMGS="' + number.encode() + b'"\r')
datain = self.ReadData(self.__readtout)
if datain[-2:] != "> ":
return "send error: [3] " + datain
# set text messages
self.__phone.write(smsmsg)
datain = self.ReadData(self.__waitrw)
self.__phone.write(chr(26))
time.sleep(3)
datain += self.ReadData(self.__readtout)
if datain[-4:] != "OK\r\n":
return "send error: [4] " + datain + " [" + datain.encode("hex") + "]"
except Exception as e:
# error detected
return "send error: [exception] " + e.message
# return empty if all ok
return ""
Lascia un commento
Devi essere connesso per inviare un commento.