mirror of
https://github.com/gunner47/GyverLamp.git
synced 2025-08-06 16:47:17 +03:00
388 lines
12 KiB
C++
388 lines
12 KiB
C++
void parseUDP()
|
||
{
|
||
int32_t packetSize = Udp.parsePacket();
|
||
|
||
if (packetSize)
|
||
{
|
||
int16_t n = Udp.read(packetBuffer, MAX_UDP_BUFFER_SIZE);
|
||
packetBuffer[n] = '\0';
|
||
strcpy(inputBuffer, packetBuffer);
|
||
|
||
#ifdef GENERAL_DEBUG
|
||
LOG.print(F("Inbound UDP packet: "));
|
||
LOG.println(inputBuffer);
|
||
#endif
|
||
|
||
if (Udp.remoteIP() == WiFi.localIP()) // не реагировать на свои же пакеты
|
||
{
|
||
return;
|
||
}
|
||
|
||
char reply[MAX_UDP_BUFFER_SIZE];
|
||
processInputBuffer(inputBuffer, reply, true);
|
||
|
||
#if (USE_MQTT) // отправка ответа выполнения команд по MQTT, если разрешено
|
||
if (espMode == 1U)
|
||
{
|
||
strcpy(MqttManager::mqttBuffer, reply); // разрешение определяется при выполнении каждой команды отдельно, команды GET, DEB, DISCOVER и OTA, пришедшие по UDP, игнорируются (приходят раз в 2 секунды от приложения)
|
||
}
|
||
#endif
|
||
|
||
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
|
||
Udp.write(reply);
|
||
Udp.endPacket();
|
||
|
||
#ifdef GENERAL_DEBUG
|
||
LOG.print(F("Outbound UDP packet: "));
|
||
LOG.println(reply);
|
||
LOG.println();
|
||
#endif
|
||
}
|
||
}
|
||
|
||
|
||
void processInputBuffer(char *inputBuffer, char *outputBuffer, bool generateOutput)
|
||
{
|
||
char buff[MAX_UDP_BUFFER_SIZE], *endToken = NULL;
|
||
|
||
if (!strncmp_P(inputBuffer, PSTR("DEB"), 3))
|
||
{
|
||
#ifdef USE_NTP
|
||
getFormattedTime(inputBuffer);
|
||
sprintf_P(inputBuffer, PSTR("OK %s"), inputBuffer);
|
||
#else
|
||
strcpy_P(inputBuffer, PSTR("OK --:--"));
|
||
#endif
|
||
}
|
||
|
||
else if (!strncmp_P(inputBuffer, PSTR("GET"), 3))
|
||
{
|
||
sendCurrent(inputBuffer);
|
||
}
|
||
|
||
else if (!strncmp_P(inputBuffer, PSTR("EFF"), 3))
|
||
{
|
||
EepromManager::SaveModesSettings(¤tMode, modes);
|
||
memcpy(buff, &inputBuffer[3], strlen(inputBuffer)); // взять подстроку, состоящую последних символов строки inputBuffer, начиная с символа 4
|
||
currentMode = (uint8_t)atoi(buff);
|
||
loadingFlag = true;
|
||
settChanged = true;
|
||
eepromTimeout = millis();
|
||
FastLED.clear();
|
||
delay(1);
|
||
sendCurrent(inputBuffer);
|
||
FastLED.setBrightness(modes[currentMode].Brightness);
|
||
|
||
#if (USE_MQTT)
|
||
if (espMode == 1U)
|
||
{
|
||
MqttManager::needToPublish = true;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
else if (!strncmp_P(inputBuffer, PSTR("BRI"), 3))
|
||
{
|
||
memcpy(buff, &inputBuffer[3], strlen(inputBuffer)); // взять подстроку, состоящую последних символов строки inputBuffer, начиная с символа 4
|
||
modes[currentMode].Brightness = constrain(atoi(buff), 1, 255);
|
||
FastLED.setBrightness(modes[currentMode].Brightness);
|
||
loadingFlag = true;
|
||
settChanged = true;
|
||
eepromTimeout = millis();
|
||
sendCurrent(inputBuffer);
|
||
|
||
#if (USE_MQTT)
|
||
if (espMode == 1U)
|
||
{
|
||
MqttManager::needToPublish = true;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
else if (!strncmp_P(inputBuffer, PSTR("SPD"), 3))
|
||
{
|
||
memcpy(buff, &inputBuffer[3], strlen(inputBuffer)); // взять подстроку, состоящую последних символов строки inputBuffer, начиная с символа 4
|
||
modes[currentMode].Speed = atoi(buff);
|
||
loadingFlag = true;
|
||
settChanged = true;
|
||
eepromTimeout = millis();
|
||
sendCurrent(inputBuffer);
|
||
|
||
#if (USE_MQTT)
|
||
if (espMode == 1U)
|
||
{
|
||
MqttManager::needToPublish = true;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
else if (!strncmp_P(inputBuffer, PSTR("SCA"), 3))
|
||
{
|
||
memcpy(buff, &inputBuffer[3], strlen(inputBuffer)); // взять подстроку, состоящую последних символов строки inputBuffer, начиная с символа 4
|
||
modes[currentMode].Scale = atoi(buff);
|
||
loadingFlag = true;
|
||
settChanged = true;
|
||
eepromTimeout = millis();
|
||
sendCurrent(inputBuffer);
|
||
|
||
#if (USE_MQTT)
|
||
if (espMode == 1U)
|
||
{
|
||
MqttManager::needToPublish = true;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
else if (!strncmp_P(inputBuffer, PSTR("P_ON"), 4))
|
||
{
|
||
ONflag = true;
|
||
loadingFlag = true;
|
||
settChanged = true;
|
||
eepromTimeout = millis();
|
||
changePower();
|
||
sendCurrent(inputBuffer);
|
||
|
||
#if (USE_MQTT)
|
||
if (espMode == 1U)
|
||
{
|
||
MqttManager::needToPublish = true;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
else if (!strncmp_P(inputBuffer, PSTR("P_OFF"), 5))
|
||
{
|
||
ONflag = false;
|
||
settChanged = true;
|
||
eepromTimeout = millis();
|
||
changePower();
|
||
sendCurrent(inputBuffer);
|
||
|
||
#if (USE_MQTT)
|
||
if (espMode == 1U)
|
||
{
|
||
MqttManager::needToPublish = true;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
else if (!strncmp_P(inputBuffer, PSTR("ALM_SET"), 7))
|
||
{
|
||
uint8_t alarmNum = (char)inputBuffer[7] - '0';
|
||
alarmNum -= 1;
|
||
if (strstr_P(inputBuffer, PSTR("ON")) - inputBuffer == 9)
|
||
{
|
||
alarms[alarmNum].State = true;
|
||
sendAlarms(inputBuffer);
|
||
}
|
||
else if (strstr_P(inputBuffer, PSTR("OFF")) - inputBuffer == 9)
|
||
{
|
||
alarms[alarmNum].State = false;
|
||
sendAlarms(inputBuffer);
|
||
}
|
||
else
|
||
{
|
||
memcpy(buff, &inputBuffer[8], strlen(inputBuffer)); // взять подстроку, состоящую последних символов строки inputBuffer, начиная с символа 9
|
||
alarms[alarmNum].Time = atoi(buff);
|
||
sendAlarms(inputBuffer);
|
||
}
|
||
EepromManager::SaveAlarmsSettings(&alarmNum, alarms);
|
||
|
||
#if (USE_MQTT)
|
||
if (espMode == 1U)
|
||
{
|
||
strcpy(MqttManager::mqttBuffer, inputBuffer);
|
||
MqttManager::needToPublish = true;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
else if (!strncmp_P(inputBuffer, PSTR("ALM_GET"), 7))
|
||
{
|
||
sendAlarms(inputBuffer);
|
||
}
|
||
|
||
else if (!strncmp_P(inputBuffer, PSTR("DAWN"), 4))
|
||
{
|
||
memcpy(buff, &inputBuffer[4], strlen(inputBuffer)); // взять подстроку, состоящую последних символов строки inputBuffer, начиная с символа 5
|
||
dawnMode = atoi(buff) - 1;
|
||
EepromManager::SaveDawnMode(&dawnMode);
|
||
sendAlarms(inputBuffer);
|
||
|
||
#if (USE_MQTT)
|
||
if (espMode == 1U)
|
||
{
|
||
MqttManager::needToPublish = true;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
else if (!strncmp_P(inputBuffer, PSTR("DISCOVER"), 8)) // обнаружение приложением модуля esp в локальной сети
|
||
{
|
||
if (espMode == 1U) // работает только в режиме WiFi клиента
|
||
{
|
||
sprintf_P(inputBuffer, PSTR("IP %u.%u.%u.%u:%u"),
|
||
WiFi.localIP()[0],
|
||
WiFi.localIP()[1],
|
||
WiFi.localIP()[2],
|
||
WiFi.localIP()[3],
|
||
ESP_UDP_PORT);
|
||
}
|
||
}
|
||
|
||
else if (!strncmp_P(inputBuffer, PSTR("TMR_GET"), 7))
|
||
{
|
||
sendTimer(inputBuffer);
|
||
}
|
||
|
||
else if (!strncmp_P(inputBuffer, PSTR("TMR_SET"), 7))
|
||
{
|
||
memcpy(buff, &inputBuffer[8], 2); // взять подстроку, состоящую из 9 и 10 символов, из строки inputBuffer
|
||
TimerManager::TimerRunning = (bool)atoi(buff);
|
||
|
||
memcpy(buff, &inputBuffer[10], 2); // взять подстроку, состоящую из 11 и 12 символов, из строки inputBuffer
|
||
TimerManager::TimerOption = (uint8_t)atoi(buff);
|
||
|
||
memcpy(buff, &inputBuffer[12], strlen(inputBuffer)); // взять подстроку, состоящую последних символов строки inputBuffer, начиная с символа 13
|
||
TimerManager::TimeToFire = millis() + strtoull(buff, &endToken, 10) * 1000;
|
||
|
||
TimerManager::TimerHasFired = false;
|
||
sendTimer(inputBuffer);
|
||
|
||
#if (USE_MQTT)
|
||
if (espMode == 1U)
|
||
{
|
||
MqttManager::needToPublish = true;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
else if (!strncmp_P(inputBuffer, PSTR("FAV_GET"), 7))
|
||
{
|
||
FavoritesManager::SetStatus(inputBuffer);
|
||
}
|
||
|
||
else if (!strncmp_P(inputBuffer, PSTR("FAV_SET"), 7))
|
||
{
|
||
FavoritesManager::ConfigureFavorites(inputBuffer);
|
||
FavoritesManager::SetStatus(inputBuffer);
|
||
settChanged = true;
|
||
eepromTimeout = millis();
|
||
|
||
#if (USE_MQTT)
|
||
if (espMode == 1U)
|
||
{
|
||
MqttManager::needToPublish = true;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
else if (!strncmp_P(inputBuffer, PSTR("OTA"), 3))
|
||
{
|
||
#ifdef OTA
|
||
otaManager.RequestOtaUpdate();
|
||
delay(50);
|
||
otaManager.RequestOtaUpdate();
|
||
currentMode = EFF_MATRIX; // принудительное включение режима "Матрица" для индикации перехода в режим обновления по воздуху
|
||
FastLED.clear();
|
||
delay(1);
|
||
ONflag = true;
|
||
changePower();
|
||
#endif
|
||
}
|
||
|
||
else if (!strncmp_P(inputBuffer, PSTR("BTN"), 3))
|
||
{
|
||
if (strstr_P(inputBuffer, PSTR("ON")) - inputBuffer == 4)
|
||
{
|
||
buttonEnabled = true;
|
||
EepromManager::SaveButtonEnabled(&buttonEnabled);
|
||
sendCurrent(inputBuffer);
|
||
}
|
||
else if (strstr_P(inputBuffer, PSTR("OFF")) - inputBuffer == 4)
|
||
{
|
||
buttonEnabled = false;
|
||
EepromManager::SaveButtonEnabled(&buttonEnabled);
|
||
sendCurrent(inputBuffer);
|
||
}
|
||
|
||
#if (USE_MQTT)
|
||
if (espMode == 1U)
|
||
{
|
||
strcpy(MqttManager::mqttBuffer, inputBuffer);
|
||
MqttManager::needToPublish = true;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
else
|
||
{
|
||
inputBuffer[0] = '\0';
|
||
}
|
||
|
||
if (strlen(inputBuffer) <= 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (generateOutput) // если запрошен вывод ответа выполнения команд, копируем его в исходящий буфер
|
||
{
|
||
strcpy(outputBuffer, inputBuffer);
|
||
}
|
||
inputBuffer[0] = '\0'; // очистка буфера, читобы не он не интерпретировался, как следующий входной пакет
|
||
}
|
||
|
||
void sendCurrent(char *outputBuffer)
|
||
{
|
||
sprintf_P(outputBuffer, PSTR("CURR %u %u %u %u %u %u"),
|
||
currentMode,
|
||
modes[currentMode].Brightness,
|
||
modes[currentMode].Speed,
|
||
modes[currentMode].Scale,
|
||
ONflag,
|
||
espMode);
|
||
|
||
#ifdef USE_NTP
|
||
strcat_P(outputBuffer, PSTR(" 1"));
|
||
#else
|
||
strcat_P(outputBuffer, PSTR(" 0"));
|
||
#endif
|
||
|
||
sprintf_P(outputBuffer, PSTR("%s %u"), outputBuffer, (uint8_t)TimerManager::TimerRunning);
|
||
sprintf_P(outputBuffer, PSTR("%s %u"), outputBuffer, (uint8_t)buttonEnabled);
|
||
|
||
#ifdef USE_NTP
|
||
char timeBuf[9];
|
||
getFormattedTime(timeBuf);
|
||
sprintf_P(outputBuffer, PSTR("%s %s"), outputBuffer, timeBuf);
|
||
#else
|
||
time_t currentTicks = millis() / 1000UL;
|
||
sprintf_P(outputBuffer, PSTR("%s %02u:%02u:%02u"), outputBuffer, hour(currentTicks), minute(currentTicks), second(currentTicks));
|
||
#endif
|
||
}
|
||
|
||
void sendAlarms(char *outputBuffer)
|
||
{
|
||
strcpy_P(outputBuffer, PSTR("ALMS"));
|
||
|
||
for (byte i = 0; i < 7; i++)
|
||
{
|
||
sprintf_P(outputBuffer, PSTR("%s %u"), outputBuffer, (uint8_t)alarms[i].State);
|
||
}
|
||
|
||
for (byte i = 0; i < 7; i++)
|
||
{
|
||
sprintf_P(outputBuffer, PSTR("%s %u"), outputBuffer, alarms[i].Time);
|
||
}
|
||
|
||
sprintf_P(outputBuffer, PSTR("%s %u"), outputBuffer, dawnMode + 1);
|
||
}
|
||
|
||
void sendTimer(char *outputBuffer)
|
||
{
|
||
sprintf_P(outputBuffer, PSTR("TMR %u %u %u"),
|
||
TimerManager::TimerRunning,
|
||
TimerManager::TimerOption,
|
||
(TimerManager::TimerRunning ? (uint16_t)floor((TimerManager::TimeToFire - millis()) / 1000) : 0));
|
||
}
|