Files
@ 4556eebe5d73
Branch filter:
Location: light9/web/collector/Light9CollectorUi.ts - annotation
4556eebe5d73
2.8 KiB
video/MP2T
topdir reorgs; let pdm have its src/ dir; separate vite area from light9/
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 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 };
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");
});
const ws = new ReconnectingWebSocket(location.href.replace("http", "ws") + "../service/collector/updates");
ws.addEventListener("message", (ev: any) => {
const outputAttrsSet = JSON.parse(ev.data).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);
}
}
|