documentation

This commit is contained in:
Darius
2025-11-22 03:16:54 +01:00
parent e1ca9d8963
commit ce1412f63d
5 changed files with 1084 additions and 114 deletions

View File

@@ -1,17 +1,49 @@
import type { HomeAssistantDeskPositionResult } from "@dpu/shared";
import { logInfo } from "@dpu/shared/dist/logger.js";
import type { FastifyReply, FastifyRequest } from "fastify";
import fastify from "fastify";
import Fastify from "fastify";
import fastifyAxios from "fastify-axios";
import {
serializerCompiler,
validatorCompiler,
type ZodTypeProvider,
} from "fastify-type-provider-zod";
import z from "zod";
import { Config } from "./config.js";
import { HomeAssistantClient } from "./homeassistant/client.js";
import { homeAssistantRoutes } from "./homeassistant/routes.js";
import { HomeAssistantService } from "./homeassistant/service.js";
import { TidalClient } from "./tidal/client.js";
import { tidalRoutes } from "./tidal/routes.js";
import { TidalService } from "./tidal/service.js";
const server = fastify();
const fastify = Fastify().withTypeProvider<ZodTypeProvider>();
await server.register(fastifyAxios, {
fastify.setValidatorCompiler(validatorCompiler);
fastify.setSerializerCompiler(serializerCompiler);
await fastify.register(require("@fastify/swagger"), {
openapi: {
info: {
title: "DPU API",
description: "API Documentation",
version: "1.0.0",
},
servers: [{ url: "http://localhost:8080", description: "Development" }],
},
transform: ({ schema, url }: { schema: unknown; url: string }) => {
return { schema, url };
},
});
await fastify.register(require("@fastify/swagger-ui"), {
routePrefix: "/docs",
uiConfig: {
docExpansion: "list",
deepLinking: false,
},
});
await fastify.register(fastifyAxios, {
clients: {
homeassistant: {
baseURL: Config.homeassistant.api_url,
@@ -25,6 +57,12 @@ await server.register(fastifyAxios, {
},
});
const haClient = new HomeAssistantClient(fastify.axios.homeassistant);
const haService = new HomeAssistantService(haClient);
const tidalClient = new TidalClient(fastify.axios.tidal);
const tidalService = new TidalService(tidalClient);
async function verifyAPIKey(
request: FastifyRequest,
reply: FastifyReply,
@@ -37,119 +75,35 @@ async function verifyAPIKey(
}
}
const haClient = new HomeAssistantClient(server.axios.homeassistant);
const haService = new HomeAssistantService(haClient);
const port = parseInt(Config.port, 10);
const tidalClient = new TidalClient(server.axios.tidal);
const tidalService = new TidalService(tidalClient);
// Register routes
await fastify.register(homeAssistantRoutes, { haService, verifyAPIKey });
await fastify.register(tidalRoutes, { tidalService, verifyAPIKey });
// HOME ASSISTANT
server.get("/homeassistant/desk/position", async (_request, reply) => {
const service_result = await haService.getDeskPosition();
if (!service_result.successful) {
reply.code(418);
return { error: service_result.result };
}
const position_result =
service_result.result as HomeAssistantDeskPositionResult;
return {
position: position_result.as_text(),
is_standing: position_result.as_boolean,
last_changed: position_result.last_changed.toReadable(true),
};
});
server.post(
"/homeassistant/desk/stand",
{ preHandler: verifyAPIKey },
async (_request, reply) => {
const service_result = await haService.startStandingAutomation();
if (!service_result.successful) {
reply.code(418);
return { error: service_result.result };
}
return service_result.result;
fastify.get(
"/ping",
{
schema: {
description: "Health check endpoint",
tags: ["default"],
response: {
200: z.literal("pong"),
},
},
},
async (_request, _reply) => {
return "pong" as const;
},
);
server.get("/homeassistant/temperature", async (_request, reply) => {
const service_result = await haService.getTemperatureText();
if (!service_result.successful) {
reply.code(418);
return { error: service_result.result };
await fastify.ready();
fastify.listen({ port: port, host: "0.0.0.0" }, (err, address) => {
if (err) {
console.error(err);
process.exit(1);
}
return service_result.result;
console.log(`Server listening at ${address}`);
});
// TIDAL
server.get("/tidal/song", async (_request, reply) => {
const service_result = await tidalService.getSong();
if (!service_result.successful) {
reply.code(418);
return { error: service_result.result };
}
return service_result.result;
});
server.get("/tidal/songFormatted", async (_request, reply) => {
const service_result = await tidalService.getSongFormatted();
if (!service_result.successful) {
reply.code(418);
return { error: service_result.result };
}
return service_result.result;
});
server.get("/tidal/volume", async (_request, reply) => {
const service_result = await tidalService.getVolume();
if (!service_result.successful) {
reply.code(418);
return { error: service_result.result };
}
return service_result.result;
});
server.post(
"/tidal/volume",
{ preHandler: verifyAPIKey },
async (request, reply) => {
const volume = request.body as string;
const service_result = await tidalService.setVolume(volume);
if (!service_result.successful) {
reply.code(418);
return { error: service_result.result };
}
return service_result.result;
},
);
// Default
server.get("/ping", async (_request, _reply) => {
return "pong";
});
server.listen(
{ port: parseInt(Config.port, 10), host: "0.0.0.0" },
(err, address) => {
if (err) {
console.error(err);
process.exit(1);
}
console.log(`Server listening at ${address}`);
},
);
console.log(`API docs available at http://localhost:${port}/docs`);