Skip to content

Commit

Permalink
feat(bluetooth-classic): adds minRssi option
Browse files Browse the repository at this point in the history
Limits the RSSI at which devices are reported by the instance in a
similar manner to maxDistance of the BLE integration.
  • Loading branch information
mKeRix committed Feb 11, 2020
1 parent 546fe62 commit 2051e8e
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 8 deletions.
4 changes: 0 additions & 4 deletions config/test.yml
Expand Up @@ -2,10 +2,6 @@ global:
instanceName: test-instance
integrations:
- bluetoothLowEnergy
bluetoothClassic:
addresses:
- 8d:ad:e3:e2:7a:01
- f7:6c:e3:10:55:b5
gpio:
binarySensors:
- name: PIR Sensor
Expand Down
8 changes: 5 additions & 3 deletions docs/integrations/bluetooth-classic.md
Expand Up @@ -40,16 +40,18 @@ You could use this to reduce the resources used by room-assistant when you are c

## Settings

| Name | Type | Default | Description |
| ----------- | ----- | ------- | ------------------------------------------------------------ |
| `addresses` | Array | | List of Bluetooth MAC addresses that should be tracked. You can usually find them in the device settings. |
| Name | Type | Default | Description |
| ----------- | ------ | ------- | ------------------------------------------------------------ |
| `addresses` | Array | | List of Bluetooth MAC addresses that should be tracked. You can usually find them in the device settings. |
| `minRssi` | Number | | Limits the RSSI at which a device is still reported if configured. Remember, the RSSI is the inverse of the sensor attribute distance, so for a cutoff at 10 you would configure -10. |

::: details Example Config
```yaml
global:
integrations:
- bluetoothClassic
bluetoothClassic:
minRssi: -20
addresses:
- '08:05:90:ed:3b:60'
- '77:50:fb:4d:ab:70'
Expand Down
@@ -1,3 +1,4 @@
export class BluetoothClassicConfig {
addresses: string[] = [];
minRssi?: number;
}
Expand Up @@ -15,6 +15,9 @@ import { NewRssiEvent } from './new-rssi.event';
import { RoomPresenceDistanceSensor } from '../room-presence/room-presence-distance.sensor';
import KalmanFilter from 'kalmanjs';
import { Switch } from '../../entities/switch';
import { BluetoothClassicConfig } from './bluetooth-classic.config';
import c from 'config';
import { ConfigService } from '../../config/config.service';

jest.mock('../room-presence/room-presence-distance.sensor');
jest.mock('kalmanjs', () => {
Expand Down Expand Up @@ -49,6 +52,14 @@ describe('BluetoothClassicService', () => {
error: jest.fn(),
warn: jest.fn()
};
const config: Partial<BluetoothClassicConfig> = {
addresses: ['8d:ad:e3:e2:7a:01', 'f7:6c:e3:10:55:b5']
};
const configService = {
get: jest.fn().mockImplementation((key: string) => {
return key === 'bluetoothClassic' ? config : c.get(key);
})
};

beforeEach(async () => {
jest.clearAllMocks();
Expand All @@ -66,6 +77,8 @@ describe('BluetoothClassicService', () => {
.useValue(entitiesService)
.overrideProvider(ClusterService)
.useValue(clusterService)
.overrideProvider(ConfigService)
.useValue(configService)
.compile();
module.useLogger(loggerService);

Expand Down Expand Up @@ -224,6 +237,45 @@ Requesting information ...
expect(handleRssiMock).not.toHaveBeenCalled();
});

it('should publish RSSI values that are bigger than the min RSSI', async () => {
jest.spyOn(service, 'shouldInquire').mockReturnValue(true);
jest.spyOn(service, 'inquireRssi').mockResolvedValue(-9);
const handleRssiMock = jest
.spyOn(service, 'handleNewRssi')
.mockImplementation(() => undefined);
config.minRssi = -10;

await service.handleRssiRequest('77:50:fb:4d:ab:70');
expect(handleRssiMock).toHaveBeenCalled();
expect(clusterService.publish).toHaveBeenCalled();
});

it('should publish RSSI values that are the same as the min RSSI', async () => {
jest.spyOn(service, 'shouldInquire').mockReturnValue(true);
jest.spyOn(service, 'inquireRssi').mockResolvedValue(-10);
const handleRssiMock = jest
.spyOn(service, 'handleNewRssi')
.mockImplementation(() => undefined);
config.minRssi = -10;

await service.handleRssiRequest('77:50:fb:4d:ab:70');
expect(handleRssiMock).toHaveBeenCalled();
expect(clusterService.publish).toHaveBeenCalled();
});

it('should not publish RSSI values that are smaller than the min RSSI', async () => {
jest.spyOn(service, 'shouldInquire').mockReturnValue(true);
jest.spyOn(service, 'inquireRssi').mockResolvedValue(-11);
const handleRssiMock = jest
.spyOn(service, 'handleNewRssi')
.mockImplementation(() => undefined);
config.minRssi = -10;

await service.handleRssiRequest('77:50:fb:4d:ab:70');
expect(handleRssiMock).not.toHaveBeenCalled();
expect(clusterService.publish).not.toHaveBeenCalled();
});

it('should ignore RSSI requests of inquiries are disabled', () => {
jest.spyOn(service, 'shouldInquire').mockReturnValue(false);
const handleRssiMock = jest
Expand Down
Expand Up @@ -87,7 +87,10 @@ export class BluetoothClassicService extends KalmanFilterable(Object, 1.4, 1)
if (this.shouldInquire()) {
let rssi = await this.inquireRssi(address);

if (rssi !== undefined) {
if (
rssi !== undefined &&
(!this.config.minRssi || rssi >= this.config.minRssi)
) {
rssi = _.round(this.filterRssi(address, rssi), 1);
const event = new NewRssiEvent(
this.configService.get('global').instanceName,
Expand Down

0 comments on commit 2051e8e

Please sign in to comment.