// http://www.cloud.bemfa.com/docs/#/
#include <WiFi.h>
#include "DHTesp.h"
#define TCP_SERVER_ADDR "bemfa.com"
#define TCP_SERVER_PORT "8344"

#define DEFAULT_STASSID  "Wokwi-GUEST"
#define DEFAULT_STAPSW ""
String UID = "0888ec5530775fccd4663bf493634ec4";
String TOPIC = "SmartHome"; 
String TOPIC2  = "light002"; 
int DHT_PIN = 40;  
int LIGHT_PIN = 17;
int PIR_PIN = 38;
 
#define upDataTime 2*1000
#define MAX_PACKETSIZE 512

DHTesp dhtSensor;
WiFiClient TCPclient;

String TcpClient_Buff = "";
unsigned int TcpClient_BuffIndex = 0;
unsigned long TcpClient_preTick = 0;
unsigned long preHeartTick = 0;
unsigned long preTCPStartTick = 0;
bool preTCPConnected = false;
String my_led_status = "off";

void doWiFiTick();
void startSTA();
void doTCPClientTick();
void startTCPClient();
void sendtoTCPServer(String p);

void sendtoTCPServer(String p){
  
  if (!TCPclient.connected()) 
  {
    Serial.println("Client is not readly");
    return;
  }
  TCPclient.print(p);
  Serial.println("[Send to TCPServer]:String");
  Serial.println(p);
}

//connect to server
void startTCPClient(){
  if(TCPclient.connect(TCP_SERVER_ADDR, atoi(TCP_SERVER_PORT))){
    Serial.print("\nConnected to server:");
    Serial.printf("%s:%d\r\n",TCP_SERVER_ADDR,atoi(TCP_SERVER_PORT));
    String tcpTemp="";
    tcpTemp = "cmd=1&uid="+UID+"&topic="+TOPIC2+"\r\n";

    sendtoTCPServer(tcpTemp);
    preTCPConnected = true;
    preHeartTick = millis();
    TCPclient.setNoDelay(true);
  }
  else{
    Serial.print("Failed connected to server:");
    Serial.println(TCP_SERVER_ADDR);
    TCPclient.stop();
    preTCPConnected = false;
  }
  preTCPStartTick = millis();
}

void doTCPClientTick(){
   if(WiFi.status() != WL_CONNECTED) return;

  if (!TCPclient.connected()) {//dis connect

  if(preTCPConnected == true){

    preTCPConnected = false;
    preTCPStartTick = millis();
    Serial.println();
    Serial.println("TCP Client disconnected.");
    TCPclient.stop();
  }
  else if(millis() - preTCPStartTick > 1*1000)// reconnect
    startTCPClient();
  }
  else
  {
    if (TCPclient.available()) {//receive data
      char c =TCPclient.read();
      TcpClient_Buff +=c;
      TcpClient_BuffIndex++;
      TcpClient_preTick = millis();
      
      if(TcpClient_BuffIndex>=MAX_PACKETSIZE - 1){
        TcpClient_BuffIndex = MAX_PACKETSIZE-2;
        TcpClient_preTick = TcpClient_preTick - 200;
      }
      preHeartTick = millis();
    }
    if(millis() - preHeartTick >= upDataTime){//upload data
      preHeartTick = millis();
      String upstr = "";
      String msg = collectData();
      upstr = "cmd=2&uid="+UID+"&topic="+TOPIC+"&msg=#"+msg+"#\r\n";
      Serial.println(msg);
      Serial.println("---");
      sendtoTCPServer(upstr);
      upstr = "";
    }
  }
  if((TcpClient_Buff.length() >= 1) && (millis() - TcpClient_preTick>=200))
  {//data ready
    TCPclient.flush();
    Serial.println("Buff");
    Serial.println(TcpClient_Buff);
   TcpClient_Buff="";
   TcpClient_BuffIndex = 0;
  }
}

void startSTA(){
  WiFi.disconnect();
  WiFi.mode(WIFI_STA);
  WiFi.begin(DEFAULT_STASSID, DEFAULT_STAPSW);
}

String collectData(){
  TempAndHumidity  data = dhtSensor.getTempAndHumidity();
  int LDRValue = analogRead(LIGHT_PIN); 
  return String(data.temperature, 2) + "#" + String(data.humidity, 1) + "#" + String(LDRValue) + "#" + digitalRead(PIR_PIN);
}

/**************************************************************************
                                 WIFI
***************************************************************************/
void doWiFiTick(){
  static bool startSTAFlag = false;
  static bool taskStarted = false;
  static uint32_t lastWiFiCheckTick = 0;

  if (!startSTAFlag) {
    startSTAFlag = true;
    startSTA();
    Serial.printf("Heap size:%d\r\n", ESP.getFreeHeap());
  }

  // reconnect
  if ( WiFi.status() != WL_CONNECTED ) {
    if (millis() - lastWiFiCheckTick > 1000) {
      lastWiFiCheckTick = millis();
    }
  }
  // connect success
  else {
    if (taskStarted == false) {
      taskStarted = true;
      Serial.print("\r\nGet IP Address: ");
      Serial.println(WiFi.localIP());
      startTCPClient();
    }
  }
}

void setup() {
  Serial.begin(115200);
  dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
}

void loop() {
  doWiFiTick();
  doTCPClientTick();
  delay(500); 
}
$abcdeabcde151015202530354045505560fghijfghij