Hi:
when i use monitor.notify() to send the critic and store notification status, it throw error " runtime error @72:6-97:6: notify: failed to evaluate map function: error calling function “encode” @93:27-93:47: got table stream instead of array. Try using tableFind() or findRecord() to extract data from stream"
The code as below:
import "strings"
import "regexp"
import "json"
import "influxdata/influxdb/secrets"
import "influxdata/influxdb/schema"
import "influxdata/influxdb/monitor"
import "http"
import "experimental"
import "math"
import "date"
endtime = date.truncate(t: 2024-08-06T01:06:00Z, unit: 1s)
starttime = date.truncate(t: 2024-08-06T01:00:00Z, unit: 1s)
offsecond = duration(v: string(v: date.second(t: starttime)) + "s")
check = {_check_id: "0ccceff1f2f2e000", _check_name: "VelocityAlert", _type: "changeRate", tags: {}}
notification = {
_notification_rule_id: "0cca7d2d652ad000",
_notification_rule_name: "AnyToCrit",
_notification_endpoint_id: "0cca7ce587077000",
_notification_endpoint_name: "collectAlertNotifications",
}
roundTo = (n, precision) => {
multiplier = math.pow10(n: precision)
return math.round(x: n * multiplier) / multiplier
}
fixed = (v, p) => {
strV = string(v: v)
splitV = strings.split(v: strV, t: ".")
hasFraction = length(arr: splitV) > 1
fraction =
if hasFraction then
splitV[1] + strings.repeat(v: "0", i: p - strings.strlen(v: splitV[1]))
else
strings.repeat(v: "0", i: p)
result = if p == 0 then "${splitV[0]}" else "${splitV[0]}.${fraction}"
return result
}
data = from(bucket: "CS107")
|> range(start: date.add(d: -5m, to: starttime), stop: endtime)
|> filter(fn: (r) => r["_measurement"] == "CS107.RA-A705" and r["_field"] == "TI16")
|> aggregateWindow(every: 1m, fn: last, offset: offsecond)
|> fill(column: "_value", usePrevious: true)
|> filter(fn: (r) => r["_time"] >= starttime)
first = data |> first()
last = data |> last()
result = union(tables: [first, last])
|> map(fn: (r) => ({ r with _value: roundTo(n: r._value, precision: 3) }))
|> derivative(unit: 1h, nonNegative: false, columns: ["_value"], timeColumn: "_time")
|> map(fn: (r) => ({ r with _value: roundTo(n: math.abs(x: r._value), precision: 3) }))
|> keep(columns: ["_measurement", "_field", "_time", "_value",],)
|> to(bucket: "VelocityAlert")
derivative = result |> findRecord(fn: (key) => true, idx: 0)
trigger = (r) => r["TI16"] < 1 or r["TI16"] > 2
messageFn =
(r) =>
"{\"AlertMessage\":\"${fixed(
v: r["TI16"],
p: 2,
)}\",\"AlertTime\":\"${r._time}\",\"AlertType\":1,\"EbrCode\":\"EBR-2408050000012\",\"EquipCode\":\"CS107.RA-A705.TI16\",\"ParameterCode\":\"6a1db9ec-46b4-c70f-e77f-08dcb50d7067|1/1\",\"TagName\":\"TI16\"}"
result
|> schema["fieldsAsCols"]()
|> filter(fn: (r) => r["_measurement"] == "CS107.RA-A705")
|> monitor["check"](data: check, messageFn: messageFn, crit: trigger)
|> filter(fn: trigger)
|> monitor["notify"](
data: notification,
endpoint:
http.endpoint(
url: "https://esb-test.porton.cn/restcloud/sebriot/api/collectAlertNotifications",
)(
mapFn: (r) => {
body = {
EbrCode: "EBR-2408050000012",
ParameterCode: "6a1db9ec-46b4-c70f-e77f-08dcb50d7067|1/1",
EquipCode: "CS107.RA-A705.TI16",
AlertTime: r._time,
AlertType: 1,
AlertMessage: fixed(v: r["TI16"], p: 2),
TagName: "TI16",
First: first,
Last: last,
}
return {
headers: {"Content-Type": "application/json"},
data: json.encode(v: body),
}
},
),
)