import type { AnyDevice , SendOptions } from '../client' ; import { extractResponse , isObjectLike , HasErrCode , hasErrCode , } from '../utils' ; export type RealtimeV1 = { current ? : number ; power ? : number ; total ? : number ; voltage ? : number ; } ; export type RealtimeV2 = { current_ma ? : number ; power_mw ? : number ; total_wh ? : number ; voltage_mv ? : number ; } ; export type Realtime = RealtimeV1 | RealtimeV2 ; export type RealtimeNormalized = RealtimeV1 & RealtimeV2 ; export function isRealtime ( candidate ) { return isObjectLike ( candidate ) ; } export default class Emeter { #realtime : Realtime = { } ; constructor ( readonly device , readonly apiModuleName , readonly childId = undefined ) { } returns { Object } get realtime ( ) : RealtimeNormalized { return this . #realtime ; } private setRealtime ( realtime ) { const normRealtime = { ... realtime } ; const normalize = < K extends keyof RealtimeNormalized > ( key1 , key2 , multiplier ) : void => { const r = normRealtime ; if ( typeof r [ key1 ] === 'number' && r [ key2 ] === undefined ) { r [ key2 ] = Math . floor ( ( r [ key1 ] as number ) * multiplier ) ; } else if ( r [ key1 ] == null && typeof r [ key2 ] === 'number' ) { r [ key1 ] = ( r [ key2 ] as number ) / multiplier ; } } ; if ( realtime != null ) { normalize ( 'current' , 'current_ma' , 1000 ) ; normalize ( 'power' , 'power_mw' , 1000 ) ; normalize ( 'total' , 'total_wh' , 1000 ) ; normalize ( 'voltage' , 'voltage_mv' , 1000 ) ; } this . #realtime = normRealtime ; this . device . emit ( 'emeter-realtime-update' , this . #realtime ) ; } param sendOptions returns throws ResponseError async getRealtime ( sendOptions ? ) { this . setRealtime ( extractResponse < Realtime & HasErrCode > ( await this . device . sendCommand ( { [ this . apiModuleName ] : { get_realtime : { } } , } , this . childId , sendOptions ) , '' , ( c ) => isRealtime ( c ) && hasErrCode ( c ) ) ) ; return this . realtime ; } param year param month param sendOptions returns throws ResponseError async getDayStats ( year , month , sendOptions ? ) { return this . device . sendCommand ( { [ this . apiModuleName ] : { get_daystat : { year , month } } , } , this . childId , sendOptions ) ; } param year param sendOptions returns throws ResponseError async getMonthStats ( year , sendOptions ? ) { return this . device . sendCommand ( { [ this . apiModuleName ] : { get_monthstat : { year } } , } , this . childId , sendOptions ) ; } param sendOptions returns throws ResponseError async eraseStats ( sendOptions ? ) { return this . device . sendCommand ( { [ this . apiModuleName ] : { erase_emeter_stat : { } } , } , this . childId , sendOptions ) ; } } module . exports = Emeter ;