diff --git a/README.md b/README.md index f99ce3b..f0f5d99 100644 --- a/README.md +++ b/README.md @@ -11,26 +11,23 @@ Currently only supports smart plugs, but it should be fairly trivial to add othe const TuyaDevice = require('tuyapi'); - var tuya = new TuyaDevice({ - type: 'outlet', - ip: 'xxx.yyy.0.zzz', + let tuya = new TuyaDevice({ id: 'xxxxxxxxxxxxxxxxxxxx', key: 'xxxxxxxxxxxxxxxx'}); - tuya.getStatus(function(error, status) { - if (error) { return console.log(error); } - console.log('Status: ' + status); + tuya.get().then(status => { + console.log('Status: ' + status); - tuya.setStatus(!status, function(error, result) { - if (error) { return console.log(error); } - console.log('Result of setting status to ' + !status + ': ' + result); + tuya.set({set: !status}).then(result => { + console.log('Result of setting status to ' + !status + ': ' + result); - tuya.getStatus(function(error, status) { - if (error) { return console.log(error); } - console.log('New status: ' + status); + tuya.get().then(status => { + console.log('New status: ' + status); + return; + }); }); }); - }); + This should report the current status, set the device to the opposite of what it currently is, then report the changed status. @@ -44,10 +41,9 @@ See the [docs](docs/API.md). ## TODO -3. Better documentation. -7. Add automated tests -8. Document details of protocol -9. Add error message for no IP +1. Add automated tests +2. Document details of protocol +3. Retry when ECONNRESET is thrown ## Contributors diff --git a/docs/API.md b/docs/API.md index 93dc25e..336666c 100644 --- a/docs/API.md +++ b/docs/API.md @@ -38,13 +38,14 @@ const tuya = new TuyaDevice([ ### resolveIds -Resolves IDs stored in class to IPs. +Resolves IDs stored in class to IPs. If you didn't pass IPs to the constructor, +you must call this before doing anything else. Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)>** true if IPs were found and devices are ready to be used ### get -Gets the device's current status. Defaults to returning only the value of the first result, +Gets a device's current status. Defaults to returning only the value of the first result, but by setting {schema: true} you can get everything. **Parameters** @@ -74,7 +75,7 @@ Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe ### set -Sets the device's status. +Sets a property on a device. **Parameters** diff --git a/index.js b/index.js index e58555e..f68bb94 100644 --- a/index.js +++ b/index.js @@ -38,6 +38,12 @@ function TuyaDevice(options) { // Standardize devices array for (let i = 0; i < this.devices.length; i++) { + if (this.devices[i].id === undefined) { + throw new Error('ID is missing from device.'); + } + if (this.devices[i].key === undefined) { + throw new Error('Encryption key is missing from device with ID ' + this.devices[i].id + '.'); + } if (this.devices[i].type === undefined) { this.devices[i].type = 'outlet'; } @@ -103,7 +109,7 @@ TuyaDevice.prototype.resolveIds = function () { }; /** -* Gets the device's current status. Defaults to returning only the value of the first result, +* Gets a device's current status. Defaults to returning only the value of the first result, * but by setting {schema: true} you can get everything. * @param {Object} [options] - optional options for getting data * @param {String} [options.id] - ID of device @@ -148,7 +154,7 @@ TuyaDevice.prototype.get = function (options) { const thisData = Buffer.from(JSON.stringify(requests[currentDevice.type].status.command)); const buffer = this._constructBuffer(currentDevice.type, thisData, 'status'); - return new Promise(resolve => { + return new Promise((resolve, reject) => { this._send(currentDevice.ip, buffer).then(data => { // Extract returned JSON data = this._extractJSON(data); @@ -158,12 +164,14 @@ TuyaDevice.prototype.get = function (options) { } else { resolve(data.dps['1']); } + }).catch(error => { + reject(error); }); }); }; /** -* Sets the device's status. +* Sets a property on a device. * @param {Object} options - options for setting properties * @param {String} [options.id] - ID of device * @param {Boolean} options.set - `true` for on, `false` for off @@ -244,7 +252,7 @@ TuyaDevice.prototype.set = function (options) { }; /** -* Sends a query to the device. +* Sends a query to a device. * @private * @param {String} ip - IP of device * @param {Buffer} buffer - buffer of data @@ -263,6 +271,7 @@ TuyaDevice.prototype._send = function (ip, buffer) { resolve(data); }); client.on('error', error => { + error.message = "Error communicating with device. Make sure nothing else is trying to control it or connected to it." reject(error); }); }); @@ -274,7 +283,7 @@ TuyaDevice.prototype._send = function (ip, buffer) { * @private * @param {String} type - type of device * @param {String} data - data to put in buffer -* @param {String} command - command (status, on, off, etc.) +* @param {String} command - command (status || set) * @returns {Buffer} buffer - buffer of data */ TuyaDevice.prototype._constructBuffer = function (type, data, command) { @@ -289,7 +298,7 @@ TuyaDevice.prototype._constructBuffer = function (type, data, command) { /** * Extracts JSON from a raw buffer and returns it as an object. * @private -* @param {Buffer} buffer of data +* @param {Buffer} data - buffer of data * @returns {Object} extracted object */ TuyaDevice.prototype._extractJSON = function (data) {