Project tutorial
Home Automation System for a Camp with Cellular Internet

Home Automation System for a Camp with Cellular Internet © GPL3+

Wouldn't it be nice if you could start warming up the camp before you leave the house? How about using Alexa to do it for you!

  • 12,949 views
  • 4 comments
  • 45 respects

Components and supplies

Amazon echo dot
Amazon Alexa Echo Dot
×1
Abx00004 iso both
Arduino MKR1000
×1
Mcp23008 scr8g5le 10a b%20(1)
ControlEverything.com Relay Shield for Particle Photon I²C 8-Channel SPDT 10-Amp
This one says its an i2c relay shield, the one I used was just an opto coupler relay shield with 8 input pins.
×1
Nova icon lijwm6pmk7
Hologram Nova
×1
R8326274 01
Raspberry Pi 2 Model B
×1
USB WiFi Dongle
×1

About this project

My idea is a home automation system for a camp with no internet.

Wouldn't it be nice if you could start warming up the camp before you leave the house? How about turn on some lights because your getting there late? Maybe you would like to know what the temperature is in an outside the camp. Well with Alexa and my cellular home automation project you could. From your home, just say "Alexa, start warming up the camp at 5:00pm," Alexa will send a trigger to my system to turn on the heat on at the time requested.

My system will use arduinos to control devices and read sensors. The arduinos will send or receive the information to a Raspberry Pi using mqtt where the Pi can connect to the internet using a Hologram Nova cellular modem.

There is a couple assumptions,

1. You have power at your camp, the gateway can run off of batteries and solar, but it wasn't tested to see how long

2. Even though you dont have internet, you still need to be in an area where cell phones work.

Sensor:

For the hardware, we will use an Arduino MKR1000 and an 8-channel relay board. See the schematic for wiring info. The MKR1000 still has a few extra IO pins, so if you wish to add a few more sensors there is space.

The sensor emulates a WeMos. I was able to find some code online that does this for an ESP8266. I used that code to port it to the MKR1000 for sending and receiving the messages.

How does the code work:

  • First it makes a wifi connection to the access point (details about this later)
  • then it starts up a server to which it will accept UDP and TCP connections.
  • IF a M-SEARCH UDP broadcast request is received, it evaluates it and returns the url to the device setup.xml.
  • The broadcaster will then request the setup.xml this file contains all the services available for the device. I will also contain the uri's to the service and what eventservice definition file is.
<serviceList>
   <service>"
      <serviceType>urn:Belkin:service:basicevent:1</serviceType>
      <serviceId>urn:Belkin:serviceId:basicevent1</serviceId>
      <controlURL>/upnp/control/basicevent1</controlURL>
      <eventSubURL>/upnp/event/basicevent1</eventSubURL>
      <SCPDURL>/eventservice.xml</SCPDURL>
   </service>
...
  • It will then wait for request to come in on the service urls and process those events as defined.

Testing the sensor

  • Open the adruino UI and load the arduino code attached.
  • Build and flash it to your MKR1000 ( other boards can be used if they have wifi)
  • Open the serial monitor, you should see some messages showing the sensor is waiting for request.
  • Open a browser, and goto http://arduino_ip/index.html. you should see a hello message. At this point your sensor should be working.
  • One more test would be to goto http://arduino_ip/setup.xml to see the xml file that gets returned on a UDP broadcast M-SEARCH

Cellular Gateway

The Cellular Gateway will use a raspberry pi 2 as its controller. Connected to that will be a hologram nova USB cellular modem and a WIFI adapter. And of course a power adapter. The USB modem will be used for access to internet and the WIFI adapter will be used to create an access point for the sensor created above to connect to.

There is a number of software packages required normally I would list off all of them, but there are existing scripts to run to add the majority of what is needed and I will give instruction to add what is missing.

Raspberry Pi setup

  • The first thing to do is assemble the hardware. basically plug everthing together. At this point DONT plugin the cellular modem. That will be done later once we're ready to create the access point. We want to make sure everything is working before we create and startup the Cellular access point. This will save on data costs. Plus its easier to debug everything if your doing it locally.
  • I'm going to assume that you know how to configure a raspberry pi. So install rasbien lite and do the standard configuration. there are many tutorial on how to do this. Just find one you like
  • Once its installed, make sure its fully up to date
$sudo apt-get update
$sudo apt-get upgrade

Nodejs, Node-Red and etc.

This software will process the messages coming in from Alexa and transform it to what the sensor can understand.

  • Now the software. The first one were going to install is called a-christmass-script. Follow the instruction on the link. Once you have it downloaded execute the script and answer a few questions, it will take a few hours to install everything. But its worth it.
  • Once its installed you should be able to get to the main page by going to http://your_pi's_ip From there you can get into node red. We will use node-red to create our nodejs flows.

Alexa Node-Red sdk

This software will add Alexa nodes to node-red.

  • Open a browser and goto http://your_pi_ip:1880 this will bring up node-red login with the admin account that was created.
  • Click on the menu icon
  • Click on manage pallet
  • Click the Install node
  • Enter alexa-node-red-contrib-sdk and press search
  • Install the node-red that comes up.
  • Once it installs, you should see these two nodes in your pallet now.

Alexa Node-Red Bridge

This software will allow you to use your Alexa though the internet to remote devices

  • Goto https://alexa-node-red.bm.hardill.me.uk/
  • Click on the Documentation link at the top. This is the instruction to setup the Alexa Node-Red bridge.
  • Follow the instruction here, The main things to do at this point is Create the account, add devices and link the account to your Alexa account.
  • To link your account download the alexa app from google playstore for android.
  • Open the app and goto add skill and look for nodejs
  • The install nodes was done above
  • You can configure the nodes after you import the node-red flow.

Node-red Flow

This will process messages coming in from Alexa via the Alexa-Node-Red Bridge and send them to the sensor

  • Login into node-red
  • Click on the menu icon
  • Click on import
  • Select the flow to import (save it from the attached files)
  • Now update the necessary nodes with your details.
  • Alexa input nodes - add the alexa node-red credentials you created for the Alexa Node-Red Bridge
  • html nodes - update the ip in the url to your devices ip.

Testing

Its time to start testing. At this point were still havn't created the access point, but for ease of debugging, we will use you router at home to give out IP's. Your raspberry pi and sensor should be connecting to the same router so they can talk

  • Open a browser and goto node-red.
  • If the configuration is correct, your alexa nodes should so connected.
  • You should be able to test from node-red by clicking on one of the Relay On buttons, the corresponding relay should activate.
  • Click the Relay Off button, again the corresponding relay should switch off
  • This tells you node-red to the sensor is working correctly.
  • Now try it with your Alexa, if you dont have an Alexa echo use echoism.io to emulate one.
  • Say "Alexa, turn on kitchen light" you should see that relay switch on.
  • Say "Alexa, turn off kitchen light" you should see that relay switch off.
  • Congradulations, you now have a working system from Alexa to sensor.

Access Point

The last piece of work is to turn your raspberry pi into an access point. We do this so all your sensors will connect directly to it instead of having to have another piece of equipment. Also at this point we will be configuring the Nova USB cellular modem so we can communicate to our pi over the internet because remember, your camp doesn't have internet access at this point.

The easiest way to do this is to use the project BenStr from Hologram has create here on hackster with the complete instruction. He does a much better job at explaining it than I would.

Conclusion

Well I hope you enjoyed this project. There are a lot of moving part, but all seem to come together pretty smoothly. Adding new sensor or switch should be pretty simple, just connect them up and alter the flow in node-red as necessary.

Thanks

Dana.

Code

sensor_relay.inoArduino
This is the arduino code for the sensor.
#include <SPI.h>
#include <WiFi101.h>
#include <WiFiMDNSResponder.h>

#define UDP_TX_PACKET_MAX_SIZE 8192

IPAddress ipMulti(239, 255, 255, 250);
const unsigned int portMulti = 1900;
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
boolean udpConnected = false;

WiFiUDP Udp;

String persistent_uuid = "1234567890";
String friendlyName = "camp";
boolean relayState = false;
int relayPin = 1;

const int ledPin = 6; // LED pin for connectivity status indicator

char mdnsName[] = "wifi101"; 

WiFiServer server(80);

// Create a MDNS responder to listen and respond to MDNS name requests.
WiFiMDNSResponder mdnsResponder;

void setup() {
  //Initialize serial:
  Serial.begin(9600);

  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, HIGH);
  pinMode(2, OUTPUT);
  digitalWrite(2, HIGH);
  pinMode(3, OUTPUT);
  digitalWrite(3, HIGH);
  pinMode(4, OUTPUT);
  digitalWrite(4, HIGH);
  pinMode(5, OUTPUT);
  digitalWrite(5, HIGH);
  pinMode(6, OUTPUT);
  digitalWrite(6, HIGH);
  pinMode(7, OUTPUT);
  digitalWrite(7, HIGH);
  pinMode(8, OUTPUT);
  digitalWrite(8, HIGH);

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue:
    while (true);
  }

  // configure the LED pin for output mode
  pinMode(ledPin, OUTPUT);

  // Start in provisioning mode:
  //  1) This will try to connect to a previously associated access point.
  //  2) If this fails, an access point named "wifi101-XXXX" will be created, where XXXX
  //     is the last 4 digits of the boards MAC address. Once you are connected to the access point,
  //     you can configure an SSID and password by visiting http://wifi101/
 // WiFi.beginProvision();
  WiFi.beginProvision(6);

  while (WiFi.status() != WL_CONNECTED) {
    // wait while not connected

    // blink the led to show an unconnected status
    digitalWrite(ledPin, HIGH);
    delay(500);
    digitalWrite(ledPin, LOW);
    delay(500);
  }

  // connected, make the LED stay on
  digitalWrite(ledPin, HIGH);

  server.begin();

  // Setup the MDNS responder to listen to the configured name.
  // NOTE: You _must_ call this _after_ connecting to the WiFi network and
  // being assigned an IP address.
  if (!mdnsResponder.begin(mdnsName)) {
    Serial.println("Failed to start MDNS responder!");
    while (1);
  }

  Serial.print("Server listening at http://");
  Serial.print(mdnsName);
  Serial.println(".local/");

  // you're connected now, so print out the status:
  printWiFiStatus();

  // only proceed if wifi connection successful
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("Start UDP server to discover devices");
    udpConnected = connectUDP();

    if (udpConnected) {
      // initialise pins if needed
      startHttpServer();
    }
  }
}

void loop() {
  // Call the update() function on the MDNS responder every loop iteration to
  // make sure it can detect and respond to name requests.
  mdnsResponder.poll();

  startHttpServer();

  if (WiFi.status() == WL_CONNECTED) {
    if (udpConnected) {
      // if there’s data available, read a packet
      int packetSize = Udp.parsePacket();

      if (packetSize) {
        IPAddress remote = Udp.remoteIP();

        for (int i = 0; i < 4; i++) {
          Serial.print(remote[i], DEC);
          if (i < 3) {
            Serial.print(".");
          }
        }

        Serial.print(", port ");
        Serial.println(Udp.remotePort());

        int len = Udp.read(packetBuffer, 255);

        if (len > 0) {
          packetBuffer[len] = 0;
        }

        String request = packetBuffer;
        Serial.println("Request:");
        Serial.println(request);

        if (request.indexOf("M-SEARCH") >= 0) {          
          if ((request.indexOf("urn:Belkin:device") > 0) || (request.indexOf("ssdp:all") > 0) || (request.indexOf("upnp:rootdevice") > 0)) {
            Serial.println("Responding to search request ...");
            respondToSearch();
          }
        }
      }
      delay(10);
    }
  } else {
    Serial.println("Cannot connect to Wifi");
  }
}


void printWiFiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

boolean connectUDP() {
  boolean state = false;

  Serial.println("");
  Serial.println("Connecting to UDP");

  //if(Udp.beginMulticast(WiFi.localIP(), ipMulti, portMulti)) {
  if (Udp.beginMulticast(ipMulti, portMulti)) {
    Serial.println("Connection successful");
    state = true;
  }
  else {
    Serial.println("Connection failed");
  }

  return state;
}

bool beginUdpMulticast() {
  // put your main code here, to run repeatedly:

  boolean state = false;

  Serial.println("Begin multicast ..");

  if (Udp.beginMulticast(ipMulti, portMulti)) {
    Serial.print("Udp multicast server started at ");
    Serial.print(ipMulti);
    Serial.print(":");
    Serial.println(portMulti);

    state = true;
  }
  else {
    Serial.println("Connection failed");
  }

  return state;

}

void serverUdpLoop() {
  int packetSize = Udp.parsePacket();
  if (packetSize <= 0)
    return;

  IPAddress senderIP = Udp.remoteIP();
  unsigned int senderPort = Udp.remotePort();

  // read the packet into the buffer
  Udp.read(packetBuffer, packetSize);

  // check if this is a M-SEARCH for WeMo device
  String request = String((char *)packetBuffer);

  if (request.indexOf('M-SEARCH') >= 0) {
    if ((request.indexOf("urn:Belkin:device:**") > 0) || (request.indexOf("ssdp:all") > 0) || (request.indexOf("upnp:rootdevice") > 0)) {
      Serial.println("Got UDP Belkin Request..");
    }
  }
}
void respondToSearch() {
  Serial.println("");
  Serial.print("Sending response to ");
  Serial.println(Udp.remoteIP());
  Serial.print("Port : ");
  Serial.println(Udp.remotePort());

  IPAddress localIP = WiFi.localIP();
  char s[16];
  sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);

  String response =
    "HTTP/1.1 200 OK\r\n"
    "CACHE-CONTROL: max-age=86400\r\n"
    "DATE: Fri, 15 Apr 2016 04:56:29 GMT\r\n"
    "EXT:\r\n"
    "LOCATION: http://" + String(s) + ":80/setup.xml\r\n"
    "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
    "01-NLS: b9200ebb-736d-4b93-bf03-835149d13983\r\n"
    "SERVER: Unspecified, UPnP/1.0, Unspecified\r\n"
    "ST: urn:Belkin:device:**\r\n"
    "USN: uuid:" + persistent_uuid + "::urn:Belkin:device:**\r\n"
    "X-User-Agent: redsonic\r\n\r\n";

  // Try changing to this if you have problems discovering
  /* 
    String response =
    "HTTP/1.1 200 OK\r\n"
    "CACHE-CONTROL: max-age=86400\r\n"
    "DATE: Fri, 15 Apr 2016 04:56:29 GMT\r\n"
    "EXT:\r\n"
    "LOCATION: http://" + String(s) + ":80/setup.xml\r\n"
    "OPT: "http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
    "01-NLS: b9200ebb-736d-4b93-bf03-835149d13983\r\n"
    "SERVER: Unspecified, UPnP/1.0, Unspecified\r\n"
    "ST: ssdp:all\r\n"
    "USN: uuid:" + persistent_uuid + "::upnp:rootdevice\r\n"
    "X-User-Agent: redsonic\r\n\r\n";
  */

  Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
  Udp.write(response.c_str());
  Udp.endPacket();

  Serial.println("Response sent !");
}

void startHttpServer() {

  WiFiClient client = server.available();
  if (client) {
    Serial.println("new udp client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    String request = "";
    String postData = "";
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        request += String(c);
        if (c == '\n' && currentLineIsBlank) {

          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    //grab post data if there is any.
    Serial.print("\nBefore Post check: " + request + "\n\n");
    if (request.indexOf("POST") >= 0) {
      int intCL = request.indexOf("Content-Length:");
      int clLen = request.indexOf(String(char(13)), intCL + 1);
      int iContentLength = request.substring(intCL + 16, clLen + 1).toInt();
      //Serial.println("Content Length 2: " + iContentLength);
      for (int i = 0; i <= iContentLength - 1; i++) {
        char c = client.read();
        postData += c;
      }
      Serial.println("Post Data: " + postData);
    }

    Serial.print("New Request: " + request);

    if (request.indexOf("/index.html") > 0) {
      Serial.println("Got Request index.html ...\n");
      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: text/html");
      //client.println("Transfer-Encoding: chunked");
      client.println("Connection: close");  // the connection will be closed after completion of the response
      client.println();
      client.println("<!DOCTYPE HTML>");
      client.println("<html>");
      // output the value of each analog input pin
      client.println("Hello World!!!");
      client.println("</html>");
      // close the connection:

    }

    if (request.indexOf("/upnp/control/basicevent") > 0) {
      Serial.println("########## Responding to  /upnp/control/basicevent ... ##########");

      if(request.indexOf("basicevent1") > 0) {
        relayPin = 1;
      }
      if(request.indexOf("basicevent2") > 0) {
        relayPin = 2;
      }
      if(request.indexOf("basicevent3") > 0) {
        relayPin = 3;
      }
      if(request.indexOf("basicevent4") > 0) {
        relayPin = 4;
      }
      if(request.indexOf("basicevent5") > 0) {
        relayPin = 5;
      }
      if(request.indexOf("basicevent6") > 0) {
        relayPin = 6;
      }
      if(request.indexOf("basicevent7") > 0) {
        relayPin = 7;
      }
      if(request.indexOf("basicevent8") > 0) {
        relayPin = 8;
      }
    
      Serial.print("request:");
      Serial.println(postData);

      if (postData.indexOf("SetBinaryState") >= 0) {
        if (postData.indexOf("<BinaryState>1</BinaryState>") >= 0) {
          Serial.println("Got Turn on request");
          turnOnRelay(client);
        }

        if (postData.indexOf("<BinaryState>0</BinaryState>") >= 0) {
          Serial.println("Got Turn off request");
          turnOffRelay(client);
        }
      }

      if (postData.indexOf("GetBinaryState") >= 0) {
        Serial.println("Got binary state request");
        sendRelayState(client);
      }
    }

    if (request.indexOf("/eventservice.xml") > 0) {

      Serial.println(" ########## Responding to eventservice.xml ... ########\n");

      String eventservice_xml = "<scpd xmlns=\"urn:Belkin:service-1-0\">"
                                "<actionList>"
                                "<action>"
                                "<name>SetBinaryState</name>"
                                "<argumentList>"
                                "<argument>"
                                "<retval/>"
                                "<name>BinaryState</name>"
                                "<relatedStateVariable>BinaryState</relatedStateVariable>"
                                "<direction>in</direction>"
                                "</argument>"
                                "</argumentList>"
                                "</action>"
                                "<action>"
                                "<name>GetBinaryState</name>"
                                "<argumentList>"
                                "<argument>"
                                "<retval/>"
                                "<name>BinaryState</name>"
                                "<relatedStateVariable>BinaryState</relatedStateVariable>"
                                "<direction>out</direction>"
                                "</argument>"
                                "</argumentList>"
                                "</action>"
                                "</actionList>"
                                "<serviceStateTable>"
                                "<stateVariable sendEvents=\"yes\">"
                                "<name>BinaryState</name>"
                                "<dataType>Boolean</dataType>"
                                "<defaultValue>0</defaultValue>"
                                "</stateVariable>"
                                "<stateVariable sendEvents=\"yes\">"
                                "<name>level</name>"
                                "<dataType>string</dataType>"
                                "<defaultValue>0</defaultValue>"
                                "</stateVariable>"
                                "</serviceStateTable>"
                                "</scpd>\r\n"
                                "\r\n";

      Serial.println("Got Request /eventservice.xml ...\n");
      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: text/plain");
      //client.println("Transfer-Encoding: chunked");
      client.println("Connection: close");  // the connection will be closed after completion of the response
      client.println();
      // output the value of each analog input pin
      client.println(eventservice_xml);
    }

    if (request.indexOf("/setup.xml") > 0) {
      Serial.println(" ########## Responding to setup.xml ... ########\n");

      IPAddress localIP = WiFi.localIP();
      char s[16];
      sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);

      String setup_xml = "<?xml version=\"1.0\"?>"
                         "<root>"
                         "<device>"
                         "<deviceType>urn:Belkin:device:controllee:1</deviceType>"
                         "<friendlyName>" + friendlyName + "</friendlyName>"
                         "<manufacturer>Belkin International Inc.</manufacturer>"
                         "<modelName>Socket</modelName>"
                         "<modelNumber>3.1415</modelNumber>"
                         "<modelDescription>Belkin Plugin Socket 1.0</modelDescription>\r\n"
                         "<UDN>uuid:" + persistent_uuid + "</UDN>"
                         "<serialNumber>221517K0101769</serialNumber>"
                         "<binaryState>0</binaryState>"
                         "<serviceList>"
                         "<service>"
                         "<serviceType>urn:Belkin:service:basicevent:1</serviceType>"
                         "<serviceId>urn:Belkin:serviceId:basicevent1</serviceId>"
                         "<controlURL>/upnp/control/basicevent1</controlURL>"
                         "<eventSubURL>/upnp/event/basicevent1</eventSubURL>"
                         "<SCPDURL>/eventservice.xml</SCPDURL>"
                         "</service>"
                         
                         "<service>"
                         "<serviceType>urn:Belkin:service:basicevent:2</serviceType>"
                         "<serviceId>urn:Belkin:serviceId:basicevent2</serviceId>"
                         "<controlURL>/upnp/control/basicevent2</controlURL>"
                         "<eventSubURL>/upnp/event/basicevent2</eventSubURL>"
                         "<SCPDURL>/eventservice.xml</SCPDURL>"
                         "</service>"
                         "<service>"
                         "<serviceType>urn:Belkin:service:basicevent:3</serviceType>"
                         "<serviceId>urn:Belkin:serviceId:basicevent3</serviceId>"
                         "<controlURL>/upnp/control/basicevent3</controlURL>"
                         "<eventSubURL>/upnp/event/basicevent3</eventSubURL>"
                         "<SCPDURL>/eventservice.xml</SCPDURL>"
                         "</service>"
                         "<service>"
                         "<serviceType>urn:Belkin:service:basicevent:4</serviceType>"
                         "<serviceId>urn:Belkin:serviceId:basicevent4</serviceId>"
                         "<controlURL>/upnp/control/basicevent4</controlURL>"
                         "<eventSubURL>/upnp/event/basicevent4</eventSubURL>"
                         "<SCPDURL>/eventservice.xml</SCPDURL>"
                         "</service>"
                         "</serviceList>"
                         "</device>"
                         "</root>\r\n"
                         "\r\n";

      Serial.println("Got Request /setup.xml ...\n");
      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: text/xml");
      //client.println("Transfer-Encoding: chunked");
      client.println("Connection: close");  // the connection will be closed after completion of the response
      client.println();
      client.println(setup_xml);
      Serial.print("Sending :");
      Serial.println(setup_xml);
    }

    if (request.indexOf("/on.html") > 0) {
      Serial.println(" ########## Responding to on.html ... ########\n");
      Serial.println("Got Request /on.html ...\n");
      Serial.println("Got Turn on request");

      turnOnRelay(client);
    }

    if (request.indexOf("/off.html") > 0) {
      Serial.println(" ########## Responding to off.html ... ########\n");
      Serial.println("Got Request /off.html ...\n");
      Serial.println("Got Turn off request");

      turnOffRelay(client);
    }

    if (request.indexOf("/status.html") > 0) {
      Serial.println(" ########## Responding to status.html ... ########\n");
      Serial.println("Got Request /status.html ...\n");
      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: text/plain");
      //client.println("Transfer-Encoding: chunked");
      client.println("Connection: close");  // the connection will be closed after completion of the response
      client.println();
      String statrespone = "0";
      if (relayState) {
        statrespone = "1";
      }
      client.println(statrespone);

      Serial.println("Got status request");

    }
    client.stop();
    Serial.println("client disonnected");
  }
}

void turnOnRelay(WiFiClient client) {
  digitalWrite(relayPin, LOW); // turn on relay with voltage LOW
  relayState = true;

  String body =
    "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body>\r\n"
    "<u:SetBinaryStateResponse xmlns:u=\"urn:Belkin:service:basicevent:1\">\r\n"
    "<BinaryState>1</BinaryState>\r\n"
    "</u:SetBinaryStateResponse>\r\n"
    "</s:Body> </s:Envelope>";

  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/xml");
  client.println("gzip: true");
  //client.println("Transfer-Encoding: chunked");
  client.println("Connection: close");  // the connection will be closed after completion of the response
  client.println();
  client.println(body);
  Serial.print("Sending :");
  Serial.println(body);
}

void turnOffRelay(WiFiClient client) {
  digitalWrite(relayPin, HIGH);  // turn off relay with voltage HIGH
  relayState = false;

  String body =
    "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body>\r\n"
    "<u:SetBinaryStateResponse xmlns:u=\"urn:Belkin:service:basicevent:1\">\r\n"
    "<BinaryState>0</BinaryState>\r\n"
    "</u:SetBinaryStateResponse>\r\n"
    "</s:Body> </s:Envelope>";

  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/xml");
  client.println("gzip: true");
  //client.println("Transfer-Encoding: chunked");
  client.println("Connection: close");  // the connection will be closed after completion of the response
  client.println();
  client.println(body);
  Serial.print("Sending :");
  Serial.println(body);
}

void sendRelayState(WiFiClient client) {
  String body =
    "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body>\r\n"
    "<u:GetBinaryStateResponse xmlns:u=\"urn:Belkin:service:basicevent:1\">\r\n"
    "<BinaryState>";

  body += (relayState ? "1" : "0");

  body += "</BinaryState>\r\n"
          "</u:GetBinaryStateResponse>\r\n"
          "</s:Body> </s:Envelope>\r\n";

  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/xml");
  //client.println("Transfer-Encoding: chunked");
  client.println("Connection: close");  // the connection will be closed after completion of the response
  client.println();
  client.println(body);
}
Node Red FlowJSON
Import this flow into your node-red. make sure you update the html nodes with your ip of the sensor. And in the Alexa nodes, make sure you update the credentials for your login you create in the alexa bridge.
[
    {
        "id": "8501e66.3bee118",
        "type": "http request",
        "z": "dbe65262.fdb3",
        "name": "",
        "method": "POST",
        "ret": "txt",
        "url": "http://your_sensor_ip:80/upnp/control/basicevent1",
        "tls": "",
        "x": 1770,
        "y": 340,
        "wires": [
            [
                "859e01c.4dcb6",
                "e7f0f559.4a79e8"
            ]
        ]
    },
    {
        "id": "607cfc83.e9fb64",
        "type": "inject",
        "z": "dbe65262.fdb3",
        "name": "Relay 1 On",
        "topic": "",
        "payload": "true",
        "payloadType": "bool",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 1200,
        "y": 400,
        "wires": [
            [
                "5ab03b5c.8181d4"
            ]
        ]
    },
    {
        "id": "8614648e.9886e8",
        "type": "debug",
        "z": "dbe65262.fdb3",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 2010,
        "y": 540,
        "wires": []
    },
    {
        "id": "cb082e4e.cea0d",
        "type": "inject",
        "z": "dbe65262.fdb3",
        "name": "Relay 1 Off",
        "topic": "",
        "payload": "false",
        "payloadType": "bool",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 1200,
        "y": 460,
        "wires": [
            [
                "5ab03b5c.8181d4"
            ]
        ]
    },
    {
        "id": "cf07e15c.c5367",
        "type": "inject",
        "z": "dbe65262.fdb3",
        "name": "Relay 1 Status",
        "topic": "",
        "payload": "<?xml version=\"1.0\" encoding=\"utf-8\"?> <s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">   <s:Body>     <u:GetBinaryState xmlns:u=\"urn:Belkin:service:basicevent:1\"></u:GetBinaryState>   </s:Body> </s:Envelope>",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 1180,
        "y": 520,
        "wires": [
            [
                "8501e66.3bee118"
            ]
        ]
    },
    {
        "id": "e2ad0877.1bb528",
        "type": "inject",
        "z": "dbe65262.fdb3",
        "name": "Relay 2 on",
        "topic": "",
        "payload": "true",
        "payloadType": "bool",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 1200,
        "y": 660,
        "wires": [
            [
                "6ddb0a38.77d0c4"
            ]
        ]
    },
    {
        "id": "8d4959c8.841058",
        "type": "inject",
        "z": "dbe65262.fdb3",
        "name": "Relay 2 Off",
        "topic": "",
        "payload": "false",
        "payloadType": "bool",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 1200,
        "y": 720,
        "wires": [
            [
                "6ddb0a38.77d0c4"
            ]
        ]
    },
    {
        "id": "abc8bca0.ae4a7",
        "type": "http request",
        "z": "dbe65262.fdb3",
        "name": "",
        "method": "POST",
        "ret": "txt",
        "url": "http://your_sensor_ip:80/upnp/control/basicevent2",
        "tls": "",
        "x": 1770,
        "y": 600,
        "wires": [
            [
                "8614648e.9886e8",
                "e7f0f559.4a79e8"
            ]
        ]
    },
    {
        "id": "5711eb3.d68b914",
        "type": "alexa-home",
        "z": "dbe65262.fdb3",
        "conf": "28c11097.692d3",
        "device": "16099",
        "acknoledge": true,
        "name": "Kitchen Light",
        "topic": "",
        "x": 1190,
        "y": 340,
        "wires": [
            [
                "5ab03b5c.8181d4",
                "dbf4dd9d.6fe8a"
            ]
        ]
    },
    {
        "id": "dbf4dd9d.6fe8a",
        "type": "debug",
        "z": "dbe65262.fdb3",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 1410,
        "y": 260,
        "wires": []
    },
    {
        "id": "5ab03b5c.8181d4",
        "type": "switch",
        "z": "dbe65262.fdb3",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "1",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "0",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 1390,
        "y": 340,
        "wires": [
            [
                "a70930e7.ccab9"
            ],
            [
                "e5ae59e5.547188"
            ]
        ]
    },
    {
        "id": "7735f9d3.78be58",
        "type": "debug",
        "z": "dbe65262.fdb3",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 2210,
        "y": 260,
        "wires": []
    },
    {
        "id": "e354e432.8e4db8",
        "type": "alexa-home-resp",
        "z": "dbe65262.fdb3",
        "x": 2240,
        "y": 340,
        "wires": []
    },
    {
        "id": "859e01c.4dcb6",
        "type": "debug",
        "z": "dbe65262.fdb3",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 2010,
        "y": 260,
        "wires": []
    },
    {
        "id": "e5ae59e5.547188",
        "type": "function",
        "z": "dbe65262.fdb3",
        "name": "Off",
        "func": "msg.payload = '<?xml version=\"1.0\" encoding=\"utf-8\"?> <s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">   <s:Body>     <u:SetBinaryState xmlns:u=\"urn:Belkin:service:basicevent:1\">       <BinaryState>0</BinaryState>     </u:SetBinaryState>   </s:Body> </s:Envelope>'\nmsg.headers = {};\nmsg.headers['content-type'] = 'application/xml';\nreturn msg;\n",
        "outputs": 1,
        "noerr": 0,
        "x": 1570,
        "y": 360,
        "wires": [
            [
                "8501e66.3bee118"
            ]
        ]
    },
    {
        "id": "a70930e7.ccab9",
        "type": "function",
        "z": "dbe65262.fdb3",
        "name": "On",
        "func": "msg.payload = '<?xml version=\"1.0\" encoding=\"utf-8\"?> <s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">   <s:Body>     <u:SetBinaryState xmlns:u=\"urn:Belkin:service:basicevent:1\">       <BinaryState>1</BinaryState>     </u:SetBinaryState>   </s:Body> </s:Envelope>'\nmsg.headers = {};\nmsg.headers['content-type'] = 'application/xml';\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 1570,
        "y": 320,
        "wires": [
            [
                "8501e66.3bee118"
            ]
        ]
    },
    {
        "id": "e7f0f559.4a79e8",
        "type": "function",
        "z": "dbe65262.fdb3",
        "name": "Alexa response",
        "func": "msg.payload = true;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 2020,
        "y": 340,
        "wires": [
            [
                "e354e432.8e4db8",
                "7735f9d3.78be58"
            ]
        ]
    },
    {
        "id": "3ab2c03c.879db",
        "type": "alexa-home",
        "z": "dbe65262.fdb3",
        "conf": "28c11097.692d3",
        "device": "16100",
        "acknoledge": true,
        "name": "Outside Lights",
        "topic": "",
        "x": 1190,
        "y": 600,
        "wires": [
            [
                "6ddb0a38.77d0c4"
            ]
        ]
    },
    {
        "id": "6ddb0a38.77d0c4",
        "type": "switch",
        "z": "dbe65262.fdb3",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "1",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "0",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 1390,
        "y": 600,
        "wires": [
            [
                "7118df30.b9565"
            ],
            [
                "92240a0c.debd18"
            ]
        ]
    },
    {
        "id": "7118df30.b9565",
        "type": "function",
        "z": "dbe65262.fdb3",
        "name": "On",
        "func": "msg.payload = '<?xml version=\"1.0\" encoding=\"utf-8\"?> <s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">   <s:Body>     <u:SetBinaryState xmlns:u=\"urn:Belkin:service:basicevent:1\">       <BinaryState>1</BinaryState>     </u:SetBinaryState>   </s:Body> </s:Envelope>'\nmsg.headers = {};\nmsg.headers['content-type'] = 'application/xml';\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 1570,
        "y": 580,
        "wires": [
            [
                "abc8bca0.ae4a7"
            ]
        ]
    },
    {
        "id": "92240a0c.debd18",
        "type": "function",
        "z": "dbe65262.fdb3",
        "name": "Off",
        "func": "msg.payload = '<?xml version=\"1.0\" encoding=\"utf-8\"?> <s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">   <s:Body>     <u:SetBinaryState xmlns:u=\"urn:Belkin:service:basicevent:1\">       <BinaryState>0</BinaryState>     </u:SetBinaryState>   </s:Body> </s:Envelope>'\nmsg.headers = {};\nmsg.headers['content-type'] = 'application/xml';\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 1570,
        "y": 620,
        "wires": [
            [
                "abc8bca0.ae4a7"
            ]
        ]
    },
    {
        "id": "28c11097.692d3",
        "type": "alexa-home-conf",
        "z": "",
        "username": "your_username"
    }
]

Schematics

Sensor wiring diagram
Sensor relay oizmeofsej

Comments

Similar projects you might like

Home Automation system using Raspberry Pi

Project tutorial by Christian Kratky

  • 127,567 views
  • 34 comments
  • 404 respects

Herb Box Eco System

Project tutorial by Walter Heger

  • 37,028 views
  • 20 comments
  • 239 respects

Smart Home Automation

by Team Kamakshi's Smart Team

  • 4,922 views
  • 1 comment
  • 14 respects

Arduino Home Automation Control Board IoT

Project tutorial by Team My Arduino Home

  • 8,403 views
  • 3 comments
  • 19 respects

Home Monitoring System and Smart Home Solution

Project showcase by Akash Kumar

  • 5,471 views
  • 0 comments
  • 21 respects

Android App-Based Home Automation System Using IOT

Project tutorial by Team Autoshack

  • 24,838 views
  • 17 comments
  • 75 respects
Add projectSign up / Login