grafana / iot-sitewise-datasource

IoT Sitewise
Apache License 2.0
19 stars 9 forks source link

feat: L4E anomaly result format support #300

Closed chejimmy closed 3 months ago

chejimmy commented 3 months ago

What this PR does / why we need it:

This PR allow users to use the Grafana query builder to extract and parse L4E predictions for visualization purpose.

The video shows get property value query in action - with(out) flattening L4E anomaly result:

https://github.com/grafana/iot-sitewise-datasource/assets/50635800/f8c44e39-a4ef-4c9a-86e5-924ca4b6afe6

The video shows get property value history query in action - with(out) flattening L4E anomaly result:

https://github.com/grafana/iot-sitewise-datasource/assets/50635800/7efa9ab1-563b-451a-98c5-9ac1883c839f

The AWS/L4E_ANOMALY_RESULT asset property value is a complex data type. The key anomaly data needed from the query is stored as a complex data type, which is a JSON string with the following shape:

interface AnomalyResultAssetPropertyValue {
   quality: string;
  timestamp: {
    offsetInNanos: number;
    timeInSeconds: number;
  },
  value: {
    // The value of `stringValue` is actually a string and must be parsed.
    stringValue: {
      anomalyScore: number;
      predictionReason: string;
      diagnostics: Diagnostic[];
    }
  }
}

interface Diagnostic {
  /** Contains the property ID of the asset property being analyzed. */
   name: string;

  /** Contains the contributing factor percentage. */
  value: number;
}

The response is a flattened version of the L4E complex data type asset property value:

interface QueryResponse {
  schema: {
    fields: [
      {
        name: "time",
        type: "time",
      },
      {
        name: "quality",
        type: "string",
      },
      {
        name: "anomaly_score",
        type: "number",
      },
      {
        name: "prediction_reason",
        type: "string"
      },

      // The following properties store the contributing factor value.
      // The number of properties is dependent on the prediction instance.
      {
        name: "<diagnostic property name 1>"
        type: "number",
      },
      {
        name: "<diagnostic property name 2>"
        type: "number",
      },
    ];
  };
  data: [
    number[], // time
    string[], // quality
    number[], // anomaly score
    string[], // prediction reason
    number[], // diagnostic 1
    number[], // diagnostic 2
  ];
}

The above query response will create a table of time-series data with the following shape:

time quality anomaly_score prediction_reason "diagnostic-name-1" " diagnostic-name-2"
1 "GOOD" 0 "reason" 0 0
2 "GOOD" 0 "reason" 0 0
3 "GOOD" 0 "reason" 0 0
4 "GOOD" 0 "reason" 0 0
5 "GOOD" 0 "reason" 0 0

Which issue(s) this PR fixes:

Query for https://github.com/grafana/iot-sitewise-datasource/issues/219 without the visualization

Special notes for your reviewer:

chejimmy commented 3 months ago

Overall looks good! I had a couple questions about fetching the diagnostic names, and would it be possible to add frontend tests for the new toggle?

Applied changes regarding the comments; Regarding the frontend tests, I've added sanity tests under src/components/query/QueryEditor.test.tsx; I will I need to look into e2e 🙏 Do you think we can do a quick followup for the tests addition or should block this PR on it?