Compare commits

...

26 Commits

Author SHA1 Message Date
J. Nick Koston
7128872bcc Enable compression for development 2023-02-27 16:10:08 -06:00
J. Nick Koston
60f3fc85ae Enable compression on the dev server 2023-02-27 15:49:01 -06:00
J. Nick Koston
3f9df79849 wip 2023-02-27 15:04:46 -06:00
J. Nick Koston
3ce4e67083 wip 2023-02-27 15:04:28 -06:00
J. Nick Koston
77e05af465 wip 2023-02-27 15:04:16 -06:00
J. Nick Koston
97b6fc03b3 wip 2023-02-27 15:00:09 -06:00
J. Nick Koston
cf142cee83 wip 2023-02-27 14:58:01 -06:00
J. Nick Koston
6347889fcb wip 2023-02-27 14:54:37 -06:00
J. Nick Koston
7f216699ac wip 2023-02-27 14:30:27 -06:00
J. Nick Koston
2639cae21e typing 2023-02-27 13:00:07 -06:00
J. Nick Koston
e6f33fb62f typing 2023-02-27 12:51:48 -06:00
J. Nick Koston
38cab70e8b Merge branch 'dev' into energy_no_ids 2023-02-27 12:49:54 -06:00
J. Nick Koston
09d10230a7 Update src/data/energy.ts
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-02-27 12:46:42 -06:00
J. Nick Koston
8174fbbc3e Update src/data/energy.ts
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-02-27 12:46:36 -06:00
J. Nick Koston
84b4daf4bf Update src/data/energy.ts
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-02-27 12:46:30 -06:00
J. Nick Koston
2d699c8f3f Update src/data/energy.ts
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-02-27 12:46:25 -06:00
J. Nick Koston
50e6a18eee Update src/data/energy.ts
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-02-27 12:46:20 -06:00
J. Nick Koston
58ecabd351 Update src/data/energy.ts
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-02-27 12:46:13 -06:00
J. Nick Koston
23e9f265ee Update src/data/energy.ts
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-02-27 12:46:04 -06:00
J. Nick Koston
4c9fc516ce Update src/data/energy.ts
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-02-27 12:45:58 -06:00
J. Nick Koston
d369ad0a37 Update src/data/energy.ts
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-02-27 12:45:54 -06:00
J. Nick Koston
f323c93a96 Update src/data/energy.ts
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-02-27 12:45:48 -06:00
J. Nick Koston
3ae49bb336 Update src/data/energy.ts
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-02-27 12:45:39 -06:00
J. Nick Koston
1ae950d17a Update src/data/energy.ts
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-02-27 12:45:31 -06:00
J. Nick Koston
fa7f5eccdb avoid downloading the whole entity registry again as well 2023-02-24 18:30:45 -06:00
J. Nick Koston
f75d17e10c Avoid fetching all stats metadata when there are no entities
Fetch all the data at once since it is not dependant
2023-02-24 17:26:29 -06:00
5 changed files with 148 additions and 80 deletions

View File

@@ -2,6 +2,7 @@ const webpack = require("webpack");
const path = require("path"); const path = require("path");
const TerserPlugin = require("terser-webpack-plugin"); const TerserPlugin = require("terser-webpack-plugin");
const { WebpackManifestPlugin } = require("webpack-manifest-plugin"); const { WebpackManifestPlugin } = require("webpack-manifest-plugin");
const CompressionWebpackPlugin = require("compression-webpack-plugin");
const log = require("fancy-log"); const log = require("fancy-log");
const WebpackBar = require("webpackbar"); const WebpackBar = require("webpackbar");
const paths = require("./paths.js"); const paths = require("./paths.js");
@@ -75,6 +76,7 @@ const createWebpackConfig = ({
chunkIds: isProdBuild && !isStatsBuild ? "deterministic" : "named", chunkIds: isProdBuild && !isStatsBuild ? "deterministic" : "named",
}, },
plugins: [ plugins: [
new CompressionWebpackPlugin(),
!isStatsBuild && new WebpackBar({ fancy: !isProdBuild }), !isStatsBuild && new WebpackBar({ fancy: !isProdBuild }),
new WebpackManifestPlugin({ new WebpackManifestPlugin({
// Only include the JS of entrypoints // Only include the JS of entrypoints

View File

@@ -100,6 +100,7 @@
"app-datepicker": "^5.1.0", "app-datepicker": "^5.1.0",
"chart.js": "^3.3.2", "chart.js": "^3.3.2",
"comlink": "^4.4.1", "comlink": "^4.4.1",
"compression-webpack-plugin": "^10.0.0",
"core-js": "^3.28.0", "core-js": "^3.28.0",
"cropperjs": "^1.5.13", "cropperjs": "^1.5.13",
"date-fns": "^2.29.3", "date-fns": "^2.29.3",

View File

@@ -11,10 +11,8 @@ import {
} from "date-fns/esm"; } from "date-fns/esm";
import { Collection, getCollection } from "home-assistant-js-websocket"; import { Collection, getCollection } from "home-assistant-js-websocket";
import { groupBy } from "../common/util/group-by"; import { groupBy } from "../common/util/group-by";
import { subscribeOne } from "../common/util/subscribe-one";
import { HomeAssistant } from "../types"; import { HomeAssistant } from "../types";
import { ConfigEntry, getConfigEntries } from "./config_entries"; import { ConfigEntry, getConfigEntries } from "./config_entries";
import { subscribeEntityRegistry } from "./entity_registry";
import { import {
fetchStatistics, fetchStatistics,
getStatisticMetadata, getStatisticMetadata,
@@ -195,6 +193,12 @@ export interface EnergyPreferencesValidation {
device_consumption: EnergyValidationIssue[][]; device_consumption: EnergyValidationIssue[][];
} }
export interface EnergyInfoAndCO2Signal {
energyInfo: EnergyInfo;
co2SignalEntity: string | undefined;
co2SignalConfigEntry: ConfigEntry | undefined;
}
export const getEnergyInfo = (hass: HomeAssistant) => export const getEnergyInfo = (hass: HomeAssistant) =>
hass.callWS<EnergyInfo>({ hass.callWS<EnergyInfo>({
type: "energy/info", type: "energy/info",
@@ -334,16 +338,11 @@ export const getReferencedStatisticIds = (
return statIDs; return statIDs;
}; };
const getEnergyData = async ( const getEnergyInfoAndCO2Signal = async (
hass: HomeAssistant, hass: HomeAssistant
prefs: EnergyPreferences, ): Promise<EnergyInfoAndCO2Signal> => {
start: Date, const [configEntries, info] = await Promise.all([
end?: Date,
compare?: boolean
): Promise<EnergyData> => {
const [configEntries, entityRegistryEntries, info] = await Promise.all([
getConfigEntries(hass, { domain: "co2signal" }), getConfigEntries(hass, { domain: "co2signal" }),
subscribeOne(hass.connection, subscribeEntityRegistry),
getEnergyInfo(hass), getEnergyInfo(hass),
]); ]);
@@ -352,15 +351,14 @@ const getEnergyData = async (
: undefined; : undefined;
let co2SignalEntity: string | undefined; let co2SignalEntity: string | undefined;
if (co2SignalConfigEntry) { if (co2SignalConfigEntry) {
for (const entry of entityRegistryEntries) { for (const entity of Object.values(hass.entities)) {
if (entry.config_entry_id !== co2SignalConfigEntry.entry_id) { if (entity.platform !== "co2signal") {
continue; continue;
} }
// The integration offers 2 entities. We want the % one. // 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 !== "%") { if (!co2State || co2State.attributes.unit_of_measurement !== "%") {
continue; 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[] = []; const consumptionStatIDs: string[] = [];
for (const source of prefs.energy_sources) { for (const source of prefs.energy_sources) {
// grid source // grid source
@@ -405,34 +421,35 @@ const getEnergyData = async (
volume: lengthUnit === "km" ? "L" : "gal", volume: lengthUnit === "km" ? "L" : "gal",
}; };
const stats = { const _energyStats: Statistics | Promise<Statistics> = energyStatIds.length
...(energyStatIds.length ? fetchStatistics(
? await fetchStatistics( hass!,
hass!, startMinHour,
startMinHour, end,
end, energyStatIds,
energyStatIds, period,
period, energyUnits,
energyUnits, ["sum"]
["sum"] )
) : {};
: {}), const _waterStats: Statistics | Promise<Statistics> = waterStatIds.length
...(waterStatIds.length ? fetchStatistics(
? await fetchStatistics( hass!,
hass!, startMinHour,
startMinHour, end,
end, waterStatIds,
waterStatIds, period,
period, waterUnits,
waterUnits, ["sum"]
["sum"] )
) : {};
: {}),
};
let statsCompare; let statsCompare;
let startCompare; let startCompare;
let endCompare; let endCompare;
let _energyStatsCompare: Statistics | Promise<Statistics> = {};
let _waterStatsCompare: Statistics | Promise<Statistics> = {};
if (compare) { if (compare) {
if (dayDifference > 27 && dayDifference < 32) { if (dayDifference > 27 && dayDifference < 32) {
// When comparing a month, we want to start at the begining of the month // 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); const compareStartMinHour = addHours(startCompare, -1);
endCompare = addMilliseconds(start, -1); endCompare = addMilliseconds(start, -1);
if (energyStatIds.length) {
statsCompare = { _energyStatsCompare = fetchStatistics(
...(energyStatIds.length hass!,
? await fetchStatistics( compareStartMinHour,
hass!, endCompare,
compareStartMinHour, energyStatIds,
endCompare, period,
energyStatIds, energyUnits,
period, ["sum"]
energyUnits, );
["sum"] }
) if (waterStatIds.length) {
: {}), _waterStatsCompare = fetchStatistics(
...(waterStatIds.length hass!,
? await fetchStatistics( compareStartMinHour,
hass!, endCompare,
compareStartMinHour, waterStatIds,
endCompare, period,
waterStatIds, waterUnits,
period, ["sum"]
waterUnits, );
["sum"] }
)
: {}),
};
} }
let fossilEnergyConsumption: FossilEnergyConsumption | undefined; let _fossilEnergyConsumption: undefined | Promise<FossilEnergyConsumption>;
let fossilEnergyConsumptionCompare: FossilEnergyConsumption | undefined; let _fossilEnergyConsumptionCompare:
| undefined
| Promise<FossilEnergyConsumption>;
if (co2SignalEntity !== undefined) { if (co2SignalEntity !== undefined) {
fossilEnergyConsumption = await getFossilEnergyConsumption( _fossilEnergyConsumption = getFossilEnergyConsumption(
hass!, hass!,
start, start,
consumptionStatIDs, consumptionStatIDs,
@@ -483,7 +498,7 @@ const getEnergyData = async (
dayDifference > 35 ? "month" : dayDifference > 2 ? "day" : "hour" dayDifference > 35 ? "month" : dayDifference > 2 ? "day" : "hour"
); );
if (compare) { if (compare) {
fossilEnergyConsumptionCompare = await getFossilEnergyConsumption( _fossilEnergyConsumptionCompare = getFossilEnergyConsumption(
hass!, hass!,
startCompare, startCompare,
consumptionStatIDs, 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) => { 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 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) { 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 = { const data: EnergyData = {
start, start,
end, end,
@@ -573,6 +615,9 @@ export const getEnergyDataCollection = (
energyCollectionKeys.push(options.key); energyCollectionKeys.push(options.key);
let energyInfoAndCO2Signal: EnergyInfoAndCO2Signal | undefined;
let forceRefreshEnergyInfo = false;
const collection = getCollection<EnergyData>( const collection = getCollection<EnergyData>(
hass.connection, hass.connection,
key, key,
@@ -600,14 +645,20 @@ export const getEnergyDataCollection = (
} }
nextFetch.setMinutes(20, 0, 0); nextFetch.setMinutes(20, 0, 0);
collection._refreshTimeout = window.setTimeout( collection._refreshTimeout = window.setTimeout(() => {
() => collection.refresh(), forceRefreshEnergyInfo = true;
nextFetch.getTime() - Date.now() collection.refresh();
); }, nextFetch.getTime() - Date.now());
} }
return getEnergyData( if (!energyInfoAndCO2Signal || forceRefreshEnergyInfo) {
energyInfoAndCO2Signal = await getEnergyInfoAndCO2Signal(hass);
forceRefreshEnergyInfo = false;
}
return getEnergyDataWithInfo(
hass, hass,
energyInfoAndCO2Signal,
collection.prefs, collection.prefs,
collection.start, collection.start,
collection.end, collection.end,

View File

@@ -19,6 +19,7 @@ module.exports = {
"**/*.json": "js", "**/*.json": "js",
"**/*.css": "js", "**/*.css": "js",
}, },
compress: true,
middleware: [cors()], middleware: [cors()],
plugins: rollupWDSPlugins, plugins: rollupWDSPlugins,
}; };

View File

@@ -6860,6 +6860,18 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "compression@npm:1.7.3":
version: 1.7.3 version: 1.7.3
resolution: "compression@npm:1.7.3" resolution: "compression@npm:1.7.3"
@@ -9626,6 +9638,7 @@ fsevents@~2.3.2:
chai: ^4.3.7 chai: ^4.3.7
chart.js: ^3.3.2 chart.js: ^3.3.2
comlink: ^4.4.1 comlink: ^4.4.1
compression-webpack-plugin: ^10.0.0
core-js: ^3.28.0 core-js: ^3.28.0
cropperjs: ^1.5.13 cropperjs: ^1.5.13
date-fns: ^2.29.3 date-fns: ^2.29.3