// add lines below to /boot/config.txt to enable extra 1-wire buses
// dtoverlay=w1-gpio,gpiopin=4
// dtoverlay=w1-gpio,gpiopin=23


// ADD FEATURES
// - monitor multiple sensors within a range of each other to detect a faulty sensor and prevent false actions from occuring

using namespace std;

class ds18b20
{
    public:
        ds18b20();
        void saveDS18B20Name(std::string address, std::string name);
        void saveDs18b20Min(int arrayID);
        void saveDs18b20Max(int arrayID);
        void resetDS18B20Min(std::string address);
        void resetDS18B20Max(std::string address);
        void saveDHT22Min(int arrayID);  // 
        void saveDHT22Max(int arrayID);  // 
        void changeTempCorF(short value);
        void ds18b20Startup();
        void startupDHT22();  // run at startup
        void autoDetectDs18b20();
        void checkTemps();
        void checkDHT22();  // check DHT22
        void saveDS18B20Charts();
        void deleteDS18B20(short id);
        void updateTempCorF(short v);
        void compileDS18B20Json();  // compile data to be sent to front end
        void compileDHT22Json();  // compile data to be sent to front end
        // std::string getDs18b20ID(short i);
        float getTemp(std::string address);
        float getTempDHT(short pinID);
        float getHumidity(short pinID);
        // float getDs18b20Count();
    private:
        short prevDs18b20Count = 0;  // tracks how many sensors are seen on previous read
        short ds18b20Count = 0;  // tracks how many sensors are seen on current read
        short ds18b20Saved = 0;  // tracks how many sensors are in database
        unsigned long long prevMillisDs18b20 = 0;  // track how often sensors are checked
        unsigned long long prevMillisDs18b20Save = 0;  // track how often sensor data is saved for chart
        unsigned long long prevMillisDHT22 = 0;  // track how often sensors are checked
        short tempCorF = 0;  // track if temp is set to celcuis or fahrenheit
        short dht22PinID[20] = {};  // unique  
        short dht22Pin[20] = {};  // pin number
        short dht22Driver[20] = {};  // driverID
        short dht22Count = 0;  // tracks how many sensors are seen on current read
        float tempFloat[20] = {};  // final temperature
        float minTemp[20] = {};  // minimum temperature
        float maxTemp[20] = {};  // maximum temperature
        float tempDHT[20] = {};  // final temperature
		float humidity[20] = {};
        float minDHT[20] = {};  // minimum temperature
        float maxDHT[20] = {};  // maximum temperature
        std::string ds18b20ID[20] = {};  // used to track sensor IDs for current read
        std::string prevDs18b20ID[20] = {};  // used to track sensor IDs for previous read
        std::string ds18b20IDSaved[20] = {};  // used to track all sensor IDs in database
        short ds18b20Start = 0;  // used to go through the startup step by step
        short reloadMinMax = 0;
        char path[30] = "/sys/bus/w1/devices/"; // file location of sensor
};
ds18b20::ds18b20(){}

// std::string ds18b20::getDs18b20ID(short i) {return ds18b20ID[i];}


// float ds18b20::getTemp(std::string address) {  // get temp
//     short arrayID = 0;
//     std::cout << "getTemp   ---------- ";
//     for(short a=0; a < ds18b20Count; a++) {  //
//         std::cout << tempFloat[a] << ", ";
//         if (ds18b20ID[a] == address) {arrayID = a; break;}
//     }
//     std::cout << " - " << ds18b20ID[arrayID] << "" << std::endl;
//     return tempFloat[arrayID];
// }

float ds18b20::getTemp(std::string address) {  // get temp
    short arrayID = 0;
    short found = 0;
    // std::cout << "getTemp   ---------- ";
    for(short a=0; a < ds18b20Count; a++) {  //
        // std::cout << tempFloat[a] << ", ";
        if (ds18b20ID[a] == address) {arrayID = a; found = 1; break;}
    }

    // std::cout << " - " << ds18b20ID[arrayID] << "" << std::endl;
    if (found == 1) {return tempFloat[arrayID];}
    else {return 999999;}  // return an error code so we know sensor was missing
    // return tempFloat[arrayID];
}

float ds18b20::getTempDHT(short pinID) {  // get DHT22 temp
    short arrayID = 0;
    for(short a=0; a < dht22Count; a++) {  //
        if (dht22PinID[a] == pinID) {arrayID = a; break;}
    }
    return tempDHT[arrayID];
}

float ds18b20::getHumidity(short pinID) {  // get humidity
    short arrayID = 0;
    for(short a=0; a < dht22Count; a++) {  //
        if (dht22PinID[a] == pinID) {arrayID = a; break;}
    }
    return humidity[arrayID];
}

// float ds18b20::getDs18b20Count() {return ds18b20Count;}

void ds18b20::updateTempCorF(short v) {tempCorF = v;}

void ds18b20::compileDS18B20Json() {  // compile data to be sent to front end

    for(short a=0; a < ds18b20Count; a++) {  //
        outgoingDataString += "{\"id\":\"";
        outgoingDataString += ds18b20ID[a];

        outgoingDataString += "\",\"t\":\"";
        std::stringstream temp;
        temp << std::fixed << std::setprecision(2) << tempFloat[a];  // round to 2 decimal places
        outgoingDataString += temp.str();
        
        std::stringstream min;
        outgoingDataString += "\",\"l\":\"";
        min << std::fixed << std::setprecision(2) << minTemp[a];  // round to 2 decimal places
        outgoingDataString += min.str();
        
        std::stringstream max;
        outgoingDataString += "\",\"h\":\"";
        max << std::fixed << std::setprecision(2) << maxTemp[a];  // round to 2 decimal places
        outgoingDataString += max.str();

        outgoingDataString += "\"}";

        if (a < ds18b20Count - 1) outgoingDataString += ",";  // add comma if another sensor is coming
    }
}

void ds18b20::compileDHT22Json() {  // compile data to be sent to front end

    for(short a=0; a < dht22Count; a++) {  //
        outgoingDataString += "{\"id\":\"dht_";
        outgoingDataString += to_string(dht22PinID[a]);

        outgoingDataString += "\",\"t\":\"";
        std::stringstream temp;
        temp << std::fixed << std::setprecision(2) << tempDHT[a];  // round to 2 decimal places
        outgoingDataString += temp.str();
        
        std::stringstream h;
        outgoingDataString += "\",\"a\":\"";
        h << std::fixed << std::setprecision(1) << humidity[a];  // round to 2 decimal places
        outgoingDataString += h.str();
        
        std::stringstream min;
        outgoingDataString += "\",\"l\":\"";
        min << std::fixed << std::setprecision(2) << minDHT[a];  // round to 2 decimal places
        outgoingDataString += min.str();
        
        std::stringstream max;
        outgoingDataString += "\",\"h\":\"";
        max << std::fixed << std::setprecision(2) << maxDHT[a];  // round to 2 decimal places
        outgoingDataString += max.str();

        outgoingDataString += "\"}";

        if (a < dht22Count - 1) outgoingDataString += ",";  // add comma if another sensor is coming
    }
}

void ds18b20::saveDS18B20Name(std::string address, std::string name) {  // save custom name
    // std::cout << "saveDS18B20Name    - " << std::endl;
    // std::cout << "name    - " << name << std::endl;
    // std::cout << "address - " << address << std::endl;
    connectMysql();
    std::string query = "UPDATE ds18b20 SET name = '" + name + "' WHERE address = '" + address + "'";
    mysql_query(conn, query.c_str()); // run query
    mysql_disconnect(); 
}

void ds18b20::saveDs18b20Min(int arrayID) {  // save minimum temperature
        // std::cout << "saveDs18b20Min-------------------------" << std::endl;
    minTemp[arrayID] = tempFloat[arrayID];
    connectMysql2();
    std::string query = "UPDATE ds18b20 SET min = '" + to_string(tempFloat[arrayID]) + "' WHERE address = '" + ds18b20ID[arrayID] + "'";
    mysql_query(conn2, query.c_str()); // run query
    mysql_disconnect2(); 
}

void ds18b20::saveDs18b20Max(int arrayID) {  // save maximum temperature
        // std::cout << "saveDs18b20Max-------------------------" << std::endl;
    maxTemp[arrayID] = tempFloat[arrayID];
    connectMysql2();
    std::string query = "UPDATE ds18b20 SET max = '" + to_string(tempFloat[arrayID]) + "' WHERE address = '" + ds18b20ID[arrayID] + "'";
    mysql_query(conn2, query.c_str()); // run query
    mysql_disconnect2(); 
}

void ds18b20::resetDS18B20Min(std::string address) {  // reset min temperature
    std::cout << "address     = " << address << std::endl;
    for (short a = 0; a < ds18b20Count; a++) {  // search address being reset
        // if (ds18b20ID[a] == address) { return;}
        if (ds18b20ID[a] == address) {saveDs18b20Min(a); return;}
    }
    std::cout << "nothing found " << address << std::endl;
    // no ds18b20 was found to reset so we check DHT22's
    for (short a = 0; a < dht22Count; a++) {  // search address being reset
        if ("dht_" + to_string(dht22PinID[a]) == address) {saveDHT22Min(a); return;}
        // if (dht22PinID[a] == std::stoi(address)) {saveDHT22Min(a); return;}
    }
    std::cout << "nothing found 2 " << address << std::endl;
}

void ds18b20::resetDS18B20Max(std::string address) {  // reset max temperature
    for (short a = 0; a < ds18b20Count; a++) {  // search address being reset
        // if (ds18b20ID[a] == address) { return;}
        if (ds18b20ID[a] == address) {saveDs18b20Max(a); return;}
    }
    std::cout << "nothing found " << address << std::endl;
    // no ds18b20 was found to reset so we check DHT22's
    for (short a = 0; a < dht22Count; a++) {  // search address being reset
        if ("dht_" + to_string(dht22PinID[a]) == address) {saveDHT22Max(a); return;}
        // if (dht22PinID[a] == std::stoi(address)) {saveDHT22Max(a); return;}
    }
}

void ds18b20::saveDHT22Min(int arrayID) {  // save minimum temperature
        // std::cout << "saveDs18b20Min-------------------------" << std::endl;
    minDHT[arrayID] = tempDHT[arrayID];
    connectMysql2();
    std::string query = "UPDATE ds18b20 SET min = '" + to_string(tempDHT[arrayID]) + "' WHERE address = 'dht_" + to_string(dht22PinID[arrayID]) + "'";
    mysql_query(conn2, query.c_str()); // run query
    mysql_disconnect2(); 
}

void ds18b20::saveDHT22Max(int arrayID) {  // save maximum temperature
        // std::cout << "saveDs18b20Max-------------------------" << std::endl;
    maxDHT[arrayID] = tempDHT[arrayID];
    connectMysql2();
    std::string query = "UPDATE ds18b20 SET max = '" + to_string(tempDHT[arrayID]) + "' WHERE address = 'dht_" + to_string(dht22PinID[arrayID]) + "'";
    mysql_query(conn2, query.c_str()); // run query
    mysql_disconnect2(); 
}

void ds18b20::changeTempCorF(short value) {  // update temperature celsius or fahrenheit format
    // std::cout << "changeTempCorF --------------------" << std::endl;
    if (value != tempCorF)
    {
        tempCorF = value;    
        for (short a = 0; a < ds18b20Count; a++)
        {
            if (tempCorF == 1) {  // convert current temp to fahrenheit
                tempFloat[a] = ((tempFloat[a] * 9) / 5) + 32;
                minTemp[a] = ((minTemp[a] * 9) / 5) + 32;
                maxTemp[a] = ((maxTemp[a] * 9) / 5) + 32;
            }
            else {  // convert current temp to celsius
                tempFloat[a] = ((tempFloat[a] - 32) * 5) / 9;
                minTemp[a] = ((minTemp[a] - 32) * 5) / 9;
                maxTemp[a] = ((maxTemp[a] - 32) * 5) / 9;
            }
            // std::cout << "ds18b20ID[a]     = " << ds18b20ID[a] << std::endl;
            // std::cout << "minTemp[a]       = " << minTemp[a] << std::endl;
            // std::cout << "maxTemp[a]       = " << maxTemp[a] << std::endl;
        }

        for (short a = 0; a < dht22Count; a++)
        {
            if (tempCorF == 1) {  // convert current temp to fahrenheit
                tempDHT[a] = ((tempDHT[a] * 9) / 5) + 32;
                minDHT[a] = ((minDHT[a] * 9) / 5) + 32;
                maxDHT[a] = ((maxDHT[a] * 9) / 5) + 32;
            }
            else {  // convert current temp to celsius
                tempDHT[a] = ((tempDHT[a] - 32) * 5) / 9;
                minDHT[a] = ((minDHT[a] - 32) * 5) / 9;
                maxDHT[a] = ((maxDHT[a] - 32) * 5) / 9;
            }
            // std::cout << "dht22PinID[a]    = " << dht22PinID[a] << std::endl;
            // std::cout << "minDHT[a]        = " << minDHT[a] << std::endl;
            // std::cout << "maxDHT[a]        = " << maxDHT[a] << std::endl;
        }
        connectMysql();
        for (short a = 0; a < ds18b20Count; a++)
        {
            std::string query = "UPDATE ds18b20 SET min = '" + to_string(minTemp[a]) + "', max = '" + to_string(maxTemp[a]) + "' WHERE address = '" + ds18b20ID[a] + "'";
            if(mysql_query(conn, query.c_str())) std::cerr << mysql_error(conn);
            
            // query = "UPDATE ds18b20 SET max = '" + to_string(maxTemp[a]) + "' WHERE address = '" + ds18b20ID[a] + "'";
            // if(mysql_query(conn, query.c_str())) std::cerr << mysql_error(conn);
        }
        for (short a = 0; a < dht22Count; a++)
        {
            std::string query = "UPDATE ds18b20 SET min = '" + to_string(minDHT[a]) + "', max = '" + to_string(maxDHT[a]) + "' WHERE address = 'dht_" + to_string(dht22PinID[a]) + "'";
            if(mysql_query(conn, query.c_str())) std::cerr << mysql_error(conn);
            
            // query = "UPDATE ds18b20 SET max = '" + to_string(maxDHT[a]) + "' WHERE address = 'dht_" + to_string(dht22PinID[a]) + "'";
            // if(mysql_query(conn, query.c_str())) std::cerr << mysql_error(conn);
        }
        std::string query = "UPDATE systemSettings SET tempCorF = '" + to_string(tempCorF) + "'";
        if(mysql_query(conn, query.c_str())) std::cerr << mysql_error(conn);
        mysql_disconnect(); 
    }
}

void ds18b20::ds18b20Startup() {  // run once when Pi starts
    if (ds18b20Start == 0) {  // allows us to access the 1-wire bus   
        system("sudo modprobe w1-gpio");
        system("sudo modprobe w1-therm");
    }
    else if (ds18b20Start == 1) // wait till sensors are read once so we know what's plugged in
    {
        std::cout << " " << std::endl;
        std::cout << "ds18b20Startup-------------------------" << std::endl;

        MYSQL_RES *res;
        MYSQL_ROW row;

        connectMysql();
        std::string query = "SELECT address FROM ds18b20 ORDER BY address ASC";  // get all ds18b20 addresses stored in database
        mysql_query(conn, query.c_str());  // run query
        res = mysql_use_result(conn);

        // short searchID = 0;
        // std::string test;
        ds18b20Saved = 0;  // reset saved count
        while ((row = mysql_fetch_row(res)) != NULL)
        {
            std::string addr = row[0];
            std::cout << "address      = " << addr << std::endl;
            // serachID = std::all_of(test.begin(), test.end(), ::isdigit); // C++11

            std::size_t isDHT = addr.find("dht");

            // short isDHT = addr.find_first_not_of("0123456789") == std::string::npos;  // check if address only has numbers, that would be a DHT22

            // searchID = std::stoi(row[0]);
            std::cout << "searchID     = " << isDHT << std::endl;
            // if (isDHT == 0) {
            if (isDHT != std::string::npos) {}
            else {
                ds18b20IDSaved[ds18b20Saved] = row[0];  // record each ds18b20 address in database
                ds18b20Saved++;  // track total saved
            }
        }
        mysql_free_result(res);
        
        query = "UPDATE ds18b20 SET plugged = '0'";  // mark all sensors in database unplugged
        mysql_query(conn, query.c_str());  // run query

        for (short a = 0; a < ds18b20Count; a++)  // go though each sensor plugged in and update database accordingly
        {
            std::string query = "UPDATE ds18b20 SET plugged = '1' WHERE address = '" + ds18b20ID[a] + "'";  // update database that sensor is plugged in
            mysql_query(conn, query.c_str());
        }

        for (short a = 0; a < dht22Count; a++)  // go though each sensor plugged in and update database accordingly
        {
            std::string query = "UPDATE ds18b20 SET plugged = '1' WHERE address = 'dht_" + to_string(dht22PinID[a]) + "'";  // update database that sensor is plugged in
            mysql_query(conn, query.c_str());
        }

        // BUG -- if sensors aren't plugged in when Pi started no min/max is loaded so it will be reset when plugged in.
        for (short a = 0; a < ds18b20Count; a++)  // go though each sensor plugged in
        {
            MYSQL_RES *res;
            MYSQL_ROW row;

            std::string query = "SELECT min, max FROM ds18b20 WHERE address = '" + ds18b20ID[a] + "'";  // get min/max from database for each sensor plugged in
            mysql_query(conn, query.c_str());  // run query
            res = mysql_use_result(conn);

            while ((row = mysql_fetch_row(res)) != NULL)
            {
                minTemp[a] = atof(row[0]);
                maxTemp[a] = atof(row[1]);
            }

            mysql_free_result(res);
        }
        mysql_disconnect();
        ds18b20Start = 2;  // go to step two of startup
        std::cout << "ds18b20Saved     = " << ds18b20Saved << std::endl;
        std::cout << "ds18b20Count     = " << ds18b20Count << std::endl;
        std::cout << " " << std::endl;
    }
}

void ds18b20::startupDHT22() {  // run at startup
	if (startupComplete == 0) {
        std::cout << " " << std::endl;
        std::cout << "startupDHT22------------------------------" << std::endl;
    }
    MYSQL_RES *res;
    MYSQL_ROW row;

    std::fill_n(dht22PinID, 20, 0);  // reset array
    std::fill_n(dht22Driver, 20, 0);  // reset array
    std::fill_n(dht22Pin, 20, 0);  // reset array
    std::fill_n(minDHT, 20, 0);  // reset array
    std::fill_n(maxDHT, 20, 0);  // reset array
	// get pins assigned as dht22
    connectMysql();
    std::string query = "SELECT pinID, driverID, gpio FROM pinsAvailable WHERE pinTypeID = '4' AND assigned = '1'";  // construct query string
    mysql_query(conn, query.c_str());  // run query

    res = mysql_use_result(conn);
    dht22Count = 0;
    while ((row = mysql_fetch_row(res)) != NULL)
    {
        dht22PinID[dht22Count] = atoi(row[0]);
        dht22Driver[dht22Count] = atoi(row[1]);
        dht22Pin[dht22Count] = atoi(row[2]);
		if (startupComplete == 0) {
            std::cout << "gpio input     - " << dht22PinID[dht22Count] << " - " << dht22Pin[dht22Count] << " - " << dht22Driver[dht22Count] << std::endl;
        }
        dht22Count++;
    }
    mysql_free_result(res);
	
    for (short a = 0; a < dht22Count; a++)  // go though each sensor plugged in
    {

        query = "SELECT min, max FROM ds18b20 WHERE address = 'dht_" + to_string(dht22PinID[a]) + "'";  // get min/max from database for each sensor plugged in
        mysql_query(conn, query.c_str());  // run query
        res = mysql_use_result(conn);

        while ((row = mysql_fetch_row(res)) != NULL)
        {
            minDHT[a] = atof(row[0]);
            maxDHT[a] = atof(row[1]);
        }

        mysql_free_result(res);
    }

    mysql_disconnect(); 
    // mysql_free_result(res);

	checkDHT22();
	if (startupComplete == 0) {
        std::cout << "dht22Count     - " << dht22Count << std::endl;
        std::cout << "----------------------------------------" << std::endl;
    }
}

void ds18b20::autoDetectDs18b20() {  // check if sensors have been plugged in, unplugged, deleted or new added
    if (ds18b20Start == 2) {  // run step 2 of startup
        // This will check if new sensors not in database were plugged in before controller was powered up
        // std::cout << "DS18B20 CHECK FOR NEW SENSORS AT STARTUP --------- " << std::endl;

        std::string newID[20] = {};  // used to store new addresses found
        short add = 0;  // count new sensors to be added to database

        for (short a = 0; a < ds18b20Count; a++)  // go through each sensor plugged in one by one
        {
            short f = 0;  // flag if sensor is already saved
            for (short b = 0; b < ds18b20Saved; b++)  // go through all sensors in database
            {
                if (ds18b20ID[a] == ds18b20IDSaved[b])  // check if sensor is already in database
                {
                    f = 1;
                    break;
                }
            }
            if (f == 0) {  // record sensor address to add
                newID[add] = ds18b20ID[a];
                add++;
            }
        }

        connectMysql2();
        for (short a = 0; a < add; a++) // go through each new address found and add to database
        {
            reloadMinMax = 1;  // need to update min/max arrays as sensor locations have changed
            // std::cout << "newID[a]           = " << newID[a] << std::endl;
            ds18b20IDSaved[ds18b20Saved] = newID[a];
            ds18b20Saved++;

            std::string query = "INSERT INTO ds18b20 (address,plugged,graphVisible,min,max) VALUES('" + newID[a] + "','1','1','" + to_string(tempFloat[a]) + "','" + to_string(tempFloat[a]) + "')";
            mysql_query(conn2, query.c_str()); // run query
        }
        mysql_disconnect2(); 
        ds18b20Start = 3;  // startup complete
    }
    if (ds18b20Start == 3)  // startup complete
    {
        if (ds18b20Count == prevDs18b20Count)  // used to detect sensor swaps at same time when overall sensor count doesn't change
        {
            for (short a = 0; a < ds18b20Count; a++) // go through each sensor plugged in one by one
            {
                if (ds18b20ID[a] != prevDs18b20ID[a]) {  // sensor address doesn't match
                    // std::cout << "DS18B20 ADDRESS CHANGED --------- " << std::endl;
                    connectMysql2();
                    std::string query = "UPDATE ds18b20 SET plugged = '0' WHERE address = '" + prevDs18b20ID[a] + "'";  // update database that sensor is unplugged
                    mysql_query(conn2, query.c_str());  // run query

                    query = "UPDATE ds18b20 SET plugged = '1' WHERE address = '" + ds18b20ID[a] + "'";  // update database that sensor is plugged in
                    mysql_query(conn2, query.c_str());  // run query
                    mysql_disconnect2(); 

                    // std::cout << "  " << std::endl;
                    // std::cout << "ds18b20ID[a]       = " << ds18b20ID[a] << std::endl;
                    // std::cout << "prevDs18b20ID[a]   = " << prevDs18b20ID[a] << std::endl;
                    // std:string t = ds18b20ID[a];
                    // ds18b20ID[a] = prevDs18b20ID[a];
                    prevDs18b20ID[a] = ds18b20ID[a];


                    reloadMinMax = 1;  // need to update min/max arrays as sensor locations have changed
                    // std::cout << "ds18b20ID[a]       = " << ds18b20ID[a] << std::endl;
                    // std::cout << "prevDs18b20ID[a]   = " << prevDs18b20ID[a] << std::endl;
                }
            }
        }
        if (ds18b20Count != prevDs18b20Count)  // sensors changed
        {
            // std::cout << "CHANGE MADE --------- " << std::endl;
            // changes = 0;  // track total number of changes
            // add = 0;  // track how many sensors need to be added to database
            // saved = 0;  // track how many sensors are already in database and only plugged in

            short changes = 0;  // track total number of changes
            short add = 0;  // track how many sensors need to be added to database
            short saved = 0;  // track how many sensors are already in database and only plugged in
            std::string changeID[10] = {};  // track addresses that changed
            std::string newID[10] = {};  // track new addresses to add to database
            std::string savedID[10] = {};  // track addresses already in database
            
            reloadMinMax = 1;  // need to update min/max arrays as sensor locations have changed
            // std::cout << "ds18b20Count       = " << ds18b20Count << std::endl;
            // std::cout << "prevDs18b20Count   = " << prevDs18b20Count << std::endl;
            for (short b = 0; b < prevDs18b20Count; b++)  // replace temperatures with error code so we don't mistakenly trigger custom rules
            {
                tempFloat[b] = 999999;  // fill array with error code until it fills up, this will stop custom rule from triggering based on another DS18B20 value
            }
            if (ds18b20Count > prevDs18b20Count)  // sensor/s was added
            {
                for (short a = 0; a < ds18b20Count; a++) // go through each sensor plugged in one by one
                {
                    short f = 0;  // flag if sensor is already saved
                    for (short b = 0; b < prevDs18b20Count; b++) // go through all previous ID's and find sensors that were plugged in
                    {
                        if (ds18b20ID[a] == prevDs18b20ID[b]) {  // sensor already plugged in
                            f = 1;
                            break;
                        }
                    }
                    if (f == 0) {  // sensors that were plugged in
                        changeID[changes] = ds18b20ID[a];
                        changes++;
                    }
                }
                if (changes > 0) {  // sort new sensors from sensors already in database
                    for (short a = 0; a < changes; a++) // go through all sensors that have changed
                    {
                        short f = 0;  // flag if sensor is already saved
                        for (short b = 0; b < ds18b20Saved; b++) // go through all sensors in database and sort new from old
                        {
                            if (changeID[a] == ds18b20IDSaved[b]) {  // sensor to mark plugged in
                                savedID[saved] = changeID[a];
                                f = 1;
                                saved++;
                                break;
                            }
                        }
                        if (f == 0) {  // sensor to add to database
                            newID[add] = changeID[a];
                            add++;
                        }
                    }
                }
                        
                connectMysql2();

                if (saved > 0) {  // update database that sensor was plugged back in
                    // std::cout << "DS18B20 PLUGGED IN ALREADY IN DATABASE --------- " << std::endl;
                    for (short a = 0; a < saved; a++) // update all sensors that need it
                    {
                        std::string query = "UPDATE ds18b20 SET plugged = '1' WHERE address = '" + savedID[a] + "'"; // update database that sensor is plugged in
                        mysql_query(conn2, query.c_str());  // run query
                    }
                }

                if (add > 0) {  // add new sensor to database
                    // std::cout << "DS18B20 NEW SENSOR PLUGGED IN --------- " << std::endl;
                    for (short a = 0; a < add; a++) // add all new sensors to database
                    {
                        // std::cout << "newID[a]           = " << newID[a] << std::endl;
                        ds18b20IDSaved[ds18b20Saved] = newID[a];
                        ds18b20Saved++;

                        std::string query = "INSERT INTO ds18b20 (address,plugged,graphVisible,min,max) VALUES('" + newID[a] + "','1','1','" + to_string(tempFloat[a]) + "','" + to_string(tempFloat[a]) + "')";
                        mysql_query(conn2, query.c_str()); // run query
                    }
                }
                mysql_disconnect2(); 
            }
            else  // sensor was unplugged
            {
                // std::cout << "DS18B20 UNPLUGGED --------- " << std::endl;
                connectMysql2();
                for (short a = 0; a < prevDs18b20Count; a++) // go through each sensor that was seen before one was unplugged
                {
                    short f = 0;  // flag if sensor is already saved
                    for (short b = 0; b < ds18b20Count; b++) // go through all sensors and find sensors to unplug
                    {
                        if (prevDs18b20ID[a] == ds18b20ID[b]) {  // sensor is still plugged in
                            f = 1;
                            break;
                        }
                    }
                    if (f == 0) {  // sensor was unplugged - mark database as such
                        changeID[changes] = prevDs18b20ID[a];
                        std::string query = "UPDATE ds18b20 SET plugged = '0' WHERE address = '" + prevDs18b20ID[a] + "'"; // update database that sensor is plugged in
                        mysql_query(conn2, query.c_str());  // run query
                        changes++;
                    }
                }
                mysql_disconnect2(); 
            }
            
            // for (short a = 0; a < ds18b20Saved; a++) // go through each sensor plugged in one by one
            // {
            //     std::cout << "ds18b20IDSaved[a]  = " << ds18b20IDSaved[a] << std::endl;
            // }
            // for (short a = 0; a < ds18b20Count; a++) // go through each sensor plugged in one by one
            // {
            //     std::cout << "ds18b20ID[a]       = " << ds18b20ID[a] << std::endl;
            // }
            // for (short a = 0; a < prevDs18b20Count; a++) // go through each sensor plugged in one by one
            // {
            //     std::cout << "prevDs18b20ID[a]   = " << prevDs18b20ID[a] << std::endl;
            // }
            // for (short a = 0; a < changes; a++) // go through each sensor plugged in one by one
            // {
            //     std::cout << "changeID[a]        = " << changeID[a] << std::endl;
            // }
            // std::cout << "changes            = " << changes << std::endl;
            // std::cout << "saved              = " << saved << std::endl;
            // std::cout << "add                = " << add << std::endl;
        }

        if (reloadMinMax == 1) {  // update min/max arrays
            connectMysql2();
            for (short a = 0; a < ds18b20Count; a++)  // go though each sensor plugged in
            {
                MYSQL_RES *res;
                MYSQL_ROW row;

                std::string query = "SELECT min, max FROM ds18b20 WHERE address = '" + ds18b20ID[a] + "'";  // get min/max from database for each sensor plugged in
                mysql_query(conn2, query.c_str());  // run query
                res = mysql_use_result(conn2);

                while ((row = mysql_fetch_row(res)) != NULL)
                {
                    minTemp[a] = atof(row[0]);
                    maxTemp[a] = atof(row[1]);
                }

                mysql_free_result(res);
            }
            mysql_disconnect2(); 
            reloadMinMax = 0;
        }
    }
}

void ds18b20::checkTemps() {  // check temperatures and manage sensors
            // std::cout << "checkTemps" << std::endl;
    if (currentMillisTime >= (prevMillisDs18b20 + 1000)) // check sensors every second
    {
        // Read Raspberry Pi cpu temperature
        // float systemp;
        // float millideg;
        // FILE *thermal;
        // int n;

        // thermal = fopen("/sys/class/thermal/thermal_zone0/temp","r");
        // n = fscanf(thermal,"%f",&millideg);
        // fclose(thermal);
        // systemp = millideg / 1000;

        // printf("CPU temperature is %f degrees C\n",systemp);

        ds18b20Startup(); // run once when Pi starts
        
        std::string fullPath[20] = {}; // used to store full path to each sensor up to 30
        DIR *dirp;  // used to open the 1-wire directory
        struct dirent *direntp = 0;  // used to browse the files in the 1-wire directory
        char *temp = 0;  // place to put temp when we get data
                
        if ((dirp = opendir(path)) == NULL)  // Check if /sys/bus/w1/devices/ exists
        {
            // std::cout << "opendir error -- " << std::endl;
            logError(1, "", "1-wire directory not found - /sys/bus/w1/devices/");
            prevMillisDs18b20 = currentMillisTime;
            checkTemps();
            return; // don't process and exit function
        }

        prevDs18b20Count = ds18b20Count; // store count of sensors found last read so we know if something was unplugged
        std::fill_n(prevDs18b20ID, 20, 0);  // reset array
        for (short a = 0; a < ds18b20Count; a++) // store previous sensor IDs found so we can identify any changes on upcoming read
        {
            prevDs18b20ID[a] = ds18b20ID[a];
        }
        ds18b20Count = 0; // reset sensor count for this read
        std::fill_n(ds18b20ID, 20, 0);  // reset array

        // go through each sub directory found, these are the sensor ID folders so we know all the sensors connected
        // while ((direntp = readdir(dirp)) != NULL)
        // {
        //     // If 28- is the substring of d_name then copy d_name to rom and print rom.
        //     if (strstr(direntp->d_name, "28-")) // check if folder starts with 28-
        //     {
        //         fullPath[ds18b20Count] = "/sys/bus/w1/devices/";  // path on pi for sensor values
        //         fullPath[ds18b20Count] += direntp->d_name;
        //         fullPath[ds18b20Count] += "/w1_slave";
                
        //         ds18b20ID[ds18b20Count] = direntp->d_name;
        //         ds18b20ID[ds18b20Count].erase(0, 3); // remove first 3 characters from string
        //         ds18b20Count++;
        //     }
        // }
        while ((direntp = readdir(dirp)) != NULL)
        {
            // If 28- is the substring of d_name then copy d_name to rom and print rom.
            char path2[50] = "/sys/bus/w1/devices/";  // path on pi for sensor values
            char rom[20];                       // internal sensor ID
            if (strstr(direntp->d_name, "28-")) // check if folder starts with 28-
            {
                strcpy(rom, direntp->d_name);
                strcat(path2, rom);
                strcat(path2, "/w1_slave");
                fullPath[ds18b20Count] = path2; // store full path to use later for checking sensor
                ds18b20ID[ds18b20Count] = rom;
                ds18b20ID[ds18b20Count].erase(0, 3); // remove first 3 characters from string
                ds18b20Count++;
            }
        }
        closedir(dirp);

        autoDetectDs18b20(); // check if sensors have been plugged in or unplugged so we can update auto detect system on front end

        // check all sensors found and retrieve temperature
        for (short a = 0; a < ds18b20Count; a++)
        {
            int fd = -1;
            char buf[80] = {}; // all data from sensor being read, gets stripped down
            buf[0] = '\0';

            if ((fd = open(fullPath[a].c_str(), O_RDONLY)) < 0) // try to open file
            {
                // std::cout << "open error -- " << std::endl;
                // std::string errorMsg = "Sensor not seen on Bus";
                // logError(1, ds18b20ID[a], errorMsg);
                prevMillisDs18b20 = currentMillisTime;
                checkTemps();
                return; // don't process and exit function
            }

            if (read(fd, buf, sizeof(buf)) < 0) // try to read the file
            {
                // std::cout << "read error -- " << std::endl;
                std::string errorMsg = "Sensor can't be read";
                logError(1, ds18b20ID[a], errorMsg);
                prevMillisDs18b20 = currentMillisTime;
                checkTemps();
                return; // don't process and exit function
            }
            close(fd);

            if (buf[0] == '\0') // check if ds18b20 was unplugged or can't be read after it was found
            {
                // std::cout << "buf empty =====================!!!!!!!!!!!!!!!!!!!!!" << std::endl;
                std::string errorMsg = "Sensor didn't return any data";
                logError(1, ds18b20ID[a], errorMsg);
                prevMillisDs18b20 = currentMillisTime;
                checkTemps();
                return; // don't process and exit function
            }

            temp = strchr(buf, 't');    // get data after the 't'
            sscanf(temp, "t=%s", temp); // remove "t=" from the array
            tempFloat[a] = atof(temp) / 1000; // convert char to float
            
            if ((tempFloat[a] >= -70.0) && (tempFloat[a] <= 70.0))  // temp must be less than 70° celsius
            {
                if (tempCorF == 1) {tempFloat[a] = ((tempFloat[a] * 9) / 5) + 32;} // convert temp to fehreheit if required

                // output temperature in string with 2 decimal places
                if (ds18b20Start == 3)  // system up and running, track min/max
                {
                    if ((tempFloat[a] < minTemp[a]) || (minTemp[a] == 0)) {saveDs18b20Min(a);}
                    if ((tempFloat[a] > maxTemp[a]) || (maxTemp[a] == 0)) {saveDs18b20Max(a);}
                }
            }
            else
            {
                // std::cout << "Temperature out of range -- " << std::endl;
                std::string errorMsg = "Sensor temperature is out of range";
                logError(1, ds18b20ID[a], errorMsg);
                prevMillisDs18b20 = currentMillisTime;
                checkTemps();
                return; // don't process and exit function
            }
            // std::cout << ds18b20ID[a] << " - " << tempFloat[a] << std::endl;
            // std::cout << ds18b20ID[a] << std::endl;
        }
        if (ds18b20Start == 0) {ds18b20Start = 1;} // first read after startup completed
        
        prevMillisDs18b20 = currentMillisTime;
            // std::cout << "checkTemps done" << std::endl;
    }
}

void ds18b20::checkDHT22() {  // check DHT22
    // if (currentMillisTime >= (prevMillisDHT22 + 1000)) // check sensors every second
    // {
            // std::cout << "checkTemps done" << std::endl;
		for(short a=0; a < dht22Count; a++)  // search all channels for matching pinID
		{
			int data[5] = { 0, 0, 0, 0, 0 };
			uint8_t laststate	= HIGH;
			uint8_t counter		= 0;
			uint8_t j			= 0, i;
		
			data[0] = data[1] = data[2] = data[3] = data[4] = 0;
		
			/* pull pin down for 18 milliseconds */
			pinMode(dht22Pin[a], OUTPUT);
			digitalWrite(dht22Pin[a], LOW);
			delay(18);
		
			/* prepare to read the pin */
			pinMode(dht22Pin[a], INPUT);
		
			/* detect change and read data */
			for (i = 0; i < 85; i++)
			{
				counter = 0;
				while (digitalRead(dht22Pin[a]) == laststate)
				{
					counter++;
					delayMicroseconds(18);
					if (counter == 255)
					{
						break;
					}
				}
				laststate = digitalRead(dht22Pin[a]);
		
				if (counter == 255) {break;}
		
				/* ignore first 3 transitions */
				if ((i >= 4) && (i % 2 == 0))
				{
					/* shove each bit into the storage bytes */
					data[j / 8] <<= 1;
					if (counter > 16)
						data[j / 8] |= 1;
					j++;
				}
			}
			/*
			* check we read 40 bits (8bit x 5 ) + verify checksum in the last byte
			* print it out if data is good
			*/
            std::cout << "data[0] = " << data[0] << std::endl;
            std::cout << "data[1] = " << data[1] << std::endl;
            std::cout << "data[2] = " << data[2] << std::endl;
            std::cout << "data[3] = " << data[3] << std::endl;
            std::cout << "data[4] = " << data[4] << std::endl;
			if ((j >= 40) && (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)))
			{
				humidity[a] = (float)((data[0] << 8) + data[1]) / 10;
				if (humidity[a] > 100)
				{
					humidity[a] = data[0];	// for DHT11
				}

				tempDHT[a] = (float)(((data[2] & 0x7F) << 8) + data[3]) / 10;
				if (tempDHT[a] > 125)
				{
					tempDHT[a] = data[2];	// for DHT11
				}
				if (data[2] & 0x80)
				{
					tempDHT[a] = -tempDHT[a];
				}
                if (tempCorF == 1) {tempDHT[a] = ((tempDHT[a] * 9) / 5) + 32;}
				// if (tempCorF == 1) {tempDHT[a] = tempDHT[a] * 1.8f + 32;}
				
				if ((tempDHT[a] < minDHT[a]) || (minDHT[a] == 0)) {saveDHT22Min(a);}
				if ((tempDHT[a] > maxDHT[a]) || (maxDHT[a] == 0)) {saveDHT22Max(a);}
				printf( "Humidity = %.2f %% Temperature = %.2f *\n", tempDHT[a], humidity[a] );
			}
			else  {
				// checkDHT22();
				// printf( "Data not good, skip -------------------------------------\n" );
				printf( "Humidity = %.2f %% Temperature = %.2f *\n", tempDHT[a], humidity[a] );
				// printf( "ERROR --- Humidity = %.2f %% Temperature = %.2f *\n", humidity[a], temperature[a] );
			}
		}
        // prevMillisDHT22 = currentMillisTime;
	// }
}

void ds18b20::saveDS18B20Charts() {  // update charts
    // if (currentMillisTime >= (prevMillisDs18b20Save + 900000)) // check sensors every second
    if ((ds18b20Start >= 1) && (currentMillisTime >= (prevMillisDs18b20Save + 300000))) // save chart every 5 minutes
    {
        // std::cout << "saveDS18B20Charts-----------------------" << std::endl;
        // std::stringstream logTimestamp;
        // time_t now = time(0);
        // tm *ltm = localtime(&now);
        // std::string monF = systemSettings.format_number(1 + ltm->tm_mon, 2);
        // std::string dayF = systemSettings.format_number(ltm->tm_mday, 2);
        // std::string hourF = systemSettings.format_number(ltm->tm_hour, 2);
        // std::string minF = systemSettings.format_number(ltm->tm_min, 2);
        // std::string secF = systemSettings.format_number(ltm->tm_sec, 2);

        // logTimestamp.str(std::string());
        // logTimestamp << 1900 + ltm->tm_year // create timestamp string for database
        //              << "/"
        //              << monF
        //              << "/"
        //              << dayF
        //              << " "
        //              << hourF
        //              << ":"
        //              << minF
        //              << ":"
        //              << secF;

        // // std::cout << logTimestamp.str() << endl;
        
        time_t rawtime = currentMillisTime / 1000;
        struct tm  ts;
        char       buf[80];

        // Format time, "ddd yyyy-mm-dd hh:mm:ss zzz"
        ts = *localtime(&rawtime);
        strftime(buf, sizeof(buf), "%Y/%m/%d %H:%M:%S", &ts);
        std::string logTimestamp = buf;

        // log DS18B20's
        for (short a = 0; a < ds18b20Count; a++)
        {
            if (tempFloat[a] != 999999)  // verify DS18B20 wasn't missing
            {
                float tempC = 0;
                float tempF = 0;

                if (tempCorF == 0) // convert current temp to fahrenheit
                {
                    tempC = tempFloat[a];
                    tempF = ((tempFloat[a] * 9) / 5) + 32;
                }
                else // convert current temp to fahrenheit
                {
                    tempC = ((tempFloat[a] - 32) * 5) / 9;
                    tempF = tempFloat[a];
                }

                if (tempF != 0)
                {
                    // save chart data to csv file - celsius
                    std::ofstream outfile;
                    std::string path = "/var/www/html/chartData/" + ds18b20ID[a] + "_C.csv";
                    std::string data = logTimestamp + ", " + to_string(tempC) + "\n";
                    outfile.open(path, std::ios_base::app); // append instead of overwrite
                    outfile << data;
                    outfile.close();
                    // outfile << "8/18/2020 12:55:20, 25.34\n";

                    // save chart data to csv file - fahrenheit
                    path = "/var/www/html/chartData/" + ds18b20ID[a] + "_F.csv";
                    data = logTimestamp + ", " + to_string(tempF) + "\n";
                    outfile.open(path, std::ios_base::app); // append instead of overwrite
                    outfile << data;
                    outfile.close();
                    // outfile << "8/18/2020 12:55:20, 81.34\n";

                    // check if sensor table exists in database
                    MYSQL_RES *res;
                    MYSQL_ROW row;
                    connectMysql3();
                    std::string query = "SHOW TABLES LIKE '" + ds18b20ID[a] + "_C'"; // construct query string
                    mysql_query(conn3, query.c_str());                                // run query

                    res = mysql_use_result(conn3);
                    // std::cout << res << std::endl;
                    if (mysql_fetch_row(res) == NULL) // if ds18b20 address isn't in database create a table
                    {
                        // creat new table in database for ds18b20 data
                        query = "CREATE TABLE " + ds18b20ID[a] + "_C (dataID int AUTO_INCREMENT, \
                                                                    temp float, \
                                                                    timestamp varchar(40), \
                                                                    PRIMARY KEY (dataID))"; // construct query string
                        mysql_query(conn3, query.c_str());                                   // run query

                        query = "CREATE TABLE " + ds18b20ID[a] + "_F (dataID int AUTO_INCREMENT, \
                                                                    temp float, \
                                                                    timestamp varchar(40), \
                                                                    PRIMARY KEY (dataID))"; // construct query string
                        mysql_query(conn3, query.c_str());                                   // run query

                        // std::cout << "added new ds18b20 chart tables to database:" << std::endl;
                    }

                    mysql_free_result(res);
                    mysql_disconnect3(); 
                    connectMysql3();
                        // std::string query = "INSERT INTO i2cDevices (decAddress) VALUES('" + to_string(decAddressScanned[a]) + "')";
                    query = "INSERT INTO " + ds18b20ID[a] + "_C (temp,timestamp) VALUES('" + to_string(tempC) + "','" + logTimestamp + "')";
                    mysql_query(conn3, query.c_str()); // run query
                    query = "INSERT INTO " + ds18b20ID[a] + "_F (temp,timestamp) VALUES('" + to_string(tempF) + "','" + logTimestamp + "')";
                    mysql_query(conn3, query.c_str()); // run query

                    /* close connection */
                    mysql_disconnect3(); 
                    // mysql_free_result(res);
                }
            }
        }

        // log DHT22's
        for (short a = 0; a < dht22Count; a++)
        {
            float tempC = 0;
            float tempF = 0;

            if (tempCorF == 0) // convert current temp to fahrenheit
            {
                tempC = tempDHT[a];
                tempF = ((tempDHT[a] * 9) / 5) + 32;
            }
            else // convert current temp to fahrenheit
            {
                tempC = ((tempDHT[a] - 32) * 5) / 9;
                tempF = tempDHT[a];
            }

            if (tempF != 0)  // REMOVE THIS CHECK, ONLY USING TO TEST MEMORY AND NOT WRITE
            {
                // save chart data to csv file - celsius
                std::ofstream outfile;
                std::string path = "/var/www/html/chartData/dht_" + to_string(dht22PinID[a]) + "_C.csv";
                std::string data = logTimestamp + ", " + to_string(tempC) + "\n";
                outfile.open(path, std::ios_base::app); // append instead of overwrite
                outfile << data;
                outfile.close();
                // outfile << "8/18/2020 12:55:20, 25.34\n";

                // save chart data to csv file - fahrenheit
                path = "/var/www/html/chartData/dht_" + to_string(dht22PinID[a]) + "_F.csv";
                data = logTimestamp + ", " + to_string(tempF) + "\n";
                outfile.open(path, std::ios_base::app); // append instead of overwrite
                outfile << data;
                outfile.close();
                // outfile << "8/18/2020 12:55:20, 81.34\n";

                // check if sensor table exists in database
                MYSQL_RES *res;
                MYSQL_ROW row;
                connectMysql3();
                std::string query = "SHOW TABLES LIKE 'dht_" + to_string(dht22PinID[a]) + "_C'"; // construct query string
                mysql_query(conn3, query.c_str());                                // run query

                res = mysql_use_result(conn3);
                // std::cout << res << std::endl;
                if (mysql_fetch_row(res) == NULL) // if ds18b20 address isn't in database create a table
                {
                    // creat new table in database for ds18b20 data
                    query = "CREATE TABLE dht_" + to_string(dht22PinID[a]) + "_C (dataID int AUTO_INCREMENT, \
                                                                temp float, \
                                                                timestamp varchar(40), \
                                                                PRIMARY KEY (dataID))"; // construct query string
                    mysql_query(conn3, query.c_str());                                   // run query

                    query = "CREATE TABLE dht_" + to_string(dht22PinID[a]) + "_F (dataID int AUTO_INCREMENT, \
                                                                temp float, \
                                                                timestamp varchar(40), \
                                                                PRIMARY KEY (dataID))"; // construct query string
                    mysql_query(conn3, query.c_str());                                   // run query

                    // std::cout << "added new ds18b20 chart tables to database:" << std::endl;
                }
                // mysql_free_result(res);
                // mysql_disconnect3(); 
		// connectMysql();
		// query = "INSERT INTO lightModeDetails(modeID, pinID, lightLevel) VALUES('" + to_string(ID) + "','" + to_string(pin[a]) + "','0')";
		// mysql_query(conn, query.c_str());  // run query
    	// mysql_disconnect(); 

                // connectMysql3();
                mysql_disconnect3(); 
                connectMysql3();
                query = "INSERT INTO dht_" + to_string(dht22PinID[a]) + "_C (temp,timestamp) VALUES(" + to_string(tempC) + ",'" + logTimestamp + "')";
                    // std::cout << query << std::endl;
                mysql_query(conn3, query.c_str()); // run query
                query = "INSERT INTO dht_" + to_string(dht22PinID[a]) + "_F (temp,timestamp) VALUES(" + to_string(tempF) + ",'" + logTimestamp + "')";
                mysql_query(conn3, query.c_str()); // run query

                /* close connection */
                mysql_free_result(res);
                mysql_disconnect3(); 
            }
        }
        prevMillisDs18b20Save = currentMillisTime;
            // std::cout << "saveDS18B20Charts3" << std::endl;
    }
}

void ds18b20::deleteDS18B20(short id) {
    // std::cout << "deleteDS18B20 ---------------------------- = " << id << std::endl;

    connectMysql();
    std::string query = "DELETE FROM ds18b20 WHERE ds18b20ID = '" + to_string(id) + "'";
    mysql_query(conn, query.c_str());  // run query
    // mysql_disconnect(); 

    // std::cout << "ds18b20Saved = " << ds18b20Saved << std::endl;
    ds18b20Saved = 0;
    ds18b20Count = 0;
    short c = 0;
    std::fill_n(ds18b20IDSaved, 20, 0);  // reset array

    MYSQL_RES *res;
    MYSQL_ROW row;

    // connectMysql();
    query = "SELECT address, plugged FROM ds18b20";  // get all ds18b20 addresses stored in database
    mysql_query(conn, query.c_str());  // run query
    res = mysql_use_result(conn);

    while ((row = mysql_fetch_row(res)) != NULL)
    {
        ds18b20IDSaved[ds18b20Saved] = row[0]; // record each ds18b20 address in database
        if (row[1] == "1") {ds18b20ID[ds18b20Count] = row[0]; ds18b20Count++;}
        // std::cout << "ds18b20IDSaved = " << ds18b20IDSaved[ds18b20Saved] << std::endl;
        ds18b20Saved++; // track total found
    }
    mysql_free_result(res);
    mysql_disconnect(); 

    // for (short a = 0; a < ds18b20Count; a++) // go through each sensor plugged in one by one
    // {
    //     std::cout << "ds18b20ID[a] = " << ds18b20ID[a] << std::endl;
    // }


    // ds18b20Saved--;
    // std::cout << "ds18b20Saved = " << ds18b20Saved << std::endl;
    // std::cout << "ds18b20Count = " << ds18b20Count << std::endl;
    // ds18b20Count--;
    // std::cout << "ds18b20Count = " << ds18b20Count << std::endl;
    // prevDs18b20Count--;
    autoDetectDs18b20();
}

ds18b20 ds18b20;

