Add milliseconds support for duration sensors (#15895)

This commit is contained in:
Raman Gupta 2023-03-26 17:52:18 -04:00 committed by GitHub
parent 34f8b48fbe
commit a19ff5aef5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 75 additions and 13 deletions

View File

@ -1,16 +1,19 @@
import secondsToDuration from "./seconds_to_duration";
import millisecondsToDuration from "./milliseconds_to_duration";
const DAY_IN_SECONDS = 86400;
const HOUR_IN_SECONDS = 3600;
const MINUTE_IN_SECONDS = 60;
const DAY_IN_MILLISECONDS = 86400000;
const HOUR_IN_MILLISECONDS = 3600000;
const MINUTE_IN_MILLISECONDS = 60000;
const SECOND_IN_MILLISECONDS = 1000;
export const UNIT_TO_SECOND_CONVERT = {
s: 1,
min: MINUTE_IN_SECONDS,
h: HOUR_IN_SECONDS,
d: DAY_IN_SECONDS,
export const UNIT_TO_MILLISECOND_CONVERT = {
ms: 1,
s: SECOND_IN_MILLISECONDS,
min: MINUTE_IN_MILLISECONDS,
h: HOUR_IN_MILLISECONDS,
d: DAY_IN_MILLISECONDS,
};
export const formatDuration = (duration: string, units: string): string =>
secondsToDuration(parseFloat(duration) * UNIT_TO_SECOND_CONVERT[units]) ||
"0";
millisecondsToDuration(
parseFloat(duration) * UNIT_TO_MILLISECOND_CONVERT[units]
) || "0";

View File

@ -0,0 +1,25 @@
const leftPad = (num: number, digits = 2) => {
let paddedNum = "" + num;
for (let i = 1; i < digits; i++) {
paddedNum = parseInt(paddedNum) < 10 ** i ? `0${paddedNum}` : paddedNum;
}
return paddedNum;
};
export default function millisecondsToDuration(d: number) {
const h = Math.floor(d / 1000 / 3600);
const m = Math.floor(((d / 1000) % 3600) / 60);
const s = Math.floor(((d / 1000) % 3600) % 60);
const ms = Math.floor(d % 1000);
if (h > 0) {
return `${h}:${leftPad(m)}:${leftPad(s)}`;
}
if (m > 0) {
return `${m}:${leftPad(s)}`;
}
if (s > 0 || ms > 0) {
return `${s}${ms > 0 ? `.${leftPad(ms, 3)}` : ``}`;
}
return null;
}

View File

@ -7,7 +7,10 @@ import {
UPDATE_SUPPORT_PROGRESS,
} from "../../data/update";
import { HomeAssistant } from "../../types";
import { formatDuration, UNIT_TO_SECOND_CONVERT } from "../datetime/duration";
import {
formatDuration,
UNIT_TO_MILLISECOND_CONVERT,
} from "../datetime/duration";
import { formatDate } from "../datetime/format_date";
import { formatDateTime } from "../datetime/format_date_time";
import { formatTime } from "../datetime/format_time";
@ -57,7 +60,7 @@ export const computeStateDisplayFromEntityAttributes = (
if (
attributes.device_class === "duration" &&
attributes.unit_of_measurement &&
UNIT_TO_SECOND_CONVERT[attributes.unit_of_measurement]
UNIT_TO_MILLISECOND_CONVERT[attributes.unit_of_measurement]
) {
try {
return formatDuration(state, attributes.unit_of_measurement);

View File

@ -4,7 +4,20 @@ import { formatDuration } from "../../../src/common/datetime/duration";
describe("formatDuration", () => {
it("works", () => {
assert.strictEqual(formatDuration("0", "ms"), "0");
assert.strictEqual(formatDuration("1", "ms"), "0.001");
assert.strictEqual(formatDuration("10", "ms"), "0.010");
assert.strictEqual(formatDuration("100", "ms"), "0.100");
assert.strictEqual(formatDuration("1000", "ms"), "1");
assert.strictEqual(formatDuration("1001", "ms"), "1.001");
assert.strictEqual(formatDuration("65000", "ms"), "1:05");
assert.strictEqual(formatDuration("3665000", "ms"), "1:01:05");
assert.strictEqual(formatDuration("39665050", "ms"), "11:01:05");
assert.strictEqual(formatDuration("932093000", "ms"), "258:54:53");
assert.strictEqual(formatDuration("0", "s"), "0");
assert.strictEqual(formatDuration("1", "s"), "1");
assert.strictEqual(formatDuration("1.1", "s"), "1.100");
assert.strictEqual(formatDuration("65", "s"), "1:05");
assert.strictEqual(formatDuration("3665", "s"), "1:01:05");
assert.strictEqual(formatDuration("39665", "s"), "11:01:05");

View File

@ -0,0 +1,18 @@
import { assert } from "chai";
import millisecondsToDuration from "../../../src/common/datetime/milliseconds_to_duration";
describe("millisecondsToDuration", () => {
it("works", () => {
assert.strictEqual(millisecondsToDuration(0), null);
assert.strictEqual(millisecondsToDuration(1), "0.001");
assert.strictEqual(millisecondsToDuration(10), "0.010");
assert.strictEqual(millisecondsToDuration(100), "0.100");
assert.strictEqual(millisecondsToDuration(1000), "1");
assert.strictEqual(millisecondsToDuration(1001), "1.001");
assert.strictEqual(millisecondsToDuration(65000), "1:05");
assert.strictEqual(millisecondsToDuration(3665000), "1:01:05");
assert.strictEqual(millisecondsToDuration(39665050), "11:01:05");
assert.strictEqual(millisecondsToDuration(932093000), "258:54:53");
});
});