This commit is contained in:
Darius
2025-11-18 20:47:00 +01:00
commit 88ae2ac260
12 changed files with 2076 additions and 0 deletions

View File

@@ -0,0 +1,105 @@
import type {
HomeAssistantDeskPositionResult,
HomeAssistantEntity,
} from "@dpu/shared";
import { logWarning } from "@dpu/shared/dist/logger.js";
import { calculateSecondsBetween } from "@dpu/shared/dist/timehelper.js";
import { Config } from "../config.js";
import type { HomeAssistantClient } from "./client.js";
export class HomeAssistantService {
private client: HomeAssistantClient;
constructor(client: HomeAssistantClient) {
this.client = client;
}
async startStandingAutomation(): Promise<unknown | null> {
try {
const position = await this.getDeskPosition();
if (position === null) {
throw Error("error accessing desk api");
}
if (position.as_boolean) {
throw Error("desk is already in standing position");
}
if (position.last_changed.seconds < 120) {
throw Error("desk has moved too recently");
}
return await this.client.triggerWebhook(
Config.homeassistant.id_webhook_stand,
);
} catch (error) {
logWarning("Error starting stand automation:", error);
return null;
}
}
async getDeskPosition(): Promise<HomeAssistantDeskPositionResult | null> {
try {
const raw = await this.client.getEntityState(
Config.homeassistant.id_desk_sensor_binary,
);
const position = Number(raw.state);
return {
raw,
as_boolean: position === 1,
as_text: () => {
if (position === 1) return "standing";
if (position === 0) return "sitting";
return "unknown";
},
last_changed: calculateSecondsBetween(
new Date(raw.last_changed).getTime(),
Date.now(),
),
};
} catch (error) {
logWarning("Error getting desk position:", error);
return null;
}
}
async getTemperatureText(): Promise<string | null> {
try {
const entities = await this.getTemperatures();
const values = entities
.map((entity) => parseFloat(entity.state))
.filter((value) => !Number.isNaN(value));
const average =
values.length > 0
? values.reduce((sum, value) => sum + value, 0) / values.length
: 0;
return average.toFixed(2);
} catch (error) {
logWarning(`Error getting temperature as text`, error);
return null;
}
}
async getTemperatures(): Promise<HomeAssistantEntity[]> {
try {
return await this.client.getEntityStates(
Config.homeassistant.id_room_sensors,
);
} catch (error) {
logWarning("Error getting temperatures:", error);
return [];
}
}
async getTemperature(entityId: string): Promise<HomeAssistantEntity | null> {
try {
return await this.client.getEntityState(entityId);
} catch (error) {
logWarning(`Error getting temperature for ${entityId}:`, error);
return null;
}
}
}