Skip to content

Commit

Permalink
Fix NaN device state
Browse files Browse the repository at this point in the history
  • Loading branch information
atrovato committed Dec 4, 2021
1 parent a418dfe commit 64611b7
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 5 deletions.
5 changes: 5 additions & 0 deletions server/lib/device/device.saveState.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const db = require('../../models');
const logger = require('../../utils/logger');
const { EVENTS, WEBSOCKET_MESSAGE_TYPES } = require('../../utils/constants');
const { BadParameters } = require('../../utils/coreErrors');

/**
* @description Save new device feature state in DB.
Expand All @@ -13,6 +14,10 @@ const { EVENTS, WEBSOCKET_MESSAGE_TYPES } = require('../../utils/constants');
* }, 12);
*/
async function saveState(deviceFeature, newValue) {
if (Number.isNaN(newValue)) {
throw new BadParameters(`device.saveState of NaN value on ${deviceFeature.selector}`);
}

logger.debug(`device.saveState of deviceFeature ${deviceFeature.selector}`);
const now = new Date();
const previousDeviceFeature = this.stateManager.get('deviceFeature', deviceFeature.selector);
Expand Down
12 changes: 12 additions & 0 deletions server/migrations/20211204080815-clean-nan-device-states.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const db = require('../models');

module.exports = {
up: async () => {
await db.DeviceFeatureState.destroy({
where: {
value: NaN,
},
});
},
down: async () => {},
};
3 changes: 1 addition & 2 deletions server/services/zigbee2mqtt/utils/convertValue.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ function convertValue(feature, value) {
result = value ? 1 : 0;
break;
}
case 'number':
case 'string': {
case 'number': {
result = value;
break;
}
Expand Down
26 changes: 26 additions & 0 deletions server/test/lib/device/device.saveState.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const { expect } = require('chai');
const { assert, stub, useFakeTimers } = require('sinon');
const Device = require('../../../lib/device');
const StateManager = require('../../../lib/state');
const { BadParameters } = require('../../../utils/coreErrors');

describe('Device.saveState', () => {
it('should saveState and keep history', async () => {
Expand Down Expand Up @@ -116,4 +118,28 @@ describe('Device.saveState', () => {
}
await Promise.all(promises);
});
it('should not save NaN as state', async () => {
const event = {
on: stub().returns(null),
};
const stateManager = new StateManager(event);
const device = new Device(event, {}, stateManager);

const nanValue = parseInt('NaN value', 10);

try {
await device.saveState(
{
id: 'ca91dfdf-55b2-4cf8-a58b-99c0fbf6f5e4',
selector: 'test-device-feature',
has_feedback: false,
keep_history: false,
},
nanValue,
);
assert.fail('NaN device state should fail');
} catch (e) {
expect(e).instanceOf(BadParameters);
}
});
});
9 changes: 6 additions & 3 deletions server/test/services/zigbee2mqtt/utils/convertValue.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,12 @@ describe('zigbee2mqtt convertValue', () => {
const result = convertValue('unknown feature', 4);
return assert.deepEqual(result, 4);
});
it('should return unknown feature string', () => {
const result = convertValue('unknown feature', 'closed');
return assert.equal(result, 'closed');
it('should throw exception on string value', () => {
assert.throw(
() => convertValue('unknown feature', 'closed'),
Error,
`Zigbee2mqqt don't handle value "closed" for feature "unknown feature".`,
);
});
it('should throw Exception', () => {
assert.throw(
Expand Down

0 comments on commit 64611b7

Please sign in to comment.