mirror of
https://gitlab.com/wgp/dougal/software.git
synced 2025-12-06 09:57:09 +00:00
The events listener now uses a proper self-consuming queue and the event handlers have been rewritten accordingly. The way this works is that running init() on the handlers library instantiates the handlers and returns two higher-order functions, prepare() and despatch(). A call to the latter of these is appended to the queue with each new incoming event. The handlers have access to a context object (ctx) which may be used to persist data between calls and/or exchange data between handlers. This is used notably to give the handlers access to project configurations, which are themselves refreshed by a project configuration change handler (DetectProjectConfigurationChange).
89 lines
2.7 KiB
JavaScript
89 lines
2.7 KiB
JavaScript
const { schema2pid } = require('../../lib/db/connection');
|
||
const { event } = require('../../lib/db');
|
||
const { ALERT, ERROR, WARNING, NOTICE, INFO, DEBUG } = require('DOUGAL_ROOT/debug')(__filename);
|
||
|
||
class DetectSOLEOL {
|
||
|
||
author = `*${this.constructor.name}*`;
|
||
prev = null;
|
||
|
||
constructor () {
|
||
DEBUG(`${this.author} instantiated`);
|
||
}
|
||
|
||
async run (data, ctx) {
|
||
if (!data || data.channel !== "realtime") {
|
||
return;
|
||
}
|
||
|
||
if (!(data.payload && data.payload.new && data.payload.new.meta)) {
|
||
return;
|
||
}
|
||
|
||
if (!this.prev) {
|
||
DEBUG("Initialising `prev`");
|
||
this.prev = data;
|
||
return;
|
||
}
|
||
|
||
try {
|
||
DEBUG("Running");
|
||
// DEBUG("%j", data);
|
||
const cur = data?.payload?.new?.meta;
|
||
const prev = this.prev?.payload?.new?.meta;
|
||
const sequence = Number(cur._sequence);
|
||
|
||
// DEBUG("%j", prev);
|
||
// DEBUG("%j", cur);
|
||
DEBUG("prv.lineName: %s\ncur.lineName: %s\nprv._sequence: %s\ncur._sequence: %s\nprv.lineStatus: %s\ncur.lineStatus: %s", prev.lineName, cur.lineName, prev._sequence, cur._sequence, prev.lineStatus, cur.lineStatus);
|
||
|
||
if (prev.lineName == cur.lineName && prev._sequence == cur._sequence &&
|
||
prev.lineStatus != "online" && cur.lineStatus == "online" && sequence) {
|
||
INFO("Transition to ONLINE detected");
|
||
|
||
// We must use schema2pid because the pid may not have been
|
||
// populated for this event.
|
||
const projectId = await schema2pid(cur._schema ?? prev._schema);
|
||
const labels = ["FSP", "FGSP"];
|
||
const remarks = `SEQ ${cur._sequence}, SOL ${cur.lineName}, BSP: ${(cur.speed*3.6/1.852).toFixed(1)} kt, Water depth: ${Number(cur.waterDepth).toFixed(0)} m.`;
|
||
const payload = {
|
||
type: "sequence",
|
||
sequence,
|
||
point: cur._point,
|
||
remarks,
|
||
labels,
|
||
meta: {auto: true, author: `*${this.constructor.name}*`}
|
||
}
|
||
INFO("Posting event", projectId, payload);
|
||
await event.post(projectId, payload);
|
||
} else if (prev.lineName == cur.lineName && prev._sequence == cur._sequence &&
|
||
prev.lineStatus == "online" && cur.lineStatus != "online" && sequence) {
|
||
INFO("Transition to OFFLINE detected");
|
||
|
||
const projectId = await schema2pid(prev._schema ?? cur._schema);
|
||
const labels = ["LSP", "LGSP"];
|
||
const remarks = `SEQ ${cur._sequence}, EOL ${cur.lineName}, BSP: ${(cur.speed*3.6/1.852).toFixed(1)} kt, Water depth: ${Number(cur.waterDepth).toFixed(0)} m.`;
|
||
const payload = {
|
||
type: "sequence",
|
||
sequence,
|
||
point: cur._point,
|
||
remarks,
|
||
labels,
|
||
meta: {auto: true, author: `*${this.constructor.name}*`}
|
||
}
|
||
INFO("Posting event", projectId, payload);
|
||
await event.post(projectId, payload);
|
||
}
|
||
|
||
} catch (err) {
|
||
DEBUG(`${this.author} error`, err);
|
||
throw err;
|
||
} finally {
|
||
this.prev = data;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
module.exports = DetectSOLEOL;
|