comparison src/FdElectricity.ts @ 16:719c8cc4d8b2

electricity report
author drewp@bigasterisk.com
date Thu, 06 Jun 2024 17:52:46 -0700
parents
children 472003015880
comparison
equal deleted inserted replaced
15:20d1fa4250c0 16:719c8cc4d8b2
1 import { LitElement, PropertyValues, css, html } from "lit";
2 import { customElement, property } from "lit/decorators.js";
3 import { shared } from "./shared";
4
5
6 @customElement("fd-electricity")
7 export class FdElectricity extends LitElement {
8 static styles = [
9 shared,
10 css`
11 :host {
12 font-size: 14px;
13 }
14
15 :host > table {
16 margin-top: 10px;
17 }
18 th {
19 text-align: left;
20 }
21 td {
22 text-align: right;
23 }
24 tr.total td,
25 tr.total th {
26 border-top: 1px solid white;
27 }
28 .bar {
29 background: yellow;
30 display: inline-block;
31 height: 10px;
32 }
33 .total .bar {
34 background: pink;
35 }
36 `,
37 ];
38 @property() seriesData: Map<string, number> = new Map();
39 constructor() {
40 super();
41 this.load();
42 setInterval(this.load.bind(this), 10 * 1000);
43 }
44 async load() {
45 this.seriesData = new Map();
46 const base = "https://bigasterisk.com/m/vmselect/select/0/prometheus/api/v1/query";
47 const now = Date.now() / 1000 - 10;
48 const seriesUrls = [
49 { url: base + `?query=powermeter_w&time=${now}&step=725ms`, label: "powermeter" },
50 { url: base + `?query=(sum%20by%20%20(s)%20(house_power_w))%20-%20(sum%20by(s)%20(powermeter_w))&time=${now}&step=725ms`, label: "unmetered" },
51 { url: base + `?query=house_power_w&time=${now}&step=725ms`, label: "total" },
52 ];
53
54 for (const series of seriesUrls) {
55 const response = await fetch(series.url);
56 const data = await response.json();
57 for (let row of data.data.result) {
58 this.seriesData.set(series.label + (row.metric.sensor ? "-" + row.metric.sensor : ""), parseFloat(row.value[1]));
59 }
60 }
61 this.update(new Map() as PropertyValues);
62 }
63 render() {
64 const disp = (n: number | undefined) => (n ? `${n.toFixed(1)}` : "");
65 const pxPerWatt = 150 / this.seriesData.get("total")!;
66 const bar = (n: number | undefined) => (n ? html`<div style="width: ${(n * pxPerWatt).toFixed(1)}px"></div>` : "");
67 return html`<h1 data-text="Electricity">Electricity</h1>
68 <table>
69 <tr>
70 <th>(unmetered)</th>
71 <td>${disp(this.seriesData.get("unmetered"))}</td>
72 <td class="bar">${bar(this.seriesData.get("unmetered"))}</td>
73 </tr>
74 <tr>
75 <th>dash</th>
76 <td>${disp(this.seriesData.get("powermeter-do_r"))}</td>
77 <td class="bar">${bar(this.seriesData.get("powermeter-do_r"))}</td>
78 </tr>
79 <tr>
80 <th>washer</th>
81 <td>${disp(this.seriesData.get("powermeter-ga_washer"))}</td>
82 <td class="bar">${bar(this.seriesData.get("powermeter-ga_washer"))}</td>
83 </tr>
84 <tr>
85 <th>fridge</th>
86 <td>${disp(this.seriesData.get("powermeter-ki_fridge"))}</td>
87 <td class="bar">${bar(this.seriesData.get("powermeter-ki_fridge"))}</td>
88 </tr>
89 <tr>
90 <th>server closet</th>
91 <td>${disp(this.seriesData.get("powermeter-st_wall"))}</td>
92 <td class="bar">${bar(this.seriesData.get("powermeter-st_wall"))}</td>
93 </tr>
94 <tr>
95 <th>theater console</th>
96 <td>${disp(this.seriesData.get("powermeter-tt_console"))}</td>
97 <td class="bar">${bar(this.seriesData.get("powermeter-tt_console"))}</td>
98 </tr>
99 <tr>
100 <th>workshop desk</th>
101 <td>${disp(this.seriesData.get("powermeter-ws_desk"))}</td>
102 <td class="bar">${bar(this.seriesData.get("powermeter-ws_desk"))}</td>
103 </tr>
104 <tr class="total">
105 <th>Total</th>
106 <td>${this.seriesData.get("total")} W</td>
107 <td class="bar">${bar(this.seriesData.get("total"))}</td>
108 </tr>
109 </table> `;
110 }
111 }