886 lines
31 KiB
C++
886 lines
31 KiB
C++
#include <lwip/sockets.h>
|
|
#undef INADDR_NONE
|
|
#include <lwip/netdb.h>
|
|
#include <WiFiServer.h>
|
|
#include <HTTPClient.h>
|
|
#include <WiFiClientSecure.h>
|
|
#include <esp_task_wdt.h>
|
|
#include <netinet/in.h> // For struct in_addr
|
|
#include <esp_task_wdt.h>
|
|
#include <esp_system.h>
|
|
#include "OTA.h"
|
|
|
|
#include "HermitCrab.h"
|
|
#include "Config.h"
|
|
#include "ConnectWiFi.h"
|
|
#include "TimeManager.h"
|
|
#include "History.h"
|
|
#include "zcd.h"
|
|
#include "AHT2x.h"
|
|
#include "WiFiHost.h"
|
|
#include "UPnPClient.h"
|
|
|
|
|
|
|
|
#define TAG_WIFI_HOST "WiFi Host"
|
|
#define TCP_PACKET_SIZE_MAX 1460
|
|
|
|
//WiFiServer wifiServer(SERVER_PORT);
|
|
//WiFiClient wifiClient;
|
|
CWiFiHost host;
|
|
CONFIG_TYPE configCopy;
|
|
|
|
void CWiFiHost::Setup()
|
|
{
|
|
// UDP Packet
|
|
packetUDP = {
|
|
.sig1 = SIGNATURE1,
|
|
.m_nSize = sizeof(UDP_PACKET),
|
|
.m_nMessage = UDP_MESSAGE::MESSAGE_HEARTBEAT,
|
|
.m_nDeviceType = config.m_nDeviceType,
|
|
.m_nResetReason = RESET_REASON_CHIP_POWER_ON,
|
|
.m_nChipID = config.m_nChipId,
|
|
.m_nDeviceID = 0,
|
|
//.m_nVersion = (uint32_t)atoll(&HC__VERSION[2]),
|
|
.dwIPAddress = 0,
|
|
.m_nPort = UDP_PORT,
|
|
//.m_MACAddress = "",
|
|
//.m_sDeviceName = "",
|
|
.status = {0},
|
|
.sig2 = SIGNATURE2 };
|
|
packetUDP.m_nVersion = (uint32_t)atoll(&HC__VERSION[2]);
|
|
strncpy((char *)packetUDP.m_MACAddress, WiFi.macAddress().c_str(), 17);
|
|
packetUDP.m_MACAddress[17] = 0;
|
|
strcpy(packetUDP.m_sDeviceName, config.m_sDeviceName);
|
|
|
|
// TCP Packet
|
|
hostPacket = {
|
|
.sig1 = SIGNATURE1,
|
|
.len = sizeof(TCP_PACKET),
|
|
.cmd = ENUM_COMMAND::CMD_HELLO,
|
|
.op = OPERATION_MODE::MODE_WAITING,
|
|
.time = 0,
|
|
.status = {0},
|
|
.sig2 = SIGNATURE2 };
|
|
clientPacket = hostPacket;
|
|
|
|
//if (m_nPublicPort == 0)
|
|
{
|
|
if (config.m_nPublicPort == 0)
|
|
config.m_nPublicPort = (uint16_t)(config.m_nChipId & 0xFFFF);
|
|
m_nPublicPort = config.m_nPublicPort;
|
|
}
|
|
|
|
wifiServer = WiFiServer(SERVER_PORT, 1);
|
|
wifiExternal = WiFiServer(m_nPublicPort, 1);
|
|
|
|
//wifiStatus = WIFI_NOT_CONNECTED;
|
|
m_nDataSend_sent = 0;
|
|
m_nDataReceive_size = 0;
|
|
m_pDataSend_data = nullptr;
|
|
m_nDataReceive_received = 0;
|
|
m_nDataReceive_size = 0;
|
|
m_pDataReceive_data = nullptr;
|
|
|
|
externalServerIP = IPAddress((uint32_t) 0UL);
|
|
//sockfd = -1;
|
|
//connectStartTime = 0;
|
|
//isConnecting = false;
|
|
|
|
// Operation
|
|
m_nMode = MODE_WAITING;
|
|
m_bHelloSent = false;
|
|
m_bSendHistoryPending = false;
|
|
|
|
m_nLastReceivedTime =
|
|
m_nLastHeartBeatSentTime =
|
|
m_nLastUDPBroadcastTime = millis();
|
|
m_bClientConnected = false;
|
|
m_dwPublicIP = 0;
|
|
wifiClient.stop();
|
|
|
|
if (isWiFiConnected())
|
|
{
|
|
// UPnP Client
|
|
{
|
|
uint32_t ip = WiFi.gatewayIP();
|
|
uint16_t port = m_nPublicPort;
|
|
CUpnpClient upnp;
|
|
|
|
if (upnp.registerUPnP(&ip, &port)) {
|
|
status.nFlags |= FLAG_UPNP;
|
|
} else {
|
|
status.nFlags &= ~FLAG_UPNP;
|
|
}
|
|
|
|
if (ip != 0)
|
|
m_dwPublicIP = ip;
|
|
if (port != m_nPublicPort) {
|
|
config.m_nPublicPort = port;
|
|
config.save();
|
|
m_nPublicPort = port;
|
|
}
|
|
|
|
}
|
|
|
|
// Server
|
|
wifiServer.begin(SERVER_PORT, 1);
|
|
wifiExternal.begin(m_nPublicPort, 1);
|
|
m_nLastReceivedTime = millis();
|
|
m_bClientConnected = false;
|
|
|
|
// UDP
|
|
packetUDP.dwIPAddress = WiFi.localIP();
|
|
udpLocal.begin(UDP_PORT);
|
|
udpExternal.begin(UDP_EXTERNAL_PORT);
|
|
|
|
if (m_cExternalServerIPAddress == IPAddress((uint32_t) 0l)) {
|
|
if (WiFi.hostByName("visionsoft.kr", m_cExternalServerIPAddress)) {
|
|
DPRINTF("WiFi - ExternalServer IP resolved as \"%s\"\n", m_cExternalServerIPAddress.toString().c_str());
|
|
} else {
|
|
m_cExternalServerIPAddress = IPAddress((uint32_t) 0);
|
|
DPRINTF("WiFi - ExternalServer IP NOT resolved\n");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
MY_IRAM_ATTR void CWiFiHost::Stop() {
|
|
CloseConnection();
|
|
|
|
// Stop server
|
|
wifiServer.stop();
|
|
wifiExternal.stop();
|
|
m_bClientConnected = false;
|
|
|
|
// Stop Client
|
|
if (wifiClient)
|
|
wifiClient.stop();
|
|
|
|
// Stop UDP
|
|
udpLocal.stop(); // or udpLocal.end(); depending on your preference
|
|
udpExternal.stop(); // or udpExternal.end(); depending on your preference
|
|
}
|
|
|
|
MY_IRAM_ATTR void CWiFiHost::CloseConnection()
|
|
{
|
|
if (wifiClient && wifiClient.connected()) wifiClient.stop();
|
|
m_bClientConnected = false;
|
|
m_nMode = MODE_WAITING;
|
|
}
|
|
|
|
IRAM_ATTR void CWiFiHost::Loop(unsigned long clock)
|
|
{
|
|
static unsigned long lastReceivedTime = 0;
|
|
if (!isWiFiConnected()) return;
|
|
|
|
switch (m_nMode) {
|
|
case MODE_WAITING: // Expecting connection from clients
|
|
if (m_bClientConnected)
|
|
{
|
|
ESP_LOGI(TAG_WIFI_HOST,"Host: dropping connection for not connected");
|
|
if (wifiClient && wifiClient.connected()) {
|
|
ESP_LOGI(TAG_WIFI_HOST,"Host: stopping wifi client");
|
|
wifiClient.stop();
|
|
}
|
|
m_bClientConnected = false;
|
|
}
|
|
|
|
// Accept from internal XOR external port
|
|
wifiClient = wifiServer.accept();
|
|
if (!wifiClient || !wifiClient.connected()) {
|
|
wifiClient = wifiExternal.accept();
|
|
}
|
|
|
|
if (wifiClient && wifiClient.connected())
|
|
{
|
|
ESP_LOGI(TAG_WIFI_HOST,"Host: Connection Accepted");
|
|
wifiClient.setNoDelay(true);
|
|
m_nLastReceivedTime = clock;
|
|
m_bClientConnected = true;
|
|
m_bHelloSent = false;
|
|
m_nMode = MODE_PACKET;
|
|
|
|
// LED
|
|
ledcWrite(PIN_LED_WIFI, PWM_FULL - 10); // Amost ON
|
|
}
|
|
break;
|
|
case MODE_PACKET:
|
|
// Client Connected
|
|
if (m_bClientConnected && wifiClient.connected())
|
|
{
|
|
CheckClient(clock);
|
|
|
|
if (m_bClientConnected) {
|
|
if (clock - m_nLastReceivedTime > 60000)
|
|
{
|
|
ESP_LOGI(TAG_WIFI_HOST,"Host: dropping connection for no HB in 60 seconds");
|
|
wifiClient.stop();
|
|
m_bClientConnected = false;
|
|
}
|
|
|
|
// Send HeartBeat
|
|
if (clock - m_nLastHeartBeatSentTime >= 1000) {
|
|
SendHeartBeat();
|
|
m_nLastHeartBeatSentTime = clock;
|
|
}
|
|
}
|
|
}
|
|
if (!m_bClientConnected || !wifiClient.connected()) {
|
|
m_nMode = MODE_WAITING;
|
|
// LED
|
|
ledcWrite(PIN_LED_WIFI, PWM_FULL - 2); // Almost Off
|
|
}
|
|
break;
|
|
case MODE_SEND:
|
|
if (SendData(clock)) {
|
|
if (m_bSendHistoryPending) {
|
|
// Mark pending to send the second part: from the start to head-1
|
|
//SendData(history.getRingData2() /* &ring[0] */, sizeof(STATUS_TYPE) * head);
|
|
//m_bSendHistoryPending = true;
|
|
//m_nPendingHistoryCount = history.getHead();
|
|
m_bSendHistoryPending = false;
|
|
if (m_nPendingHistoryCount > 0) {
|
|
ESP_LOGI(TAG_WIFI_HOST,"WfFi Host - SendData - 2nd part of History (%d)\n", m_nPendingHistoryCount);
|
|
SendData(history.getRingData2(), sizeof(STATUS_TYPE) * m_nPendingHistoryCount);
|
|
m_nPendingHistoryCount = 0;
|
|
}
|
|
} else {
|
|
m_nMode = MODE_PACKET;
|
|
}
|
|
}
|
|
break;
|
|
case MODE_RECV:
|
|
if (ReceiveData(clock)) m_nMode = MODE_PACKET;
|
|
break;
|
|
}
|
|
}
|
|
|
|
MY_IRAM_ATTR void CWiFiHost::SendHeartBeat(unsigned long clock) {
|
|
if (!isWiFiConnected()) {
|
|
//ESP_LOGI(TAG_WIFI_HOST,"WiFiHost - SendHeartBeat() called while not connected!");
|
|
return;
|
|
}
|
|
|
|
// Send Heartbeats to external server and to local devices
|
|
if (clock - m_nLastUDPBroadcastTime > 1000) {
|
|
static int count = 55;
|
|
|
|
// UDP Heartbeat
|
|
if (++count >= 60) {
|
|
// External Heartbeat
|
|
UDP_CONFIG_TYPE pktConfig;
|
|
pktConfig.udp = packetUDP;
|
|
pktConfig.udp.m_nPort = m_nPublicPort;
|
|
pktConfig.udp.dwIPAddress = m_dwPublicIP;
|
|
pktConfig.udp.status = status;
|
|
|
|
if (((uint32_t)m_cExternalServerIPAddress) != (uint32_t)0l)
|
|
udpExternal.beginPacket(m_cExternalServerIPAddress, (uint16_t)UDP_EXTERNAL_PORT);
|
|
else
|
|
udpExternal.beginPacket("visionsoft.kr", (uint16_t)UDP_EXTERNAL_PORT);
|
|
|
|
if (config.bConfigSaved) {
|
|
// Config is save locally. Save it on cloud
|
|
config.bConfigSaved = false;
|
|
pktConfig.udp.m_nMessage = MESSAGE_CONFIG_SAVE;
|
|
pktConfig.con = config;
|
|
udpExternal.write((uint8_t*)&pktConfig, sizeof(pktConfig));
|
|
ESP_LOGI(TAG_WIFI_HOST,"HeartBeat Packet *Config Save* sent out to external Server");
|
|
} else {
|
|
// Send only UDP packet
|
|
udpExternal.write((uint8_t*)&(pktConfig.udp), sizeof(UDP_PACKET));
|
|
}
|
|
udpExternal.endPacket();
|
|
count = 0;
|
|
} else if (!m_bClientConnected) {
|
|
// Local AP broadcast
|
|
packetUDP.m_nMessage = UDP_MESSAGE::MESSAGE_HEARTBEAT;
|
|
packetUDP.dwIPAddress = WiFi.localIP();
|
|
packetUDP.m_nPort = SERVER_PORT;
|
|
strcpy(packetUDP.m_sCompanyName, COMPANY_NAME);
|
|
strcpy(packetUDP.m_sService, SERVICE_NAME);
|
|
udpLocal.beginPacket((IPAddress)0xFFFFFFFF, (uint16_t)UDP_PORT);
|
|
udpLocal.write((uint8_t*)&packetUDP, sizeof(UDP_PACKET));
|
|
udpLocal.endPacket();
|
|
}
|
|
m_nLastUDPBroadcastTime = clock;
|
|
}
|
|
}
|
|
|
|
MY_IRAM_ATTR void CWiFiHost::MonitorUDP() {
|
|
// Listen for UDP External port
|
|
IPAddress ip;
|
|
int size = udpExternal.parsePacket();
|
|
if (size >= sizeof(packetUDP)) {
|
|
if ((udpExternal.read((char *) &packetUDP, sizeof(packetUDP)) == sizeof(packetUDP)) &&
|
|
packetUDP.sig1 == SIGNATURE1 &&
|
|
packetUDP.sig2 == SIGNATURE2 &&
|
|
packetUDP.m_nChipID == config.m_nChipId) {
|
|
|
|
switch (packetUDP.m_nMessage) {
|
|
case MESSAGE_IP: // Extenal IP and Port set
|
|
// if (packetUDP.m_nChipID == config.m_nChipId) {
|
|
// m_dwPublicIP = packetUDP.dwIPAddress;
|
|
// m_nPublicPort = packetUDP.m_nPort;
|
|
// ip = IPAddress(m_dwPublicIP);
|
|
// ESP_LOGI(TAG_WIFI_HOST,"External IP(%s) and Port(%d)\n", ip.toString().c_str(), m_nPublicPort);
|
|
// } else {
|
|
// ESP_LOGI(TAG_WIFI_HOST,"External Server Response for other device Received\n");
|
|
// }
|
|
break;
|
|
case MESSAGE_CONFIG_SEND:
|
|
if (size == sizeof(UDP_PACKET) + sizeof(CONFIG_STRUCT)) {
|
|
if (udpExternal.read((char*) &configCopy, sizeof(configCopy))) {
|
|
ESP_LOGI(TAG_WIFI_HOST,"CONFIG received from the external DB server\n");
|
|
}
|
|
} else {
|
|
char *buffer[256];
|
|
while((size = udpExternal.parsePacket()) > 0) {
|
|
// Discard any leftover data
|
|
udpExternal.read((char*) &buffer, sizeof(buffer));
|
|
}
|
|
}
|
|
break;
|
|
case MESSAGE_QUERY_IP:
|
|
// if (m_nMode == MODE_WAITING) {
|
|
// // Get sender's IP and port
|
|
// externalServerIP = udpExternal.remoteIP();
|
|
// uint16_t senderPort = udpExternal.remotePort();
|
|
// ESP_LOGI(TAG_WIFI_HOST,"External Server - MESSAGE_QUERY_IP from %s:%d\n", externalServerIP.toString().c_str(), senderPort);
|
|
// m_nMode = MODE_EXTERNAL_SERVER;
|
|
// }
|
|
break;
|
|
case MESSAGE_RESET:
|
|
Restart();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
IRAM_ATTR void CWiFiHost::CheckClient(unsigned long clock)
|
|
{
|
|
bool bLED = false;
|
|
static TCP_PACKET cpkt;
|
|
int available = wifiClient.available();
|
|
if (available >= sizeof(TCP_PACKET)) {
|
|
uint8_t* pC = (uint8_t*)&cpkt;
|
|
int count = wifiClient.readBytes(pC, sizeof(TCP_PACKET));
|
|
if (count == sizeof(TCP_PACKET)) {
|
|
// Now we have a full packet size data
|
|
if (cpkt.sig1 == SIGNATURE1 &&
|
|
cpkt.sig2 == SIGNATURE2 &&
|
|
cpkt.len == sizeof(TCP_PACKET)) {
|
|
// Process the completed PACKET
|
|
ProcessPacket(cpkt);
|
|
m_nLastReceivedTime = clock;
|
|
return;
|
|
}
|
|
|
|
// Invalid Packet - remove the first byte off from the buff
|
|
ESP_LOGI(TAG_WIFI_HOST,"Invalid Packet %s%s size: %d/%d\n",
|
|
cpkt.sig1 == SIGNATURE1 ? "SIG1 OK" : "",
|
|
cpkt.sig2 == SIGNATURE2 ? "SIG2 OK" : "",
|
|
cpkt.len, sizeof(TCP_PACKET));
|
|
// Shift the buffer data off by 1 byte for the next cycle
|
|
//buffIndexC = sizeof(TCP_PACKET) - 1;
|
|
//memcpy(pC, &pC[1], buffIndexC);
|
|
while (m_bClientConnected &&
|
|
wifiClient.connected() &&
|
|
wifiClient.readBytes((uint8_t *) &cpkt, sizeof(cpkt)) > 0) {
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
IRAM_ATTR void CWiFiHost::ProcessPacket(TCP_PACKET& pkt)
|
|
{
|
|
switch (pkt.cmd)
|
|
{
|
|
// System
|
|
case CMD_HEARTBEAT:
|
|
m_nLastReceivedTime = millis();
|
|
//ESP_LOGI(TAG_WIFI_HOST,"H");
|
|
break;
|
|
case CMD_HELLO:
|
|
case CMD_HELLO_DEBUG:
|
|
{
|
|
// Send the Config Data to PC
|
|
// Send Packet Back
|
|
ESP_LOGI(TAG_WIFI_HOST,"WiFi - HELLO received");
|
|
pkt.u16[0] = SIGNATURE1;
|
|
pkt.n16[1] = sizeof(CONFIG_TYPE);
|
|
pkt.u16[2] = SIGNATURE2;
|
|
config.m_nChipId;
|
|
SendPacket(pkt);
|
|
|
|
// Send Data Packets
|
|
ESP_LOGI(TAG_WIFI_HOST,"WiFi - Config Send pending...");
|
|
int sent = SendData((uint8_t*)&config, sizeof(CONFIG_TYPE));
|
|
m_bHelloSent = true;
|
|
}
|
|
break;
|
|
case CMD_DROP_CONNECTION:
|
|
wifiClient.stop();
|
|
m_bClientConnected = false;
|
|
m_nMode = MODE_WAITING;
|
|
ESP_LOGI(TAG_WIFI_HOST,"WiFI - Client requets to DROP CONNECTION");
|
|
break;
|
|
case CMD_RESET_REASON:
|
|
pkt.n16[0] = esp_reset_reason();
|
|
SendPacket(pkt);
|
|
break;
|
|
case CMD_SAVE_RESTART:
|
|
if (pkt.u16[0] == SIGNATURE1 &&
|
|
pkt.u16[1] == SIGNATURE2) {
|
|
yield();
|
|
Restart();
|
|
}
|
|
break;
|
|
case CMD_RESET_RESTART:
|
|
if (pkt.u16[0] == SIGNATURE1 &&
|
|
pkt.u16[1] == SIGNATURE2) {
|
|
pkt.cmd = CMD_DROP_CONNECTION;
|
|
SendPacket(pkt);
|
|
yield();
|
|
Restart();
|
|
}
|
|
break;
|
|
case CMD_SEND_HISTORY:
|
|
if (pkt.u16[0] == SIGNATURE1 && pkt.u16[1] == SIGNATURE2) {
|
|
int16_t count = history.getRingCount();
|
|
if (count > 0 ) {
|
|
// inform client the count of history
|
|
pkt.op = count;
|
|
SendPacket(pkt);
|
|
int16_t size = history.getRingSize();
|
|
if (count < size) {
|
|
ESP_LOGI(TAG_WIFI_HOST,"WfFi Host - SendData - Whold part of History (%d)\n", count);
|
|
SendData(history.getRingData1()/* &ring[tail] */, sizeof(STATUS_TYPE) * count);
|
|
} else {
|
|
int count1st = size - history.getRingTail();
|
|
ESP_LOGI(TAG_WIFI_HOST,"WfFi Host - SendData - 1st part of History Total(%d), 1st(%d) H(%d) T(%d)\n",
|
|
count, count1st, history.getRingHead(), history.getRingTail());
|
|
SendData(history.getRingData1(), sizeof(STATUS_TYPE) * count1st),
|
|
// Mark pending to send the second part: from the start to head-1
|
|
//SendData(history.getRingData2() /* &ring[0] */, sizeof(STATUS_TYPE) * head);
|
|
m_bSendHistoryPending = true;
|
|
m_nPendingHistoryCount = history.getRingHead();
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case CMD_PAUSE:
|
|
break;
|
|
case CMD_RESUME:
|
|
break;
|
|
case CMD_RESET_SENSOR:
|
|
aht25.setScanFlag(true);
|
|
aht10_0x39.setScanFlag(true);
|
|
break;
|
|
|
|
// Config
|
|
case CMD_INIT_CONFIG:
|
|
if (pkt.u16[0] == SIGNATURE1 &&
|
|
pkt.u16[1] == sizeof(CONFIG_STRUCT) &&
|
|
pkt.u16[2] == SIGNATURE2) {
|
|
config.init();
|
|
config.save();
|
|
}
|
|
break;
|
|
case CMD_LOAD_CONFIG:
|
|
if (pkt.u16[0] == SIGNATURE1 &&
|
|
pkt.u16[1] == sizeof(CONFIG_STRUCT) &&
|
|
pkt.u16[2] == SIGNATURE2) {
|
|
config.load();
|
|
history.loadPID();
|
|
}
|
|
break;
|
|
case CMD_SAVE_CONFIG:
|
|
if (pkt.u16[0] == SIGNATURE1 &&
|
|
pkt.u16[1] == sizeof(CONFIG_STRUCT) &&
|
|
pkt.u16[2] == SIGNATURE2) {
|
|
config.save();
|
|
}
|
|
break;
|
|
case CMD_RECV_CONFIG:
|
|
// Receive Confif Data from PC
|
|
if (pkt.u16[0] == SIGNATURE1 &&
|
|
pkt.u16[1] == sizeof(CONFIG_STRUCT) &&
|
|
pkt.u16[2] == SIGNATURE2) {
|
|
ReceiveData((uint8_t *)&configCopy, sizeof(CONFIG_TYPE));
|
|
m_bReceiveConfigPending = true;
|
|
ESP_LOGI(TAG_WIFI_HOST,"WiFi - Receive Config initiated...");
|
|
}
|
|
break;
|
|
case CMD_SEND_CONFIG:
|
|
if (pkt.u16[0] == SIGNATURE1 &&
|
|
pkt.u16[1] == sizeof(CONFIG_STRUCT) &&
|
|
pkt.u16[2] == SIGNATURE2) {
|
|
SendPacket(pkt);
|
|
SendData((const uint8_t *)&config, (unsigned int) sizeof(config));
|
|
ESP_LOGI(TAG_WIFI_HOST,"WiFi - Send Config initiated...");
|
|
}
|
|
break;
|
|
case CMD_SEND_CONFIG_SERVER:
|
|
|
|
case CMD_LOAD_CONFIG_SERVER:
|
|
break;
|
|
|
|
// PID
|
|
case CMD_INIT_PID_PARAM:
|
|
history.savePID();
|
|
break;
|
|
case CMD_LOAD_PID_PARAM:
|
|
history.loadPID();
|
|
break;
|
|
case CMD_SAVE_PID_PARAM:
|
|
history.savePID();
|
|
break;
|
|
case CMD_SET_PID:
|
|
config.Kp_Temp1 = pkt.f[0];
|
|
config.Kd_Temp1 = pkt.f[1];
|
|
config.LR_Temp1 = pkt.f[2];
|
|
config.Kp_Humidity = pkt.f[3];
|
|
config.Kd_Humidity = pkt.f[4];
|
|
config.LR_Humidity = pkt.f[5];
|
|
history.loadPID();
|
|
break;
|
|
case CMD_GET_PID:
|
|
pkt.f[0] = config.Kp_Temp1;
|
|
pkt.f[1] = config.Kd_Temp1;
|
|
pkt.f[2] = config.LR_Temp1;
|
|
pkt.f[3] = config.Kp_Humidity;
|
|
pkt.f[4] = config.Kd_Humidity;
|
|
pkt.f[5] = config.LR_Humidity;
|
|
SendPacket(pkt);
|
|
break;
|
|
|
|
// Control
|
|
case CMD_SET_CONTROL:
|
|
config.bSmartControl = pkt.by[0] ? true : false;
|
|
config.bNightControl = pkt.by[1] ? true : false;
|
|
config.bControlTemperature = pkt.by[2] ? true : false;
|
|
config.bControlHumidity = pkt.by[3] ? true : false;
|
|
break;
|
|
case CMD_GET_CONTROL:
|
|
pkt.by[0] = config.bSmartControl ? 0xFF : 0;
|
|
pkt.by[1] = config.bNightControl ? 0xFF : 0;
|
|
pkt.by[2] = config.bControlTemperature ? 0xFF : 0;
|
|
pkt.by[3] = config.bControlHumidity ? 0xFF : 0;
|
|
SendPacket(pkt);
|
|
break;
|
|
|
|
// Operation
|
|
case CMD_SET_TEMP_TARGET:
|
|
config.nTempTarget = pkt.u16[0];
|
|
ESP_LOGI(TAG_WIFI_HOST,"WiFi - TempTarget changed to: %d\n", pkt.u16[0]);
|
|
break;
|
|
case CMD_SET_TEMP_TARGET_NIGHT:
|
|
config.nTempTargetNight = pkt.u16[0];
|
|
ESP_LOGI(TAG_WIFI_HOST,"WiFi - TempTargetNight changed to: %d\n", pkt.u16[0]);
|
|
break;
|
|
case CMD_SET_HUMID_TARGET:
|
|
config.nHumidTarget = pkt.u16[0];
|
|
ESP_LOGI(TAG_WIFI_HOST,"WiFi - HumidTarget changed to: %d\n", pkt.u16[0]);
|
|
break;
|
|
case CMD_SET_SENSOR_OFFSET:
|
|
config.nTemp1Offset = pkt.n16[0];
|
|
config.nHumid1Offset = pkt.n16[1];
|
|
if (pkt.n16[2] > 1) {
|
|
config.nTemp2Offset = pkt.n16[2];
|
|
config.nHumid2Offset = pkt.n16[3];
|
|
if (pkt.n16[2] > 2)
|
|
config.nTemp3Offset = pkt.n16[4];
|
|
}
|
|
ESP_LOGI(TAG_WIFI_HOST,"WiFi - SensorOffset changed to: %d, %d\n", pkt.n16[0], pkt.n16[1]);
|
|
break;
|
|
|
|
case CMD_SET_AC1_PARAM:
|
|
config.ac1 = pkt.device;
|
|
break;
|
|
case CMD_SET_AC2_PARAM:
|
|
config.ac2 = pkt.device;
|
|
break;
|
|
case CMD_SET_MIST_PARAM:
|
|
config.mist = pkt.device;
|
|
break;
|
|
case CMD_SET_FAN_PARAM:
|
|
config.fan = pkt.device;
|
|
break;
|
|
case CMD_SET_MOTOR_PARAM:
|
|
config.motor = pkt.device;
|
|
break;
|
|
case CMD_SET_LIGHT_PARAM:
|
|
config.light = pkt.device;
|
|
break;
|
|
|
|
// Status
|
|
case CMD_SET_HEATER1_DUTY:
|
|
status.nHeater1Duty = pkt.u16[0];
|
|
if (pkt.u16[1])
|
|
status.nFlags |= FLAG_MANUAL_HEATER1;
|
|
else
|
|
status.nFlags &= ~FLAG_MANUAL_HEATER1;
|
|
if (status.nHeater1Duty == 0) {
|
|
setHeater1Duty(0);
|
|
}
|
|
break;
|
|
case CMD_SET_HEATER2_DUTY:
|
|
status.nHeater2Duty = pkt.u16[0];
|
|
if (pkt.u16[1])
|
|
status.nFlags |= FLAG_MANUAL_HEATER2;
|
|
else
|
|
status.nFlags &= ~FLAG_MANUAL_HEATER2;
|
|
if (status.nHeater2Duty == 0) {
|
|
setHeater2Duty(0);
|
|
}
|
|
break;
|
|
case CMD_SET_MIST_DUTY:
|
|
status.nMistDuty = pkt.u16[0];
|
|
if (pkt.u16[1])
|
|
status.nFlags |= FLAG_MANUAL_MIST;
|
|
else
|
|
status.nFlags &= ~FLAG_MANUAL_MIST;
|
|
break;
|
|
case CMD_SET_FAN_DUTY:
|
|
status.nFanDuty = pkt.u16[0];
|
|
if (pkt.u16[1])
|
|
status.nFlags |= FLAG_MANUAL_FAN;
|
|
else
|
|
status.nFlags &= ~FLAG_MANUAL_FAN;
|
|
|
|
break;
|
|
case CMD_SET_MOTOR_DUTY:
|
|
status.nMotorDuty = pkt.u16[0];
|
|
if (pkt.u16[1])
|
|
status.nFlags |= FLAG_MANUAL_MOTOR;
|
|
else
|
|
status.nFlags &= ~FLAG_MANUAL_MOTOR;
|
|
break;
|
|
case CMD_SET_LIGHT_DUTY:
|
|
status.nLightTargetDuty = pkt.u16[0];
|
|
if (pkt.u16[1])
|
|
status.nFlags |= FLAG_MANUAL_LIGHT;
|
|
else
|
|
status.nFlags &= ~FLAG_MANUAL_LIGHT;
|
|
break;
|
|
|
|
// Manual Operation
|
|
case CMD_SET_MANUAL_HEATER1:
|
|
if (pkt.u16[0])
|
|
status.nFlags |= FLAG_MANUAL_HEATER1;
|
|
else
|
|
status.nFlags &= ~FLAG_MANUAL_HEATER1;
|
|
break;
|
|
case CMD_SET_MANUAL_HEATER2:
|
|
if (pkt.u16[0])
|
|
status.nFlags |= FLAG_MANUAL_HEATER2;
|
|
else
|
|
status.nFlags &= ~FLAG_MANUAL_HEATER2;
|
|
break;
|
|
case CMD_SET_MANUAL_MIST:
|
|
if (pkt.u16[0])
|
|
status.nFlags |= FLAG_MANUAL_MIST;
|
|
else
|
|
status.nFlags &= ~FLAG_MANUAL_MIST;
|
|
break;
|
|
case CMD_SET_MANUAL_FAN:
|
|
if (pkt.u16[0])
|
|
status.nFlags |= FLAG_MANUAL_FAN;
|
|
else
|
|
status.nFlags &= ~FLAG_MANUAL_FAN;
|
|
break;
|
|
case CMD_SET_MANUAL_LIGHT:
|
|
if (pkt.u16[0])
|
|
status.nFlags |= FLAG_MANUAL_LIGHT;
|
|
else
|
|
status.nFlags &= ~FLAG_MANUAL_LIGHT;
|
|
break;
|
|
|
|
// Time
|
|
case CMD_SET_TIME_NIGHT:
|
|
config.nNightStartHour = pkt.u16[0];
|
|
config.nNightStartMin = pkt.u16[1];
|
|
config.nNightEndHour = pkt.u16[2];
|
|
config.nNightEndMin = pkt.u16[3];
|
|
break;
|
|
case CMD_SET_WIFI_CLIENT_DISPLAY:
|
|
config.m_nDisplayTempHigh = pkt.n16[0];
|
|
config.m_nDisplayTempLow = pkt.n16[1];
|
|
config.m_nDisplayTime = pkt.n16[2];
|
|
config.m_fShowRealTime = pkt.n16[3];
|
|
config.m_fShowHistory = pkt.n16[4];
|
|
ESP_LOGI(TAG_WIFI_HOST,"WiFi - Client Display Settings changed.");
|
|
break;
|
|
|
|
default:
|
|
ESP_LOGI(TAG_WIFI_HOST,"WiFi - Packet Received Type: %d\n", pkt.cmd);
|
|
break;
|
|
}
|
|
}
|
|
|
|
IRAM_ATTR int CWiFiHost::SendPacket(TCP_PACKET& pkt)
|
|
{
|
|
size_t sent = 0;
|
|
if (m_bClientConnected && wifiClient && wifiClient.connected())
|
|
{
|
|
sent = wifiClient.write((char*)&pkt, sizeof(TCP_PACKET));
|
|
}
|
|
return sent;
|
|
}
|
|
|
|
IRAM_ATTR size_t CWiFiHost::SendData(const uint8_t* data, size_t size) {
|
|
if (data != nullptr) {
|
|
m_nMode = MODE_SEND;
|
|
m_pDataSend_data = (char *) data;
|
|
m_nDataSend_size = size;
|
|
m_nDataSend_sent = 0;
|
|
ESP_LOGI(TAG_WIFI_HOST,"WfFi Host - SendData(size: %d)\n", size);
|
|
return size;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
IRAM_ATTR bool CWiFiHost::SendData(unsigned long clock)
|
|
{
|
|
if (m_nDataSend_sent < m_nDataSend_size)
|
|
{
|
|
bool connected = wifiClient.connected();
|
|
if (m_bClientConnected && wifiClient && connected) {
|
|
size_t count = m_nDataSend_size - m_nDataSend_sent;
|
|
if (count > TCP_PACKET_SIZE_MAX) count = TCP_PACKET_SIZE_MAX;
|
|
//size_t avail = wifiClient.availableForWrite();
|
|
//if (avail < count) {
|
|
// ESP_LOGI(TAG_WIFI_HOST,"WiFiHost - SendData() avail(%d) is less than count(%d)\n", avail, count);
|
|
// //count = avail;
|
|
//}
|
|
|
|
if (count > 0) {
|
|
int16_t sentCount = wifiClient.write(&m_pDataSend_data[m_nDataSend_sent], count);
|
|
if (sentCount != count) {
|
|
ESP_LOGI(TAG_WIFI_HOST,"WiFiHost - SendData() sent(%d) is not count(%d)\n", sentCount, count);
|
|
if (sentCount <= 0)
|
|
yield();
|
|
}
|
|
m_nDataSend_sent += sentCount;
|
|
ESP_LOGI(TAG_WIFI_HOST,"WiFiHost - SendData() size(%d) sent(%d) total_sent(%d)\n", m_nDataSend_size, count, m_nDataSend_sent);
|
|
}
|
|
//else {
|
|
// ESP_LOGI(TAG_WIFI_HOST,"WiFiHost - SendData() avail is 0");
|
|
// yield();
|
|
//}
|
|
} else {
|
|
m_nMode = MODE_WAITING;
|
|
m_pDataSend_data = nullptr;
|
|
m_nDataSend_size = 0;
|
|
m_nDataSend_sent = 0;
|
|
ESP_LOGI(TAG_WIFI_HOST," SendData: Connection lost - reset sendData()!");
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (m_nDataSend_sent == m_nDataSend_size) {
|
|
ESP_LOGI(TAG_WIFI_HOST, " SendDdata: DataSend completed!");
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
IRAM_ATTR size_t CWiFiHost::ReceiveData(uint8_t* data, size_t size)
|
|
{
|
|
m_nMode = MODE_RECV;
|
|
m_pDataReceive_data = (char *) data;
|
|
m_nDataReceive_size = size;
|
|
m_nDataReceive_received = 0;
|
|
#ifdef ESP8266
|
|
digitalWrite(PIN_EXTRA, LED_ON);
|
|
#endif
|
|
return size;
|
|
}
|
|
|
|
IRAM_ATTR bool CWiFiHost::ReceiveData(unsigned long clock)
|
|
{
|
|
// Receive Data
|
|
size_t nSize = 0;
|
|
if (m_nDataReceive_received < m_nDataReceive_size)
|
|
{
|
|
if (m_bClientConnected && wifiClient && wifiClient.connected()) {
|
|
int16_t count = m_nDataReceive_size - m_nDataReceive_received;
|
|
if (count > TCP_PACKET_SIZE_MAX) count = TCP_PACKET_SIZE_MAX;
|
|
nSize = wifiClient.readBytes(&m_pDataReceive_data[m_nDataReceive_received], count);
|
|
if (nSize > 0) {
|
|
m_nLastReceivedTime = clock;
|
|
m_nDataReceive_received += nSize;
|
|
}
|
|
} else {
|
|
m_nMode = MODE_WAITING;
|
|
m_pDataReceive_data = nullptr;
|
|
m_nDataReceive_size = 0;
|
|
m_nDataReceive_received = 0;
|
|
ESP_LOGI(TAG_WIFI_HOST," SendData: Connection lost - reset receiveData()!");
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// Check for any pending action
|
|
if (m_nDataReceive_received == m_nDataReceive_size) {
|
|
if (m_bReceiveConfigPending && m_pDataReceive_data == (char *)&configCopy) {
|
|
config = configCopy;
|
|
history.loadPID();
|
|
ESP_LOGI(TAG_WIFI_HOST,"WiFi - Config Received");
|
|
m_bReceiveConfigPending = false;
|
|
}
|
|
ESP_LOGI(TAG_WIFI_HOST," ReceiveData: Data Receive Completed!");
|
|
return true;
|
|
}
|
|
|
|
if (nSize <= 0 && clock - m_nLastReceivedTime > 5000) {
|
|
ESP_LOGI(TAG_WIFI_HOST," ReceiveData: TimeOut Abort!");
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
IRAM_ATTR void CWiFiHost::SendHeartBeat() {
|
|
if (m_bHelloSent) {
|
|
hostPacket.cmd = CMD_HEARTBEAT;
|
|
time_t now = time(NULL); // Get current time in seconds
|
|
status.now = (uint32_t) time(NULL);
|
|
//status.uptime = now - timeManager.getFirstNTPTime();
|
|
hostPacket.status = status;
|
|
SendPacket(hostPacket);
|
|
}
|
|
}
|
|
|
|
MY_IRAM_ATTR void CWiFiHost::Restart() {
|
|
if (isWiFiConnected()) {
|
|
if (m_bClientConnected && m_bClientConnected && wifiClient && wifiClient.connected()) {
|
|
hostPacket.cmd = CMD_DROP_CONNECTION;
|
|
SendPacket(hostPacket);
|
|
}
|
|
}
|
|
vTaskDelay(500/portTICK_PERIOD_MS);
|
|
|
|
// stop all network sockets
|
|
Stop(); // Stop Sockets
|
|
|
|
vTaskDelay(50/portTICK_PERIOD_MS);
|
|
|
|
// Turn Off
|
|
setHeater1Duty(0);
|
|
setHeater2Duty(0);
|
|
ledcWrite(PIN_MIST, 0);
|
|
ledcWrite(PIN_FAN, 0);
|
|
ledcWrite(PIN_MOTOR, 0);
|
|
ledcWrite(PIN_LIGHT, 0);
|
|
vTaskDelay(50/portTICK_PERIOD_MS);
|
|
config.statusSave = status;
|
|
config.save();
|
|
vTaskDelay(50/portTICK_PERIOD_MS);
|
|
ESP.restart();
|
|
}
|