{
  "productInfo" : {
    "company" : "HighByte",
    "product" : "IntelligenceHub",
    "version" : "4.4.1",
    "build" : "2026.4.14.7",
    "stage" : "Release"
  },
  "project" : {
    "version" : 13,
    "connections" : [ {
      "name" : "canary_write",
      "uri" : "rest.client://canary",
      "description" : "This is a connection to the Canary Store and Forward Service API used to write data to the Canary Historian.",
      "tags" : [ "starter_canary" ],
      "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" : {
        "authentication" : {
          "type" : "Bearer Token",
          "options" : {
            "token" : "{{System.Variables.canary_token}}"
          }
        },
        "baseURL" : "https://{{System.Variables.canary_write_host_port}}/api/v1",
        "ignoreCertificate" : true
      }
    }, {
      "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"
      }
    } ],
    "inputs" : [ {
      "name" : "canary_write_input_get_session_token",
      "connection" : "canary_write",
      "type" : "rest.client",
      "qualifier" : {
        "acceptType" : "*/*",
        "method" : "POST",
        "contentType" : "application/json",
        "includeMetadata" : false,
        "endpointURL" : "/getSessionToken",
        "body" : "{\n\"historians\":[\"localhost\"],\n\"clientId\":\"starter_solution\",\n\"settings\":{\n\"clientTimeout\":300000,\n\"fileSize\":8,\n\"autoCreateDatasets\":true\n}\n}",
        "isFile" : false
      },
      "cacheLifetime" : {
        "enabled" : false
      },
      "template" : {
        "type" : "Off"
      },
      "parameters" : {
        "type" : "EmptyParameters"
      }
    }, {
      "name" : "canary_write_input_version",
      "connection" : "canary_write",
      "type" : "rest.client",
      "qualifier" : {
        "acceptType" : "*/*",
        "method" : "POST",
        "contentType" : "application/json",
        "includeMetadata" : false,
        "endpointURL" : "/version",
        "isFile" : false
      },
      "cacheLifetime" : {
        "enabled" : false
      },
      "template" : {
        "type" : "Off"
      },
      "parameters" : {
        "type" : "EmptyParameters"
      }
    }, {
      "name" : "mqtt_input_value_changes_test",
      "connection" : "mqtt",
      "type" : "mqtt",
      "qualifier" : {
        "inputType" : "LastPublish",
        "payloadType" : "json",
        "qos" : 0,
        "topic" : "testValue",
        "includeTopic" : true
      },
      "cacheLifetime" : {
        "enabled" : false
      },
      "template" : {
        "type" : "Off"
      },
      "parameters" : {
        "type" : "EmptyParameters"
      }
    } ],
    "outputs" : [ {
      "name" : "canary_write_output_value",
      "connection" : "canary_write",
      "type" : "rest.client",
      "qualifier" : {
        "method" : "POST",
        "bodyType" : "defaultjson",
        "breakupArrays" : false,
        "endpointURL" : "/storeData"
      }
    } ],
    "modeling" : {
      "models" : [ {
        "name" : "starter_write_values_canary",
        "groupAs" : "/starter_write_values",
        "tags" : [ "starter_canary" ],
        "attributes" : [ {
          "attributeType" : "Internal",
          "name" : "sessionToken",
          "nullable" : false,
          "required" : true,
          "array" : false,
          "internalType" : "String"
        }, {
          "attributeType" : "Internal",
          "name" : "tvqs",
          "nullable" : false,
          "required" : true,
          "array" : false,
          "internalType" : "Any"
        } ]
      } ],
      "instances" : [ ]
    },
    "conditions" : [ ],
    "functions" : [ ],
    "tags" : [ {
      "name" : "starter_canary"
    } ],
    "pipelines" : [ {
      "name" : "starter_output_mqtt_value_changes_canary",
      "description" : "This Pipeline obtains a value from a MQTT broker and writes the value to Canary Historian.  The Canary tag name is defined in the Pipeline.  The write to Canary requires a session token.  The Pipeline design assumes that writes are being performed every few seconds. Canary sessions are designed to be long-lived.  Once the Pipeline opens a session it holds it open.",
      "groupAs" : "/starter_hist_write_values",
      "tags" : [ "starter_canary" ],
      "inputStages" : [ "check_for_payload" ],
      "stages" : [ {
        "name" : "read_session_retry",
        "display" : {
          "position" : {
            "x" : 4290,
            "y" : 0
          }
        },
        "description" : "This Stage obtains a new session token from Canary Historian.",
        "config" : {
          "type" : ".ReadConfig",
          "failureOutputs" : [ ],
          "reference" : {
            "type" : "Input",
            "name" : "canary_write_input_get_session_token",
            "path" : "",
            "params" : { },
            "connectionName" : "canary_write"
          }
        },
        "outputs" : [ "assign_new_session_retry" ]
      }, {
        "name" : "assign_new_session",
        "display" : {
          "position" : {
            "x" : 2940,
            "y" : -45
          }
        },
        "description" : "This Stage writes the new session token to metadata and to a Pipeline state variable.",
        "config" : {
          "type" : ".JavaScriptTransformConfig",
          "transformExpression" : "let sessionToken = event.value.sessionToken;\r\nstage.setMetadata(\"session\", sessionToken);\r\nstate.pipeline.set(\"session\", sessionToken);\r\nstage.setValue(event.value);"
        },
        "outputs" : [ "apply_model" ]
      }, {
        "name" : "apply_model",
        "display" : {
          "position" : {
            "x" : 3390,
            "y" : 0
          }
        },
        "description" : "This Stage models the payload for Canary. ",
        "config" : {
          "type" : ".ModelConfig",
          "model" : "starter_write_values_canary",
          "objectName" : "",
          "initExpression" : "",
          "attributes" : [ {
            "name" : "sessionToken",
            "expression" : {
              "type" : "PipelineStageReference",
              "stageReference" : "event.metadata.session"
            }
          }, {
            "name" : "tvqs",
            "expression" : {
              "type" : "JavaScript",
              "expression" : "let time = event.timestamp;\r\nlet value = event.metadata.payload.value;\r\nlet tagName = \"Roadshow - Water District.CanaryWater.Guadalupe.Station01.Pump01.Current\";\r\n\r\nlet d = new Date(time);\r\nlet iso = d.toISOString();\r\nlet formattedTime = iso.replace(/\\.(\\d{3})Z$/, '.$10000-04:00');\r\n\r\nlet result = {};\r\nresult[tagName] = [[formattedTime, value]];\r\n\r\nreturn result;"
            }
          } ]
        },
        "outputs" : [ "to_canary" ]
      }, {
        "name" : "assign_session",
        "display" : {
          "position" : {
            "x" : 1590,
            "y" : 0
          }
        },
        "description" : "This Stage obtains the session from metadata.",
        "config" : {
          "type" : ".JavaScriptTransformConfig",
          "transformExpression" : "let noSession = \"no_session\";\r\nlet session = state.pipeline.get(\"session\", noSession);\r\nstage.setMetadata(\"session\", session);\r\nstage.setValue(event.value);"
        },
        "outputs" : [ "check_for_session" ]
      }, {
        "name" : "check_for_session",
        "display" : {
          "position" : {
            "x" : 2040,
            "y" : 0
          }
        },
        "description" : "This Stage checks for a session value.",
        "config" : {
          "type" : ".SwitchConfig",
          "switchCases" : [ {
            "expression" : "return Boolean((event.metadata.session === null || event.metadata.session === undefined || event.metadata.session === \"\" || event.metadata.session === \"no_session\"))",
            "outputs" : [ "read_session" ],
            "description" : "no session"
          }, {
            "expression" : "return true",
            "outputs" : [ "apply_model" ],
            "description" : "session"
          } ]
        },
        "outputs" : [ ]
      }, {
        "name" : "apply_model_retry",
        "display" : {
          "position" : {
            "x" : 5190,
            "y" : 0
          }
        },
        "description" : "This Stage models the payload for Canary. ",
        "config" : {
          "type" : ".ModelConfig",
          "model" : "starter_write_values_canary",
          "objectName" : "",
          "initExpression" : "",
          "attributes" : [ {
            "name" : "sessionToken",
            "expression" : {
              "type" : "PipelineStageReference",
              "stageReference" : "event.metadata.session"
            }
          }, {
            "name" : "tvqs",
            "expression" : {
              "type" : "JavaScript",
              "expression" : "let time = event.timestamp;\r\nlet value = event.metadata.payload.value;\r\nlet tagName = \"Roadshow - Water District.CanaryWater.Guadalupe.Station01.Pump01.Current\";\r\n\r\nlet d = new Date(time);\r\nlet iso = d.toISOString();\r\nlet formattedTime = iso.replace(/\\.(\\d{3})Z$/, '.$10000-04:00');\r\n\r\nlet result = {};\r\nresult[tagName] = [[formattedTime, value]];\r\n\r\nreturn result;"
            }
          } ]
        },
        "outputs" : [ "to_canary_retry" ]
      }, {
        "name" : "assign_new_session_retry",
        "display" : {
          "position" : {
            "x" : 4740,
            "y" : 0
          }
        },
        "description" : "This Stage writes the new session token to metadata and to a Pipeline state variable.",
        "config" : {
          "type" : ".JavaScriptTransformConfig",
          "transformExpression" : "let sessionToken = event.value.sessionToken;\r\nstage.setMetadata(\"session\", sessionToken);\r\nstate.pipeline.set(\"session\", sessionToken);\r\nstage.setValue(event.value);"
        },
        "outputs" : [ "apply_model_retry" ]
      }, {
        "name" : "read_session",
        "display" : {
          "position" : {
            "x" : 2490,
            "y" : -45
          }
        },
        "description" : "This Stage obtains a new session token from Canary Historian.",
        "config" : {
          "type" : ".ReadConfig",
          "failureOutputs" : [ ],
          "reference" : {
            "type" : "Input",
            "name" : "canary_write_input_get_session_token",
            "path" : "",
            "params" : { },
            "connectionName" : "canary_write"
          }
        },
        "outputs" : [ "assign_new_session" ]
      }, {
        "name" : "assign_test_value",
        "display" : {
          "position" : {
            "x" : 690,
            "y" : -45
          }
        },
        "description" : "This Stage assigns a test payload.",
        "config" : {
          "type" : ".JavaScriptTransformConfig",
          "transformExpression" : "event.value = {\r\n\t\"_topic\": \"testValue\",\r\n\t\"value\": 1\r\n}\r\nstage.setValue(event.value);"
        },
        "outputs" : [ "to_metadata" ]
      }, {
        "name" : "to_metadata",
        "display" : {
          "position" : {
            "x" : 1140,
            "y" : 0
          }
        },
        "description" : "This Stage moves the payload to metadata for downstream processing.",
        "config" : {
          "type" : ".JavaScriptTransformConfig",
          "transformExpression" : "stage.setMetadata(\"payload\", event.value);\r\nstage.setValue(event.value);"
        },
        "outputs" : [ "assign_session" ]
      }, {
        "name" : "to_canary",
        "display" : {
          "position" : {
            "x" : 3840,
            "y" : 0
          }
        },
        "description" : "This Stage writes the value to Canary for the respective tag name.",
        "config" : {
          "type" : ".WriteConfig",
          "failureOutputs" : [ "read_session_retry" ],
          "references" : [ "{{Connection.canary_write.canary_write_output_value}}" ],
          "writeReturn" : "completion"
        },
        "outputs" : [ ]
      }, {
        "name" : "to_canary_retry",
        "display" : {
          "position" : {
            "x" : 5640,
            "y" : 0
          }
        },
        "description" : "This Stage writes the value to Canary for the respective tag name.",
        "config" : {
          "type" : ".WriteConfig",
          "failureOutputs" : [ ],
          "references" : [ "{{Connection.canary_write.canary_write_output_value}}" ],
          "writeReturn" : "ignore"
        },
        "outputs" : [ ]
      }, {
        "name" : "check_for_payload",
        "display" : {
          "position" : {
            "x" : 240,
            "y" : 0
          }
        },
        "description" : "This Switch Stage is used for diagnostic purposes and allows the Pipeline to be executed on demand using a test value. ",
        "config" : {
          "type" : ".SwitchConfig",
          "switchCases" : [ {
            "expression" : "return Boolean((event.metadata.source === null || event.metadata.source === undefined || event.metadata.source === \"\"))",
            "outputs" : [ "assign_test_value" ],
            "description" : "no payload"
          }, {
            "expression" : "return true",
            "outputs" : [ "to_metadata" ],
            "description" : "payload"
          } ]
        },
        "outputs" : [ ]
      } ],
      "trackActivity" : false,
      "triggers" : [ {
        "name" : "event_trigger",
        "display" : {
          "position" : {
            "x" : -450,
            "y" : 0
          }
        },
        "description" : "The event triggers when a value is published to the topic.",
        "config" : {
          "type" : ".TriggerEvent",
          "enabled" : false,
          "reference" : {
            "type" : "Input",
            "name" : "mqtt_input_value_changes_test",
            "path" : "",
            "params" : { },
            "connectionName" : "mqtt"
          },
          "outputMode" : "ALL"
        }
      } ],
      "errorHandler" : {
        "type" : "default"
      }
    } ],
    "namespace" : [ ]
  },
  "network" : {
    "groups" : [ ],
    "hubs" : [ ]
  }
}