implement sse
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import {
|
||||
API_HA_DeskPosition,
|
||||
BaseService,
|
||||
type HomeAssistantDeskPositionResult,
|
||||
type HomeAssistantEntity,
|
||||
type ServiceResult,
|
||||
type API_HA_DeskPosition,
|
||||
BaseService,
|
||||
type HomeAssistantDeskPositionResult,
|
||||
type HomeAssistantEntity,
|
||||
type ServiceResult,
|
||||
} from "@dpu/shared";
|
||||
import { logWarning } from "@dpu/shared/dist/logger.js";
|
||||
import { calculateSecondsBetween } from "@dpu/shared/dist/timehelper.js";
|
||||
@@ -11,105 +11,107 @@ 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();
|
||||
async startStandingAutomation(): Promise<ServiceResult<unknown | string>> {
|
||||
try {
|
||||
const positionResult = await this.getDeskPosition();
|
||||
|
||||
if (!positionResult.successful) {
|
||||
throw Error(positionResult.result as string);
|
||||
}
|
||||
if (!positionResult.successful) {
|
||||
throw Error(positionResult.result as string);
|
||||
}
|
||||
|
||||
const position = positionResult.result as HomeAssistantDeskPositionResult;
|
||||
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.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");
|
||||
}
|
||||
if (position.last_changed.seconds < 300) {
|
||||
throw Error("desk has moved too recently");
|
||||
}
|
||||
|
||||
const result = await this.getClient().triggerWebhook(
|
||||
Config.homeassistant.id_webhook_stand,
|
||||
);
|
||||
const result = await this.getClient().triggerWebhook(
|
||||
Config.homeassistant.id_webhook_stand,
|
||||
);
|
||||
|
||||
return this.getSuccessfulResult(result);
|
||||
} catch (error) {
|
||||
const error_message = `error starting stand automation. ${error instanceof Error ? error.message : error}`;
|
||||
logWarning(error_message);
|
||||
return this.getErrorResult(error_message);
|
||||
}
|
||||
}
|
||||
return this.getSuccessfulResult(result);
|
||||
} catch (error) {
|
||||
const error_message = `error starting stand automation. ${error instanceof Error ? error.message : error}`;
|
||||
logWarning(error_message);
|
||||
return this.getErrorResult(error_message);
|
||||
}
|
||||
}
|
||||
|
||||
async getDeskPosition(): Promise<
|
||||
ServiceResult<HomeAssistantDeskPositionResult | string>
|
||||
> {
|
||||
try {
|
||||
const raw = await this.getClient().getEntityState(
|
||||
Config.homeassistant.id_desk_sensor_binary,
|
||||
);
|
||||
async getDeskPosition(): Promise<
|
||||
ServiceResult<HomeAssistantDeskPositionResult | string>
|
||||
> {
|
||||
try {
|
||||
const raw = await this.getClient().getEntityState(
|
||||
Config.homeassistant.id_desk_sensor_binary,
|
||||
);
|
||||
|
||||
const position = Number(raw.state);
|
||||
const position = Number(raw.state);
|
||||
|
||||
const result = {
|
||||
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(),
|
||||
),
|
||||
};
|
||||
const result = {
|
||||
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(),
|
||||
),
|
||||
};
|
||||
|
||||
return this.getSuccessfulResult(result);
|
||||
} catch (error) {
|
||||
const error_message = "error getting desk position";
|
||||
logWarning(error_message, error);
|
||||
return this.getErrorResult(error_message);
|
||||
}
|
||||
}
|
||||
return this.getSuccessfulResult(result);
|
||||
} catch (error) {
|
||||
const error_message = "error getting desk position";
|
||||
logWarning(error_message, error);
|
||||
return this.getErrorResult(error_message);
|
||||
}
|
||||
}
|
||||
|
||||
convertPosResultToApiAnswer(position: HomeAssistantDeskPositionResult): API_HA_DeskPosition {
|
||||
return {
|
||||
position: position.as_text(),
|
||||
is_standing: position.as_boolean,
|
||||
last_changed: position.last_changed.toReadable(true),
|
||||
}
|
||||
}
|
||||
convertPosResultToApiAnswer(
|
||||
position: HomeAssistantDeskPositionResult,
|
||||
): API_HA_DeskPosition {
|
||||
return {
|
||||
position: position.as_text(),
|
||||
is_standing: position.as_boolean,
|
||||
last_changed: position.last_changed.toReadable(true),
|
||||
};
|
||||
}
|
||||
|
||||
async getTemperatureText(): Promise<ServiceResult<string>> {
|
||||
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;
|
||||
const result = average.toFixed(2);
|
||||
return this.getSuccessfulResult(result);
|
||||
} catch (error) {
|
||||
const error_message = "error getting temperature as text";
|
||||
logWarning(error_message, error);
|
||||
return this.getErrorResult(error_message);
|
||||
}
|
||||
}
|
||||
async getTemperatureText(): Promise<ServiceResult<string>> {
|
||||
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;
|
||||
const result = average.toFixed(2);
|
||||
return this.getSuccessfulResult(result);
|
||||
} catch (error) {
|
||||
const error_message = "error getting temperature as text";
|
||||
logWarning(error_message, error);
|
||||
return this.getErrorResult(error_message);
|
||||
}
|
||||
}
|
||||
|
||||
private async getTemperatures(): Promise<HomeAssistantEntity[]> {
|
||||
try {
|
||||
return await this.getClient().getEntityStates(
|
||||
Config.homeassistant.id_room_sensors,
|
||||
);
|
||||
} catch (error) {
|
||||
logWarning("error getting temperatures:", error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
private async getTemperatures(): Promise<HomeAssistantEntity[]> {
|
||||
try {
|
||||
return await this.getClient().getEntityStates(
|
||||
Config.homeassistant.id_room_sensors,
|
||||
);
|
||||
} catch (error) {
|
||||
logWarning("error getting temperatures:", error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user