#include "QueueLib.h"
#include "Wifi_ADI.h"
#include "FS.h"
#include "SD.h"

int wifinum = 0;
int lastwifinum = 10;
int wifi_counter = 0;
int wifiRSSI = -40;
String Str;
String wifistr;
int scanrequest = 0;


const char *WiFiErr[] = {"WL_IDLE_STATUS", "WL_NO_SSID_AVAIL", "WL_SCAN_COMPLETED", "WL_CONNECTED", "WL_CONNECT_FAILED", "WL_CONNECTION_LOST", "WL_DISCONNECTED"};

WiFiClient client;
IPAddress ipp;

#define WIFIRESPONSELIMIT 600

// AT100 Upload

// const char* host = "at.automationtec.net";
const char *host = "automationtec.net";
const char *ftphost = "appdig.com";
// const char* faulthost = "appdig.com";
const char *faulthost = "faults.appdig.com";
const int httpPort = 80;

int ssidCount = 0;
char cstr[1500];
int replyindx = 0;
int getHttpsBin = 0;
int uploadparmftpbin = 0;
int uploadlogftpbin = 0;
int uploadParmHttpsBin = 3;
int uploadRemoteParmHttps = 0;
char tmpstrW[80];

String WiFiStr;
int wifiForward = 0;

// file
File file;
File file2 = SD.open("/PARMS.ADI");

//*******************************************************
//
//*******************************************************

void UpdateLogFTP(void)
{
  uploadlogftpbin = 1;
}

void UpdateParmHTTPs(void)
{
  uploadParmHttpsBin = 1;
}

void UpdateRemoteParmFTP(void)
{
  char tempbuff[128];
  String Str;

  Str = String(remoteParmFetchSerial) + String(".PRM");
  Str.toCharArray(tempbuff, 127);

  // SD_RemoteParmWrite(tempbuff);
  //SD_RemoteParmWrite("/TEMP.PRM");
  uploadRemoteParmHttps = 1;
}

//*******************************************************
//
//*******************************************************

void UpdateParmFTP(void)
{
  uploadparmftpbin = 1;
}

//*******************************************************
//
//*******************************************************

int32_t getWifiRSSI(void)
{
  // return(-87);
  return (wifiRSSI);
}

//*******************************************************
//
//*******************************************************

void beginOTA(void)
{
  displayText("OTA Update Begin");
  // kickDog();
  getHttpsBin = 1;
  delay(2000);
}

//*******************************************************
//
//*******************************************************

void requestScan(void)
{
  scanrequest = 1;
}

//*******************************************************
//
//*******************************************************

void initWiFi(void)
{
  // Serial.println("Reading WiFi Credentials");
  // SD_FileRead(reinterpret_cast<uint8_t*>(ssid), "/SS.ADI", sizeof(ssid)); //Read OK
  // SD_FileRead(reinterpret_cast<uint8_t*>(pass), "/PA.ADI", sizeof(pass)); //Read OK
  Serial.println("WiFi Config");
}

//*******************************************************
//
//*******************************************************

uint16_t numberNetworks(void)
{
  return (ssidCount);
}

//*******************************************************
//
//*******************************************************

void wifiService(void)
{
  int i;
  uint32_t ep;
  char tmpstr[64];
  byte tmpbyte[10];

  if (lastwifinum != wifinum)
  {
    Serial.print("Wifi Case: ");
    Serial.println(wifinum);
    lastwifinum = wifinum;
  }

  // if(scanrequest == 1) wifinum = 0;
  WiFiStr = String(ssid);
  if (WiFiStr.length() == 0)
    ssid[0] = 'S';

  if (Timers[WIFITIMEOUT] > 1200) //
  {
    wifinum = 999;
    //    qualifyFault(5);
  }

  /* //fixed SS PA on Renlita
    if (scanrequest != 0)
    {
      wifinum = 30;
      scanrequest = 0;
      //if (VB)
      Serial.println("~ScanRequest WiFi");
      //kickDog();
    }
  */

  /*
    if (VB)
      if (onesecondflag)
      {
        Serial.print("\nWIFI SWITCH: ");
        Serial.print(String(wifinum));
        Serial.print(" / ");
        Serial.print(String(Timers[WIFIRESPONSETIMER]));
        Serial.print(" / ");
        Serial.println(String(replyindx));
      }
  */

  switch (wifinum)
  {
  case 0: // idle
    //      digitalWrite(LED3, LOW);
    Timers[WIFITIMEOUT] = 1; //  start/reset it

    if (getHttpsBin == 1)
    {
      wifinum = 1;
      wifiForward = 70;
      getHttpsBin = 0;
      Serial.println("~Get Https Bin");
      displayText("Downloading Bin....");
      // kickDog();
      break;
    }

    if (uploadParmHttpsBin > 0)
    {
      wifinum = 1;
      wifiForward = 72;
      Serial.println("~Upload parms");

      displayText("Uploading Parms...");
      // kickDog();
      break;
    }

    if (uploadRemoteParmHttps > 0)
    {
      wifinum = 1;
      wifiForward = 73;
      Serial.println("~Upload remote parms");

      displayText("Uploading Remote Parms");
      break;
    }

    if (atQ_size() != 0)
    {
      wifinum = 1;
      wifiForward = 20;
      Serial.println("~AT200Upload");
      break;
    }

    if (faultQ_size() != 0)
    {
      wifinum = 1;
      wifiForward = 19;
      Serial.println("~Fault Upload");
      break;
    }
    break;

  case 1: // Wifi Setup
    if (WiFi.status() == WL_CONNECTED)
    {
      Serial.println("WiFi Still connected");
      wifiRSSI = WiFi.RSSI();
      wifinum = wifiForward;
    }
    else // not connected
    {
      // We start by connecting to a WiFi network
      Serial.printf("Connecting to %s, %s\n", ssid, pass);
      WiFi.mode(WIFI_STA);
      delay(500);
      WiFi.begin(ssid, pass);
      wifi_counter = 0;
      wifinum++;
    }
    break;

  case 2:
    if (WiFi.status() != WL_CONNECTED)
    {
      if (++wifi_counter > 200)
      {
        // delay(10);
        sprintf(tmpstr, "WiFi ERR: %s\n", WiFiErr[WiFi.status()]);
        Serial.print(tmpstr);
        displayText(tmpstr);
        WiFi.disconnect();
        delay(500);
        WiFi.begin(ssid, pass);
        delay(500);
        wifinum = 0;
      }
    }
    else
    {
      // wifinum++;
      Serial.println("WiFi connected");
      displayText("WiFi connected");

      ipp = WiFi.localIP();
      sprintf(tmpstr, "IP:  %d.%d.%d.%d", ipp[0], ipp[1], ipp[2], ipp[3]);
      Serial.println(tmpstr);

      WiFi.macAddress(tmpbyte);
      sprintf(tmpstr, "MAC: %02X:%02X:%02X:%02X:%0X:%02X", tmpbyte[5], tmpbyte[4], tmpbyte[3], tmpbyte[2], tmpbyte[1], tmpbyte[0]);
      Serial.println(tmpstr);

      wifiRSSI = WiFi.RSSI();
      wifinum = wifiForward;
    }
    break;

  case 30: // Set WiFi to station mode and disconnect from an AP if it was previously connected

    // displayTextAttributes(0, 4, 0, 1, 1, tCADETBLUE, tBLACK);

    ipp = WiFi.localIP();
    sprintf(tmpstr, "IP:  %d.%d.%d.%d", ipp[0], ipp[1], ipp[2], ipp[3]);
    // displayText(510, 300, String(tmpstr));

    WiFi.macAddress(tmpbyte);
    sprintf(tmpstr, "MAC: %02X:%02X:%02X:%02X:%0X:%02X", tmpbyte[5], tmpbyte[4], tmpbyte[3], tmpbyte[2], tmpbyte[1], tmpbyte[0]);
    //      displayText(510, 325, String(tmpstr));

    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
    delay(100);
    Serial.println("Wifi Setup done");
    wifinum++;
    break;

  case 31: // Scan
    Serial.println("AP scan start");

    //     displayTextAttributes(1, 4, 0, 2, 2, tGRAY, tAQUA);
    //     displayText(145, 220, "Scanning");
    // WiFi.scanNetworks will return the number of networks found

    // kickDog();
    ssidCount = WiFi.scanNetworks();
    // kickDog();

    wifinum++;

    //     displayText(145, 220, "        ");
    Serial.println("AP scan done");

    if (ssidCount == 0)
    {
      Serial.println("no networks found");
    }
    else
    {
      Serial.print(ssidCount);
      Serial.println(" networks found");
      Serial.println(" ");
      if (ssidCount > 6)
        ssidCount = 6; // only show the strongest 6

      // scanrequest = n;

      for (i = 0; i < ssidCount; ++i)
      {
        // Print SSID and RSSI for each network found
        WiFiStr = String(i);
        WiFiStr += ": ";
        WiFiStr += String(WiFi.SSID(i));
        WiFiStr += " (";
        WiFiStr += String(WiFi.RSSI(i));
        WiFiStr += ")";
        if (WiFi.encryptionType(i) == WIFI_AUTH_OPEN)
          WiFiStr += " $";
        WiFiStr += '\n';
        Serial.println(WiFiStr);

        //          displayTextAttributes(0, 4, 0, 1, 1, tCADETBLUE, tBLACK);
        //          displayText(110, (i * 50) + 100, WiFiStr);
      }

      //       displayTextAttributes(0, 4, 0, 1, 1, tCADETBLUE, tBLACK);
      //        displayText(528, 100, ssid);*
      //       displayText(528, 150, pass);
    }
    Serial.println("");
    // wifinum = 0;
    break;

  case 32: // wait here for display to update

    break;

  case 19:
    // digitalWrite(LED3, HIGH);
    wifiForward = 19;
    wifinum = 21;

    clearbuffer();
    Timers[WIFIRESPONSETIMER] = 0;
    faultQ_pull();
    sendFaultpacket();
    Serial.println();
    break;

  case 20:
    wifiForward = 20;

    // digitalWrite(LED3, HIGH);
    wifinum = 21;

    Timers[WIFIRESPONSETIMER] = 0;

    // v980
    // atQ_pull();
    // sendAT100packet();

    sendMultiDataString();

    break;

  case 21:

    VB = 1;
    Serial.println("Looking for cloud response..");

    while (client.available())
    {
      cstr[replyindx++] = client.read();
      // Serial.print(cstr[replyindx-1]);
      if (replyindx > 500)
        break;
    }

    Str = String(cstr);

    // Check for errors
    if (
        (Timers[WIFIRESPONSETIMER] > WIFIRESPONSELIMIT) ||
        (Str.indexOf("Too many connections") > 0))
    {
      if (VB)
        Serial.println('\n');
      if (VB)
        Serial.println(Str);
      if (VB)
        Serial.print(" ** ** ** ** ** Response Time: ");
      if (VB)
        Serial.println(String(Timers[WIFIRESPONSETIMER]));
      Timers[WIFIRESPONSETIMER] = -1;
      wifinum = 999;
    }

    // Check for good response
    if (
        (Str.indexOf("BOOGYDAT") > 0) ||
        (Str.indexOf("success") > 0))
    {
      wifinum = 22;
      displayText("Uploading Finished");
      if (VB)
        Serial.println('\n');
      if (VB)
        Serial.println(Str);
      if (VB)
        Serial.print(" ** ** **  ** ** Response Time: ");
      if (VB)
        Serial.println(String(Timers[WIFIRESPONSETIMER]));
      Timers[WIFIRESPONSETIMER] = -1;
    }

    if (Str.indexOf("gimmedaparms") > 0)
    {
      UpdateParmFTP();
    }

    if (Str.indexOf("gimmedalog") > 0)
    {
      UpdateLogFTP();
    }

    // Check for OTA
    if (Str.indexOf("gimmedatupdate") > 0)
    {
      beginOTA();
    }

    // Master Reset
    if (Str.indexOf("gimmeMasterReset") > 0)
    {
      displayText("Master Reset");
      tone(HEARTBEATLED, 100, 500); // set wdog timeout to 2 sec
      delay(5000);
      displayText("WDT FAILED!!!!");
      delay(2000);
      ESP.restart();
    }

    char *ptr;
    // Check for Time Update
    if (Str.indexOf("BOOGYTIME") > 0)
    {
      ptr = strstr(cstr, "BOOGYTIME");
      if (ptr)
      {
        // Move the pointer 9 positions forward to skip the "BOOGYTIME" prefix
        ptr += 9;

        // Convert the remaining characters to an unsigned long
        unsigned long tempEpoch = strtoul(ptr, NULL, 10);

        // Update the RTC with the new Unix timestamp (tempEpoch)
        setEpochRtc(tempEpoch);

        wifinum = 0;
      }
    }

    // Check for command    command4U+12345,2255,954123,22*****
    long cmndarray[6];
    for (i = 0; i < 6; i++)
      cmndarray[i] = 0;

    ptr = strstr(cstr, "command4U+");
    if (ptr)
    {
      for (i = 0; i < 10; i++)
        ptr++;

      if (VB)
      {
        Serial.print("Start Char");
        Serial.println(*ptr);
      }

      parse_commands(ptr, cmndarray);

      if (cmndarray[0] == 6)
      {
        if (cmndarray[1] < PARMSIZE)
        {
          parms.write(cmndarray[1], cmndarray[2]);
        }
      }

      /*
              if (cmndarray[0] == 7)
              {
                if(cmndarray[1] <= parm[21])
                {
                motorArray[ (cmndarray[1]) ][0] = cmndarray[2];
                Serial.println("Remote Command :");
                }
              }
      */

      //***command 6
      if (cmndarray[0] == 6)
      {
        if (cmndarray[1] < PARMSIZE)
        {
          if (cmndarray[1] != 64) // can't write serial remotely
          {
            parm[cmndarray[1]] = cmndarray[2];
            SD_ParmWrite(1);
          }
        }
      }

      //***command 116
      // command4U+116,sssssss,pp,dd*****
      // rf parm write
      if (cmndarray[0] == 116) // rf Parm write
      {
        extParmsWrite[0] = 116;
        extParmsWrite[1] = cmndarray[1]; // serial #
        extParmsWrite[2] = cmndarray[2]; // parm#
        extParmsWrite[3] = cmndarray[3]; // data
        cmndarray[0] = 0;
        Serial.printf("Sending %d to parm %d in %d", cmndarray[3], cmndarray[2], cmndarray[1]);
      }

      //***command 105
      if (cmndarray[0] == 105) // rf Parm fetch
      {
        remoteParmFetchSerial = cmndarray[1]; // serial #
        remoteParmNum = 0;
        parmRetryCounter = -1;
        remoteParmLast = -1;
        remoteParmCounter = -1;

        cmndarray[0] = 0;
        cmndarray[1] = 0;

        memset(remoteParm, 0, sizeof(remoteParm));
        Timers[PARMFETCHTIMER] = 1;

        sprintf(tmpstrW, "Begin Parm Fetch from %d", remoteParmFetchSerial);
        Serial.println(tmpstrW);
      }

      // extParmRFWrite(248, 5154155, 65000, 52);
      // extParmRFWrite(248, extParmsWrite[1], extParmsWrite[2], extParmsWrite[3]);


      if (VB)
        for (i = 0; i < 4; i++)
        {
          Serial.print(cmndarray[i]);
          Serial.println("---");
        }
      // process commands here
    }

    ptr = strstr(cstr, "gimmedaparms");
    if (ptr)
      UpdateParmHTTPs();

    if (replyindx > 500)
      wifinum = 999;

    VB = 0;
    break;

  case 22:

    wifinum = 0;
    clearbuffer();
    // digitalWrite(LED3, LOW);

    if (wifiForward == 20)
      if (atQ_size() != 0)                 // some more to send?
        if (WiFi.status() == WL_CONNECTED) // still connected?
        {
          wifinum = wifiForward;
          // if (VB)
          Serial.print("..more AT to send: ");
          Serial.println(atQ_size());
        }

    if (wifiForward == 19)
      if (faultQ_size() != 0)              // some more to send?
        if (WiFi.status() == WL_CONNECTED) // still connected?
        {
          wifinum = wifiForward;
          if (VB)
            Serial.println("..more FLT to send");
        }

    // if (VB)
    if (wifinum == 0)
    {
      displayText("Upload Finished");
      Serial.println("queue is empty");
    }

    break;

  case 70:
    // Go back to idle if an error occurs
    Serial.println("We made it to case 70");
    wifinum = 0;

    // Set up the file where the bin will be stored
    file = fileLibSD.open(UPDATE_BIN, FILE_WRITE);
    if (!file)
    {
      Serial.println("Failed to open file for update");
      break;
    }

    if (!https.connect(HTTPS_HOST))
    {
      Serial.printf("Could not connect to server: %s", HTTPS_HOST);
      break;
    }

    // optional callback to track download progress
    
    https.setProgressCallback(drawLoadingBar);
    

    // set the bin source and target destination
    https.setTarget(BIN_SOURCE, file);
    //https.setCustomHeader(AUTH_HEADER);
    delay(2000);

    // if we make it here go to the download state
    wifinum = 71;
    break;

  case 71:
    https.advanceStateMachine();
    delay(2000);
    Serial.println("MadeItToDownloadPhase");

    if (https.isErrorOccurred())
    {
      Serial.println("Error occurred during download.");
      wifinum = 0;
      break;
    }
    else if (https.isResponseComplete())
    {
      Serial.println("Download complete.");
      delay(2000);
      updateFromFS();
      wifinum = 0;
      break;
    }

    break;

  case 72:
    wifinum = 0;
    https.setCustomHeader(AUTH_HEADER);

    file2 = fileLibSD.open("/PARMS.ADI", FILE_READ);
    if (!file2)
    {
      Serial.println("Failed to open file");
      break;
    }

    if (!https.connect(HTTPS_HOST))
    {
      Serial.println("Could not connect to server.");
      break;
    }

    Str = String(parm[64]) + String(".PRM");
    Serial.println("Uploading");
    if (!https.uploadFile(UPLOAD_PARMS_DEST, file2, Str))
    {
      Serial.println("Could not upload parms.");
    }
    else
    {
      Serial.println(("PARM HTTPS OK............................................"));
      delay(100);
      displayText("...Parms Upload OK");
      uploadParmHttpsBin = 0;
    }
    uploadParmHttpsBin = 0;

    break;

  case 73:
    Str = "/httpdocs/aQParms/" + String(remoteParmFetchSerial) + String(".PRM");
    //Str.toCharArray(tempbuff, 127);

    char tempbuff1[128];
    Str = String(remoteParmFetchSerial) + String(".PRM");
    Str.toCharArray(tempbuff1, 127);

    // open temp file
    file2 = SD.open("/TEMP.PRM", FILE_READ);
    if (!file2)
    {
      Serial.println("Failed to open file");
      if (uploadParmHttpsBin > 0)
        uploadParmHttpsBin--; // try again
      break;
    }
    if (!https.connect(HTTPS_HOST))
    {
      Serial.println("Could not connect to server.");
      break;
    }

    Str = String(remoteParmFetchSerial) + String(".PRM");
    if (!https.uploadFile(UPLOAD_PARMS_DEST, file2, Str))
    {
      Serial.println("Could not upload parms.");
    }
    else
    {
      Serial.println(("PARM FTP OK"));
      delay(100);
      displayText("...Parms Upload OK");
      remoteParmFetchSerial = 0;
      uploadRemoteParmHttps = 1;
    }
    wifinum = 0;
    break;

  case 999: // timeout.. reset everything
    // digitalWrite(LED3, LOW);
    Timers[WIFITIMEOUT] = 0;
    clearbuffer();

    wifinum = 1000;
    client.stop();
    WiFi.disconnect();
    delay(600);
    break;

  case 1000:
    wifinum = 0;
    break;

  default:
    wifinum = 0; // just in case
    break;
  }
} // wifi service

//*******************************************************
//
//*******************************************************

void sendAT100packet(void)
{
  int j;
  int i;

  clearbuffer();

  if (VB)
    Serial.println();
  if (VB)
    Serial.println("sending AT100 packet");

  // connect

  if (!client.connect(host, httpPort))
  {
    Serial.println("Wifi connection failed");
    return;
  }

  // build it

  // String wifistr = String("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><AT100><ATID>");
  wifistr = String("<AT100><ATID>");

  wifistr += String(at_QTempData.serial);
  wifistr += String("</ATID><DATA>");

  wifistr += String((at_QTempData.data / 10)); // data sent in x.x format
  wifistr += String('.');
  wifistr += String((at_QTempData.data % 10));

  wifistr += String("</DATA><TYPE>");
  wifistr += String(at_QTempData.type);
  wifistr += String("</TYPE><STATE>");
  wifistr += String(at_QTempData.stat);
  wifistr += String("</STATE><VER>");
  wifistr += String(at_QTempData.ver);

  wifistr += String("</VER><RSSI>");

  wifistr += String(at_QTempData.rssi);

  wifistr += String("</RSSI><MAC>");

  if (VB)
    Serial.println(String(WiFi.macAddress()));

  Str = String(WiFi.macAddress());
  for (j = 0; j < 5; j++)
  {
    i = Str.indexOf(':');
    Str.remove(i, 1);
  }

  wifistr += Str;
  wifistr += String("</MAC>");

  wifistr += String("<CH>");
  wifistr += String(at_QTempData.chan);
  wifistr += String("</CH>");

  wifistr += String("<BATT>");
  wifistr += String(at_QTempData.batt);
  wifistr += String("</BATT>");

  wifistr += String("<ESTAMP>");
  wifistr += String(at_QTempData.etime);
  wifistr += "</ESTAMP><SYS>BOOGYDAT</SYS>";
  wifistr += "<TZ>";
  wifistr += String(parm[7]);
  wifistr += "</TZ></AT100>\r\n\r\n ";
  // Serial.println(String(wifistr));

  Serial.println(wifistr);

  // send it

  // client.print(String("POST / HTTP/1.1\r\nContent-Type: text/xml\r\nHost:at.automationtec.net\r\nContent-Length:"));
  client.print(String("POST /AutoTecSQL/ HTTP/1.1\r\nContent-Type: text/xml\r\nHost:automationtec.net\r\nContent-Length:"));
  i = wifistr.length();
  client.print(String(i));
  client.print(String("\r\nConnection: close\r\n\r\n"));
  client.print(wifistr);

  if (VB)
    Serial.println(String(wifistr));
  // get reply

  // delay(600);

  if (VB)
    Serial.println("\n*******************Reply: ");
  if (VB)
    Serial.println(String(cstr));
  if (VB)
    Serial.println();
}

void sendMultiDataString(void) // v981
{
  String multiDataString;
  int count = 0;
  String Str7;
  int i, j;

  clearbuffer();

  Serial.println();
  Serial.println("sending new AT100 packets");

  // connect

  if (!client.connect(host, httpPort))
  {
    displayText("Wifi failed");
    return;
  }

  if (atQ_size() > 0) // we have data
  {
    displayText("Uploading AT Data");
    multiDataString = "<ATEC>";
    multiDataString += "<ID>";
    multiDataString += String(parm[64]);
    multiDataString += "</ID>";
    multiDataString += "<V>";
    multiDataString += String(parm[14]);
    multiDataString += "</V>";
    multiDataString += "<ST>";
    multiDataString += String(0);
    multiDataString += "</ST>";
    multiDataString += "<R>";
    multiDataString += String(getWifiRSSI());
    multiDataString += "</R>";

    multiDataString += "<M>";
    Str7 = String(WiFi.macAddress());

    for (j = 0; j < 5; j++)
    {
      i = Str7.indexOf(':');
      Str7.remove(i, 1);
    }
    multiDataString += Str7;
    multiDataString += String("</M>");

    multiDataString += "<TZ>";
    multiDataString += String(parm[7]);
    multiDataString += "</TZ>";
    multiDataString += "<SYS>BOOGYDAT</SYS>";

    multiDataString += "<I>";

    while (atQ_size() > 0)
    {
      atQ_pull_FIFO();
      // atQ_pullLIFO();//v528

      multiDataString += "<S>";
      multiDataString += "<C>";
      multiDataString += String(at_QTempData.chan);
      multiDataString += "</C><T>";
      multiDataString += String(at_QTempData.type);
      multiDataString += "</T><D>";
      // v510
      multiDataString += String((at_QTempData.data / 10)); // data sent in x.x format
      multiDataString += String('.');
      multiDataString += String((at_QTempData.data % 10));
      // multiDataString += String(at_QTempData.data);

      multiDataString += "</D><E>";

      multiDataString += String(at_QTempData.etime);
      multiDataString += "</E>";

      multiDataString += "<SV>";           // <-- Added v533
      multiDataString += String(parm[14]); // <-- Added
      multiDataString += "</SV>";          // <-- Added

      multiDataString += "</S>";

      // Serial.println(multiDataString);

      if (++count > 6)
        break;
    }

    multiDataString += "</I>";
    multiDataString += "</ATEC>\r\n\r\n ";

    client.print(String("POST /AutoTecSQL/atecUpload.php HTTP/1.1\r\nContent-Type: text/xml\r\nHost:automationtec.net\r\nContent-Length:")); // new url
    // client.print(String("POST /AutoTecSQL/ HTTP/1.1\r\nContent-Type: text/xml\r\nHost:automationtec.net\r\nContent-Length:"));
    client.print(String(multiDataString.length()));
    client.print(String("\r\nConnection: close\r\n\r\n"));
    client.print(multiDataString);

    Serial.print("  Pull: ");
    Serial.print(multiDataString.length());
    Serial.print(" ");
    Serial.println(multiDataString);
    // delay(1000);//v980
  }
}

/*
  void sendAT100packetA(void)
  {
  int j;
  int i;

  clearbuffer();

  if (VB)Serial.println();
  if (VB)Serial.println("sending AT100 packet");

  //connect
  if (!client.connect(host, httpPort))
  {
    Serial.println("Wifi connection failed");
    return;
  }

  //build it
  //String wifistr = String("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><AT100><ATID>");
  wifistr = String("<AT100><ATID>");

  wifistr += String(at_QTempData.serial);
  wifistr += String("</ATID><DATA>");

  wifistr += String((at_QTempData.data / 10)); //data sent in x.x format
  wifistr += String('.');
  wifistr += String((at_QTempData.data % 10));

  wifistr += String("</DATA><TYPE>");
  wifistr += String(at_QTempData.type);
  wifistr += String("</TYPE><STATE>");
  wifistr += String(at_QTempData.stat);
  wifistr += String("</STATE><VER>");
  wifistr += String(at_QTempData.ver);

  wifistr += String("</VER><RSSI>");

  wifistr += String(at_QTempData.rssi);

  wifistr += String("</RSSI><MAC>");

  if (VB)Serial.println(String(WiFi.macAddress()));

  Str = String(WiFi.macAddress());
  for (j = 0; j < 5; j++)
  {
    i = Str.indexOf(':');
    Str.remove(i, 1);
  }

  wifistr += Str;
  wifistr += String("</MAC><ESTAMP>");
  wifistr += String(at_QTempData.etime);
  wifistr += "</ESTAMP><SYS>BOOGYDAT</SYS>";
  wifistr += "<TZ>";
  wifistr += String(parm[7]);
  wifistr += "</TZ></AT100>\r\n\r\n ";
  //Serial.println(String(wifistr));



  // send it

  //client.print(String("POST / HTTP/1.1\r\nContent-Type: text/xml\r\nHost:at.automationtec.net\r\nContent-Length:"));
  client.print(String("POST /AutoTecSQL/ HTTP/1.1\r\nContent-Type: text/xml\r\nHost:automationtec.net\r\nContent-Length:"));
  i = wifistr.length();
  client.print(String(i));
  client.print(String("\r\nConnection: close\r\n\r\n"));
  client.print(wifistr);

  if (VB)Serial.println(String(wifistr));


  // get reply

  //delay(600);

  if (VB)Serial.println("\n*******************Reply: ");
  if (VB)Serial.println(String(cstr));
  if (VB)Serial.println();
  }
*/

//*******************************************************
//
//*******************************************************

void sendFaultpacket(void)
{
  int j;
  int i;

  Serial.println();
  Serial.println("sending Fault packet");

  clearbuffer();

  // connect
  if (!client.connect(faulthost, httpPort))
  {
    Serial.println("Wifi connection failed");
    return;
  }

  // build it

  //   wifistr = String("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><AFC><EM>");
  wifistr = String("<APPDIG><DATA>");
  wifistr += String(parm[64]); // serial number
  wifistr += String(",");

  wifistr += String(fault_Qtempdata.faultnum); // fault
  wifistr += String(',');
  for (i = 0; i < 6; i++)
  {
    wifistr += String(fault_Qtempdata.data[i]);
    wifistr += String(',');
  }

  wifistr += String(fault_Qtempdata.etime);
  wifistr += String("</DATA></APPDIG>\r\n\r\n");

  // if(VB)Serial.println(String(WiFi.macAddress()));

  // send it

  // client.print(String("POST /faults/ HTTP/1.1\r\nContent-Type: text/xml\r\nHost:faults.appdig.com\r\nContent-Length:"));
  client.print(String("POST /faults HTTP/1.1\r\nContent-Type: text/xml\r\nHost:www.faults.appdig.com\r\nContent-Length:"));
  i = wifistr.length();
  client.print(String(i));
  client.print(String("\r\nConnection: close\r\n\r\n"));
  client.print(wifistr);

  //   if (VB)
  Serial.println(wifistr);

  // get reply

  // delay(700);

  if (VB)
    Serial.println("\n*******************Reply: ");
  if (VB)
    Serial.println(String(cstr));
  if (VB)
    Serial.println();
}
/*void sendFaultpacket(void)
{
  int j;
  int i;

  Serial.println();
  Serial.println("sending Fault packet");

  clearbuffer();

  //connect

  if (!client.connect(faulthost, httpPort))
  {
    Serial.println("Wifi connection failed");
    return;
  }

  //build it


  //   wifistr = String("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><AFC><EM>");
  wifistr = String("<AFC><EM>");
  wifistr += String(parm[64]);
  wifistr += String(",");

  wifistr += String(fault_Qtempdata.faultnum);
  wifistr += String(',');
  wifistr += String("0,0,0,0,0,0,");

  wifistr += String(fault_Qtempdata.etime);
  wifistr += String(',');
  wifistr += String(parm[7]);
  wifistr += String("</EM></AFC>\r\n\r\n");

  //if(VB)Serial.println(String(WiFi.macAddress()));

  // send it

  client.print(String("POST /UltimoControls/RusticaNet/upload.php HTTP/1.1\r\nContent-Type: text/xml\r\nHost:www.appdig.com\r\nContent-Length:"));
  i = wifistr.length();
  client.print(String(i));
  client.print(String("\r\nConnection: close\r\n\r\n"));
  client.print(wifistr);

  if (VB)Serial.println(wifistr);

  // get reply

  //delay(700);

  if (VB)Serial.println("\n*******************Reply: ");
  if (VB)Serial.println(String(cstr));
  if (VB)Serial.println();

}
*/

//*******************************************************
//
//*******************************************************

void clearbuffer(void)
{
  // int i;
  // for (i = 0; i < sizeof(cstr); cstr[i++] = 0);
  memset(cstr, 0, sizeof(cstr));
  replyindx = 0;
}

void parse_commands(char *indata, long *cmnds) // points to next char
{

  int i, j, minus = 0;

  for (i = 0; i < 4; i++)
  {
    j = 0;
    if (*indata == 45) // minus sign
    {
      indata++;
      minus = 1;
    }
    for (*cmnds = 0; isDigit(*indata);) // get the digits
    {
      *cmnds *= 10;
      *cmnds += (*indata - 48);
      indata++;
      if (j++ > 7)
        break;
      if (*indata == '*')
        break;
    }
    if (minus)
      *cmnds *= -1;
    cmnds++;
    indata++;
    if (*indata == '*')
      break;
  }
}

// Function that gets current epoch time //new ntp
unsigned long getTime()
{
  time_t now;
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo))
  {
    displayText("Failed to obtain time");
    return (0);
  }
  time(&now);
  return now;
}
