change from poll to update from hooks
This commit is contained in:
12
.env.example
12
.env.example
@@ -1,11 +1 @@
|
|||||||
API_KEY=apiKey
|
look into config.ts
|
||||||
PORT=
|
|
||||||
ENV_DEV=true
|
|
||||||
|
|
||||||
TIDAL_HOST=http://localhost:47836
|
|
||||||
|
|
||||||
HA_API_URL=http://homeassistant.com/api/states/
|
|
||||||
HA_API_TOKEN=Nina hätte hier jetzt ihr Token ausversehen stehen hihi
|
|
||||||
HA_ROOMTEMP_SENSOR_IDS=entityId(,separated)
|
|
||||||
HA_STANDING_WEBHOOK=webhookId
|
|
||||||
HA_DESK_SENSOR_BINARY=entityId
|
|
||||||
|
|||||||
26
package-lock.json
generated
26
package-lock.json
generated
@@ -30,8 +30,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@dpu/shared": {
|
"node_modules/@dpu/shared": {
|
||||||
"version": "1.9.1",
|
"version": "1.9.6",
|
||||||
"resolved": "git+https://git.dariusbag.dev/DarDarBinks/dpu-shared.git#2b85020d52e9f79956e2fde3833eef071f6b73af",
|
"resolved": "git+https://git.dariusbag.dev/DarDarBinks/dpu-shared.git#872d3755d06c8e8c6452d8ab7212b6426d84943b",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/ws": "^8.18.1",
|
"@types/ws": "^8.18.1",
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
@@ -679,9 +679,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@fastify/swagger": {
|
"node_modules/@fastify/swagger": {
|
||||||
"version": "9.6.1",
|
"version": "9.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/@fastify/swagger/-/swagger-9.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/@fastify/swagger/-/swagger-9.7.0.tgz",
|
||||||
"integrity": "sha512-fKlpJqFMWoi4H3EdUkDaMteEYRCfQMEkK0HJJ0eaf4aRlKd8cbq0pVkOfXDXmtvMTXYcnx3E+l023eFDBsA1HA==",
|
"integrity": "sha512-Vp1SC1GC2Hrkd3faFILv86BzUNyFz5N4/xdExqtCgkGASOzn/x+eMe4qXIGq7cdT6wif/P/oa6r1Ruqx19paZA==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@@ -790,9 +790,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "24.10.11",
|
"version": "24.10.12",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.11.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.12.tgz",
|
||||||
"integrity": "sha512-/Af7O8r1frCVgOz0I62jWUtMohJ0/ZQU/ZoketltOJPZpnb17yoNc9BSoVuV9qlaIXJiPNOpsfq4ByFajSArNQ==",
|
"integrity": "sha512-68e+T28EbdmLSTkPgs3+UacC6rzmqrcWFPQs1C8mwJhI/r5Uxr0yEuQotczNRROd1gq30NGxee+fo0rSIxpyAw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~7.16.0"
|
"undici-types": "~7.16.0"
|
||||||
@@ -872,13 +872,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/axios": {
|
"node_modules/axios": {
|
||||||
"version": "1.13.4",
|
"version": "1.13.5",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.4.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz",
|
||||||
"integrity": "sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==",
|
"integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"follow-redirects": "^1.15.6",
|
"follow-redirects": "^1.15.11",
|
||||||
"form-data": "^4.0.4",
|
"form-data": "^4.0.5",
|
||||||
"proxy-from-env": "^1.1.0"
|
"proxy-from-env": "^1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
"clean": "rimraf dist",
|
"clean": "rimraf dist",
|
||||||
"build": "npm run clean && tsc",
|
"build": "npm run clean && tsc",
|
||||||
"start": "node dist/index.js",
|
"start": "node dist/index.js",
|
||||||
"dev": "tsx watch --inspect-brk src/index.ts"
|
"dev": "tsx watch src/index.ts",
|
||||||
|
"devdbg": "tsx watch --inspect-brk src/index.ts"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "Darius",
|
"author": "Darius",
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export const Config = {
|
|||||||
api_token: process.env.HA_API_TOKEN || "",
|
api_token: process.env.HA_API_TOKEN || "",
|
||||||
|
|
||||||
id_sensor_desk_binary: process.env.HA_SENSOR_DESK_BINARY || "",
|
id_sensor_desk_binary: process.env.HA_SENSOR_DESK_BINARY || "",
|
||||||
id_sensors_roomtemp: process.env.HA_SENSORS_ROOMTEMP?.split(",") || [],
|
id_sensor_roomtemp: process.env.HA_SENSOR_ROOMTEMP || "",
|
||||||
|
|
||||||
id_webhook_stand: process.env.HA_STANDING_WEBHOOK || "",
|
id_webhook_stand: process.env.HA_STANDING_WEBHOOK || "",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
BaseService,
|
BaseService,
|
||||||
type GristRecord_PersonalGoals,
|
type GristRecord_PersonalGoals,
|
||||||
logWarning,
|
|
||||||
type ServiceResult,
|
type ServiceResult,
|
||||||
} from "@dpu/shared";
|
} from "@dpu/shared";
|
||||||
import { DateTime } from "luxon";
|
import { DateTime } from "luxon";
|
||||||
@@ -25,14 +24,12 @@ export class GristService extends BaseService<GristClient> {
|
|||||||
this.transformToPersonalGoals(response.records[0].fields),
|
this.transformToPersonalGoals(response.records[0].fields),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const error_message = "error finding record from grist";
|
return this.getErrorResult(
|
||||||
logWarning(error_message);
|
"error getting record from grist. record not found.",
|
||||||
return this.getErrorResult(error_message);
|
);
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (error) {
|
||||||
const error_message = "error getting record from grist";
|
return this.getErrorResult("error getting record from grist.", error);
|
||||||
logWarning(error_message);
|
|
||||||
return this.getErrorResult(error_message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,16 +2,6 @@ import { BaseClient, type HomeAssistantEntity } from "@dpu/shared";
|
|||||||
import { printNetworkError } from "@dpu/shared/dist/logger.js";
|
import { printNetworkError } from "@dpu/shared/dist/logger.js";
|
||||||
|
|
||||||
export class HomeAssistantClient extends BaseClient {
|
export class HomeAssistantClient extends BaseClient {
|
||||||
async getEntityStates(entityIds: string[]): Promise<HomeAssistantEntity[]> {
|
|
||||||
try {
|
|
||||||
const promises = entityIds.map((id) => this.getEntityState(id));
|
|
||||||
return await Promise.all(promises);
|
|
||||||
} catch (error) {
|
|
||||||
printNetworkError(error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async getEntityState(entityId: string): Promise<HomeAssistantEntity> {
|
async getEntityState(entityId: string): Promise<HomeAssistantEntity> {
|
||||||
try {
|
try {
|
||||||
const response = await this.getAxios().get<HomeAssistantEntity>(
|
const response = await this.getAxios().get<HomeAssistantEntity>(
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ export async function homeAssistantRoutes(
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
async (_request, reply) => {
|
async (_request, reply) => {
|
||||||
const service_result = await haService.getTemperatureText();
|
const service_result = await haService.getTemperature();
|
||||||
|
|
||||||
if (!service_result.successful) {
|
if (!service_result.successful) {
|
||||||
reply.code(418);
|
reply.code(418);
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import {
|
|||||||
type HomeAssistantEntity,
|
type HomeAssistantEntity,
|
||||||
type ServiceResult,
|
type ServiceResult,
|
||||||
} from "@dpu/shared";
|
} from "@dpu/shared";
|
||||||
import { logWarning } from "@dpu/shared/dist/logger.js";
|
|
||||||
import { calculateSecondsBetween } from "@dpu/shared/dist/timehelper.js";
|
import { calculateSecondsBetween } from "@dpu/shared/dist/timehelper.js";
|
||||||
import { Config } from "../config.js";
|
import { Config } from "../config.js";
|
||||||
import type { HomeAssistantClient } from "./client.js";
|
import type { HomeAssistantClient } from "./client.js";
|
||||||
@@ -37,9 +36,7 @@ export class HomeAssistantService extends BaseService<HomeAssistantClient> {
|
|||||||
|
|
||||||
return this.getSuccessfulResult(result);
|
return this.getSuccessfulResult(result);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const error_message = `error starting stand automation. ${error instanceof Error ? error.message : error}`;
|
return this.getErrorResult("error starting stand automation.", error);
|
||||||
logWarning(error_message);
|
|
||||||
return this.getErrorResult(error_message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,25 +48,27 @@ export class HomeAssistantService extends BaseService<HomeAssistantClient> {
|
|||||||
Config.homeassistant.id_sensor_desk_binary,
|
Config.homeassistant.id_sensor_desk_binary,
|
||||||
);
|
);
|
||||||
|
|
||||||
const position = Number(raw.state);
|
return this.getSuccessfulResult(this.convertHaEntityToPosResult(raw));
|
||||||
|
|
||||||
const result = {
|
|
||||||
raw,
|
|
||||||
as_boolean: position === 1,
|
|
||||||
last_changed: calculateSecondsBetween(
|
|
||||||
new Date(raw.last_changed).getTime(),
|
|
||||||
Date.now(),
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
||||||
return this.getSuccessfulResult(result);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const error_message = "error getting desk position";
|
return this.getErrorResult("error getting desk position.", error);
|
||||||
logWarning(error_message, error);
|
|
||||||
return this.getErrorResult(error_message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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(
|
convertPosResultToApiAnswer(
|
||||||
position: HomeAssistantDeskPositionResult,
|
position: HomeAssistantDeskPositionResult,
|
||||||
): API_HA_DeskPosition {
|
): API_HA_DeskPosition {
|
||||||
@@ -80,33 +79,15 @@ export class HomeAssistantService extends BaseService<HomeAssistantClient> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async getTemperatureText(): Promise<ServiceResult<string>> {
|
async getTemperature(): Promise<ServiceResult<string>> {
|
||||||
try {
|
try {
|
||||||
const entities = await this.getTemperatures();
|
const entity = await this.getClient().getEntityState(
|
||||||
const values = entities
|
Config.homeassistant.id_sensor_roomtemp,
|
||||||
.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_sensors_roomtemp,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return this.getSuccessfulResult(entity.state);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logWarning("error getting temperatures:", error);
|
return this.getErrorResult("error getting temperature.", error);
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,31 @@
|
|||||||
import type {
|
import type {
|
||||||
API_HA_DeskPosition,
|
API_HA_DeskPosition,
|
||||||
|
ComponentUpdate,
|
||||||
GristRecord_PersonalGoals,
|
GristRecord_PersonalGoals,
|
||||||
|
HA_Update,
|
||||||
|
HomeAssistantEntity,
|
||||||
TidalGetCurrent,
|
TidalGetCurrent,
|
||||||
} from "@dpu/shared";
|
} from "@dpu/shared";
|
||||||
import type { FastifyInstance } from "fastify";
|
import type { FastifyInstance, FastifyReply } from "fastify";
|
||||||
|
import type { FastifyRequest } from "fastify/types/request.js";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { Config } from "../config.js";
|
||||||
|
import type { HomeAssistantService } from "../homeassistant/service.js";
|
||||||
import type { HomepageService } from "./service.js";
|
import type { HomepageService } from "./service.js";
|
||||||
|
|
||||||
export async function homepageRoutes(
|
export async function homepageRoutes(
|
||||||
fastify: FastifyInstance,
|
fastify: FastifyInstance,
|
||||||
{
|
{
|
||||||
hpService,
|
hpService,
|
||||||
|
haService,
|
||||||
|
verifyAPIKey,
|
||||||
}: {
|
}: {
|
||||||
hpService: HomepageService;
|
hpService: HomepageService;
|
||||||
|
haService: HomeAssistantService;
|
||||||
|
verifyAPIKey: (
|
||||||
|
request: FastifyRequest,
|
||||||
|
reply: FastifyReply,
|
||||||
|
) => Promise<void>;
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
fastify.get(
|
fastify.get(
|
||||||
@@ -47,4 +60,96 @@ export async function homepageRoutes(
|
|||||||
return service_result.result;
|
return service_result.result;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
fastify.post(
|
||||||
|
"/homepage/update/homeassistant",
|
||||||
|
{
|
||||||
|
preHandler: verifyAPIKey,
|
||||||
|
schema: {
|
||||||
|
description: "Update information for component on dpu status page",
|
||||||
|
tags: ["homepage"],
|
||||||
|
body: z.custom<unknown>(),
|
||||||
|
response: {
|
||||||
|
200: z.string(),
|
||||||
|
418: z.object({
|
||||||
|
error: z.string(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
hide: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
async (request, reply) => {
|
||||||
|
const ha_update = request.body as HA_Update;
|
||||||
|
const ha_entity: HomeAssistantEntity = {
|
||||||
|
entity_id: ha_update.entity_id,
|
||||||
|
state: ha_update.state,
|
||||||
|
attributes: ha_update.attributes,
|
||||||
|
last_changed: ha_update.timestamp,
|
||||||
|
};
|
||||||
|
const updates: ComponentUpdate[] = [];
|
||||||
|
|
||||||
|
switch (ha_update.entity_id) {
|
||||||
|
case Config.homeassistant.id_sensor_desk_binary: {
|
||||||
|
updates.push({
|
||||||
|
component: "desk",
|
||||||
|
data: haService.convertPosResultToApiAnswer(
|
||||||
|
haService.convertHaEntityToPosResult(ha_entity),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Config.homeassistant.id_sensor_roomtemp:
|
||||||
|
updates.push({
|
||||||
|
component: "desk",
|
||||||
|
data: ha_entity.state,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
const service_result = await hpService.updatePartial(updates);
|
||||||
|
|
||||||
|
if (!service_result.successful) {
|
||||||
|
reply.code(418);
|
||||||
|
return { error: service_result.result };
|
||||||
|
}
|
||||||
|
|
||||||
|
return service_result.result;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
fastify.post(
|
||||||
|
"/homepage/update/tidal",
|
||||||
|
{
|
||||||
|
preHandler: verifyAPIKey,
|
||||||
|
schema: {
|
||||||
|
description: "Update information for component on dpu status page",
|
||||||
|
tags: ["homepage"],
|
||||||
|
body: z.custom<TidalGetCurrent>(),
|
||||||
|
response: {
|
||||||
|
200: z.string(),
|
||||||
|
418: z.object({
|
||||||
|
error: z.string(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
hide: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
async (request, reply) => {
|
||||||
|
const update = request.body as TidalGetCurrent;
|
||||||
|
const service_result = await hpService.updatePartial([
|
||||||
|
{
|
||||||
|
component: "tidal",
|
||||||
|
data: update,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!service_result.successful) {
|
||||||
|
reply.code(418);
|
||||||
|
return { error: service_result.result };
|
||||||
|
}
|
||||||
|
|
||||||
|
return service_result.result;
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
type TidalGetCurrent,
|
type TidalGetCurrent,
|
||||||
type WsService,
|
type WsService,
|
||||||
} from "@dpu/shared";
|
} from "@dpu/shared";
|
||||||
import { logInfo, logWarning } from "@dpu/shared/dist/logger.js";
|
import { logInfo } from "@dpu/shared/dist/logger.js";
|
||||||
import type { GristService } from "../grist/service";
|
import type { GristService } from "../grist/service";
|
||||||
import type { HomeAssistantService } from "../homeassistant/service";
|
import type { HomeAssistantService } from "../homeassistant/service";
|
||||||
import type { TidalService } from "../tidal/service";
|
import type { TidalService } from "../tidal/service";
|
||||||
@@ -58,10 +58,8 @@ export class HomepageService extends BaseService<null> {
|
|||||||
grist_personal_goals: personal_goals,
|
grist_personal_goals: personal_goals,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
} catch {
|
} catch (error) {
|
||||||
const error_message = "error getting all information";
|
return this.getErrorResult("error getting all information.", error);
|
||||||
logWarning(error_message);
|
|
||||||
return this.getErrorResult(error_message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +73,7 @@ export class HomepageService extends BaseService<null> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _getTemp(): Promise<string | null> {
|
private async _getTemp(): Promise<string | null> {
|
||||||
const temp = await this.haService.getTemperatureText();
|
const temp = await this.haService.getTemperature();
|
||||||
return temp.successful ? temp.result : null;
|
return temp.successful ? temp.result : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,22 +108,37 @@ export class HomepageService extends BaseService<null> {
|
|||||||
return newPoll;
|
return newPoll;
|
||||||
}
|
}
|
||||||
|
|
||||||
async updatePartial(components: string[]): Promise<void> {
|
async updatePartial(
|
||||||
|
components: ComponentUpdate[],
|
||||||
|
): Promise<ServiceResult<string>> {
|
||||||
const updates: ComponentUpdate[] = [];
|
const updates: ComponentUpdate[] = [];
|
||||||
for (const component of components) {
|
for (const component of components) {
|
||||||
switch (component) {
|
switch (component.component) {
|
||||||
case "desk": {
|
case "desk": {
|
||||||
this.updateHaDesk(await this._getDesk(), updates);
|
this.updateHaDesk(
|
||||||
|
(component.data as API_HA_DeskPosition) ?? (await this._getDesk()),
|
||||||
|
updates,
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "temp":
|
case "temp":
|
||||||
this.updateHaTemp(await this._getTemp(), updates);
|
this.updateHaTemp(
|
||||||
|
(component.data as string) ?? (await this._getTemp()),
|
||||||
|
updates,
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case "tidal":
|
case "tidal":
|
||||||
this.updateTidal(await this._getTidal(), updates);
|
this.updateTidal(
|
||||||
|
(component.data as TidalGetCurrent) ?? (await this._getTidal()),
|
||||||
|
updates,
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case "grist":
|
case "grist":
|
||||||
this.updateGristPG(await this._getGristPG(), updates);
|
this.updateGristPG(
|
||||||
|
(component.data as GristRecord_PersonalGoals) ??
|
||||||
|
(await this._getGristPG()),
|
||||||
|
updates,
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
@@ -135,9 +148,11 @@ export class HomepageService extends BaseService<null> {
|
|||||||
type: "update",
|
type: "update",
|
||||||
data: updates,
|
data: updates,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return this.getSuccessfulResult("update broadcasted");
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateHaDesk(
|
updateHaDesk(
|
||||||
new_ha_desk_position: API_HA_DeskPosition | null,
|
new_ha_desk_position: API_HA_DeskPosition | null,
|
||||||
updates: ComponentUpdate[],
|
updates: ComponentUpdate[],
|
||||||
): void {
|
): void {
|
||||||
@@ -153,10 +168,7 @@ export class HomepageService extends BaseService<null> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateHaTemp(
|
updateHaTemp(new_ha_temp: string | null, updates: ComponentUpdate[]): void {
|
||||||
new_ha_temp: string | null,
|
|
||||||
updates: ComponentUpdate[],
|
|
||||||
): void {
|
|
||||||
if (this.lastPoll.ha_temp !== new_ha_temp) {
|
if (this.lastPoll.ha_temp !== new_ha_temp) {
|
||||||
this.lastPoll.ha_temp = new_ha_temp;
|
this.lastPoll.ha_temp = new_ha_temp;
|
||||||
updates.push({
|
updates.push({
|
||||||
@@ -166,7 +178,7 @@ export class HomepageService extends BaseService<null> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateTidal(
|
updateTidal(
|
||||||
new_tidal_current: TidalGetCurrent | null,
|
new_tidal_current: TidalGetCurrent | null,
|
||||||
updates: ComponentUpdate[],
|
updates: ComponentUpdate[],
|
||||||
): void {
|
): void {
|
||||||
@@ -184,7 +196,7 @@ export class HomepageService extends BaseService<null> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateGristPG(
|
updateGristPG(
|
||||||
new_grist_personal_goals: GristRecord_PersonalGoals | null,
|
new_grist_personal_goals: GristRecord_PersonalGoals | null,
|
||||||
updates: ComponentUpdate[],
|
updates: ComponentUpdate[],
|
||||||
): void {
|
): void {
|
||||||
@@ -227,10 +239,16 @@ export class HomepageService extends BaseService<null> {
|
|||||||
startPolling(): void {
|
startPolling(): void {
|
||||||
logInfo("Polling started");
|
logInfo("Polling started");
|
||||||
|
|
||||||
const config: [string[], number][] = [
|
const config: [ComponentUpdate[], number][] = [
|
||||||
[["tidal"], 20_000],
|
//[[{ component: "tidal", data: null }], 20_000],
|
||||||
[["desk"], 60_000],
|
//[[{ component: "desk", data: null }], 60_000],
|
||||||
[["temp", "grist"], 600_000],
|
[
|
||||||
|
[
|
||||||
|
//{ component: "temp", data: null },
|
||||||
|
{ component: "grist", data: null },
|
||||||
|
],
|
||||||
|
600_000,
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
this.pollingIntervals = config.map(([components, interval]) =>
|
this.pollingIntervals = config.map(([components, interval]) =>
|
||||||
|
|||||||
10
src/index.ts
10
src/index.ts
@@ -8,10 +8,10 @@ import type { FastifyReply, FastifyRequest } from "fastify";
|
|||||||
import Fastify from "fastify";
|
import Fastify from "fastify";
|
||||||
import fastifyAxios from "fastify-axios";
|
import fastifyAxios from "fastify-axios";
|
||||||
import {
|
import {
|
||||||
jsonSchemaTransform,
|
jsonSchemaTransform,
|
||||||
serializerCompiler,
|
serializerCompiler,
|
||||||
validatorCompiler,
|
validatorCompiler,
|
||||||
type ZodTypeProvider,
|
type ZodTypeProvider,
|
||||||
} from "fastify-type-provider-zod";
|
} from "fastify-type-provider-zod";
|
||||||
import { SwaggerTheme, SwaggerThemeNameEnum } from "swagger-themes";
|
import { SwaggerTheme, SwaggerThemeNameEnum } from "swagger-themes";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
@@ -129,7 +129,7 @@ await fastify.register(gristRoutes, { gristService });
|
|||||||
await fastify.register(homeAssistantRoutes, { haService, verifyAPIKey });
|
await fastify.register(homeAssistantRoutes, { haService, verifyAPIKey });
|
||||||
await fastify.register(tidalRoutes, { tidalService, verifyAPIKey });
|
await fastify.register(tidalRoutes, { tidalService, verifyAPIKey });
|
||||||
await fastify.register(wsRoutes, { wsService });
|
await fastify.register(wsRoutes, { wsService });
|
||||||
await fastify.register(homepageRoutes, { hpService });
|
await fastify.register(homepageRoutes, { hpService, haService, verifyAPIKey });
|
||||||
|
|
||||||
fastify.get(
|
fastify.get(
|
||||||
"/ping",
|
"/ping",
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import {
|
|||||||
type ServiceResult,
|
type ServiceResult,
|
||||||
type TidalGetCurrent,
|
type TidalGetCurrent,
|
||||||
} from "@dpu/shared";
|
} from "@dpu/shared";
|
||||||
import { logWarning } from "@dpu/shared/dist/logger.js";
|
|
||||||
import type { TidalClient } from "./client.js";
|
import type { TidalClient } from "./client.js";
|
||||||
|
|
||||||
export class TidalService extends BaseService<TidalClient> {
|
export class TidalService extends BaseService<TidalClient> {
|
||||||
@@ -27,10 +26,8 @@ export class TidalService extends BaseService<TidalClient> {
|
|||||||
const response = await this.getClient().get<TidalGetCurrent>("current");
|
const response = await this.getClient().get<TidalGetCurrent>("current");
|
||||||
|
|
||||||
return this.getSuccessfulResult(response);
|
return this.getSuccessfulResult(response);
|
||||||
} catch {
|
} catch (error) {
|
||||||
const error_message = "error getting song from tidal";
|
return this.getErrorResult("error getting song from tidal.", error);
|
||||||
logWarning(error_message);
|
|
||||||
return this.getErrorResult(error_message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,10 +38,8 @@ export class TidalService extends BaseService<TidalClient> {
|
|||||||
return this.getSuccessfulResult(
|
return this.getSuccessfulResult(
|
||||||
Math.round(response.volume * 100), // * 100 because it's a decimal and we want a percentage
|
Math.round(response.volume * 100), // * 100 because it's a decimal and we want a percentage
|
||||||
);
|
);
|
||||||
} catch {
|
} catch (error) {
|
||||||
const error_message = "error getting volume from tidal";
|
return this.getErrorResult("error getting volume from tidal.", error);
|
||||||
logWarning(error_message);
|
|
||||||
return this.getErrorResult(error_message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,9 +68,7 @@ export class TidalService extends BaseService<TidalClient> {
|
|||||||
return await this.setVolumeToTidal(clampValue);
|
return await this.setVolumeToTidal(clampValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
const error_message = "error parsing volume to set";
|
return this.getErrorResult("error parsing volume to set.");
|
||||||
logWarning(error_message);
|
|
||||||
return this.getErrorResult(error_message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async setVolumeToTidal(
|
async setVolumeToTidal(
|
||||||
@@ -88,10 +81,8 @@ export class TidalService extends BaseService<TidalClient> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return this.getSuccessfulResult(Math.round(volume));
|
return this.getSuccessfulResult(Math.round(volume));
|
||||||
} catch {
|
} catch (error) {
|
||||||
const error_message = "error setting volume from tidal";
|
return this.getErrorResult("error setting volume from tidal.", error);
|
||||||
logWarning(error_message);
|
|
||||||
return this.getErrorResult(error_message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user