@@ -49,6 +49,9 @@ export type EnergyHistoryResponse = {
4949 total_events ?: number ;
5050 } ;
5151} ;
52+ export type EnergyHistorySummary = Partial <
53+ Omit < EnergyHistoryEvent , "timestamp" >
54+ > ;
5255
5356// Interface for event type safety
5457type TeslemetryEnergyEventMap = {
@@ -77,6 +80,7 @@ export declare interface TeslemetryEnergyApi {
7780 event : K ,
7881 data : TeslemetryEnergyEventMap [ K ] ,
7982 ) : boolean ;
83+ listenerCount < K extends keyof TeslemetryEnergyEventMap > ( event : K ) : number ;
8084}
8185
8286type PollingEndpoints = keyof TeslemetryEnergyEventMap ;
@@ -338,7 +342,7 @@ export class TeslemetryEnergyApi extends EventEmitter {
338342 return data ;
339343 }
340344
341- requestPolling ( endpoint : PollingEndpoints ) : ( ) => void {
345+ public requestPolling ( endpoint : PollingEndpoints ) : ( ) => void {
342346 if ( ! this . refreshIntervals [ endpoint ] ) {
343347 switch ( endpoint ) {
344348 case "siteInfo" : {
@@ -361,9 +365,14 @@ export class TeslemetryEnergyApi extends EventEmitter {
361365 // Schedule 30 seconds after each 5-minute mark aligned to clock time
362366 this . refreshIntervals [ endpoint ] = scheduler (
363367 ( ) => {
364- this . getCalendarHistory ( "backup" , "day" ) . catch (
365- this . root . logger . warn ,
366- ) ;
368+ if ( this . listenerCount ( "backupHistory" ) ) {
369+ this . getCalendarHistory ( "backup" , "day" )
370+ . then ( ( backupHistory ) => {
371+ if ( backupHistory )
372+ this . emit ( "backupHistory" , backupHistory ) ;
373+ } )
374+ . catch ( this . root . logger . warn ) ;
375+ }
367376 } ,
368377 300_000 ,
369378 20_000 + Math . round ( 10_000 * Math . random ( ) ) ,
@@ -373,9 +382,14 @@ export class TeslemetryEnergyApi extends EventEmitter {
373382 // Schedule 30 seconds after each 5-minute mark aligned to clock time
374383 this . refreshIntervals [ endpoint ] = scheduler (
375384 ( ) => {
376- this . getCalendarHistory ( "energy" , "day" ) . catch (
377- this . root . logger . warn ,
378- ) ;
385+ if ( this . listenerCount ( "energyHistory" ) ) {
386+ this . getCalendarHistory ( "energy" , "day" )
387+ . then ( ( energyHistory ) => {
388+ if ( energyHistory )
389+ this . emit ( "energyHistory" , energyHistory ) ;
390+ } )
391+ . catch ( this . root . logger . warn ) ;
392+ }
379393 } ,
380394 300_000 ,
381395 20_000 + Math . round ( 10_000 * Math . random ( ) ) ,
@@ -385,7 +399,14 @@ export class TeslemetryEnergyApi extends EventEmitter {
385399 // Schedule 30 seconds after each 5-minute mark aligned to clock time
386400 this . refreshIntervals [ endpoint ] = scheduler (
387401 ( ) => {
388- this . getTelemetryHistory ( "day" ) . catch ( this . root . logger . warn ) ;
402+ if ( this . listenerCount ( "chargeHistory" ) ) {
403+ this . getTelemetryHistory ( "day" )
404+ . then ( ( chargeHistory ) => {
405+ if ( chargeHistory )
406+ this . emit ( "chargeHistory" , chargeHistory ) ;
407+ } )
408+ . catch ( this . root . logger . warn ) ;
409+ }
389410 } ,
390411 300_000 ,
391412 20_000 + Math . round ( 10_000 * Math . random ( ) ) ,
@@ -407,4 +428,32 @@ export class TeslemetryEnergyApi extends EventEmitter {
407428 }
408429 } ;
409430 }
431+
432+ /**
433+ * Sum energy history entries to find the total energy usage of each type.
434+ * @param energyHistory
435+ */
436+ public sumEnergyHistory (
437+ energyHistory : EnergyHistoryResponse ,
438+ ) : EnergyHistorySummary {
439+ const summary : EnergyHistorySummary = { } ;
440+
441+ if ( ! energyHistory ?. response ?. events ) {
442+ return summary ;
443+ }
444+
445+ for ( const event of energyHistory . response . events ) {
446+ for ( const [ key , value ] of Object . entries ( event ) ) {
447+ if ( key === "timestamp" ) continue ;
448+
449+ if ( typeof value === "number" ) {
450+ const typedKey = key as keyof Omit < EnergyHistoryEvent , "timestamp" > ;
451+ const currentValue = summary [ typedKey ] as number | undefined ;
452+ summary [ typedKey ] = ( currentValue ?? 0 ) + value ;
453+ }
454+ }
455+ }
456+
457+ return summary ;
458+ }
410459}
0 commit comments