Доброго всем вечера.
Из-за блокировки Телеграм пришлось срочно модифицировать свои автополивалки. ESP-32 довольно просто перевел на Гуглотаблицы. Но есть проблема с передачей данных. Сначала использовал совсем простой вариант - постучал и ушол.
else if (mode == 1)
//------------ ПЕРЕДАЧА ДАННЫХ ---------------
{
if (wifiConnected())
{
//Передача данных на сервер
HTTPClient http;
String Send_Data = Web_App_URL + "?sts=write";
Send_Data += "&date=" + dateStr;
Send_Data += "&time=" + timeStr;
Serial.println(Send_Data);
for (int i = 0; i <= 5; i++)
{
String I = String(i);
Send_Data += "&moisture" + I + "=" + String(Channels[i].soilMoisturePercent);
Send_Data += "&setMoisture" + I + "=" + String(Channels[i].soilMoisturePercentControl);
Send_Data += "&flowRate" + I + "=" + String(Channels[i].flowRate);
Send_Data += "&limit" + I + "=" + String(Channels[i].volumeControl);
Send_Data += "&block" + I + "=" + String(Channels[i].isBlock);
Send_Data += "&coef" + I + "=" + String(Channels[i].volumeCoeff);
}
Send_Data += "&reservuar=" + String(reservuar);
Send_Data += "&flowCoeff=" + String(flowCoeff);
Serial.println("Загрузка в Google Spreadsheet...");
http.begin(Send_Data.c_str());
http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
int httpResponseCode = http.GET();
if (httpResponseCode > 0)
{
String payload;
payload = http.getString();
Serial.print("payload : ");
Serial.println(payload);
Serial.print("HTTP Status Code : ");
Serial.println(httpResponseCode);
}
else
{
Serial.println("Send failed.");
}
http.end();
}
mode = 2; // ОЖИДАНИЕ
}
В таком варианте в таблицу могут записаться как все 12 строк (каждые 2 часа), так и 5, и 7, и 4.
Решил проявить настойчивость в количестве пяти штук.
if (mode == 0)
//------------ ОБНОВЛЕНИЕ ДАННЫХ ---------------
{
if (wifiConnected())
{
//Обновление параметров каналов
HTTPClient http;
String Read_Data = Web_App_URL + "?sts=read";
Serial.println("Чтение из Google Spreadsheet...");
http.begin(Read_Data.c_str());
http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
//Подключаемся 5 раз
bool flag = false;
for(int i=0; i<5; i++)
{
int httpResponseCode = http.GET();
if (httpResponseCode > 0)
{
flag = true;
String payload;
payload = http.getString();
Serial.println("Payload OK get: " + payload);
for (int i = 0; i <= 5; i++)
{
if (getValue(payload, ',', 18).toInt() != 0)
{
prefs.begin("my-app", false);
Channels[i].soilMoisturePercentControl = getValue(payload, ',', i * 3).toInt();
Channels[i].volumeControl = getValue(payload, ',', i * 3 + 1).toInt();
prefs.putUChar(moistControlKeys[i], Channels[i].soilMoisturePercentControl);
prefs.putUChar(volControlKeys[i], Channels[i].volumeControl);
prefs.end();
Serial.println("Установки каналов обновлены");
}
if (getValue(payload, ',', i * 3 + 2).toInt() == 0)
{
Channels[i].isBlock = false;
}
if (getValue(payload, ',', i * 3 + 2).toInt() == 1)
{
Channels[i].isBlock = true;
}
}
if (getValue(payload, ',', 20).toInt() != 0)
{
flowCoeff = getValue(payload, ',', 19).toInt();
prefs.begin("my-app", false);
prefs.putUChar(flowCoeffKeys, flowCoeff);
prefs.end();
}
Serial.print("errorGet ");
Serial.println(errorGet);
break;
}
else
{
Serial.println("Get failed. Retrying...");
errorGet++;
}
}
if (!flag)
{
Serial.print("Could not get server: ");
Serial.println(errorGet);
FullErrorGet = 1;
}
http.end();
}
mode = 3;// КОНТРОЛЬ
}
else if (mode == 1)
//------------ ПЕРЕДАЧА ДАННЫХ ---------------
{
if (wifiConnected())
{
//Передача данных на сервер
HTTPClient http;
String Send_Data = Web_App_URL + "?sts=write";
Send_Data += "&date=" + dateStr;
Send_Data += "&time=" + timeStr;
Serial.println(Send_Data);
for (int i = 0; i <= 5; i++)
{
String I = String(i);
Send_Data += "&moisture" + I + "=" + String(Channels[i].soilMoisturePercent);
Send_Data += "&setMoisture" + I + "=" + String(Channels[i].soilMoisturePercentControl);
Send_Data += "&flowRate" + I + "=" + String(Channels[i].flowRate);
Send_Data += "&limit" + I + "=" + String(Channels[i].volumeControl);
Send_Data += "&block" + I + "=" + String(Channels[i].isBlock);
Send_Data += "&coef" + I + "=" + String(Channels[i].volumeCoeff);
}
Send_Data += "&reservuar=" + String(reservuar);
Send_Data += "&flowCoeff=" + String(flowCoeff);
Send_Data += "&erG=" + String(errorGet);
Send_Data += "&fErG=" + String(FullErrorGet);
Serial.println("Загрузка в Google Spreadsheet...");
Serial.print(errorSend);
Serial.print("...");
Serial.println(errorGet);
//Подключаемся 5 раз
bool flag = false;
for(int i=0; i<5; i++)
{
String Send_Data2 = "&erS=" + String(errorSend);
Send_Data2 += "&fErS=" + String(FullErrorSend);
Send_Data += Send_Data2;
http.begin(Send_Data.c_str());
http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
int httpResponseCode = http.GET();
Serial.print("HTTP Status Code : ");
Serial.println(httpResponseCode);
String payload;
payload = http.getString();
Serial.println("Payload send: " + payload);
if (httpResponseCode > 0)
{
flag = true;
//String payload;
Serial.print("HTTP Status Code : ");
Serial.println(httpResponseCode);
errorSend = 0;
FullErrorSend = 0;
errorGet = 0;
FullErrorGet = 0;
http.end();
break;
}
else
{
Serial.println("Send failed. Retrying...");
errorSend++;
http.end();
}
}
if (!flag)
{
Serial.print("Could not send to server: ");
Serial.println(errorSend);
FullErrorSend = 1;
}
}
mode = 2; // ОЖИДАНИЕ
}
При этом коде в случае сбоя (неправильный httpResponseCode) делается повторное подключение. Но… если в моониторе виден один сбой - в Гугле две идентичные записи, если два сбоя - три записи дрруг за другом.
17:21:27.617 -> https://script.google.com/macros/s/AKfycby_F7DFGWr1lbkndNWqarAFWWCijKWsuYNsECd6L7syDag756FcL8Ep9jBoqKm63B9N/exec?sts=write&date=21.05.2026&time=17:21:08
17:21:27.804 -> Загрузка в Google Spreadsheet...
17:21:33.535 -> HTTP Status Code : -11
17:21:33.535 -> Payload send:
17:21:33.581 -> Send failed. Retrying...
17:21:38.133 -> HTTP Status Code : 200
17:21:38.133 -> Payload send: Ok
17:21:38.179 -> HTTP Status Code : 200
17:27:08.203 -> Чтение из Google Spreadsheet...
17:27:13.568 -> Payload OK get: 70,40,0,80,40,0,70,40,0,60,30,0,70,40,0,70,40,0,0,128,0
Это из монитора порта. И на 17:21 в таблице две одинаковые записи.
Пытался подставить костыль в скрипте таблиц. Сравнить время с предыдущей записью и не писать дубль. Что-то не работает.
Получение данных (блок mode=0) работает хорошо. А вот в передаче (блок mode=1) где-то накосячил.
Если надо могу выложитть полный код и скрипт для таблицы, но без актуального идентификатора работать не будет.