@@ -2,24 +2,15 @@ import { Injectable, inject, DestroyRef } from '@angular/core';
22import { HttpClient , HttpParams } from '@angular/common/http' ;
33import { firstValueFrom } from 'rxjs' ;
44import { takeUntilDestroyed } from '@angular/core/rxjs-interop' ;
5+ import type { AggregateMethod , TimeRangeQueryParams } from '@signalk/server-api/history' ;
56import { SignalKConnectionService } from './signalk-connection.service' ;
67
7- /**
8- * Represents a single data point from the History API response.
9- * The array format: [timestamp_string, value1, value2, ...]
10- * where each value corresponds to the paths in the request.
11- */
12- export interface IHistoryDataPoint {
13- timestamp : string ;
14- values : ( number | string | null | number [ ] ) [ ] ;
15- }
16-
178/**
189 * Represents a single series metadata from the History API response.
1910 */
20- export interface IHistoryValueMetadata {
11+ interface IHistoryValueMetadata {
2112 path : string ;
22- method ?: string ; // e.g., 'sma', ' avg', 'min', 'max'
13+ method ?: AggregateMethod | 'avg' ; // keep ' avg' for compatibility with existing backends/tests
2314}
2415
2516/**
@@ -36,16 +27,22 @@ export interface IHistoryValuesResponse {
3627}
3728
3829/**
39- * Query parameters for the History API.
30+ * Query parameters supported by the /history/values endpoint in this app.
31+ *
32+ * Extends server-api query params while preserving current app compatibility:
33+ * - allows string `resolution` passthrough (e.g. `PT1S`)
34+ * - requires `paths` for the HTTP endpoint variant used by KIP
4035 */
41- export interface IHistoryQueryParams {
42- from ?: string ; // ISO 8601 date-time (inclusive)
43- to ?: string ; // ISO 8601 date-time (inclusive, defaults to now)
44- duration ?: string ; // ISO 8601 duration or milliseconds
45- paths : string ; // Required: comma-separated Signal K paths with optional aggregation
46- context ?: string ; // Optional Signal K context, default 'vessels.self'
47- resolution ?: string | number ; // Optional: window length in seconds or time expression
48- }
36+ type IHistoryValuesQueryParams = Partial < TimeRangeQueryParams > & {
37+ paths : string ;
38+ context ?: string ;
39+ resolution ?: number | string ;
40+ } ;
41+
42+ /**
43+ * Query parameters supported by history endpoints that only require a time range.
44+ */
45+ type IHistoryTimeRangeQueryParams = Partial < TimeRangeQueryParams > ;
4946
5047@Injectable ( {
5148 providedIn : 'root'
@@ -73,7 +70,7 @@ export class SignalkHistoryService {
7370 /**
7471 * Gets paths that have historical data available for the specified time range.
7572 *
76- * @param {Partial<IHistoryQueryParams> } params - Optional time range parameters.
73+ * @param {IHistoryTimeRangeQueryParams } params - Optional time range parameters.
7774 * - from: Start of the time range (ISO 8601), optional
7875 * - to: End of the time range (ISO 8601), optional
7976 * - duration: Duration of the time range (ISO 8601 or milliseconds), optional
@@ -91,7 +88,7 @@ export class SignalkHistoryService {
9188 *
9289 * @memberof SignalkHistoryService
9390 */
94- public async getPaths ( params ?: Partial < IHistoryQueryParams > ) : Promise < string [ ] | null > {
91+ public async getPaths ( params ?: IHistoryTimeRangeQueryParams ) : Promise < string [ ] | null > {
9592 try {
9693 if ( ! this . historyServiceUrl ) {
9794 console . warn ( '[SignalkHistoryService] No HTTP service URL available' ) ;
@@ -127,6 +124,60 @@ export class SignalkHistoryService {
127124 }
128125 }
129126
127+ /**
128+ * Gets contexts that have historical data available for the specified time range.
129+ *
130+ * @param {IHistoryTimeRangeQueryParams } params - Optional time range parameters.
131+ * - from: Start of the time range (ISO 8601), optional
132+ * - to: End of the time range (ISO 8601), optional
133+ * - duration: Duration of the time range (ISO 8601 or milliseconds), optional
134+ *
135+ * @returns {Promise<string[] | null> } Array of Signal K contexts with historical data, or null if the request fails.
136+ *
137+ * @example
138+ * const contexts = await historyService.getContexts({ duration: 'PT1H' });
139+ * if (contexts) {
140+ * console.log('Available contexts:', contexts);
141+ * }
142+ *
143+ * @memberof SignalkHistoryService
144+ */
145+ public async getContexts ( params ?: IHistoryTimeRangeQueryParams ) : Promise < string [ ] | null > {
146+ try {
147+ if ( ! this . historyServiceUrl ) {
148+ console . warn ( '[SignalkHistoryService] No HTTP service URL available' ) ;
149+ return null ;
150+ }
151+
152+ const historyUrl = `${ this . historyServiceUrl } history/contexts` ;
153+ let httpParams = new HttpParams ( ) ;
154+
155+ // Build query parameters (time range only)
156+ if ( params ?. from ) {
157+ httpParams = httpParams . set ( 'from' , params . from ) ;
158+ }
159+ if ( params ?. to ) {
160+ httpParams = httpParams . set ( 'to' , params . to ) ;
161+ }
162+ if ( params ?. duration ) {
163+ httpParams = httpParams . set ( 'duration' , params . duration . toString ( ) ) ;
164+ }
165+
166+ const fullUrl = `${ historyUrl } ?${ httpParams . toString ( ) } ` ;
167+ console . log ( `[SignalkHistoryService] GET ${ fullUrl } ` ) ;
168+
169+ const response = await firstValueFrom (
170+ this . http . get < string [ ] > ( historyUrl , { params : httpParams } )
171+ ) ;
172+
173+ console . log ( `[SignalkHistoryService] Retrieved ${ response ?. length ?? 0 } available contexts` ) ;
174+ return response ;
175+ } catch ( error ) {
176+ console . error ( '[SignalkHistoryService] History API /contexts request failed:' , error ) ;
177+ return null ;
178+ }
179+ }
180+
130181 /**
131182 * Fetches historical data from the Signal K History API.
132183 *
@@ -135,7 +186,7 @@ export class SignalkHistoryService {
135186 * signalk-parquet. If no history is available or the API is not installed,
136187 * the request will fail.
137188 *
138- * @param {IHistoryQueryParams } params - Query parameters for the history request.
189+ * @param {IHistoryValuesQueryParams } params - Query parameters for the history request.
139190 * - paths (required): comma-separated Signal K paths with optional aggregation suffixes
140191 * (e.g., 'navigation.speedOverGround:sma:5,navigation.speedThroughWater:avg')
141192 * - from, to, duration: define the time range
@@ -159,7 +210,7 @@ export class SignalkHistoryService {
159210 *
160211 * @memberof SignalkHistoryService
161212 */
162- public async getValues ( params : IHistoryQueryParams ) : Promise < IHistoryValuesResponse | null > {
213+ public async getValues ( params : IHistoryValuesQueryParams ) : Promise < IHistoryValuesResponse | null > {
163214 try {
164215 if ( ! this . historyServiceUrl ) {
165216 console . warn ( '[SignalkHistoryService] No HTTP service URL available' ) ;
0 commit comments