formatting and grist
This commit is contained in:
@@ -2,8 +2,7 @@ API_KEY=apiKey
|
|||||||
PORT=
|
PORT=
|
||||||
ENV_DEV=true
|
ENV_DEV=true
|
||||||
|
|
||||||
TIDAL_HOST=http://localhost
|
TIDAL_HOST=http://localhost:47836
|
||||||
TIDAL_PORT=47836
|
|
||||||
|
|
||||||
HA_API_URL=http://homeassistant.com/api/states/
|
HA_API_URL=http://homeassistant.com/api/states/
|
||||||
HA_API_TOKEN=Nina hätte hier jetzt ihr Token ausversehen stehen hihi
|
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": {
|
"node_modules/@dpu/shared": {
|
||||||
"version": "1.7.1",
|
"version": "1.8.1",
|
||||||
"resolved": "git+https://git.dariusbag.dev/DarDarBinks/dpu-shared.git#cd95b631746e3f5d50120c68f69b934cf7f8e87b",
|
"resolved": "git+https://git.dariusbag.dev/DarDarBinks/dpu-shared.git#27dc6f2b1214b8e2aff65de510caea402c2f88db",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/ws": "^8.18.1",
|
"@types/ws": "^8.18.1",
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
@@ -1383,9 +1383,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/get-tsconfig": {
|
"node_modules/get-tsconfig": {
|
||||||
"version": "4.13.5",
|
"version": "4.13.6",
|
||||||
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.5.tgz",
|
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz",
|
||||||
"integrity": "sha512-v4/4xAEpBRp6SvCkWhnGCaLkJf9IwWzrsygJPxD/+p2/xPE3C5m2fA9FD0Ry9tG+Rqqq3gBzHSl6y1/T9V/tMQ==",
|
"integrity": "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"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 src/index.ts"
|
"dev": "tsx watch --inspect-brk src/index.ts"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "Darius",
|
"author": "Darius",
|
||||||
|
|||||||
@@ -7,18 +7,24 @@ export const Config = {
|
|||||||
port: process.env.PORT || "8080",
|
port: process.env.PORT || "8080",
|
||||||
env_dev: process.env.ENV_DEV || false,
|
env_dev: process.env.ENV_DEV || false,
|
||||||
|
|
||||||
tidal: {
|
grist: {
|
||||||
host: process.env.TIDAL_HOST || "",
|
api_url: process.env.GRIST_API_URL || "",
|
||||||
port: process.env.TIDAL_PORT || "",
|
api_token: process.env.GRIST_API_TOKEN || "",
|
||||||
|
|
||||||
|
table_personal_goals_path: process.env.GRIST_TPG_PATH || "",
|
||||||
},
|
},
|
||||||
|
|
||||||
homeassistant: {
|
homeassistant: {
|
||||||
api_url: process.env.HA_API_URL || "",
|
api_url: process.env.HA_API_URL || "",
|
||||||
api_token: process.env.HA_API_TOKEN || "",
|
api_token: process.env.HA_API_TOKEN || "",
|
||||||
|
|
||||||
id_desk_sensor_binary: process.env.HA_DESK_SENSOR_BINARY || "",
|
id_sensor_desk_binary: process.env.HA_SENSOR_DESK_BINARY || "",
|
||||||
id_room_sensors: process.env.HA_ROOMTEMP_SENSOR_IDS?.split(",") || [],
|
id_sensors_roomtemp: process.env.HA_SENSORS_ROOMTEMP?.split(",") || [],
|
||||||
|
|
||||||
id_webhook_stand: process.env.HA_STANDING_WEBHOOK || "",
|
id_webhook_stand: process.env.HA_STANDING_WEBHOOK || "",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tidal: {
|
||||||
|
address: process.env.TIDAL_ADDRESS || "",
|
||||||
|
},
|
||||||
} as const;
|
} 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 {
|
try {
|
||||||
const raw = await this.getClient().getEntityState(
|
const raw = await this.getClient().getEntityState(
|
||||||
Config.homeassistant.id_desk_sensor_binary,
|
Config.homeassistant.id_sensor_desk_binary,
|
||||||
);
|
);
|
||||||
|
|
||||||
const position = Number(raw.state);
|
const position = Number(raw.state);
|
||||||
@@ -108,7 +108,7 @@ export class HomeAssistantService extends BaseService<HomeAssistantClient> {
|
|||||||
private async getTemperatures(): Promise<HomeAssistantEntity[]> {
|
private async getTemperatures(): Promise<HomeAssistantEntity[]> {
|
||||||
try {
|
try {
|
||||||
return await this.getClient().getEntityStates(
|
return await this.getClient().getEntityStates(
|
||||||
Config.homeassistant.id_room_sensors,
|
Config.homeassistant.id_sensors_roomtemp,
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logWarning("error getting temperatures:", 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 { SwaggerTheme, SwaggerThemeNameEnum } from "swagger-themes";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { Config } from "./config.js";
|
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 { HomeAssistantClient } from "./homeassistant/client.js";
|
||||||
import { homeAssistantRoutes } from "./homeassistant/routes.js";
|
import { homeAssistantRoutes } from "./homeassistant/routes.js";
|
||||||
import { HomeAssistantService } from "./homeassistant/service.js";
|
import { HomeAssistantService } from "./homeassistant/service.js";
|
||||||
@@ -69,6 +72,12 @@ await fastify.register(fastifySwaggerUi, {
|
|||||||
|
|
||||||
await fastify.register(fastifyAxios, {
|
await fastify.register(fastifyAxios, {
|
||||||
clients: {
|
clients: {
|
||||||
|
grist: {
|
||||||
|
baseURL: Config.grist.api_url,
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${Config.grist.api_token}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
homeassistant: {
|
homeassistant: {
|
||||||
baseURL: Config.homeassistant.api_url,
|
baseURL: Config.homeassistant.api_url,
|
||||||
headers: {
|
headers: {
|
||||||
@@ -76,13 +85,16 @@ await fastify.register(fastifyAxios, {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
tidal: {
|
tidal: {
|
||||||
baseURL: `${Config.tidal.host}:${Config.tidal.port}`,
|
baseURL: `${Config.tidal.address}`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await fastify.register(fastifyWebsocket);
|
await fastify.register(fastifyWebsocket);
|
||||||
|
|
||||||
|
const gristClient = new GristClient(fastify.axios.grist);
|
||||||
|
const gristService = new GristService(gristClient);
|
||||||
|
|
||||||
const haClient = new HomeAssistantClient(fastify.axios.homeassistant);
|
const haClient = new HomeAssistantClient(fastify.axios.homeassistant);
|
||||||
const haService = new HomeAssistantService(haClient);
|
const haService = new HomeAssistantService(haClient);
|
||||||
|
|
||||||
@@ -108,6 +120,7 @@ async function verifyAPIKey(
|
|||||||
const port = parseInt(Config.port, 10);
|
const port = parseInt(Config.port, 10);
|
||||||
|
|
||||||
// Register routes
|
// Register routes
|
||||||
|
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 });
|
||||||
|
|||||||
Reference in New Issue
Block a user