merdok / homebridge-miot

Homebridge plugin for devices supporting the Xiaomi miot protocol
MIT License
395 stars 63 forks source link

Handshake timeout with Smartmi Standing Fan 3 on different VLAN #271

Closed ste-fle closed 2 years ago

ste-fle commented 2 years ago

Describe the bug I recently purchased the Smartmi Standing Fan 3 and connected it to my IOT Wifi / VLAN and enabled internet access. It works from the Xiaomi Home app without problems. I then added it to Homebridge using the build-in token extractor. It found the token and also got the right IP-adress, but the fan won't connect and always fail with an handshake timeout error.

Expected behavior Homebridge should be able to connect to the fan despite being on a different VLAN.

Your config.json {             "micloud": {                 "username": "xxx",                 "password": "xxx",                 "country": "de",                 "forceMiCloud": true,                 "timeout": 5000             },             "devices": [                 {                     "name": "Fan",                     "ip": "192.168.2.180",                     "token": "xxx",                     "deviceId": "xxx",                     "model": "zhimi.fan.za5",                     "pollingInterval": 10,                     "deepDebugLog": true,                     "micloud": {                         "username": "xxx",                         "password": "",                         "country": "de",                         "forceMiCloud": true                     },                     "buzzerControl": false,                     "ledControl": false,                     "childLockControl": false,                     "modeControl": true,                     "swingControl": false,                     "ioniserControl": false                 },                 {                     "name": "Roborock S5",                     "ip": "192.168.2.191",                     "token": "xxx",                     "deviceId": "xxx",                     "model": "roborock.vacuum.s5",                     "pollingInterval": 10,                     "deepDebugLog": false,                     "buzzerControl": true,                     "ledControl": true,                     "childLockControl": true,                     "modeControl": true                 }             ],             "platform": "miot"         }

Debug log [5/15/2022, 3:29:44 PM] [miot] [Fan] (Protocol) Start handshake 192.168.2.180 [5/15/2022, 3:29:48 PM] [miot] [Fan] Error: Could not connect to device, handshake timeout [5/15/2022, 3:29:48 PM] [miot] [Fan] Could not connect to the device! Retrying in 40 seconds!

Additional context When adding the fan to my normal Wifi/VLAN, it does connect and is controllable via Homekit!

I created firewall rules to allow all connections TO the IOT VLAN and allow established connections FROM it. For testing purposes I even created one for the fan to connect to any other VLAN, which didn't help. The fan is pingable from the Homebridge:

root@raspberrypi:/homebridge# ping 192.168.2.180 PING 192.168.2.180 (192.168.2.180) 56(84) bytes of data. 64 bytes from 192.168.2.180: icmp_seq=1 ttl=254 time=188 ms 64 bytes from 192.168.2.180: icmp_seq=2 ttl=254 time=106 ms 64 bytes from 192.168.2.180: icmp_seq=3 ttl=254 time=26.9 ms 64 bytes from 192.168.2.180: icmp_seq=4 ttl=254 time=158 ms 64 bytes from 192.168.2.180: icmp_seq=5 ttl=254 time=380 ms 64 bytes from 192.168.2.180: icmp_seq=6 ttl=254 time=301 ms ^C --- 192.168.2.180 ping statistics --- 6 packets transmitted, 6 received, 0% packet loss, time 5004ms rtt min/avg/max/mdev = 26.901/193.573/380.271/117.630 ms

I already tried forcing the MiCloud but this didn't seem to have any effect. The Roborock is also on this IOT network and it does work without problems.

Do you have an idea what might be the problem and how to solve it? I don't really want to give the fan access to my main VLAN.

merdok commented 2 years ago

I read somewhere that miot devices might have issues when connected to subnets. The roborock does not have such issue because it is a device which uses the older miio protocol. Not exactly sure what is the proper solution for that. I never had the issue myself hence I never invested time in that.

ste-fle commented 2 years ago

I see, thank you for your response. But I don’t understand, why the „Force Cloud“ option is not working - since I can control the fan via Xiaomi Home app on a different VLAN (according to the app via remote connection). Shouldn’t the plugin option result I in the same behavior?

merdok commented 2 years ago

The plugin still tries to connect initially to the device locally before going to the cloud in order to make sure the device is actually there and responds and also to get some required information. All the subsequent requests are then afterwards done over the cloud. The force option forces devices which does not require MiCloud, like miot devices, to still do sync calls over cloud.

ste-fle commented 2 years ago

Thanks for the explanation - so might there be a problem with the force option since homebridge can't connect but the Xiaomi App can remotely? Or do you think there is nothing you could do to get the handshake to work with this setup?

merdok commented 2 years ago

With the handshake there is unfortunately nothing I can do as this is a local network issue.

At some point I might add an option to go completely over micloud without checking if the device is locally available. The issue with that will be that more information needs to be provided in the config which otherwise can be fetched automatically, and also in case of when the device is offline endless login attempts will be made to the cloud just to check if by any chance the device went online... This is something I need to carefully think through before attempting it.

ste-fle commented 2 years ago

That would be great! I think there might also be quite a few people who want to separate their IOT devices from the rest of the network and would appreciate this feature.

merdok commented 2 years ago

Yeah, I will investigate that. But I unfortunately cannot promise to do it anytime soon as I still have other stuff to do...

ste-fle commented 2 years ago

Just for information if somebody has the same problem... I did a little more research (Documentation, Github Discussion) and got it working (UnifiOS Router) with the following change via SSH:

iptables -t nat -A POSTROUTING -s Homebridge_IP/32 -d IOT_Subet/24 -p UDP -j MASQUERADE --to-ports 54321

merdok commented 2 years ago

Nice! Thanks for the info!

drinksomewhiskey commented 1 year ago

Just for information if somebody has the same problem... I did a little more research (Documentation, Github Discussion) and got it working (UnifiOS Router) with the following change via SSH:

iptables -t nat -A POSTROUTING -s Homebridge_IP/32 -d IOT_Subet/24 -p UDP -j MASQUERADE --to-ports 54321

This worked with my UDM Pro indeed! Thank you. Out of curiosity, can you explain what the command exactly does?

ste-fle commented 1 year ago

Just for information if somebody has the same problem... I did a little more research (Documentation, Github Discussion) and got it working (UnifiOS Router) with the following change via SSH:

iptables -t nat -A POSTROUTING -s Homebridge_IP/32 -d IOT_Subet/24 -p UDP -j MASQUERADE --to-ports 54321

This worked with my UDM Pro indeed! Thank you. Out of curiosity, can you explain what the command exactly does?

I only got this command from the GitHub discussion linked in my comment but basically what it does is masquerading the source IP from the original separated VLAN to one from the IOT VLAN so that the fan accepts it.