diff --git a/src/config.ts b/src/config.ts index 7aac4f4..b6c75bb 100644 --- a/src/config.ts +++ b/src/config.ts @@ -6,6 +6,8 @@ export const Config = { api_key: process.env.API_KEY, port: process.env.PORT || "8080", + timezone: process.env.TIMEZONE || "Europe/Berlin", + gadgetbridge: { db_path: process.env.GADGETBRIDGE_DB_PATH || "src/gadgetbridge/db/Gadgetbridge.db", diff --git a/src/gadgetbridge/client.ts b/src/gadgetbridge/client.ts index 104e9f6..acc4241 100644 --- a/src/gadgetbridge/client.ts +++ b/src/gadgetbridge/client.ts @@ -25,29 +25,32 @@ export class GadgetbridgeClient { return db; } - getStepsPerDay(fromTimestamp: number, toTimestamp: number): StepRow[] { + getStepsPerDay(fromTimestamp: number, toTimestamp: number, utcOffset: string): StepRow[] { const stmt = this.db.prepare(` SELECT date, SUM(steps) AS steps FROM ( SELECT - DATE(TIMESTAMP, 'unixepoch', 'localtime') AS date, + DATE(TIMESTAMP, 'unixepoch', ?) AS date, STEPS AS steps FROM HUAMI_EXTENDED_ACTIVITY_SAMPLE WHERE TIMESTAMP >= ? AND TIMESTAMP < ? UNION ALL SELECT date, steps FROM old.steps - WHERE date >= DATE(?, 'unixepoch', 'localtime') - AND date < DATE(?, 'unixepoch', 'localtime') + WHERE date >= DATE(?, 'unixepoch', ?) + AND date < DATE(?, 'unixepoch', ?) ) GROUP BY date ORDER BY date `); return stmt.all( + utcOffset, fromTimestamp, toTimestamp, fromTimestamp, + utcOffset, toTimestamp, + utcOffset, ) as StepRow[]; } } diff --git a/src/gadgetbridge/public-routes.ts b/src/gadgetbridge/public-routes.ts index 5438bbb..cc8a857 100644 --- a/src/gadgetbridge/public-routes.ts +++ b/src/gadgetbridge/public-routes.ts @@ -34,13 +34,7 @@ export async function publicGadgetbridgeRoutes( async (request, reply) => { const { from, to } = request.query as any; - const fromDate = new Date(`${from}T00:00:00`); - const toDate = new Date(`${to}T00:00:00`); - - const service_result = gadgetbridgeService.getStepsForTimespan( - fromDate, - toDate, - ); + const service_result = gadgetbridgeService.getStepsForTimespan(from, to); if (!service_result.successful) { reply.code(418); diff --git a/src/gadgetbridge/service.ts b/src/gadgetbridge/service.ts index 34567e5..97b5270 100644 --- a/src/gadgetbridge/service.ts +++ b/src/gadgetbridge/service.ts @@ -1,14 +1,24 @@ import { BaseService, type ServiceResult, type StepRow } from "@dpu/shared"; +import { DateTime } from "luxon"; +import { Config } from "../config.js"; import type { GadgetbridgeClient } from "./client.js"; export class GadgetbridgeService extends BaseService { - getStepsForTimespan(from: Date, to: Date): ServiceResult { + getStepsForTimespan(from: string, to: string): ServiceResult { try { - const fromTs = Math.floor(from.getTime() / 1000); - // Add one day to make `to` inclusive - const toTs = Math.floor(to.getTime() / 1000) + 86400; + const tz = Config.timezone; + const fromDt = DateTime.fromISO(from, { zone: tz }).startOf("day"); + const toDt = DateTime.fromISO(to, { zone: tz }).startOf("day").plus({ days: 1 }); - const rows = this.getClient().getStepsPerDay(fromTs, toTs); + const fromTs = Math.floor(fromDt.toSeconds()); + const toTs = Math.floor(toDt.toSeconds()); + + const offsetMinutes = fromDt.offset; + const sign = offsetMinutes >= 0 ? "+" : "-"; + const abs = Math.abs(offsetMinutes); + const utcOffset = `${sign}${String(Math.floor(abs / 60)).padStart(2, "0")}:${String(abs % 60).padStart(2, "0")}`; + + const rows = this.getClient().getStepsPerDay(fromTs, toTs, utcOffset); return this.getSuccessfulResult(rows); } catch (error) { return this.getErrorResult(