Mercurial > code > home > repos > front-door-display
diff src/FdElectricity.ts @ 16:719c8cc4d8b2
electricity report
author | drewp@bigasterisk.com |
---|---|
date | Thu, 06 Jun 2024 17:52:46 -0700 |
parents | |
children | 472003015880 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/FdElectricity.ts Thu Jun 06 17:52:46 2024 -0700 @@ -0,0 +1,111 @@ +import { LitElement, PropertyValues, css, html } from "lit"; +import { customElement, property } from "lit/decorators.js"; +import { shared } from "./shared"; + + +@customElement("fd-electricity") +export class FdElectricity extends LitElement { + static styles = [ + shared, + css` + :host { + font-size: 14px; + } + + :host > table { + margin-top: 10px; + } + th { + text-align: left; + } + td { + text-align: right; + } + tr.total td, + tr.total th { + border-top: 1px solid white; + } + .bar { + background: yellow; + display: inline-block; + height: 10px; + } + .total .bar { + background: pink; + } + `, + ]; + @property() seriesData: Map<string, number> = new Map(); + constructor() { + super(); + this.load(); + setInterval(this.load.bind(this), 10 * 1000); + } + async load() { + this.seriesData = new Map(); + const base = "https://bigasterisk.com/m/vmselect/select/0/prometheus/api/v1/query"; + const now = Date.now() / 1000 - 10; + const seriesUrls = [ + { url: base + `?query=powermeter_w&time=${now}&step=725ms`, label: "powermeter" }, + { 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" }, + { url: base + `?query=house_power_w&time=${now}&step=725ms`, label: "total" }, + ]; + + for (const series of seriesUrls) { + const response = await fetch(series.url); + const data = await response.json(); + for (let row of data.data.result) { + this.seriesData.set(series.label + (row.metric.sensor ? "-" + row.metric.sensor : ""), parseFloat(row.value[1])); + } + } + this.update(new Map() as PropertyValues); + } + render() { + const disp = (n: number | undefined) => (n ? `${n.toFixed(1)}` : ""); + const pxPerWatt = 150 / this.seriesData.get("total")!; + const bar = (n: number | undefined) => (n ? html`<div style="width: ${(n * pxPerWatt).toFixed(1)}px"></div>` : ""); + return html`<h1 data-text="Electricity">Electricity</h1> + <table> + <tr> + <th>(unmetered)</th> + <td>${disp(this.seriesData.get("unmetered"))}</td> + <td class="bar">${bar(this.seriesData.get("unmetered"))}</td> + </tr> + <tr> + <th>dash</th> + <td>${disp(this.seriesData.get("powermeter-do_r"))}</td> + <td class="bar">${bar(this.seriesData.get("powermeter-do_r"))}</td> + </tr> + <tr> + <th>washer</th> + <td>${disp(this.seriesData.get("powermeter-ga_washer"))}</td> + <td class="bar">${bar(this.seriesData.get("powermeter-ga_washer"))}</td> + </tr> + <tr> + <th>fridge</th> + <td>${disp(this.seriesData.get("powermeter-ki_fridge"))}</td> + <td class="bar">${bar(this.seriesData.get("powermeter-ki_fridge"))}</td> + </tr> + <tr> + <th>server closet</th> + <td>${disp(this.seriesData.get("powermeter-st_wall"))}</td> + <td class="bar">${bar(this.seriesData.get("powermeter-st_wall"))}</td> + </tr> + <tr> + <th>theater console</th> + <td>${disp(this.seriesData.get("powermeter-tt_console"))}</td> + <td class="bar">${bar(this.seriesData.get("powermeter-tt_console"))}</td> + </tr> + <tr> + <th>workshop desk</th> + <td>${disp(this.seriesData.get("powermeter-ws_desk"))}</td> + <td class="bar">${bar(this.seriesData.get("powermeter-ws_desk"))}</td> + </tr> + <tr class="total"> + <th>Total</th> + <td>${this.seriesData.get("total")} W</td> + <td class="bar">${bar(this.seriesData.get("total"))}</td> + </tr> + </table> `; + } +}