IoT under iOS control. Part 2.

In Previous Part I wrote how to implement HomeKit Accessory Protocol(HAP) for your devices using third party library written in GO.

In this part I will describe how to control your IoT device from iOS.


First of all you will need a microcontroller with Wifi interface. I used ESP8266 with connected leds, temp sensor and coffee machine(switch). You can buy ready to use device or create it on your own. The device should be based on ESP8266 for the code below. So, let’s get started with some coding!

All code listed below you can find here.

Getting Started:

  1. Download Arduino IDE. from arduino.cc
  2. Go to ESP8266 repository and complete all steps from Installing with Boards Manager
  3. Go to Tools -> Board and select “Generic ESP8266 Module”
  4. Go to Sketch -> Include Library -> Library Manager and download all of the following libraries:
aREST //library that implements a REST API for Arduino
aREST_UI //
is an embedded UI for the aREST framework
OneWire //
lets you access 1-wire devices for example temp sensor
DallasTemperature //library for working with Dallas temp sensor
Tip: If you want to use your custom text editor, instead of Arduino IDE editor, you can go to Preferences and enable Use external editor

Create new file and include libraries:

#include <aREST.h>
#include <aREST_UI.h>
#include <OneWire.h>
#include <DallasTemperature.h>

Define pins to which lightbulb, temp sensor and coffee machine are connected:

#define LED_CONTROL_PIN 5
#define ONE_WIRE_BUS 12
#define COFFEE_CONTROL_PIN 13

Setup our temp sensor and create aRestUI instance:

// Setup a oneWire instance to communicate with any OneWire devices 
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// Create aREST instance, so we could control our IoT device using browser 
aREST_UI rest = aREST_UI();

Create an instance of the server:

// WiFi parameters
const char* ssid = "YOUR_WIFI_NETWORK_NAME";
const char* password = "YOUR_WIFI_PASSWORD";
// The port to listen for incoming TCP connections
#define LISTEN_PORT 80
// Create an instance of the server
WiFiServer server(LISTEN_PORT);

Declare variables and functions exposed to the Rest API, since we do not set temperature, only get, we can create a variable which will keep the result of current temp. For led and coffee we create functions which will change its status depending on request:

// Variables to be exposed to the API
float temperature;
int ledControl(String command);
int coffeeControl(String command);

Base setup:

void setup(void) {
sensors.begin();
  // Start Serial. Since we begin serial with upload speed of 115200, we also should set the upload speed in Tools -> Upload Speed to 115200
Serial.begin(115200);
  // Set the title
rest.title("aREST UI Demo");
  // Create button to control pin 5 and 13
rest.button(LED_CONTROL_PIN);
rest.button(COFFEE_CONTROL_PIN);
  // Init variables and expose them to REST API
rest.variable("temperature", &temperature);
  // Labels
rest.label("temperature");
  // Functions to be exposed
rest.function("led", ledControl);
rest.function("coffee", coffeeControl);
  // Give name and ID to device
rest.set_id("1");
rest.set_name("esp8266");
  // Connect to WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
  Serial.println("");
Serial.println("WiFi connected");
  // Start the server
server.begin();
Serial.println("Server started");
  // Print the IP address. We will need it to connect to this device from our implementation of HAP.
Serial.println(WiFi.localIP());
}

Implemet loop() to do something in infinite cycle. In this method check if our server is available and handle REST calls to it. Update temperature variable from temperature sensor:

void loop() {
// Handle REST calls
WiFiClient client = server.available();
if (!client) {
return;
}
while (!client.available()) {
delay(1);
}
rest.handle(client);
  sensors.requestTemperatures(); // Send the command to get temperatures
temperature = sensors.getTempCByIndex(0);
}

Implement our functions to control our coffee and led. Since our requests will be in this format:

YOUR_DEVICE_IP/digital/5/1
// 1 to turn it on, 0 to turn it off
// or if we want to pass a brightness to led we could pass from 0 to 255 as analog, to do soo make sure that the pin you connect lighbulb to is analog.
YOUR_DEVICE_IP/analog/5/125

Implementation will look like this:

int ledControl(String command) {
// Print command
Serial.println(command);
  // Get state from command
int state = command.toInt();
digitalWrite(LED_CONTROL_PIN, state);
return 1;
}

For coffee machine(switch) the only difference will be:

digitalWrite(COFFEE_CONTROL_PIN, state);

This is all you need to create Rest API for you IoT device. Let’s try to run it and check if it works.

Now let’s compile and upload our code to ESP8266, to do so we should:

  1. Connect via USB ESP8266 to our computer
  2. Go to Tools and set ESP8266 params (see the image below)
  3. Set our ESP8266 to upload mode
  4. Click upload in your IDE

When your upload was successful, open Tools -> Serial Monitor and set the port speed to 115200 in the bottom panel on the right. After this we can restart our Esp8266 and check in serial monitor if device is connected to WiFi:

You should see something like this, but ip address probably will be different

Connect our computer and device to the same WiFi network and enter IP from the image above in the browser. You should see this page:

Now, we can play with on/off state and see that our lighbulb or coffee machine(switch) changes.

It is time to check if we can control IoT device from Home App. Navigate to your implementation of HAP which we wrote in Previous Part, open it and change the rootURL to IP address from your serial monitor. Save it and run:

go run lightbulb.go // or any other implementation HAP for device

Open Home App on your iOS device and try to turn on or off your lighbulb by tapping on it. You should see that your actual lightbulb turns on and off. Same with temp sensor, you can add it as accessory and check that temperature changes in real time.

Congrats you are pretty much done with your first IoT under iOS control!

This is the second part of iOT under iOS control. Next, in the Part 3, I will tell you about “How to build your own iOS app with HomeKit”.

Got any questions?

Please feel free to contact me by: vlad.somov@icloud.com