Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Google Home: Should normalize brightness scale when controlling device with custom scale #1813

Merged
merged 3 commits into from
Jun 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const { normalize } = require('../../../../utils/device');
const { DEVICE_FEATURE_CATEGORIES, DEVICE_FEATURE_TYPES } = require('../../../../utils/constants');

/**
Expand All @@ -19,7 +20,7 @@ const brightnessTrait = {
{
key: 'brightness',
readValue: (feature) => {
return feature.last_value;
return Math.round(normalize(feature.last_value, feature.min, feature.max, 0, 100));
},
},
],
Expand All @@ -34,7 +35,7 @@ const brightnessTrait = {
if (relatedFeature) {
events.push({
device_feature: relatedFeature.selector,
value: brightness,
value: Math.round(normalize(brightness, 0, 100, relatedFeature.min, relatedFeature.max)),
});
}

Expand Down
2 changes: 1 addition & 1 deletion server/services/homekit/lib/buildService.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const {
EVENTS,
DEVICE_FEATURE_UNITS,
} = require('../../../utils/constants');
const { normalize } = require('./utils');
const { normalize } = require('../../../utils/device');
const { fahrenheitToCelsius } = require('../../../utils/units');

const sleep = promisify(setTimeout);
Expand Down
2 changes: 1 addition & 1 deletion server/services/homekit/lib/sendState.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { intToRgb, rgbToHsb } = require('../../../utils/colors');
const { DEVICE_FEATURE_CATEGORIES, DEVICE_FEATURE_TYPES, DEVICE_FEATURE_UNITS } = require('../../../utils/constants');
const { normalize } = require('./utils');
const { normalize } = require('../../../utils/device');
const { fahrenheitToCelsius } = require('../../../utils/units');
const { mappings } = require('./deviceMappings');

Expand Down
18 changes: 0 additions & 18 deletions server/services/homekit/lib/utils.js

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ describe('GoogleActions Handler - onSync - brightness (light)', () => {
category: DEVICE_FEATURE_CATEGORIES.LIGHT,
type: DEVICE_FEATURE_TYPES.LIGHT.BRIGHTNESS,
last_value: 73,
min: 0,
max: 100,
},
],
model: 'device-model',
Expand Down Expand Up @@ -144,6 +146,65 @@ describe('GoogleActions Handler - onSync - brightness (light)', () => {
assert.notCalled(gladys.event.emit);
});

it('should get device value with custom scale - onQuery', async () => {
const device = {
name: 'Device 1',
selector: 'device-1',
external_id: 'device-1-external-id',
features: [
{
selector: 'feature-1',
category: DEVICE_FEATURE_CATEGORIES.LIGHT,
type: DEVICE_FEATURE_TYPES.LIGHT.BRIGHTNESS,
last_value: 127,
min: 0,
max: 254,
},
],
model: 'device-model',
room: {
name: 'living-room',
},
};

gladys = {
event: {
emit: fake.resolves(null),
},
stateManager: {
get: fake.returns(device),
state: {
device: {
device_1: {
get: fake.returns(device),
},
},
},
},
};

googleActionsHandler = new GoogleActionsHandler(gladys, serviceId);
const result = await googleActionsHandler.onQuery(body);

const expectedResult = {
requestId: 'request-id',
payload: {
agentUserId: 'user-id',
devices: {
'device-1': {
online: true,
brightness: 50,
},
},
},
};
expect(result).to.deep.eq(expectedResult);

assert.notCalled(gladys.stateManager.state.device.device_1.get);
assert.calledOnceWithExactly(gladys.stateManager.get, 'device', 'device-1');
assert.notCalled(gladys.event.emit);
});

it('should emit Gladys event with new value - onExecute', async () => {
const result = await googleActionsHandler.onExecute(body);

Expand Down Expand Up @@ -171,4 +232,68 @@ describe('GoogleActions Handler - onSync - brightness (light)', () => {
value: 20,
});
});
it('should emit Gladys event with new value on scale 0 - 254 - onExecute', async () => {
const device = {
name: 'Device 1',
selector: 'device-1',
external_id: 'device-1-external-id',
features: [
{
selector: 'feature-1',
category: DEVICE_FEATURE_CATEGORIES.LIGHT,
type: DEVICE_FEATURE_TYPES.LIGHT.BRIGHTNESS,
last_value: 73,
min: 0,
max: 254,
},
],
model: 'device-model',
room: {
name: 'living-room',
},
};

gladys = {
event: {
emit: fake.resolves(null),
},
stateManager: {
get: fake.returns(device),
state: {
device: {
device_1: {
get: fake.returns(device),
},
},
},
},
};

googleActionsHandler = new GoogleActionsHandler(gladys, serviceId);
const result = await googleActionsHandler.onExecute(body);

const expectedResult = {
requestId: 'request-id',
payload: {
agentUserId: 'user-id',
commands: [
{
ids: ['device-1'],
status: 'PENDING',
},
],
},
};
expect(result).to.deep.eq(expectedResult);

assert.notCalled(gladys.stateManager.state.device.device_1.get);
assert.calledOnceWithExactly(gladys.stateManager.get, 'device', 'device-1');
assert.calledOnceWithExactly(gladys.event.emit, EVENTS.ACTION.TRIGGERED, {
device: 'device-1',
device_feature: 'feature-1',
status: 'pending',
type: 'device.set-value',
value: 51,
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ describe('GoogleActions Handler - onSync - brightness (switch)', () => {
selector: 'feature-1',
category: DEVICE_FEATURE_CATEGORIES.SWITCH,
type: DEVICE_FEATURE_TYPES.SWITCH.DIMMER,
min: 0,
max: 100,
last_value: 73,
},
],
Expand Down
10 changes: 0 additions & 10 deletions server/test/services/homekit/lib/utils.test.js

This file was deleted.

9 changes: 9 additions & 0 deletions server/test/utils/device.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const {
hasDeviceChanged,
mergeFeatures,
mergeDevices,
normalize,
} = require('../../utils/device');

const buildObject = (prefix, attributes) => {
Expand Down Expand Up @@ -262,3 +263,11 @@ describe('mergeDevice', () => {
expect(mergedDevice).to.deep.equal(expectedDevice);
});
});

describe('normalize', () => {
it('should normalize data to new range', async () => {
const newValue = normalize(50, 0, 100, 0, 360);

expect(newValue).to.equal(180);
});
});
16 changes: 16 additions & 0 deletions server/utils/device.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,27 @@ function mergeDevices(newDevice, existingDevice, updateAttribute = 'updatable')
return { ...existingDevice, ...newDevice, name, room_id: roomId, features, [updateAttribute]: deviceChanged };
}

/**
* @description Normalize value to new range.
* @param {number} value - Actual value.
* @param {number} currentMin - Actual possible min value.
* @param {number} currentMax - Actual possible max value.
* @param {number} newRangeMin - Target possible min value.
* @param {number} newRangeMax - Target possible max value.
* @returns {number} New value in target range.
* @example
* normalize(5, 0, 255, 0, 360)
*/
function normalize(value, currentMin, currentMax, newRangeMin, newRangeMax) {
return ((newRangeMax - newRangeMin) * (value - currentMin)) / (currentMax - currentMin) + newRangeMin;
}

module.exports = {
getDeviceParam,
setDeviceParam,
getDeviceFeature,
hasDeviceChanged,
mergeFeatures,
mergeDevices,
normalize,
};