mirror of
				https://github.com/home-assistant/frontend.git
				synced 2025-11-04 00:19:47 +00:00 
			
		
		
		
	Compare commits
	
		
			26 Commits
		
	
	
		
			20230526.0
			...
			compress_w
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					7128872bcc | ||
| 
						 | 
					60f3fc85ae | ||
| 
						 | 
					3f9df79849 | ||
| 
						 | 
					3ce4e67083 | ||
| 
						 | 
					77e05af465 | ||
| 
						 | 
					97b6fc03b3 | ||
| 
						 | 
					cf142cee83 | ||
| 
						 | 
					6347889fcb | ||
| 
						 | 
					7f216699ac | ||
| 
						 | 
					2639cae21e | ||
| 
						 | 
					e6f33fb62f | ||
| 
						 | 
					38cab70e8b | ||
| 
						 | 
					09d10230a7 | ||
| 
						 | 
					8174fbbc3e | ||
| 
						 | 
					84b4daf4bf | ||
| 
						 | 
					2d699c8f3f | ||
| 
						 | 
					50e6a18eee | ||
| 
						 | 
					58ecabd351 | ||
| 
						 | 
					23e9f265ee | ||
| 
						 | 
					4c9fc516ce | ||
| 
						 | 
					d369ad0a37 | ||
| 
						 | 
					f323c93a96 | ||
| 
						 | 
					3ae49bb336 | ||
| 
						 | 
					1ae950d17a | ||
| 
						 | 
					fa7f5eccdb | ||
| 
						 | 
					f75d17e10c | 
@@ -2,6 +2,7 @@ const webpack = require("webpack");
 | 
			
		||||
const path = require("path");
 | 
			
		||||
const TerserPlugin = require("terser-webpack-plugin");
 | 
			
		||||
const { WebpackManifestPlugin } = require("webpack-manifest-plugin");
 | 
			
		||||
const CompressionWebpackPlugin = require("compression-webpack-plugin");
 | 
			
		||||
const log = require("fancy-log");
 | 
			
		||||
const WebpackBar = require("webpackbar");
 | 
			
		||||
const paths = require("./paths.js");
 | 
			
		||||
@@ -75,6 +76,7 @@ const createWebpackConfig = ({
 | 
			
		||||
      chunkIds: isProdBuild && !isStatsBuild ? "deterministic" : "named",
 | 
			
		||||
    },
 | 
			
		||||
    plugins: [
 | 
			
		||||
      new CompressionWebpackPlugin(),
 | 
			
		||||
      !isStatsBuild && new WebpackBar({ fancy: !isProdBuild }),
 | 
			
		||||
      new WebpackManifestPlugin({
 | 
			
		||||
        // Only include the JS of entrypoints
 | 
			
		||||
 
 | 
			
		||||
@@ -100,6 +100,7 @@
 | 
			
		||||
    "app-datepicker": "^5.1.0",
 | 
			
		||||
    "chart.js": "^3.3.2",
 | 
			
		||||
    "comlink": "^4.4.1",
 | 
			
		||||
    "compression-webpack-plugin": "^10.0.0",
 | 
			
		||||
    "core-js": "^3.28.0",
 | 
			
		||||
    "cropperjs": "^1.5.13",
 | 
			
		||||
    "date-fns": "^2.29.3",
 | 
			
		||||
 
 | 
			
		||||
@@ -11,10 +11,8 @@ import {
 | 
			
		||||
} from "date-fns/esm";
 | 
			
		||||
import { Collection, getCollection } from "home-assistant-js-websocket";
 | 
			
		||||
import { groupBy } from "../common/util/group-by";
 | 
			
		||||
import { subscribeOne } from "../common/util/subscribe-one";
 | 
			
		||||
import { HomeAssistant } from "../types";
 | 
			
		||||
import { ConfigEntry, getConfigEntries } from "./config_entries";
 | 
			
		||||
import { subscribeEntityRegistry } from "./entity_registry";
 | 
			
		||||
import {
 | 
			
		||||
  fetchStatistics,
 | 
			
		||||
  getStatisticMetadata,
 | 
			
		||||
@@ -195,6 +193,12 @@ export interface EnergyPreferencesValidation {
 | 
			
		||||
  device_consumption: EnergyValidationIssue[][];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface EnergyInfoAndCO2Signal {
 | 
			
		||||
  energyInfo: EnergyInfo;
 | 
			
		||||
  co2SignalEntity: string | undefined;
 | 
			
		||||
  co2SignalConfigEntry: ConfigEntry | undefined;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const getEnergyInfo = (hass: HomeAssistant) =>
 | 
			
		||||
  hass.callWS<EnergyInfo>({
 | 
			
		||||
    type: "energy/info",
 | 
			
		||||
@@ -334,16 +338,11 @@ export const getReferencedStatisticIds = (
 | 
			
		||||
  return statIDs;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const getEnergyData = async (
 | 
			
		||||
  hass: HomeAssistant,
 | 
			
		||||
  prefs: EnergyPreferences,
 | 
			
		||||
  start: Date,
 | 
			
		||||
  end?: Date,
 | 
			
		||||
  compare?: boolean
 | 
			
		||||
): Promise<EnergyData> => {
 | 
			
		||||
  const [configEntries, entityRegistryEntries, info] = await Promise.all([
 | 
			
		||||
const getEnergyInfoAndCO2Signal = async (
 | 
			
		||||
  hass: HomeAssistant
 | 
			
		||||
): Promise<EnergyInfoAndCO2Signal> => {
 | 
			
		||||
  const [configEntries, info] = await Promise.all([
 | 
			
		||||
    getConfigEntries(hass, { domain: "co2signal" }),
 | 
			
		||||
    subscribeOne(hass.connection, subscribeEntityRegistry),
 | 
			
		||||
    getEnergyInfo(hass),
 | 
			
		||||
  ]);
 | 
			
		||||
 | 
			
		||||
@@ -352,15 +351,14 @@ const getEnergyData = async (
 | 
			
		||||
    : undefined;
 | 
			
		||||
 | 
			
		||||
  let co2SignalEntity: string | undefined;
 | 
			
		||||
 | 
			
		||||
  if (co2SignalConfigEntry) {
 | 
			
		||||
    for (const entry of entityRegistryEntries) {
 | 
			
		||||
      if (entry.config_entry_id !== co2SignalConfigEntry.entry_id) {
 | 
			
		||||
    for (const entity of Object.values(hass.entities)) {
 | 
			
		||||
      if (entity.platform !== "co2signal") {
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // The integration offers 2 entities. We want the % one.
 | 
			
		||||
      const co2State = hass.states[entry.entity_id];
 | 
			
		||||
      const co2State = hass.states[entity.entity_id];
 | 
			
		||||
      if (!co2State || co2State.attributes.unit_of_measurement !== "%") {
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
@@ -370,6 +368,24 @@ const getEnergyData = async (
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return <EnergyInfoAndCO2Signal>{
 | 
			
		||||
    energyInfo: info,
 | 
			
		||||
    co2SignalEntity: co2SignalEntity,
 | 
			
		||||
    co2SignalConfigEntry: co2SignalConfigEntry,
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const getEnergyDataWithInfo = async (
 | 
			
		||||
  hass: HomeAssistant,
 | 
			
		||||
  energyInfoAndCO2Signal: EnergyInfoAndCO2Signal,
 | 
			
		||||
  prefs: EnergyPreferences,
 | 
			
		||||
  start: Date,
 | 
			
		||||
  end?: Date,
 | 
			
		||||
  compare?: boolean
 | 
			
		||||
): Promise<EnergyData> => {
 | 
			
		||||
  const info = energyInfoAndCO2Signal.energyInfo;
 | 
			
		||||
  const co2SignalEntity = energyInfoAndCO2Signal.co2SignalEntity;
 | 
			
		||||
  const co2SignalConfigEntry = energyInfoAndCO2Signal.co2SignalConfigEntry;
 | 
			
		||||
  const consumptionStatIDs: string[] = [];
 | 
			
		||||
  for (const source of prefs.energy_sources) {
 | 
			
		||||
    // grid source
 | 
			
		||||
@@ -405,34 +421,35 @@ const getEnergyData = async (
 | 
			
		||||
    volume: lengthUnit === "km" ? "L" : "gal",
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const stats = {
 | 
			
		||||
    ...(energyStatIds.length
 | 
			
		||||
      ? await fetchStatistics(
 | 
			
		||||
          hass!,
 | 
			
		||||
          startMinHour,
 | 
			
		||||
          end,
 | 
			
		||||
          energyStatIds,
 | 
			
		||||
          period,
 | 
			
		||||
          energyUnits,
 | 
			
		||||
          ["sum"]
 | 
			
		||||
        )
 | 
			
		||||
      : {}),
 | 
			
		||||
    ...(waterStatIds.length
 | 
			
		||||
      ? await fetchStatistics(
 | 
			
		||||
          hass!,
 | 
			
		||||
          startMinHour,
 | 
			
		||||
          end,
 | 
			
		||||
          waterStatIds,
 | 
			
		||||
          period,
 | 
			
		||||
          waterUnits,
 | 
			
		||||
          ["sum"]
 | 
			
		||||
        )
 | 
			
		||||
      : {}),
 | 
			
		||||
  };
 | 
			
		||||
  const _energyStats: Statistics | Promise<Statistics> = energyStatIds.length
 | 
			
		||||
    ? fetchStatistics(
 | 
			
		||||
        hass!,
 | 
			
		||||
        startMinHour,
 | 
			
		||||
        end,
 | 
			
		||||
        energyStatIds,
 | 
			
		||||
        period,
 | 
			
		||||
        energyUnits,
 | 
			
		||||
        ["sum"]
 | 
			
		||||
      )
 | 
			
		||||
    : {};
 | 
			
		||||
  const _waterStats: Statistics | Promise<Statistics> = waterStatIds.length
 | 
			
		||||
    ? fetchStatistics(
 | 
			
		||||
        hass!,
 | 
			
		||||
        startMinHour,
 | 
			
		||||
        end,
 | 
			
		||||
        waterStatIds,
 | 
			
		||||
        period,
 | 
			
		||||
        waterUnits,
 | 
			
		||||
        ["sum"]
 | 
			
		||||
      )
 | 
			
		||||
    : {};
 | 
			
		||||
 | 
			
		||||
  let statsCompare;
 | 
			
		||||
  let startCompare;
 | 
			
		||||
  let endCompare;
 | 
			
		||||
  let _energyStatsCompare: Statistics | Promise<Statistics> = {};
 | 
			
		||||
  let _waterStatsCompare: Statistics | Promise<Statistics> = {};
 | 
			
		||||
 | 
			
		||||
  if (compare) {
 | 
			
		||||
    if (dayDifference > 27 && dayDifference < 32) {
 | 
			
		||||
      // When comparing a month, we want to start at the begining of the month
 | 
			
		||||
@@ -443,38 +460,36 @@ const getEnergyData = async (
 | 
			
		||||
 | 
			
		||||
    const compareStartMinHour = addHours(startCompare, -1);
 | 
			
		||||
    endCompare = addMilliseconds(start, -1);
 | 
			
		||||
 | 
			
		||||
    statsCompare = {
 | 
			
		||||
      ...(energyStatIds.length
 | 
			
		||||
        ? await fetchStatistics(
 | 
			
		||||
            hass!,
 | 
			
		||||
            compareStartMinHour,
 | 
			
		||||
            endCompare,
 | 
			
		||||
            energyStatIds,
 | 
			
		||||
            period,
 | 
			
		||||
            energyUnits,
 | 
			
		||||
            ["sum"]
 | 
			
		||||
          )
 | 
			
		||||
        : {}),
 | 
			
		||||
      ...(waterStatIds.length
 | 
			
		||||
        ? await fetchStatistics(
 | 
			
		||||
            hass!,
 | 
			
		||||
            compareStartMinHour,
 | 
			
		||||
            endCompare,
 | 
			
		||||
            waterStatIds,
 | 
			
		||||
            period,
 | 
			
		||||
            waterUnits,
 | 
			
		||||
            ["sum"]
 | 
			
		||||
          )
 | 
			
		||||
        : {}),
 | 
			
		||||
    };
 | 
			
		||||
    if (energyStatIds.length) {
 | 
			
		||||
      _energyStatsCompare = fetchStatistics(
 | 
			
		||||
        hass!,
 | 
			
		||||
        compareStartMinHour,
 | 
			
		||||
        endCompare,
 | 
			
		||||
        energyStatIds,
 | 
			
		||||
        period,
 | 
			
		||||
        energyUnits,
 | 
			
		||||
        ["sum"]
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    if (waterStatIds.length) {
 | 
			
		||||
      _waterStatsCompare = fetchStatistics(
 | 
			
		||||
        hass!,
 | 
			
		||||
        compareStartMinHour,
 | 
			
		||||
        endCompare,
 | 
			
		||||
        waterStatIds,
 | 
			
		||||
        period,
 | 
			
		||||
        waterUnits,
 | 
			
		||||
        ["sum"]
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  let fossilEnergyConsumption: FossilEnergyConsumption | undefined;
 | 
			
		||||
  let fossilEnergyConsumptionCompare: FossilEnergyConsumption | undefined;
 | 
			
		||||
 | 
			
		||||
  let _fossilEnergyConsumption: undefined | Promise<FossilEnergyConsumption>;
 | 
			
		||||
  let _fossilEnergyConsumptionCompare:
 | 
			
		||||
    | undefined
 | 
			
		||||
    | Promise<FossilEnergyConsumption>;
 | 
			
		||||
  if (co2SignalEntity !== undefined) {
 | 
			
		||||
    fossilEnergyConsumption = await getFossilEnergyConsumption(
 | 
			
		||||
    _fossilEnergyConsumption = getFossilEnergyConsumption(
 | 
			
		||||
      hass!,
 | 
			
		||||
      start,
 | 
			
		||||
      consumptionStatIDs,
 | 
			
		||||
@@ -483,7 +498,7 @@ const getEnergyData = async (
 | 
			
		||||
      dayDifference > 35 ? "month" : dayDifference > 2 ? "day" : "hour"
 | 
			
		||||
    );
 | 
			
		||||
    if (compare) {
 | 
			
		||||
      fossilEnergyConsumptionCompare = await getFossilEnergyConsumption(
 | 
			
		||||
      _fossilEnergyConsumptionCompare = getFossilEnergyConsumption(
 | 
			
		||||
        hass!,
 | 
			
		||||
        startCompare,
 | 
			
		||||
        consumptionStatIDs,
 | 
			
		||||
@@ -494,6 +509,39 @@ const getEnergyData = async (
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const statsMetadata: Record<string, StatisticsMetaData> = {};
 | 
			
		||||
  const _getStatisticMetadata:
 | 
			
		||||
    | Promise<StatisticsMetaData[]>
 | 
			
		||||
    | StatisticsMetaData[] = allStatIDs.length
 | 
			
		||||
    ? getStatisticMetadata(hass, allStatIDs)
 | 
			
		||||
    : [];
 | 
			
		||||
  const [
 | 
			
		||||
    energyStats,
 | 
			
		||||
    waterStats,
 | 
			
		||||
    energyStatsCompare,
 | 
			
		||||
    waterStatsCompare,
 | 
			
		||||
    statsMetadataArray,
 | 
			
		||||
    fossilEnergyConsumption,
 | 
			
		||||
    fossilEnergyConsumptionCompare,
 | 
			
		||||
  ] = await Promise.all([
 | 
			
		||||
    _energyStats,
 | 
			
		||||
    _waterStats,
 | 
			
		||||
    _energyStatsCompare,
 | 
			
		||||
    _waterStatsCompare,
 | 
			
		||||
    _getStatisticMetadata,
 | 
			
		||||
    _fossilEnergyConsumption,
 | 
			
		||||
    _fossilEnergyConsumptionCompare,
 | 
			
		||||
  ]);
 | 
			
		||||
  const stats = { ...energyStats, ...waterStats };
 | 
			
		||||
  if (compare) {
 | 
			
		||||
    statsCompare = { ...energyStatsCompare, ...waterStatsCompare };
 | 
			
		||||
  }
 | 
			
		||||
  if (allStatIDs.length) {
 | 
			
		||||
    statsMetadataArray.forEach((x) => {
 | 
			
		||||
      statsMetadata[x.statistic_id] = x;
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Object.values(stats).forEach((stat) => {
 | 
			
		||||
    // if the start of the first value is after the requested period, we have the first data point, and should add a zero point
 | 
			
		||||
    if (stat.length && new Date(stat[0].start) > startMinHour) {
 | 
			
		||||
@@ -507,12 +555,6 @@ const getEnergyData = async (
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  const statsMetadataArray = await getStatisticMetadata(hass, allStatIDs);
 | 
			
		||||
  const statsMetadata: Record<string, StatisticsMetaData> = {};
 | 
			
		||||
  statsMetadataArray.forEach((x) => {
 | 
			
		||||
    statsMetadata[x.statistic_id] = x;
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  const data: EnergyData = {
 | 
			
		||||
    start,
 | 
			
		||||
    end,
 | 
			
		||||
@@ -573,6 +615,9 @@ export const getEnergyDataCollection = (
 | 
			
		||||
 | 
			
		||||
  energyCollectionKeys.push(options.key);
 | 
			
		||||
 | 
			
		||||
  let energyInfoAndCO2Signal: EnergyInfoAndCO2Signal | undefined;
 | 
			
		||||
  let forceRefreshEnergyInfo = false;
 | 
			
		||||
 | 
			
		||||
  const collection = getCollection<EnergyData>(
 | 
			
		||||
    hass.connection,
 | 
			
		||||
    key,
 | 
			
		||||
@@ -600,14 +645,20 @@ export const getEnergyDataCollection = (
 | 
			
		||||
        }
 | 
			
		||||
        nextFetch.setMinutes(20, 0, 0);
 | 
			
		||||
 | 
			
		||||
        collection._refreshTimeout = window.setTimeout(
 | 
			
		||||
          () => collection.refresh(),
 | 
			
		||||
          nextFetch.getTime() - Date.now()
 | 
			
		||||
        );
 | 
			
		||||
        collection._refreshTimeout = window.setTimeout(() => {
 | 
			
		||||
          forceRefreshEnergyInfo = true;
 | 
			
		||||
          collection.refresh();
 | 
			
		||||
        }, nextFetch.getTime() - Date.now());
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return getEnergyData(
 | 
			
		||||
      if (!energyInfoAndCO2Signal || forceRefreshEnergyInfo) {
 | 
			
		||||
        energyInfoAndCO2Signal = await getEnergyInfoAndCO2Signal(hass);
 | 
			
		||||
        forceRefreshEnergyInfo = false;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return getEnergyDataWithInfo(
 | 
			
		||||
        hass,
 | 
			
		||||
        energyInfoAndCO2Signal,
 | 
			
		||||
        collection.prefs,
 | 
			
		||||
        collection.start,
 | 
			
		||||
        collection.end,
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@ module.exports = {
 | 
			
		||||
    "**/*.json": "js",
 | 
			
		||||
    "**/*.css": "js",
 | 
			
		||||
  },
 | 
			
		||||
  compress: true,
 | 
			
		||||
  middleware: [cors()],
 | 
			
		||||
  plugins: rollupWDSPlugins,
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								yarn.lock
									
									
									
									
									
								
							@@ -6860,6 +6860,18 @@ __metadata:
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"compression-webpack-plugin@npm:^10.0.0":
 | 
			
		||||
  version: 10.0.0
 | 
			
		||||
  resolution: "compression-webpack-plugin@npm:10.0.0"
 | 
			
		||||
  dependencies:
 | 
			
		||||
    schema-utils: ^4.0.0
 | 
			
		||||
    serialize-javascript: ^6.0.0
 | 
			
		||||
  peerDependencies:
 | 
			
		||||
    webpack: ^5.1.0
 | 
			
		||||
  checksum: 2ac9079b7ab87141639c62ddbb2820a06f105198e27ef4c3860da3186bdbefc00d1e206969833ce7a4b7b26161ddbec7b8d20d30f9f9c1d494818b9b86f0d5cc
 | 
			
		||||
  languageName: node
 | 
			
		||||
  linkType: hard
 | 
			
		||||
 | 
			
		||||
"compression@npm:1.7.3":
 | 
			
		||||
  version: 1.7.3
 | 
			
		||||
  resolution: "compression@npm:1.7.3"
 | 
			
		||||
@@ -9626,6 +9638,7 @@ fsevents@~2.3.2:
 | 
			
		||||
    chai: ^4.3.7
 | 
			
		||||
    chart.js: ^3.3.2
 | 
			
		||||
    comlink: ^4.4.1
 | 
			
		||||
    compression-webpack-plugin: ^10.0.0
 | 
			
		||||
    core-js: ^3.28.0
 | 
			
		||||
    cropperjs: ^1.5.13
 | 
			
		||||
    date-fns: ^2.29.3
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user