From 732fe7e45d797eeab54eb249edfb9c05806cbc1a Mon Sep 17 00:00:00 2001 From: Thiemo Hoffmann <20605452+theimo1221@users.noreply.github.com> Date: Sat, 12 Oct 2024 22:01:29 +0200 Subject: [PATCH] Correct JSON Filtering on sub-objects with own filter --- src/models/iJsonOmitKeys.ts | 9 +++++++++ src/models/index.ts | 1 + src/server/devices/IoBrokerBaseDevice.ts | 15 ++++++++++++--- .../devices/dachs/dachsTemperatureSensor.ts | 5 ----- src/server/devices/sharedFunctions/battery.ts | 13 ++++++++----- .../devices/sharedFunctions/handleSensor.ts | 13 ++++++++----- .../devices/sharedFunctions/humiditySensor.ts | 13 ++++++++----- .../devices/sharedFunctions/temperatureSensor.ts | 7 +++++-- src/server/services/utils/utils.ts | 6 +++++- src/server/services/victron/victron-device.ts | 8 +++++--- 10 files changed, 61 insertions(+), 29 deletions(-) create mode 100644 src/models/iJsonOmitKeys.ts diff --git a/src/models/iJsonOmitKeys.ts b/src/models/iJsonOmitKeys.ts new file mode 100644 index 00000000..01f9d282 --- /dev/null +++ b/src/models/iJsonOmitKeys.ts @@ -0,0 +1,9 @@ +/** + * An object which defines certain keys to exclude from the JSON output + */ +export interface iJsonOmitKeys { + /** + * List of keys to exclude + */ + readonly jsonOmitKeys: string[]; +} diff --git a/src/models/index.ts b/src/models/index.ts index e342493e..bbd24a0c 100644 --- a/src/models/index.ts +++ b/src/models/index.ts @@ -14,3 +14,4 @@ export * from './objectSettings'; export * from './temperatureSettings'; export * from './timeCallback'; export { BlockAutomaticSettings } from './blockAutomaticSettings'; +export { iJsonOmitKeys } from './iJsonOmitKeys'; diff --git a/src/server/devices/IoBrokerBaseDevice.ts b/src/server/devices/IoBrokerBaseDevice.ts index 20f4401a..1785e60a 100644 --- a/src/server/devices/IoBrokerBaseDevice.ts +++ b/src/server/devices/IoBrokerBaseDevice.ts @@ -1,12 +1,21 @@ import { iRoomDevice } from './baseDeviceInterfaces'; import { API, LogDebugType, ServerLogService, Utils } from '../services'; -import { DeviceSettings, LogLevel, RoomAddDeviceItem, RoomBase, RoomDeviceAddingSettings } from '../../models'; +import { + DeviceSettings, + iJsonOmitKeys, + LogLevel, + RoomAddDeviceItem, + RoomBase, + RoomDeviceAddingSettings, +} from '../../models'; import { IOBrokerConnection, ioBrokerMain } from '../ioBroker'; import { DeviceType } from './deviceType'; import { IoBrokerDeviceInfo } from './IoBrokerDeviceInfo'; import { DeviceCapability } from './DeviceCapability'; -export abstract class IoBrokerBaseDevice implements iRoomDevice { +export abstract class IoBrokerBaseDevice implements iRoomDevice, iJsonOmitKeys { + /** @inheritDoc */ + public readonly jsonOmitKeys: string[] = ['individualStateCallbacks']; /** * The settings for adding devices to Rooms */ @@ -147,7 +156,7 @@ export abstract class IoBrokerBaseDevice implements iRoomDevice { /** @inheritDoc */ public toJSON(): Partial { - return Utils.jsonFilter(this, ['individualStateCallbacks'], ['_room']); + return Utils.jsonFilter(this, this.jsonOmitKeys, ['_room']); } /** @inheritDoc */ diff --git a/src/server/devices/dachs/dachsTemperatureSensor.ts b/src/server/devices/dachs/dachsTemperatureSensor.ts index ed80871c..a163e38d 100644 --- a/src/server/devices/dachs/dachsTemperatureSensor.ts +++ b/src/server/devices/dachs/dachsTemperatureSensor.ts @@ -91,11 +91,6 @@ export class DachsTemperatureSensor implements iTemperatureSensor { this.roomTemperature = newTemperatur; } - /** @inheritDoc */ - public persistTemperaturSensor(): void { - this.temperatureSensor.persist(); - } - /** @inheritDoc */ public log(level: LogLevel, message: string, debugType: LogDebugType = LogDebugType.None): void { ServerLogService.writeLog(level, `${this.name}: ${message}`, { diff --git a/src/server/devices/sharedFunctions/battery.ts b/src/server/devices/sharedFunctions/battery.ts index fa01dcc4..feaee530 100644 --- a/src/server/devices/sharedFunctions/battery.ts +++ b/src/server/devices/sharedFunctions/battery.ts @@ -1,8 +1,9 @@ import { iBatteryDevice } from '../baseDeviceInterfaces'; import { Utils } from '../../services'; import { BatteryLevelChangeAction, VictronDeviceSettings } from '../../../models'; +import { iJsonOmitKeys } from '../../../models/iJsonOmitKeys'; -export class Battery { +export class Battery implements iJsonOmitKeys { /** * The last time the battery was persisted (in milliseconds since 1970) */ @@ -11,6 +12,8 @@ export class Battery { private _lastLevel: number = -1; private _levelCallbacks: Array<(action: BatteryLevelChangeAction) => void> = []; private _lastChangeReportMs: number = 0; + /** @inheritDoc */ + public readonly jsonOmitKeys: string[] = ['_device']; public constructor(private readonly _device: iBatteryDevice) {} @@ -34,10 +37,6 @@ export class Battery { this._lastPersist = now; } - public toJSON(): Partial { - return Utils.jsonFilter(this, ['_device']); - } - /** * Checks whether the battery level did change and if so fires the callbacks */ @@ -64,4 +63,8 @@ export class Battery { public addBatteryLevelCallback(pCallback: (action: BatteryLevelChangeAction) => void): void { this._levelCallbacks.push(pCallback); } + + public toJSON(): Partial { + return Utils.jsonFilter(this, this.jsonOmitKeys); + } } diff --git a/src/server/devices/sharedFunctions/handleSensor.ts b/src/server/devices/sharedFunctions/handleSensor.ts index 534dba53..bf7293a4 100644 --- a/src/server/devices/sharedFunctions/handleSensor.ts +++ b/src/server/devices/sharedFunctions/handleSensor.ts @@ -4,8 +4,11 @@ import { iDisposable, LogDebugType, TelegramService, Utils, WeatherService } fro import { HeatGroup, Window } from '../groups'; import { iHandleSensor } from '../baseDeviceInterfaces'; import { HandleSettings } from '../../../models/deviceSettings/handleSettings'; +import { iJsonOmitKeys } from '../../../models/iJsonOmitKeys'; -export class HandleSensor implements iDisposable { +export class HandleSensor implements iDisposable, iJsonOmitKeys { + /** @inheritDoc */ + public readonly jsonOmitKeys: string[] = ['_device', 'window']; /** * The current position of the handle */ @@ -139,10 +142,6 @@ export class HandleSensor implements iDisposable { this._closedCallback.push(pCallback); } - public toJSON(): Partial { - return Utils.jsonFilter(this, ['_device', 'window']); - } - public dispose(): void { if (this._iOpenTimeout) { clearInterval(this._iOpenTimeout); @@ -166,4 +165,8 @@ export class HandleSensor implements iDisposable { public log(level: LogLevel, message: string, debugType: LogDebugType = LogDebugType.None): void { this._device.log(level, message, debugType); } + + public toJSON(): Partial { + return Utils.jsonFilter(this, this.jsonOmitKeys); + } } diff --git a/src/server/devices/sharedFunctions/humiditySensor.ts b/src/server/devices/sharedFunctions/humiditySensor.ts index 9a42ec42..1cd03e13 100644 --- a/src/server/devices/sharedFunctions/humiditySensor.ts +++ b/src/server/devices/sharedFunctions/humiditySensor.ts @@ -1,8 +1,11 @@ import { Utils } from '../../services'; import { HumiditySensorChangeAction } from '../../../models'; import { iHumiditySensor, UNDEFINED_TEMP_VALUE } from '../baseDeviceInterfaces'; +import { iJsonOmitKeys } from '../../../models/iJsonOmitKeys'; -export class HumiditySensor { +export class HumiditySensor implements iJsonOmitKeys { + /** @inheritDoc */ + public readonly jsonOmitKeys: string[] = ['_device']; private _humidityCallbacks: ((action: HumiditySensorChangeAction) => void)[] = []; private _humidity: number = UNDEFINED_TEMP_VALUE; private readonly _persistHumiditySensorInterval: NodeJS.Timeout = Utils.guardedInterval( @@ -37,14 +40,14 @@ export class HumiditySensor { Utils.dbo?.persistHumiditySensor(this._device); } - public toJSON(): Partial { - return Utils.jsonFilter(this, ['_device']); - } - public addHumidityCallback(pCallback: (action: HumiditySensorChangeAction) => void): void { this._humidityCallbacks.push(pCallback); if (this._humidity > 0) { pCallback(new HumiditySensorChangeAction(this._device, this._humidity)); } } + + public toJSON(): Partial { + return Utils.jsonFilter(this, this.jsonOmitKeys); + } } diff --git a/src/server/devices/sharedFunctions/temperatureSensor.ts b/src/server/devices/sharedFunctions/temperatureSensor.ts index 8a1204ba..cb96ff08 100644 --- a/src/server/devices/sharedFunctions/temperatureSensor.ts +++ b/src/server/devices/sharedFunctions/temperatureSensor.ts @@ -1,8 +1,11 @@ import { Utils } from '../../services'; import { TemperatureSensorChangeAction } from '../../../models'; import { iTemperatureSensor, UNDEFINED_TEMP_VALUE } from '../baseDeviceInterfaces'; +import { iJsonOmitKeys } from '../../../models/iJsonOmitKeys'; -export class TemperatureSensor { +export class TemperatureSensor implements iJsonOmitKeys { + /** @inheritDoc */ + public readonly jsonOmitKeys: string[] = ['_device']; /** * The current room temperature as a number in Celsius */ @@ -55,6 +58,6 @@ export class TemperatureSensor { } public toJSON(): Partial { - return Utils.jsonFilter(this, ['_device']); + return Utils.jsonFilter(this, this.jsonOmitKeys); } } diff --git a/src/server/services/utils/utils.ts b/src/server/services/utils/utils.ts index 7ccdf76b..74bb100b 100644 --- a/src/server/services/utils/utils.ts +++ b/src/server/services/utils/utils.ts @@ -7,6 +7,7 @@ import { SettingsService } from '../settings-service'; import { CatchEmResult } from './catchEmResult'; import { iTimePair } from '../../config'; import { RGB } from './RGB'; +import { iJsonOmitKeys } from '../../../models/iJsonOmitKeys'; export const DAYMS: number = 24 * 60 * 60 * 1000; @@ -114,9 +115,11 @@ export class Utils { 'interval', 'timeouts', 'callback', + 'callbacks', 'otaInfo', 'precalculatedDistancesMap', 'stateMap', + 'jsonOmitKeys', ]; keysToOmit.push(...additionalOmitKeys); const loweredOmitKeys: string[] = keysToOmit.map((key) => key.toLowerCase()); @@ -223,6 +226,7 @@ export class Utils { if (level > 10 && level < 20) { ServerLogService.writeLog(LogLevel.Warn, `DeepOmit Loop Level ${level} reached for ${currentKey}`); } + const combinedOmmitKeys: string[] = [...keysToOmit, ...((obj as iJsonOmitKeys)?.jsonOmitKeys ?? [])]; // the inner function which will be called recursivley return _.transform(obj, (result: { [name: string]: unknown }, value, key: string | number) => { if (value === undefined || value === null) { @@ -230,7 +234,7 @@ export class Utils { } if (typeof key == 'string') { const lowerKey: string = key.toLowerCase(); - for (const checkKey of keysToOmit) { + for (const checkKey of combinedOmmitKeys) { // if the key is in the index skip it if (lowerKey.includes(checkKey)) { return; diff --git a/src/server/services/victron/victron-device.ts b/src/server/services/victron/victron-device.ts index 1306f0a2..4bc8c749 100644 --- a/src/server/services/victron/victron-device.ts +++ b/src/server/services/victron/victron-device.ts @@ -9,12 +9,14 @@ import { iExcessEnergyConsumer, } from '../../devices'; import { EnergyConsumerStateChange, EnergyManagerUtils, Utils } from '../utils'; -import { EnergyCalculation, LogLevel, TimeOfDay, VictronDeviceSettings } from '../../../models'; +import { EnergyCalculation, iJsonOmitKeys, LogLevel, TimeOfDay, VictronDeviceSettings } from '../../../models'; import { LogDebugType, ServerLogService } from '../log-service'; import { VictronDeviceData, VictronMqttConnectionOptions, VictronMqttConsumer } from 'victron-mqtt-consumer'; import { SunTimeOffsets, TimeCallbackService } from '../time-callback-service'; -export class VictronDevice implements iEnergyManager, iBatteryDevice { +export class VictronDevice implements iEnergyManager, iBatteryDevice, iJsonOmitKeys { + /** @inheritDoc */ + public readonly jsonOmitKeys: string[] = ['_victronConsumer', '_excessEnergyConsumer']; /** @inheritDoc */ public readonly deviceCapabilities: DeviceCapability[] = [ DeviceCapability.energyManager, @@ -200,7 +202,7 @@ export class VictronDevice implements iEnergyManager, iBatteryDevice { injectingWattage: this.injectingWattage, selfConsumingWattage: this.selfConsumingWattage, }, - ...Utils.jsonFilter(this, ['_victronConsumer', '_excessEnergyConsumer']), + ...Utils.jsonFilter(this, this.jsonOmitKeys), }; }