0

List events

by
Published today

List AKIPS event records (status changes, threshold crossings, uptime resets) in a time window.

Script akips Verified

The script

Submitted by hugo989 Typescript (fetch-only)
Verified 6 hours ago
1
//native
2

3
/**
4
 * List events
5
 * List event records (status changes, threshold crossings, uptime resets) in a time window, in chronological order. The time filter uses AKIPS syntax, e.g. last1h, today, "from 2026-01-31 08:00 to 2026-01-31 17:00". AKIPS returns all matches at once; limit/offset page through them.
6
 */
7
export async function main(
8
  auth: RT.Akips,
9
  time_filter: string,
10
  event_type: "all" | "critical" | "enum" | "threshold" | "uptime" | undefined,
11
  device: string | undefined,
12
  child: string | undefined,
13
  attribute: string | undefined,
14
  group: string | undefined,
15
  limit: number | undefined,
16
  offset: number | undefined
17
) {
18
  const tf = time_filter.trim()
19
  const quotedTf = /\s/.test(tf) && !tf.startsWith('"') ? `"${tf}"` : tf
20
  let cmd = `mget event ${event_type || "all"} time ${quotedTf}`
21
  if (device || child || attribute) {
22
    cmd += ` ${device || "*"} ${child || "*"} ${attribute || "*"}`
23
  }
24
  if (group) {
25
    cmd += ` any group ${group}`
26
  }
27

28
  // A line break starts a second api-db command (§4.5.2 data), so inputs must stay on one line.
29
  if (/[\r\n]/.test(cmd)) throw new Error("api-db command must be a single line")
30

31
  // Documented form (API guide §4.5.2): password in the URL, commands in the POST body.
32
  const url = new URL(`${auth.base_url}/api-db`)
33
  url.searchParams.append("username", auth.username)
34
  url.searchParams.append("password", auth.password)
35
  const response = await fetch(url, {
36
    method: "POST",
37
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
38
    body: new URLSearchParams({ cmds: cmd }),
39
  }).catch((e) => {
40
    // Network errors quote the full URL: drop the query string, which holds the password.
41
    throw new Error(String(e).replaceAll(url.search, ""))
42
  })
43
  const text = await response.text()
44
  if (!response.ok || text.startsWith("ERROR:")) {
45
    throw new Error(`${response.status} ${text}`)
46
  }
47

48
  // Each line: "{epoch} {parent} {child} {attribute} {type} {flags} {value} [{child description}]"
49
  // value is the new enum value, the last uptime in seconds, or the threshold rule exceeded.
50
  const all = []
51
  for (const line of text.split("\n")) {
52
    const match = line.match(
53
      /^(\d+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s*(.*)$/
54
    )
55
    if (!match) continue
56
    const [, epoch, parent, childName, attr, type, flags, value, description] =
57
      match
58
    all.push({
59
      time: new Date(Number(epoch) * 1000).toISOString(),
60
      epoch: Number(epoch),
61
      device: parent,
62
      child: childName,
63
      attribute: attr,
64
      type,
65
      flags: flags.split(","),
66
      value,
67
      child_description: description || undefined,
68
    })
69
  }
70

71
  const start = offset || 0
72
  const size = limit || 500
73
  return {
74
    total: all.length,
75
    offset: start,
76
    limit: size,
77
    next_offset: start + size < all.length ? start + size : null,
78
    events: all.slice(start, start + size),
79
  }
80
}
81