0

起初,我的问题来自我的小项目 IoT。目的,使用 ESP32 通过 Google App Script 向 Google Sheet 发送数据。

ESP32的任务是取两个随机数,通过http通过Google App Script(Web App)传给Google Sheet。

我的问题是,在 ESP32 和 Google App Script 之间的连接每次都失败之后,我只能向 Google Sheet 插入数据 3-4 条记录。我不确定这个问题。

我的代码有 2 个部分,第一个是 ESP32(Arduino IDE),第二个是 Google App Script

第一部分代码如下,非常简单。

#include <WiFi.h>
#include <WiFiClientSecure.h>
String t;
const char* host = "script.google.com";
const int httpsPort = 443;
const char* ssid = "MY_SSID";
const char* pass = "MY_SSID_PW";
String GAS_ID = "GAS_ID";
String GAS_Sheet = "dht_data";
WiFiClientSecure client;
long now = millis();
long lastMeasure = 0;
void setup() {
    Serial.begin(115200); delay(500);
    WiFi.begin(ssid, pass);
    Serial.print("\nConnecting");
    while (WiFi.status() != WL_CONNECTED) {
        Serial.print(".");
    }
    Serial.print("\nSuccessfully connected to : "); Serial.println(ssid);
    Serial.print("\nIP address: "); Serial.println(WiFi.localIP());
    Serial.println();
    client.setInsecure();
}
void loop() {
    now = millis();
    if (now - lastMeasure > 30000) {
        lastMeasure = now;
        float ValueSensor1 = random(2000, 4000) / 100.0;
        float ValueSensor2 = random(6000, 8000) / 100.0;
        Serial.println();
        Serial.print("\ntemperature = "); Serial.print(ValueSensor1, 1);
        Serial.print("\thumidity = "); Serial.print(ValueSensor2, 1);
        Serial.println();
        sendData(ValueSensor1, ValueSensor2);
    }
}
void sendData(float SValue1, float SValue2) {
    Serial.println("==========");
    Serial.print("connecting to "); Serial.println(host);
    //---- Connect to Google host
    if (!client.connect(host, httpsPort)) {
        Serial.println("connection failed");
        return;
    }
    //---- Post Data
    String url;
    url += "/macros/s/" + GAS_ID + "/exec?";
    url += "id=" + String(GAS_Sheet);
    url += "&temperature=" + String(SValue1, 2);
    url += "&humidity=" + String(SValue2, 2);
    Serial.print("requesting URL: "); Serial.println(url);
    client.print(String("GET ") + url + " HTTP/1.1\r\n" +
            "Host: " + host + "\r\n" +
            "User-Agent: BuildFailureDetectorESP8266\r\n" +
            "Connection: close\r\n\r\n");
    Serial.println("request sent");
    //---- Wait Echo
    while (client.connected()) {
        String line = client.readStringUntil('\n');
        if (line == "\r") {
            Serial.println("headers received");
            break;
        }
    }
    String line = client.readStringUntil('\n');
    if (line.startsWith("{\"state\":\"success\"")) {
        Serial.println("ESP-32/Arduino CI successfull!");
    } else {
        Serial.println("ESP-32/Arduino CI has failed");
    }
    Serial.print("reply was : ");
    Serial.println(line);
    Serial.println("closing connection");
    Serial.println("==========");
    Serial.println();
}

第二部分代码如下,

function doGet(e){
    // open the spreadsheet
    var ss = SpreadsheetApp.getActive();

    // use the 'id' parameter to differentiate between sheets
    var sheet = ss.getSheetByName(e.parameter["id"]);

    // extract headers
    // getRange accepts row, col, number_of_rows and num_of_cols as argument
    // getLastColumn returns the position of the last column that has content
    var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];

    // store the position of the last row
    var lastRow = sheet.getLastRow();
    var cell = sheet.getRange('a1');
    var col = 0;
    var d = new Date();
    for (i in headers){
        // loop through the headers and if a parameter name matches the header name insert the value
        if (headers[i] == "Timestamp") {
            val = d.toDateString() + ", " + d.toLocaleTimeString();
        } else {
            val = e.parameter[headers[i]];
        }
        // append data to the last row
        cell.offset(lastRow, col).setValue(val);
        col++;
    }
    return ContentService.createTextOutput('success');
}

问题的原因是什么?我该如何解决?

非常感谢您提前。

4

1 回答 1

0

这只是我的猜测。从 开始My problem is, I can insert data to Google Sheet only 3-4 records, after that connection between ESP32 and Google App Script has failed everytime. I am not sure about the problem.,我担心将数据发送到 Web 应用程序的频率。我认为当数据不断发送到Web Apps时,可能会出现这样的错误。那么在这种情况下,下面的修改呢?

修改后的脚本:

在此修改中,我降低了您的 Google Apps Script for Web Apps 的处理成本,并添加了 LockService。

function doGet(e) {
  const lock = LockService.getDocumentLock();
  if (lock.tryLock(350000)) {
    try {
      var sheet = SpreadsheetApp.getActive().getSheetByName(e.parameter["id"]);
      var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
      var d = new Date();
      var values = headers.map(h => h == "Timestamp" ? d.toDateString() + ", " + d.toLocaleTimeString() : e.parameter[h]);
      sheet.getRange(sheet.getLastRow() + 1, 1, 1, values.length).setValues([values]);
    } catch (e) {
      return ContentService.createTextOutput(JSON.stringify(e));
    } finally {
      lock.releaseLock();
      return ContentService.createTextOutput('success');
    }
  } else {
    return ContentService.createTextOutput("timeout");
  }
}

笔记:

  • 当您修改 Google Apps 脚本时,请将部署修改为新版本。这样,修改后的脚本就会反映在 Web Apps 中。请注意这一点。
  • 您可以在“在不更改新 IDE 的 Web 应用程序 URL 的情况下重新部署 Web 应用程序”的报告中查看详细信息。
  • 在我最近的报告中,当 Web Apps 的脚本处理成本较低时,可以为 Web Apps 做大约 60 次并发访问。参考但是,就您的情况的流程成本而言,我从未测量过。所以我不确定这是否是您问题的直接解决方案。

参考:

于 2021-10-23T07:41:37.183 回答