Internet de les coses amb ESP32 i ESP8266

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

Sensor de corrent elèctric

Projecte del grup 1

En aquest cas s'ha implementat un menú a la pantalla que permet triar entre dues formes de treballar: valors actuals de corrent o potència i estudi de consum. A l'estudi de consum es fan mesures durant un temps establert i es reb un informe de resultats per correu electrònic. La durada de l'estudi es pot triar entre una i vint-i-quatre hores. L'informe inclou la recomanació de la companyia elèctrica més favorable als resultats obtinguts.

El programa del microcontrolador és el següent:

// BIBLIOTEQUES
#include <ssd1306.h>
#include <ssd1306_console.h>
#include <SPI.h> 
#include <WiFiNINA.h> 
// DEFINICIONS
#define SensLec      A5  
#define SensRef      A6  
#define numEsp       2  
#define numCicles    100 
#define brunzidor    3
#define pols_ok      4
#define pols_down    5
#define pols_home    7
#define N_Sol4       784
#define N_La4        880
#define N_Si4        988
#define N_Do5        1047
#define N_Mi5        1319
#define server_len   50    // Wifi
#define pag_len      400   // Wifi
// VARIABLES GLOBALS
Ssd1306Console console;
SAppMenu menu;
unsigned long tempsAnt;
float maxI = 0;  
float minI = 0;  
float sumaquad = 0;  
float suma = 0;  
int n = 0;  
const char* elements_main[] = { "Estudi de Consum", "Dades" };
const char* elements_dades[] = { "Intensitat", "Potencia"};
const char* elements_estudideconsum[] = { "1 h",  "2 h",  "3 h",  "4 h",  "5 h",  "6 h",  "7 h",
                                          "8 h",  "9 h",  "10 h", "11 h", "12 h", "13 h", "14 h",
                                          "15 h", "16 h", "17 h", "18 h", "19 h", "20 h", "21 h",
                                          "22 h", "23 h", "24 h"};
int pg_actual = 0;
float Intensitat = 0;
float Potencia = 0;
int HoresEstudi = 0;
int ValorInicialBarra = 0;
int Temps1percent = 0;
bool estatEstudi = false;
const char idXarxa[] = "xarxa-wifi";   // Nom del wifi
const char contrasenya[] = "contrasenya-wifi";   // Contrasenya wifi
const String server0 = "script.google.com";
String pagina0 = "";
const String pagina_base = "/macros/s/^^fycby1cuinpq5leudHyDWD15ck5aiJOHGW39HzpQeqPEj48SIyTl0lEWCaNTUatL668rf4rg/exec";
char server[server_len];
char pagina[pag_len];
unsigned long darreraConnexio = 0;
const unsigned long periodeConnexio = 10000UL;
bool pendent, completa, redir;
bool ara = false;
String data;
String peticio = "";   // Aquí guardarem una línia de la petició del client
String peticioAux = "";   // i la petició anterior (també ho farem servir de reserva)
int status = WL_IDLE_STATUS;
WiFiSSLClient client;
// SETUP
void setup(){
  Serial.begin(9600);   // Monitor sèrie
  // Pantalla i menu
  ssd1306_setFixedFont(ssd1306xled_font6x8);
  ssd1306_128x64_i2c_init();
  ssd1306_clearScreen();
  ssd1306_createMenu(&menu, elements_main, sizeof(elements_main) / sizeof(elements_main[0]));
  ssd1306_showMenu(&menu);
  // Conexió wifi
  while (!Serial){
    ;   // Esperem que l'usuari obri el monitor sèrie
  }
  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(); 
  redir = false;
  // Definició de pins
  pinMode(brunzidor, OUTPUT);
  pinMode(pols_down, INPUT_PULLUP);
  pinMode(pols_ok, INPUT_PULLUP);
  pinMode(pols_home, INPUT_PULLUP);
  // Musiqueta tot llest
  tone(3, N_Sol4, 120);
  delay(140);
  tone(3, N_La4, 120);
  delay(140);
  tone(3, N_Si4, 120);
  delay(140);
  tone(3, N_Do5, 250);
  delay(300);
  noTone(3);
}
// LOOP
void loop(){
  calculSensor();
  sendData();
  menuNavigation();
  realTimeShow();
}
// FUNCIONS
void musiqueta(){
  tone(3, N_Do5, 80);
  delay(100);
  tone(3, N_Mi5, 80);
  delay(100);
  noTone(3);
}
void calculSensor(){
  int lec_sensor = analogRead(SensLec);
  int ref_sensor = analogRead(SensRef);
  float Iinst = 30 * 3.3 * (lec_sensor - ref_sensor) / 1023 / numEsp;
  sumaquad = sumaquad + (Iinst * Iinst);
  suma = suma + abs(Iinst);
  n++;
  if(Iinst > maxI){
    maxI = Iinst;
  }
  if(Iinst < minI){
    minI = Iinst;
  }
  if((millis() - tempsAnt) > (20 * numCicles)){
    tempsAnt = millis();
    float medI = 1.1107 * suma / n; 
    float Irms = sqrt(sumaquad / n);
    Intensitat = Irms;
    Potencia = Irms*230;
    maxI = 0;
    minI = 0;
    sumaquad = 0;
    suma = 0;
    n = 0;
  }
}
void sendData(){
  while (client.available()){
    char c = client.read();   // Rebem caràcters del servidor
    if (c == '\n'){
      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
    }
    if (completa){
      if (peticioAux.startsWith("HTTP/1.1 200")){
        pendent = true;
      }
      if (peticioAux.startsWith("HTTP/1.1 302")){ 
        redir = true;
      }
      if (redir && (peticioAux.startsWith("Location:"))){
        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, 50);
        pagina1.toCharArray(pagina, 400);
        ara = true;
      }
      completa = false;
    }
  }
  if (pendent){
    pendent = false;
  }
  if (ara || ((millis() - darreraConnexio > periodeConnexio))){
    if(!ara){
      data = "?";
      data += "Intensitat=";
      data += Intensitat;
    }
    if (redir){
      redir = false;
    } else {
      pagina0 = pagina_base + data;
      server0.toCharArray(server, server_len);
      pagina0.toCharArray(pagina, pag_len);
    }
    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();
      darreraConnexio = millis();
      Serial.print("Enviat: ");
      Serial.println(data);
    } else {
      Serial.println("connection failed");
    }
    ara = false;
  }
}
void menuNavigation(){
  if (!digitalRead(pols_down) && (pg_actual == 0 || pg_actual == 1 || pg_actual == 2 )){
    ssd1306_menuDown(&menu);
    ssd1306_clearScreen();
    ssd1306_showMenu(&menu);
    delay(200);  // Debounce
  } else if (!digitalRead(pols_ok)) {
    int selection = ssd1306_menuSelection(&menu);
    if (pg_actual == 0){  // MAIN
      musiqueta();
      if (selection == 0){  // MAIN>ESTUDI DE CONSUM
        pg_actual = 1;
        ssd1306_clearScreen();
        ssd1306_createMenu(&menu, elements_estudideconsum, sizeof(elements_estudideconsum) / sizeof(elements_estudideconsum[0]));
        ssd1306_showMenu(&menu);
      } else if (selection == 1){  // MAIN>DADES
        pg_actual = 2;
        ssd1306_clearScreen();
        ssd1306_createMenu(&menu, elements_dades, sizeof(elements_dades) / sizeof(elements_dades[0]));
        ssd1306_showMenu(&menu);
      }
    } else if (pg_actual == 1){  // MAIN>ESTUDI DE CONSUM
      musiqueta();
      pg_actual = 5;
      estatEstudi = true;
      HoresEstudi = selection + 1;
      ssd1306_clearScreen();
    } else if (pg_actual == 2){  // MAIN>DADES
      musiqueta();
      if (selection == 0){  // MAIN>DADES>INTENSITAT
        pg_actual = 3;
        ssd1306_clearScreen();
      } else if (selection == 1){  // MAIN>DADES>POTENCIA
        pg_actual = 4;
        ssd1306_clearScreen();
      }
    }
    delay(200);  // Debounce
  } else if (!digitalRead(pols_home)){
    musiqueta();
    pg_actual = 0;
    ssd1306_clearScreen();
    ssd1306_createMenu(&menu, elements_main, sizeof(elements_main) / sizeof(elements_main[0]));
    ssd1306_showMenu(&menu);
    delay(200);  // Debounce
  }
}
void realTimeShow(){
  if (pg_actual == 3){  // MAIN>DADES>INTENSITAT
    console.setCursor(24, 16);
    console.print("I = ");
    console.print(Intensitat);
    console.print("A");
  } else if (pg_actual == 4){  // MAIN>DADES>POTENCIA
    console.setCursor(24, 16);
    console.print("P = ");
    console.print(Potencia);
    console.print("W");
  }
  delay(200);
}

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

var IdFull = "^^zcjd3PBGwORLSSCea_3pgE-NEx3dMftXp2LnyOj8qY";
function doGet(e) {
  if (!e || !e.parameter) {
    return ContentService.createTextOutput("Error: no s'han rebut paràmetres.");
  }
  // Establir les variables principals.
  var intensitat = e.parameter.Intensitat;
  var horesestudi = e.parameter.HoresEstudi;
  var resultat = ''
  var camps = new Array(4);
  // Obtenir hora actual.
  var ara = new Date();
  var Ho = ara.getHours();
  var Min = ara.getMinutes();
  var Seg = ara.getSeconds();
  var Hora = ara.getHours().toString().padStart(2, '0') + ":" + ara.getMinutes().toString().padStart(2, '0');
  Hora += ":" + ara.getSeconds().toString().padStart(2, '0');
  var Data = ara.getDate() + "/" + (ara.getMonth()+1) + "/" + ara.getFullYear();
  var potencia = (Number(intensitat)*230/1000).toFixed(2); //Calcular la potència en kW
  // Obrir el document de Google Sheets.
  var llibre = SpreadsheetApp.openById(IdFull);
  var full = llibre.getSheets()[0];
  // Comprovar si ja hi ha títols.
  var primeraFila = full.getRange(1, 1, 1, 3).getValues()[0];
  if (primeraFila[0] !== "Data" || primeraFila[1] !== "Hora" || primeraFila[2] !== "Intensitat (A)") {
    full.clearContents(); // neteja el full si no té els títols correctes
    full.appendRow(["Data", "Hora", "Intensitat (A)","Potència (kW)"]);
  }
  // Intentem llegir el valor guardat anteriorment (si n'hi ha)
  var horesGuardades = full.getRange(1, 6).getValue();
  // Si horesestudi és diferent de 0 i encara no hem guardat res, ho guardem
  if (horesestudi !== 0 && horesGuardades === "") {
    full.getRange(1, 6).clear()
    var durada = String(horesestudi).replace('.',',');
    full.getRange(1,6).setValue(durada);
  }
  if (horesestudi && Number(horesestudi) !== 0 && intensitat) {
    camps[0]=String(Data)
    camps[1]=String(Hora);
    camps[2]=String(intensitat).replace('.', ',');
    camps[3]=String(potencia).replace('.', ',');
    // Comprovar si la gràfica ja existeix.
    full.appendRow(camps);   // Afegeix una columna amb la llista de dades en format matriu.
    resultat = 'Oriol estaria orgullós';
  }
  // Començar el càlcul d'energies
  if (Number(horesestudi) === 0){
    calculEnergies()
    resultat = 'Olé';
  }
  return ContentService.createTextOutput(resultat);
} 
function calculEnergies() {
  // Definir els fulls del Google Sheets.
  var llibre = SpreadsheetApp.openById(IdFull);
  var full1 = llibre.getSheets()[0];
  var full2 = llibre.getSheets()[1];
  var full3 = llibre.getSheets()[2];  
  // Llegir valors de Hora i Potència del full d'Intensitats.
  var ultimafilafull1 = full1.getLastRow();
  var filesvalors = ultimafilafull1 - 1
  var columnaPot = full1.getRange(2,4,filesvalors,1).getValues();
  var columnaHoMinSeg = full1.getRange(2,2,filesvalors,1).getValues();
  var columnaHora = [];
  // Obtenir la zona horaria perque llegeixi bé les hores del full 1.
  var zonahoraria = SpreadsheetApp.getActive().getSpreadsheetTimeZone();
  // Cal assegurar que no hi ha errors en les lectures d'hora i afegim les hores.
  for (var i = 0; i < columnaHoMinSeg.length; i++) {
    var cel = columnaHoMinSeg[i][0];
    if (cel instanceof Date && !isNaN(cel.getTime())) {
      var horaString = Utilities.formatDate(cel, zonahoraria, "H"); // sense 0 inicial
      columnaHora.push(parseInt(horaString));
    } else {
      columnaHora.push(null);
    }
  }
  // Recorrer les dues llistes per tal de fer els sumatoris d'energies puntuals i classificar-les
  // per hores. Després escriure els valors a la columna d'energia consumida.
  for (let j = 2; j < 26; j++) {
    var wh = 0;
    var numvalors = 0
    for (let i = 0; i < columnaHoMinSeg.length; i++) {
      if (Number(columnaHora[i]) === j-2) {
        var valor = columnaPot[i][0].toFixed(2);
        var p = String(valor).replace(',', '.');
        wh += parseFloat(p);
        numvalors++ 
      }
    }
    if (numvalors === 0) {
      var kWh = 0;
    }
    else {
      var kWh = String(wh/numvalors).replace('.', ',');
    }
    full2.getRange(j, 3).setValue(kWh);
  }
  // Omplir la taula de preus segons la energia consumida.
  var energies = full2.getRange(2, 3, 24, 1).getValues();
  for (let i = 2; i < 26; i++) {
    var preusComa = full3.getRange(i, 2, 1, 5).getValues();
    var preusHora = [];
    for (let j = 0; j < 5; j++) {
      var preuPunt = String(preusComa[0][j]).replace(',', '.');
      var energiaPunt = String(energies[i-2][0]).replace(',', '.');
      var preuXenergia = String((Number(preuPunt)*Number(energiaPunt)).toFixed(2)).replace('.', ',');
      preusHora.push(preuXenergia);
    }
    full2.getRange(i, 4, 1, 5).setValues([preusHora]);
  }
  Utilities.sleep(5000);
  creaDocument()
}
function creaDocument() {
  var llibre = SpreadsheetApp.openById(IdFull);
  var full1 = llibre.getSheets()[0];
  var full2 = llibre.getSheets()[1];
  var full3 = llibre.getSheets()[2]; 
  var full4 = llibre.getSheets()[3]; 
  // Obtenir les dades i gràfiques que volem introduïr al document.
  var dadesEnergia_Preu = full2.getDataRange();
  var grafics = full1.getCharts();
  var taulaPreusGenerics = full3.getRange(28,9,25,7);
  var ultimafilafull1 = full1.getLastRow();
  var filesvalors = ultimafilafull1 - 1
  // Calcular màx de la intensitat.
  var columnaInt = full1.getRange(2,3,filesvalors,1).getValues().flat().map(val => Number(typeof val === 'string' ? val.replace(',', '.') : val));
  var maximInt = Math.max(...columnaInt);
  var indexosInt = columnaInt
  .map((valor, i) => ({ valor, fila: i + 2 })) // +2 perquè comencem a D2
  .filter(obj => obj.valor === maximInt)
  .map(obj => obj.fila);
  // Obtenir el valor màxim de potència i els dies i hores en què s'ha donat aquesta situació.
  var maxPot = (maximInt*230/1000).toFixed(2); //Calcular la potència màxima en kW
  // Mirar quants valors son major de 1, per tant, es considera que estan encessos
  // i multipliquem per 10 (segons entre mesures).
  var tempsActiu = (columnaInt.filter(valor => valor > 1).length) * 10;
  var ho = Math.floor(tempsActiu / 3600);
  var min = Math.floor((tempsActiu % 3600) / 60);
  var seg = tempsActiu % 60;
  var tempsEnces = String(ho).padStart(2, '0') + " hores " + String(min).padStart(2, '0') + " minuts i " + String(seg).padStart(2, '0') + " segons";
  var preusTotal = full2.getRange(26,4,1,5).getValues().flat().map(val => Number(typeof val === 'string' ? val.replace(',', '.') : val));
  var preuMin = Math.min(...preusTotal);
  var celaPreuMin = (preusTotal.indexOf(preuMin))+4;
  var companyiaPreuMin = full2.getRange(1,celaPreuMin).getValue();
  // Crear un nou document de Google Docs
  var doc = DocumentApp.create("Informe del teu estudi");
  var pagina = doc.getBody();
  // Obtenir el dia
  // Obtenir hora actual
  var ara = new Date();
  var Data = ara.getDate() + "/" + (ara.getMonth()+1) + "/" + ara.getFullYear();
  // Afegir el títol
  pagina.appendParagraph(`Informe del teu consum elèctric (${Data})`).setHeading(DocumentApp.ParagraphHeading.HEADING1).setAlignment(DocumentApp.HorizontalAlignment.CENTER).setFontFamily('Times New Roman');
  pagina.appendParagraph("(generat automàticament)").setAlignment(DocumentApp.HorizontalAlignment.CENTER).setFontFamily('Times New Roman');
  pagina.appendParagraph("");
  // Usuari
  var ufila4 = full4.getLastRow();
  var correu = full4.getRange(ufila4,2).getValue();
  pagina.appendParagraph(`Usuari: ${correu}`).setFontFamily('Times New Roman').setFontSize(12).setBold(true);
  pagina.appendParagraph("");
  // Primer punt: resum
  pagina.appendParagraph("Resum:").setFontFamily('Times New Roman').setFontSize(12).setBold(true);
  pagina.appendParagraph("");
  //Obtenir el valor de horesestudi adjuntat a la casella F1
  var duradaestudi = full1.getRange(1,6).getValue();
  pagina.appendParagraph(`La durada de l'estudi ha estat de ${duradaestudi} hora/es.`).setFontSize(10).setFontFamily('Times New Roman').setLineSpacing(1.5).setBold(false);
  pagina.appendParagraph(`El dispositiu ha estat encès ${tempsEnces}.`).setFontFamily('Times New Roman').setLineSpacing(1.5);
  pagina.appendParagraph(`Intensitat màxima: ${maximInt} A.`).setFontFamily('Times New Roman').setLineSpacing(1.5);
  pagina.appendParagraph(`Potència màxima: ${maxPot} kW.`).setFontFamily('Times New Roman').setLineSpacing(1.5);
  // Si hi ha dos màxims s'ha d'indicar els dos moments de temps en què ha ocurregut el màxim
  if (indexosInt.length > 1) {
    var datesMax=[];
    for (let i=0;i < indexosInt.length; i++) {
      var r = full1.getRange(indexosInt[i],1,1,2).getValues();
      // Convertim a Date i formatem
      var data = new Date(r[0][0]);
      var dia = data.getDate().toString().padStart(2, '0') + "/" + (data.getMonth()+1).toString().padStart(2, '0') + "/" + data.getFullYear().toString()
      var hora = new Date(r[0][1]);
      var horaescrita = hora.getHours().toString() + ":" + hora.getMinutes().toString().padStart(2, '0') + ":" + hora.getSeconds().toString().padStart(2, '0')
      var s = dia + ' a les ' + horaescrita;
      datesMax.push(s);
    }
    pagina.appendParagraph(`Aquests valors màxims han succeït: ${datesMax.join(';')}.`).setFontFamily('Times New Roman').setLineSpacing(1.5);
  } else {
    var r = full1.getRange(indexosInt[0],1,1,2).getValues();
    var data = new Date(r[0][0]);
    var dia = data.getDate() + "/" + (data.getMonth()+1) + "/" + data.getFullYear();
    var hora = new Date(r[0][1]);
    var horaescrita = hora.getHours().toString() + ":" + hora.getMinutes().toString().padStart(2, '0') + ":" + hora.getSeconds().toString();
    var s = dia + ' a les ' + horaescrita;
    pagina.appendParagraph(`Aquest valor màxim ha succeït: ${s}.`).setFontFamily('Times New Roman').setLineSpacing(1.5);
  }
  pagina.appendParagraph(`La companyia elèctrica més econòmica segons el teu consum es: ${companyiaPreuMin} amb el cost de ${preuMin.toFixed(2)}€.`).setFontFamily('Times New Roman').setLineSpacing(1.5);
  pagina.appendPageBreak();
  //Segon punt: gràfics
  pagina.appendParagraph("Gràfica de intensitat:").setFontFamily('Times New Roman').setFontSize(12).setBold(true);
  var imatgeGrafic1 = grafics[0].getAs('image/png');
  pagina.appendImage(imatgeGrafic1);
  pagina.appendParagraph("");
  pagina.appendParagraph("Gràfica de potència:").setFontFamily('Times New Roman').setFontSize(12).setBold(true);
  var imatgeGrafic2 = grafics[1].getAs('image/png');
  pagina.appendImage(imatgeGrafic2);
  pagina.appendPageBreak();
  // Tercer punt: taules
  // Taula de preus genèrics
  pagina.appendParagraph("Taula de preus de companyies elèctriques més comuns a Catalunya (dia 02/03/2025):").setFontSize(12).setFontFamily('Times New Roman').setBold(true);
  pagina.appendParagraph("");
  var dadesTaula1 = taulaPreusGenerics.getValues();
  var taula1 = pagina.appendTable();
  var fons1 = taulaPreusGenerics.getBackgrounds();
  // Omplir la taula i apliquem colors als fons:
  for (let i = 0; i < taulaPreusGenerics.getValues().length; i++) {
    var fila = taula1.appendTableRow();
    for (let j = 0; j < dadesTaula1[i].length; j++) {
      var cela = fila.appendTableCell(dadesTaula1[i][j].toString());
      // Estil del text
      const textStyle = {};
      // Assignar estils
      cela.setBackgroundColor(fons1[i][j]);
      cela.setFontFamily('Times New Roman');
      cela.setFontSize(8);
      cela.setBold(false);
    }
  }
  pagina.appendPageBreak();
  // Taula d'energia i preus de l'usuari
  pagina.appendParagraph(`Taula de consum d'energia i comparativa de preus de l'usuari (Dia ${Data}):`).setFontSize(13).setFontFamily('Times New Roman').setBold(true);
  pagina.appendParagraph("");
  var dadesTaula2 = dadesEnergia_Preu.getValues();
  var taula2 = pagina.appendTable();
  var fons2 = dadesEnergia_Preu.getBackgrounds();
  // Omplir la taula i apliquem colors als fons:
  for (let i = 0; i < dadesTaula2.length; i++) {
    var fila = taula2.appendTableRow();
    for (let j = 0; j < dadesTaula2[i].length; j++) {
      if (typeof dadesTaula2[i][j] === 'number') {
        num = Number(String(dadesTaula2[i][j]).replace(',', '.')).toFixed(2);
        str = String(num.replace('.', ','));
        var cela = fila.appendTableCell(str);
      } else if (typeof dadesTaula2[i][j] === 'string') {
        var cela = fila.appendTableCell(dadesTaula2[i][j].toString());
      }
      // Assignar estils
      cela.setBackgroundColor(fons2[i][j]);
      cela.setFontFamily('Times New Roman');
      cela.setFontSize(9);
      cela.setBold(false);
    }
  }
  // Després de generar tot el document...
  doc.saveAndClose();
  // Convertir el document a PDF
  var aPDF = DriveApp.getFileById(doc.getId());
  var pDF = aPDF.getAs('application/pdf')
  // Guardar el PDF amb un nom nou
  var nomPDF = "Informe de consum - " + Data + ".pdf";
  var arxiuPDF = DriveApp.createFile(pDF).setName(nomPDF);
  // Fer públic el document
  arxiuPDF.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
  // Mostrar l'enllaç al PDF al log
  Logger.log("Pots accedir al PDF aquí: " + arxiuPDF.getUrl());
  Utilities.sleep(5000); //Esperar 5 segons
  //Enviar PDF per correu electrònic
  MailApp.sendEmail(correu, "Estudi energètic del teu dispositiu", `(Missatge generat automàticament)` + "\n\n" + `Aquí té el document amb tota la informació obtinguda sobre el seu estudi de consum energètic, esperem li sigui de gran ajut:` + "\n\n" + ` ${arxiuPDF.getUrl()}` + "\n\n" + `No respongui a aquest correu`);
  Utilities.sleep(10000); //Esperar 10 segons
  netejaFulls()
}
function netejaFulls() {
  var llibre = SpreadsheetApp.openById(IdFull);
  var full1 = llibre.getSheets()[0];
  var full2 = llibre.getSheets()[1]; 
  var full4 = llibre.getSheets()[3]; 
  var ultimaFila1 = full1.getLastRow();
  full1.getRange(2,1,ultimaFila1,4).clearContent();
  full1.getRange(1,6).clear();
  full2.getRange(2,3,24,6).clearContent();
  var ultimafilafull4 = full4.getLastRow
  //full4.getRange(2,1,ultimafilafull4,2).clear();
  full4.clear();
}

 

 

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