Scheduling Hourly Speed Tests with DiagnosticsState Updates

I am attempting to schedule a speed test to run every hour.

In my test environment, I use a single preset without any kind of filters.

With the following provision, everything works as expected:

const hourly = Date.now(3600000);  
const model = declare('DeviceID.ProductClass', { value: 1 }).value[0];  
declare("InternetGatewayDevice.DownloadDiagnostics.DownloadURL", { value: hourly }, { value: "http://server/speedtest" });  
declare("InternetGatewayDevice.DownloadDiagnostics.TimeBasedTestDuration", { value: hourly }, { value: "20" });  
commit();  
declare("InternetGatewayDevice.DownloadDiagnostics.DiagnosticsState", { value: hourly }, { value: "Requested" });

However, when I modify the previous provision to refresh the value of DiagnosticsState, the hourly constraint of the speed test request is no longer respected, and the speed test runs again whenever the CPE sends an event of any type.

For example:

const hourly = Date.now(3600000);  
const model = declare('DeviceID.ProductClass', { value: 1 }).value[0];  
const now = Date.now();  

declare("InternetGatewayDevice.DownloadDiagnostics.DownloadURL", { value: hourly }, { value: "http://server/speedtest" });  
declare("InternetGatewayDevice.DownloadDiagnostics.TimeBasedTestDuration", { value: hourly }, { value: "20" });  
commit();  
declare("InternetGatewayDevice.DownloadDiagnostics.DiagnosticsState", { value: hourly }, { value: "Requested" });  
commit();  
declare("InternetGatewayDevice.DownloadDiagnostics.DiagnosticsState", { path: now, value: now });

By observing the debug logs, I noticed that during the “8 DIAGNOSTICS COMPLETE” event, the ACS queries the value of DiagnosticsState. The CPE responds with “Completed,” and immediately after, the ACS sets DiagnosticsState back to “Requested.”

This causes the speed test to execute again, ignoring the one-hour constraint, leading to an infinite loop of speed tests being initiated without adhering to the intended time interval.

Why does this happen? I understand that a workaround could involve adding event filters to the preset, but I would like to understand the root cause, as this does not seem to be the expected behavior. The behavior I expect is: The speed test runs every hour, and DiagnosticsState is refreshed whenever the CPE sends an event of any type.

What is the actual problem you are trying to solve? Are you trying to run hourly speedtests to complete some sort of required government performance testing?

Yes, the actual problem is scheduling a speed test to run every X hours. I have a service that collects data directly from the GenieACS database periodically and exports it to an external service.

The issue I’m facing is that when I add a statement to refresh the DiagnosticsState value in the provision, a new speed test is initiated as soon as the previous one finishes.

There are a few ways of accomplishing this. The easiest way is to have an external system handle all the scheduling, this is how I accomplish this.

Another way would require you to create a vparam to hold the timestamp of the last test run. Then compare the value stored in this vparam and see if the difference is greater than or equal to 3_600_000 (60 [seconds / minute] * [60 minutes / hour] * 1000 [to convert to JS timestamp format), and then set the diag state to requested.

Ideally, you would be able to do this entirely inside of a provision script, but the GenieACS sandbox does not appear to expose the timestamp values at this time.

1 Like

Perfect, I will try to adopt the solution you suggested. Thank you!

Just to clarify about how GenieACS works: Do you know why the initial solution doesn’t work? It seems that GenieACS gets confused when there are two “declare” statements for the same parameter with different time constraints.

I’m honestly not sure. On first glance, this should work.

BTW, you can take out the path param in the timestamps arg.

/**
  * This causes GPN and GPV requests to the CPE every time. This is not needed
  * since the path is not transient. This increases workload on the CPE and the ACS.
  */
declare("InternetGatewayDevice.DownloadDiagnostics.DiagnosticsState", { path: now, value: now });

// Do just a GPV
declare("InternetGatewayDevice.DownloadDiagnostics.DiagnosticsState", { value: now });
1 Like