view 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 source

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> `;
    }
}