view src/FdElectricity.ts @ 17:472003015880

restyle using css grid
author drewp@bigasterisk.com
date Fri, 07 Jun 2024 21:22:37 -0700
parents 719c8cc4d8b2
children 499996b8224a
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,
      td {
        padding: 0 0;
      }
      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> `;
  }
}