
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.