{
  "productInfo" : {
    "company" : "HighByte",
    "product" : "IntelligenceHub",
    "version" : "4.5.0",
    "build" : "2026.8.14.399",
    "stage" : "Release"
  },
  "project" : {
    "version" : 14,
    "connections" : [ {
      "name" : "duckdb",
      "uri" : "jdbc://localhost:443",
      "description" : "This Connection enables the query of local parquet files and supports the PI Point historical backfill solution.",
      "tags" : [ "starter_pi_da" ],
      "writes" : {
        "flattenModeledValues" : false
      },
      "writeThrottle" : {
        "enabled" : false,
        "maxBatchSizePerTarget" : 1000,
        "batchDelay" : {
          "duration" : 20,
          "units" : "Milliseconds"
        }
      },
      "subscriptions" : { },
      "storeForward" : {
        "enabled" : false,
        "maxEntries" : 100,
        "waitOnFailureInterval" : {
          "duration" : 1,
          "units" : "Seconds"
        }
      },
      "settings" : {
        "strategy" : {
          "type" : "default"
        },
        "connectString" : "jdbc:duckdb:;memory_limit=4GB",
        "classPath" : "org.duckdb.DuckDBDriver",
        "sqlSyntax" : "postgresql",
        "database" : ""
      }
    }, {
      "name" : "file",
      "uri" : "file://file",
      "description" : "This Connection enables management of local files and supports the PI Point historical backfill solution.",
      "tags" : [ "starter_pi_da" ],
      "writes" : {
        "flattenModeledValues" : false
      },
      "writeThrottle" : {
        "enabled" : false,
        "maxBatchSizePerTarget" : 1000,
        "batchDelay" : {
          "duration" : 20,
          "units" : "Milliseconds"
        }
      },
      "subscriptions" : { },
      "storeForward" : {
        "enabled" : false,
        "maxEntries" : 100,
        "waitOnFailureInterval" : {
          "duration" : 1,
          "units" : "Seconds"
        }
      },
      "settings" : {
        "communicationProtocol" : {
          "type" : "FILE_PROTOCOL",
          "options" : { }
        },
        "directory" : "\\"
      }
    }, {
      "name" : "mqtt",
      "uri" : "mqtt://localhost:1889",
      "description" : "This is a Connection to the Intelligence Hub MQTT broker created for the purpose of viewing Pipeline outputs.",
      "tags" : [ "starter_canary", "starter_ip21", "starter_pi_af", "starter_pi_da" ],
      "writes" : {
        "flattenModeledValues" : false
      },
      "writeThrottle" : {
        "enabled" : false,
        "maxBatchSizePerTarget" : 1000,
        "batchDelay" : {
          "duration" : 20,
          "units" : "Milliseconds"
        }
      },
      "subscriptions" : { },
      "storeForward" : {
        "enabled" : false,
        "maxEntries" : 100,
        "waitOnFailureInterval" : {
          "duration" : 1,
          "units" : "Seconds"
        }
      },
      "settings" : {
        "connectionTimeoutSeconds" : 10,
        "keepAliveSeconds" : 60,
        "requestTimeoutMS" : 5000,
        "maxInflight" : 1000,
        "cleanSession" : true,
        "mcpEnabled" : "disabled",
        "ssl" : false,
        "redundantBrokers" : [ ],
        "inputDiscovery" : "",
        "clientId" : "Intelligence_Hub_Reference",
        "maxMessagesReceived" : 0
      }
    }, {
      "name" : "pi_da",
      "uri" : "osisoft.afsdk://{{System.Variables.reference_host}}:45299",
      "description" : "This is a Connection to AVEVA PI System.  The purpose of the Connection is to obtain data for starter solution examples and, specifically starter solutions related to PI Data Archive.  HighByte note: this Connection uses a dedicated agent installed on a demo system EC2.",
      "tags" : [ "starter_pi_da" ],
      "writes" : {
        "flattenModeledValues" : false
      },
      "writeThrottle" : {
        "enabled" : false,
        "maxBatchSizePerTarget" : 1000,
        "batchDelay" : {
          "duration" : 20,
          "units" : "Milliseconds"
        }
      },
      "subscriptions" : { },
      "storeForward" : {
        "enabled" : false,
        "maxEntries" : 100,
        "waitOnFailureInterval" : {
          "duration" : 1,
          "units" : "Seconds"
        }
      },
      "settings" : {
        "connectTimeoutSeconds" : 5,
        "requestTimeoutMS" : 120000,
        "compression" : "GZIP",
        "auth" : {
          "type" : "credentials",
          "username" : "osisoft",
          "password" : {
            "type" : "Reference",
            "value" : "pi_password"
          }
        },
        "password" : {
          "type" : "Reference",
          "value" : "pi_token_reference"
        }
      }
    } ],
    "inputs" : [ {
      "name" : "duckdb_input_pi_point_count",
      "connection" : "duckdb",
      "type" : "jdbc",
      "qualifier" : {
        "query" : "SELECT count(*) AS count FROM read_parquet('{{this.fileName}}') ",
        "index" : {
          "enabled" : false,
          "indexName" : "",
          "indexValue" : ""
        }
      },
      "cacheLifetime" : {
        "enabled" : false
      },
      "template" : {
        "type" : "Off"
      },
      "referenceMap" : [ ],
      "parameters" : {
        "type" : "inline",
        "model" : {
          "name" : "params",
          "tags" : [ ],
          "attributes" : [ {
            "attributeType" : "Internal",
            "name" : "fileName",
            "nullable" : false,
            "required" : false,
            "array" : false,
            "defaultValue" : "..//appData//pi.parquet",
            "internalType" : {
              "variant" : "String"
            }
          } ],
          "modelVersion" : ""
        }
      }
    }, {
      "name" : "duckdb_input_pi_point_select_transform",
      "connection" : "duckdb",
      "type" : "jdbc",
      "qualifier" : {
        "query" : "SELECT\n    name AS \"pointName\",\n    COALESCE(value_double, value_int64) AS \"valueNumber\",\n    CASE\n        WHEN value_double IS NULL AND value_int64 IS NULL\n        THEN COALESCE(value_string, CAST(value_boolean AS VARCHAR))\n    END AS \"valueOther\",\n    quality,\n    time\nFROM read_parquet('{{this.fileName}}') limit {{this.limit}} offset {{this.offset}}",
        "index" : {
          "enabled" : false,
          "indexName" : "",
          "indexValue" : ""
        }
      },
      "cacheLifetime" : {
        "enabled" : false
      },
      "template" : {
        "type" : "Off"
      },
      "referenceMap" : [ ],
      "parameters" : {
        "type" : "inline",
        "model" : {
          "name" : "params",
          "tags" : [ ],
          "attributes" : [ {
            "attributeType" : "Internal",
            "name" : "fileName",
            "nullable" : false,
            "required" : false,
            "array" : false,
            "defaultValue" : "..//appData//pi.parquet",
            "internalType" : {
              "variant" : "String"
            }
          }, {
            "attributeType" : "Internal",
            "name" : "limit",
            "nullable" : false,
            "required" : false,
            "array" : false,
            "defaultValue" : 5000,
            "internalType" : {
              "variant" : "String"
            }
          }, {
            "attributeType" : "Internal",
            "name" : "offset",
            "nullable" : false,
            "required" : false,
            "array" : false,
            "defaultValue" : 0,
            "internalType" : {
              "variant" : "String"
            }
          } ],
          "modelVersion" : ""
        }
      }
    }, {
      "name" : "mqtt_input_value_changes_asset_testValue",
      "connection" : "mqtt",
      "type" : "mqtt",
      "qualifier" : {
        "inputType" : "LastPublish",
        "payloadType" : "json",
        "qos" : 0,
        "includeTopic" : true,
        "topic" : "site/area/line/asset/testValue"
      },
      "cacheLifetime" : {
        "enabled" : false
      },
      "template" : {
        "type" : "Off"
      },
      "referenceMap" : [ ],
      "parameters" : {
        "type" : "EmptyParameters"
      }
    }, {
      "name" : "mqtt_input_value_changes_testValue",
      "connection" : "mqtt",
      "type" : "mqtt",
      "qualifier" : {
        "inputType" : "LastPublish",
        "payloadType" : "json",
        "qos" : 0,
        "topic" : "testValue",
        "includeTopic" : true
      },
      "cacheLifetime" : {
        "enabled" : false
      },
      "template" : {
        "type" : "Off"
      },
      "referenceMap" : [ ],
      "parameters" : {
        "type" : "EmptyParameters"
      }
    }, {
      "name" : "Grains_Sim_Plant_001__Reporting_Corn_Wet_Mill_KPI_Oil_in_Fiber_LI_FE_Baume",
      "connection" : "pi_da",
      "type" : "osisoft.afsdk",
      "qualifier" : {
        "type" : "assetdatapipe",
        "options" : {
          "database" : "Grains",
          "query" : "Name: 'LI.FE Baume' Parent: 'Sim Plant 001\\_Reporting\\Corn Wet Mill\\KPI\\Oil in Fiber'",
          "get" : "currentValue",
          "index" : false,
          "includeMetaData" : false,
          "includeChildren" : false,
          "indexWindow" : "",
          "subscriptionId" : "test24557272"
        }
      },
      "cacheLifetime" : {
        "enabled" : false
      },
      "template" : {
        "type" : "Off"
      },
      "referenceMap" : [ ],
      "parameters" : {
        "type" : "EmptyParameters"
      }
    }, {
      "name" : "pi_da_input_current_values",
      "connection" : "pi_da",
      "type" : "osisoft.afsdk",
      "qualifier" : {
        "type" : "point",
        "options" : {
          "get" : "currentValue",
          "includeMetaData" : false,
          "includeChildren" : true,
          "useReference" : false,
          "query" : "",
          "index" : false,
          "indexWindow" : "",
          "calcBasis" : "timeWeighted",
          "points" : [ "{{this.flow}}", "{{this.status}}" ],
          "format" : "JSON"
        }
      },
      "cacheLifetime" : {
        "enabled" : false
      },
      "template" : {
        "type" : "Off"
      },
      "referenceMap" : [ ],
      "parameters" : {
        "type" : "inline",
        "model" : {
          "name" : "params",
          "tags" : [ ],
          "attributes" : [ {
            "attributeType" : "Internal",
            "name" : "flow",
            "nullable" : false,
            "required" : false,
            "array" : false,
            "defaultValue" : "OSIDemo_Line 1.Outlet Pump.Flow Rate.71d1777b-99ae-5bcc-3123-3ca8750adb04",
            "internalType" : {
              "variant" : "String"
            }
          }, {
            "attributeType" : "Internal",
            "name" : "status",
            "nullable" : false,
            "required" : false,
            "array" : false,
            "defaultValue" : "OSIDemo_Line 1.Outlet Pump.Status.794e1043-b3b2-54ff-0364-8e5b16aaee56",
            "internalType" : {
              "variant" : "String"
            }
          } ],
          "modelVersion" : ""
        }
      }
    }, {
      "name" : "pi_da_input_metadata_points",
      "connection" : "pi_da",
      "type" : "osisoft.afsdk",
      "qualifier" : {
        "type" : "pointbrowse",
        "options" : {
          "get" : "currentValue",
          "includeMetaData" : true,
          "includeChildren" : true,
          "query" : "OSIDemo_Line*p.Flow* OR OSIDemo_Line*p.Status*",
          "index" : false,
          "indexWindow" : "",
          "additionalMetadataProperties" : [ "changedate" ]
        }
      },
      "cacheLifetime" : {
        "enabled" : false
      },
      "template" : {
        "type" : "Off"
      },
      "referenceMap" : [ ],
      "parameters" : {
        "type" : "EmptyParameters"
      }
    }, {
      "name" : "pi_da_input_point_list",
      "connection" : "pi_da",
      "type" : "osisoft.afsdk",
      "qualifier" : {
        "type" : "pointbrowse",
        "options" : {
          "get" : "currentValue",
          "includeMetaData" : false,
          "includeChildren" : true,
          "query" : "OSIDemo_Line*p.Flow* OR OSIDemo_Line*p.Status*",
          "index" : false,
          "indexWindow" : ""
        }
      },
      "cacheLifetime" : {
        "enabled" : true,
        "interval" : {
          "duration" : 1,
          "units" : "Days"
        }
      },
      "template" : {
        "type" : "Off"
      },
      "referenceMap" : [ ],
      "parameters" : {
        "type" : "EmptyParameters"
      }
    }, {
      "name" : "pi_da_input_points_for_current_values",
      "connection" : "pi_da",
      "type" : "osisoft.afsdk",
      "qualifier" : {
        "type" : "pointbrowse",
        "options" : {
          "get" : "currentValue",
          "includeMetaData" : false,
          "includeChildren" : true,
          "query" : "OSIDemo_Line 1*p.Flow* OR OSIDemo_Line 1*p.Status* OR OSIDemo_Line 2*p.Flow* OR OSIDemo_Line 2*p.Status*",
          "index" : false,
          "indexWindow" : "",
          "additionalMetadataProperties" : [ ]
        }
      },
      "cacheLifetime" : {
        "enabled" : true,
        "interval" : {
          "duration" : 1,
          "units" : "Days"
        }
      },
      "template" : {
        "type" : "Off"
      },
      "referenceMap" : [ ],
      "parameters" : {
        "type" : "EmptyParameters"
      }
    }, {
      "name" : "pi_da_input_points_for_time_span",
      "connection" : "pi_da",
      "type" : "osisoft.afsdk",
      "qualifier" : {
        "type" : "pointbrowse",
        "options" : {
          "get" : "currentValue",
          "includeMetaData" : false,
          "includeChildren" : true,
          "query" : "OSIDemo_Line*p.Flow* OR OSIDemo_Line*p.Status*",
          "index" : false,
          "indexWindow" : "",
          "additionalMetadataProperties" : [ ]
        }
      },
      "cacheLifetime" : {
        "enabled" : true,
        "interval" : {
          "duration" : 1,
          "units" : "Days"
        }
      },
      "template" : {
        "type" : "Off"
      },
      "referenceMap" : [ ],
      "parameters" : {
        "type" : "EmptyParameters"
      }
    }, {
      "name" : "pi_da_input_points_for_value_changes",
      "connection" : "pi_da",
      "type" : "osisoft.afsdk",
      "qualifier" : {
        "type" : "pointbrowse",
        "options" : {
          "get" : "currentValue",
          "includeMetaData" : false,
          "includeChildren" : true,
          "query" : "OSIDemo_Line*",
          "index" : false,
          "indexWindow" : ""
        }
      },
      "cacheLifetime" : {
        "enabled" : true,
        "interval" : {
          "duration" : 1,
          "units" : "Days"
        }
      },
      "template" : {
        "type" : "Off"
      },
      "referenceMap" : [ ],
      "parameters" : {
        "type" : "EmptyParameters"
      }
    }, {
      "name" : "pi_da_input_value_changes",
      "connection" : "pi_da",
      "type" : "osisoft.afsdk",
      "qualifier" : {
        "type" : "pointdatapipe",
        "options" : {
          "get" : "currentValue",
          "includeMetaData" : false,
          "includeChildren" : true,
          "useReference" : true,
          "maxPerRead" : 10000,
          "reference" : "{{Connection.pi_da.pi_da_input_points_for_value_changes}}",
          "subscriptionId" : "pi_da_input_value_changes_8_14",
          "query" : "",
          "index" : false,
          "indexWindow" : "",
          "format" : "JSON"
        }
      },
      "cacheLifetime" : {
        "enabled" : false
      },
      "template" : {
        "type" : "Off"
      },
      "referenceMap" : [ ],
      "parameters" : {
        "type" : "EmptyParameters"
      }
    }, {
      "name" : "pi_da_input_values_time_span",
      "connection" : "pi_da",
      "type" : "osisoft.afsdk",
      "qualifier" : {
        "type" : "point",
        "options" : {
          "get" : "rawValues",
          "includeMetaData" : true,
          "includeChildren" : true,
          "useReference" : true,
          "boundaryType" : "inside",
          "startTime" : "{{this.startTime}}",
          "endTime" : "{{this.endTime}}",
          "query" : "",
          "index" : false,
          "indexWindow" : "",
          "calcBasis" : "timeWeighted",
          "points" : [ "{{this.tagList}}]]]" ],
          "reference" : "{{Connection.pi_da.pi_da_input_points_for_time_span}}",
          "format" : "JSON"
        }
      },
      "cacheLifetime" : {
        "enabled" : false
      },
      "template" : {
        "type" : "Off"
      },
      "referenceMap" : [ ],
      "parameters" : {
        "type" : "inline",
        "model" : {
          "name" : "params",
          "tags" : [ ],
          "attributes" : [ {
            "attributeType" : "Internal",
            "name" : "startTime",
            "nullable" : false,
            "required" : false,
            "array" : false,
            "defaultValue" : "2026-08-11T15:00:00.0000000Z",
            "internalType" : {
              "variant" : "String"
            }
          }, {
            "attributeType" : "Internal",
            "name" : "endTime",
            "nullable" : false,
            "required" : false,
            "array" : false,
            "defaultValue" : "2026-08-11T15:01:00.0000000Z",
            "internalType" : {
              "variant" : "String"
            }
          } ],
          "modelVersion" : ""
        }
      }
    }, {
      "name" : "pi_da_input_values_time_span_parquet",
      "connection" : "pi_da",
      "type" : "osisoft.afsdk",
      "qualifier" : {
        "type" : "point",
        "options" : {
          "get" : "rawValues",
          "includeMetaData" : true,
          "includeChildren" : true,
          "useReference" : true,
          "boundaryType" : "inside",
          "startTime" : "{{this.startTime}}",
          "endTime" : "{{this.endTime}}",
          "query" : "",
          "index" : false,
          "indexWindow" : "",
          "calcBasis" : "timeWeighted",
          "points" : [ "{{this.tagList}}]]]" ],
          "reference" : "{{Connection.pi_da.pi_da_input_points_for_time_span}}",
          "format" : "Parquet"
        }
      },
      "cacheLifetime" : {
        "enabled" : false
      },
      "template" : {
        "type" : "Off"
      },
      "referenceMap" : [ ],
      "parameters" : {
        "type" : "inline",
        "model" : {
          "name" : "params",
          "tags" : [ ],
          "attributes" : [ {
            "attributeType" : "Internal",
            "name" : "startTime",
            "nullable" : false,
            "required" : false,
            "array" : false,
            "defaultValue" : "2025-11-01T00:00:00.000Z",
            "internalType" : {
              "variant" : "String"
            }
          }, {
            "attributeType" : "Internal",
            "name" : "endTime",
            "nullable" : false,
            "required" : false,
            "array" : false,
            "defaultValue" : "2025-11-01T01:00:00.000Z",
            "internalType" : {
              "variant" : "String"
            }
          } ],
          "modelVersion" : ""
        }
      }
    }, {
      "name" : "pi_da_input_verify_write",
      "connection" : "pi_da",
      "type" : "osisoft.afsdk",
      "qualifier" : {
        "type" : "point",
        "options" : {
          "get" : "currentValue",
          "includeMetaData" : false,
          "includeChildren" : true,
          "useReference" : false,
          "points" : [ "dynamicPath.testValue" ],
          "query" : "",
          "index" : false,
          "indexWindow" : "",
          "calcBasis" : "timeWeighted",
          "format" : "JSON"
        }
      },
      "cacheLifetime" : {
        "enabled" : false
      },
      "template" : {
        "type" : "Off"
      },
      "referenceMap" : [ ],
      "parameters" : {
        "type" : "EmptyParameters"
      }
    } ],
    "outputs" : [ {
      "name" : "pi_output_value",
      "connection" : "pi_da",
      "type" : "osisoft.afsdk",
      "qualifier" : {
        "type" : "point",
        "breakupArrays" : false,
        "options" : {
          "updateOption" : "Insert",
          "path" : "{{this.path}}",
          "timestamp" : "{{this.time}}",
          "create" : true,
          "pointSource" : "starter"
        },
        "filterList" : [ "_name", "_model", "_timestamp", "path", "time" ]
      }
    } ],
    "modeling" : {
      "models" : [ ],
      "instances" : [ ]
    },
    "conditions" : [ ],
    "functions" : [ ],
    "tags" : [ {
      "name" : "starter_pi_da"
    } ],
    "pipelines" : [ {
      "name" : "starter_output_pi_da_historical_backfill_values_to_mqtt",
      "description" : "This Pipeline executes many times to index through a time period of historical PI Point value changes.  The Pipeline obtains data from PI Data Archive and models the data before formatting it into an array.  The modeled data would typically be written to a file for a data lake or written directly to a data warehouse table.  The dates for the time period and the index interval time are stored in JavaScript Stages that must be edited.  A date is also stored as a State Variable that must be deleted to reset the Pipeline.  The solution relies on a Parquet file that is stored locally.",
      "groupAs" : "/starter_hist_historical_backfill",
      "tags" : [ "starter_pi_da" ],
      "inputStages" : [ "get_start_time" ],
      "stages" : [ {
        "name" : "set_next_start_time",
        "display" : {
          "position" : {
            "x" : 5740,
            "y" : 0
          }
        },
        "description" : "This JavaScript Stage establishes the end time for the next batch of PI Point values changes obtained from data archive. ",
        "config" : {
          "type" : ".JavaScriptTransformConfig",
          "transformExpression" : "// set NextRunStartTime pipeline state to endTime of current run.\r\nstate.pipeline.set(\"nextRunStartTime\", event.metadata.endTime);\r\n\r\nstage.setValue(event.value);"
        },
        "outputs" : [ ]
      }, {
        "name" : "check_pipeline_end",
        "display" : {
          "position" : {
            "x" : 1140,
            "y" : 0
          }
        },
        "description" : "This Switch Stage is used to determine if the Pipeline should continue to index through the overall time period.",
        "config" : {
          "type" : ".SwitchConfig",
          "switchCases" : [ {
            "expression" : "return Boolean(new Date(event.metadata.startTime) < new Date(event.metadata.pipelineEndTime))",
            "outputs" : [ "calc_end_time" ],
            "description" : "Value Is True"
          }, {
            "expression" : "return true",
            "outputs" : [ ],
            "description" : "Default"
          } ]
        },
        "outputs" : [ ]
      }, {
        "name" : "write_file",
        "display" : {
          "position" : {
            "x" : 2490,
            "y" : 0
          }
        },
        "description" : "This Stage writes the payload to a local parquet file. ",
        "config" : {
          "type" : ".DynamicWriteConfig",
          "failureOutputs" : [ ],
          "connectionReference" : "{{Connection.file}}",
          "eventPath" : "",
          "connectionType" : "file",
          "qualifier" : {
            "type" : "write",
            "fileName" : "{{event.metadata.fileName}}",
            "breakupArrays" : false
          },
          "qualifierExpression" : "",
          "writeReturn" : "completion"
        },
        "outputs" : [ "get_count" ]
      }, {
        "name" : "get_count",
        "display" : {
          "position" : {
            "x" : 2940,
            "y" : 0
          }
        },
        "description" : "This Stage queries the parquet file to determine the number of rows in the file. ",
        "config" : {
          "type" : ".ReadConfig",
          "failureOutputs" : [ ],
          "reference" : {
            "type" : "Input",
            "name" : "duckdb_input_pi_point_count",
            "path" : "",
            "params" : {
              "fileName" : "{{event.metadata.fileName}}"
            },
            "connectionName" : "duckdb"
          },
          "handleGoodNoData" : false,
          "goodNoDataOutputs" : [ ]
        },
        "outputs" : [ "count_to_metadata" ]
      }, {
        "name" : "calc_end_time",
        "display" : {
          "position" : {
            "x" : 1590,
            "y" : 0
          }
        },
        "description" : "This JavaScript Stage is used to set the time interval for each index and to calculate the end time for the current execution of the Pipeline.",
        "config" : {
          "type" : ".JavaScriptTransformConfig",
          "transformExpression" : "// intervalSeconds (1 hour)\r\nlet intervalSeconds = 60*60;\r\n\r\n// intervalMilliseconds\r\nlet intervalMilliseconds = intervalSeconds * 1000;\r\n\r\n// set startTime\r\nlet startTime = new Date(event.metadata.startTime);\r\n\r\n// set endTime\r\nlet endTime = new Date();\r\nendTime.setTime(startTime.getTime() + intervalMilliseconds);\r\n\r\n// set endTime as metadata\r\nstage.setMetadata(\"endTime\", endTime.toISOString());\r\n\r\nstage.setValue(event.value);"
        },
        "outputs" : [ "read_pi_values" ]
      }, {
        "name" : "count_to_metadata",
        "display" : {
          "position" : {
            "x" : 3390,
            "y" : 0
          }
        },
        "description" : "The row count is written to metadata.",
        "config" : {
          "type" : ".JavaScriptTransformConfig",
          "transformExpression" : "stage.setMetadata(\"count\", event.value[0].count);\r\n\r\n// Get \"count\" from pipeline state, default to 0 if it does not exist\r\nlet count = state.pipeline.get(\"count\", 0);\r\n\r\n// Increment by event.value[0].count\r\ncount += event.value[0].count;\r\n\r\n// Save the new value back to state\r\nstate.pipeline.set(\"count\", count);\r\n\r\nstage.setValue(event.value);"
        },
        "outputs" : [ "while" ]
      }, {
        "name" : "while",
        "display" : {
          "position" : {
            "x" : 3840,
            "y" : -105
          },
          "size" : {
            "width" : 1750,
            "height" : 300
          },
          "metadata" : { }
        },
        "description" : "This loop processes each batch of PI Point value changes.  ",
        "config" : {
          "type" : ".WhileLoopConfig",
          "failureOutputs" : [ ],
          "loopOutputs" : [ "limit_100k_offset" ],
          "stageTimeout" : {
            "duration" : 5,
            "units" : "Minutes"
          },
          "expression" : "return loop.metadata.count >  loop.metadata.limit * (loop.runCount - 1)",
          "loopValue" : "LAST_RETURN"
        },
        "outputs" : [ "set_next_start_time" ]
      }, {
        "name" : "set_file_name",
        "display" : {
          "position" : {
            "x" : 690,
            "y" : 0
          }
        },
        "description" : "This JavaScript Stage establishes the name of the file that the Pipeline writes to.",
        "config" : {
          "type" : ".JavaScriptTransformConfig",
          "transformExpression" : "stage.setMetadata(\"fileName\", \"../appData/pi.parquet\");\r\nstage.setValue(event.value);"
        },
        "outputs" : [ "check_pipeline_end" ]
      }, {
        "name" : "read_pi_values",
        "display" : {
          "position" : {
            "x" : 2040,
            "y" : 0
          }
        },
        "description" : "The Stage reads the value changes from PI Data Archive for the parameterized start and end time and tag list saved as a reference for the PI Connection Input.",
        "config" : {
          "type" : ".ReadConfig",
          "failureOutputs" : [ ],
          "reference" : {
            "type" : "Input",
            "name" : "pi_da_input_values_time_span_parquet",
            "path" : "",
            "params" : {
              "startTime" : "{{event.metadata.startTime}}",
              "endTime" : "{{event.metadata.endTime}}"
            },
            "connectionName" : "pi_da"
          },
          "handleGoodNoData" : false,
          "goodNoDataOutputs" : [ ]
        },
        "outputs" : [ "write_file" ]
      }, {
        "name" : "get_start_time",
        "display" : {
          "position" : {
            "x" : 240,
            "y" : 0
          }
        },
        "description" : "This JavaScript Stage is used to set the overall time period and to calculate the start time for the current execution of the Pipeline.",
        "config" : {
          "type" : ".JavaScriptTransformConfig",
          "transformExpression" : "// set initial for start time and end time\r\nlet initialStartTime = new Date('2025-11-01T00:00:00.000Z');\r\nlet pipelineEndTime = new Date('2025-11-02T00:00:00.000Z');\r\nstage.setMetadata(\"pipelineEndTime\", pipelineEndTime);\r\n// read NextRunStartTime as the state value if it exists or initialStartTime if it does not exist.\r\nlet startTime = new Date(state.pipeline.get(\"nextRunStartTime\", initialStartTime));\r\n// set startTime metadata\r\nstage.setMetadata(\"startTime\", startTime.toISOString());\r\nstage.setValue(event.value);"
        },
        "outputs" : [ "set_file_name" ]
      }, {
        "name" : "return",
        "display" : {
          "position" : {
            "x" : 1400,
            "y" : 105
          },
          "metadata" : {
            "parent" : "while"
          }
        },
        "description" : "",
        "config" : {
          "type" : ".ReturnConfig"
        },
        "outputs" : [ ]
      }, {
        "name" : "limit_100k_offset",
        "display" : {
          "position" : {
            "x" : 50,
            "y" : 105
          },
          "metadata" : {
            "parent" : "while"
          }
        },
        "description" : "This JavaScript Stage determines the parameters used to query the parquet file. ",
        "config" : {
          "type" : ".JavaScriptTransformConfig",
          "transformExpression" : "const limit = 100000;\r\nconst offset = event.metadata.loopIndex * limit;\r\nstage.setMetadata(\"limit\", limit); \r\nstage.setMetadata(\"offset\", offset);\r\nstage.setValue(event.value);"
        },
        "outputs" : [ "read_parquet" ]
      }, {
        "name" : "to_mqtt",
        "display" : {
          "position" : {
            "x" : 950,
            "y" : 105
          },
          "metadata" : {
            "parent" : "while"
          }
        },
        "description" : "In this example value change arrays are being written to the Intelligence Hub MQTT broker for ease of visibility.  ",
        "config" : {
          "type" : ".DynamicWriteConfig",
          "failureOutputs" : [ ],
          "connectionReference" : "{{Connection.mqtt}}",
          "eventPath" : "",
          "connectionType" : "mqtt",
          "qualifier" : {
            "topic" : "Historical_Backfill_PI_DA",
            "qos" : 0,
            "namedRoot" : false,
            "retained" : false,
            "breakupArrays" : false,
            "filterList" : [ "_name", "_model", "_timestamp" ]
          },
          "qualifierExpression" : "",
          "writeReturn" : "ignore"
        },
        "outputs" : [ "return" ]
      }, {
        "name" : "read_parquet",
        "display" : {
          "position" : {
            "x" : 500,
            "y" : 105
          },
          "metadata" : {
            "parent" : "while"
          }
        },
        "description" : "",
        "config" : {
          "type" : ".ReadConfig",
          "failureOutputs" : [ ],
          "reference" : {
            "type" : "Input",
            "name" : "duckdb_input_pi_point_select_transform",
            "path" : "",
            "params" : {
              "fileName" : "{{event.metadata.fileName}}",
              "limit" : "{{event.metadata.limit}} ",
              "offset" : "{{event.metadata.offset}}"
            },
            "connectionName" : "duckdb"
          },
          "handleGoodNoData" : false,
          "goodNoDataOutputs" : [ ]
        },
        "outputs" : [ "to_mqtt" ]
      } ],
      "trackActivity" : false,
      "queueSize" : 10000,
      "triggers" : [ {
        "name" : "polled_trigger",
        "display" : {
          "position" : {
            "x" : -450,
            "y" : 0
          }
        },
        "description" : "This Pipeline trigger is set to Continuous mode, so the next Pipeline execution starts as soon as the previous execution ends.",
        "config" : {
          "type" : ".TriggerPolled",
          "enabled" : false,
          "interval" : {
            "duration" : 1,
            "units" : "Seconds"
          },
          "mode" : "continuous"
        }
      } ],
      "errorHandler" : {
        "type" : "default"
      }
    } ],
    "namespace" : [ ],
    "lookupMap" : [ ],
    "servers" : {
      "i3x" : {
        "historyReadPipeline" : {
          "type" : "Empty"
        },
        "writePipeline" : {
          "type" : "Empty"
        }
      }
    }
  },
  "network" : {
    "groups" : [ ],
    "hubs" : [ ]
  }
}