diff --git a/src/integrations/bluetooth-low-energy/bluetooth-low-energy.service.spec.ts b/src/integrations/bluetooth-low-energy/bluetooth-low-energy.service.spec.ts index 82c934a3..00857083 100644 --- a/src/integrations/bluetooth-low-energy/bluetooth-low-energy.service.spec.ts +++ b/src/integrations/bluetooth-low-energy/bluetooth-low-energy.service.spec.ts @@ -531,6 +531,33 @@ describe('BluetoothLowEnergyService', () => { ); }); + it('should look up overrides in case insensitive manner', async () => { + const handleDistanceSpy = jest + .spyOn(service, 'handleNewDistance') + .mockImplementation(() => undefined); + jest.spyOn(service, 'isOnAllowlist').mockReturnValue(true); + jest.spyOn(service, 'isAllowlistEnabled').mockReturnValue(true); + mockConfig.tagOverrides = { + ABcd: { + id: 'new-id', + }, + }; + + await service.handleDiscovery({ + id: 'abcd', + rssi: -12, + advertisement: { + localName: 'Test BLE Device', + }, + } as Peripheral); + + expect(handleDistanceSpy).toHaveBeenCalledWith( + expect.objectContaining({ + tagId: 'new-id', + }) + ); + }); + it('should not publish state changes for devices that are not on the allowlist', async () => { jest.spyOn(service, 'isOnAllowlist').mockReturnValue(false); diff --git a/src/integrations/bluetooth-low-energy/bluetooth-low-energy.service.ts b/src/integrations/bluetooth-low-energy/bluetooth-low-energy.service.ts index a690a72d..6ba45a0f 100644 --- a/src/integrations/bluetooth-low-energy/bluetooth-low-energy.service.ts +++ b/src/integrations/bluetooth-low-energy/bluetooth-low-energy.service.ts @@ -29,6 +29,7 @@ import { BluetoothLowEnergyPresenceSensor } from './bluetooth-low-energy-presenc import { BluetoothService } from '../../integration-support/bluetooth/bluetooth.service'; import { promiseWithTimeout } from '../../util/promises'; import * as util from 'util'; +import { getPropertyCaseInsensitive } from '../../util/objects'; export const NEW_DISTANCE_CHANNEL = 'bluetooth-low-energy.new-distance'; const APPLE_ADVERTISEMENT_ID = Buffer.from([0x4c, 0x00]); @@ -36,7 +37,8 @@ const APPLE_ADVERTISEMENT_ID = Buffer.from([0x4c, 0x00]); @Injectable() export class BluetoothLowEnergyService extends KalmanFilterable(Object, 0.008, 4) - implements OnModuleInit, OnApplicationBootstrap { + implements OnModuleInit, OnApplicationBootstrap +{ private readonly config: BluetoothLowEnergyConfig; private readonly logger: Logger; private readonly seenIds = new Set(); @@ -462,8 +464,12 @@ export class BluetoothLowEnergyService * @returns Same tag with potentially overridden data */ protected applyOverrides(tag: Tag): Tag { - if (this.config.tagOverrides.hasOwnProperty(tag.id)) { - const overrides = this.config.tagOverrides[tag.id]; + const overrides = getPropertyCaseInsensitive( + this.config.tagOverrides, + tag.id + ); + + if (overrides != undefined) { if (overrides.id !== undefined) { tag.id = overrides.id; } diff --git a/src/util/objects.ts b/src/util/objects.ts new file mode 100644 index 00000000..7b3737c0 --- /dev/null +++ b/src/util/objects.ts @@ -0,0 +1,17 @@ +/** + * Retrieves an object property in a case insensitive manner. + * Adapted from https://stackoverflow.com/questions/12484386/access-javascript-property-case-insensitively. + * + * @param object - Object in which to look for the property + * @param key - Key of the property + */ +export function getPropertyCaseInsensitive< + T extends Record, + K extends keyof T +>(object: T, key: K): T[K] { + return object[ + Object.keys(object).find( + (k) => k.toLowerCase() === key.toString().toLowerCase() + ) + ] as T[K]; +}