Internet de les coses amb ESP32 i ESP8266

Exemples Referència Plaques   Recursos CITCEA
Projectes Programació Perifèrics   Inici

Sensor de llum

Projecte del grup 4

En aquest cas s'ha dissenyat un sistema per analitzar si les plantes d'interior reben una quantitat suficient de llum. El sistema compara les mesures amb la climatologia prevista a la comarca indicada per l'usuari. La gestió del sistema es fa mitjançant un xatbot de Telegram. El programa del microcontrolador és el següent:

#include <SPI.h>    // Carreguem la biblioteca SPI
#include <WiFiNINA.h>    // Carreguem la biblioteca WiFiNINA
#include <Adafruit_NeoPixel.h>    // biblioteca per als NeoPixels
#define LDRpin A3  // Pota on hi ha el sensor
#define LED 1    // pota on hem connectat el LED
#define server_len 50
#define pag_len 400
const char idXarxa[] = "xarxa-wifi";    // Nom del punt d'accés 
const char contrasenya[] = "contrasenya-wifi";    // Contrasenya de connexió
const char server0[] = "script.google.com";
String pagina0 = "";
const String pagina_base = "/macros/s/^^fycbxSBDRxiOkZdX09nGqZ669tP507PZ1BZZt8On8EbgQ8qIVqObj55WACWZzLehBWbBHO/exec?accio=neo";
char server[server_len];
char pagina[pag_len];
unsigned long darreraConnexio = 0;
const unsigned long periodeConnexio = 10000UL;
bool pendent, completa, redir;
bool ara = false;
int lectura;
String data;
String R, G, B;    // Aquí guardarem els colors
String peticio = "";    // Aquí guardarem una línia de la petició del client
String resp = ""; // Aquí guardarem la resposta de l'script
String peticioAux = "";    // i la petició anterior (també ho farem servir de reserva)
int status = WL_IDLE_STATUS;
Adafruit_NeoPixel cadena = Adafruit_NeoPixel(1, LED, NEO_GRB + NEO_KHZ800);
WiFiSSLClient client;
void setup() {    // Inicialització
  Serial.begin(9600);    // Monitor sèrie
  cadena.begin();  // Inicialitza els NeoPixels        
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("No s'ha trobat el dispositiu Wi-Fi");
    while (true)
      ;    // Bloquegem el programa
  }
  String versio = WiFi.firmwareVersion();
  if (versio < "1.0.0") {
    Serial.println("Convindria actualitzar el firmware");
  }
  while (status != WL_CONNECTED) {
    Serial.print("Connectant a la xarxa ");
    Serial.println(idXarxa);
    status = WiFi.begin(idXarxa, contrasenya);
    delay(10000);    // Ho tornarem a intentar passats 10 s
  }
  Serial.print("Connectat a "); 
  Serial.println(WiFi.SSID());
  Serial.print("Estat de la connexió: ");
  Serial.println(WiFi.status()); 
  Serial.print("Adreça IP del dispositiu: ");
  Serial.println(WiFi.localIP()); 
  Serial.print("Intensitat del senyal: ");
  Serial.print(WiFi.RSSI()); 
  Serial.println(" dBm");
  Serial.println(); 
  Serial.println("Anem a connectar al servidor");
  redir = false;
}
void loop() { // Programa que es repeteix indefinidament
  while (client.available()) {
    char c = client.read();    // Rebem caràcters del servidor
    if (c == '\n') {    // Mirem si és un salt de línia
      peticioAux = peticio;    // Guardem la petició anterior
      peticio = "";    // Ens preparem per a la línia següent
      completa = true;    // Preparat per escriure-ho
    } else {
      peticio += c;    // Afegim el caràcter rebut
    }
    // Quan ha arribat un salt de línia, hem de mirar què ha arribat
    if (completa){  // Ha arribat una línia completa
      resp = "";
      if (peticioAux.startsWith("HTTP/1.1 200")){    // Resposta bona
         pendent = true;
      }
      if (peticioAux.startsWith("HTTP/1.1 302")){    // Redireccionament
        redir = true;
      }
      if (peticioAux.startsWith("v=")){    // Línia que conté el valor
        resp = peticioAux.substring(2);    // Agafem el que queda després del signe =
         R = resp.substring(0, resp.indexOf(","));
         resp = resp.substring(resp.indexOf(",") +1);
         G = resp.substring(0, resp.indexOf(","));
         B = resp.substring(resp.indexOf(",") +1);
      }
      if (redir && (peticioAux.startsWith("Location: "))){
        // Si hi ha redireccionament, hem de buscar l'adreça
        // i extreure'n el servidor i la pàgina
        String adre = peticioAux.substring(peticioAux.indexOf("//") +2);
        String server1 = adre.substring(0, adre.indexOf(".com") +4);
        String pagina1 = adre.substring(adre.indexOf(".com") +4);
        server1.toCharArray(server, server_len);
        pagina1.toCharArray(pagina, pag_len);
        ara = true;
      }
      completa = false;
    }
  }
  // Hi ha una resposta per processar
  // En aquest cas, les dades estan a la darrera línia rebuda
  if (pendent) {
    pendent = false;
    // Ara només s'envien els tres colors, no hi ha la marca de temps
    cadena.setPixelColor(0, R.toInt(), G.toInt(), B.toInt());
    cadena.show();
    Serial.print("(");
    Serial.print(R);
    Serial.print(", ");
    Serial.print(G);
    Serial.print(", ");
    Serial.print(B);
    Serial.println(")");
    delay(10000);
    cadena.setPixelColor(0, B.toInt(), G.toInt(), R.toInt());
    cadena.show();
  }
  // Quan toca, tornem a fer una petició
  if (ara || ((millis() - darreraConnexio > periodeConnexio))) {
    if(!ara) {
      delay(600000);
      lectura = analogRead(LDRpin);
      Serial.print("Lectura = ");
      Serial.println(lectura);
      data = "&";
      data += "l=";
      data += lectura;
    }
    if (redir){
      redir = false;
    } else {
      pagina0 = pagina_base + data;
      for (int j = 0; j < server_len; j++){
        server[j] = server0[j];
      }
      for (int j = 0; j < pag_len; j++){
        pagina[j] = pagina0[j];
      }
    }
    ara = false;
    client.stop();
    if (client.connect(server, 443)) {
      Serial.println("S'ha fet la connexió al servidor");
      client.print("GET ");
      client.print(pagina);
      client.println(" HTTP/1.1");
      client.print("Host: ");
      client.println(server);
      client.println("Connection: close");
      client.println();
      // Guardem quan hem fet la connexió
      darreraConnexio = millis();
      Serial.print("Enviat: ");
      Serial.println(data);
    } else {
      Serial.println("connection failed");
    }
  }
}

El programa de l'script és el següent:

var IdFull = "^^NSrx0UvRyluPHM4SY7yQDiVdvunpsz2ukUxHXAcT2c"; // Identificador del full de càlcul 
var numFull = 0;  // Número del full amb el que hem de treballar
var comptador = 0;
var Accio = "";
function doGet(e) {
  if (sun()[0] == 'True'){
    var resultat = '';
    var camps = new Array(4);  // Valors per guardar a la taula
    var ara = new Date();
    var Hora = ara.getHours();
    var Minut = ara.getMinutes();
    var Segon = ara.getSeconds();
    var Time = Hora + ":" + Minut +":" + Segon;
    var intermati = "12:00:00";
    var intertarda = "15:00:00";
    var Lum = e.parameter.l;
    var sh = SpreadsheetApp.openById(IdFull);
    var sheet = sh.getSheets();
    var full = sheet[numFull].getDataRange().getValues();
    if (Lum == undefined){
      resultat = 'Falten paràmetres';
    } else {
      camps[0] = Time;
      camps[1] = Lum;
      if (Lum <= 365){
        comptador = comptador + 1;
      }
      camps[3] = comptador;
      if((Time>=sun()[1]) && (Time<=intermati)){
        camps[2] = meteo()[0];
        camps[4] = infomet(meteo()[0]);
        var prev = new Array(2);
        var valu = new Array(1);
        var sh = SpreadsheetApp.openById(IdFull);
        var sheet = sh.getSheets();
        var rangeVal = sheet[numFull].getRange(2, 5, 1, 2);
        prev[0] = meteo()[1];
        prev[0] = meteo()[0];
        valu[0] = prev;
        rangeVal.setValues(valu)
      }
      if((Time>=intermati) && (Time<=intertarda)){
        var filera = full[1];    // Agafem una filera
        var casella = filera[5];    // Agafem una casella
        camps[2] = casella;
        camps[4] = infomet(casella);
      }
      if((Time>=intertarda) && (Time<=sun()[2])){
        var filera = full[1];    // Agafem una filera
        var casella = filera[4];    // Agafem una casella
        camps[2] = casella;
        camps[4] = infomet(casella);
      }
      var sh = SpreadsheetApp.openById(IdFull);
      var sheet = sh.getSheets();
      sheet[numFull].appendRow(camps);   // Afegeix una fila amb la llista de dades en format matriu 
      resultat = 'Valors guardats';
    }
    return ContentService.createTextOutput(resultat); 
  } else {
    var suma = 15;
    var ara = new Date();
    var nova = new Date(ara.getTime() + suma * 60000);
    var Hora = nova.getHours();
    var Minut = nova.getMinutes();
    var Segon = nova.getSeconds();
    var maxi = Hora + ":" + Minut + ":" + Segon;
    var Hour = ara.getHours();
    var Minute = ara.getMinutes();
    var Second = ara.getSeconds();
    var Time = Hour + ":" + Minute +":" + Second;
    if ((Time >= sun()[2]) && (Time <= maxi)){
      correu();
    }
    var sh = SpreadsheetApp.openById(IdFull);
    var sheet = sh.getSheets();
    var full = sheet[numFull].getDataRange().getValues();
    var filera = full[3];    // Agafem una filera
    var casella = filera[6];    // Agafem una casella
    if (casella < 42){
      var mat = new Array(1);
      var resp = new Array(1);
      var fil = full[2];
      var casel = fil[6];
      var rangeVal = sheet[numFull].getRange(3,7,1,1);
      mat[0] = casel + 1;
      resp[0] = mat;
      rangeVal.setValues(resp);
      var Accio = e.parameter.accio;
      if (Accio.substring(0,3) == "neo"){
        // Obrim el full de càlcul
        var sh = SpreadsheetApp.openById(IdFull);
        var sheet = sh.getSheets();
        // Llegim les dades del full seleccionat
        var full = sheet[1].getDataRange().getValues();
        range = sheet[1].getLastRow();
        if (range > 1){    // Si és 1 només hi ha els títols
          var filera = full[1]; 
          var resultat = 'v=';
          for(var j = 0;j < numCols;j++){ 
            if (j > 0){
              resultat = resultat + ',';
            }
          resultat = resultat + filera[j];
          }
        }
      } else {
        var resultat = 'Acció incorrecta';
      }
      return ContentService.createTextOutput(resultat);
    } else {
      var sh = SpreadsheetApp.openById(IdFull);
      var sheet = sh.getSheets();
      // Llegim les dades del full seleccionat
      var full = sheet[1].getDataRange().getValues();
      range = sheet[1].getLastRow();
      if (range > 1){    // Si és 1 només hi ha els títols
        var filera = full[2];
        var resultat = 'v=';
        for(var j = 0;j < numCols;j++){ 
          if (j > 0){
            resultat = resultat + ',';
          }
          resultat = resultat + filera[j];
        }
      }
      if (("06:00:00" <= Time) && (Time <= sun()[1])){
        esborra();
      }
      return ContentService.createTextOutput(resultat);
    }
  }
}
function meteo(){
  var sh = SpreadsheetApp.openById(IdFull);
  var sheet = sh.getSheets();
  var full = sheet[numFull].getDataRange().getValues();
  var filera = full[1];    // Agafem una filera
  var casella = filera[2];    // Agafem una casella
  var nc = casella.toLowerCase();
  var peticio = "https://static-m.meteo.cat/content/opendata/ctermini_comarcal.xml";
  var response = UrlFetchApp.fetch(peticio).getContentText(); // Carrega la resposta a la petició
  var document = XmlService.parse(response);  // Tracta les dades XML rebudes
  var root = document.getRootElement();  // Arrel de l'estructura de dades
  var comarques = root.getChildren("comarca");  // Informació de les comarques
  var punter = -1;
  for (var i = 0; i < comarques.length; i++){  // Mira totes les comarques
    var nomCom = comarques[i].getAttribute("nomCOMARCA").getValue().toLowerCase();  // Nom de la comarca
    if(nomCom == nc){  // Si hi ha alguna coincidència
      punter = i;  // Posició de la coincidència
    }
  }
  var ara = new Date();  // Avui
  var dema = new Date(ara.getTime());
  var dia = dema.getDate();
  var mes = dema.getMonth() + 1;  // Compta els mesos de 0 a 11
  var any = dema.getFullYear();
  var data = "";
  if (dia < 10){
    data = data + "0";
  }
  data = data + dia + "-";
  if (mes < 10){
    data = data + "0";
  }
  data = data + mes + "-" + any;
  var previsio = root.getChildren("prediccio");  // Busca la predicció
  var prevCom = previsio[punter];  // Agafa la de la comarca demanada
  var previsions = prevCom.getChildren("variable");  // Agafa les dades
  var pntr = -1;  // Si no ho troba valdrà -1
  for (var i = 0; i < previsions.length; i++){  // Mira totes les respostes
    if (previsions[i].getAttribute("data").getValue() == data){  // Comprova la data
      pntr = i;  // Índex de la data desitjada
    }
  }
  var nomComarca = comarques[punter].getAttribute("nomCOMARCA").getValue();  // Nom de la comarca
  var simbolmati = previsions[pntr].getAttribute("simbolmati").getValue();  // Símbol de predicció matí
  var simboltarda = previsions[pntr].getAttribute("simboltarda").getValue();  // Símbol de predicció tarda
  var simbol = new Array(26);
  simbol = ["1.png", "2.png", "3.png", "4.png", "5.png", "6.png", "7.png", "8.png", "9.png", "10.png",
            "11.png", "12.png", "13.png", "20.png", "21.png", "22.png", "23.png", "24.png", "25.png",
            "26.png", "27.png", "28.png", "29.png", "30.png", "31.png", "32.png"];
  var info = new Array(26);
  info = ["sol", "sol i núvols alts", "entre poc i mig ennuvolat", "molt cobert", "plugim", "pluja", "xàfec",
          "tempesta", "tempesta calamarsa", "neu", "boira", "boirina", "xàfec neu", 
          "entre mig i molt ennuvolat", "cobert", "calitja", "ruixat", "xàfec amb tempesta", "xàfec",
          "ruixat", "neu feble", "tempesta neu", "xàfec", "aiguaneu", "ruixat", "plugim"];
  for (var i in simbol){
    if (simbolmati == simbol[i]){
      mati = info[i];
    }
    if (simboltarda == simbol[i]){
      tarda = info[i];
    }
  }
  return [mati, tarda];
}
function sun(){
  var Longitude = comarca()[1];
  var Latitude = comarca()[0];
  var urlsun = 'https://api.sunrise-sunset.org/json?lat=';
  var result = UrlFetchApp.fetch(urlsun + Latitude + '&lng=' + Longitude + '&formatted=0');
  var resultJson = JSON.parse(result);
  var sunrise = new Date(resultJson.results.sunrise);
  var sunset = new Date(resultJson.results.sunset);
  var lluna = sunset.toString().substring(16,24);
  var sol = sunrise.toString().substring(16,24);
  var ara = new Date();
  var Hora = ara.getHours();
  var Minut = ara.getMinutes();
  var Segon = ara.getSeconds();
  var Time = Hora + ":" + Minut +":" + Segon;
  if (sol <= Time){
    if (Time <= lluna){
      igualtat = 'True';
    } else {
      igualtat = 'False';
    }
  } else {
    igualtat = 'False'
  }
  return [igualtat,sol,lluna]
}
function comarca() {
  var sh = SpreadsheetApp.openById(IdFull);
  var sheet = sh.getSheets();
  var full = sheet[numFull].getDataRange().getValues();
  var filera = full[1];    // Agafem una filera
  var casella = filera[2];    // Agafem una casella
  var nom = casella.toLowerCase();
  var comarca = new Array(42);
  comarca = ["l'alt empordà", "el baix empordà", "el pla de l'estany", "el gironès",
             "la selva", "la garrotxa", "el ripollès", "osona", "el vallès oriental",
             "el maresme", "moianès", "el barcelonès", "el vallès occidental",
             "el baix llobregat", "el bages", "el berguedà", "la cerdanya", "el garraf",
             "l'alt penedès", "l'anoia", "el solsonès", "l'alt urgell", "el pallars sobirà",
             "la val d'aran", "l'alta ribagorça", "el pallars jussà", "la noguera",
             "el pla d'urgell", "l'urgell", "la segarra", "la conca de barberà", "l'alt camp",
             "el tarragonès", "el baix camp", "el priorat", "les garrigues", "el segrià",
             "la ribera d'ebre", "el baix ebre", "la terra alta", "el montsià", "el baix penedès"];
  var Long = new Array(42);
  Long = [2.9616300, 3.0500000, 2.7666700, 2.8249300, 2.6666700, 2.4901200, 2.1903300, 2.2548600,
          2.2877300, 2.4445000, 2.0958100, 2.1589900, 2.1013700, 2.0500000, 1.8265600, 1.8462800,
          1.9281900, 1.7251100, 1.7000000, 1.6172000, 1.5170600, 1.4614400, 1.0768400, 0.7726300,
          0.7438900, 0.8948700, 0.8109400, 0.9000000, 1.1395700, 1.2689200, 1.1616300, 1.2499300,
          1.2500000, 1.1068700, 0.8174200, 0.8529500, 0.6221800, 0.5962200, 0.5216000, 0.4385000,
          0.5810300, 1.5333300];
  var Lat = new Array(42);
  Lat = [42.2664500, 41.9500000, 42.1166700, 41.9831100, 41.8666700, 42.1809600, 42.2006400,
         41.9301200, 41.6079700, 41.5421100, 41.8100900, 41.3887900, 41.5487800, 41.3833300,
         41.7249800, 42.1042900, 41.5487800, 41.2239200, 41.3500000, 41.5809800, 41.9939500,
         42.3587700, 42.4526100, 42.6846200, 42.4066000, 42.1670300, 41.7911700, 41.6333300,
         41.6470400, 41.6683000, 41.3763600, 41.2861200, 41.1166700, 41.1561200, 41.1663700,
         41.5076800, 41.6167400, 41.1040000, 40.8124900, 41.0537500, 40.7130800, 41.2166700];
  for (var i in comarca){
    if (comarca[i] == nom){
      longitud = Long[i];
      latitud = Lat[i];
    }
  }
  return [latitud, longitud]
}
function correu() {
  var sh = SpreadsheetApp.openById(IdFull);
  var sheet = sh.getSheets();
  var full = sheet[numFull].getDataRange().getValues();
  var filera = full[1];    // Agafem una filera
  var destinatari = filera[0];    // Agafem una casella
  var ara = new Date();
  var Hora = ara.getHours();
  var Minut = ara.getMinutes();
  var Segon = ara.getSeconds();
  var Time = Hora + ":" + Minut +":" + Segon;
  var fila = full[3];
  var comptasol = fila[6]; 
  if (comptasol < 42){
    if (filera[7] <= 2){
      missatge = "La planta no ha rebut les hores necessàries de llum tot i que el dia ";
      missatge = missatge + "ha estat favorable, convindria buscar-li una nova ubicació.";
    }
    if (filera[7] > 2){
      missatge = "La planta no ha rebut les hores necessàries de llum, però com que el dia ";
      missatge = missatge + "no ha estat favorable, no podem determinar-ne la causa.";
    }
  } else {
    missatge = "La planta ha rebut les hores necessàries de llum.";
  }
  var titol = "Correu enviat des de l'script de Sòltesi";
  var text = "Avui a les " + Time + " s'ha produït un esdeveniment ";
  text = text + " que ha provocat l'enviament d'aquest correu electrònic. ";
  text = text + "https://docs.google.com/spreadsheets/d/e/";
  text = text + "^^ACX-1vSFXQPQ9_FGtBE30Y5jPgf3wFuE0f5ys4lWGtB2GzQXeCmBveWf4lh4svTeL2q";
  text = text + "-GxNlVNdokNuyl4Sd/pubchart?oid=941429670&format=interactive";
  text = text + "\n\n";  // Dos salts de línia
  text = text + missatge;
  MailApp.sendEmail(destinatari, titol, text);
}
function infomet(valor){
  var valsol = new Array(3);
  var valmig = new Array(3);
  var noval = new Array(16);
  valsol = ["sol", "sol i núvols alts", "entre poc i mig ennuvolat"];
  valmig = ["entre mig i molt ennuvolat", "xàfec", "ruixat"];
  noval = ["molt cobert", "plugim", "pluja", "tempesta", "tempesta calamarsa", "neu", "boira",
           "boirina", "xàfec neu", "cobert", "calitja", "xàfec amb tempesta", "neu feble",
           "tempesta neu", "aiguaneu", "plugim"];
  var c = 0;
  if (valsol.includes(valor)){
    var c = 1;
  }
  if (valmig.includes(valor)){
    var c = 2;
  }
  if (noval.includes(valor)){
    var c = 3;
  }
  return c
}
function esborra() {
  var sh = SpreadsheetApp.openById(IdFull).getSheetByName("Full 1");
  var range = sh.getRange("A5:E105");
  var cela = sh.getRange("G3");
  range.clearContent();
  cela.clearContent();
}
// Telegram
var IdFull = "^^NSrx0UvRyluPHM4SY7yQDiVdvunpsz2ukUxHXAcT2c";
var sh = SpreadsheetApp.openById(IdFull);  // Obrim el full de càlcul
var sheet = sh.getSheets();  // Agafem els fulls
var token = "5665863258:AAFdyhzZTfwoyVYRElkXJEmq33tlnvi-dRQ"; // API Token de Telegram 
var telegramUrl = "https://api.telegram.org/bot" + token;  // Url que comunica el nostre xatbot amb Telegram 
var webAppUrl = "https://script.google.com/macros/s/"
webAppUrl = webAppUrl + "^^fycbwyW1BURwrLjxS78kHGHdLa8oq_fcv_en77yjkgspaL5I-t-6tYdr0fI808qusow3Rb/exec";
function setWebhook() {
  var url = telegramUrl + "/setWebhook?url=" + webAppUrl;
  var response = UrlFetchApp.fetch(url);
}
function sendText(chatId,text_env){  
  var cont = {
    method: "post",
    payload: {
      method: "sendMessage",
      chat_id: String(chatId),
      text: text_env,
      parse_mode: "HTML"
    }
  }
  UrlFetchApp.fetch(telegramUrl + '/', cont);
}
function doPost(e){ // Función que recibe los datos enviados por Telegram que seran por metodo Post 
  var fet = 0;
  var resposta = '';
  var dades = JSON.parse(e.postData.contents);  // Tracta les dades rebudes com a JSON i les guarda a dades
  // Extraiem les dades
  var text = dades.message.text;  // Recupera el text del missatge
  var id = dades.message.chat.id;  // Recupera l'identificador de la finestra des de la que s'ha enviat
  var comanda = text.split("-");  // Separa per les @
  var cmd = comanda[0];  // Comanda
  var par1 = comanda[1];  // Primer paràmetre
  if (cmd == '/llistat'){
    var llista = "/llistat - Llista de les comandes disponibles.\n";  // Text que es retornarà a Telegram
    llista = llista + "/correu - Guarda el teu gmail al full de càlcul per rebre informació.\n";
    llista = llista + "/comarca - Guarda la comarca on vius al full de càlcul. Cal escriure ";
    llista = llista + "la comarca amb l'article i l'accentuació corresponents.\n";
    llista = llista + "/diagrama - Rep la gràfica dels valors recollits des de l'hora que surt ";
    llista = llista + "el sol fins a l'hora en què envies la comanda. El diagrama només està ";
    llista = llista + "disponible entre l'hora que surt el sol i l'hora en què es pon.\n"
    llista = llista + "/llegircorreu - Llegeix el gmail que has introduït.\n";
    llista = llista + "/llegircomarca - Llegeix la comarca que has introduït.\n";
    sendText(id,llista);
    fet = 1;
  }
  if (cmd == '/start'){
    var llista = "Hola!, soc el @Soltesi_bot i estic aquí per ajudar-te a personalitzar ";
    llista = llista + "el dispositiu de Sòltesi. "
    llista = llista + "Aquest t'ajudarà a determinar si les teves plantes, a la posició ";
    llista = llista + on es troben, estan rebent suficient llum per créixer. \n\n"
    llista = llista + "Pots començar provant aquesta comanda: /llistat \n"
    var numFull = 0;  // Número del full amb el que hem de treballar
    var rangeVal = sheet[numFull].getRange(2, 2);  // Selecciona la casella
    rangeVal.setValue(id);  // Guarda el valor a la casella, substituïnt l'anterior
    sendText(id,llista);
    fet = 1;
  }
  if (cmd == '/correu'){
    if (par1 == undefined){
      resposta = "No s'ha rebut cap dada per guardar.\n";
      resposta = resposta + "La sintaxi és /correu-dada\n";
      resposta = resposta + "Per exemple: /correu-usuari@gmail.com";
    } else { 
      var numFull = 0;  // Número del full amb el que hem de treballar
      var rang = sheet[numFull].getLastRow();  // Darrera línia ocupada
      if (rang > 1){  // Mira si ja hi ha un valor (si és 1 només hi ha els títols)
        // La funció getRange ens permet seleccionar el grup de caselles sobre les que anem a escriure
        // El primer paràmetre és la filera on comença el grup, en el nostre cas la darrera escrita
        // El segon paràmetre és la columna on comença el grup, en el nostre exemple la primera
        var rangeVal = sheet[numFull].getRange(2, 1);  // Selecciona la casella
        rangeVal.setValue(par1);  // Guarda el valor a la casella, substituïnt l'anterior
      } else {
        // Si no n'hi ha cap, afegeix una fila amb la llista de dades en format matriu
        sheet[numFull].appendRow([par1]);
      }
    }
    sendText(id,resposta);
    fet = 1;
  }
  if (cmd == '/diagrama'){
    var text = "Missatge enviat des de l'script de Sòltesi. \n\n";
    text = text + "S'adjunta la gràfica dels valors de llum recollits fins l'hora actual.\n";
    var imat = "https://docs.google.com/spreadsheets/d/e/";
    imat = imat + "^^ACX-1vSFXQPQ9_FGtBE30Y5jPgf3wFuE0f5ys4lWGtB2GzQXeCmBveWf4lh4svTeL2q-GxNlVNdokNuyl4Sd";
    imat = imat + "/pubchart?oid=941429670&format=image";
    var response = UrlFetchApp.fetch(imat); // Carrega la imatge corresponent a la url generada 
    var binaryData = response.getContent();   // Imatge en dades binàries
    // La funció newBlob té tres paràmetres: les dades, el tipus de dades i el nom que li volem donar
    // carrega la imatge com a dades binaries en una variable 
    var blob_data = Utilities.newBlob(binaryData, 'image/png', text); 
    sendBlobFile(id,blob_data,text); // Enviem la imatge al Telegram però amb format binari (BLOB)
    fet = 1;
  }
  if (cmd == '/llegircorreu'){
    var full = sheet[0].getDataRange().getValues();
    var rang = sheet[0].getLastRow();  // Índex de la darrera filera
    var filera = full[1];
    resposta = filera[0];
    if (resposta == ""){
      resposta = "No hi ha cap dada guardada.";
    }
    sendText(id,resposta);
    fet = 1;
  }
  if (cmd == '/llegircomarca'){
    var full = sheet[0].getDataRange().getValues();
    var rang = sheet[0].getLastRow();  // Índex de la darrera filera
    var filera = full[1];
    resposta = filera[2];
    if (resposta == ""){
      resposta = "No hi ha cap dada guardada.";
    }
    sendText(id,resposta);
    fet = 1;
  }
  if (cmd == '/comarca'){
    if (par1 == undefined){
      resposta = "No s'ha rebut cap dada per guardar.\n";
      resposta = resposta + "La sintaxi és /comarca-dada\n";
      resposta = resposta + "Per exemple: /comarca-El Barcelonès";
    } else { 
      var numFull = 0;  // Número del full amb el que hem de treballar
      var rang = sheet[numFull].getLastRow();  // Darrera línia ocupada
      if (rang > 1){  // Mira si ja hi ha un valor (si és 1 només hi ha els títols)
        // La funció getRange ens permet seleccionar el grup de caselles sobre les que anem a escriure
        // El primer paràmetre és la filera on comença el grup
        // El segon paràmetre és la columna on comença el grup
        var rangeVal = sheet[numFull].getRange(2, 3);  // Selecciona la casella
        rangeVal.setValue(par1);  // Guarda el valor a la casella, substituïnt l'anterior
      } else {
        // Si no n'hi ha cap, afegeix una fila amb la llista de dades en format matriu
        sheet[numFull].appendRow([par1]);
      }
    }
    sendText(id,resposta);
    fet = 1;
  }
// Si no hem entrat a cap if vol dir que la comanda no s'ha reconegut
if (fet == 0){
    resposta = "Comanda incorrecta.";
    sendText(id,resposta);
  }
}
function sendBlobFile(chatId,blob_data,caption){
  // La funció newBlob té tres paràmetres: les dades,
  //   el tipus de dades i el nom que li volem donar
  var payload = {
    method: "sendPhoto",
    chat_id: String(chatId),
    photo: blob_data,
    caption: caption,
    parse_mode: "HTML"
  };
  var options = {
    method: "POST",
    payload: payload,
    muteHttpExceptions: true
  };
  UrlFetchApp.fetch( telegramUrl + '/', options);
}

 

 

Llicència de Creative Commons
Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.