From c57c9b86fda828d4c0d989340fc2151f2f100d56 Mon Sep 17 00:00:00 2001 From: Zoe Codez Date: Wed, 15 May 2024 19:01:16 -0500 Subject: [PATCH 1/4] tweaks --- README.md | 5 +- package-lock.json | 49 ++++++++++--------- package.json | 4 +- src/automation.module.ts | 6 +-- src/extensions/index.ts | 1 + src/extensions/solar-calc.extension.ts | 19 ++++--- .../{utils.extension.ts => time.extension.ts} | 32 ++++++++++-- 7 files changed, 70 insertions(+), 46 deletions(-) rename src/extensions/{utils.extension.ts => time.extension.ts} (73%) diff --git a/README.md b/README.md index 37a3d7b..fdba969 100644 --- a/README.md +++ b/README.md @@ -104,10 +104,7 @@ export function ExampleRoom({ automation, context }: TServiceParams) { // check sun position if (automation.solar.isBetween("dawn", "dusk")) { - - // create some reference points with dayjs - const [PM530, NOW] = automation.utils.shortTime(["PM5:30", "NOW"]); - return NOW.isBefore(PM530); + return automation.time.isBefore("PM5:30") } return false; }, diff --git a/package-lock.json b/package-lock.json index 94baaf9..f3eb08a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { "name": "@digital-alchemy/automation", - "version": "0.3.5", + "version": "0.3.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@digital-alchemy/automation", - "version": "0.3.5", + "version": "0.3.6", "license": "MIT", "dependencies": { - "@digital-alchemy/core": "^0.3.12", - "@digital-alchemy/hass": "^0.3.20", + "@digital-alchemy/core": "^0.3.15", + "@digital-alchemy/hass": "^0.3.24", "@digital-alchemy/synapse": "^0.3.5", "dayjs": "^1.11.10", "prom-client": "^15.1.1" @@ -1170,9 +1170,9 @@ } }, "node_modules/@digital-alchemy/core": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/@digital-alchemy/core/-/core-0.3.12.tgz", - "integrity": "sha512-aqPukCZ1Rnujh5iRN2zx4XsNlUIKp06s2uUZsLn6LrgJULSRS7XbAzQ3R+9Zgv47UvPXz+OxYaN5OPacYwlKAA==", + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/@digital-alchemy/core/-/core-0.3.15.tgz", + "integrity": "sha512-b3ynKxKsB7ss7XVqYJMUyq/CuOZhoge2eqRpXsCoZ9v7MiE2GFVZxZv+zzW1MA3xoOBB5kWss5Yi7dwK11JJcA==", "dependencies": { "chalk": "^5.3.0", "dayjs": "^1.11.10", @@ -1191,14 +1191,17 @@ } }, "node_modules/@digital-alchemy/hass": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@digital-alchemy/hass/-/hass-0.3.20.tgz", - "integrity": "sha512-Z2wcEVO2oqYrnnns8pUAJ1Uu8ovt0NiKB8+ytkh30EHqJNeECc5Rdi4nuvT+kgKoKZLsBFVvQPN0Xji7pT+VOg==", + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/@digital-alchemy/hass/-/hass-0.3.24.tgz", + "integrity": "sha512-YCe8u1KnwsTlotiPDfc7YOmH3DOCvB/f9IhIEDKCEr8w6/O5DrzbrFeYJNI46OhcaUmjt1YbCTFWxw+vpttYZw==", "dependencies": { - "@digital-alchemy/core": "^0.3.11", - "dayjs": "^1.11.10", - "prom-client": "^15.1.1", - "ws": "^8.16.0" + "@digital-alchemy/core": "^0.3.14", + "dayjs": "^1.11.11", + "prom-client": "^15.1.2", + "ws": "^8.17.0" + }, + "bin": { + "mock-assistant": "dist/mock_assistant/main.js" }, "engines": { "node": ">=20" @@ -4765,9 +4768,9 @@ } }, "node_modules/dayjs": { - "version": "1.11.10", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", - "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", + "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==" }, "node_modules/debug": { "version": "4.3.4", @@ -10367,9 +10370,9 @@ } }, "node_modules/prom-client": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-15.1.1.tgz", - "integrity": "sha512-GVA2H96QCg2q71rjc3VYvSrVG7OpnJxyryC7dMzvfJfpJJHzQVwF3TJLfHzKORcwJpElWs1TwXLthlJAFJxq2A==", + "version": "15.1.2", + "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-15.1.2.tgz", + "integrity": "sha512-on3h1iXb04QFLLThrmVYg1SChBQ9N1c+nKAjebBjokBqipddH3uxmOUcEkTnzmJ8Jh/5TSUnUqS40i2QB2dJHQ==", "dependencies": { "@opentelemetry/api": "^1.4.0", "tdigest": "^0.1.1" @@ -12490,9 +12493,9 @@ } }, "node_modules/ws": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", - "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz", + "integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==", "engines": { "node": ">=10.0.0" }, diff --git a/package.json b/package.json index 8a4ad46..596087f 100644 --- a/package.json +++ b/package.json @@ -25,8 +25,8 @@ }, "license": "MIT", "dependencies": { - "@digital-alchemy/core": "^0.3.12", - "@digital-alchemy/hass": "^0.3.20", + "@digital-alchemy/core": "^0.3.15", + "@digital-alchemy/hass": "^0.3.24", "@digital-alchemy/synapse": "^0.3.5", "dayjs": "^1.11.10", "prom-client": "^15.1.1" diff --git a/src/automation.module.ts b/src/automation.module.ts index 7748ef2..5539aef 100644 --- a/src/automation.module.ts +++ b/src/automation.module.ts @@ -10,8 +10,8 @@ import { Room, SequenceWatcher, SolarCalculator, + Time, } from "./extensions"; -import { Utils } from "./extensions/utils.extension"; export const LIB_AUTOMATION = CreateLibrary({ configuration: { @@ -73,7 +73,7 @@ export const LIB_AUTOMATION = CreateLibrary({ depends: [LIB_HASS, LIB_SYNAPSE], name: "automation", // light depends circadian - priorityInit: ["utils", "circadian"], + priorityInit: ["time", "circadian"], services: { /** * # Aggressive Scenes extension @@ -117,7 +117,7 @@ export const LIB_AUTOMATION = CreateLibrary({ /** * Helper functions */ - utils: Utils, + time: Time, }, }); diff --git a/src/extensions/index.ts b/src/extensions/index.ts index 7e0e353..469dbbe 100644 --- a/src/extensions/index.ts +++ b/src/extensions/index.ts @@ -5,3 +5,4 @@ export * from "./managed-switch.extension"; export * from "./room.extension"; export * from "./sequence-matcher.extension"; export * from "./solar-calc.extension"; +export * from "./time.extension"; diff --git a/src/extensions/solar-calc.extension.ts b/src/extensions/solar-calc.extension.ts index ca2c4ab..46962ff 100644 --- a/src/extensions/solar-calc.extension.ts +++ b/src/extensions/solar-calc.extension.ts @@ -1,5 +1,7 @@ import { CronExpression, + is, + NONE, TBlackHole, TContext, TServiceParams, @@ -191,19 +193,16 @@ export function SolarCalculator({ }; solarReference.onEvent = ({ - context, eventName, label, exec, + offset, }: OnSolarEvent) => { - event.on(eventName, async () => { - await internal.safeExec({ - duration: undefined, - errors: undefined, - exec: async () => await exec(), - executions: undefined, - labels: { context, label }, - }); + scheduler.sliding({ + exec: async () => await exec(), + label, + next: () => solarReference[eventName].add(offset ?? NONE, "ms"), + reset: CronExpression.EVERY_DAY_AT_MIDNIGHT, }); }; @@ -211,8 +210,8 @@ export function SolarCalculator({ } type OnSolarEvent = { - context: TContext; label?: string; + offset?: number; eventName: SolarEvents; exec: () => TBlackHole; }; diff --git a/src/extensions/utils.extension.ts b/src/extensions/time.extension.ts similarity index 73% rename from src/extensions/utils.extension.ts rename to src/extensions/time.extension.ts index d41e55f..8053704 100644 --- a/src/extensions/utils.extension.ts +++ b/src/extensions/time.extension.ts @@ -1,11 +1,12 @@ -import { NONE, START } from "@digital-alchemy/core"; +import { NONE, sleep, START, TServiceParams } from "@digital-alchemy/core"; import dayjs, { Dayjs } from "dayjs"; type Digit = `${number}`; type TimeString = Digit | `${Digit}:${Digit}` | `${Digit}:${Digit}:${Digit}`; -type ShortTime = `${AmPm}${ShortDigits}${ShortSuffix}` | "NOW" | "TOMORROW"; +export type TShortTime = `${AmPm}${ShortDigits}${ShortSuffix}`; +type ShortTime = TShortTime | "NOW" | "TOMORROW"; type ShortDigits = | "1" | "2" @@ -33,9 +34,29 @@ type ShortSuffix = "" | ":00" | ":15" | ":30" | ":45"; const SLICE_LENGTH = "AM".length; const ROLLOVER = 12; - -export function Utils() { +export function Time({ automation }: TServiceParams) { return { + /** + * Fast time check + */ + isAfter(time: TShortTime) { + const [NOW, target] = automation.time.shortTime(["NOW", time]); + return NOW.isAfter(target); + }, + /** + * Fast time check + */ + isBefore(time: TShortTime) { + const [NOW, target] = automation.time.shortTime(["NOW", time]); + return NOW.isBefore(target); + }, + /** + * Fast time check + */ + isBetween(start: TShortTime, end: TShortTime) { + const [NOW, START, END] = automation.time.shortTime(["NOW", start, end]); + return NOW.isBetween(START, END); + }, /** * Quickly calculate reference points in time. * Times are in reference to 12AM/midnight this morning, and input in 24 hour format. @@ -60,6 +81,7 @@ export function Utils() { const today = dayjs().format("YYYY-MM-DD"); return times.map(i => dayjs(`${today} ${i}`).millisecond(NONE)); }, + /** * Quickly calculate reference points in time. * Times are in reference to 12AM/midnight this morning. @@ -97,5 +119,7 @@ export function Utils() { return dayjs(`${today} ${hour}:${minute}`).millisecond(NONE); }); }, + + wait: (ms: number | Date) => sleep(ms), }; } From 76ddb0c5580087687d1904718e1a40c07be4a88c Mon Sep 17 00:00:00 2001 From: Zoe Codez Date: Wed, 15 May 2024 20:53:12 -0500 Subject: [PATCH 2/4] more ways to define offsets --- src/extensions/solar-calc.extension.ts | 70 ++++++++++++++++++++------ src/index.ts | 3 ++ 2 files changed, 58 insertions(+), 15 deletions(-) diff --git a/src/extensions/solar-calc.extension.ts b/src/extensions/solar-calc.extension.ts index 46962ff..0905674 100644 --- a/src/extensions/solar-calc.extension.ts +++ b/src/extensions/solar-calc.extension.ts @@ -3,11 +3,15 @@ import { is, NONE, TBlackHole, - TContext, TServiceParams, } from "@digital-alchemy/core"; import { HassConfig } from "@digital-alchemy/hass"; import dayjs, { Dayjs } from "dayjs"; +import { + Duration, + DurationUnitsObjectType, + DurationUnitType, +} from "dayjs/plugin/duration"; import EventEmitter from "events"; import { calcSolNoon, calcSunriseSet } from ".."; @@ -46,6 +50,29 @@ const degreesBelowHorizon = { twilight: 6, }; const UNLIMITED = 0; +type Part = `${number}${CHAR}` | ""; +type Time = `T${Part<"H">}${Part<"M">}${Part<"S">}` | ""; +type ISO_8601 = `P${Part<"Y">}${Part<"M">}${Part<"W">}${Part<"D">}${Time}`; + +type OffsetTypes = + | Duration + | number + | DurationUnitsObjectType + | ISO_8601 + | [quantity: number, unit: DurationUnitType]; + +type OnSolarEvent = { + label?: string; + offset?: OffsetTypes | (() => OffsetTypes); + eventName: SolarEvents; + exec: () => TBlackHole; +}; + +type SolarReference = Record & { + isBetween: (a: SolarEvents, b: SolarEvents) => boolean; + loaded: boolean; + onEvent: (options: OnSolarEvent) => TBlackHole; +}; /** * Benefits from a persistent cache, like Redis @@ -53,7 +80,6 @@ const UNLIMITED = 0; export function SolarCalculator({ logger, cache, - internal, scheduler, hass, lifecycle, @@ -198,10 +224,31 @@ export function SolarCalculator({ exec, offset, }: OnSolarEvent) => { + let duration: Duration; + if (is.function(offset)) { + offset = offset(); + } + if (is.array(offset)) { + const [amount, unit] = offset; + duration = dayjs.duration(amount, unit); + } else if (is.object(offset)) { + duration = isDuration(offset) + ? (offset as Duration) + : dayjs.duration(offset as DurationUnitsObjectType); + } + if (is.string(offset)) { + duration = dayjs.duration(offset); + } + if (is.number(offset)) { + duration = dayjs.duration(offset, "ms"); + } scheduler.sliding({ exec: async () => await exec(), label, - next: () => solarReference[eventName].add(offset ?? NONE, "ms"), + next: () => + duration + ? solarReference[eventName].add(duration) + : solarReference[eventName], reset: CronExpression.EVERY_DAY_AT_MIDNIGHT, }); }; @@ -209,15 +256,8 @@ export function SolarCalculator({ return solarReference as SolarReference; } -type OnSolarEvent = { - label?: string; - offset?: number; - eventName: SolarEvents; - exec: () => TBlackHole; -}; - -type SolarReference = Record & { - isBetween: (a: SolarEvents, b: SolarEvents) => boolean; - loaded: boolean; - onEvent: (options: OnSolarEvent) => TBlackHole; -}; +function isDuration( + item: Duration | DurationUnitsObjectType, +): item is Duration { + return typeof item.days === "function"; +} diff --git a/src/index.ts b/src/index.ts index 350037a..069a8f0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,9 @@ import dayjs from "dayjs"; +import duration from "dayjs/plugin/duration"; import isBetween from "dayjs/plugin/isBetween"; + dayjs.extend(isBetween); +dayjs.extend(duration); export * from "./automation.module"; export * from "./extensions"; From 5361073b2c4cfe9d2d54e8fa9c75cbfa508e1b16 Mon Sep 17 00:00:00 2001 From: Zoe Codez Date: Wed, 15 May 2024 21:43:45 -0500 Subject: [PATCH 3/4] resolution tweaks --- src/extensions/solar-calc.extension.ts | 58 ++++++++++++++++++-------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/src/extensions/solar-calc.extension.ts b/src/extensions/solar-calc.extension.ts index 0905674..87aa5b1 100644 --- a/src/extensions/solar-calc.extension.ts +++ b/src/extensions/solar-calc.extension.ts @@ -1,7 +1,6 @@ import { CronExpression, is, - NONE, TBlackHole, TServiceParams, } from "@digital-alchemy/core"; @@ -51,19 +50,35 @@ const degreesBelowHorizon = { }; const UNLIMITED = 0; type Part = `${number}${CHAR}` | ""; -type Time = `T${Part<"H">}${Part<"M">}${Part<"S">}` | ""; -type ISO_8601 = `P${Part<"Y">}${Part<"M">}${Part<"W">}${Part<"D">}${Time}`; +type ISO_8601_PARTIAL = + | `${Part<"H" | "h">}${Part<"M" | "m">}${Part<"S" | "s">}` + | ""; -type OffsetTypes = +export type OffsetTypes = | Duration | number | DurationUnitsObjectType - | ISO_8601 + | ISO_8601_PARTIAL | [quantity: number, unit: DurationUnitType]; +type TOffset = OffsetTypes | (() => OffsetTypes); + type OnSolarEvent = { label?: string; - offset?: OffsetTypes | (() => OffsetTypes); + /** + * **Any quantity may be negative** + * + * Value must be: + * - (`number`) `ms` + * - (`tuple`) [`quantity`, `unit`] + * - (`string`) `ISO 8601` duration string: `P(#Y)(#M)(#D)(T(#H)(#M)(#S))` + * - (`object`) mapping of units to quantities + * - (`Duration`) `dayjs.duration` object + * - (`function`) a function that returns any of the above + * --- + * Offset calculated at midnight & init + */ + offset?: TOffset; eventName: SolarEvents; exec: () => TBlackHole; }; @@ -218,37 +233,46 @@ export function SolarCalculator({ return now.isBetween(solarReference[a], solarReference[b]); }; - solarReference.onEvent = ({ - eventName, - label, - exec, - offset, - }: OnSolarEvent) => { + function getNextTime(eventName: SolarEvents, offset: TOffset, label: string) { let duration: Duration; + // * if function, unwrap if (is.function(offset)) { offset = offset(); + logger.trace({ eventName, label, offset }, `resolved offset`); } + // * if tuple, resolve if (is.array(offset)) { const [amount, unit] = offset; duration = dayjs.duration(amount, unit); + // * resolve objects, or capture Duration } else if (is.object(offset)) { duration = isDuration(offset) ? (offset as Duration) : dayjs.duration(offset as DurationUnitsObjectType); } + // * resolve from partial ISO 8601 if (is.string(offset)) { - duration = dayjs.duration(offset); + duration = dayjs.duration(`PT${offset.toUpperCase()}`); } + // * ms if (is.number(offset)) { duration = dayjs.duration(offset, "ms"); } + return duration + ? solarReference[eventName].add(duration) + : solarReference[eventName]; + } + + solarReference.onEvent = ({ + eventName, + label, + exec, + offset, + }: OnSolarEvent) => { scheduler.sliding({ exec: async () => await exec(), label, - next: () => - duration - ? solarReference[eventName].add(duration) - : solarReference[eventName], + next: () => getNextTime(eventName, offset, label), reset: CronExpression.EVERY_DAY_AT_MIDNIGHT, }); }; From b07277da842f5c892e38ac29c48d6f625b61c41f Mon Sep 17 00:00:00 2001 From: Zoe Codez Date: Wed, 15 May 2024 22:17:18 -0500 Subject: [PATCH 4/4] type fixes --- package-lock.json | 14 +++---- package.json | 4 +- src/extensions/aggressive-scenes.extension.ts | 5 ++- src/extensions/light-manager.extension.ts | 40 +++++++++++-------- src/extensions/room.extension.ts | 1 - 5 files changed, 36 insertions(+), 28 deletions(-) diff --git a/package-lock.json b/package-lock.json index f3eb08a..1643e4f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { "name": "@digital-alchemy/automation", - "version": "0.3.6", + "version": "0.3.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@digital-alchemy/automation", - "version": "0.3.6", + "version": "0.3.7", "license": "MIT", "dependencies": { "@digital-alchemy/core": "^0.3.15", - "@digital-alchemy/hass": "^0.3.24", + "@digital-alchemy/hass": "^0.3.25", "@digital-alchemy/synapse": "^0.3.5", "dayjs": "^1.11.10", "prom-client": "^15.1.1" @@ -1191,11 +1191,11 @@ } }, "node_modules/@digital-alchemy/hass": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/@digital-alchemy/hass/-/hass-0.3.24.tgz", - "integrity": "sha512-YCe8u1KnwsTlotiPDfc7YOmH3DOCvB/f9IhIEDKCEr8w6/O5DrzbrFeYJNI46OhcaUmjt1YbCTFWxw+vpttYZw==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@digital-alchemy/hass/-/hass-0.3.25.tgz", + "integrity": "sha512-5K/UZUMzPMW9MGoGChzggrPoF7ZiiiJ/u5JqV9kttZmJi1HvhVLZrISW5outthpZa6MiIKGY4HqJcr0GwG3ioA==", "dependencies": { - "@digital-alchemy/core": "^0.3.14", + "@digital-alchemy/core": "^0.3.15", "dayjs": "^1.11.11", "prom-client": "^15.1.2", "ws": "^8.17.0" diff --git a/package.json b/package.json index 596087f..38dccaa 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@digital-alchemy/automation", "repository": "https://github.com/Digital-Alchemy-TS/automation", "homepage": "https://docs.digital-alchemy.app/Automation", - "version": "0.3.6", + "version": "0.3.7", "scripts": { "build": "rm -rf dist/; tsc", "lint": "eslint src", @@ -26,7 +26,7 @@ "license": "MIT", "dependencies": { "@digital-alchemy/core": "^0.3.15", - "@digital-alchemy/hass": "^0.3.24", + "@digital-alchemy/hass": "^0.3.25", "@digital-alchemy/synapse": "^0.3.5", "dayjs": "^1.11.10", "prom-client": "^15.1.1" diff --git a/src/extensions/aggressive-scenes.extension.ts b/src/extensions/aggressive-scenes.extension.ts index 40b7edc..b55ab99 100644 --- a/src/extensions/aggressive-scenes.extension.ts +++ b/src/extensions/aggressive-scenes.extension.ts @@ -61,7 +61,10 @@ export function AggressiveScenes({ return; } - const attributes = entity.attributes as { entity_id: PICK_ENTITY[] }; + // TODO: FIXME + const attributes = entity.attributes as unknown as { + entity_id: PICK_ENTITY[]; + }; if ("entity_id" in attributes) { // ? This is a group const id = attributes.entity_id; diff --git a/src/extensions/light-manager.extension.ts b/src/extensions/light-manager.extension.ts index d82ff0a..6e41788 100644 --- a/src/extensions/light-manager.extension.ts +++ b/src/extensions/light-manager.extension.ts @@ -13,6 +13,7 @@ import { ByIdProxy, ENTITY_STATE, GenericEntityDTO, + HassEntityContext, PICK_ENTITY, PICK_FROM_AREA, TAreaId, @@ -27,22 +28,27 @@ import { } from "../helpers"; type ColorModes = "color_temp" | "xy" | "brightness"; -export type ColorLight = GenericEntityDTO<{ - brightness: number; - color_mode: ColorModes; - color_temp: number; - color_temp_kelvin: number; - entity_id?: PICK_ENTITY<"light">[]; - hs_color: [h: number, s: number]; - max_color_temp_kelvin: number; - max_mireds: number; - min_color_temp_kelvin: number; - min_mireds: number; - rgb_color: [number, number, number]; - supported_color_modes: ColorModes[]; - supported_features: number; - xy_color: [x: number, y: number]; -}>; +export type ColorLight = GenericEntityDTO< + { + brightness: number; + color_mode: ColorModes; + color_temp: number; + color_temp_kelvin: number; + entity_id?: PICK_ENTITY<"light">[]; + hs_color: [h: number, s: number]; + max_color_temp_kelvin: number; + max_mireds: number; + min_color_temp_kelvin: number; + min_mireds: number; + rgb_color: [number, number, number]; + supported_color_modes: ColorModes[]; + supported_features: number; + xy_color: [x: number, y: number]; + }, + string, + HassEntityContext, + "light" +>; // const MAX_DIFFERENCE = 100; type DiffList = { @@ -293,7 +299,7 @@ export function LightManager({ const entity = current[key] as { state: string }; // TODO: Introduce additional checks for items like rgb color return entity.state !== "off"; - }); + }) as PICK_ENTITY<"light">[]; }), ) as PICK_ENTITY<"light">[]; diff --git a/src/extensions/room.extension.ts b/src/extensions/room.extension.ts index e4924c0..e53f1a5 100644 --- a/src/extensions/room.extension.ts +++ b/src/extensions/room.extension.ts @@ -145,7 +145,6 @@ export function Room({ const kelvin = automation.circadian.getKelvin(); const list = entities .map(name => { - // @ts-expect-error wtf const value = definition[name] as SceneLightState; if (is.domain(name, "switch")) {