
using namespace std;

class controller
{
    public:
        controller();
        void startupController();  // run at startup
        void reconfigPorts();  // runs when port configuration has changed
        void updateRoboTankVersion(short version);  // update Robo-Tank version - v1, v2 or v3
        void update1wireBus(short status, short gpio);  // enable / disable 1wire bus in /boot/config.txt file
        short getControllerVersion();  // get controller version
    private:
        short controllerVersion = 0;
        short prevControllerVersion = 0;
};
controller::controller(){}

short controller::getControllerVersion() {  // get controller version
    return controllerVersion;
}

void controller::startupController() {  // run at startup
    std::cout << " " << std::endl;
    std::cout << "startupController-------------------------" << std::endl;
    MYSQL_RES *res;
    MYSQL_ROW row;

    connectMysql();
    std::string query = "SELECT controllerVersion FROM systemSettings WHERE userID = 1";  // check if temperature should be celcuis or fehrenheit
    mysql_query(conn, query.c_str());  // run query
    res = mysql_use_result(conn);

    while ((row = mysql_fetch_row(res)) != NULL)
    {
        controllerVersion = atoi(row[0]);  // get controller version
    }
    mysql_free_result(res);
    mysql_disconnect();
    
    prevControllerVersion = controllerVersion;
    
	if (startupComplete == 0) {
        std::cout << "prevControllerVersion       - " << prevControllerVersion << std::endl;
        std::cout << "controllerVersion           - " << controllerVersion << std::endl;
    }

    for(short a=0; a < 23; a++) {  // search through all outlets
        GPIOExport(a+5);
    }
}

void controller::updateRoboTankVersion(short version) {  // update Robo-Tank version - v1, v2 or v3
    //     std::cout << "prevControllerVersion 1      - " << prevControllerVersion << std::endl;
    //     std::cout << "version                      - " << version << std::endl;
    if (version != prevControllerVersion)  // only run if version actually changed
    {
        std::cout << "updateRoboTankVersion -------------------------" << std::endl;
        prevControllerVersion = controllerVersion;
        controllerVersion = version;
        std::cout << "prevControllerVersion 2      - " << prevControllerVersion << std::endl;
        std::cout << "controllerVersion 2          - " << controllerVersion << std::endl;
        connectMysql();
        std::string query = "UPDATE systemSettings SET controllerVersion = '" + to_string(controllerVersion) + "'";
        mysql_query(conn, query.c_str());  // run query

        MYSQL_RES *res;
        MYSQL_ROW row;

        short currentPinID[40] = {};
        short currentDriverID[40] = {};
        short currentGpio[40] = {};

        // short* currentPinID = new short[40];
        // short* currentDriverID = new short[40];
        // short* currentGpio = new short[40];
        std::vector<std::string> portName;

        // short* currentPinTypeID = new short[40];  // track if mode level
        std::string newPortName = "";
        
        query = "SELECT pinID, driverID, gpio, portName\
                FROM pinsAvailable\
                WHERE driverID = 2 OR driverID = 3\
                ORDER BY driverID, GPIO ASC";
                //  ORDER BY portName ASC";
                
        mysql_query(conn, query.c_str());  // run query
        res = mysql_use_result(conn);

        short c = 0;
        while ((row = mysql_fetch_row(res)) != NULL)
        {
            currentPinID[c] = atoi(row[0]);
            currentDriverID[c] = atoi(row[1]);
            currentGpio[c] = atoi(row[2]);
            portName.push_back(row[3]);
            c++;
        }
        mysql_free_result(res);
        
        // std::cout << "Current Data -------------------------" << std::endl;
        // for (short a=0; a < 39; a++) 
        // {
        //     std::cout << a << " - " << currentDriverID[a] << " - " << currentGpio[a] << " - " << portName[a] << std::endl;
        // }

        std::string comm = "";
        
        if (controllerVersion == 0)  // version 1
        {
            // rewrite /boot/config.txt file without 1wire pins for sensor ports
            std::string line;
            ifstream in("/boot/config.txt");  // open input file
            if( !in.is_open())
            {
                cout << "Input file failed to open\n";
                return;
            }
            
            ofstream out("/boot/outfile.txt");  // open temporary output file
            while(getline(in,line))  // loop to read/write the file.
            {
                if (line.find("dtoverlay=w1-gpio,gpiopin") != std::string::npos) {}  // Line matched
                else {out << line << "\n";}  // copy line
                // out << line << "\n";
            }
            in.close();
            out.close();
            remove("/boot/config.txt");  // delete the original file
            rename("/boot/outfile.txt","/boot/config.txt");  // rename old to new

            // add possible GPIO pins to /boot/config.txt file so we can use 1wire bus
            comm = "dtoverlay=w1-gpio,gpiopin=4\n#dtoverlay=w1-gpio,gpiopin=18\n#dtoverlay=w1-gpio,gpiopin=17\n#dtoverlay=w1-gpio,gpiopin=27\n#dtoverlay=w1-gpio,gpiopin=19\n#dtoverlay=w1-gpio,gpiopin=20\n#dtoverlay=w1-gpio,gpiopin=26\n#dtoverlay=w1-gpio,gpiopin=21";
            string filename("/boot/config.txt");
            fstream file;

            file.open(filename, std::ios_base::app);
            if (file.is_open()) {file.write(comm.data(), comm.size());}

            for (short a=0; a < 39; a++)  // rearrange all pins
            {
                switch (a)
                {
                    case 0: newPortName = "Power Bar 2 - Outlet 3"; break;  // Pi GPIO 5
                    case 1: newPortName = "Power Bar 2 - Outlet 2"; break;  // Pi GPIO 6
                    case 2: newPortName = "Power Bar 2 - Outlet 4"; break;  // Pi GPIO 7
                    case 3: newPortName = "Power Bar 2 - Outlet 6"; break;  // Pi GPIO 8
                    case 4: newPortName = "Power Bar 1 - Outlet 1"; break;  // Pi GPIO 9
                    case 5: newPortName = "Power Bar 1 - Outlet 2"; break;  // Pi GPIO 10
                    case 6: newPortName = "Power Bar 2 - Outlet 5"; break;  // Pi GPIO 11
                    case 7: newPortName = "Power Bar 2 - Outlet 7"; break;  // Pi GPIO 12
                    case 8: newPortName = "Power Bar 2 - Outlet 8"; break;  // Pi GPIO 13
                    case 9: newPortName = "Power Bar 1 - Outlet 5"; break;  // Pi GPIO 14
                    case 10: newPortName = "Power Bar 1 - Outlet 4"; break;  // Pi GPIO 15
                    case 11: newPortName = "Power Bar 2 - Outlet 1"; break;  // Pi GPIO 16
                    case 12: newPortName = "Sensor Port 1"; break;  // Pi GPIO 17
                    case 13: newPortName = "DS18B20"; break;  // Pi GPIO 18
                    case 14: newPortName = "Sensor Port 3"; break;  // Pi GPIO 19
                    case 15: newPortName = "Sensor Port 4"; break;  // Pi GPIO 20
                    case 16: newPortName = "Sensor Port 6"; break;  // Pi GPIO 21
                    case 17: newPortName = "Power Bar 1 - Outlet 3"; break;  // Pi GPIO 22
                    case 18: newPortName = "Power Bar 1 - Outlet 6"; break;  // Pi GPIO 23
                    case 19: newPortName = "Power Bar 1 - Outlet 7"; break;  // Pi GPIO 24
                    case 20: newPortName = "Power Bar 1 - Outlet 8"; break;  // Pi GPIO 25
                    case 21: newPortName = "Sensor Port 5"; break;  // Pi GPIO 26
                    case 22: newPortName = "Sensor Port 2"; break;  // Pi GPIO 27
                    case 23: newPortName = "PWM / Analog Port 1"; break;  // pca9685 GPIO 0
                    case 24: newPortName = "PWM / Analog Port 2"; break;  // pca9685 GPIO 1
                    case 25: newPortName = "PWM / Analog Port 3"; break;  // pca9685 GPIO 2
                    case 26: newPortName = "PWM / Analog Port 4"; break;  // pca9685 GPIO 3
                    case 27: newPortName = "PWM / Analog Port 5"; break;  // pca9685 GPIO 4
                    case 28: newPortName = "PWM / Analog Port 6"; break;  // pca9685 GPIO 5
                    case 29: newPortName = "PWM / Analog Port 7"; break;  // pca9685 GPIO 6
                    case 30: newPortName = "PWM / Analog Port 8"; break;  // pca9685 GPIO 7
                    case 31: newPortName = "Feeder Port"; break;  // pca9685 GPIO 8
                    case 32: newPortName = "Internal Fan"; break;  // pca9685 GPIO 9  // DC port 7
                    case 33: newPortName = "DC Port 6"; break;  // pca9685 GPIO 10
                    case 34: newPortName = "DC Port 5"; break;  // pca9685 GPIO 11
                    case 35: newPortName = "DC Port 4"; break;  // pca9685 GPIO 12
                    case 36: newPortName = "DC Port 3"; break;  // pca9685 GPIO 13
                    case 37: newPortName = "DC Port 2"; break;  // pca9685 GPIO 14
                    case 38: newPortName = "DC Port 1"; break;  // pca9685 GPIO 15
                }

                std::vector<int> arrayID = getIndexes(portName, newPortName);  // find old array location so we can move driver and GPIO to correct port

                // std::cout << "Current Data -------------------------" << std::endl;
                // std::cout << arrayID[0] << " - " << currentDriverID[a] << " - " << currentGpio[a] << " - " << portName[a] << std::endl;
                // std::cout << "Updated Data -------------------------" << std::endl;
                // std::cout << a << " - " << currentDriverID[arrayID[0]] << " - " << currentGpio[arrayID[0]] << " - " << portName[a] << std::endl;
                // std::cout << "" << std::endl;

                // update record with new driverID and gpio according to controller version
                query = "UPDATE pinsAvailable\
                        SET driverID = '" + to_string(currentDriverID[a]) + "',\
                            gpio = '" + to_string(currentGpio[a]) + "'\
                        WHERE portName = '" + portName[arrayID[0]] + "'";
                mysql_query(conn, query.c_str());  // run query
            }
        }
        else if (controllerVersion == 1)  // version 2
        {
            // rewrite /boot/config.txt file without 1wire pins for sensor ports
            std::string line;
            ifstream in("/boot/config.txt");  // open input file
            if( !in.is_open())
            {
                cout << "Input file failed to open\n";
                return;
            }
            
            ofstream out("/boot/outfile.txt");  // open temporary output file
            while(getline(in,line))  // loop to read/write the file.
            {
                if (line.find("dtoverlay=w1-gpio,gpiopin") != std::string::npos) {}  // Line matched
                else {out << line << "\n";}  // copy line
                // out << line << "\n";
            }
            in.close();
            out.close();
            remove("/boot/config.txt");  // delete the original file
            rename("/boot/outfile.txt","/boot/config.txt");  // rename old to new
            
            // add possible GPIO pins to /boot/config.txt file so we can use 1wire bus
            comm = "dtoverlay=w1-gpio,gpiopin=4\ndtoverlay=w1-gpio,gpiopin=23\n#dtoverlay=w1-gpio,gpiopin=14\n#dtoverlay=w1-gpio,gpiopin=27\n#dtoverlay=w1-gpio,gpiopin=8\n#dtoverlay=w1-gpio,gpiopin=17\n#dtoverlay=w1-gpio,gpiopin=18\n#dtoverlay=w1-gpio,gpiopin=15";
            string filename("/boot/config.txt");
            fstream file;

            file.open(filename, std::ios_base::app);
            if (file.is_open()) {file.write(comm.data(), comm.size());}

            for (short a=0; a < 39; a++)  // rearrange all pins
            {
                switch (a)
                {
                    case 0: newPortName = "Power Bar 2 - Outlet 5"; break;  // Pi GPIO 5
                    case 1: newPortName = "Power Bar 1 - Outlet 6"; break;  // Pi GPIO 6
                    case 2: newPortName = "Power Bar 2 - Outlet 6"; break;  // Pi GPIO 7
                    case 3: newPortName = "Sensor Port 3"; break;  // Pi GPIO 8
                    case 4: newPortName = "Power Bar 2 - Outlet 8"; break;  // Pi GPIO 9
                    case 5: newPortName = "Power Bar 2 - Outlet 2"; break;  // Pi GPIO 10
                    case 6: newPortName = "Power Bar 2 - Outlet 7"; break;  // Pi GPIO 11
                    case 7: newPortName = "Power Bar 1 - Outlet 4"; break;  // Pi GPIO 12
                    case 8: newPortName = "Power Bar 1 - Outlet 3"; break;  // Pi GPIO 13
                    case 9: newPortName = "Sensor Port 1"; break;  // Pi GPIO 14
                    case 10: newPortName = "Sensor Port 6"; break;  // Pi GPIO 15
                    case 11: newPortName = "Power Bar 1 - Outlet 2"; break;  // Pi GPIO 16
                    case 12: newPortName = "Sensor Port 4"; break;  // Pi GPIO 17
                    case 13: newPortName = "Sensor Port 5"; break;  // Pi GPIO 18
                    case 14: newPortName = "Power Bar 1 - Outlet 7"; break;  // Pi GPIO 19
                    case 15: newPortName = "Power Bar 1 - Outlet 8"; break;  // Pi GPIO 20
                    case 16: newPortName = "Power Bar 1 - Outlet 5"; break;  // Pi GPIO 21
                    case 17: newPortName = "Power Bar 2 - Outlet 4"; break;  // Pi GPIO 22
                    case 18: newPortName = "DS18B20"; break;  // Pi GPIO 23
                    case 19: newPortName = "Power Bar 2 - Outlet 3"; break;  // Pi GPIO 24
                    case 20: newPortName = "Power Bar 2 - Outlet 1"; break;  // Pi GPIO 25
                    case 21: newPortName = "Power Bar 1 - Outlet 1"; break;  // Pi GPIO 26
                    case 22: newPortName = "Sensor Port 2"; break;  // Pi GPIO 27
                    case 23: newPortName = "Internal Fan"; break;  // pca9685 GPIO 0
                    case 24: newPortName = "DC Port 1"; break;  // pca9685 GPIO 1
                    case 25: newPortName = "DC Port 2"; break;  // pca9685 GPIO 2
                    case 26: newPortName = "DC Port 3"; break;  // pca9685 GPIO 3
                    case 27: newPortName = "DC Port 4"; break;  // pca9685 GPIO 4
                    case 28: newPortName = "DC Port 5"; break;  // pca9685 GPIO 5
                    case 29: newPortName = "DC Port 6"; break;  // pca9685 GPIO 6
                    case 30: newPortName = "Feeder Port"; break;  // pca9685 GPIO 7
                    case 31: newPortName = "PWM / Analog Port 8"; break;  // pca9685 GPIO 8
                    case 32: newPortName = "PWM / Analog Port 7"; break;  // pca9685 GPIO 9
                    case 33: newPortName = "PWM / Analog Port 6"; break;  // pca9685 GPIO 10
                    case 34: newPortName = "PWM / Analog Port 5"; break;  // pca9685 GPIO 11
                    case 35: newPortName = "PWM / Analog Port 4"; break;  // pca9685 GPIO 12
                    case 36: newPortName = "PWM / Analog Port 3"; break;  // pca9685 GPIO 13
                    case 37: newPortName = "PWM / Analog Port 2"; break;  // pca9685 GPIO 14
                    case 38: newPortName = "PWM / Analog Port 1"; break;  // pca9685 GPIO 15
                }

                std::vector<int> arrayID = getIndexes(portName, newPortName);  // find old array location so we can move driver and GPIO to correct port

                // std::cout << "Current Data -------------------------" << std::endl;
                // std::cout << arrayID[0] << " - " << currentDriverID[a] << " - " << currentGpio[a] << " - " << portName[a] << std::endl;
                // std::cout << "Updated Data -------------------------" << std::endl;
                // std::cout << a << " - " << currentDriverID[arrayID[0]] << " - " << currentGpio[arrayID[0]] << " - " << portName[a] << std::endl;
                // std::cout << "" << std::endl;

                // update record with new driverID and gpio according to controller version
                query = "UPDATE pinsAvailable\
                        SET driverID = '" + to_string(currentDriverID[a]) + "',\
                            gpio = '" + to_string(currentGpio[a]) + "'\
                        WHERE portName = '" + portName[arrayID[0]] + "'";
                mysql_query(conn, query.c_str());  // run query
            }
        }
        else if (controllerVersion == 2)  // version 3
        {
            // rewrite /boot/config.txt file without 1wire pins for sensor ports
            std::string line;
            ifstream in("/boot/config.txt");  // open input file
            if( !in.is_open())
            {
                cout << "Input file failed to open\n";
                return;
            }
            
            ofstream out("/boot/outfile.txt");  // open temporary output file
            while(getline(in,line))  // loop to read/write the file.
            {
                if (line.find("dtoverlay=w1-gpio,gpiopin") != std::string::npos) {}  // Line matched
                else {out << line << "\n";}  // copy line
                // out << line << "\n";
            }
            in.close();
            out.close();
            remove("/boot/config.txt");  // delete the original file
            rename("/boot/outfile.txt","/boot/config.txt");  // rename old to new

            // add possible GPIO pins to /boot/config.txt file so we can use 1wire bus
            comm = "dtoverlay=w1-gpio,gpiopin=4\ndtoverlay=w1-gpio,gpiopin=22\n#dtoverlay=w1-gpio,gpiopin=14\n#dtoverlay=w1-gpio,gpiopin=15\n#dtoverlay=w1-gpio,gpiopin=17\n#dtoverlay=w1-gpio,gpiopin=18\n#dtoverlay=w1-gpio,gpiopin=27\n#dtoverlay=w1-gpio,gpiopin=23";
            string filename("/boot/config.txt");
            fstream file;

            file.open(filename, std::ios_base::app);
            if (file.is_open()) {file.write(comm.data(), comm.size());}

            for (short a=0; a < 39; a++)  // rearrange all pins
            {
                switch (a)
                {
                    case 0: newPortName = "Power Bar 2 - Outlet 1"; break;  // Pi GPIO 5
                    case 1: newPortName = "Power Bar 1 - Outlet 4"; break;  // Pi GPIO 6
                    case 2: newPortName = "Power Bar 2 - Outlet 8"; break;  // Pi GPIO 7
                    case 3: newPortName = "Power Bar 2 - Outlet 7"; break;  // Pi GPIO 8
                    case 4: newPortName = "Power Bar 2 - Outlet 3"; break;  // Pi GPIO 9
                    case 5: newPortName = "Power Bar 2 - Outlet 4"; break;  // Pi GPIO 10
                    case 6: newPortName = "Power Bar 2 - Outlet 2"; break;  // Pi GPIO 11
                    case 7: newPortName = "Power Bar 1 - Outlet 5"; break;  // Pi GPIO 12
                    case 8: newPortName = "Power Bar 1 - Outlet 6"; break;  // Pi GPIO 13
                    case 9: newPortName = "Sensor Port 1"; break;  // Pi GPIO 14
                    case 10: newPortName = "Sensor Port 2"; break;  // Pi GPIO 15
                    case 11: newPortName = "Power Bar 1 - Outlet 3"; break;  // Pi GPIO 16
                    case 12: newPortName = "Sensor Port 3"; break;  // Pi GPIO 17
                    case 13: newPortName = "Sensor Port 4"; break;  // Pi GPIO 18
                    case 14: newPortName = "Power Bar 1 - Outlet 7"; break;  // Pi GPIO 19
                    case 15: newPortName = "Power Bar 1 - Outlet 2"; break;  // Pi GPIO 20
                    case 16: newPortName = "Power Bar 1 - Outlet 1"; break;  // Pi GPIO 21
                    case 17: newPortName = "DS18B20"; break;  // Pi GPIO 22
                    case 18: newPortName = "Sensor Port 6"; break;  // Pi GPIO 23
                    case 19: newPortName = "Power Bar 2 - Outlet 5"; break;  // Pi GPIO 24
                    case 20: newPortName = "Power Bar 2 - Outlet 6"; break;  // Pi GPIO 25
                    case 21: newPortName = "Power Bar 1 - Outlet 8"; break;  // Pi GPIO 26
                    case 22: newPortName = "Sensor Port 5"; break;  // Pi GPIO 27
                    case 23: newPortName = "Feeder Port"; break;  // pca9685 GPIO 0
                    case 24: newPortName = "DC Port 1"; break;  // pca9685 GPIO 1
                    case 25: newPortName = "DC Port 2"; break;  // pca9685 GPIO 2
                    case 26: newPortName = "DC Port 3"; break;  // pca9685 GPIO 3
                    case 27: newPortName = "DC Port 4"; break;  // pca9685 GPIO 4
                    case 28: newPortName = "Internal Fan"; break;  // pca9685 GPIO 5
                    case 29: newPortName = "DC Port 6"; break;  // pca9685 GPIO 6
                    case 30: newPortName = "DC Port 5"; break;  // pca9685 GPIO 7
                    case 31: newPortName = "PWM / Analog Port 2"; break;  // pca9685 GPIO 8
                    case 32: newPortName = "PWM / Analog Port 1"; break;  // pca9685 GPIO 9
                    case 33: newPortName = "PWM / Analog Port 3"; break;  // pca9685 GPIO 10
                    case 34: newPortName = "PWM / Analog Port 4"; break;  // pca9685 GPIO 11
                    case 35: newPortName = "PWM / Analog Port 5"; break;  // pca9685 GPIO 12
                    case 36: newPortName = "PWM / Analog Port 6"; break;  // pca9685 GPIO 13
                    case 37: newPortName = "PWM / Analog Port 7"; break;  // pca9685 GPIO 14
                    case 38: newPortName = "PWM / Analog Port 8"; break;  // pca9685 GPIO 15
                }

                std::vector<int> arrayID = getIndexes(portName, newPortName);  // find old array location so we can move driver and GPIO to correct port

                // std::cout << "Current Data -------------------------" << std::endl;
                // std::cout << arrayID[0] << " - " << currentDriverID[a] << " - " << currentGpio[a] << " - " << portName[a] << std::endl;
                // std::cout << "Updated Data -------------------------" << std::endl;
                // std::cout << a << " - " << currentDriverID[arrayID[0]] << " - " << currentGpio[arrayID[0]] << " - " << portName[a] << std::endl;
                // std::cout << "" << std::endl;

                // update record with new driverID and gpio according to controller version
                query = "UPDATE pinsAvailable\
                        SET driverID = '" + to_string(currentDriverID[a]) + "',\
                            gpio = '" + to_string(currentGpio[a]) + "'\
                        WHERE portName = '" + portName[arrayID[0]] + "'";
                mysql_query(conn, query.c_str());  // run query
            }
        }
        mysql_disconnect();

        std::cout << "prevControllerVersion 3      - " << prevControllerVersion << std::endl;
        std::cout << "controllerVersion 3          - " << controllerVersion << std::endl;
        systemSettings.logActivity(8,1,currentPinID[0],2,"");  // log action
        systemSettings.restart();
    }
}

void controller::reconfigPorts() {  // runs when port configuration has changed
    sensors.startupSensors();  // read sensors
    ds18b20.startupDHT22();
    lights.readLightModes();  // reload light modes
    outlets.startupACoutlets();
    dcPorts.startupDCports();
    dosing.startupDosing();
    schedules.smartStart();
}

void controller::update1wireBus(short status, short gpio) {  // enable / disable 1wire bus in /boot/config.txt file
    std::cout << "update1wireBus = " << status << " - " << gpio << std::endl;


    MYSQL_RES *res;
    MYSQL_ROW row;

    short pinID = 0;
    
    std::string query = "SELECT pinID\
            FROM pinsAvailable\
            WHERE driverID = 2 AND gpio = " + to_string(gpio);
            
    connectMysql();
    mysql_query(conn, query.c_str());  // run query
    res = mysql_use_result(conn);

    while ((row = mysql_fetch_row(res)) != NULL)
    {
        pinID = atoi(row[0]);
    }
    mysql_free_result(res);
    mysql_disconnect();

    std::cout << "pinID = " << pinID << std::endl;
    std::string comm = "";
    if (status == 0) {  // disable 1wire gpio
        systemSettings.logActivity(10,6,pinID,2,"");  // log action
        comm = "sudo sed -i 's/dtoverlay=w1-gpio,gpiopin=" + to_string(gpio) + "$/#dtoverlay=w1-gpio,gpiopin=" + to_string(gpio) + "/g' /boot/config.txt";
    }
    else if (status == 1) {  // enable 1wire gpio
        systemSettings.logActivity(9,6,pinID,2,"");  // log action
        comm = "sudo sed -i 's/#dtoverlay=w1-gpio,gpiopin=" + to_string(gpio) + "$/dtoverlay=w1-gpio,gpiopin=" + to_string(gpio) + "/g' /boot/config.txt";
    }
    system(comm.c_str());  // run command to update /boot/config.txt file for 1wire interface
    
    systemSettings.restart();
}

controller controller;

// # For more options and information see
// # http://rpf.io/configtxt
// # Some settings may impact device functionality. See link above for details

// # uncomment if you get no picture on HDMI for a default "safe" mode
// #hdmi_safe=1

// # uncomment the following to adjust overscan. Use positive numbers if console
// # goes off screen, and negative if there is too much border
// #overscan_left=16
// #overscan_right=16
// #overscan_top=16
// #overscan_bottom=16

// # uncomment to force a console size. By default it will be display's size minus
// # overscan.
// #framebuffer_width=1280
// #framebuffer_height=720

// # uncomment if hdmi display is not detected and composite is being output
// #hdmi_force_hotplug=1

// # uncomment to force a specific HDMI mode (this will force VGA)
// #hdmi_group=1
// #hdmi_mode=1

// # uncomment to force a HDMI mode rather than DVI. This can make audio work in
// # DMT (computer monitor) modes
// #hdmi_drive=2

// # uncomment to increase signal to HDMI, if you have interference, blanking, or
// # no display
// #config_hdmi_boost=4

// # uncomment for composite PAL
// #sdtv_mode=2

// #uncomment to overclock the arm. 700 MHz is the default.
// #arm_freq=800

// # Uncomment some or all of these to enable the optional hardware interfaces
// dtparam=i2c_arm=on
// dtparam=i2c_arm_baudrate=10000
// dtoverlay=pwm-2chan
// #dtparam=i2s=on
// dtparam=spi=off

// # Uncomment this to enable infrared communication.
// #dtoverlay=gpio-ir,gpio_pin=17
// #dtoverlay=gpio-ir-tx,gpio_pin=18

// # Additional overlays and parameters are documented /boot/overlays/README

// # Enable audio (loads snd_bcm2835)
// dtparam=audio=on

// # Automatically load overlays for detected cameras
// camera_auto_detect=1

// # Automatically load overlays for detected DSI displays
// display_auto_detect=1

// # Enable DRM VC4 V3D driver
// dtoverlay=vc4-kms-v3d
// max_framebuffers=2

// # Disable compensation for displays with overscan
// disable_overscan=1

// [cm4]
// # Enable host mode on the 2711 built-in XHCI USB controller.
// # This line should be removed if the legacy DWC2 controller is required
// # (e.g. for USB device mode) or if USB support is not required.
// otg_mode=1

// [all]

// [pi4]
// # Run as fast as firmware / board allows
// arm_boost=1

// [all]
// #dtoverlay=w1-gpio
// dtoverlay=w1-gpio,gpiopin=4
// dtoverlay=w1-gpio,gpiopin=22
// #dtoverlay=w1-gpio,gpiopin=14
// #dtoverlay=w1-gpio,gpiopin=15
// #dtoverlay=w1-gpio,gpiopin=17
// #dtoverlay=w1-gpio,gpiopin=18
// #dtoverlay=w1-gpio,gpiopin=27
// #dtoverlay=w1-gpio,gpiopin=23