Смартфон Android версия прошивки - 2.19.1
Локальный сервер - версия 0.33.1. Проблема наблюдается во всех версиях начиная с 0.30.3 по 0.33.1. В версии 0.30.2 локального сервера проблема отсутствует.
Версия библиотеки - 0.5.1
Устройства основаны на Wemos d1 mini pro.
Суть проблемы:
В аккаунте находится четыре проекта. Настройки виджета Time Input в одном приложении влияют на настройки в другом. Хотя проекты между собой никак не связаны, даже мостом. Попробую наглядно показать на скриншотах ниже.
В истории показывает значение начала работы таймера в секундах. После первого запуска устройства видно это значение равно 36000 секундам, что соответствует настройке таймера на 10 часов утра. Затем переменная принимает значение 10800 секунд, что соответствует 3 часам утра. При этом таймер расположенный слева работает отменно. Виртуальный пин проблемного таймера V7 в приложении роллета.
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <TimeLib.h>
#include <WidgetRTC.h>
#include <ArduinoOTA.h>
// Присваивсаем ножкам функции
#define SVET 5 // ножка управляет светом на балконе D1
#define PITANIE 4 // ножка управляет светом на балконе D2
#define ROLLETA 16 // ножка управляет роллетой на балконе D0
#define TIME 40000 // время открытия/закрытия роллеты в мс
BlynkTimer timer;
WidgetRTC rtc;
WidgetTerminal terminal(V0); // виртуальный пин для терминала на телефоне
char auth[] = "-";
char ssid[] = "-";
char pass[] = "-";
String week = " ";
String currentTime; // переменная хранит время
String currentDate; // переменная хранит дату
String minutenorm; // переменная для преобразования минут в нормальный формат
long timenow = 0; // текущее время в секундах
boolean firststart; //переменная хранящая значение первый ли это старт, чтобы при старте устройства не писалось сообщение о подключении к облаку.
int buttonV6; // кнопка свет балкон
int buttonV9; // кнопка автооткрытие
boolean otkritie = false; // переменная true во время открытия роллеты
boolean zakritie = false; // переменная true во время закрытия роллеты
boolean sostoyanie = false; // переменная true - когда роллета открыта и false - когда закрыта.
long startTimeV4 = 0; // начало задания в секундах, автооткрытие
boolean weekV4[8]; // день недели, зона автооткрытие
long startTimeV7 = 0; // начало задания в секундах, автооткрытие
boolean weekV7[8]; // день недели, зона автооткрытие
BLYNK_CONNECTED() {
if (firststart == true) {
terminal.println(String(currentTime) + " " + currentDate + " Подключение к облаку!"); // сообщение о подключении к облаку
terminal.flush(); // отправляет данные из устройства в терминал
}
Blynk.syncAll();// синхронизируем выходы, после потерия связи.
}
// АВТООТКРЫТИЕ
BLYNK_WRITE(V4) {
TimeInputParam tV4(param);
startTimeV4 = param[0].asLong();
for (int i = 1; i <= 6; i++) {
if (tV4.isWeekdaySelected(i)) {weekV4[i+1] = 1;} // с понедельника по субботу
else {weekV4[i+1] = 0;}
}
if (tV4.isWeekdaySelected(7)) {weekV4[1] = 1;} // воскресенье
else {weekV4[1] = 0;}
}
// АВТООТКРЫТИЕ
BLYNK_WRITE(V7) {
TimeInputParam tV7(param);
startTimeV7 = param[0].asLong();
for (int i = 1; i <= 6; i++) {
if (tV7.isWeekdaySelected(i)) {weekV7[i+1] = 1;} // с понедельника по субботу
else {weekV7[i+1] = 0;}
}
if (tV7.isWeekdaySelected(7)) {weekV7[1] = 1;} // воскресенье
else {weekV7[1] = 0;}
}
// Кнопка СВЕТ БАЛКОН
BLYNK_WRITE(V6) {
if(param.asInt() != buttonV6){
buttonV6 = param.asInt();
if (buttonV6 == 1) {
digitalWrite(SVET, LOW); // переводим пин D1 в включенное состояние
terminal.println(String(currentTime) + " " + currentDate + " Свет балкон - ВКЛЮЧЕНО");
}
else {
digitalWrite(SVET, HIGH); // переводим пин D1 в выключенное состояние
terminal.println(String(currentTime) + " " + currentDate + " Свет балкон - ВЫКЛЮЧЕНО");
}
terminal.flush(); // отправляет данные из устройства в терминал
}
}
// Кнопка АВТООТКРЫТИЕ
BLYNK_WRITE(V9) {
if(param.asInt() != buttonV9){
buttonV9 = param.asInt();
if (buttonV9 == 1) {
terminal.println(String(currentTime) + " " + currentDate + " Автооткрытие - ВКЛ.!");
}
else {
terminal.println(String(currentTime) + " " + currentDate + " Автооткрытие - ВЫКЛ.!");
}
terminal.flush(); // отправляет данные из устройства в терминал
}
}
// Кнопка СТОП
BLYNK_WRITE(V8) {
if ((param.asInt() == 1) && ((otkritie == true) || (zakritie == true))) {
digitalWrite(PITANIE, HIGH); // выключаем питание
terminal.println(String(currentTime) + " " + currentDate + " Роллета - СТОП!");
terminal.flush(); // отправляет данные из устройства в терминал
}
}
// Кнопка РОЛЛЕТА
BLYNK_WRITE(V5) {
if ((param.asInt() == 1) && (firststart == true) && (sostoyanie == true) && (otkritie == false) && (zakritie == false)) { // ЗАКРЫТИЕ
zakritie = true; //блокируем выполнение команд во время закрытия
digitalWrite(ROLLETA, LOW); // закрываем роллету
digitalWrite(PITANIE, LOW); // включаем питание
timer.setTimeout(TIME, pitanietimer); // таймер ОТКРЫТИЯ/ЗАКРЫТИЯ роллеты
}
if ((param.asInt() == 1) && (firststart == true) && (sostoyanie == false) && (otkritie == false) && (zakritie == false)) { // ОТКРЫТИЕ
otkritie = true; //блокируем выполнение команд во время открытия
digitalWrite(ROLLETA, HIGH); // открываем роллету
digitalWrite(PITANIE, LOW); // включаем питание
timer.setTimeout(TIME, pitanietimer); // таймер ОТКРЫТИЯ/ЗАКРЫТИЯ роллеты
}
}
void pitanietimer() {
digitalWrite(PITANIE, HIGH); // выключаем питание
if (sostoyanie == true) {
sostoyanie = false; // переводим переменную в состояние ЗАКРЫТО
zakritie = false; // разблокируем выполнение команд во время закрытия
Blynk.setProperty(V5, "onLabel", "Открыть"); // меняем надпись на кнопке РОЛЛЕТА
Blynk.setProperty(V5, "offLabel", "Открыть");
terminal.println(String(currentTime) + " " + currentDate + " Роллета - ЗАКРЫТА");
}
else {
sostoyanie = true; // переводим переменную в состояние ОТКРЫТО
otkritie = false; // разблокируем выполнение команд во время открытия
Blynk.setProperty(V5, "onLabel", "Закрыть"); // меняем надпись на кнопке РОЛЛЕТА
Blynk.setProperty(V5, "offLabel", "Закрыть");
terminal.println(String(currentTime) + " " + currentDate + " Роллета - ОТКРЫТА");
}
terminal.flush(); // отправляет данные из устройства в терминал
}
void autoplay() {
// ЧАСЫ И ДАТА
if (minute() < 10) {minutenorm = String("0") + minute();} // необходимо для преобразования минут в формат 00 - 59
else {minutenorm = minute();}
currentTime = String(hour()) + ":" + minutenorm; //записываем в переменную время
switch (weekday()) {
case 1:
week = "Sun";
break;
case 2:
week = "Mon";
break;
case 3:
week = "Tue";
break;
case 4:
week = "Wed";
break;
case 5:
week = "Thu";
break;
case 6:
week = "Fri";
break;
case 7:
week = "Sat";
break;
default:
week = "Err";
}
currentDate = String(day()) + "." + month() + "." + year() + " " + week; //записываем в переменную дату
Blynk.virtualWrite(V1, currentTime); // выводим в приложение время
Blynk.virtualWrite(V2, currentDate); // выводим в приложение дату
// УРОВЕНЬ WI-FI
Blynk.virtualWrite(V3, WiFi.RSSI());
timenow = hour()*3600 + minute()*60 + second(); //текущее время в секундах
// АВТООТКРЫТИЕ
if (((buttonV9 == 1) && (otkritie == false) && (sostoyanie == false) && (weekV4[weekday()] == true) && (timenow >= startTimeV4) && (timenow <= (startTimeV4 + TIME/1000))) || ((buttonV9 == 1) && (otkritie == false) && (sostoyanie == false) && (weekV7[weekday()] == true) && (timenow >= startTimeV7) && (timenow <= (startTimeV7 + TIME/1000))))
{
otkritie = true; //блокируем выполнение команд во время открытия
digitalWrite(ROLLETA, HIGH); // открываем роллету
digitalWrite(PITANIE, LOW); // включаем питание
timer.setTimeout(TIME, pitanietimer); // таймер ОТКРЫТИЯ/ЗАКРЫТИЯ роллеты
}
// terminal.println(timenow);
// terminal.println(weekV4[weekday()]);
// terminal.println(startTimeV4);
// terminal.println(weekV7[weekday()]);
terminal.println(startTimeV7);
terminal.flush(); // отправляет данные из устройства в терминал
}
void setup() {
pinMode(SVET, OUTPUT); // перевод пина D1 в режим выхода СВЕТ БАЛКОН
pinMode(PITANIE, OUTPUT); // перевод пина D2 в режим выхода ПИТАНИЕ РОЛЛЕТЫ
pinMode(ROLLETA, OUTPUT); // перевод пина D0 в режим выхода УПРАВЛЕНИЕ РОЛЛЕТОЙ
digitalWrite(SVET, HIGH); // переводим пин D1 в выключенное состояние
digitalWrite(PITANIE, HIGH); // переводим пин D2 в выключенное состояние
digitalWrite(ROLLETA, HIGH); // переводим пин D0 в выключенное состояние
Blynk.begin(auth, ssid, pass, IPAddress(192,168,0,105), 8080);
rtc.begin(); // синхронизируем часы
terminal.println("Успешный старт!"); // пишем что все ОК
terminal.print("- Уровень сигнала, dBm: ");
terminal.println(WiFi.RSSI()); // уровень сигнала
terminal.print("- IP адресс: ");
terminal.println(WiFi.localIP()); // IP адресс выданный в сети
terminal.print("- MAC адресс: ");
terminal.println(WiFi.macAddress()); // MAC адресс выданный в сети
terminal.flush(); // отправляет данные из устройства в терминал
Blynk.virtualWrite(V3, WiFi.RSSI()); // уровень сигнала при старте
timer.setInterval(3000, autoplay); // вызываем цикл каждые 3 секунд
firststart = true; // первое подключение к облаку.
ArduinoOTA.setPassword((const char *)"-"); // пароль для обновления по воздуху
ArduinoOTA.begin(); //обновление по воздуху
}
void loop() {
Blynk.run();
timer.run();
ArduinoOTA.handle();
}