formatting and grist
This commit is contained in:
@@ -2,8 +2,7 @@ API_KEY=apiKey
|
||||
PORT=
|
||||
ENV_DEV=true
|
||||
|
||||
TIDAL_HOST=http://localhost
|
||||
TIDAL_PORT=47836
|
||||
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
|
||||
|
||||
10
package-lock.json
generated
10
package-lock.json
generated
@@ -28,8 +28,8 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@dpu/shared": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "git+https://git.dariusbag.dev/DarDarBinks/dpu-shared.git#cd95b631746e3f5d50120c68f69b934cf7f8e87b",
|
||||
"version": "1.8.1",
|
||||
"resolved": "git+https://git.dariusbag.dev/DarDarBinks/dpu-shared.git#27dc6f2b1214b8e2aff65de510caea402c2f88db",
|
||||
"dependencies": {
|
||||
"@types/ws": "^8.18.1",
|
||||
"axios": "^1.7.9",
|
||||
@@ -1383,9 +1383,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/get-tsconfig": {
|
||||
"version": "4.13.5",
|
||||
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.5.tgz",
|
||||
"integrity": "sha512-v4/4xAEpBRp6SvCkWhnGCaLkJf9IwWzrsygJPxD/+p2/xPE3C5m2fA9FD0Ry9tG+Rqqq3gBzHSl6y1/T9V/tMQ==",
|
||||
"version": "4.13.6",
|
||||
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz",
|
||||
"integrity": "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"clean": "rimraf dist",
|
||||
"build": "npm run clean && tsc",
|
||||
"start": "node dist/index.js",
|
||||
"dev": "tsx watch src/index.ts"
|
||||
"dev": "tsx watch --inspect-brk src/index.ts"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Darius",
|
||||
|
||||
@@ -7,18 +7,24 @@ export const Config = {
|
||||
port: process.env.PORT || "8080",
|
||||
env_dev: process.env.ENV_DEV || false,
|
||||
|
||||
tidal: {
|
||||
host: process.env.TIDAL_HOST || "",
|
||||
port: process.env.TIDAL_PORT || "",
|
||||
grist: {
|
||||
api_url: process.env.GRIST_API_URL || "",
|
||||
api_token: process.env.GRIST_API_TOKEN || "",
|
||||
|
||||
table_personal_goals_path: process.env.GRIST_TPG_PATH || "",
|
||||
},
|
||||
|
||||
homeassistant: {
|
||||
api_url: process.env.HA_API_URL || "",
|
||||
api_token: process.env.HA_API_TOKEN || "",
|
||||
|
||||
id_desk_sensor_binary: process.env.HA_DESK_SENSOR_BINARY || "",
|
||||
id_room_sensors: process.env.HA_ROOMTEMP_SENSOR_IDS?.split(",") || [],
|
||||
id_sensor_desk_binary: process.env.HA_SENSOR_DESK_BINARY || "",
|
||||
id_sensors_roomtemp: process.env.HA_SENSORS_ROOMTEMP?.split(",") || [],
|
||||
|
||||
id_webhook_stand: process.env.HA_STANDING_WEBHOOK || "",
|
||||
},
|
||||
|
||||
tidal: {
|
||||
address: process.env.TIDAL_ADDRESS || "",
|
||||
},
|
||||
} as const;
|
||||
|
||||
15
src/grist/client.ts
Normal file
15
src/grist/client.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { BaseClient } from "@dpu/shared";
|
||||
import { printNetworkError } from "@dpu/shared/dist/logger.js";
|
||||
|
||||
export class GristClient extends BaseClient {
|
||||
async get<T>(endpoint: string): Promise<T> {
|
||||
try {
|
||||
const response = await this.getAxios().get<T>(`${endpoint}`);
|
||||
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
printNetworkError(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
39
src/grist/routes.ts
Normal file
39
src/grist/routes.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import type { GristRecord_PersonalGoals } from "@dpu/shared";
|
||||
import type { FastifyInstance } from "fastify";
|
||||
import { z } from "zod";
|
||||
import type { GristService } from "./service";
|
||||
|
||||
export async function gristRoutes(
|
||||
fastify: FastifyInstance,
|
||||
{
|
||||
gristService,
|
||||
}: {
|
||||
gristService: GristService;
|
||||
},
|
||||
) {
|
||||
fastify.get(
|
||||
"/grist/today",
|
||||
{
|
||||
schema: {
|
||||
description: "Get goals for today",
|
||||
tags: ["grist"],
|
||||
response: {
|
||||
200: z.custom<GristRecord_PersonalGoals>(),
|
||||
418: z.object({
|
||||
error: z.string(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
async (_request, reply) => {
|
||||
const service_result = await gristService.getToday();
|
||||
|
||||
if (!service_result.successful) {
|
||||
reply.code(418);
|
||||
return { error: service_result.result };
|
||||
}
|
||||
|
||||
return service_result.result;
|
||||
},
|
||||
);
|
||||
}
|
||||
53
src/grist/service.ts
Normal file
53
src/grist/service.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import {
|
||||
BaseService,
|
||||
type GristRecord_PersonalGoals,
|
||||
logWarning,
|
||||
type ServiceResult,
|
||||
} from "@dpu/shared";
|
||||
import { Config } from "../config.js";
|
||||
import type { GristClient } from "./client.js";
|
||||
|
||||
export class GristService extends BaseService<GristClient> {
|
||||
async getToday(): Promise<ServiceResult<GristRecord_PersonalGoals | string>> {
|
||||
try {
|
||||
const filter_string = encodeURIComponent(
|
||||
`{ "id": [${this.getTodayAsId()}]}`,
|
||||
);
|
||||
const query = `${Config.grist.table_personal_goals_path}?filter=${filter_string}`;
|
||||
|
||||
const response =
|
||||
await this.getClient().get<Record<string, unknown>>(query);
|
||||
|
||||
return this.getSuccessfulResult(this.transformToPersonalGoals(response));
|
||||
} catch {
|
||||
const error_message = "error getting record from grist";
|
||||
logWarning(error_message);
|
||||
return this.getErrorResult(error_message);
|
||||
}
|
||||
}
|
||||
|
||||
getTodayAsId(date = new Date()) {
|
||||
const start = new Date(date.getFullYear(), 0, 0);
|
||||
const diff = date.getTime() - start.getTime();
|
||||
return Math.floor(diff / 86400000);
|
||||
}
|
||||
|
||||
transformToPersonalGoals(
|
||||
obj: Record<string, unknown>,
|
||||
): GristRecord_PersonalGoals {
|
||||
return {
|
||||
went_outside: (obj.went_outside as boolean) ?? false,
|
||||
standing: (obj.standing as boolean) ?? false,
|
||||
standing_goal: (obj.standing_goal as number) ?? 0,
|
||||
steps: (obj.steps as boolean) ?? false,
|
||||
steps_goal: (obj.steps_goal as number) ?? 0,
|
||||
pushups: (obj.pushups as boolean) ?? false,
|
||||
squats: (obj.squats as boolean) ?? false,
|
||||
leg_raises: (obj.leg_raises as boolean) ?? false,
|
||||
reps_goal: (obj.reps_goal as number) ?? 0,
|
||||
stairs: (obj.stairs as boolean) ?? false,
|
||||
stairs_goal: (obj.stairs_goal as number) ?? 0,
|
||||
is_workday: (obj.WeekdayHelper as number) === 1,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,7 @@ export class HomeAssistantService extends BaseService<HomeAssistantClient> {
|
||||
> {
|
||||
try {
|
||||
const raw = await this.getClient().getEntityState(
|
||||
Config.homeassistant.id_desk_sensor_binary,
|
||||
Config.homeassistant.id_sensor_desk_binary,
|
||||
);
|
||||
|
||||
const position = Number(raw.state);
|
||||
@@ -108,7 +108,7 @@ export class HomeAssistantService extends BaseService<HomeAssistantClient> {
|
||||
private async getTemperatures(): Promise<HomeAssistantEntity[]> {
|
||||
try {
|
||||
return await this.getClient().getEntityStates(
|
||||
Config.homeassistant.id_room_sensors,
|
||||
Config.homeassistant.id_sensors_roomtemp,
|
||||
);
|
||||
} catch (error) {
|
||||
logWarning("error getting temperatures:", error);
|
||||
|
||||
15
src/index.ts
15
src/index.ts
@@ -16,6 +16,9 @@ import {
|
||||
import { SwaggerTheme, SwaggerThemeNameEnum } from "swagger-themes";
|
||||
import { z } from "zod";
|
||||
import { Config } from "./config.js";
|
||||
import { GristClient } from "./grist/client.js";
|
||||
import { gristRoutes } from "./grist/routes.js";
|
||||
import { GristService } from "./grist/service.js";
|
||||
import { HomeAssistantClient } from "./homeassistant/client.js";
|
||||
import { homeAssistantRoutes } from "./homeassistant/routes.js";
|
||||
import { HomeAssistantService } from "./homeassistant/service.js";
|
||||
@@ -69,6 +72,12 @@ await fastify.register(fastifySwaggerUi, {
|
||||
|
||||
await fastify.register(fastifyAxios, {
|
||||
clients: {
|
||||
grist: {
|
||||
baseURL: Config.grist.api_url,
|
||||
headers: {
|
||||
Authorization: `Bearer ${Config.grist.api_token}`,
|
||||
},
|
||||
},
|
||||
homeassistant: {
|
||||
baseURL: Config.homeassistant.api_url,
|
||||
headers: {
|
||||
@@ -76,13 +85,16 @@ await fastify.register(fastifyAxios, {
|
||||
},
|
||||
},
|
||||
tidal: {
|
||||
baseURL: `${Config.tidal.host}:${Config.tidal.port}`,
|
||||
baseURL: `${Config.tidal.address}`,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await fastify.register(fastifyWebsocket);
|
||||
|
||||
const gristClient = new GristClient(fastify.axios.grist);
|
||||
const gristService = new GristService(gristClient);
|
||||
|
||||
const haClient = new HomeAssistantClient(fastify.axios.homeassistant);
|
||||
const haService = new HomeAssistantService(haClient);
|
||||
|
||||
@@ -108,6 +120,7 @@ async function verifyAPIKey(
|
||||
const port = parseInt(Config.port, 10);
|
||||
|
||||
// Register routes
|
||||
await fastify.register(gristRoutes, { gristService });
|
||||
await fastify.register(homeAssistantRoutes, { haService, verifyAPIKey });
|
||||
await fastify.register(tidalRoutes, { tidalService, verifyAPIKey });
|
||||
await fastify.register(wsRoutes, { wsService });
|
||||
|
||||
Reference in New Issue
Block a user