beveradb / sonoff-lan-mode-homeassistant

Home Assistant platform to control Sonoff switches running the latest Itead firmware, locally (LAN mode).
MIT License
74 stars 36 forks source link

Some devices don't drop into LAN mode automatically after boot with no internet #8

Open beveradb opened 5 years ago

beveradb commented 5 years ago

Report from user with S20, firmware 2.6.1:

"When I plug it in and internet access is blocked, mine keeps blinking once every couple of seconds, trying to connect to the internet. This goes on forever. A few seconds after unblocking its internet traffic, it stops blinking and fixes the green LED. Some minutes after I block the internet connectivity again, it drops to lan mode. So this one requires internet access to set itself up before being able to drop to lan mode. :/"

Originally posted by @tiagoboldt in https://github.com/beveradb/sonoff-lan-mode-homeassistant/pull/4#issuecomment-452022379

beveradb commented 5 years ago

So, I opened this in the hope of working with @tiagoboldt to do a bit of trial and error with his device (as I don't own an S20 yet).

I believe there's a chance we may be able to write code to programmatically force the device into LAN mode by telling it to use an invalid server URL.

Here are instructions copied from several repos: sonoff-server, simple-sonoff-server, SonOTA and this blog post, to configure your device to connect to a different URL for the "cloud" server:

  1. Put the SonOff/Wemos device in AP mode (press and hold button for 5s) 1a. On various devices it appears that a 2nd 7 second button press is required sometimes to put the Sonoff into Configuration mode so it will broadcast the ITEAD-###### SSID. If after pressing the button for 7 seconds you have a pattern such as blink-blink-blink-pause-blink-blink-blink-pause, press the button again for another 7 seconds until you have a steady blink-blink-blink...
  2. Find the device and connect to it (SSID: ITEAD-10000xxxxx Password: 12345678)
  3. Add route if necessary sudo route change 0.0.0.0 mask 0.0.0.0 10.10.7.1
  4. (optional) use httpie to read device info http http://10.10.7.1/device.
  5. use httpie to send local WiFi settings to device http POST http://10.10.7.1/ap version:=4 ssid=[YOUR NETWORK SSID] password=[YOUR NETWORK PASSWORD] serverName=[IP OF YOUR SERVER] port=8080

The device will automatically drop out of AP mode and attempt to connect to the WiFi and server IP provided.

Now, I'm not sure what happens if you follow these instructions successfully but configure the device with a nonsense / unreachable server IP. It's possible the firmware just gives up and falls back to a hard-coded cloud hostname (e.g. coolkit.cc) if it can't connect to the specified address.

However, there's also a chance that it might fall back to LAN mode! So, here's hoping 😄

peterbuga commented 5 years ago

great work @beveradb please keep it going as i would love to borrow some of the code 😊 i had this crazy (and most likely stupid) idea regarding this issue: what if a golden-flow could be created when component is loaded and cut the internet connection of a the sonoff device after it connects to the internet forcing it to drop to LAN mode only using something like this https://github.com/roglew/wifikill

now i know this add a lot of complexity (and packages) to this whole (again crazy/stupid) idea but i'm thinking that in the future, by merging both of our work, i could do something like this: pull sonoff device list from cloud, check their connectivity (this assumes that HA has a connection to the internet), try to find their current local IP addresses using the device MAC address, cut their internet connection via software (and try to keep it like this) in order to drop to LAN mode, control & query their state exclusively via local network using your implementation.

i'll try a POC these days to see if it's even remotely doable 😅

tiagoboldt commented 5 years ago

Hey guys, I won't be able to help. I've opened my S20 and flashed it "manually". Keep it up :)

beveradb commented 5 years ago

Cheers @peterbuga - you're of course welcome to use anything of value. Your websocket client implementation was very helpful to me as a starting point for the test scripts I implemented yesterday. One of them is a very basic mock Sonoff device, allowing me to test my own LAN mode client until I have access to an original firmware Sonoff again 😄

That's a really interesting idea for sure - performing an ARP poisoning attack against the device to break its connectivity could actually work pretty well, and would certainly be more flexible as it would in theory be able to enable/disable at will programmatically, enabling the "best of both worlds" cloud + local implementation you're keen on.

Unfortunately, we wouldn't be able to do that from HomeAssistant though, as you'd need root access to send the required ARP packets. I guess it could work as a Hass.io addon with security disabled, but that could be confusing for users to install both a custom component and an addon, and would only work for folks running Hass.io.

I'm still keen to try the instructions above with a real device to see if it's at least possible to get a device to stay in LAN mode permanently, for users of this repo. If not, I'll probably go ahead and implement an ARP poisoning Hass.io add-on!