27. November 2016

After successful implementation of MQTT into Lamp Relay with ESP8266 there was one remaining challenge. Communication of Android Lamp App with ESP8266 via MQTT. It was little bit harder than I expected, because examples were not very clear.

Sending commands to MQTT broker was relatively easy. There was just a catch. It is necessary to declare the MQTT service in AndroidManifest.xml:

Well, there is support in the same MQTT library for topic subscriptions. The issue is that incoming message is being processed on background thread and it’s not possible to update UI. It took me some time to realize the source of problem. I was hunting ghosts. I thought that there is some problem in ImageButton or TobbleButton.

Correct solution was to move communication to Android service class. Then bind the service so UI can send commands to the service and the last part was to add broadcast receiver to pass message from service to UI.

Here is small schema which describes delivery of message from broker to app.

It was necessary to make also small update in ESP8266 in order to tell Mosquitto to persist the state of a lamp (the last bool parameter):

mqttClient.publish(topicName("relay"), "off", true);

The result is nice. I can turn on the lamp via web interface and all connected Android apps are updated and user can see the state of the lamp.

The code for Android app is available at Github – LampApp. Previous code with REST API was moved to branch v0.1. The code for ESP8266 module is also at Github – LampESP. Feel free to customize the app. You can find instructions in README.md.

I see the next challenge for LampApp: display lamp control widget at lock screen. Maybe I’ll be more successful than the last time.

I had an idea about next cool feature: turn on/off lamp based on sunset and sunrise. I found very simple and elegant solution that I would like to share with you.

Download Sunwait and compile it. The program just starts and waits until the time of sunrise or sunset based on geographic coordinates. You can also specify offset (how long before or after event) should program end.

Now you can put the sunwait into your local cron table and chain it with command that should be executed after sunrise/sunset occurs.

Here is example how to configure cron to turn on the lamp 15 minutes before sunset and turn it off 15 minutes after sunrise.

The lamp is now working. The only problem is the Android app. I thought that adding MQTT client to Android app will be as easy as adding it to ESP8266, but it’s far from truth. There are still some challenges 😉

Go was trying to get repository from Eclipse using unsecure HTTP. Luckily there was feature request to add switch for accessing insecure repositories by Go get – issue #9637. The solution was just to add “-insecure” parameter:

That was the easy part. I was able to control relay directly from mobile phone via web browser which was not very convenient. The widget would serve better.

Writing a widget for Android was real challenge. There is very little documentation about it and even Android Studio does not contain template for writing widget. I spent several hours learning how widget works. It is very different from common application.