-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #42 from Grizzelbee/Dev_0.7.0
Dev 0.7.0
- Loading branch information
Showing
12 changed files
with
1,675 additions
and
1,203 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
'use strict'; | ||
|
||
const _ = require('lodash'); | ||
const crypto = require('crypto'); | ||
|
||
// class DysonUtils { | ||
// DysonUtils() {} | ||
// } | ||
|
||
/** | ||
* Function zeroFill | ||
* | ||
* Formats a number as a string with leading zeros | ||
* | ||
* @param number {number} Value thats needs to be filled up with leading zeros | ||
* @param width {number} width of the complete new string incl. number and zeros | ||
* | ||
* @returns The given number filled up with leading zeros to a given width (excluding the negative sign), returns empty string if number is not an actual number. | ||
*/ | ||
module.exports.zeroFill = function (number, width) { | ||
const num = parseInt(number); | ||
|
||
if (isNaN(num)) { | ||
return ''; | ||
} | ||
|
||
const negativeSign = num < 0 ? '-' : ''; | ||
const str = '' + Math.abs(num); | ||
|
||
return `${negativeSign}${_.padStart(str, width, '0')}`; | ||
}; | ||
|
||
/** | ||
* checkAdapterConfig | ||
* | ||
* {promise} Tests whether the given adapters config is valid | ||
* resolves if the config is valid | ||
* rejects if the config is invalid | ||
* | ||
* @param config {Adapter} ioBroker adapter which contains the configuration that should be checked | ||
*/ | ||
module.exports.checkAdapterConfig = async function (adapter) { | ||
adapter.log.debug('Entering function [checkAdapterConfig]...'); | ||
|
||
const config = adapter.config; | ||
|
||
// Masking sensitive fields (password) for logging configuration (creating a deep copy of the config) | ||
const logConfig = JSON.parse(JSON.stringify(config)); | ||
logConfig.Password = '(***)'; | ||
// TODO Move to separate function for masking config wherever needed in this module | ||
|
||
return new Promise( | ||
function (resolve, reject) { | ||
// TODO Do more precise tests. This is very rough | ||
if ((!config.email || config.email === '') | ||
|| (!config.Password || config.Password === '') | ||
|| (!config.country || config.country === '')) { | ||
adapter.log.debug(`Invalid configuration provided: ${logConfig}`); | ||
reject('Given adapter config is invalid. Please fix.'); | ||
} else { | ||
resolve('Given config seems to be valid.'); | ||
} | ||
}); | ||
}; | ||
|
||
/** | ||
* Function decryptMqttPasswd | ||
* decrypts the fans local mqtt password and returns a value you can connect with | ||
* | ||
* @param LocalCredentials {string} encrypted mqtt password | ||
*/ | ||
module.exports.decryptMqttPasswd = function (LocalCredentials) { | ||
// Gets the MQTT credentials from the thisDevice (see https://github.com/CharlesBlonde/libpurecoollink/blob/master/libpurecoollink/utils.py) | ||
const key = Uint8Array.from(Array(32), (_, index) => index + 1); | ||
const initializationVector = new Uint8Array(16); | ||
const decipher = crypto.createDecipheriv('aes-256-cbc', key, initializationVector); | ||
const decryptedPasswordString = decipher.update(LocalCredentials, 'base64', 'utf8') + decipher.final('utf8'); | ||
const decryptedPasswordJson = JSON.parse(decryptedPasswordString); | ||
return decryptedPasswordJson.apPasswordHash; | ||
}; | ||
|
||
/** | ||
* Parse an incoming JSON message payload from the Dyson device | ||
* | ||
* @param msg Incoming JSON message | ||
*/ | ||
module.exports.parseDysonMessage = function (msg) { | ||
if (null == msg || '' == msg) return; | ||
|
||
// TODO incomplete | ||
|
||
// const data = JSON.parse(msg); | ||
// console.log(data); | ||
return; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
'use strict'; | ||
|
||
const fs = require('fs'); | ||
|
||
const { fail } = require('assert'); | ||
const { expect } = require('chai'); | ||
const sinon = require('sinon'); | ||
|
||
const dysonUtils = require('./dyson-utils'); | ||
|
||
describe('dysonUtils => zeroFill', () => { | ||
it('should left-pad zeroes for positive input numbers', () => { | ||
const data = [ | ||
[5, 4, '0005'], | ||
[1, 1, '1'], | ||
[45, 2, '45'], | ||
[734, 8, '00000734'], | ||
]; | ||
|
||
data.forEach(d => { | ||
expect(dysonUtils.zeroFill(d[0], d[1])).to.equal(d[2]); | ||
}); | ||
}); | ||
|
||
it('should left-pad zeroes for negative input numbers (width excludes negative sign)', () => { | ||
const data = [ | ||
[-5, 4, '-0005'], | ||
[-1, 1, '-1'], | ||
[-45, 2, '-45'], | ||
[-734, 8, '-00000734'], | ||
]; | ||
|
||
data.forEach(d => { | ||
expect(dysonUtils.zeroFill(d[0], d[1])).to.equal(d[2]); | ||
}); | ||
}); | ||
|
||
it('should return empty string for invalid (non-number or empty) input', () => { | ||
expect(dysonUtils.zeroFill('', 50)).to.equal(''); | ||
expect(dysonUtils.zeroFill('äöüß', 50)).to.equal(''); | ||
}); | ||
}); | ||
|
||
describe('dysonUtils => checkAdapterConfig', () => { | ||
after(() => sinon.restore() ); | ||
|
||
const fakeAdapter = { | ||
log: { debug: sinon.fake() }, | ||
config: null | ||
}; | ||
|
||
it('should reject an empty adapter configuration', () => { | ||
fakeAdapter.config = { | ||
temperatureUnit: '', | ||
pollInterval: '', | ||
country: '', | ||
email: '', | ||
Password: '' | ||
}; | ||
expect(dysonUtils.checkAdapterConfig(fakeAdapter)).to.be.rejected; | ||
}); | ||
|
||
it('should pass with a valid adapter configuration', () => { | ||
fakeAdapter.config = { | ||
temperatureUnit: 'C', | ||
pollInterval: 60, | ||
country: 'DE', | ||
email: '[email protected]', | ||
Password: 'SecretPassword' | ||
}; | ||
expect(dysonUtils.checkAdapterConfig(fakeAdapter)).to.be.fulfilled; | ||
}); | ||
|
||
}); | ||
|
||
describe('dysonUtils => decrypt', () => { | ||
it.skip('should verify decrypt mechanism', () => {}); | ||
}); | ||
|
||
describe('dysonUtils => decryptMqttPasswd', () => { | ||
it.skip('should verify decrypt MQTT password mechanism', () => {}); | ||
}); | ||
|
||
describe('dysonUtils => parseDysonMsgPayload', () => { | ||
// TODO See adapter.processMsg() for now, considering migration to separate message parser later | ||
|
||
it('should ignore empty or null message payload', () => { | ||
try { | ||
dysonUtils.parseDysonMessage(''); | ||
dysonUtils.parseDysonMessage(null); | ||
} catch (error) { | ||
fail(`Error ${error} thrown during message processing.`); | ||
} | ||
}); | ||
|
||
it.skip('should parse a DP01 CURRENT-STATE payload', () => { | ||
const msg = fs.readFileSync('./test/sample-data/sample-msg-DP01-1.json'); | ||
const data = JSON.parse(msg); | ||
|
||
console.log(data); | ||
}); | ||
|
||
it.skip('should parse a DP01 ENVIRONMENTAL-CURRENT-SENSOR-DATA payload', () => { | ||
const msg = fs.readFileSync('./test/sample-data/sample-msg-DP01-2.json'); | ||
const data = JSON.parse(msg); | ||
|
||
console.log(data); | ||
}); | ||
|
||
it.skip('should parse a DP01 STATE-CHANGE payload', () => { | ||
const msg = fs.readFileSync('./test/sample-data/sample-msg-DP01-3.json'); | ||
const data = JSON.parse(msg); | ||
|
||
console.log(data); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.