diff --git a/src/http/client.ts b/src/http/client.ts index 8c5a838..7816752 100644 --- a/src/http/client.ts +++ b/src/http/client.ts @@ -1,10 +1,11 @@ import { createLogger } from '../logger' -const logger = createLogger('http') +type BodyPromise = Promise +const logger = createLogger('http') let requestTimeout = 0 let lastTimestamp = 0 -const promiseCache = new Map>() +const promiseCache = new Map() const createRequestParams = (): RequestInit => { return { @@ -20,7 +21,11 @@ export const setRequestTimeout = (timeoutMs: number) => { logger.info(`Using ${timeoutMs} millisecond timeout for HTTP requests`) } -export const getDedupedResponse = async (timestamp: number, url: string): Promise => { +const resolveBody = async (request: Request): BodyPromise => { + return (await fetch(request)).text() +} + +export const getDedupedResponseBody = async (timestamp: number, url: string): BodyPromise => { // Clear the cache whenever the timestamp changes if (timestamp !== lastTimestamp) { lastTimestamp = timestamp @@ -35,7 +40,7 @@ export const getDedupedResponse = async (timestamp: number, url: string): Promis const request = new Request(url, createRequestParams()) logger.debug(`GET ${url}`) - const promise = fetch(request) + const promise = resolveBody(request) promiseCache.set(key, promise) return promise diff --git a/src/sensor/iotawatt.ts b/src/sensor/iotawatt.ts index 188b84c..52d55bb 100644 --- a/src/sensor/iotawatt.ts +++ b/src/sensor/iotawatt.ts @@ -9,7 +9,7 @@ import { PowerSensorPollFunction, } from '../sensor' import { Circuit } from '../circuit' -import { getDedupedResponse } from '../http/client' +import { getDedupedResponseBody } from '../http/client' import { Characteristics } from '../characteristics' import { createLogger } from '../logger' @@ -114,10 +114,10 @@ export const getSensorData: PowerSensorPollFunction = async ( const sensor = circuit.sensor as IotawattSensor try { - const configurationResult = (await getDedupedResponse(timestamp, getConfigurationUrl(sensor))).clone() - const configuration = (await configurationResult.json()) as IotawattConfiguration - const statusResult = (await getDedupedResponse(timestamp, getStatusUrl(sensor))).clone() - const status = (await statusResult.json()) as IotawattStatus + const configurationResult = await getDedupedResponseBody(timestamp, getConfigurationUrl(sensor)) + const configuration = JSON.parse(configurationResult) as unknown as IotawattConfiguration + const statusResult = await getDedupedResponseBody(timestamp, getStatusUrl(sensor)) + const status = JSON.parse(statusResult) as unknown as IotawattStatus return { timestamp: timestamp, @@ -142,8 +142,8 @@ export const getCharacteristicsSensorData: CharacteristicsSensorPollFunction = a const sensor = characteristics.sensor as IotawattCharacteristicsSensor try { - const queryResult = (await getDedupedResponse(timestamp, getQueryUrl(sensor))).clone() - const query = (await queryResult.json()) as IotawattCharacteristicsQuery + const queryResult = await getDedupedResponseBody(timestamp, getQueryUrl(sensor)) + const query = JSON.parse(queryResult) as unknown as IotawattCharacteristicsQuery return { timestamp: timestamp, diff --git a/src/sensor/shelly.ts b/src/sensor/shelly.ts index be2172b..a64551f 100644 --- a/src/sensor/shelly.ts +++ b/src/sensor/shelly.ts @@ -10,7 +10,7 @@ import { ShellyType, } from '../sensor' import { Circuit } from '../circuit' -import { getDedupedResponse } from '../http/client' +import { getDedupedResponseBody } from '../http/client' import { Characteristics } from '../characteristics' import { createLogger } from '../logger' @@ -64,10 +64,10 @@ const getSensorDataUrl = (sensor: ShellySensor | ShellyCharacteristicsSensor): s const parseGen1Response = async ( timestamp: number, circuit: Circuit, - httpResponse: Response, + responseBody: string, ): Promise => { const sensor = circuit.sensor as ShellySensor - const data = (await httpResponse.json()) as Gen1StatusResult + const data = JSON.parse(responseBody) as unknown as Gen1StatusResult return { timestamp: timestamp, @@ -79,9 +79,9 @@ const parseGen1Response = async ( const parseGen2PMResponse = async ( timestamp: number, circuit: Circuit, - httpResponse: Response, + responseBody: string, ): Promise => { - const data = (await httpResponse.json()) as Gen2SwitchGetStatusResult + const data = JSON.parse(responseBody) as unknown as Gen2SwitchGetStatusResult return { timestamp: timestamp, @@ -93,10 +93,10 @@ const parseGen2PMResponse = async ( const parseGen2EMResponse = async ( timestamp: number, circuit: Circuit, - httpResponse: Response, + responseBody: string, ): Promise => { const sensor = circuit.sensor as ShellySensor - const data = (await httpResponse.json()) as Gen2EMGetStatusResult + const data = JSON.parse(responseBody) as unknown as Gen2EMGetStatusResult let power = 0 let apparentPower = 0 @@ -136,16 +136,16 @@ export const getSensorData: PowerSensorPollFunction = async ( const url = getSensorDataUrl(sensor) try { - const httpResponse = (await getDedupedResponse(timestamp, url)).clone() + const responseBody = await getDedupedResponseBody(timestamp, url) // Parse the response differently depending on what type of Shelly we're dealing with switch (sensor.shelly.type as ShellyType) { case ShellyType.Gen1: - return await parseGen1Response(timestamp, circuit, httpResponse) + return await parseGen1Response(timestamp, circuit, responseBody) case ShellyType.Gen2PM: - return await parseGen2PMResponse(timestamp, circuit, httpResponse) + return await parseGen2PMResponse(timestamp, circuit, responseBody) case ShellyType.Gen2EM: - return await parseGen2EMResponse(timestamp, circuit, httpResponse) + return await parseGen2EMResponse(timestamp, circuit, responseBody) } } catch (e) { logger.error(e) @@ -166,8 +166,8 @@ export const getCharacteristicsSensorData: CharacteristicsSensorPollFunction = a } try { - const httpResponse = (await getDedupedResponse(timestamp, url)).clone() - const data = (await httpResponse.json()) as Gen2EMGetStatusResult + const result = await getDedupedResponseBody(timestamp, url) + const data = JSON.parse(result) as unknown as Gen2EMGetStatusResult let voltage = 0 let frequency = 0 diff --git a/tests/sensor/shelly.test.ts b/tests/sensor/shelly.test.ts index 9735c18..7d63133 100644 --- a/tests/sensor/shelly.test.ts +++ b/tests/sensor/shelly.test.ts @@ -10,8 +10,8 @@ const gen2pmResponse = fs.readFileSync('./tests/sensor/shelly-plus-1pm.Switch.Ge // Mock getDedupedResponse calls to return real-world data jest.mock('../../src/http/client', () => ({ - getDedupedResponse: async (timestamp: number, url: string) => { - let contents: string | null = null + getDedupedResponseBody: async (timestamp: number, url: string): Promise => { + let contents = '' switch (url) { case 'http://127.0.0.1/status': @@ -25,7 +25,7 @@ jest.mock('../../src/http/client', () => ({ break } - return Promise.resolve(new Response(contents)) + return Promise.resolve(contents) }, }))