Autodetect motion and occupancy sensors.
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
import { HomeAssistant } from 'custom-card-helpers';
|
||||
import { homeAssistantWSRequest } from '.';
|
||||
import {
|
||||
Entity,
|
||||
EntityList,
|
||||
entityListSchema,
|
||||
ExtendedEntity,
|
||||
extendedEntitySchema
|
||||
} from '../../types.js';
|
||||
|
||||
export class ExtendedEntityCache {
|
||||
protected _cache: Map<string, ExtendedEntity> = new Map();
|
||||
|
||||
/**
|
||||
* Determine if the cache has a given entity_id.
|
||||
* @param id
|
||||
* @returns `true` if the id is in the cache, `false` otherwise.
|
||||
*/
|
||||
public has(id: string): boolean {
|
||||
return this._cache.has(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first value that returns true for the given predicate.
|
||||
* @param func A callback function that returns a boolean.
|
||||
* @returns The first matching value.
|
||||
*/
|
||||
public getMatch(func: (arg: ExtendedEntity) => boolean): ExtendedEntity | null {
|
||||
return [...this._cache.values()].find(func) ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get entity information given an id.
|
||||
* @param id The entity id.
|
||||
* @returns The `ExtendedEntity` for this id.
|
||||
*/
|
||||
public get(id: string): ExtendedEntity | undefined {
|
||||
return this._cache.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a given ExtendedEntity to the cache.
|
||||
* @param extendedEntity
|
||||
*/
|
||||
public set(extendedEntity: ExtendedEntity): void {
|
||||
this._cache.set(extendedEntity.entity_id, extendedEntity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the extended entity information for an entity. May throw.
|
||||
* @param hass The Home Assistant object.
|
||||
* @param entity The entity id.
|
||||
* @param cache An optional ExtendedEntityCache.
|
||||
* @returns The ExtendedEntity information.
|
||||
*/
|
||||
export const getExtendedEntity = async (
|
||||
hass: HomeAssistant,
|
||||
entity: string,
|
||||
cache?: ExtendedEntityCache,
|
||||
): Promise<ExtendedEntity> => {
|
||||
const cachedValue = cache ? cache.get(entity) : undefined;
|
||||
if (cachedValue) {
|
||||
return cachedValue;
|
||||
}
|
||||
const result = await homeAssistantWSRequest<ExtendedEntity>(
|
||||
hass,
|
||||
extendedEntitySchema,
|
||||
{
|
||||
type: 'config/entity_registry/get',
|
||||
entity_id: entity,
|
||||
},
|
||||
);
|
||||
if (cache) {
|
||||
cache.set(result);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the extended entity information for an array of entities.
|
||||
* @param hass The Home Assistant object.
|
||||
* @param entities An array of entity ids.
|
||||
* @param cache An optional ExtendedEntityCache.
|
||||
* @returns A map of entity id to ExtendedEntity objects.
|
||||
*/
|
||||
export const getExtendedEntities = async (
|
||||
hass: HomeAssistant,
|
||||
entities: string[],
|
||||
cache?: ExtendedEntityCache,
|
||||
): Promise<Map<string, Entity>> => {
|
||||
const output: Map<string, Entity> = new Map();
|
||||
const _storeExtendedEntity = async (entity: string): Promise<void> => {
|
||||
output.set(entity, await getExtendedEntity(hass, entity, cache));
|
||||
};
|
||||
await Promise.all(entities.map(_storeExtendedEntity));
|
||||
return output;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a list of all entities from the entity registry.
|
||||
* @param hass The Home Assistant object.
|
||||
* @returns An entity list object.
|
||||
*/
|
||||
export const getAllEntities = async (hass: HomeAssistant): Promise<EntityList> => {
|
||||
return await homeAssistantWSRequest<EntityList>(hass, entityListSchema, {
|
||||
type: 'config/entity_registry/list',
|
||||
});
|
||||
};
|
||||
+18
-2
@@ -4,8 +4,7 @@ import { StyleInfo } from 'lit/directives/style-map.js';
|
||||
import { ZodSchema } from 'zod';
|
||||
import { localize } from '../../localize/localize.js';
|
||||
import {
|
||||
CardHelpers,
|
||||
ExtendedHomeAssistant,
|
||||
CardHelpers, ExtendedHomeAssistant,
|
||||
SignedPath,
|
||||
signedPathSchema,
|
||||
StateParameters
|
||||
@@ -306,3 +305,20 @@ export const sideLoadHomeAssistantElements = async (): Promise<boolean> => {
|
||||
export const isTriggeredState = (state?: HassEntity): boolean => {
|
||||
return !!state && ['on', 'open'].includes(state.state);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get entities from the HASS object.
|
||||
* @param hass
|
||||
* @param domain
|
||||
* @returns
|
||||
*/
|
||||
export const getEntitiesFromHASS = (hass: HomeAssistant, domain?: string): string[] => {
|
||||
if (!hass) {
|
||||
return [];
|
||||
}
|
||||
const entities = Object.keys(hass.states).filter(
|
||||
(eid) => !domain || eid.substr(0, eid.indexOf('.')) === domain,
|
||||
);
|
||||
entities.sort();
|
||||
return entities;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { HomeAssistant } from 'custom-card-helpers';
|
||||
import QuickLRU from 'quick-lru';
|
||||
import { homeAssistantWSRequest } from '.';
|
||||
import {
|
||||
FrigateBrowseMediaSource,
|
||||
ResolvedMedia,
|
||||
resolvedMediaSchema
|
||||
} from '../types.js';
|
||||
import { homeAssistantWSRequest } from './ha';
|
||||
FrigateBrowseMediaSource,
|
||||
ResolvedMedia,
|
||||
resolvedMediaSchema
|
||||
} from '../../types.js';
|
||||
|
||||
// It's important the cache size be at least as large as the largest likely
|
||||
// media query or media items will from a given query will be evicted for other
|
||||
@@ -21,19 +21,42 @@ export class ResolvedMediaCache {
|
||||
this._cache = new QuickLRU({ maxSize: RESOLVED_MEDIA_CACHE_SIZE });
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the cache has a given id.
|
||||
* @param id
|
||||
* @returns `true` if the id is in the cache, `false` otherwise.
|
||||
*/
|
||||
public has(id: string): boolean {
|
||||
return this._cache.has(id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get resolved media information given an id.
|
||||
* @param id The id.
|
||||
* @returns The `ResolvedMedia` for this id.
|
||||
*/
|
||||
public get(id: string): ResolvedMedia | undefined {
|
||||
return this._cache.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a given ResolvedMedia to the cache.
|
||||
* @param id The id for the object.
|
||||
* @param resolvedMedia The `ResolvedMedia` object.
|
||||
*/
|
||||
public set(id: string, resolvedMedia: ResolvedMedia): void {
|
||||
this._cache.set(id, resolvedMedia);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a given media source item.
|
||||
* @param hass The Home Assistant object.
|
||||
* @param mediaSource The media source object.
|
||||
* @param cache An optional ResolvedMediaCache object.
|
||||
* @returns
|
||||
*/
|
||||
export const resolveMedia = async (
|
||||
hass: HomeAssistant,
|
||||
mediaSource?: FrigateBrowseMediaSource,
|
||||
Reference in New Issue
Block a user