ha-frontend/src/data/floor_registry.ts

134 lines
3.2 KiB
TypeScript

import { Connection, createCollection } from "home-assistant-js-websocket";
import { Store } from "home-assistant-js-websocket/dist/store";
import { stringCompare } from "../common/string/compare";
import { HomeAssistant } from "../types";
import { AreaRegistryEntry } from "./area_registry";
import { debounce } from "../common/util/debounce";
export { subscribeAreaRegistry } from "./ws-area_registry";
export interface FloorRegistryEntry {
floor_id: string;
name: string;
level: number;
icon: string | null;
aliases: string[];
}
export interface FloorAreaLookup {
[floorId: string]: AreaRegistryEntry[];
}
export interface FloorRegistryEntryMutableParams {
name: string;
level?: number;
icon?: string | null;
aliases?: string[];
}
const fetchFloorRegistry = (conn: Connection) =>
conn
.sendMessagePromise({
type: "config/floor_registry/list",
})
.then((floors) =>
(floors as FloorRegistryEntry[]).sort((ent1, ent2) => {
if (ent1.level !== ent2.level) {
return (ent1.level ?? 0) - (ent2.level ?? 0);
}
return stringCompare(ent1.name, ent2.name);
})
);
const subscribeFloorRegistryUpdates = (
conn: Connection,
store: Store<FloorRegistryEntry[]>
) =>
conn.subscribeEvents(
debounce(
() =>
fetchFloorRegistry(conn).then((areas: FloorRegistryEntry[]) =>
store.setState(areas, true)
),
500,
true
),
"floor_registry_updated"
);
export const subscribeFloorRegistry = (
conn: Connection,
onChange: (floors: FloorRegistryEntry[]) => void
) =>
createCollection<FloorRegistryEntry[]>(
"_floorRegistry",
fetchFloorRegistry,
subscribeFloorRegistryUpdates,
conn,
onChange
);
export const createFloorRegistryEntry = (
hass: HomeAssistant,
values: FloorRegistryEntryMutableParams
) =>
hass.callWS<FloorRegistryEntry>({
type: "config/floor_registry/create",
...values,
});
export const updateFloorRegistryEntry = (
hass: HomeAssistant,
floorId: string,
updates: Partial<FloorRegistryEntryMutableParams>
) =>
hass.callWS<AreaRegistryEntry>({
type: "config/floor_registry/update",
floor_id: floorId,
...updates,
});
export const deleteFloorRegistryEntry = (
hass: HomeAssistant,
floorId: string
) =>
hass.callWS({
type: "config/floor_registry/delete",
floor_id: floorId,
});
export const getFloorAreaLookup = (
areas: AreaRegistryEntry[]
): FloorAreaLookup => {
const floorAreaLookup: FloorAreaLookup = {};
for (const area of areas) {
if (!area.floor_id) {
continue;
}
if (!(area.floor_id in floorAreaLookup)) {
floorAreaLookup[area.floor_id] = [];
}
floorAreaLookup[area.floor_id].push(area);
}
return floorAreaLookup;
};
export const floorCompare =
(entries?: FloorRegistryEntry[], order?: string[]) =>
(a: string, b: string) => {
const indexA = order ? order.indexOf(a) : -1;
const indexB = order ? order.indexOf(b) : -1;
if (indexA === -1 && indexB === -1) {
const nameA = entries?.[a]?.name ?? a;
const nameB = entries?.[b]?.name ?? b;
return stringCompare(nameA, nameB);
}
if (indexA === -1) {
return 1;
}
if (indexB === -1) {
return -1;
}
return indexA - indexB;
};