BulkData for devices without BulkData iplementation

Is there interest for a virtual BulkData tree for CPEs who don’t implement the BulkData subtree? My idea is using GenieACS as an intermediary agent for collecting each parameter defined in the profile, and then making requests to the configured profile.

I’m interested!

We already do something similar for TR143 diagnostic data. Our home-grown subscriber management system sets up the Upload/Download/IPPing/UDPEcho diagnostic. After its completed, the data is packaged up by a provision script and then sent to an extension script which then sends the data back to our subscriber management system. To work around the limitations of TR069, namely that the only information you get from the CPE is 8 DIAGNOSTIC COMPLETE I have a vparam I use to store the type of test requested and when.

Its been on my list of tasks for a while to investigate the bulk data stuff and how I can incorporate it into our subscriber management server.

I have a similar problem too. To add slat to injury some CPEs I work with don’t even show a 8 DIAGNOSTIC COMPLETE in their inform once the diagnostic is complete.

Back on topic, I have implemented a parallel data collection pipeline that I could adapt to run as a virtual BulkData client. As it is now It’s a system that runs after GenieACS’s provsions scripts. It can make several direct ACS requests to the CPE, and it doesn’t mess with Genie’s data, it’s very fast and doesn’t consumes much CPU. After it’s done, it sends the data collected to a server I configured.

I’m very interested in your solution. Do you have a repo with the work you can share?

  • Note: This branch has other modifications not related to this feature

You will need to create a file inside the analytics folder called “generated_arguments.js”
Here is a reduced version of the one I’m using right now, it collects some host data and RSSI data.

/* eslint-disable no-case-declarations */
/* eslint-disable @typescript-eslint/explicit-function-return-type */
const pathList = [

const pathListRegexMatcher = new RegExp(pathList.join("|"))

module.exports = function generateArguments(context) {
  //Analytics will run once ever 20 minutes 
  if(context.previousAnalyticsRunTimestamp > context.sessionTimestamp - (20 * 60 * 1000)){
    context.log("No need to run analytics")
    return null;

  const desiredParameterValues = []
  const analyticsExportValuyes = []

  if(!context.cpeResponse && context.analyTicsIteation !== 0){
    return null;

  switch (context.analyTicsIteation) {
    case 0:
      context.log("Asking device parameters")
      return context.generateGetParameterNames("InternetGatewayDevice.", false)
    case 1:
      context.log("Filtering parameters to ask")
      context.cpeResponse.parameterList.forEach(parameter => {
        const path = parameter[0].toString()

        if (path.match(pathListRegexMatcher)) {
          //context.log(`Adding parameter: ${path}`);

      return context.genetrateGetParameterValues(desiredParameterValues)
    case 2:
      context.cpeResponse.parameterList.forEach(parameter => {
        const path = parameter[0].toString()
        analyticsExportValuyes.push({ path: path, value: parameter[1] })

      context.log(`Exporting data ${JSON.stringify(analyticsExportValuyes)}`)
      // you should export the data collected to your server here.

      // Return null when you want to end the script
      return null;

  return null;