From 782cdf8af83d1854f1b9588b8cb475074c1ca515 Mon Sep 17 00:00:00 2001 From: Dipesh Kumar Sah Date: Tue, 2 Dec 2025 11:36:01 +0545 Subject: [PATCH] feat: update logic to support and fetch station details --- .../schedule-sources-data.service.ts | 124 ++---------------- .../src/adapters/dhm-rainfall.adapter.ts | 71 +++++++++- .../src/adapters/dhm-water-level.adapter.ts | 74 ++++++++++- .../src/types/dhm-observation.type.ts | 12 ++ 4 files changed, 162 insertions(+), 119 deletions(-) diff --git a/apps/triggers/src/sources-data/schedule-sources-data.service.ts b/apps/triggers/src/sources-data/schedule-sources-data.service.ts index 32e5754..9721262 100644 --- a/apps/triggers/src/sources-data/schedule-sources-data.service.ts +++ b/apps/triggers/src/sources-data/schedule-sources-data.service.ts @@ -11,8 +11,6 @@ import { DhmWaterLevelAdapter, DhmRainfallAdapter, DhmService, - RiverStationData, - RainfallStationData, } from '@lib/dhm-adapter'; import { GlofasAdapter, GlofasServices } from '@lib/glofas-adapter'; import { GfhAdapter, GfhService } from '@lib/gfh-adapter'; @@ -104,56 +102,12 @@ export class ScheduleSourcesDataService riverData.data.forEach(async (indicator) => { const riverId = (indicator.location as any)?.basinId; - // Currently we do not have station data so we are using dummy data - const info: RiverStationData = { - id: 5554, - onm: '', - name: riverId, - tags: [], - basin: 'Mahakali', - images: [ - { - id: 2625, - name: 'bdca0624990c25570064692a7b807baa', - size: 75478, - type: 0, - description: '', - }, - { - id: 2669, - name: '8a0a35e1047c0877bef6f16699bbc61f', - size: 61510, - type: 0, - description: '', - }, - ], - status: 'BELOW WARNING LEVEL', - steady: 'STEADY', - district: 'Kanchanpur', - latitude: 28.8526, - elevation: 162, - longitude: 80.4344, - series_id: 29089, - description: 'Doda (Machheli) river at East West Highway', - danger_level: '3.8', - stationIndex: '281.5', - warning_level: '3.4', - waterLevel: { - value: indicator.value, - datetime: indicator.issuedAt, - }, - history: indicator.info, - indicator: indicator.indicator, - units: indicator.units, - value: indicator.value, - }; - const result = await this.dhmService.saveDataInDhm( + await this.dhmService.saveDataInDhm( SourceType.WATER_LEVEL, riverId, - info, + indicator.info, ); - console.log('result', result); }); } @@ -170,73 +124,17 @@ export class ScheduleSourcesDataService } else { this.logger.warn(rainfallData.details); } - // return; + return; } - console.log('rainfallData', rainfallData); - // Currently rainfall api is not working so we are using dummy data - const info: RainfallStationData = { - id: 111, - name: 'Doda river at East-West Highway', - basin: 'Koshi', - blink: false, - status: 'BELOW WARNING LEVEL', - history: [ - { - max: 0, - min: 0, - value: 0, - datetime: '2025-10-14T05:00:00.000Z', - }, - { - max: 0, - min: 0, - value: 0, - datetime: '2025-10-14T06:00:00.000Z', - }, - { - max: 0, - min: 0, - value: 0, - datetime: '2025-10-14T07:00:00.000Z', - }, - { - max: 0, - min: 0, - value: 0, - datetime: '2025-10-14T08:00:00.000Z', - }, - { - max: 0, - min: 0, - value: 0, - datetime: '2025-10-14T09:00:00.000Z', - }, - { - max: 0, - min: 0, - value: 0, - datetime: '2025-10-14T10:00:00.000Z', - }, - ], - district: 'Sunsari', - interval: null, - latitude: 26.855192, - longitude: 87.152283, - series_id: 1505, - description: 'Hydrological Station with RLS', - stationIndex: '695', - indicator: 'water_level_m', - units: 'mm', - value: 10.9, - }; - - const result = await this.dhmService.saveDataInDhm( - SourceType.RAINFALL, - info.name, - info, - ); - console.log('result', result); + rainfallData.data.forEach(async (indicator) => { + const riverId = (indicator.location as any)?.basinId; + await this.dhmService.saveDataInDhm( + SourceType.RAINFALL, + riverId, + indicator.info, + ); + }); } // run every hour diff --git a/packages/dhm-adapter/src/adapters/dhm-rainfall.adapter.ts b/packages/dhm-adapter/src/adapters/dhm-rainfall.adapter.ts index ec13b48..bac004b 100644 --- a/packages/dhm-adapter/src/adapters/dhm-rainfall.adapter.ts +++ b/packages/dhm-adapter/src/adapters/dhm-rainfall.adapter.ts @@ -7,6 +7,9 @@ import { DhmNormalizedItem, DhmSourceDataTypeEnum, DhmFetchResponse, + RainfallStationItem, + RiverStationItem, + DhmStationResponse, } from "../types/dhm-observation.type"; import { Indicator, @@ -27,7 +30,6 @@ import { RainfallWaterLevelConfig, PrismaService, } from "@lib/database"; -import { AxiosError } from "axios"; import { EventEmitter2 } from "@nestjs/event-emitter"; @Injectable() @@ -69,6 +71,61 @@ export class DhmRainfallAdapter extends ObservationAdapter { }); } + private async getStationsDetailsBySeriesId( + seriesId: number + ): Promise { + //TODO: DHM is changing the APIs so for not let it be constant + const baseUrl = `https://dhm.gov.np/home/getAPIData/3`; + + const defaultStation: RainfallStationItem = { + name: "", + blink: false, + interval: 0, + id: 0, + stationIndex: "", + basin: "", + district: "", + latitude: 0, + longitude: 0, + series_id: 0, + status: "", + description: "", + indicator: "", + units: "", + value: 0, + }; + try { + const response = + await this.httpService.axiosRef.get(baseUrl); + const riverWatch = response.data.rainfall_watch; + + const station = riverWatch.find( + (station) => station.series_id === seriesId + ); + + if (!station) { + this.logger.warn(`Station not found for seriesId ${seriesId}`); + return defaultStation; + } + + return station; + } catch (error: any) { + this.logger.error( + `Failed to get stations details for seriesId ${seriesId}`, + error + ); + return defaultStation; + } + } + + private getLatestObservationValue( + stationDetail: RiverStationItem | RainfallStationItem + ): number { + if ("latest_observation" in stationDetail) { + return stationDetail.latest_observation?.value ?? 0; + } + return 0; + } /** * Fetch raw HTML/data from DHM website */ @@ -102,6 +159,7 @@ export class DhmRainfallAdapter extends ObservationAdapter { return { data: await this.httpService.axiosRef.post(baseUrl, form), + stationDetail: await this.getStationsDetailsBySeriesId(seriesId), location: cfg.LOCATION, seriesId, }; @@ -169,7 +227,9 @@ export class DhmRainfallAdapter extends ObservationAdapter { for (const { data: { data: rawData }, + stationDetail, seriesId, + location, } of rawDatas) { const data = scrapeDataFromHtml(rawData.data.table); @@ -184,7 +244,9 @@ export class DhmRainfallAdapter extends ObservationAdapter { observations.push({ data: normalizedData, + stationDetail, seriesId, + location, }); } @@ -210,12 +272,13 @@ export class DhmRainfallAdapter extends ObservationAdapter { location: { type: "STATION" as const, seriesId: obs.seriesId, + basinId: obs.location!, }, source: { key: "DHM", metadata: { originalUnit: "m" }, }, - history: obs.data, + info: { ...obs.stationDetail, history: obs.data }, }; const results: Indicator[] = []; @@ -224,8 +287,8 @@ export class DhmRainfallAdapter extends ObservationAdapter { results.push({ ...baseIndicator, indicator: "rainfall_mm", - units: "m", - value: obs.data[0]?.value || 0, + units: "mm", + value: this.getLatestObservationValue(obs.stationDetail), }); return results; diff --git a/packages/dhm-adapter/src/adapters/dhm-water-level.adapter.ts b/packages/dhm-adapter/src/adapters/dhm-water-level.adapter.ts index b3eb1fd..061bc9e 100644 --- a/packages/dhm-adapter/src/adapters/dhm-water-level.adapter.ts +++ b/packages/dhm-adapter/src/adapters/dhm-water-level.adapter.ts @@ -7,6 +7,10 @@ import { DhmNormalizedItem, DhmSourceDataTypeEnum, DhmFetchResponse, + DhmStationResponse, + RiverStationData, + RainfallStationItem, + RiverStationItem, } from "../types/dhm-observation.type"; import { Indicator, @@ -68,6 +72,69 @@ export class DhmWaterLevelAdapter extends ObservationAdapter { this.registerHealthConfig(payload); } + async getStationsDetailsBySeriesId( + seriesId: number + ): Promise { + const baseUrl = `https://dhm.gov.np/home/getAPIData/3`; + const defaultStation: RiverStationData = { + name: "", + id: 0, + stationIndex: "", + basin: "", + district: "", + latitude: 0, + longitude: 0, + series_id: 0, + waterLevel: { + value: 0, + datetime: new Date().toISOString(), + }, + status: "", + warning_level: "", + danger_level: "", + steady: "", + onm: "", + description: "", + elevation: 0, + images: [], + tags: [], + indicator: "", + units: "", + value: 0, + }; + try { + const response = + await this.httpService.axiosRef.get(baseUrl); + const riverWatch = response.data.river_watch; + const station = riverWatch.find( + (station) => station.series_id === seriesId + ); + + if (!station) { + this.logger.warn(`Station not found for seriesId ${seriesId}`); + return defaultStation; + } + + return station; + } catch (error: any) { + this.logger.error( + `Failed to get stations details for seriesId ${seriesId}`, + error + ); + return defaultStation; + } + } + + private getLatestWaterLevelValue( + stationDetail: RiverStationItem | RainfallStationItem + ): number { + if ("waterLevel" in stationDetail) { + return stationDetail.waterLevel?.value ?? 0; + } + + return 0; + } + /** * Fetch raw HTML/data from DHM website */ @@ -103,6 +170,7 @@ export class DhmWaterLevelAdapter extends ObservationAdapter { return { data: await this.httpService.axiosRef.post(baseUrl, form), + stationDetail: await this.getStationsDetailsBySeriesId(seriesId), seriesId, location: cfg.LOCATION, }; @@ -171,6 +239,7 @@ export class DhmWaterLevelAdapter extends ObservationAdapter { for (const { data: { data: rawData }, + stationDetail, seriesId, location, } of rawDatas) { @@ -187,6 +256,7 @@ export class DhmWaterLevelAdapter extends ObservationAdapter { observations.push({ data: normalizedData, + stationDetail, seriesId, location, }); @@ -220,7 +290,7 @@ export class DhmWaterLevelAdapter extends ObservationAdapter { key: "DHM", metadata: { originalUnit: "m" }, }, - info: obs.data, + info: { ...obs.stationDetail, history: obs.data }, }; const results: Indicator[] = []; @@ -230,7 +300,7 @@ export class DhmWaterLevelAdapter extends ObservationAdapter { ...baseIndicator, indicator: "water_level_m", units: "m", - value: obs.data[0]?.value || 0, + value: this.getLatestWaterLevelValue(obs.stationDetail), }); return results; diff --git a/packages/dhm-adapter/src/types/dhm-observation.type.ts b/packages/dhm-adapter/src/types/dhm-observation.type.ts index b6e3ae1..2ce8e0f 100644 --- a/packages/dhm-adapter/src/types/dhm-observation.type.ts +++ b/packages/dhm-adapter/src/types/dhm-observation.type.ts @@ -1,7 +1,9 @@ +import { Result } from "@lib/core"; import axios from "axios"; export interface DhmObservation { data: DhmNormalizedItem[]; + stationDetail: RiverStationItem | RainfallStationItem; seriesId: number; location?: string; } @@ -82,6 +84,10 @@ export interface RiverStationItem { } export type RainfallStationItem = { + latest_observation?: { + value: number; + datetime: string; + }; id: number; series_id: number; stationIndex: string; @@ -113,3 +119,9 @@ export interface RiverStationData extends RiverStationItem { export interface RainfallStationData extends RainfallStationItem { history?: RiverWaterHistoryItem[]; } + +export interface DhmStationResponse { + type: number; + rainfall_watch: RainfallStationItem[]; + river_watch: RiverStationItem[]; +}