# POE set IP

This script allows you to set static or dynamic IP, or clear bootloader config on your OAK-POE device.

> Make sure to
> **set mask and gateway correctly!**
> If they are set incorrectly you will soft-brick your device (you won't be able to access it), and will have to
> [factory reset](https://docs.luxonis.com/hardware/platform/deploy/poe-deployment-guide.md)
> your OAK PoE.

> We suggest using
> [Device Manager](https://docs.luxonis.com/software/depthai-components/bootloader.md)
> , a GUI tool for interfacing with the bootloader and its configurations.

## Demo

Example script output:

```bash
Found device with name: 192.168.1.136
    -------------------------------------
    "1" to set a static IPv4 address
    "2" to set a dynamic IPv4 address
    "3" to clear the config
    1
    -------------------------------------
    Enter IPv4: 192.168.1.200
    Enter IPv4 Mask: 255.255.255.0
    Enter IPv4 Gateway: 192.168.1.1
    Flashing static IPv4 192.168.1.200, mask 255.255.255.0, gateway 192.168.1.1 to the POE device. Enter 'y' to confirm. y
    Flashing successful.
```

If you run the same example again after 10 seconds, you will see that IP changed to 192.168.1.200:

```bash
Found device with name: 192.168.1.200
    -------------------------------------
    "1" to set a static IPv4 address
    "2" to set a dynamic IPv4 address
    "3" to clear the config
```

You can also use the device's default IP address, which it will revert to if no DHCP server is detected. For more details on how
this works, please refer to the No DHCP section in the [Poe Deployment
Guide](https://docs.luxonis.com/hardware/platform/deploy/poe-deployment-guide.md).

## Setup

Please run the [install script](https://github.com/luxonis/depthai-python/blob/main/examples/install_requirements.py) to download
all required dependencies. Please note that this script must be ran from git context, so you have to download the
[depthai-python](https://github.com/luxonis/depthai-python) repository first and then run the script

```bash
git clone https://github.com/luxonis/depthai-python.git
cd depthai-python/examples
python3 install_requirements.py
```

For additional information, please follow the [installation guide](https://docs.luxonis.com/software/depthai/manual-install.md).

## Source code

#### Python

```python
import depthai as dai

(found, info) = dai.DeviceBootloader.getFirstAvailableDevice()

def check_str(s: str):
    spl = s.split(".")
    if len(spl) != 4:
        raise ValueError(f"Entered value {s} doesn't contain 3 dots. Value has to be in the following format: '255.255.255.255'")
    for num in spl:
        if 255 < int(num):
            raise ValueError("Entered values can't be above 255!")
    return s

if found:
    print(f'Found device with name: {info.name}')
    print('-------------------------------------')
    print('"1" to set a static IPv4 address')
    print('"2" to set a dynamic IPv4 address')
    print('"3" to clear the config')
    key = input('Enter the number: ').strip()
    print('-------------------------------------')
    if int(key) < 1 or 3 < int(key):
        raise ValueError("Entered value should either be '1', '2' or '3'!")

    with dai.DeviceBootloader(info) as bl:
        if key in ['1', '2']:
            ipv4 = check_str(input("Enter IPv4: ").strip())
            mask = check_str(input("Enter IPv4 Mask: ").strip())
            gateway = check_str(input("Enter IPv4 Gateway: ").strip())
            mode = 'static' if key == '1' else 'dynamic'
            val = input(f"Flashing {mode} IPv4 {ipv4}, mask {mask}, gateway {gateway} to the POE device. Enter 'y' to confirm. ").strip()
            if val != 'y':
                raise Exception("Flashing aborted.")

            conf = dai.DeviceBootloader.Config()
            if key == '1': conf.setStaticIPv4(ipv4, mask, gateway)
            elif key == '2': conf.setDynamicIPv4(ipv4, mask, gateway)
            (success, error) = bl.flashConfig(conf)
        elif key == '3':
            (success, error) = bl.flashConfigClear()

        if not success:
            print(f"Flashing failed: {error}")
        else:
            print(f"Flashing successful.")
```

#### C++

```cpp
#include <chrono>
#include <iostream>
#include <string>

#include "depthai/depthai.hpp"
#include "depthai/xlink/XLinkConnection.hpp"

// for string delimiter
std::vector<int> split(std::string s, std::string delimiter) {
    size_t pos_start = 0, pos_end, delim_len = delimiter.length();
    std::string token;
    std::vector<int> res;

    while((pos_end = s.find(delimiter, pos_start)) != std::string::npos) {
        token = s.substr(pos_start, pos_end - pos_start);
        pos_start = pos_end + delim_len;
        res.push_back(stoi(token));
    }
    res.push_back(stoi(s.substr(pos_start)));
    return res;
}

std::string checkStr(std::string str) {
    std::vector<int> v = split(str, ".");
    if(v.size() != 4) {
        std::cout << "Entered value " << str << " doesn't contain 3 dots. Value has to be in the following format: '255.255.255.255'" << std::endl;
        exit(0);
    }
    for(auto i : v) {
        if(i < 0 || 255 < i) {
            std::cout << "Entered values can't be above 255!" << std::endl;
            exit(0);
        }
    }
    return str;
}

int main(int argc, char** argv) {
    bool found = false;
    dai::DeviceInfo info;
    std::tie(found, info) = dai::DeviceBootloader::getFirstAvailableDevice();
    if(!found) {
        std::cout << "No device found to flash. Exiting." << std::endl;
        return -1;
    }

    std::cout << "Found device with name: " << info.getMxId() << std::endl;
    std::cout << "-------------------------------------" << std::endl;
    std::cout << "\"1\" to set a static IPv4 address" << std::endl;
    std::cout << "\"2\" to set a dynamic IPv4 address" << std::endl;
    std::cout << "\"3\" to clear the config" << std::endl;
    auto key = std::cin.get();
    std::cout << "-------------------------------------" << std::endl;

    bool success = false;
    std::string error;
    dai::DeviceBootloader bl(info, true);
    if(key == '1' || key == '2') {
        std::string ip, mask, gateway, in;

        std::cout << "Enter IPv4: ";
        std::cin >> ip;
        checkStr(ip);

        std::cout << "Enter IPv4 Mask: ";
        std::cin >> mask;
        checkStr(mask);

        std::cout << "Enter IPv4 Gateway: ";
        std::cin >> gateway;
        checkStr(gateway);

        std::string mode = "static";
        if(key == '2') mode = "dynamic";
        std::cout << "Flashing " << mode << " IPv4 " << ip << ", mask " << mask << ", gateway " << gateway << " to the POE device. Enter 'y' to confirm. ";
        std::cin >> in;
        if(in != "y") {
            std::cout << "Flashing aborted.";
            return 0;
        }
        auto conf = dai::DeviceBootloader::Config();
        if(key == '1') {
            conf.setStaticIPv4(ip, mask, gateway);
        } else {
            conf.setDynamicIPv4(ip, mask, gateway);
        }

        std::tie(success, error) = bl.flashConfig(conf);
    } else if(key == '3') {
        std::tie(success, error) = bl.flashConfigClear();
    } else {
        std::cout << "Entered value should either be '1', '2' or '3'!";
        return 0;
    }

    if(success) {
        std::cout << "Flashing successful." << std::endl;
    } else {
        std::cout << "Flashing failed: " << error << std::endl;
    }
}
```

### Need assistance?

Head over to [Discussion Forum](https://discuss.luxonis.com/) for technical support or any other questions you might have.
