Files
@ 9a4bc2ea264e
Branch filter:
Location: light9/web/collector/Light9CollectorUi.ts - annotation
9a4bc2ea264e
3.0 KiB
video/MP2T
ui tweaks and link fix
4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 ef3cde3e81e8 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 ef3cde3e81e8 ef3cde3e81e8 ef3cde3e81e8 ef3cde3e81e8 ef3cde3e81e8 ef3cde3e81e8 ef3cde3e81e8 ef3cde3e81e8 ef3cde3e81e8 ef3cde3e81e8 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 4556eebe5d73 | import debug from "debug";
import { html, LitElement } from "lit";
import { customElement, property } from "lit/decorators.js";
import { NamedNode } from "n3";
import ReconnectingWebSocket from "reconnectingwebsocket";
import { sortBy, uniq } from "underscore";
import { Patch } from "../patch";
import { getTopGraph } from "../RdfdbSyncedGraph";
import { SyncedGraph } from "../SyncedGraph";
import { Light9CollectorDevice } from "./Light9CollectorDevice";
export { RdfdbSyncedGraph } from "../RdfdbSyncedGraph";
export { Light9CollectorDevice };
import { avro } from "../lib/avro";
debug.enable("*");
const log = debug("collector");
@customElement("light9-collector-ui")
export class Light9CollectorUi extends LitElement {
graph!: SyncedGraph;
render() {
return html`<rdfdb-synced-graph></rdfdb-synced-graph>
<h1>Collector</h1>
<h2>Devices</h2>
<div style="column-width: 11em">${this.devices.map((d) => html`<light9-collector-device .uri=${d}></light9-collector-device>`)}</div> `;
}
@property() devices: NamedNode[] = [];
constructor() {
super();
getTopGraph().then((g) => {
this.graph = g;
this.graph.runHandler(this.findDevices.bind(this), "findDevices");
});
this.setupListener();
}
async setupListener() {
const CollectorUpdateType = await avro.loadType("CollectorUpdate");
const ws = new ReconnectingWebSocket(`ws://${location.host}/service/collector/updates`);
ws.addEventListener("message", async (ev: ReconnectingWebSocket.MessageEvent) => {
const jsMsg = await avro.parseBlob(CollectorUpdateType, ev.data);
const outputAttrsSet = jsMsg.OutputAttrsSet;
if (outputAttrsSet) {
this.updateDev(outputAttrsSet.dev, outputAttrsSet.attrs);
}
});
}
findDevices(patch?: Patch) {
const U = this.graph.U();
this.devices = [];
this.clearDeviceChildElementCache();
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.devices.push(dev as NamedNode);
});
});
}
deviceElements: Map<string, Light9CollectorDevice> = new Map();
clearDeviceChildElementCache() {
this.deviceElements = new Map();
}
findDeviceChildElement(uri: string): Light9CollectorDevice | undefined {
const known = this.deviceElements.get(uri);
if (known) {
return known;
}
for (const el of this.shadowRoot!.querySelectorAll("light9-collector-device")) {
const eld = el as Light9CollectorDevice;
if (eld.uri.value == uri) {
this.deviceElements.set(uri, eld);
return eld;
}
}
return undefined;
}
updateDev(uri: string, attrs: { attr: string; chan: string; val: string; valClass: string }[]) {
const el = this.findDeviceChildElement(uri);
if (!el) {
// unresolved race: updates come in before we have device elements to display them
setTimeout(() => this.updateDev(uri, attrs), 300);
return;
}
el.setAttrs(attrs);
}
}
|