diff --git a/main.js b/main.js index cd3e519..1dac964 100644 --- a/main.js +++ b/main.js @@ -300,6 +300,97 @@ class eWeLink { ...CurrentMonth.parse({ hundredDaysKwhData }), }; } + + /** + * Get device current temperature + * + * @param deviceId + * + * @returns {Promise<{temperature: *, status: string}|{msg: string, error: *}>} + */ + async getDeviceCurrentTemperature(deviceId) { + const device = await this.getDevice(deviceId); + const error = _get(device, 'error', false); + const model = _get(device, 'extra.extra.model', ''); + const temperature = _get(device, 'params.currentTemperature', false); + + if (error || model !== 'PSA-BHA-GL' || !temperature) { + if (error && parseInt(error) === 401) { + return device; + } + return { error, msg: 'Device does not exist' }; + } + + return { status: 'ok', temperature }; + } + + /** + * Get device current humidity + * + * @param deviceId + * + * @returns {Promise<{humidity: *, status: string}|{msg: string, error: *}>} + */ + async getDeviceCurrentHumidity(deviceId) { + const device = await this.getDevice(deviceId); + const error = _get(device, 'error', false); + const model = _get(device, 'extra.extra.model', ''); + const humidity = _get(device, 'params.currentHumidity', false); + + if (error || model !== 'PSA-BHA-GL' || !humidity) { + if (error && parseInt(error) === 401) { + return device; + } + return { error, msg: 'Device does not exist' }; + } + + return { status: 'ok', humidity }; + } + + /** + * Get device channel count + * + * @param deviceId + * + * @returns {Promise<{switchesAmount: *, status: string} + */ + async getDeviceChannelCount(deviceId) { + const device = await this.getDevice(deviceId); + const error = _get(device, 'error', false); + const uiid = _get(device, 'extra.extra.uiid', false); + const switchesAmount = getDeviceChannelCount(uiid); + + if (error) { + if (error && parseInt(error) === 401) { + return device; + } + return { error, msg: 'Device does not exist' }; + } + + return { status: 'ok', switchesAmount }; + } + + /** + * Get device firmware version + * + * @param deviceId + * + * @returns {Promise<{fwVersion: *, status: string}|{msg: string, error: *}>} + */ + async getFirmwareVersion(deviceId) { + const device = await this.getDevice(deviceId); + const error = _get(device, 'error', false); + const fwVersion = _get(device, 'params.fwVersion', false); + + if (error || !fwVersion) { + if (error && parseInt(error) === 401) { + return device; + } + return { error, msg: 'Device does not exist' }; + } + + return { status: 'ok', fwVersion }; + } } module.exports = eWeLink; diff --git a/package-lock.json b/package-lock.json index d9c1bee..482d05a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "ewelink-api", - "version": "1.4.1", + "version": "1.5.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 5801aa2..4a97ac0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ewelink-api", - "version": "1.4.1", + "version": "1.5.0", "description": "eWeLink API for Node.js", "author": "Martín M.", "license": "MIT", @@ -20,7 +20,15 @@ ], "main": "main.js", "scripts": { - "test": "jest --runInBand --verbose --testPathIgnorePatterns '(node_modules|.cache)'" + "test": "jest --runInBand --verbose", + "lint": "eslint .", + "lint:fix": "eslint . --fix" + }, + "jest": { + "testPathIgnorePatterns": [ + "/node_modules/", + ".cache" + ] }, "dependencies": { "delay": "^4.3.0", diff --git a/test/_setup/credentials.json b/test/_setup/credentials.json index fad99fd..92ecd7c 100644 --- a/test/_setup/credentials.json +++ b/test/_setup/credentials.json @@ -4,5 +4,6 @@ "singleChannelDeviceId": "", "deviceIdWithPower": "", "deviceIdWithoutPower": "", + "deviceIdWithTempAndHum": "", "fourChannelsDevice": "" } \ No newline at end of file diff --git a/test/_setup/expectations.js b/test/_setup/expectations.js index 4c674e1..23b628e 100644 --- a/test/_setup/expectations.js +++ b/test/_setup/expectations.js @@ -13,6 +13,7 @@ const allDevicesExpectations = { extra: { extra: { uiid: expect.any(Number), + model: expect.any(String), }, }, }; @@ -25,6 +26,7 @@ const specificDeviceExpectations = { extra: { extra: { uiid: expect.any(Number), + model: expect.any(String), }, }, }; diff --git a/test/main-env-node.spec.js b/test/main-env-node.spec.js index 50efdc5..843cf0c 100644 --- a/test/main-env-node.spec.js +++ b/test/main-env-node.spec.js @@ -1,12 +1,14 @@ const delay = require('delay'); const ewelink = require('../main'); + const { email, password, singleChannelDeviceId, fourChannelsDevice, } = require('./_setup/credentials.json'); + const { loginExpectations, allDevicesExpectations, @@ -136,4 +138,27 @@ describe('env: node script', () => { deviceVerifyAgain.params.switches[channel - 1].switch; expect(currentState).toBe(currentStateVerifyAgain); }); + + test('get channel count 1', async () => { + const result = await conn.getDeviceChannelCount(singleChannelDeviceId); + expect(typeof result).toBe('object'); + expect(result.status).toBe('ok'); + expect(result.switchesAmount).toBe(1); + }); + + test('get channel count 4', async () => { + const result = await conn.getDeviceChannelCount(fourChannelsDevice); + expect(typeof result).toBe('object'); + expect(result.status).toBe('ok'); + expect(result.switchesAmount).toBe(4); + }); + + test('get firmware version', async () => { + const device = await conn.getDevice(singleChannelDeviceId); + const currentVersion = device.params.fwVersion; + const firmware = await conn.getFirmwareVersion(singleChannelDeviceId); + expect(typeof firmware).toBe('object'); + expect(firmware.status).toBe('ok'); + expect(firmware.fwVersion).toBe(currentVersion); + }); }); diff --git a/test/main-env-serverless.spec.js b/test/main-env-serverless.spec.js index 99f0f0b..7c517d1 100644 --- a/test/main-env-serverless.spec.js +++ b/test/main-env-serverless.spec.js @@ -6,7 +6,9 @@ const { email, password, singleChannelDeviceId, + fourChannelsDevice, } = require('./_setup/credentials.json'); + const { loginExpectations, allDevicesExpectations, @@ -90,4 +92,30 @@ describe('env: serverless', () => { const currentStateVerifyAgain = deviceVerifyAgain.params.switch; expect(currentState).toBe(currentStateVerifyAgain); }); + + test('get channel count 1', async () => { + const conn = new ewelink({ at: accessToken }); + const result = await conn.getDeviceChannelCount(singleChannelDeviceId); + expect(typeof result).toBe('object'); + expect(result.status).toBe('ok'); + expect(result.switchesAmount).toBe(1); + }); + + test('get channel count 4', async () => { + const conn = new ewelink({ at: accessToken }); + const result = await conn.getDeviceChannelCount(fourChannelsDevice); + expect(typeof result).toBe('object'); + expect(result.status).toBe('ok'); + expect(result.switchesAmount).toBe(4); + }); + + test('get device firmware version', async () => { + const conn = new ewelink({ at: accessToken }); + const device = await conn.getDevice(singleChannelDeviceId); + const currentVersion = device.params.fwVersion; + const firmware = await conn.getFirmwareVersion(singleChannelDeviceId); + expect(typeof firmware).toBe('object'); + expect(firmware.status).toBe('ok'); + expect(firmware.fwVersion).toBe(currentVersion); + }); }); diff --git a/test/main-invalid-credentials.spec.js b/test/main-invalid-credentials.spec.js index ac11fa2..b818e29 100644 --- a/test/main-invalid-credentials.spec.js +++ b/test/main-invalid-credentials.spec.js @@ -5,6 +5,8 @@ const ewelink = require('../main'); const { singleChannelDeviceId, deviceIdWithPower, + deviceIdWithTempAndHum, + fourChannelsDevice, } = require('./_setup/credentials.json'); describe('invalid credentials', () => { @@ -69,4 +71,50 @@ describe('invalid credentials', () => { expect(powerUsage.msg).toBe('Authentication error'); expect(powerUsage.error).toBe(401); }); + + // test('get device current temperature should fail', async () => { + // const conn = new ewelink({ email: 'invalid', password: 'credentials' }); + // const powerState = await conn.getDeviceCurrentTemperature( + // deviceIdWithTempAndHum + // ); + // expect(typeof powerState).toBe('object'); + // expect(powerUsage.msg).toBe('Authentication error'); + // expect(powerUsage.error).toBe(401); + // }); + + // test('get device current humidity should fail', async () => { + // const conn = new ewelink({ email: 'invalid', password: 'credentials' }); + // const powerState = await conn.getDeviceCurrentHumidity( + // deviceIdWithTempAndHum + // ); + // expect(typeof powerState).toBe('object'); + // expect(powerUsage.msg).toBe('Authentication error'); + // expect(powerUsage.error).toBe(401); + // }); + + test('get channel count 1 should fail', async () => { + const conn = new ewelink({ email: 'invalid', password: 'credentials' }); + const switchesAmount = await conn.getDeviceChannelCount( + singleChannelDeviceId + ); + expect(typeof switchesAmount).toBe('object'); + expect(switchesAmount.msg).toBe('Authentication error'); + expect(switchesAmount.error).toBe(401); + }); + + test('get channel count 4 should fail', async () => { + const conn = new ewelink({ email: 'invalid', password: 'credentials' }); + const switchesAmount = await conn.getDeviceChannelCount(fourChannelsDevice); + expect(typeof switchesAmount).toBe('object'); + expect(switchesAmount.msg).toBe('Authentication error'); + expect(switchesAmount.error).toBe(401); + }); + + test('get device firmware version should fail', async () => { + const conn = new ewelink({ email: 'invalid', password: 'credentials' }); + const firmware = await conn.getFirmwareVersion(singleChannelDeviceId); + expect(typeof firmware).toBe('object'); + expect(firmware.msg).toBe('Authentication error'); + expect(firmware.error).toBe(401); + }); }); diff --git a/test/main-valid-credentials.spec.js b/test/main-valid-credentials.spec.js index 1678c9c..cf17e5b 100644 --- a/test/main-valid-credentials.spec.js +++ b/test/main-valid-credentials.spec.js @@ -86,6 +86,40 @@ describe('valid credentials, invalid device', () => { expect(typeof powerUsage).toBe('object'); expect(powerUsage.error).toBe('No power usage data found.'); }); + + test('get device current temperature should fail', async () => { + const conn = new ewelink({ email, password }); + const temperature = await conn.getDeviceCurrentTemperature( + 'invalid deviceid' + ); + expect(typeof temperature).toBe('object'); + expect(temperature.msg).toBe('Device does not exist'); + expect(temperature.error).toBe(500); + }); + + test('get device current humidity should fail', async () => { + const conn = new ewelink({ email, password }); + const humidity = await conn.getDeviceCurrentHumidity('invalid deviceid'); + expect(typeof humidity).toBe('object'); + expect(humidity.msg).toBe('Device does not exist'); + expect(humidity.error).toBe(500); + }); + + test('get channel count should fail', async () => { + const conn = new ewelink({ email, password }); + const switchesAmount = await conn.getDeviceChannelCount('invalid deviceid'); + expect(typeof switchesAmount).toBe('object'); + expect(switchesAmount.msg).toBe('Device does not exist'); + expect(switchesAmount.error).toBe(500); + }); + + test('get device firmware version should fail', async () => { + const conn = new ewelink({ email, password }); + const firmwareVersion = await conn.getFirmwareVersion('invalid deviceid'); + expect(typeof firmwareVersion).toBe('object'); + expect(firmwareVersion.msg).toBe('Device does not exist'); + expect(firmwareVersion.error).toBe(500); + }); }); describe('valid credentials, wrong region', () => { diff --git a/test/temperature-humidity.spec.js b/test/temperature-humidity.spec.js new file mode 100644 index 0000000..cb485b7 --- /dev/null +++ b/test/temperature-humidity.spec.js @@ -0,0 +1,74 @@ +const ewelink = require('../main'); + +const { + email, + password, + deviceIdWithTempAndHum, +} = require('./_setup/credentials.json'); + +describe.skip('current temerature and humidity: node script', () => { + let conn; + + beforeAll(async () => { + conn = new ewelink({ email, password }); + await conn.login(); + }); + + test('should return current temperature', async () => { + const device = await conn.getDevice(deviceIdWithTempAndHum); + const { currentTemperature } = device.params; + const temperature = await conn.getDeviceCurrentTemperature( + deviceIdWithTempAndHum + ); + expect(typeof temperature).toBe('object'); + expect(temperature.status).toBe('ok'); + expect(temperature.state).toBe(currentTemperature); + }); + + test('should return current humidity', async () => { + const device = await conn.getDevice(deviceIdWithTempAndHum); + const { currentHumidity } = device.params; + const humidity = await conn.getDeviceCurrentHumidity( + deviceIdWithTempAndHum + ); + expect(typeof humidity).toBe('object'); + expect(humidity.status).toBe('ok'); + expect(humidity.state).toBe(currentHumidity); + }); +}); + +describe('current temerature and humidity: serverless', () => { + let accessToken; + let apiKey; + + beforeAll(async () => { + const conn = new ewelink({ email, password }); + const login = await conn.login(); + accessToken = login.at; + apiKey = login.user.apikey; + }); + + test('should return current temperature', async () => { + const conn = new ewelink({ at: accessToken, apiKey }); + const device = await conn.getDevice(deviceIdWithTempAndHum); + const { currentTemperature } = device.params; + const temperature = await conn.getDeviceCurrentTemperature( + deviceIdWithTempAndHum + ); + expect(typeof temperature).toBe('object'); + expect(temperature.status).toBe('ok'); + expect(temperature.state).toBe(currentTemperature); + }); + + test('should return current humidity', async () => { + const conn = new ewelink({ at: accessToken, apiKey }); + const device = await conn.getDevice(deviceIdWithTempAndHum); + const { currentHumidity } = device.params; + const humidity = await conn.getDeviceCurrentHumidity( + deviceIdWithTempAndHum + ); + expect(typeof humidity).toBe('object'); + expect(humidity.status).toBe('ok'); + expect(humidity.state).toBe(currentHumidity); + }); +});