Setting IP address on one of the multiple found cameras

I have an issue that I can not set the IP on a specific camera - I only get the nodemap from the first device event though I use the DeviceUpdateList-command.
I want to set the IP-address to 192.168.20.51 to the camera that I found with my connection_id.
I found the camera as the 2nd camera in the deviceList. I try to do what is shown in how-to-set-a-the-ip-address-of-gev-camera-programmatically-in-cvb but something is not working as expected for me, and the IP is set on the first camera in the deviceList.

Here is my code:

logger->info("Found devices:");
for (auto &deviceInfo : deviceList)
{
    PrintDeviceInfo(deviceInfo, logger);
}

logger->info("{} available devices to connect to", deviceList.size());

for (auto t : deviceList)
{
    auto selectedCamera = SelectDevice(t, connection_id, logger);
    if (selectedCamera != nullptr)
    {
        logger->info("Camera found using {}: ", MimerUtils::ToString(t));
        PrintDeviceInfo(*selectedCamera, logger);

        std::string deviceMAC, deviceIP, nicIP;
        selectedCamera->TryGetProperty(Cvb::DiscoveryProperties::DeviceMac, deviceMAC);
        selectedCamera->TryGetProperty(Cvb::DiscoveryProperties::DeviceIP, deviceIP);
        selectedCamera->TryGetProperty(Cvb::DiscoveryProperties::InterfaceSubNetList, nicIP);
        fixMACAddress(deviceMAC);
        fixNICIP(nicIP);

        int a = 0, b = 0, c = 0, d = 0;
        sscanf(nicIP.c_str(), "%d.%d.%d.%d", &a, &b, &c, &d);

        char tmp[17];
        d = (d + auto_set_ip) & 0xFF; //New IP is same as nic with last part offsetted
        sprintf(tmp, "%d.%d.%d.%d", a, b, c, d);
        std::string ip_str(tmp);

        logger->info(" Configuration is requesting that device shall have IP {}", ip_str);
        logger->info("  DeviceMac: {}", deviceMAC);
        logger->info("  Trying to set camera IP to: {}", ip_str);

        auto access_token = selectedCamera->AccessToken();
        auto device = Cvb::DeviceFactory::Open(access_token);
        auto nodemap = device->NodeMap("TLInterface");

        // get all required nodes
        auto deviceUpdateListNode = nodemap->Node<Cvb::CommandNode>("DeviceUpdateList");
        // make node map aware of the device
        deviceUpdateListNode->Execute();

        auto deviceIDNode = nodemap->Node<Cvb::StringNode>("DeviceID");
        auto deviceMacNode = nodemap->Node<Cvb::IntegerNode>("DeviceMAC");
        auto cfgIPNode = nodemap->Node<Cvb::IntegerNode>("Cust::IPCfg_IP");
        auto cfgSubnetNode = nodemap->Node<Cvb::IntegerNode>("Cust::IPCfg_Subnet");
        auto cfgMacNode = nodemap->Node<Cvb::IntegerNode>("Cust::IPCfg_MAC");
        auto cfgForceNode = nodemap->Node<Cvb::CommandNode>("Cust::IPCfg_SetForceIP");
        auto cfgStaticNode = nodemap->Node<Cvb::CommandNode>("Cust::IPCfg_SetStatIP");

        //Diagnostic printout
        {
            auto mac_verification = deviceMacNode->Value();
            auto mac_str = macToString(mac_verification);
            std::cerr << deviceIDNode->Value() << " " << mac_str << std::endl;
        }
        {
            auto mac2 = device->NodeMap("Device")->Node<Cvb::IntegerNode>("Std::GevMACAddress")->Value();
            auto mac_str = macToString(mac2);
            std::cerr << mac_str << std::endl;
        }

        // we want to configure the found device
        cfgMacNode->SetValue(deviceMacNode->Value());
        // IP 10.0.0.1 (given that your NIC has a suitable address like 10.0.0.2)
        uint32_t ipInt = (a << 24) + (b << 16) + (c << 8) + d;
        //auto str = ipToString(ipInt);
        cfgIPNode->SetValue(ipInt);
        // Subnet 255.255.255.0
        cfgSubnetNode->SetValue(0xFFFFFF00);
        // // Force the new IP
        cfgForceNode->Execute();
        // // // make node map aware of new IP
        deviceUpdateListNode->Execute();
        // // // permanently write the IP to the camera
        cfgStaticNode->Execute();
    }
}

and the relevant output of the code:

[info] connection_id: G-KBS41D2001012
[info] Found devices:
[info] Photonfocus AG MV1-D2080-C040-160-G2-12 (SN: 072100024891, addr: 00:11:1c:f5:a8:d9/192.168.20.251) in interface 24:5e:be:4d:9a:7f/192.168.20.1.
[info] Tucsen Dhyana 401A-G (SN: G-KBS41D2001012, addr: 70:b3:d5:8a:70:0c/192.168.20.5) in interface 24:5e:be:4d:9a:7f/192.168.20.1.
[info] Tucsen Dhyana 401A-G (SN: G-KBS41D2001013, addr: 70:b3:d5:8a:70:0d/192.168.20.2) in interface 24:5e:be:4d:9a:7f/192.168.20.1.
[info] 3 available devices to connect to
[info] Camera found using DeviceId:
[info] Tucsen Dhyana 401A-G (SN: G-KBS41D2001012, addr: 70:b3:d5:8a:70:0c/192.168.20.5) in interface 24:5e:be:4d:9a:7f/192.168.20.1.
[info] Configuration is requesting that device shall have IP 192.168.20.51
[info] DeviceMac: 70:b3:d5:8a:70:0c
[info] Trying to set camera IP to: 192.168.20.51
::ID->00-11-1C-F5-A8-D9::192.168.20.251 d9:a8:f5:1c:11:00
70:b3:d5:8a:70:0c

The thing that tells me that something is malfunctioning are the two last lines in the output that I added for diagnostics.
The deviceIDNode->Value() and mac_str matches the first camera in my deviceList and not the camera that is in “device”.
The device->NodeMap(“Device”)->NodeCvb::IntergerNode(“GevMACAddress”)->Value is the correct one.

It works fine to stream images from the “device” correctly so I reckon I must do most of the things the right way.

Hi, I was pointed to this issue.

Looking at your code I have an idea: it looks as if you don’t rediscover your devices after force ip. After the force IP the camera has a new IP and all communication to it with the old data (IP address) fails. So if you change your program to

  1. Force IP all cameras to the desired IP address
  2. rediscover all devices
  3. Set persistent/static IP address to all cameras

Depending on the device forcing the IP address a while. Thus repeating the discover process until all cameras are back up is recommended.

Thank you for digging into this.
The issue is that if I only want to change IP on the second device found, it still will change the first found device. I.e I do not want to call ForceIP on the first found device just on a specific device.
The nodemap variable that I get from the device seems to be seems to pointing to the first device even though the selectedCamera is the second.

Ah, thank you for the clafication.

Then it could be that you didn’t use the Std::DeviceSelector node. The DeviceMAC, DeviceIP, … nodes are all selected. This means that the value depends on the selector index. Its default is 0 and thus the first camera.

If you set the Std::DeviceSelector to a higher number the nodes like DeviceMAC will be updated.

If you want to set the persistent/static IP, the changes described above still need to be considered, though.

I have the same problems even when I use the DeviceSelector node

selectedCamera->TryGetProperty(Cvb::DiscoveryProperties::DeviceMac, deviceMAC);

logger->debug("  DeviceIdx: {}", device_idx);
logger->info("  DeviceMac: {}", deviceMAC);
logger->info("  Trying to set camera IP to: {}", ip_str);

auto access_token = selectedCamera->AccessToken();
auto device = Cvb::DeviceFactory::Open(access_token);
auto nodemap = device->NodeMap("TLInterface");

auto deviceSelectorNode = nodemap->Node<Cvb::IntegerNode>("DeviceSelector");
deviceSelectorNode->SetValue(device_idx);
logger->trace("deviceSelectorNode->Value() = {}", deviceSelectorNode->Value());

auto deviceUpdateListNode = nodemap->Node<Cvb::CommandNode>("DeviceUpdateList");
deviceUpdateListNode->Execute();

auto deviceIDNode = nodemap->Node<Cvb::StringNode>("DeviceID");
auto deviceMacNode = nodemap->Node<Cvb::IntegerNode>("DeviceMAC");
auto cfgIPNode = nodemap->Node<Cvb::IntegerNode>("Cust::IPCfg_IP");
auto cfgSubnetNode = nodemap->Node<Cvb::IntegerNode>("Cust::IPCfg_Subnet");
auto cfgMacNode = nodemap->Node<Cvb::IntegerNode>("Cust::IPCfg_MAC");
auto cfgForceNode = nodemap->Node<Cvb::CommandNode>("Cust::IPCfg_SetForceIP");
auto cfgStaticNode = nodemap->Node<Cvb::CommandNode>("Cust::IPCfg_SetStatIP");

logger->trace("deviceIDNode->Value() = {}", deviceIDNode->Value());

auto currentMac = deviceMacNode->Value();
logger->trace("currentMac {0:d} {0:x} == {1}", currentMAC, macToString(currentMAC));

auto gevMACAddressNode = device->NodeMap("Device")->Node<Cvb::IntegerNode>("Std::GevMACAddress");
auto gevMACAddress = gevMACAddressNode->Value();
logger->trace("gevMACAddress {0:d} {0:x} == {1}", gevMACAddress, macToString(gevMACAddress));

and the relevant output of the code:

[info] Looking for mimer device with connection_id: 70:b3:d5:8a:70:1d
[info] Discovered devices:
[info] 4 available devices to connect to[info] MIMER PCB (SN: 10000002 UN: 10000002 addr: 00:80:e1:1f:00:2f/172.29.12.10) on interface ce:5d:fc:b2:5c:dc/172.29.12.1.
[info] MIMER PCB (SN: 10000012 UN: 10000012 addr: 00:80:e1:48:00:2b/172.29.12.11) on interface ce:5d:fc:b2:5c:dc/172.29.12.1.
[info] Tucsen Dhyana 401A-G (SN: G-KBS41D2004004 UN: 10000012 addr: 70:b3:d5:8a:70:16/172.29.12.3) on interface ce:5d:fc:b2:5c:dc/172.29.12.1.
[info] Tucsen Dhyana 401A-G (SN: G-KBS41D2004011 UN: 10000002 addr: 70:b3:d5:8a:70:1d/172.29.12.2) on interface ce:5d:fc:b2:5c:dc/172.29.12.1.
[info] Camera found using DeviceMAC: 70:b3:d5:8a:70:1d
[info] Tucsen Dhyana 401A-G (SN: G-KBS41D2004011 UN: 10000002 addr: 70:b3:d5:8a:70:1d/172.29.12.2) on interface ce:5d:fc:b2:5c:dc/172.29.12.1.
[info]  Configuration is requesting that device shall have IP 172.29.12.201
[debug]   DeviceIdx: 3
[info]   DeviceMac: 70:b3:d5:8a:70:1d
[info]   Trying to set camera IP to: 172.29.12.201
[trace] deviceSelectorNode->Value() = 3 
[trace] deviceIDNode->Value() = ::ID->00-80-E1-1F-00-2F::172.29.12.10 
[trace] currentMac 51677581377536 2f001fe18000 == 2f:00:1f:e1:80:00
[trace] gevMACAddress 32369202803568 1d708ad5b370 == 1d:70:8a:d5:b3:70

The deviceIDNode and currentMac are still referencing the Idx 0 GEV-device, even after I set SelectorNode to 3 (and I execute the DeviceUpdateList node).
The gevMACAddress is for reference just to show what I expect current MAC to be.

If is set the IPCfg_IP, IPCfg_Subnet and IPCfg_MAC using IPCfg_MAC 51677581377536, the Device with idx 0 GEVDevice gets the IP I try to set when calling IPCfg_SetForceIP.
If I try to do the same thing but with IPCfg_MAC 32369202803568, ie the mac from device with idx 3 nothing happens when calling IPCfg_SetForceIP.

I do not understand what I am doing wrong and why the nodes in the nodemap are referencing the device with idx 0!

Hi @jridd

I think the problem is, that you try to set the IP directly on the camera.

Instead you should open the interface, the camera is connected to (using DeviceFactory::Open) and get all the cfgXX Nodes (cfgIP, cfgMac, etc) from there.

To ensure, that the correct camera gets configured, set the Cust::IPCfg_MAC Node to the MAC of the actual camera you want to target.

Please let me know, if that helped :nerd:

2 Likes

Thank you so much for pointing out that I should open the interface.
When I changed to open the interface and setting the cfgXX Nodes using the interface, the code worked as expected (after removing stuff that became irrelevant).

I didn’t realize that I could not do that from the camera itself, but needed to be on the interface.

3 Likes