Send commands to an Arduino using HTTP - example executes IR remote codes

This is an Arduino sketch designed to decode HTTP commands and execute them using one of these Ardunios:

It uses HTTP, so it doesn’t have to rely on a permanent socket connection. The loss of a permanent socket connection, ie say the controlled device is just switched off; then that requires a Vera Luup engine restart to restore the connection. That’s undesirable for any equipment that gets/turned on and off regularly.

The HTTP command is case insensitive and is of the form:
http://arduino_ip_address/command/parameter1/parameter2

The sketch implements a working example that allows an Arduino to receive an IR code via HTTP and then transmit the IR code via an attached LED, to the associated media device. eg:

command = IR
parameter1 = NEC
parameter2 = IRcodeToSend

http://arduino_ip_address/ir/nec/12345678

The commands can be sent:

[ul][li]via your browser[/li]
[li]using a mac or PC[/li]
[li]using Luup.wget in a scene in Vera
http://wiki.mios.com/index.php/Luup_Lua_extensions#function:_wget[/li]
[li]or you can develop your own custom plugin to recreate your remote completely by [/li][/ul]

rehacking say this:
http://forum.micasaverde.com/index.php/topic,13418.msg99897.html#msg99897

and keep an eye on progress here:
http://forum.micasaverde.com/index.php/topic,17850.msg152066.html#msg152066

The sketch could be readily modified to do other commands and/or use more parameters as long as you can do the sketch programming.

There is no password protection - so evil doers could potentially turn up the sound on your TV.

The example used a visible LED “emitter” similar to this one:
http://www.xantech.com/files/manuals/117_283M.pdf

More details on the IR side of things can be found here:

Note the error in IRremoteInt.h for the NEC transmit:
Change NEC_ONE_SPACE definition to equal 1690
https://github.com/shirriff/Arduino-IRremote/issues/41

The reverse of the above - an IR receiver - can be found here:
http://forum.micasaverde.com/index.php/topic,18289.msg141271.html#msg141271

Ver 0.51
See attached.

@a-lurker,

I was searching for <Vera + HTTP + Arduino> and came across this post. I recently bought some of these WiFi modules for Arduino thinking that I would try to create a WiFi layer on my Vera in addition to the current MySensors layer (which works well with the new 1.4.1 and Ethernet Gateway).

This is interesting to me because of the low cost of the WiFi module (compared to either ethernet or other WiFi modules for Arduino). Potentially with one of these and say, a nano (with the 328 chip) you could you could add WiFi control to a device or sensor for about US$15. Not too bad.

Anyways, I tried your approach here and it worked… just set up a simple relay. The cost of the ethernet-capable Arduino is too high for my projects, but this low cost WiFi looks interesting.

Thanks for posting this.

Glad you could make some use of it.

The WiFi chips look interesting and the hackers are getting things happening with the Ardunio. Plus the great price. Looking forward to seeing this in action.

As aside it should be possible to send the mySensors commands as HTTP parameters as well. Not sure if that’s a useful thing or not however.

^^I’m keen on trying to figure that out^^

This is how I ended up with the Ethernet device, basic and stripped from examples, it works (and I have to say, with great reliability and a cute little webpage). Example with NTP Clock and webpage/vera/arduino control:

#include <Wire.h>
#include <SPI.h>         
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <Time.h>
#include <Timezone.h>
#include <LiquidCrystal_I2C.h>

#define DEBUG_ON
#define LED_PIN 8

#ifdef DEBUG_ON
#define DEBUG_PRINT(x)   Serial.print(x)
#define DEBUG_PRINTLN(x) Serial.println(x)
#define SERIAL_START(x)  Serial.begin(x)
#else
#define DEBUG_PRINT(x)
#define DEBUG_PRINTLN(x)
#define SERIAL_START(x)
#endif
//
LiquidCrystal_I2C lcd(0x27, 16, 2);
uint8_t clock[8] = {
  0x0,0xe,0x15,0x17,0x11,0xe,0x0}; // I'm-fetching-time indicator
//
EthernetUDP Udp;
EthernetServer server(80);
byte mac[] = { 
  0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE };
unsigned int localPort = 8888;
IPAddress timeServer(132, 163, 4, 101); // time-a.timefreq.bldrdoc.gov NTP server  // IPAddress timeServer(132, 163, 4, 102); // time-b.timefreq.bldrdoc.gov NTP server  // IPAddress timeServer(132, 163, 4, 103); // time-c.timefreq.bldrdoc.gov NTP server
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets 
//
const char *dayOfWeek[] = {
  "Null","Sunday ","Monday ", "Tuesday ", "Wednesday ", "Thursday ", "Friday ", "Saturday "};
// 
TimeChangeRule usEDT = {
  "EDT", Second, Sun, Mar, 2, -240};  //Eastern Daylight Time = UTC - 4 hours
TimeChangeRule usEST = {
  "EST", First, Sun, Nov, 2, -300};   //Eastern Standard Time = UTC - 5 hours
Timezone usET(usEDT, usEST);
TimeChangeRule *tcr;
//
boolean justStarted = true;
boolean forceClockUpdate = true;
//
String readString;
//
//
void setup() 
{
  Serial.begin(9600);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);
  DEBUG_PRINTLN(F("configuring ethernet"));
  if (Ethernet.begin(mac) == 0) // start Ethernet and UDP
  {
    DEBUG_PRINTLN(F("Failed to configure Ethernet using DHCP")); 
    while(true){
    }
  }
  server.begin();
  Udp.begin(localPort);
  //
  lcd.init();
  lcd.clear();
  lcd.backlight();
  lcd.createChar(0, clock);
  lcd.print("   NPT  Clock   ");
  delay(3000);
}
//
void loop()
{
  updateLCD();
  getNTPtime();
  webControl();
}
//
void updateLCD()
{
  static int lastSecond; 
  time_t rightNow = now();
  if (second(rightNow) != lastSecond)
  {
    lcd.setCursor(0,0);
    lcd.print(F("Time:"));
    DEBUG_PRINT(F("Time:"));
    lcd.print(hourFormat12(rightNow) < 10 ? F(" ") : F(""));
    DEBUG_PRINT(hourFormat12(rightNow) < 10 ? F(" ") : F(""));
    lcd.print(hourFormat12(rightNow));
    DEBUG_PRINT(hourFormat12(rightNow));
    lcd.print(minute(rightNow) < 10 ? F(":0") : F(":"));
    DEBUG_PRINT(minute(rightNow) < 10 ? F(":0") : F(":"));
    lcd.print(minute(rightNow));
    DEBUG_PRINT(minute(rightNow));
    lcd.print(second(rightNow) < 10 ? F(":0") : F(":"));
    DEBUG_PRINT(second(rightNow) < 10 ? F(":0") : F(":"));
    lcd.print(second(rightNow));
    DEBUG_PRINT(second(rightNow));
    lcd.print(isAM() ? "am" : "pm");
    DEBUG_PRINT(isAM() ? " am " : " pm ");
    lcd.setCursor(0,1);
    lcd.print(dayOfWeek[weekday(rightNow)]);
    DEBUG_PRINTLN(dayOfWeek[weekday(rightNow)]);
    lcd.print(F("      "));
    lcd.setCursor(11,1);
    lcd.print(month(rightNow) < 10 ? F(" ") : F(""));
    lcd.print(month(rightNow));
    lcd.print(day(rightNow) < 10 ? F("/0") : F("/"));
    lcd.print(day(rightNow));
  }
  lastSecond = second(rightNow);
}
//
unsigned long sendNTPpacket(IPAddress& address) // Send an NTP request to the time server at the given address 
{
  memset(packetBuffer, 0, NTP_PACKET_SIZE); 
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;            // Stratum, or type of clock
  packetBuffer[2] = 6;            // Polling Interval
  packetBuffer[3] = 0xEC;         // Peer Clock Precision
  packetBuffer[12]  = 49; 
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;		   
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  Udp.write(packetBuffer,NTP_PACKET_SIZE);
  Udp.endPacket(); 
}
//
void receiveTime(unsigned long newTime)
{
  DEBUG_PRINT(F("Time value received: "));
  int lastSecond = second();
  int lastMinute = minute();
  int lastHour = hour();
  setTime(newTime);
  if ((second() != lastSecond) || (minute() != lastMinute) || (hour() != lastHour))
  {
    DEBUG_PRINTLN(F("Clock updated...."));
    DEBUG_PRINT(F("Sensor's time currently set to:"));
    DEBUG_PRINT(hourFormat12() < 10? F(" 0") : F(" "));
    DEBUG_PRINT(hourFormat12());
    DEBUG_PRINT(minute() < 10? F(":0") : F(":"));
    DEBUG_PRINT(minute());
    DEBUG_PRINTLN(isAM()? F("am") : F("pm"));
    DEBUG_PRINT(month());
    DEBUG_PRINT(F("/"));
    DEBUG_PRINT(day());
    DEBUG_PRINT(F("/"));
    DEBUG_PRINTLN(year());
    DEBUG_PRINTLN(dayOfWeek[weekday()]);
  }
  lcd.setCursor(15,0);
  lcd.print(F(" "));
}
//
void getNTPtime()
{
  static unsigned long lastUpdateTime;
  const unsigned long interval = 600000UL;
  if ((millis() - lastUpdateTime >= interval) || forceClockUpdate)
  {
    lcd.setCursor(15,0);
    lcd.write(0);
    sendNTPpacket(timeServer); // send an NTP packet to a time server
    delay(1000);  
    if (Udp.parsePacket()) 
    {  
      Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer
      unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
      unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);  
      unsigned long secsSince1900 = highWord << 16 | lowWord;  
      DEBUG_PRINT(F("Seconds since Jan 1 1900 = "));
      DEBUG_PRINTLN(secsSince1900);               
      Serial.print(F("Unix time = "));
      time_t utcEpoch = secsSince1900 - 2208988800UL;//seventyYears = 2208988800UL
      DEBUG_PRINTLN(utcEpoch);                               
      receiveTime(usET.toLocal(utcEpoch, &tcr) + 2);  //about 2 seconds to call for time
    }
    if (!forceClockUpdate)
    {
      lastUpdateTime += interval;
    }
    forceClockUpdate = false;
  }
}
//
void webControl()
{
  EthernetClient client = server.available();
  if (client) 
  {
    while (client.connected()) 
    {
      if (client.available()) 
      {
        char c = client.read();
        if (readString.length() < 100) 
        {
          readString += c;
          DEBUG_PRINTLN(c);
        }
        if (c == '\n') //if HTTP request has ended
        {
          DEBUG_PRINTLN(readString);
          client.println(F("HTTP/1.1 200 OK")); //new page
          client.println(F("Content-Type: text/html"));
          client.println();
          client.println(F("<HTML>"));
          client.println(F("<HEAD>"));
          client.println(F("<meta name='apple-mobile-web-app-capable' content='yes' />"));
          client.println(F("<meta name='apple-mobile-web-app-status-bar-style' content='black-translucent' />"));
          client.println(F("<link rel='stylesheet' type='text/css' href='http://homeautocss.net84.net/a.css' />"));
          client.println(F("<TITLE>Jim's Home Automation</TITLE>"));
          client.println(F("</HEAD>"));
          client.println(F("<BODY>"));
          client.println(F("<H1>NTP Clock Light</H1>"));
          client.println(F("<hr />"));
          client.println(F("<br />"));
          client.println(F("<a href=\"/?lighton\"\">Turn On Light</a>"));
          client.println(F("<a href=\"/?lightoff\"\">Turn Off Light</a><br />"));  
          client.println(F("<br />"));
          client.println(F("<br />"));
          client.println(F("<a href=\"/?syncClock\"\">Synchronize Clock</a>")); 
          client.println(F("</BODY>"));
          client.println(F("</HTML>"));
          delay(1);
          client.stop();
          if(readString.indexOf("?lighton") > 0) // control arduino pin and LCD backlight //checks for 'on'
          {
            digitalWrite(LED_PIN, HIGH);
            lcd.backlight();
            DEBUG_PRINTLN(F("Led On"));
          }
          else if (readString.indexOf("?lightoff") > 0)//checks for 'off'
          {
            digitalWrite(LED_PIN, LOW);
            lcd.noBacklight();
            DEBUG_PRINTLN(F("Led Off"));
          }
          else if (readString.indexOf("?syncClock") > 0)// forces clock synchronization
          {
            forceClockUpdate = true;
          }
          readString=""; //clearing string for next read
        }
      }
    }
  }
}[/code]

I have to pull out the String class, but I was lazy...

the luup on/off:

[code]local myvar = luup.inet.wget("http://192.168.1.50/?lighton")
local myvar = luup.inet.wget("http://192.168.1.50/?lightoff")

Once I get the WiFi cracked, I’ll update (if I can!!)

@a-lurker,

I’m wanting to transmit HTTP command from arduino to vera e.g.:

http://192.168.1.59:3480/data_request?id=action&output_format=xml&DeviceNum=88&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0

would you know how to do that?

I am looking to directly affect vera with an ethernet connected device. In the above example, a sensor attached to an ethernet connected device to issue commands to Vera.

I’m struggling Arduino side.

I haven’t tried this but this sort of code should do it:

It’s just implementing a GET command. So just do the GET on Vera using your URL.

[quote=“a-lurker, post:6, topic:179875”]I haven’t tried this but this sort of code should do it:

It’s just implementing a GET command. So just do the GET on Vera using your URL.[/quote]

Thanks,

I had already come across that tutorial and managed to get that working with this type of structure:

void myFunction(boolean status) { if (client.connect(myserver, 3480)) //starts client connection, checks for connection { DEBUG_PRINTLN(F("connected")); client.print(F("GET /data_request?")); client.print(F("id=action&output_format=xml")); client.print(F("&DeviceNum=88")); client.print(F("&serviceId=urn:upnp-org:")); client.print(F("serviceId:SwitchPower1")); client.print(F("&action=SetTarget")); client.print(F("&newTargetValue=")); client.print(status ? F("1") : F("0")); client.println(F(" HTTP/1.1")); client.println(F("Connection: close")); //close 1.1 persistent connection client.println(); //end of get request delay(1); client.stop(); } }

Well, I had a ton of problems with it until I figured out that the string of text ought to be broken up into several shorter bursts (as above) instead of like this:

http://192.168.1.59:3480/data_request?id=action&output_format=xml&DeviceNum=88&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0

It occurred to me that dumping an entire http get into the stack was what was overflowing, and locking up the program.

Works well now and Again, I appreciate your assistance.

While more expensive (the ethernet shield) it offers up a lot of flexibility to put sensors and other devices throughout a home.

It’s good to hear it’s working OK but I’m not convinced it’s a string length problem. After the GET is terminated with the new line, you have a delay before the stop. It may be preferable to actually read what was sent by the other end to purge the Arduino as it were. I think Vera just sends a short page that says OK. Might be worth checking in the code if an “OK” is rx’ed as well.

hmmm…

Are you saying something like this?

void myFunction(boolean status) { if (client.connect(myserver, 3480)) //starts client connection, checks for connection { DEBUG_PRINTLN(F("connected")); client.print(F("GET /data_request?")); client.print(F("id=action&output_format=xml")); client.print(F("&DeviceNum=88")); client.print(F("&serviceId=urn:upnp-org:")); client.print(F("serviceId:SwitchPower1")); client.print(F("&action=SetTarget")); client.print(F("&newTargetValue=")); client.print(status ? F("1") : F("0")); client.println(F(" HTTP/1.1")); client.println(F("Connection: close")); //close 1.1 persistent connection client.println(); //end of get request delay(1); myWaitForAckFunction();// <<here? client.stop(); } }

Or, do you think I just set a flag to ignore other HTTP GETS from Vera (for a short time dumping the contents of the buffer)?

not sure what to do here…

I appreciate the comments, I’ve attached the code if you are interested in seeing what I’m trying to do.

it compiles to under 26K…

#include <Wire.h>
#include <EEPROM.h>
#include <SPI.h>         
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <utility/w5100.h>
#include <Time.h>
#include <Timezone.h>
#include <LiquidCrystal_I2C.h>
#include "DHT.h"

//#define DEBUG_ON
#define LED_PIN 8
#define DHT_SENSOR_PIN 7

#ifdef DEBUG_ON
#define DEBUG_PRINT(x)   Serial.print(x)
#define DEBUG_PRINTLN(x) Serial.println(x)
#define SERIAL_START(x)  Serial.begin(x)
#else
#define DEBUG_PRINT(x)
#define DEBUG_PRINTLN(x)
#define SERIAL_START(x)
#endif
//
boolean lightOn;
DHT dht;
//
LiquidCrystal_I2C lcd(0x27, 16, 2);
uint8_t clock[8] = {
  0x0,0xe,0x15,0x17,0x11,0xe,0x0}; // I'm-fetching-time-indicator for LCD display
//
EthernetUDP Udp;
EthernetServer server(80);
uint8_t mac[] = { 
  0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE };
const unsigned int localPort = 8888;
IPAddress timeServer(132, 163, 4, 101); // time-a.timefreq.bldrdoc.gov NTP server  // IPAddress timeServer(132, 163, 4, 102); // time-b.timefreq.bldrdoc.gov NTP server  // IPAddress timeServer(132, 163, 4, 103); // time-c.timefreq.bldrdoc.gov NTP server
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets 
byte socketStat[MAX_SOCK_NUM];
//
char myString[100];
byte locator = 0;
EthernetClient client;
const byte myserver[] = { 
  192,168,1,59 };
//
const char *dayOfWeek[] = {
  "Null","Sunday ","Monday ", "Tuesday ", "Wednesday ", "Thursday ", "Friday ", "Saturday "};
const char *monthString[] = {
  "NULL", "January", "February", "March", "April", "May", "June", "July", "August","September", "October", "November", "December"};
// 
TimeChangeRule usEDT = {
  "EDT", Second, Sun, Mar, 2, -240};  //Eastern Daylight Time = UTC - 4 hours
TimeChangeRule usEST = {
  "EST", First, Sun, Nov, 2, -300};   //Eastern Standard Time = UTC - 5 hours
Timezone usET(usEDT, usEST);
TimeChangeRule *tcr;
boolean forceClockUpdate = true;
//
void setup() 
{
  SERIAL_START(9600);
  dht.setup(DHT_SENSOR_PIN);
  //
  DEBUG_PRINTLN(F("configuring ethernet"));
  if (Ethernet.begin(mac) == 0) // start Ethernet and UDP
  {
    DEBUG_PRINTLN(F("Failed to configure Ethernet using DHCP")); 
    while(true){
    }
  }
  server.begin();
  Udp.begin(localPort);
  //
  lightOn = EEPROM.read(0);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, lightOn);
  //
  lcd.init();
  lcd.clear();
  lightOn? lcd.backlight() : lcd.noBacklight();
  lcd.createChar(0, clock);
}
//
void loop()
{
  updateLCD();
  getNTPtime();
  webControl();
}
//
void updateLCD()
{
  static int lastSecond; 
  time_t rightNow = now();
  if (second(rightNow) != lastSecond)
  {
    lcd.setCursor(0,0);
    lcd.print(F("Time:"));
    DEBUG_PRINT(F("Time:"));
    lcd.print(hourFormat12(rightNow) < 10 ? F(" ") : F(""));
    DEBUG_PRINT(hourFormat12(rightNow) < 10 ? F(" ") : F(""));
    lcd.print(hourFormat12(rightNow));
    DEBUG_PRINT(hourFormat12(rightNow));
    lcd.print(minute(rightNow) < 10 ? F(":0") : F(":"));
    DEBUG_PRINT(minute(rightNow) < 10 ? F(":0") : F(":"));
    lcd.print(minute(rightNow));
    DEBUG_PRINT(minute(rightNow));
    lcd.print(second(rightNow) < 10 ? F(":0") : F(":"));
    DEBUG_PRINT(second(rightNow) < 10 ? F(":0") : F(":"));
    lcd.print(second(rightNow));
    DEBUG_PRINT(second(rightNow));
    lcd.print(isAM() ? "am" : "pm");
    DEBUG_PRINT(isAM() ? " am " : " pm ");
    lcd.setCursor(0,1);
    lcd.print(dayOfWeek[weekday(rightNow)]);
    DEBUG_PRINTLN(dayOfWeek[weekday(rightNow)]);
    lcd.print(F("      "));
    lcd.setCursor(11,1);
    lcd.print(month(rightNow) < 10 ? F(" ") : F(""));
    lcd.print(month(rightNow));
    lcd.print(day(rightNow) < 10 ? F("/0") : F("/"));
    lcd.print(day(rightNow));
  }
  lastSecond = second(rightNow);
}
//
void sendNTPpacket(IPAddress& address) // Send an NTP request to the time server at the given address 
{
  memset(packetBuffer, 0, NTP_PACKET_SIZE); 
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;            // Stratum, or type of clock
  packetBuffer[2] = 6;            // Polling Interval
  packetBuffer[3] = 0xEC;         // Peer Clock Precision
  packetBuffer[12]  = 49; 
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;		   
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  Udp.write(packetBuffer,NTP_PACKET_SIZE);
  Udp.endPacket(); 
}
//
void receiveTime(unsigned long newTime)
{
  DEBUG_PRINT(F("Time value received: "));
  int lastSecond = second();
  int lastMinute = minute();
  int lastHour = hour();
  setTime(newTime);
  if ((second() != lastSecond) || (minute() != lastMinute) || (hour() != lastHour))
  {
    DEBUG_PRINTLN(F("Clock updated...."));
    DEBUG_PRINT(F("Sensor's time currently set to:"));
    DEBUG_PRINT(hourFormat12() < 10? F(" 0") : F(" "));
    DEBUG_PRINT(hourFormat12());
    DEBUG_PRINT(minute() < 10? F(":0") : F(":"));
    DEBUG_PRINT(minute());
    DEBUG_PRINTLN(isAM()? F("am") : F("pm"));
    DEBUG_PRINT(month());
    DEBUG_PRINT(F("/"));
    DEBUG_PRINT(day());
    DEBUG_PRINT(F("/"));
    DEBUG_PRINTLN(year());
    DEBUG_PRINTLN(dayOfWeek[weekday()]);
  }
  lcd.setCursor(15,0);
  lcd.print(F(" "));
}
//
void getNTPtime()
{
  static unsigned long lastUpdateTime;
  const unsigned long interval = 60000UL;
  if ((millis() - lastUpdateTime >= interval) || forceClockUpdate)
  {
    lcd.setCursor(15,0);
    lcd.write(0);
    sendNTPpacket(timeServer); // send an NTP packet to a time server
    delay(1000);  
    if (Udp.parsePacket()) 
    {  
      Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer
      unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
      unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);  
      unsigned long secsSince1900 = highWord << 16 | lowWord;  
      DEBUG_PRINT(F("Seconds since Jan 1 1900 = "));
      DEBUG_PRINTLN(secsSince1900);               
      DEBUG_PRINT(F("Unix time = "));
      time_t utcEpoch = secsSince1900 - 2208988800UL;//seventyYears = 2208988800UL
      DEBUG_PRINTLN(utcEpoch);                               
      receiveTime(usET.toLocal(utcEpoch, &tcr) + 2);  //about 2 seconds to call for time
    }
    if (!forceClockUpdate)
    {
      lastUpdateTime += interval;
    }
    forceClockUpdate = false;
  }
}
//
void webControl()
{
  EthernetClient client = server.available();
  if (client) 
  {
    while (client.connected()) 
    {
      if (client.available()) 
      {
        char c = client.read();
        if (locator < 100)
        {
          myString[locator] = c;
          locator++;
          myString[locator] = '\0'; 
        }
        if (c == '\n') //if HTTP request has ended
        {
          DEBUG_PRINTLN(F("MyString ="));
          DEBUG_PRINTLN(myString);
          client.println(F("HTTP/1.1 200 OK")); //new page
          client.println(F("Content-Type: text/html"));
          client.println();
          client.println(F("<HTML>"));
          client.println(F("<HEAD>"));
          client.println(F("<meta name='apple-mobile-web-app-capable' content='yes' />"));
          client.println(F("<meta name='apple-mobile-web-app-status-bar-style' content='black-translucent' />"));
          client.println(F("<link rel='stylesheet' type='text/css' href='http://homeautocss.net84.net/a.css' />"));
          client.println(F("<TITLE>Jim's Home Automation</TITLE>"));
          client.println(F("</HEAD>"));
          client.println(F("<BODY>"));
          client.println(F("<H1>NTP Clock/Light</H1>"));
          client.println(F("<hr />"));
          client.println(F("<br />"));
          client.println(F("<a href=\"/?ledOn\"\">Light On</a>"));
          client.println(F("<a href=\"/?ledOff\"\">Light Off</a><br />"));  
          client.println(F("<br />"));
          client.println(F("<br />"));
          client.println(F("<a href=\"/?phoneyOn\"\">PhoneyTV On</a>"));
          client.println(F("<a href=\"/?phoneyOff\"\">PhoneyTV Off</a><br />"));  
          client.println(F("<br />"));
          client.println(F("<br />"));
          client.println(F("<a href=\"/?syncClock\"\">Force Synchronize Clock</a>"));
          client.println(F("<br />"));
          client.println(F("<br />"));
          client.println(F("<hr />"));
          client.println(F("<H2>Current Conditions</H2>"));
          client.println(F("<H3>"));
          client.println(dayOfWeek[weekday()]);
          client.println(F(","));
          client.println(monthString[month()]);
          client.println(F(" "));
          client.println(day());
          client.println(F(","));
          client.println(year());
          client.println(F("<br />"));
          client.println(F("<br />"));
          client.println(F("<font color=\"blue\">Temperature</font>"));
          client.println(F("<font color=\"red\">"));
          client.println((int)floor(dht.toFahrenheit(dht.getTemperature()) + 0.5), 1);
          client.println(F("</font>"));
          client.println(F("<font color=\"blue\">F</font>"));
          client.println(F("<br />"));
          client.println(F("<H3><font color=\"blue\">Humidity</font>"));
          client.println(F("<font color=\"red\">"));
          client.println((int)floor(dht.getHumidity() + 0.5), 1);
          client.println(F("</font>"));
          client.println(F("<font color=\"blue\">%</font>"));
          client.println(F("<br />"));
          client.println(F("<div style=\"background-color:grey;"));
          client.print(F(" color:black; margin:20px; padding:20px;\">"));
          client.println(F("<h3>Jim Brower</h3>"));
          client.println(F("<p>"));
          client.println("&#169");
          client.println(F(" 2014"));
          client.println(F("</p>"));
          client.println(F("</div>"));
          client.println(F("</BODY>"));
          client.println(F("</HTML>"));
          delay(1);
          client.stop();
          if(strstr(myString, "?ledOn")) // control arduino pin and LCD backlight //checks for 'on'
          {
            lightOn = true;
            EEPROM.write(0,0xFF);
            digitalWrite(LED_PIN, HIGH);
            lcd.backlight();
            DEBUG_PRINTLN(F("Led On"));
          }
          if(strstr(myString, "?ledOff")) // compliment to above
          {
            lightOn = false;
            EEPROM.write(0,0x00);
            digitalWrite(LED_PIN, LOW);
            lcd.noBacklight();
            DEBUG_PRINTLN(F("Led Off"));
          }
          else if (strstr(myString, "?syncClock"))
          {
            forceClockUpdate = true;
            DEBUG_PRINTLN(F("Sync Set"));
          }
          else if (strstr(myString, "?phoneyOn"))
          {
            phoneyTV(true);
            DEBUG_PRINTLN(F("PhoneyTV On"));
          }
          else if (strstr(myString, "?phoneyOff"))
          {
            phoneyTV(false);
            DEBUG_PRINTLN(F("PhoneyTV Off"));
          }
          myString[0] = '\0'; //clearing string for next read
          locator = 0;
        }
      }
    }
  }
}
//
void phoneyTV(boolean status)
{
  ShowSockStatus();
  if (client.connect(myserver, 3480)) //starts client connection, checks for connection
  {  
    DEBUG_PRINTLN(F("connected"));
    client.print(F("GET /data_request?"));
    client.print(F("id=action&output_format=xml"));
    client.print(F("&DeviceNum=88"));
    client.print(F("&serviceId=urn:upnp-org:"));
    client.print(F("serviceId:SwitchPower1"));
    client.print(F("&action=SetTarget"));
    client.print(F("&newTargetValue="));
    client.print(status ? F("1") : F("0"));
    client.println(F(" HTTP/1.1"));
    client.println(F("Connection: close"));  //close 1.1 persistent connection  
    client.println(); //end of get request
    delay(1);
    client.stop();
  }
}

void ShowSockStatus()
{
  for (int i = 0; i < MAX_SOCK_NUM; i++) 
  {
    DEBUG_PRINT(F("Socket#"));
    DEBUG_PRINT(i);
    uint8_t s = W5100.readSnSR(i);
    socketStat[i] = s;
    DEBUG_PRINT(F(":0x"));
#ifdef DEBUG_ON
    Serial.print(s,16);
#endif
    DEBUG_PRINT(F(" "));
    DEBUG_PRINT(W5100.readSnPORT(i));
    DEBUG_PRINT(F(" D:"));
    uint8_t dip[4];
    W5100.readSnDIPR(i, dip);
    for (int j=0; j<4; j++) 
    {
      Serial.print(dip[j],10);
      if (j<3) Serial.print(".");
    }
    DEBUG_PRINT(F("("));
    DEBUG_PRINT(W5100.readSnDPORT(i));
    DEBUG_PRINT(F(")"));
  }
}