Closed petetastic closed 5 years ago
As long as you're creating multiple TuyAPI objects, one for each device, all with persistentConnection
enabled, it should work the same as if you were controlling one device as long as your network doesn't have something weird going on. What does your code look like?
I am creating multiple objects, but anything after the first one fails, no matter what, with an error:
UnhandledPromiseRejectionWarning: Error: bind EADDRINUSE 0.0.0.0:6666
Here's a stripped down version of my code. So I created my own device class like this:
module.exports = class Device {
constructor(name, tuyaData) {
this.tuyaDevice = new TuyAPI(tuyaData);
this.tuyaDevice.resolveId()
.then(()=>{this.tuyaDevice.connect();})
}
}
...and I create multiple devices like this:
for (var i=0; i<data.devices.length; i++) {
devices[data.devices[i].name] = (new Device(
data.devices[i].name,
data.devices[i].tuyaData
));
}
Am I missing something simple?
Thanks
Oh, the issue is that the discovery process for finding IPs binds to the hard-coded port 6666. I need to change that so it's randomized.
Until I do so, try passing in the IP to your constructor, take out resolveId()
, and see if it works.
EDIT: Looks like more investigation is needed. I'm not a network expert, but it appears Tuya devices only broadcast to 6666, so I'm not sure if that can be changed.
I would recemend making an array of Promises, then using something like described in this post to resolve them sequentially.
Thanks. Sorry if if I'm misunderstanding, but what would this array of promises contain exactly?
Just the resolveId()
functions.
It's not the only way to do it, but it's what I thought of first. 🤷♂️
Nope, still doesn't work if I connect to them synchronously. I tried just doing two lights, one after the other like this:
devices["New York"].connect()
.then(() => {
console.log("New York is Connected");
devices["London"].connect()
.then(() => {
console.log("London is Connected");
})
})
where connect is a class function that looks like:
async connect()
{
try {
this.tuyaDevice.resolveId()
.then(()=>{
this.tuyaDevice.connect();
})
} catch (error) {
console.log("error",error);
}
}
but I still get EADDRINUSE.
Hmmm. The app must have a way of connecting to them all at once. Maybe it connects on port 6666 and then cunningly switches port somehow as a sneaky way to give them all guaranteed different port numbers?
TuyAPI should release port 6666 after resolving the ID.
I think your promises are resolving in parallel, you can check this by adding a log statement to your connect()
function:
async connect()
{
try {
this.tuyaDevice.resolveId()
.then(()=>{
this.tuyaDevice.connect();
})
} catch (error) {
console.log("error",error);
}
console.log('Resolved.');
}
When run, your script should then have a delay between each printed 'Resolved'.
I'm guessing the changes you'll have to make are:
async connect()
{
try {
await this.tuyaDevice.resolveId();
this.tuyaDevice.connect();
} catch (error) {
console.log("error",error);
}
}
I have the same issue and #116 fixes it.
@petetastic I merged @neojski's PR in v3.1.5
if you want to test it now.
I used this API to control my Tuya sockets with a Raspberry Pi and was delighted to find that the control is instantaneous—as fast as a light switch—but I can't seem to do this for more than one light. Your doc states that we can't have more than one TCP connection per device but is there a way to maintain persistent connections to multiple devices? If not, we must connect each time, and the result is that it takes ~3-4 secs to turn a light off. How does the Tuya app do it?
Thanks!