SMS

În vederea transmiterii mesagelor, prin protocolul SMS, fără utilizarea unui modem am recurs la serviciul oferit de TWILIO . Pentru a putea accesa serviciul este necesar a vă înregistra pe site, după care este necesar a achiziționa un număr de telefon. Din păcate, în acest moment, pentru România, nu se poate achiziționa un număr de telefon ce poate asigura serviciul de sms, dar se poate achiziționa un număr dintr-o altă țară.

Atenție la costurile aferente fiecărei țări!

Luând în ordine alfabetică m-am oprit la un număr din Belgia pe care l-am achiziționat contra sumei de 1 USD. Costul transmiterii unui sms este de 0,068 USD. Cum folosim serviciul de transmitere a unui sms este documentat la următorul link iar un exemplu găsim aici. În testarea exemplului vom fi atenți să ne completăm următoarele linii cu informățiile de autentificare obținute din consola de acces la serviciu.
Acestea sunt:

...
const char* account_sid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";//se obține din câmpul ACCOUNT SID
const char* auth_token = "Your AUTH TOKEN";//se obține din câmpul AUTH TOKEN apăsând view
...

De asemenea, în exemplu avem de completat/înlocuit 3 numere de telefon:

...
String to_number    = "+18005551212";//numărul de telefon către care trimitem sms
String from_number = "+18005551212"; //numărul de telefon de la care trimitem sms - cel cumpărat
...
String master_number    = "+18005551212";//numărul de telefon autorizat să trimită sms/comenzi către ESP8266
...

Fingerprint-ul de mai jos va trebui înlocuit cu unul valabil iar acesta se obține prin rularea comenzii:
echo | openssl s_client -connect api.twilio.com:443 | openssl x509 -fingerprint

...
const char* fingerprint = "CF C4 40 77 88 75 5F BD 07 0F 88 3F 1C BD 95 3B DD AE 5F 13";
...

în acest moment (decembrie 2018) fingerprint valabil este:

...
const char* fingerprint = "4C FE 00 19 F3 57 89 7B 02 9A A4 AA 2E 7B CB 6E 53 D1 7E AE";
...

obținut din răspusnul comenzii de mai sus.
SHA1 Fingerprint=4C:FE:00:19:F3:57:89:7B:02:9A:A4:AA:2E:7B:CB:6E:53:D1:7E:AE

Din exemplu anterior am verificat, cu succes, numai transmiterea unui mesaj sms nu și recepția unei comenzi prin sms de către ESP8266.

Exemplu de cod, unde am introdus opțiunea de a alege tipul de comunicație serială (software sau hardware):

 /*
 * Twilio SMS and MMS on ESP8266 Example.
 */
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include "twilio.hpp"
//
// Use 1 for software serial for debugging and 0 for hardware serial debugging?
#define USE_SOFTWARE_SERIAL 0
//
// Your network SSID and password
const char* ssid = "*****";
const char* password = "*****";
//
// Find the api.twilio.com SHA1 fingerprint, this one was valid as 
// of December 2018.
const char* fingerprint = "4C FE 00 19 F3 57 89 7B 02 9A A4 AA 2E 7B CB 6E 53 D1 7E AE";
//
// Twilio account specific details, from https://twilio.com/console
// Please see the article: 
// https://www.twilio.com/docs/guides/receive-and-reply-sms-and-mms-messages-esp8266-c-and-ngrok
//
// If this device is deployed in the field you should only deploy a revocable
// key. This code is only suitable for prototyping or if you retain physical
// control of the installation.
const char* account_sid = "AC********************************";
const char* auth_token = "********************************";
//
// Details for the SMS we'll send with Twilio.  Should be a number you own 
// (check the console, link above).
String to_number    = "+40*********";
String from_number = "+32*********";
String message_body    = "Buna ESP8266 foloseste Twilio pentru acest sms!";
//
// The 'authorized number' to text the ESP8266 for our example
String master_number    = "+40*********";
//
// Optional - a url to an image.  See 'MediaUrl' here: 
// https://www.twilio.com/docs/api/rest/sending-messages
String media_url = "";
//
// Global twilio objects
Twilio *twilio;
ESP8266WebServer twilio_server(8000);
//
//  Optional software serial debugging
#if USE_SOFTWARE_SERIAL == 1
#include <SoftwareSerial.h>
// You'll need to set pin numbers to match your setup if you
// do use Software Serial
extern SoftwareSerial swSer(14, 4, false, 256);
#endif
//
//
/*
 * Callback function when we hit the /message route with a webhook.
 * Use the global 'twilio_server' object to respond.
 */
 void handle_message() {
        #if USE_SOFTWARE_SERIAL == 1
        swSer.println("Incoming connection!  Printing body:");
        #endif
        #if USE_SOFTWARE_SERIAL == 0
        Serial.println("Incoming connection!  Printing body:");
        #endif
        bool authorized = false;
        char command = '\0';
//
        // Parse Twilio's request to the ESP
        for (int i = 0; i < twilio_server.args(); ++i) {
                #if USE_SOFTWARE_SERIAL == 1
                swSer.print(twilio_server.argName(i));
                swSer.print(": ");
                swSer.println(twilio_server.arg(i));
                #endif
                #if USE_SOFTWARE_SERIAL == 0
                Serial.print(twilio_server.argName(i));
                Serial.print(": ");
                Serial.println(twilio_server.arg(i));
                #endif
//
                if (twilio_server.argName(i) == "From" and 
                    twilio_server.arg(i) == master_number) {
                    authorized = true;
                } else if (twilio_server.argName(i) == "Body") {
                        if (twilio_server.arg(i) == "?" or
                            twilio_server.arg(i) == "0" or
                            twilio_server.arg(i) == "1") {
                                command = twilio_server.arg(i)[0];
                        }
                }
        } // end for loop parsing Twilio's request
//
        // Logic to handle the incoming SMS
        String response = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
        if (command != '\0') {
                if (authorized) {
                        switch (command) {
                        case '0':
                                digitalWrite(LED_BUILTIN, LOW);
                                response += "<Response><Message>"
                                "Turning light off!"
                                "</Message></Response>";
                                break;
                        case '1':
                                digitalWrite(LED_BUILTIN, HIGH);
                                response += "<Response><Message>"
                                "Turning light on!"
                                "</Message></Response>";
                                break;
                        case '?':
                        default:
                                response += "<Response><Message>"
                                "0 - Light off, 1 - Light On, "
                                "? - Help\n"
                                "The light is currently: ";
                                response += digitalRead(LED_BUILTIN);
                                response += "</Message></Response>";
                                break;               
                        }
                } else {
                        response += "<Response><Message>"
                        "Unauthorized!"
                        "</Message></Response>";
                }
//
        } else {
                response += "<Response><Message>"
                "Look: a SMS response from an ESP8266!"
                "</Message></Response>";
        }
//
        twilio_server.send(200, "application/xml", response);
}
//
/*
 * Setup function for ESP8266 Twilio Example.
 * 
 * Here we connect to a friendly wireless network, instantiate our twilio 
 * object, optionally set up software serial, then send a SMS or MMS message.
 */
void setup() {
        WiFi.begin(ssid, password);
        twilio = new Twilio(account_sid, auth_token, fingerprint);
//
        #if USE_SOFTWARE_SERIAL == 1
        swSer.begin(115200);
        while (WiFi.status() != WL_CONNECTED) {
                delay(1000);
                swSer.print(".");
        }
        swSer.println("");
        swSer.println("Connected to WiFi, IP address: ");
        swSer.println(WiFi.localIP());
        #else
        while (WiFi.status() != WL_CONNECTED) delay(1000);
        #endif
//
        #if USE_SOFTWARE_SERIAL == 0
        Serial.begin(115200);
        while (WiFi.status() != WL_CONNECTED) {
                delay(1000);
                Serial.print(".");
        }
        Serial.println("");
        Serial.println("Connected to WiFi, IP address: ");
        Serial.println(WiFi.localIP());
        #else
        while (WiFi.status() != WL_CONNECTED) delay(1000);
        #endif
//
        // Response will be filled with connection info and Twilio API responses
        // from this initial SMS send.
        String response;
        bool success = twilio->send_message(
                to_number,
                from_number,
                message_body,
                response,
                media_url
                );
//
        // Set up a route to /message which will be the webhook url
        twilio_server.on("/message", handle_message);
        twilio_server.begin();
//
        // Use LED_BUILTIN to find the LED pin and set the GPIO to output
        pinMode(LED_BUILTIN, OUTPUT);
//
        #if USE_SOFTWARE_SERIAL == 1
        swSer.println(response);
        #endif
        #if USE_SOFTWARE_SERIAL == 0
        Serial.println(response);
        #endif
}
//
//
/* 
 *  In our main loop, we listen for connections from Twilio in handleClient().
 */
void loop() {
        twilio_server.handleClient();
}