OpenHAB, MQTT, Arduino and ESP8266: Part 3: Hardware: Arduino with Ethernet Shield

The following series of posts will document my journey to full Home Automation using the MQTT protocol, all custom hardware (Arduino and ESP8266 based), and all tied together using OpenHAB

  • Part 1:  Setting up the server / environment
  • Part 2:  Publish, Subscribe, Command, State, and WTFs
  • Part 3:  Hardware:  Arduino with Ethernet Shield
  • Part 4:  Hardware:  ESP8266 with NodeMCU firmware
  • Part 5:  Hardware:  Sensors
    • Part 5.1:  Graphing Sensor Data
  • Part 6:  OpenHAB Automation Rules

Lets dive right in:
Take a Arduino Uno, and install a standard Ethernet shield on top.   Wire pin D4 and D5 to a two channel relay breakout or just LEDs (for now – just testing phase)

Wire a I2C LCD to SDA/SCL and VCC/GND  – I used this as a supplementary check of what my code is doing but this may also make it into any final hardware version

#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>


// Update these with values suitable for your network.
byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
byte server[] = { 192, 168, 0, 100 }; // IP Address of your MQTT Server
byte ip[]     = { 192, 168, 0, 120 }; // IP for this device


EthernetClient ethClient;
PubSubClient client(server, 1883, callback, ethClient);


LiquidCrystal_I2C    lcd(0x27,2,1,0,4,5,6,7); // 0x27 is the I2C bus address for an unmodified backpack


byte bulb[8] = {
    0b01110,
    0b10001,
    0b10001,
    0b10001,
    0b01110,
    0b01010,
    0b01110,
    0b00100
};

byte plug[8] = {
    0b01010,
    0b01010,
    0b11111,
    0b10001,
    0b10001,
    0b01110,
    0b00100,
    0b00100
};

void callback(char* topic, byte* payload, unsigned int length) {
Serial.println("Callback");
Serial.print("Topic:");
Serial.println(topic);
Serial.print("Length:");
Serial.println(length);
Serial.print("Payload:");
Serial.write(payload,length);
Serial.println();

  if (strcmp(topic,"/home/1/ard1/p1/com")==0) { 
   if (payload[0] == '0') 
    {
    digitalWrite(4, LOW);
    lcd.home();
    lcd.clear();
    lcd.write((uint8_t)1);
    lcd.print ("Turning Fan OFF");
    delay(100);
    client.publish("/home/1/ard1/p1/state","0");
    } 
    else if (payload[0] == '1') 
    {
    digitalWrite(4, HIGH);
    lcd.home();
    lcd.clear();
    lcd.write((uint8_t)1);
    lcd.print ("Turning Fan ON");
    delay(100);
    client.publish("/home/1/ard1/p1/state","1");
    }
   } 

  if (strcmp(topic,"/home/1/ard1/p2/com")==0) { 
   if (payload[0] == '0') 
    {
    digitalWrite(5, LOW);
    lcd.home();
    lcd.clear();
    lcd.write((uint8_t)1);
    lcd.print ("Turning Light OFF");
    delay(100);
    client.publish("/home/1/ard1/p2/state","0");
    } 
    else if (payload[0] == '1') 
    {
    digitalWrite(5, HIGH);
    lcd.home();
    lcd.clear();
    lcd.write((uint8_t)1);
    lcd.print ("Turning Light ON");
    delay(100);
    client.publish("/home/1/ard1/p2/state","1");
    }
   } 


}

void setup()
{
  Serial.begin(9600);
  lcd.begin (20,4); // for 16 x 2 LCD module
  lcd.createChar(0, bulb);
  lcd.createChar(1, plug);
  lcd.home(); // set cursor to 0,0
  lcd.print(" Starting  "); 
  delay(1000);
  Ethernet.begin(mac, ip);
    lcd.home();
    lcd.clear();
    lcd.print("Ethernet Connected"); 
    
  
  if (client.connect("arduinoClient")) {
    lcd.home();
    lcd.clear();
    lcd.print("MTQQ Connected");
    client.publish("outTopic","hello world");
    client.subscribe("/home/1/ard1/#");  // Subscribe to all messages for this device
  }
  pinMode(4, OUTPUT);
  digitalWrite(4, LOW);
  pinMode(5, OUTPUT);
  digitalWrite(5, LOW);

}

void loop()
{
  client.loop();


}

Now comes the interesting time: Time to start customizing OpenHAB to handle this newly built hardware (:

1.   Create a new Sitemap – sitemaps in OpenHAB define which items to display

sudo vi /etc/openhab/configurations/sitemaps/dolphin.sitemap

Inside this file, paste the following content

sitemap dolphin label="Main Menu"
{
   Frame label="MQTT" {
   Switch item=mqttsw1 label="MQTT Switch 1"
   Switch item=mqttsw2 label="MQTT Switch 2"
   Switch item=lamp1 label="Office Lamp"
  }  
}

Lets configure these three new items

sudo vi /etc/openhab/configurations/items/dolphin.items

Add the following to the new file

Group All
Switch mqttsw1 "Switch 1" (all) {mqtt=">[broker:/home/1/ard1/p1/com:command:on:1],>[broker:/home/1/ard1/p1/com:command:off:0]"}
Switch mqttsw2 "Switch 2" (all) {mqtt=">[broker:/home/1/ard1/p2/com:command:off:0],>[broker:/home/1/ard1/p2/com:command:on:1]"}Restart OpenHAB
sudo /etc/init.d/openhab restart

Once it has started, access your new sitemap:

http://127.0.0.1:8080/openhab.app?sitemap=dolphin

mqtt

Lets recap the configuration:

  1. We have a device(s) on /home/1/ard1/p1/com and /home/1/ard1/p2/com
  2. These devices subscribe to our MQTT broker on 192.168.0.100:1883 (See the arduino Sketch)
  3. Our MQTT Broker, Mosquitto, runs on 192.168.0.100:1883
  4. OpenHAB has a Broker configuration in /etc/openhab/configurations/openhab.cfg (Where OpenHAB can Publish commands, for example turn ON or OFF /home/1/ard1/p1)
  5. We configured a sitemap with two items (sorry screenshot above shows 3 devices – ahead of myself there) under /etc/openhab/configurations/sitemaps/dolphin.sitemap (we’ll add groups and other cool bits later – for now the basics)
  6. The items in our sitemap, has relevant configurations under /etc/openhab/configurations/items/dolphin.items
  7. These items have a MQTT Binding to send 1 = ON and 2 = OFF
    {mqtt=">[broker:/home/1/ard1/p1/com:command:on:1],>[broker:/home/1/ard1/p1/com:command:off:0]"}
Advertisements

#include