0
|
1 import { LitElement, css, html } from "lit";
|
|
2 import { customElement, state } from "lit/decorators.js";
|
|
3
|
|
4 @customElement("lb-page")
|
|
5 export class LbPage extends LitElement {
|
|
6 static styles = [
|
|
7 css`
|
|
8 :host {
|
|
9 display: flex;
|
|
10 flex-direction: column;
|
|
11 height: 100vh;
|
|
12 }
|
|
13 table {
|
|
14 border-collapse: collapse;
|
|
15 }
|
|
16 td,
|
|
17 th {
|
|
18 border: 1px solid #aaa;
|
|
19 text-align: center;
|
|
20 }
|
|
21 .color {
|
|
22 display: inline-block;
|
|
23 width: 30px;
|
|
24 height: 30px;
|
|
25 border-radius: 50%;
|
|
26 margin: 3px;
|
|
27 vertical-align: middle;
|
|
28 }
|
|
29 `,
|
|
30 ];
|
|
31 @state() lights: object[] = [];
|
|
32
|
|
33 connectedCallback(): void {
|
|
34 super.connectedCallback();
|
|
35 const es = new EventSource("api/table");
|
|
36 es.onmessage = (ev) => {
|
|
37 this.lights = JSON.parse(ev.data).lights;
|
|
38 };
|
|
39 }
|
|
40 render() {
|
|
41 return html`
|
|
42 <h1>Light-bridge</h1>
|
|
43
|
|
44 <table>
|
|
45 <tr>
|
|
46 <th>light</th>
|
|
47 <th>address</th>
|
|
48 <th>online</th>
|
|
49 <th>color request</th>
|
|
50 <th>color message</th>
|
|
51 <th>color current</th>
|
|
52 <th>latency</th>
|
|
53 </tr>
|
|
54 ${this.lights.map(
|
|
55 (d: any) => html`
|
|
56 <tr>
|
|
57 <td>${d.light.name}</td>
|
|
58 <td><code>${d.light.address}</code></td>
|
|
59 <td>${d.light.online ? "✔" : ""}</td>
|
|
60 <td>
|
|
61 <code>${d.light.colorRequest}</code>
|
|
62 <input type="color" @input=${this.onColorRequest.bind(this, d.light.name)} value="${d.light.colorRequest}" />
|
|
63 </td>
|
|
64 <td><code>${JSON.stringify(d.light.colorMessage)}</code></td>
|
|
65 <td>${d.light.colorCurrent} <span class="color" style="background: ${d.light.colorCurrent}"></span></td>
|
|
66 <td>${d.light.latencyMs} ms</td>
|
|
67 </tr>
|
|
68 `
|
|
69 )}
|
|
70 </table>
|
|
71 <p>
|
|
72 <a href="metrics">metrics</a> |
|
|
73 <a href="api/graph">graph</a>
|
|
74 </p>
|
|
75 <bigast-loginbar></bigast-loginbar>
|
|
76 `;
|
|
77 }
|
|
78 onColorRequest(lightName: string, ev: InputEvent) {
|
|
79 const value = (ev.target as HTMLInputElement).value;
|
|
80 const url = new URL("api/output", location as any);
|
|
81 url.searchParams.append("light", lightName);
|
|
82 fetch(url, { method: "PUT", body: value }); // todo: only run one fetch at a time, per light
|
|
83 }
|
|
84 }
|