Files
dpu-api/src/homeassistant/service.ts
2026-02-08 14:55:54 +01:00

94 lines
2.5 KiB
TypeScript

import {
type API_HA_DeskPosition,
BaseService,
type HomeAssistantDeskPositionResult,
type HomeAssistantEntity,
type ServiceResult,
} from "@dpu/shared";
import { calculateSecondsBetween } from "@dpu/shared/dist/timehelper.js";
import { Config } from "../config.js";
import type { HomeAssistantClient } from "./client.js";
export class HomeAssistantService extends BaseService<HomeAssistantClient> {
async startStandingAutomation(): Promise<ServiceResult<unknown | string>> {
try {
const positionResult = await this.getDeskPosition();
if (!positionResult.successful) {
throw Error(positionResult.result as string);
}
const position = positionResult.result as HomeAssistantDeskPositionResult;
if (position.as_boolean) {
throw Error(
`desk is already in standing position and has been for ${position.last_changed.toReadable(true)}`,
);
}
if (position.last_changed.seconds < 300) {
throw Error("desk has moved too recently");
}
const result = await this.getClient().triggerWebhook(
Config.homeassistant.id_webhook_stand,
);
return this.getSuccessfulResult(result);
} catch (error) {
return this.getErrorResult("error starting stand automation.", error);
}
}
async getDeskPosition(): Promise<
ServiceResult<HomeAssistantDeskPositionResult | string>
> {
try {
const raw = await this.getClient().getEntityState(
Config.homeassistant.id_sensor_desk_binary,
);
return this.getSuccessfulResult(this.convertHaEntityToPosResult(raw));
} catch (error) {
return this.getErrorResult("error getting desk position.", error);
}
}
convertHaEntityToPosResult(
raw: HomeAssistantEntity,
): HomeAssistantDeskPositionResult {
const position = Number(raw.state);
return {
raw,
as_boolean: position === 1,
last_changed: calculateSecondsBetween(
new Date(raw.last_changed).getTime(),
Date.now(),
),
};
}
convertPosResultToApiAnswer(
position: HomeAssistantDeskPositionResult,
): API_HA_DeskPosition {
return {
is_standing: position.as_boolean,
last_changed: position.last_changed.toReadable(true),
last_changed_seconds: position.last_changed.seconds,
};
}
async getTemperature(): Promise<ServiceResult<string>> {
try {
const entity = await this.getClient().getEntityState(
Config.homeassistant.id_sensor_roomtemp,
);
return this.getSuccessfulResult(entity.state);
} catch (error) {
return this.getErrorResult("error getting temperature.", error);
}
}
}