homieiot / homie-esp8266

💡 ESP8266 framework for Homie, a lightweight MQTT convention for the IoT
http://homieiot.github.io/homie-esp8266
MIT License
1.36k stars 308 forks source link

User Friendly Discovery? #199

Closed Bee-Certain closed 7 years ago

Bee-Certain commented 7 years ago

Hi, I'm brand new to Homie. Looks terrific.

I've developed a Beehive Health Monitoring System based on panStamps and Raspberry Pi. My current system uses: panStamp-->LagartoSWAP-->Mosquito-->NodeRed-->InfluxDB-->Grafana. Here is a video: https://youtu.be/9XCGk_AvPNY

Now I want to add ESP8266 support. The Pi implements its own AP, so it seems reasonable for Homie to connect to the Pi and use the existing MQTT broker. Is the following a reasonable sequence of events:

  1. A new Homie device starts in configuration mode with an open AP
  2. Pi has a cron job that periodically scans for new WiFi devices with a well known prefix such as Homie-XXXXXXXX
  3. The Pi sends a JSON configuration file to the Homie device pointing the device to the Pi's SSID and passphrase
  4. The Homie device connects to the Pi's AP and the MQTT broker on the Pi.

The user (beekeeper in this case) has the option of changing the SSID and pasphrase of the Pi through the web interface. The web page invokes a cgi script. I plan on modifying the script to do the following additional steps:

  1. Get a list of known Homie devices via MQTT
  2. For each Homie device: change the SSID and passphrase to the new Pi settings, and reset (???) the Homie device
  3. Restart the Pi AP

All Homie devices will fail to connect to thePi untill the Pi AP is restarted. Any Homie device that fails to connect with the new SSID and passphrase will stay in configuration mode (???). The user has the option of restarting the Homie device, in which case, it comes up with an open AP and the cycle starts over from the very top (???)

I think it is OK to have the Homie device come up as an open AP every time it powers up. It will eventually connect to the Pi using the above sequence.

Am I even close?

Thanks for a great effort, Bob

marvinroger commented 7 years ago

Hi!

Your first sequence is perfectly reasonable and is actually the only way to automate the configuration.

Your second sequence is also fine. When you change the configuration of a device through $implementation/config/set, the device reboots, it is not resetted. So it will reboot back into normal mode, and it will try to connect indefinitely (in your case, until the Pi AP is restarted).

So the Homie device will only come up as an open AP the first time, before being configured by the cron task. Or, if you reset it, obviously.

Does it sound good?

Bee-Certain commented 7 years ago

Thanks for your quick reply.

Am I correct that if I cycle the power, then the Homie device will boot into configuration mode with an open AP (unless I set standalone mode)?

Am I correct that if I have setStandalone() in setup, and recycle the power, then I will come back up with whatever configuration the Homie device had before it went down? (i.e. the parameters and non-volatile)

Is it reasonable to read a digital input and conditionally invoke setStandalone()?

Thanks, Bob

marvinroger commented 7 years ago

If you cycle the power, the Homie device will reboot into normal mode. The configuration is stored into the SPIFFS of the ESP8266, so it does not get erased after a reboot.

A device set as standalone, during its first boot, won't spawn an AP. It just works as-is, without configuration (that's why it's named standalone). To configure it, you have to reset the device, to go from standalone mode to config mode. A device not set as standalone will directly boot into configuration mode, actually spawning an AP.

And yes, you can set a device as standalone after a digital read, as long as you call it before 'Homie.setup()`.

marvinroger commented 7 years ago

@Bee-Certain any success?

Bee-Certain commented 7 years ago

Yes! Homie is great! I haven't closed the loop yet, but the major parts are working.

I have a python script on the Pi that goes out and finds all the open ESP8266 APs and loads JSON data into those devices. The JSON data points the device back to the Pi 's AP.

Still to do: I haven't tried it yet, but I assume that with the device in configuration mode, I can use CURL to get /device_info and I will get back a JSON structure with firmware.name and firmware.version. I can then use that information to set a name, device_id, and any custom settings based on the firmware.

Still do to: If the user decides to change the SSID and/or password on the Pi (which I let then do through a web interface), then I will need to go out and change those settings in each of the ESP8266 devices. Any device that does not get changed will indicate loss of WiFi. I need to figure out a clean way for the user to recover. Perhaps letting the user put the device back in configuration mode? The process would then start all over again with the device in open AP mode. This will become more of a problem if I implement battery powered devices that go into deep sleep.

Still to do: A configuration web page that lets the user set device parameters.

Here is an graph of humidity. Humidity_000 is from a ESP8266. The others are from panStamps. image

Here is a plot an ESP8266 CO2 monitor. image

I have to say that the ESP8266, Arduino, Homie, Raspberry Pi, ... all make for an amazingly capable system.

stufisher commented 7 years ago

I had not thought about this, i think i will try and roll this solution into homie-control.

The problem is that i'd really rather not store the wifi AP password in plaintext in the db!

EDIT: Offtopic @Bee-certain i assume you need two wifi dongles? One to run the AP, and one to scan / connect and send configs.

Bee-Certain commented 7 years ago

I'm using a Raspberry Pi 3 with one built-in WiFi and one Edimax WiFi dongle. Prior to the "3", I used two Edimax dongles. The SSID and passphrase for the AP are stored in plaintext in the system's configuration file. I think that is unavoidable. More troubling than that is my passing the SSID and passphrase back and forth to the user's web browser.

If I were using the Pi's AP for only communication with the Homie devices, then I would have no need to ever expose the passphrase -- it could be generated by the Pi based on some random event.

Ultimately, I'm counting on either no Internet access, or use behind a router's firewall to provide some level of security.

cobii commented 7 years ago

Hey Bee-Certain, That sounds cool what you are doing. Couldn't it be a way give homie-ota the features you want to add to the homie system? Uploading a new firmware and configuring a device are a bit similar. Ahoy Christian

marvinroger commented 7 years ago

@Bee-Certain just wondering, you're saying

I have a python script on the Pi that goes out and finds all the open ESP8266 APs

By default, the Homie APs are secured by a password. You decided to make the AP open? If so, why?

Bee-Certain commented 7 years ago

Hmmm. Keep in mind I'm new at this, so please tell me if I've made any bad assumptions, or errors in reasoning.

The default password for Homie can be determined from the SSID if you know the not-so-secret rule of setting the password based on the AP name. So, the default password does not provide much security. As soon as the Homie device is configured, it takes itself out of AP mode and has to connect to an "upstream" AP -- is that correct? In my opinion, it is better to let the upstream computer (Raspberry Pi in my case) access any Homie device APs, configure the devices and get then to connect to the Pi's AP.

It looks like a Homie device in normal mode does not have an AP, it that correct?

In my approach, the Pi distributes its AP passphrase to each Homie device in clear text over the air. An unhappy situation that I would like to avoid. Standalone mode solves the initial setup vulnerability if we assume that the upstream passphrase is fixed for all time -- another vulnerability.

Am I missing something?

I think my conclusion is that the Homie's passphrase is unimportant since it is short lived. The bigger problem of distribution of the upstream passphrase does not have a secure solution -- short of implementing SSL.

I guess the general problem is how to secure the IOT infrastructure?

Bob

shogsbro commented 7 years ago

I understand SSL (especially OpenSSL) is too heavy for Homie.

I would like to see MQTT brokers support libSodium, given that it apparently is quite doable even on old Arduinos.

Bee-Certain commented 7 years ago

For now, I think I can just assume that there is either: 1) no connection to the Internet (off grid), or 2) the user has a firewall. Implicit in that assumption is that a "bad guy" will not be within WiFi range. That will be good enough in my case. For now, I'll support Marvin and his work and hope for a TLS solution. Bob

marvinroger commented 7 years ago

@Bee-Certain indeed, the password for the AP does not secure anything (see #230). But as I was considering removing the AP password, I wanted to know why you did that. So we removed the AP password in #232

You're not missing anything, the AP is only spawned in configuration mode. Once configured, the AP won't be spawned unless resetted to configuration mode (with the button or through MQTT).

About TLS, the ESP8266 is I think too limited to handle that cleanly. ESP32 is our best bet. 😉