# HG changeset patch # User drewp@bigasterisk.com # Date 1653373957 25200 # Node ID 1a96f8647126de3c3ac5fc120324755e9b7d0675 # Parent 17b268d2b7f3d38448fd1a0630a3591475d20cc8 big graph & autodep porting to make collector display labels from a syncedgraph diff -r 17b268d2b7f3 -r 1a96f8647126 light9/collector/web/Light9CollectorDevice.ts --- a/light9/collector/web/Light9CollectorDevice.ts Sun May 22 03:04:18 2022 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -import * as debug from "debug"; -import { css, html, LitElement } from "lit"; -import { customElement, property } from "lit/decorators.js"; -debug.enable("*"); - -@customElement("light9-collector-device") -export class Light9CollectorDevice extends LitElement { - static styles = [ - css` - :host { - display: block; - break-inside: avoid-column; - font-size: 80%; - } - h3 { - margin-top: 12px; - margin-bottom: 0; - } - td { - white-space: nowrap; - } - - td.nonzero { - background: #310202; - color: #e25757; - } - td.full { - background: #2b0000; - color: red; - font-weight: bold; - } - `, - ]; - - render() { - return html` -

- - - - - - - -
out attrvaluechan
- `; - } - @property() graph: Object = {}; - @property() uri: Object = {}; - @property() attrs: Array = []; - - // observers: [ - // "initUpdates(updates)", - // ], - initUpdates(updates) { - updates.addListener(function (msg) { - if (msg.outputAttrsSet && msg.outputAttrsSet.dev == this.uri.value) { - this.set("attrs", msg.outputAttrsSet.attrs); - this.attrs.forEach(function (row) { - row.valClass = row.val == 255 ? "full" : row.val ? "nonzero" : ""; - }); - } - }); - } -} diff -r 17b268d2b7f3 -r 1a96f8647126 light9/collector/web/Light9CollectorUi.ts --- a/light9/collector/web/Light9CollectorUi.ts Sun May 22 03:04:18 2022 -0700 +++ b/light9/collector/web/Light9CollectorUi.ts Mon May 23 23:32:37 2022 -0700 @@ -1,75 +1,63 @@ import debug from "debug"; import { html, LitElement } from "lit"; -import { customElement, property } from "lit/decorators.js"; +import { customElement, property, state } from "lit/decorators.js"; import ReconnectingWebSocket from "reconnectingwebsocket"; import { sortBy, uniq } from "underscore"; +import { SyncedGraph } from "../../web/SyncedGraph"; +import { GraphAwarePage } from "../../web/GraphAwarePage"; +import { getTopGraph, GraphChangedEvent } from "../../web/RdfdbSyncedGraph"; +import { NamedNode } from "n3"; +import { Patch } from "../../web/patch"; +import { linkHorizontal } from "d3"; -debug.enable('*'); +export { RdfdbSyncedGraph } from "../../web/RdfdbSyncedGraph"; +export { Light9CollectorDevice } from "../../web/collector/Light9CollectorDevice"; + +debug.enable("*"); const log = debug("collector"); -class Updates { - constructor() { - this.listeners = []; - } - addListener(cb) { - this.listeners.push(cb); - } - onMessage(msg) { - this.listeners.forEach(function (lis) { - lis(msg); - }); - } -} - @customElement("light9-collector-ui") -export class Light9CollectorUi extends LitElement { +export class Light9CollectorUi extends GraphAwarePage { + graph?: SyncedGraph; static styles = []; render() { - return html` - - + return html`${super.render()}

Collector [metrics]

Devices

-
- -
+ `; + } +} + +@customElement("light9-collector-device-list") +export class Light9CollectorDeviceList extends LitElement { + graph!: SyncedGraph; + @property() devices: NamedNode[] = []; + + render() { + return html` +

Devices

+ +
${this.devices.map((d) => html``)}
`; } - - @property() graph: Object = {}; - @property() updates: Updates; - @property() devices: Array = []; - // observers: [ - // 'onGraph(graph)', - // ], - + constructor() { super(); - this.updates = new Updates(); - const ws = new ReconnectingWebSocket(location.href.replace("http", "ws") + "api/updates"); - ws.addEventListener("message", (ev: any) => { - log("ws msg", ev); - this.updates.onMessage(ev.data); + getTopGraph().then((g) => { + this.graph = g; + this.graph.runHandler(this.findDevices.bind(this), "findDevices"); }); } - - onGraph(graph) { - this.graph.runHandler(this.findDevices.bind(this), "findDevices"); - } - - findDevices() { - var U = function (x) { - return this.graph.Uri(x); - }; - this.set("devices", []); - + + findDevices(patch?: Patch) { + const U = this.graph.U(); + + this.devices = []; let classes = this.graph.subjects(U("rdf:type"), U(":DeviceClass")); uniq(sortBy(classes, "value"), true).forEach((dc) => { sortBy(this.graph.subjects(U("rdf:type"), dc), "value").forEach((dev) => { - this.push("devices", dev); + this.devices.push(dev as NamedNode); }); }); } diff -r 17b268d2b7f3 -r 1a96f8647126 light9/collector/web/index.html --- a/light9/collector/web/index.html Sun May 22 03:04:18 2022 -0700 +++ b/light9/collector/web/index.html Mon May 23 23:32:37 2022 -0700 @@ -5,7 +5,7 @@ - + - graph: [[status]] - - - - - diff -r 17b268d2b7f3 -r 1a96f8647126 light9/web/rdfdbclient.ts --- a/light9/web/rdfdbclient.ts Sun May 22 03:04:18 2022 -0700 +++ b/light9/web/rdfdbclient.ts Mon May 23 23:32:37 2022 -0700 @@ -9,10 +9,10 @@ _patchesReceived: number; _patchesSent: number; _connectionId: string; - _reconnectionTimeout: number | null; - ws: WebSocket | undefined; - _pingLoopTimeout: any; - // Send and receive patches from rdfdb + _reconnectionTimeout?: number; + ws?: WebSocket; + _pingLoopTimeout?: number; + // Send and receive patches from rdfdb. Primarily used in SyncedGraph. // // What this should do, and does not yet, is keep the graph // 'coasting' over a reconnect, applying only the diffs from the old @@ -30,7 +30,6 @@ this._patchesReceived = 0; this._patchesSent = 0; this._connectionId = "??"; - this._reconnectionTimeout = null; this.ws = undefined; this._newConnection(); @@ -63,7 +62,7 @@ } sendPatch(patch: Patch) { - log("rdfdbclient: queue patch to server ", patchSizeSummary(patch)); + log("queue patch to server ", patchSizeSummary(patch)); this._patchesToSend.push(patch); this._updateStatus(); this._continueSending(); @@ -76,35 +75,37 @@ this.ws.close(); } this.ws = new WebSocket(fullUrl); + this.ws.onopen = this.onWsOpen.bind(this); + this.ws.onerror = this.onWsError.bind(this); + this.ws.onclose = this.onWsClose.bind(this); + this.ws.onmessage = this._onMessage.bind(this); + } - this.ws.onopen = () => { - log("rdfdbclient: new connection to", fullUrl); - this._updateStatus(); - this.clearGraphOnNewConnection(); - return this._pingLoop(); - }; + private onWsOpen() { + log("new connection to", this.patchSenderUrl); + this._updateStatus(); + this.clearGraphOnNewConnection(); + return this._pingLoop(); + } - this.ws.onerror = (e: Event) => { - log("rdfdbclient: ws error " + e); - if (this.ws !== undefined) { - const closeHandler = this.ws.onclose?.bind(this.ws); - if (!closeHandler) { - throw new Error(); - } - closeHandler(new CloseEvent("forced")); + private onWsError(e: Event) { + log("ws error", e); + if (this.ws !== undefined) { + const closeHandler = this.ws.onclose?.bind(this.ws); + if (!closeHandler) { + throw new Error(); } - }; + closeHandler(new CloseEvent("forced")); + } + } - this.ws.onclose = (ev: CloseEvent) => { - log("rdfdbclient: ws close"); - this._updateStatus(); - if (this._reconnectionTimeout != null) { - clearTimeout(this._reconnectionTimeout); - } - this._reconnectionTimeout = (setTimeout(this._newConnection.bind(this), 1000) as unknown) as number; - }; - - this.ws.onmessage = this._onMessage.bind(this); + private onWsClose(ev: CloseEvent) { + log("ws close"); + this._updateStatus(); + if (this._reconnectionTimeout !== undefined) { + clearTimeout(this._reconnectionTimeout); + } + this._reconnectionTimeout = (setTimeout(this._newConnection.bind(this), 1000) as unknown) as number; } _pingLoop() { @@ -115,7 +116,7 @@ if (this._pingLoopTimeout != null) { clearTimeout(this._pingLoopTimeout); } - this._pingLoopTimeout = setTimeout(this._pingLoop.bind(this), 10000); + this._pingLoopTimeout = (setTimeout(this._pingLoop.bind(this), 10000) as unknown) as number; } } @@ -131,6 +132,7 @@ if (input.connectedAs) { this._connectionId = input.connectedAs; } else { + log("patch from server [0]") parseJsonPatch(input, this.applyPatch.bind(this)); this._patchesReceived++; } @@ -148,7 +150,7 @@ const sendOne = (patch: any, cb: (arg0: any) => any) => { return toJsonPatch(patch, (json: string) => { - log("rdfdbclient: send patch to server, " + json.length + " bytes"); + log("send patch to server, " + json.length + " bytes"); if (!this.ws) { throw new Error("can't send"); } diff -r 17b268d2b7f3 -r 1a96f8647126 light9/web/resource-display.html --- a/light9/web/resource-display.html Sun May 22 03:04:18 2022 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,158 +0,0 @@ - - - - - - - -