Format sensors with state class duration (#12426)

This commit is contained in:
J. Nick Koston 2022-04-25 16:07:11 -10:00 committed by GitHub
parent 876fd9e85a
commit 145e5d7bc6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 0 deletions

View File

@ -0,0 +1,16 @@
import secondsToDuration from "./seconds_to_duration";
const DAY_IN_SECONDS = 86400;
const HOUR_IN_SECONDS = 3600;
const MINUTE_IN_SECONDS = 60;
export const UNIT_TO_SECOND_CONVERT = {
s: 1,
min: MINUTE_IN_SECONDS,
h: HOUR_IN_SECONDS,
d: DAY_IN_SECONDS,
};
export const formatDuration = (duration: string, units: string): string =>
secondsToDuration(parseFloat(duration) * UNIT_TO_SECOND_CONVERT[units]) ||
"0";

View File

@ -13,6 +13,7 @@ import { formatNumber, isNumericState } from "../number/format_number";
import { LocalizeFunc } from "../translations/localize";
import { computeStateDomain } from "./compute_state_domain";
import { supportsFeature } from "./supports-feature";
import { formatDuration, UNIT_TO_SECOND_CONVERT } from "../datetime/duration";
export const computeStateDisplay = (
localize: LocalizeFunc,
@ -28,6 +29,21 @@ export const computeStateDisplay = (
// Entities with a `unit_of_measurement` or `state_class` are numeric values and should use `formatNumber`
if (isNumericState(stateObj)) {
// state is duration
if (
stateObj.attributes.device_class === "duration" &&
stateObj.attributes.unit_of_measurement &&
UNIT_TO_SECOND_CONVERT[stateObj.attributes.unit_of_measurement]
) {
try {
return formatDuration(
compareState,
stateObj.attributes.unit_of_measurement
);
} catch (_err) {
// fallback to default
}
}
if (stateObj.attributes.device_class === "monetary") {
try {
return formatNumber(compareState, locale, {

View File

@ -0,0 +1,34 @@
import { assert } from "chai";
import { formatDuration } from "../../../src/common/datetime/duration";
describe("formatDuration", () => {
it("works", () => {
assert.strictEqual(formatDuration("0", "s"), "0");
assert.strictEqual(formatDuration("65", "s"), "1:05");
assert.strictEqual(formatDuration("3665", "s"), "1:01:05");
assert.strictEqual(formatDuration("39665", "s"), "11:01:05");
assert.strictEqual(formatDuration("932093", "s"), "258:54:53");
assert.strictEqual(formatDuration("0", "min"), "0");
assert.strictEqual(formatDuration("65", "min"), "1:05:00");
assert.strictEqual(formatDuration("3665", "min"), "61:05:00");
assert.strictEqual(formatDuration("39665", "min"), "661:05:00");
assert.strictEqual(formatDuration("932093", "min"), "15534:53:00");
assert.strictEqual(formatDuration("12.4", "min"), "12:24");
assert.strictEqual(formatDuration("0", "h"), "0");
assert.strictEqual(formatDuration("65", "h"), "65:00:00");
assert.strictEqual(formatDuration("3665", "h"), "3665:00:00");
assert.strictEqual(formatDuration("39665", "h"), "39665:00:00");
assert.strictEqual(formatDuration("932093", "h"), "932093:00:00");
assert.strictEqual(formatDuration("24.3", "h"), "24:18:00");
assert.strictEqual(formatDuration("24.32423", "h"), "24:19:27");
assert.strictEqual(formatDuration("0", "d"), "0");
assert.strictEqual(formatDuration("65", "d"), "1560:00:00");
assert.strictEqual(formatDuration("3665", "d"), "87960:00:00");
assert.strictEqual(formatDuration("39665", "d"), "951960:00:00");
assert.strictEqual(formatDuration("932093", "d"), "22370232:00:00");
});
});

View File

@ -8,5 +8,6 @@ describe("secondsToDuration", () => {
assert.strictEqual(secondsToDuration(65), "1:05");
assert.strictEqual(secondsToDuration(3665), "1:01:05");
assert.strictEqual(secondsToDuration(39665), "11:01:05");
assert.strictEqual(secondsToDuration(932093), "258:54:53");
});
});