94 lines
2.5 KiB
TypeScript
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);
|
|
}
|
|
}
|
|
}
|