Bluebie / homebridge-miio

Xiaomi Mi Home Plugin for Homebridge
112 stars 26 forks source link

Use tinkerhub-mdns instead of mdns #10

Closed aguedob closed 7 years ago

aguedob commented 7 years ago

I managed to workaround mdns issue in Raspberry Pi using tinkerhub-mdns instead of mdns

Bluebie commented 7 years ago

Three reasons I won't merge this as it currently stands:

  1. tinkerhub-mdns is just a thin wrapper around bonjour. we shouldn't depend on thin abstractions unless they provide clear benefit. I don't see any benefit in this one.
  2. bonjour is a pure javascript implementation of an mDNS/DNS-SD service. Usually systems have only one DNS service running per machine. I'd need to explore the implications of running multiple services on one machine. At a minimum, it will limit the effectiveness of caching, but i'm worried it might have implications in multiple processes trying to bind to the same port.
  3. your implementation is wrong: mdns's 'host' field is the hostname of the device, for example brand-device-1234serialnum.local.. in bonjour's events, host refers to the IP address of the device. By passing the IP in to the rest of homebridge-miio, things will seem to work initially, but if your network devices allocate your plugs to different IPs in the future when their DHCP reservations expire, or when the router is restarted, or the WiFi connection interrupted, your fork will interpret the device's old IP as being offline, and the new IP as being an entirely different device, until eventually your homekit database will be full of dead ghost plugs.

The third point is easy enough to solve, and probably worth doing in the future anyway. Caching the IP of the device is likely to make commands execute on device slightly faster when they've been idle for a while and the hostname isn't cached in the system dns service anymore.

Bluebie commented 7 years ago

https://github.com/agnat/node_mdns/issues/130#issuecomment-274837566

we would rather however not use the bonjour package,
as it does seem to suffer from many issues,
and does not seem to be very active community wise.

and https://github.com/agnat/node_mdns/issues/130#issuecomment-278761279

the bonjour package doesn't work well, it misses some
devices depending on the order you switch them on
(and start advertising).

This pure-js implementation really doesn't seem like a good answer to reliability problems.

aholstenson commented 7 years ago

A better solution is to use the new discovery features in miio that uses a UDP multicast that seems to work reliably with the devices even when mDNS fails. There are a few differences from using mDNS:

  1. The model of the device is not known before connecting to the device via miio.device(options)
  2. The token is provided in the discovery process, if the token is not set you know that the device can not be connected to (unless the token is provided somehow)

As a sidenote: The only benefits tinkerhub-mdns provides over bonjour is that it correctly removes services that are no longer available.

Bluebie commented 7 years ago

Downside to using miio discover, is it continually broadcasts to every device on the network, polling for devices three times more frequently than whatever the cacheTime is set to. Sending these discover messages to devices that aren't part of the miio ecosystem, like smartphones and watches, is likely to reduce their battery life. Looking in the docs for things like Yeelight, they use multicast SSDP to discover devices, which shouldn't have this problem, but I haven't been able to figure out a way to generalise it to find all miio devices or even apply it to other kinds of devices than yeelight :(

I guess i'll probably switch to miio discover until we have something better. It would be nice to get rid of all these awful mdns issues. working on an update now.

Bluebie commented 7 years ago

version 0.2.0 of homebridge-mdns uses native miio discovery instead of mdns, so i consider this issue resolved.