TheAgentK / tuya-mqtt

Nodejs-Script to combine tuyaapi and openhab via mqtt
MIT License
173 stars 81 forks source link

Different names after service restart #86

Closed Angel0ffDeath closed 10 months ago

Angel0ffDeath commented 10 months ago

@TheAgentK , @tsightler , @michael-c-hoffman , @vkoop

I see this project is on hold, but I have a question.

tuya-mqtt service by me is working perfect. Only 1 small problem; I'm integrating tuya devices in FHEM. The devices are tuya IR remote controls - 2 with temp/humidity sensors and 2 without. For each device I have defined a template and everything is working ok. I'm using the native MQTT server built in FHEM, so I don't need mosquitto. Autocreate option of MQTT server is on, so as soon as I start the tuya-mqtt service all devices are imidiatelly discovered and created in FHEM. As I said everything works perfect. The only problem occurs when tuya-mqtt service restarts - manual restart or reboot - everything works again ok, but devices are published with new names (definitions). Of course FHEM finds and creates them immideatelly, but old definitions are no longer working and I must delete them. Of course I didn't change anything in devices configuration like names, etc.

For instance: The name for one of the devices: mqttjs_61bfdcd6 after restart of the service, the same device becomes mqttjs_1d07da6f

I disconnected all other devices to discover that, so I'm sure about this change.

So the question is - Is it possible the names of the devices published by the service to be the same after restart of the service?

tsightler commented 10 months ago

Those are not the device names, that is the MQTT clientId that is used when connecting to the MQTT broker. I have no idea why any tool would try to use the clientId as part of the device identifier, but that is clearly what FHEM is doing (whatever FHEM is).

Currently tuya-mqtt does not provide a persistent clientId because, realistically, it's not expected to matter. When no explicit clientId is defined, the MQTT.js library automatically generates a clientId as documented on here.

If you look at tuya-mqtt.js, around line 107, you will see code like this:

    mqttClient = mqtt.connect({
        host: CONFIG.host,
        port: CONFIG.port,
        username: CONFIG.mqtt_user,
        password: CONFIG.mqtt_pass,
    })

You can manually add a persistent clientId option here if you wish, say something like:

    mqttClient = mqtt.connect({
        host: CONFIG.host,
        port: CONFIG.port,
        username: CONFIG.mqtt_user,
        password: CONFIG.mqtt_pass,
        clientId: 'tuya-mqtt'
    })

And then the client ID will be the same every time.

Angel0ffDeath commented 10 months ago

@tsightler Thanks for the fast response.

  1. FHEM is something like HASS but written in Perl. And - Yes native MQTT server built in FHEM is using clientId to identify devices.
  2. Yes adding clientId works... with 1 device. Unfortunately if you have more than 1 device then all clienId's are the same and all devices go under 1 definition. Of course different topics. I think it is better to set clientId to device name or deviceId (maybe deviceId better - I didn't tested 2 tuya devices in 2 different rooms, but with the same names :) , but who knows.... ), It seems in configDevices we have all necessary info, but unfortunately I'm not an expert in JS and can't find out how to extract deviceId

Any ideas?

tsightler commented 10 months ago

You can't because there's only a single connection to MQTT per tuya-mqtt instance no matter how many Tuya devices you have configured, so there's only a single clientId possible. That's why I think it's crazy for FHEM to use this as an identifier. It's like it assumes that every device is it's own client, which is true for things like a Tasmota switch, but is not true for things like tuya-mqtt, which will bridge mulituple devices with a single MQTT connection. I would take it up with FHEM to use something other than clientId as, if they are using that alone, that's just crazy, IMO.

Regardless, you could perhaps just run mulitple instances of tuya-mqtt, one for each device, with a unqiue clientId for each one. I have no idea if that will work, I've never tested it and I don't use or maintain this project anymore, but I think it should.

Angel0ffDeath commented 10 months ago

@tsightler Thanks again for the fast response, but I don't think the above in you answer is quite correct. When I attach all my 4 devices - I have 4 definitions in FHEM, i.e. 4 times MQTT.js library was invoked to generate 4 different clientId's. This doesn't mean we have 4 connections to MQTT server (but probably we have in order if devices must speak simoultaneously to server, not to wait). Just means we have 4 different clientId's. With all 4 devices after service restart I have 4 new devices (new clientId's since in the code of MQTT.js library it is random number). This definitely means, this function is invoked for each device.

So the idea is to set this clientId in tuya-mqtt.js and not to leave it to MQTT.js library.

As far as I'm working with MQTT, and as far as I know each device should have unique ID. How many connections will be opened from client to server - depends on brocker (server) and client of course, but usualy 1 connection for each device with unique clientId.

Of course I found already about 2 work arounds, but I still believe something could e improved in tuya-mqtt.

Thank you.

Edit: If you give me a clue how to find deviceId from configDevices structure for each device, I can test it and prove or revoke my theory above. I'm just not an expert with JS and will take me a lot of time to find it. Thank you in advance

tsightler commented 10 months ago

OK, well, I wrote the code you are talking about, as well as maintain other projects which make far greater use of MQTT than this project, so I have a pretty good grasp of how it all works, but you are welcome to think whatever you wish. Your statements are simply incorrect, but I won't continue to waste my time. Good luck!

Angel0ffDeath commented 10 months ago

Ok. Sorry. I was just thinking.... Sorry again.

tsightler commented 10 months ago

OK, I will try again.

This definitely means, this function is invoked for each device.

It is absolutely not the case, the code is quite clear, a single MQTT client is created. That's the way MQTT bridges work, they bridge multiple non-MQTT devices, in this cases Tuya devices, to MQTT via a single MQTT client. Sure, as I stated above, if you have mulitple devices that speak MQTT natively, then each will have it's own client ID, but that is not the case here, tuya-mqtt is a bridge.

I took a quick look at FHEM documentation and it clearly understands that bridges will have multiple devices with a single client ID, the use of client ID is just kind of a default behavior. For bridges it has the bridgeRegexp attribute which can be used to create individual devices from the topics created for different devices via tuya-mqtt.

In a quick glance at the FHEM source code I see there is also some basic support for Home Assitant style MQTT autodiscovery, which tuya-mqtt also supports and sends automatically, so I'm guessing that could be how you are seeing multiple devices now. Regardless, FHEM provides all the tools needed to uniquely identify multiple devices coming from the same MQTT client ID.

Angel0ffDeath commented 10 months ago

@tsightler The above is correct. This was one of the work arounds I spoke above. The other is to define dummy devices and take necessary readings. Both approaches have procs and cons. Since only 2 of the devices have temp/humidity readings I removed the other 2 from config file. I'm not going to operate tuya IR remote control from FHEM - it is easier to operate with original remote. So in general now I have temp/humidity readings in 2 different devices, which was the purpose.

Thank you for the support. And one more time sorry, if I insulted you.

One last question - I noticed, after I start tuya-mqtt service from time to time my headless RPi (while im typing on remote PC) is not responding. After about 5-10 seconds everything I typed appears. The situation is the same even after I stop tuya-mqtt service. But after reboot everything is ok. Is it possible tuyapi to cause this problem?

Edit: You can consider this as 'Solved' and close the issue, if you want.

tsightler commented 10 months ago

Anything is possible, but I think it is unlikely the tuya-mqtt is directly related to any delays. I mean, it has to fire up node, which is heavy, especially during initial startup, so that might cause delay. Overall, tuya-mqtt doesn't do any direct network connectivity, but it uses MQTTjs for MQTT client, and tuyapi for communiation with Tuya devices. I doubt MQTTjs would be the cause as it is widely used, but tuyapi, well, it does some unique things for discovery, etc., so maybe, although still seems unlikely. Still, that is not in direct control of tuya-mqtt.

I'm glad you have something that works for you.