From 7e112a78e66dca0f095657b08a15837dc0634b36 Mon Sep 17 00:00:00 2001 From: Evert Prants Date: Fri, 29 Sep 2023 18:18:44 +0300 Subject: [PATCH] out of bounds data catch --- src/app.service.ts | 7 ---- src/module/ws1080.ts | 92 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 89 insertions(+), 10 deletions(-) diff --git a/src/app.service.ts b/src/app.service.ts index f907493..1289c91 100644 --- a/src/app.service.ts +++ b/src/app.service.ts @@ -185,13 +185,6 @@ export class AppService implements OnApplicationShutdown { } } - @Cron('0 * * * *') - scheduledPulls() { - this.getWeather().catch(() => { - // do nothing - }); - } - onApplicationShutdown() { this.station?.close(); } diff --git a/src/module/ws1080.ts b/src/module/ws1080.ts index 4f3c61a..d628ca4 100644 --- a/src/module/ws1080.ts +++ b/src/module/ws1080.ts @@ -20,6 +20,21 @@ const WIND_DIRS = [ 'NNW', ]; +interface Data { + indoorHumidity: number; + outdoorHumidity: number; + indoorTemperature: number; + outdoorTemperature: number; + outdoorDewPoint: number; + windChillTemp: number; + windSpeed: number; + gustSpeed: number; + windDirection: string; + rainDiff: number; + totalRain: number; + absPressure: number; +} + /** * Model Dreamlink WH1080/WS1080 * @@ -176,7 +191,7 @@ class WS1080 { * Read weather data from WS1080 * @returns Weather data */ - async read() { + async read(): Promise { const block = await WS1080.readBlock(this.device, this.dInterface, 0); if (!block) throw new Error('No data returned for request.'); @@ -246,8 +261,8 @@ class WS1080 { this.previousRain = totalRain; - // Return the data! Finally! - return { + // Compile the data + const data: Data = { indoorHumidity, outdoorHumidity, indoorTemperature, @@ -261,11 +276,82 @@ class WS1080 { totalRain, absPressure, }; + + // Validate the data integrity + this.validateReadings(data, currentBlock); + + // Return the data! Finally! + return data; } close() { this.device.close(); } + + private validateReadings(input: Data, packet: Buffer) { + const humidReadings: Array = [ + 'indoorHumidity', + 'outdoorHumidity', + ]; + const tempReadings: Array = [ + 'indoorTemperature', + 'outdoorTemperature', + 'windChillTemp', + 'outdoorDewPoint', + ]; + const speedReadings: Array = ['windSpeed', 'gustSpeed']; + + for (const key of humidReadings) { + if ( + input[key] != null && + ((input[key] as number) < -1 || (input[key] as number) > 101) + ) { + console.error( + 'Invalid packet detected', + packet.toString('hex'), + 'parsed', + input, + ); + throw new Error( + `Erronous data readings detected: ${key} ${input[key]} is out of bounds.`, + ); + } + } + + for (const key of tempReadings) { + if ( + input[key] != null && + ((input[key] as number) < -100 || (input[key] as number) > 100) + ) { + console.error( + 'Invalid packet detected', + packet.toString('hex'), + 'parsed', + input, + ); + throw new Error( + `Erronous data readings detected: ${key} ${input[key]} is out of bounds.`, + ); + } + } + + for (const key of speedReadings) { + if ( + input[key] != null && + ((input[key] as number) < -1 || (input[key] as number) > 160) + ) { + console.error( + 'Invalid packet detected', + packet.toString('hex'), + 'parsed', + input, + ); + throw new Error( + `Erronous data readings detected: ${key} ${input[key]} is out of bounds.`, + ); + } + } + } } export default WS1080;