Skip to content

Commit

Permalink
fix: use new room presence logic for timeout check
Browse files Browse the repository at this point in the history
The state logic of the room presence sensors has been changed to account
for all distances in the cluster, but the timeout still worked the same.
This will use the same logic for the timeout, which should get rid of
some random not_home states.
  • Loading branch information
mKeRix committed Feb 17, 2020
1 parent 87d74c0 commit 872c766
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 27 deletions.
Expand Up @@ -137,7 +137,7 @@ export class BluetoothClassicService extends KalmanFilterable(Object, 1.4, 1)
distributeInquiries(): void {
if (this.clusterService.isMajorityLeader()) {
const nodes = this.getParticipatingNodes();
const addresses = Object.values(this.config.addresses);
const addresses = this.config.addresses;
if (this.rotationOffset >= Math.max(nodes.length, addresses.length)) {
this.rotationOffset = 0;
}
Expand Down Expand Up @@ -316,7 +316,7 @@ export class BluetoothClassicService extends KalmanFilterable(Object, 1.4, 1)
customizations
) as RoomPresenceDistanceSensor;

const interval = setInterval(sensor.checkForTimeout.bind(sensor), INTERVAL);
const interval = setInterval(sensor.updateState.bind(sensor), INTERVAL);
this.schedulerRegistry.addInterval(`${sensorId}_timeout_check`, interval);

return sensor;
Expand All @@ -329,7 +329,7 @@ export class BluetoothClassicService extends KalmanFilterable(Object, 1.4, 1)
*/
protected calculateCurrentTimeout(): number {
const nodes = this.getParticipatingNodes();
const addresses = Object.values(this.config.addresses); // workaround for node-config deserializing to an Array-like object
const addresses = this.config.addresses;
return (Math.max(nodes.length, addresses.length) * 2 * INTERVAL) / 1000;
}

Expand Down
Expand Up @@ -212,7 +212,7 @@ export class BluetoothLowEnergyService extends KalmanFilterable(Object, 0.8, 15)
) as RoomPresenceDistanceSensor;

const interval = setInterval(
sensor.checkForTimeout.bind(sensor),
sensor.updateState.bind(sensor),
this.config.timeout * 1000
);
this.schedulerRegistry.addInterval(`${sensorId}_timeout_check`, interval);
Expand Down
Expand Up @@ -54,34 +54,34 @@ describe('RoomPresenceDistanceSensor', () => {
it('should set the state to not_home if timeout has passed with no other measurements', () => {
sensor.timeout = 15;
sensor.handleNewDistance('room1', 1);
sensor.attributes.lastUpdatedAt = new Date(
sensor.distances.get('room1').lastUpdatedAt = new Date(
Date.now() - 20 * 1000
).toISOString();
);

sensor.checkForTimeout();
sensor.updateState();
expect(sensor.state).toBe(STATE_NOT_HOME);
expect(sensor.attributes.distance).toBeUndefined();
});

it('should disable the timeout check if set to 0', () => {
sensor.timeout = 0;
sensor.handleNewDistance('room1', 3.3);
sensor.attributes.lastUpdatedAt = new Date(
sensor.distances.get('room1').lastUpdatedAt = new Date(
Date.now() - 60 * 60 * 1000
).toISOString();
);

sensor.checkForTimeout();
sensor.updateState();
expect(sensor.state).toBe('room1');
});

it('should not set the state to not_home if the timeout has not passed yet', () => {
sensor.timeout = 30;
sensor.handleNewDistance('room1', 1.2);
sensor.attributes.lastUpdatedAt = new Date(
sensor.distances.get('room1').lastUpdatedAt = new Date(
Date.now() - 10 * 1000
).toISOString();
);

sensor.checkForTimeout();
sensor.updateState();
expect(sensor.state).toBe('room1');
});

Expand Down
21 changes: 7 additions & 14 deletions src/integrations/room-presence/room-presence-distance.sensor.ts
Expand Up @@ -35,6 +35,13 @@ export class RoomPresenceDistanceSensor extends Sensor {
outOfRange = false
): void {
this.distances.set(instanceName, new TimedDistance(distance, outOfRange));
this.updateState();
}

/**
* Updates the sensor state and attributes based on the recorded distances.
*/
updateState(): void {
const closestInRange = this.getClosestInRange();

if (closestInRange) {
Expand All @@ -51,20 +58,6 @@ export class RoomPresenceDistanceSensor extends Sensor {
}
}

/**
* Updates the sensor state to STATE_NOT_HOME if the configured timeout has passed.
*/
checkForTimeout(): void {
if (this.state !== STATE_NOT_HOME && this.timeout > 0) {
const lastUpdate = Date.parse(this.attributes.lastUpdatedAt as string);
const timeoutLimit = new Date(lastUpdate + this.timeout * 1000);

if (Date.now() > timeoutLimit.getTime()) {
this.setNotHome();
}
}
}

/**
* Determines the closest instance.
*
Expand Down

0 comments on commit 872c766

Please sign in to comment.