Problem with virtual parameters

Problem with virtual parameters

Hello,

I have different models of routers. I want to display their serial numbers in the device tab. I’ve figured out that I need to make a virtual parameter that combines the two values for each router model.
I’ve been reading the documentation on the official site all afternoon but I can’t do it. I realized that just creating the virtual parameter wasn’t enough. But I can’t manage it.

Here’s my virtual parameter:

let m = "";
let serial1 = declare("InternetGatewayDevice.DeviceInfo.SoftwareVersion", {value: Date.now()});
let serial2 = declare("Device.DeviceInfo.SoftwareVersion", {value: Date.now()});

if (serial1.size) {
  for (let p of serial1) {
    if (p.value[0]) {
      m = p.value[0];
      break;
    }
  }
}
else if (serial2.size) {
  for (let p of serial2) {
    if (p.value[0]) {
      m = p.value[0];
      break;
    }
  }
}

Here are my default provisions:

const hourly = Date.now(3600000);

// Refresh basic parameters hourly
declare("InternetGatewayDevice.DeviceInfo.HardwareVersion", {path: hourly, value: hourly});
declare("InternetGatewayDevice.DeviceInfo.SoftwareVersion", {path: hourly, value: hourly});
declare("InternetGatewayDevice.WANDevice.*.WANConnectionDevice.*.WANIPConnection.*.MACAddress", {path: hourly, value: hourly});
declare("InternetGatewayDevice.WANDevice.*.WANConnectionDevice.*.WANIPConnection.*.ExternalIPAddress", {path: hourly, value: hourly});
declare("InternetGatewayDevice.LANDevice.*.WLANConfiguration.*.SSID", {path: hourly, value: hourly});
// Don't refresh password field periodically because CPEs always report blank passowrds for security reasons
declare("InternetGatewayDevice.LANDevice.*.WLANConfiguration.*.KeyPassphrase", {path: hourly, value: 1});
declare("InternetGatewayDevice.LANDevice.*.Hosts.Host.*.HostName", {path: hourly, value: hourly});
declare("InternetGatewayDevice.LANDevice.*.Hosts.Host.*.IPAddress", {path: hourly, value: hourly});
declare("InternetGatewayDevice.LANDevice.*.Hosts.Host.*.MACAddress", {path: hourly, value: hourly});

Here are my inform provisions:

// Device ID as user name
const username = declare("DeviceID.ID", {value: 1}).value[0]

// Password will be fixed for a given device because Math.random() is seeded with device ID by default.
const password = Math.trunc(Math.random() * Number.MAX_SAFE_INTEGER).toString(36);

const informInterval = 300;

// Refresh values daily
const daily = Date.now(86400000);

// Unique inform offset per device for better load distribution
const informTime = daily % 86400000;

declare("InternetGatewayDevice.ManagementServer.ConnectionRequestUsername", {value: daily}, {value: username});
declare("InternetGatewayDevice.ManagementServer.ConnectionRequestPassword", {value: daily}, {value: password});
declare("InternetGatewayDevice.ManagementServer.PeriodicInformEnable", {value: daily}, {value: true});
declare("InternetGatewayDevice.ManagementServer.PeriodicInformInterval", {value: daily}, {value: informInterval});
declare("InternetGatewayDevice.ManagementServer.PeriodicInformTime", {value: daily}, {value: informTime});


declare("Device.ManagementServer.ConnectionRequestUsername", {value: daily}, {value: username});
declare("Device.ManagementServer.ConnectionRequestPassword", {value: daily}, {value: password});
declare("Device.ManagementServer.PeriodicInformEnable", {value: daily}, {value: true});
declare("Device.ManagementServer.PeriodicInformInterval", {value: daily}, {value: informInterval});
declare("Device.ManagementServer.PeriodicInformTime", {value: daily}, {value: informTime});
// Paramètres Virtuels
declare("VirtualParameters.macaddress", {value: daily}, {value: informTime});
declare("VirtualParameters.serialnumber", {value: daily}, {value: informTime});

Here’s my Device page:

- label: "'Serial number'"
      parameter: VirtualParameters.serialnumber

Here’s the error:

task_64ee16e184affe1f85f5e62c script Invalid virtual parameter return value 0 29/08/2023 18:03:45

Please help me. Despite my research and numerous tests, I can’t find it. Thank’s ! :slight_smile:

You have five different issues going on. First, the device serial and mac do not change, so there is no need to refresh them daily. Second issue is the third param of the declare function is to set a parameter value, your serial number vparam isn’t writable, and even if it was, the CPE will not allow you to overwrite the serial number.

Third issue. In your vparam, you aren’t returning any values. Forth, you if you need to get the device serial you can use DeviceID.SerialNumber.

There are 4 built-in parameters that are essentially vparams. Those are:
DeviceID.SerialNumber
DeviceID.ProductClass
DeviceID.OUI
DeviceID.ID

And finally, depending on your CPE vendor, the MACAddress param can be 00:00:00:00:00:00 if the interface isn’t up. This is how several of my CPEs operate. I never use MAC for device identification. There are way to many issues. I’ve included a vparam script at the bottom to pull back the mac address that matches the one on the belly label for the CPEs in my network. You will need to investigate on your own which param is necessary for your devices.

Change the last two lines of your inform provision to:

// Paramètres Virtuels
declare("VirtualParameters.macaddress", {value: 1});
declare("VirtualParameters.serialnumber", {value: 1});

Change your vparam to:

let m = "";
let serial1 = declare("InternetGatewayDevice.DeviceInfo.SoftwareVersion", {value: Date.now()});
let serial2 = declare("Device.DeviceInfo.SoftwareVersion", {value: Date.now()});

if (serial1.size) {
  for (let p of serial1) {
    if (p.value[0]) {
      m = p.value[0];
      break;
    }
  }
}
else if (serial2.size) {
  for (let p of serial2) {
    if (p.value[0]) {
      m = p.value[0];
      break;
    }
  }
}

return {writable: false, value: [m, 'xsd:string']};

MACAddress vparam:

const modelName = declare('VirtualParameters.Model', {value: 1}).value[0];

const mapping = {
    '834-5': 'Device.Ethernet.Interface.1.MACAddress',
    'SR360n': 'InternetGatewayDevice.WANDevice.1.WANConnectionDevice.2.WANIPConnection.1.MACAddress',
    'SR510N': 'InternetGatewayDevice.WANDevice.*.WANConnectionDevice.*.WANIPConnection.[ConnectionStatus:Connected].MACAddress',
    'SR515ac': 'InternetGatewayDevice.WANDevice.*.WANConnectionDevice.*.WANIPConnection.[ConnectionStatus:Connected].MACAddress',
    'SR516ac': 'InternetGatewayDevice.WANDevice.*.WANConnectionDevice.*.WANIPConnection.[ConnectionStatus:Connected].MACAddress',
    'SR552n': 'InternetGatewayDevice.WANDevice.*.WANConnectionDevice.*.WANIPConnection.[ConnectionStatus:Connected].MACAddress',
    'SR555ac': 'InternetGatewayDevice.WANDevice.*.WANConnectionDevice.*.WANIPConnection.[ConnectionStatus:Connected].MACAddress',
    'EX3510-B0': 'Device.Ethernet.Link.3.MACAddress',
    'EX3510-B1': 'Device.Ethernet.Link.3.MACAddress',
    'VMG4927-B50A': 'Device.Ethernet.Link.[Status:Up].MACAddress',
    'EX5510-B0': 'Device.Ethernet.Link.3.MACAddress',
};

const path = mapping[modelName];

let result = "00:00:00:00:00:00";
let d = declare(path, {value: 1});

if (d.size) {
    for (let p of d) {
        if (p.value[0]) {
            result = p.value[0];
            break;
        }
    }
}

return {writable: false, value: [result, "xsd:string"]};

Model vparam:

const keys = [
    'InternetGatewayDevice.DeviceInfo.ModelName',
    'Device.DeviceInfo.ModelName'
];

return {writable: false, value: [getParameterValue(keys, ''), 'xsd:string']};

function getParameterValue(keys, def) {
    for (let key of keys) {
        let d = declare(key, {value: Date.now()});

        for (let item of d) {
            if (item.value && item.value[0]) {
                return item.value[0];
            }
        }
    }

    return def;
}
1 Like

Thank you so much for your help! I can finally display what I need and, above all, better understand what I’m doing and understand the GenieACS architecture a little better.
Thanks again!

Now I’ll try to set up some virtual parameters that I can modify, like the router’s LAN ip.

Good journey to you!

1 Like

Here is an editable vparam for the PPPoE Username you can use as a template.

let result = '';

if ("value" in args[1]) {
    result = args[1].value[0];
} else {
    let keys = [
        'InternetGatewayDevice.WANDevice.*.WANConnectionDevice.*.WANPPPConnection.*.Username',
        'Device.PPP.Interface.*.Username'
    ];

    result = getParameterValue(keys);
}

log('PPPoEUsername: ' + result);
return {writable: true, value: [result, "xsd:string"]};

function getParameterValue(keys) {
    for (let key of keys) {
        let d = declare(key, {path: Date.now() - (120 * 1000), value: Date.now()});

        for (let item of d) {
            if (item.value && item.value[0]) {
                return item.value[0];
            }
        }
    }

    return 'UNKNOWN';
}

2 Likes

Hello,
With this file, modifications are not taken into account.
Is this normal?

I’ve tried several different settings but nothing works.

The change is taken into account because the spots return green but when I refresh the elements I have the old value that appears.

When I connect to the router, the old value still appears.

Here’s an example of my configurations:

  • Vparam :
let result = '';

if ("value" in args[1]) {
    result = args[1].value[0];
} else {
    let keys = [
        'InternetGatewayDevice.LANDevice.1.WLANConfiguration.1.SSID',
        'Device.WiFi.SSID.1.SSID'
    ];

    result = getParameterValue(keys);
}

log('SSID: ' + result);
return {writable: true, value: [result, "xsd:string"]};

function getParameterValue(keys) {
    for (let key of keys) {
        let d = declare(key, {path: Date.now(), value: Date.now()});

        for (let item of d) {
            if (item.value && item.value[0]) {
                return item.value[0];
            }
        }
    }

    return 'UNKNOWN';
}

  • Inform
// Paramètres Virtuels
declare("VirtualParameters.macaddress", {value: 1});
declare("VirtualParameters.serialnumber", {value: 1});
declare("VirtualParameters.IPWAN", {value: daily}, {value: informInterval});
declare("VirtualParameters.uptime", {value: daily}, {value: informInterval});
declare("VirtualParameters.ssid", {value: 1});
declare("VirtualParameters.ssidModify", {value: 1});
declare("VirtualParameters.Model", {value: daily}, {value: informInterval});
declare("VirtualParameters.LAN", {value: daily}, {value: informInterval});
declare("VirtualParameters.dhcpaddrmin", {value: 1});
declare("VirtualParameters.dhcpaddrmax", {value: 1});
declare("VirtualParameters.dhcpenable", {value: 1});
declare("VirtualParameters.dhcpbail", {value: 1});
declare("VirtualParameters.dhcpdns", {value: 1});
declare("VirtualParameters.hardwareversion", {value: 1});
declare("VirtualParameters.softwareversion", {value: 1});
  • Device
- type: "'parameter-list'"
  parameters:
    - element: "'span.inform'"
      label: "'Last inform'"
      parameter: DATE_STRING(Events.Inform)
      type: "'container'"
      components:
        - type: "'parameter'"
        - chart: "'online'"
          type: "'overview-dot'"
        - type: "'summon-button'"
          parameters:
            - Device.DeviceInfo.X_MIKROTIK_SystemIdentity
.........
            - VirtualParameters
   - label: "'SSID'"
      parameter: VirtualParameters.ssid
.........

Thank you in advance for your help.

I don’t see any errors in the logs either:

2023-09-01T13:36:36.689Z [INFO] ::ffff:192.168.1.80 3460F9-IGD-3460F96B0C01: Inform; cpeRequestId=“1320” informEvent=“6 CONNECTION REQUEST” informRetryCount=0
2023-09-01T13:36:36.699Z [INFO] ::ffff:192.168.1.80 3460F9-IGD-3460F96B0C01: Script: IP LAN: 192.168.50.1
2023-09-01T13:36:39.694Z [INFO] ::ffff:192.168.1.80 3460F9-IGD-3460F96B0C01: Inform; cpeRequestId=“1321” informEvent=“6 CONNECTION REQUEST” informRetryCount=0
2023-09-01T13:36:39.765Z [INFO] ::ffff:192.168.1.80 3460F9-IGD-3460F96B0C01: ACS request; acsRequestId=“18a50f5c8e20000” acsRequestName=“GetParameterNames”
2023-09-01T13:36:39.769Z [INFO] ::ffff:192.168.1.80 3460F9-IGD-3460F96B0C01: ACS request; acsRequestId=“18a50f5c8e20001” acsRequestName=“GetParameterNames”
2023-09-01T13:36:39.819Z [INFO] ::ffff:192.168.1.80 3460F9-IGD-3460F96B0C01: ACS request; acsRequestId=“18a50f5c8e20002” acsRequestName=“GetParameterValues”
2023-09-01T13:36:39.938Z [INFO] ::ffff:192.168.1.80 3460F9-IGD-3460F96B0C01: Script: DHCP Addr max: 192.168.0.249
2023-09-01T13:36:39.939Z [INFO] ::ffff:192.168.1.80 3460F9-IGD-3460F96B0C01: Script: DHCP Addr min: 192.168.0.2
2023-09-01T13:36:39.940Z [INFO] ::ffff:192.168.1.80 3460F9-IGD-3460F96B0C01: Script: Bail DHCP: 7200
2023-09-01T13:36:39.940Z [INFO] ::ffff:192.168.1.80 3460F9-IGD-3460F96B0C01: Script: DHCP DNS: 0.0.0.0
2023-09-01T13:36:39.941Z [INFO] ::ffff:192.168.1.80 3460F9-IGD-3460F96B0C01: Script: Activation DHCP: true
2023-09-01T13:36:39.942Z [INFO] ::ffff:192.168.1.80 3460F9-IGD-3460F96B0C01: Script: SSID: TP-Link_0C01
2023-09-01T13:36:39.943Z [INFO] ::ffff:192.168.1.80 3460F9-IGD-3460F96B0C01: Script: IP LAN: 192.168.0.1
2023-09-01T13:37:02.129Z [INFO] ::ffff:192.168.1.30 78C57D-LTE3301%2DPLUS-S230Z12008110: Inform; cpeRequestId=“S230Z12008110” informEvent=“2 PERIODIC” informRetryCount=0
2023-09-01T13:37:03.543Z [INFO] ::ffff:81.185.175.209 CCE8AC-B535%2D333-FGX7S22510004792: Inform; cpeRequestId=“6287” informEvent=“2 PERIODIC” informRetryCount=0
2023-09-01T13:37:33.608Z [INFO] ::ffff:81.185.175.209 CCE8AC-B535%2D333-FGX7S22510004792: Inform; cpeRequestId=“6288” informEvent=“2 PERIODIC” informRetryCount=0

You should probably read up on how the declare function works. You have bad syntax.

Yes, I fix it.

Thanks