@dayve218
well, having some free time I've expanded it quite a bit, and I am not 100% sure it will run on an UNO... It works on a mega. I added a bunch of stuff:
-
tells you how many unread emails you have using a BASH script on a server to send updates every so often (I'll post that too).
-
control the brightness of the LCD with a dimmer.
-
uses Vera dimmer and switch to control relay and brightness (uses standard xml files to upload to Vera)
-
more weather
I don't have a display demo right now, been testing in my Serial Monitor
I can help you with any of it:
/*
Vera Auxilliary Controller a.k.a. Arduino/Vera Ethernet Device
December, 2014
Version .91
This sketch features the following:
* With the device's own website it allows you to send the device a message along with a visual or sound indicator
* Control LCD backlight
* Control led (relay)
* Control your alarm state or lights or execute scenes...
* Control attached Relay
* Processes and displays "Vital" data from Vera like the Weather, Alarm State
* Reliably runs on an UNO but very expandable if you want to use a Mega instead
* Displays Indoor Temp and Humidity using DHT sensor
INSTRUCTIONS:
* There are multiple debug serial prints that can be monitored to assure that it is operating properly.
* https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads for the I2C library, or use yours
* Add virtual switches to your Vera by following instructions here:http://faq.mios.com/content/2/40/en/how-to-create-virtual-device.html
* and create a scene and add luup (lua) code like this:
local state = luup.variable_get("urn:upnp-org:serviceId:SwitchPower1", "Status", 3)
luup.inet.wget("192.168.1.50//?ledState=“..state..”&”)
copyright (c) by Jim Brower (BulldogLowell@gmail.com)
*/
#include <Wire.h>
#include <EEPROM.h>
#include <SPI.h>
//#include <SD.h> // you will need a MEGA for this, if you want to really expand the web UI
#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 // comment out getNTPtime(); in loop to get this to fit on an UNO for debug, otherwise debug on a MEGA
//#define USE_DHCP // uncomment here for DHCP but uses more than 3kBytes, so warm up your MEGA it is too big for your UNO
#define DIMMER_PIN 6 // available PWM capable pin
#define DHT_SENSOR_PIN 7 // Thermometer-Hygrometer
#define RELAY_PIN 13//8 // Relay control output
#define DISPLAY_UPDATE_TIME 3000UL // 3.5 seconds seems OK
#define NUMBER_OF_MESSAGE_TYPES 17 // Kinds of transmissions from Vera/Internet
#define TONE_PIN 6 // If you want Audio alerts
#define NUMBER_OF_ACTION_BUTTONS 5 // your device can control scenes, devices, etc Vera-side
//
#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
//
typedef enum{
LCD_WIND, LCD_TIME, LCD_ALARM_STATUS, LCD_GARAGE, LCD_GUEST_GARAGE, LCD_IP_ADDRESS, LCD_TEMPERATURE, LCD_AC_SETPOINT, LCD_OUTSIDE_TEMP, LCD_WEATHER, LCD_FORECAST, LCD_MESSAGE, LCD_HI_LOW, LCD_EMAIL}
lcdState;
//
lcdState state = LCD_TIME; // display start on Time
//
//File webFile;
//
char *messagePtr;
const char *messageType[NUMBER_OF_MESSAGE_TYPES] = {
"?ledStatus=", "?alarmState=", "?garageState=", "?guestGarageState=", "?weatherCondition=", "?outsideTemp=", "?outsideHumid=", "?airconSetpoint=", "?weatherForecast=", "?messageData=", "?todayHigh=", "?todayLow=", "?windSpeed=", "?windDirection=", "?relayState=", "?brightLevel=", "?emailCount="};
//
boolean messageFlag = false;
unsigned long timerStart;
unsigned long timerDuration;
int signal = 0;
//
boolean lightOn;
boolean relayState;
boolean garageOpen = false;
boolean guestGarageOpen = false;
char customMessage [30];
char weatherCondition[30] = {
" Not Yet Reported"};
char weatherForecast[30] = {
" Not Yet Reported"};
int outdoorTemp = -99;
int outdoorHumid = -99;
int todayHigh = -99;
int todayLow = -99;
int airconSetpoint = 78;
int alarmArmed = -1;
int windSpeed = 99;
char windDirection[6] = {"ZZZ"};
char myCharBuffer[30];
byte brightLevel = 0;
byte oldBrightLevel;
int emailCount = -1;
//
byte buttonPin[NUMBER_OF_ACTION_BUTTONS] = {
4, 5, A0, A1, A2};
byte lastButtonState[4];
//
DHT dht;
//
LiquidCrystal_I2C lcd(0x27, 20,4);
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 };
IPAddress ip(192,168,1,50);
//
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 veraServer[] = {
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;
//
void setup()
{
SERIAL_START(9600);
lightOn = EEPROM.read(0);
relayState = EEPROM.read(1);
pinMode(RELAY_PIN, OUTPUT);
pinMode(DIMMER_PIN, OUTPUT);
digitalWrite(RELAY_PIN, relayState? HIGH : LOW);
//
for (byte i = 0; i < 4; i++)
{
pinMode(buttonPin[i], INPUT_PULLUP);
}
//
dht.setup(DHT_SENSOR_PIN);
//
#ifdef USE_DHCP
DEBUG_PRINTLN(F("configuring e-net"));
if (Ethernet.begin(mac) == 0) // start Ethernet and UDP
{
DEBUG_PRINTLN(F("Fail Ethernet DHCP"));
while(true){
}
}
#else
Ethernet.begin(mac, ip);
#endif
//
server.begin();
Udp.begin(localPort);
//
lcd.init();
lcd.clear();
lightOn? lcd.backlight() : lcd.noBacklight();
lcd.createChar(0, clock);
}
//
void loop()
{
updateLCD();
getNTPtime();
webControl();
messageTimer();
updateBriteness();
for (byte i = 0; i < NUMBER_OF_ACTION_BUTTONS; i++)
{
byte buttonState = digitalRead(buttonPin[i]);
if (buttonState == LOW && lastButtonState[i] == HIGH)
{
buttonPress(i);
}
lastButtonState[i] = buttonState;
}
}
//
void updateLCD()
{
static unsigned long lastDisplayChangeTime;
if (millis() - lastDisplayChangeTime >= DISPLAY_UPDATE_TIME)
{
switch (state)
{
case LCD_TIME:
fastClearLCD();
lcd.setCursor(0,0);
timeDate();
lcd.setCursor(0,1);
DEBUG_PRINT(F("Time: "));
DEBUG_PRINT(hourFormat12());
DEBUG_PRINT(F(":"));
DEBUG_PRINT(minute());
DEBUG_PRINTLN(isAM() ? "a" : "p");
DEBUG_PRINTLN(dayOfWeek[weekday()]);
lcd.print(dayOfWeek[weekday()]);
displayStatus();
if (emailCount != -1)
state = LCD_EMAIL;
else
state = LCD_ALARM_STATUS;
break;
//
case LCD_EMAIL:
fastClearLCD();
lcd.setCursor(0,0);
timeDate();
lcd.setCursor(0,1);
lcd.print(F(" Email Count"));
DEBUG_PRINT(F("emails: "));
lcd.setCursor(0,2);
lcd.print(F(" "));
lcd.print(emailCount);
DEBUG_PRINTLN(emailCount);
displayStatus();
state = LCD_ALARM_STATUS;
break;
//
case LCD_ALARM_STATUS:
fastClearLCD();
lcd.setCursor(0,0);
timeDate();
lcd.setCursor(0,1);
lcd.print(F(" Alarm Status"));
DEBUG_PRINT(F("Alm: "));
lcd.setCursor(0,2);
if (alarmArmed == 0)
{
lcd.print(F(" Not Armed"));
}
else if (alarmArmed == 1)
{
lcd.print(F(" Armed"));
}
else
{
lcd.print(F(" Not Yet Reported"));
}
DEBUG_PRINTLN(alarmArmed ? F("Yes") : F("NO"));
displayStatus();
state = LCD_GARAGE;
break;
//
case LCD_GARAGE:
fastClearLCD();
lcd.setCursor(0,0);
timeDate();
lcd.setCursor(0,1);
lcd.print(F(" Main Garage"));
DEBUG_PRINT(F("Garage: "));
lcd.setCursor(0,2);
if (garageOpen == 0)
{
lcd.print(F(" Closed"));
}
else if (garageOpen == 1)
{
lcd.print(F(" Open"));
}
else
{
lcd.print(F(" Not Yet Reported"));
}
DEBUG_PRINTLN(garageOpen ? F("OPEN") : F("CLOSE"));
displayStatus();
state = LCD_GUEST_GARAGE;
break;
//
case LCD_GUEST_GARAGE:
fastClearLCD();
lcd.setCursor(0,0);
timeDate();
lcd.setCursor(0,1);
lcd.print(F(" Guest Garage"));
DEBUG_PRINT(F("Guest: "));
lcd.setCursor(0,2);
if (guestGarageOpen == 0)
{
lcd.print(F(" Closed"));
}
else if (guestGarageOpen == 1)
{
lcd.print(F(" Open"));
}
else
{
lcd.print(F(" Not Yet Reported"));
}
DEBUG_PRINTLN(guestGarageOpen ? F("OPEN") : F("CLOSE"));
displayStatus();
state = LCD_TEMPERATURE;
break;
//
case LCD_TEMPERATURE:
fastClearLCD();
lcd.setCursor(0,0);
timeDate();
lcd.setCursor(0,1);
lcd.print(F(" Temperture:"));
DEBUG_PRINT(F("Inside Temp:"));
lcd.print(dht.toFahrenheit(dht.getTemperature()), 0);
lcd.print(char(223));
lcd.print(F("F"));
lcd.setCursor(0,2);
lcd.print(F(" Humidity:"));
lcd.print(dht.getHumidity(), 0);
DEBUG_PRINT(F("Humidity:"));
DEBUG_PRINTLN(dht.getHumidity());
lcd.print(F("%"));
displayStatus();
state = LCD_AC_SETPOINT;
break;
case LCD_AC_SETPOINT:
//
fastClearLCD();
lcd.setCursor(0,0);
timeDate();
lcd.setCursor(0,1);
lcd.print(F(" A/C Setpoint"));
lcd.setCursor(0,2);
lcd.print(F(" "));
lcd.print(airconSetpoint);
lcd.print(char(223));
lcd.print(F("F"));
DEBUG_PRINT(F("A/C setpoint:"));
DEBUG_PRINTLN(airconSetpoint);
displayStatus();
state = LCD_OUTSIDE_TEMP;
break;
//
case LCD_OUTSIDE_TEMP:
//
fastClearLCD();
lcd.setCursor(0,0);
timeDate();
lcd.setCursor(0,1);
lcd.print(F(" Outdoor Temp:"));
DEBUG_PRINT(F("Ext. Temp:"));
lcd.print(outdoorTemp);
lcd.print(char(223));
lcd.print(F("F"));
DEBUG_PRINTLN(outdoorTemp);
lcd.setCursor(0,2);
lcd.print(F(" Humidity:"));
DEBUG_PRINT(F("Humidity:"));
lcd.print (outdoorHumid);
lcd.print(F("%"));
DEBUG_PRINTLN(outdoorHumid);
displayStatus();
state = LCD_WEATHER;
break;
//
case LCD_WEATHER:
//
fastClearLCD();
lcd.setCursor(0,0);
timeDate();
lcd.setCursor(0,1);
lcd.print(F(" Today's Weather"));
DEBUG_PRINT(F("Weather: "));
lcd.setCursor(0,2);
lcd.print(weatherCondition);
DEBUG_PRINTLN(weatherCondition);
displayStatus();
state = LCD_HI_LOW;
break;
//
case LCD_HI_LOW:
//
fastClearLCD();
DEBUG_PRINTLN(F("Weather Hi/Lows"));
timeDate();
lcd.setCursor(0,1);
lcd.print(F("Today's High: "));
lcd.print(todayHigh);
lcd.print(char(223));
lcd.print(F("F"));
lcd.setCursor(0,2);
lcd.print(F(" Low: "));
lcd.print (todayLow);
lcd.print(char(223));
lcd.print(F("F"));
displayStatus();
if (windSpeed > 2)
{
state = LCD_WIND;
}
else
{
state = LCD_FORECAST;
DEBUG_PRINTLN(F("wind too light to report..."));
}
break;
//
case LCD_WIND:
//
fastClearLCD();
lcd.setCursor(0,0);
timeDate();
lcd.setCursor(0,1);
lcd.print(F(" Winds Gusting"));
DEBUG_PRINT(F("Winds: "));
DEBUG_PRINTLN(windSpeed);
lcd.print(F(" "));
lcd.setCursor(1,2);
if (windSpeed < 10) lcd.print(F(" "));
lcd.print(windSpeed);
lcd.print(F("mph from the "));
lcd.print(windDirection);
displayStatus();
state = LCD_FORECAST;
break;
case LCD_FORECAST:
//
fastClearLCD();
lcd.setCursor(0,0);
timeDate();
lcd.setCursor(0,1);
lcd.print(F(" Tomorrow"));
DEBUG_PRINT(F("Forecast: "));
lcd.setCursor(0,2);
lcd.print(weatherForecast);
DEBUG_PRINTLN(weatherForecast);
displayStatus();
if (messageFlag)
state = LCD_MESSAGE;
else
state = LCD_IP_ADDRESS;
break;
//
case LCD_MESSAGE:
//
fastClearLCD();
lcd.setCursor(0,0);
timeDate();
if (signal == 2 && lightOn == 1)
{
for (int i = 0; i < 20; i++)
{
lcd.noBacklight();
delay(50);
lcd.backlight();
delay(50);
}
}
else if (signal == 1 && lightOn == 1)
{
beepTone();
}
if (signal != 0)
{
lastDisplayChangeTime - millis(); // give the message back the time lost in the flash/blinking
}
lcd.setCursor(0,1);
lcd.print(F(" *** Message ***"));
DEBUG_PRINT(F("Message: "));
lcd.setCursor(0,2);
lcd.print(customMessage);
DEBUG_PRINTLN(customMessage);
displayStatus();
state = LCD_IP_ADDRESS;
break;
//
case LCD_IP_ADDRESS:
//
fastClearLCD();
lcd.setCursor(0,0);
timeDate();
lcd.setCursor(0,1);
lcd.print(F(" IP Address"));
DEBUG_PRINT(F("IP Address: "));
lcd.setCursor(0,2);
lcd.print(" ");
for (byte thisByte = 0; thisByte < 4; thisByte++) // print the value of each byte of the IP address:
{
lcd.print(Ethernet.localIP()[thisByte], DEC);
if (thisByte < 3) lcd.print(".");
#ifdef DEBUG_ON
Serial.print(Ethernet.localIP()[thisByte], DEC);
#endif
if (thisByte < 3) DEBUG_PRINT(".");
else DEBUG_PRINTLN(F(" "));
}
lcd.print(F(" "));
displayStatus();
state = LCD_TIME;
break;
//
}
lastDisplayChangeTime = millis();
DEBUG_PRINT(F("free ram:"));
DEBUG_PRINTLN(freeRam());
}
}
//
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(19,0);
lcd.print(F(" "));
}
//
void getNTPtime()
{
static unsigned long lastUpdateTime;
const unsigned long interval = 60000UL;
if ((millis() - lastUpdateTime >= interval))
{
lcd.setCursor(19,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
lastUpdateTime += interval;
}
}
}
//
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);
// Send a full website with controls functions and handles message input...
client.println(F(
"<html>"
"<head>"
"<title>Vera Helper</title>"
"</head>"
"<body>"
"<div align=\"center\">"
"<H2>Arduino Auxilliary Controller</H2>"
"<H3>for Vera</H3>"
"<hr>"
"<H2><font color=\"green\">Comfort Settings</H2>"
"<H4><font color=\"blue\">Temperature</font>"
"<font color=\"red\">"));
client.println(dht.toFahrenheit(dht.getTemperature()), 1);
client.println(F("</font>"
"<font color=\"blue\">F</font>"
"<br />"
"<H4><font color=\"blue\">Humidity</font>"
"<font color=\"red\">"));
client.println(dht.getHumidity(), 1);
client.println(F("</font>"
"<font color=\"blue\">%</font>"
"<H4><font color=\"midnightBlue\">AirConditioning Setpoint</font>"
"<font color=\"red\">"));
client.println(airconSetpoint);
client.println(F("</font>"
"<font color=\"blue\">F</font>"
"<br />"
"<hr>"
"<h2>"
"Send Message<br>"
"<form>"
"<input type=\"text\" size=\"20\" name= \"messageData\" value=\"Enter message here\">"
"<select name=\"time\">"
"<option value=\"5\">5min</option>"
"<option value=\"15\">15min</option>"
"<option selected value=\"30\">30min</option>"
"<option value=\"60\">60min</option>"
"<option value=\"720\">12hrs</option>"
"<option value=\"1440\">24hrs</option>"
"</select>"
"<h4>"
"<div align=\"center\">"
"<input type=\"radio\" name=\"signal\" value=\"2\"> Flash<br>"
"<input type=\"radio\" name=\"signal\" value=\"1\"> Tone <br>"
"<input type=\"radio\" name=\"signal\" value=\"0\" checked> None</h4>"
"<input type=\"submit\" onclick=\"alert('Message Sent!')\" value=\"Send\"> <input type=\"reset\" value=\"Reset\"></h2>"
"</form>"
"<hr>"
"<a href=\"/?ledStatus=1?\"\">Turn On LED Backlight</a> "
"<a href=\"/?ledStatus=0?\"\">Turn Off LED Backlight</a>"
"<br />"
"<a href=\"/?relayState=1?\"\">Turn On Outlet</a> "
"<a href=\"/?relayState=0?\"\">Turn Off Outlet</a><br /> "
"<br />"
"<a href=\"/?airconSetpoint="));
if (airconSetpoint > 70) client.println(airconSetpoint - 1);
else client.println(airconSetpoint);
client.println(F("?\"\">Lower Air Conditioning Setpoint</a><br /> "
"<br />"
"<div style=\"background-color:LightSlateGray; color:black; margin:20px; padding:20px;\">"
"<h3>Jim Brower</h3>"
"<h5>© copyright 2014</h5>"
"<h5><a href=\"mailto:bulldoglowell@gmail.com?subject=Arduino/Vera Home Controller\">"
"Send Email</a><h5>"
"</div>"
"</body>"
"</html>"));
delay(1);
client.stop();
//
// let's sort out that HTTP request...
//
for (byte i = 0; i < NUMBER_OF_MESSAGE_TYPES; i++)
{
messagePtr = strstr(myString, messageType[i]); // we need a global variable here
if (messagePtr)
{
DEBUG_PRINT(F("network msg..."));
DEBUG_PRINTLN(messageType[i]);
processMessage(i);
break;
}
}
myString[0] = '\0'; //clearing string for next read
locator = 0;
}
}
}
}
}
//
#ifdef DEBUG_ON
int freeRam ()
{
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
#endif
//
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);
#ifdef DEBUG_ON
for (int j=0; j<4; j++)
{
Serial.print(dip[j],10);
if (j<3) Serial.print(".");
}
#endif
DEBUG_PRINT(F("("));
DEBUG_PRINT(W5100.readSnDPORT(i));
DEBUG_PRINT(F(")"));
}
}
//
void processMessage(byte httpMessage)
{
switch (httpMessage)
{
case 0: // "?ledStatus="
//
lightOn = parseNumber(httpMessage) ? 1 : 0;
//(myString[messagePtr - myString + strlen(messageType[httpMessage])]) == '0' ? lightOn = 0 : lightOn = 1;
EEPROM.write(0, lightOn? 0xFF : 0x00);
if (lightOn) lcd.backlight();
else lcd.noBacklight();
DEBUG_PRINT(F("LCD Backlight: "));
DEBUG_PRINTLN(lightOn ? F("ON") : F("OFF"));
break;
case 1: // "?alarmState="
//
alarmArmed = parseNumber(httpMessage) ? 1 : 0;
DEBUG_PRINTLN(alarmArmed ? F("Alarm is ON") : F("Alarm is OFF"));
break;
case 2: // "?garageState="
//
garageOpen = parseNumber(httpMessage) ? 1 : 0;
DEBUG_PRINTLN(garageOpen ? F("Garage is Open") : F("garage is Closed"));
break;
case 3: // "?guestGarageState="
//
guestGarageOpen = parseNumber(httpMessage) ? 1 : 0;
DEBUG_PRINTLN(guestGarageOpen ? F("Guest garage is Open") : F("Guest garage is Closed"));
break;
case 4: // "?weatherCondition=" // Parse Weather
//
{
strncpy(weatherCondition, parseString(httpMessage), sizeof weatherCondition);
DEBUG_PRINTLN(weatherCondition);
if (strstr(weatherCondition, "%20"))
{
strncpy(weatherCondition, cleanString(weatherCondition, "%20"), sizeof weatherCondition);
DEBUG_PRINTLN(weatherCondition);
}
if (strlen(weatherCondition) < 19)
{
strncpy(weatherCondition, centerString(weatherCondition), sizeof weatherCondition);
}
}
break;
case 5: // "?outsideTemp=" // Parse Outside Temperature
//
outdoorTemp = parseNumber(httpMessage);
break;
case 6: // "?outsideHumid=" // Parse Outside Humidity
//
outdoorHumid = parseNumber(httpMessage);
break;
case 7: // "?airconSetpoint=" // Parse A/C Setpoint
//
airconSetpoint = parseNumber(httpMessage);
break;
case 8: // "?weatherForecast=" // Parse the weather forecast
//
{
strncpy(weatherForecast, parseString(httpMessage), sizeof weatherForecast);
DEBUG_PRINTLN(weatherForecast);
if (strstr(weatherForecast, "+"))
{
strncpy(weatherForecast, cleanString(weatherForecast, "+"), sizeof weatherForecast);
DEBUG_PRINTLN(weatherForecast);
}
if (strlen(weatherForecast) < 19)
{
strncpy(weatherForecast, centerString(weatherForecast), sizeof weatherForecast);
}
}
break;
case 9: //"?messageData=" // Parse display message
//
{
strncpy(customMessage, parseString(httpMessage), sizeof customMessage);
if (strstr(customMessage, "+"))
{
strncpy(customMessage, cleanString(customMessage, "+"), sizeof customMessage);
DEBUG_PRINTLN(customMessage);
}
if (strlen(customMessage) < 19)
{
strncpy(customMessage, centerString(customMessage), sizeof customMessage);
}
Serial.println(myString);
if (strstr(myString, "&time="))
{
DEBUG_PRINTLN(F("Got length marker..."));
char *timePointer = (strstr(myString, "&time="));
timerDuration = atoi(timePointer + 6);
timerStart = millis();
DEBUG_PRINT(F("message length:"));
DEBUG_PRINTLN(timerDuration);
}
else
{
DEBUG_PRINTLN(F("No length marker..."));
timerDuration = 5;
}
if (strstr(myString, "&signal="))
{
DEBUG_PRINTLN(F("Got signal..."));
char *signalPointer = (strstr(myString, "&signal="));
signal = atoi(signalPointer + 8);
timerStart = millis();
DEBUG_PRINT(F("Signal ="));
DEBUG_PRINTLN(signal);
}
else
{
DEBUG_PRINTLN(F("No signal..."));
timerDuration = 5;
}
timerStart = millis();
messageFlag = true;
}
break;
case 10: // "?todayHigh=" // Parse Outside High Temperature
//
todayHigh = parseNumber(httpMessage);
break;
case 11: // "?todayLow=" // Parse Outside Low Temperature
//
todayLow = parseNumber(httpMessage);
break;
case 12: // "?windSpeed=" // Parse Outside Low Temperature
//
windSpeed = parseNumber(httpMessage);
break;
case 13: // "?windDirection" // Parse Outside Low Temperature
//
strncpy(windDirection, parseString(httpMessage), sizeof windDirection);
break;
//
case 14: // "?relayState=" // Get the state of the relay
//
relayState = parseNumber(httpMessage) ? 1 : 0;
//(myString[messagePtr - myString + strlen(messageType[httpMessage])]) == '0' ? relayState = 0 : relayState = 1;
EEPROM.write(1, relayState ? 0xFF : 0x00);
digitalWrite(RELAY_PIN, relayState ? HIGH : LOW);
DEBUG_PRINT(F("Relay Status: "));
DEBUG_PRINTLN(relayState ? F("ON") : F("OFF"));
break;
//
case 15: // "?brightLevel=" // Get the brightness of the LED
//
brightLevel = parseNumber(httpMessage);
brightLevel = map(brightLevel, 0, 100, 0, 255);
DEBUG_PRINT(F("Brite:"));
DEBUG_PRINTLN(brightLevel);
break;
//
case 16: // "?emailCount" // Parse email count
//
emailCount = parseNumber(httpMessage);
break;
default:
{
//Nothing to do here...
}
}
}
//
void buttonPress(int buttonID)
{
DEBUG_PRINTLN(F("buttonPress"));
ShowSockStatus();
if (client.connect(veraServer, 3480)) //starts client connection, checks for connection
{
DEBUG_PRINTLN(F("connected"));
switch (buttonID)
{
case 0: // Toggle LED backlight (?ledStatus=)
//
client.print(F("GET /data_request?"
"id=action&output_format=xml"
"&DeviceNum=111" // <<<<< Set Vera Device Number for LCD backlight
"&serviceId=urn:upnp-org:"
"serviceId:SwitchPower1"
"&action=SetTarget"
"&newTargetValue="));
client.println(lightOn ? F("0") : F("1"));
client.println(F(" HTTP/1.1"
"Connection: close")); //close 1.1 persistent connection
client.println(); //end of get request
delay(1);
client.stop();
break;
//
case 1: // Toggle Relay (relayState)
//
client.print(F("GET /data_request?"
"id=action&output_format=xml"
"&DeviceNum=116" // <<<<< Set Vera Device Number for Relay
"&serviceId=urn:upnp-org:"
"serviceId:SwitchPower1"
"&action=SetTarget"
"&newTargetValue="));
client.print(relayState ? F("0") : F("1"));
client.println(F(" HTTP/1.1"
"Connection: close")); //close 1.1 persistent connection
client.println(); //end of get request
delay(1);
client.stop();
break;
//
case 2: // Toggle Alarm
//
client.print(F("GET /data_request?"
"id=action&output_format=xml"
"&DeviceNum=112" /* <<<<< Set Vera Device Number for Alarm */
"&serviceId=urn:upnp-org:"
"serviceId:SwitchPower1"
"&action=SetTarget"
"&newTargetValue="));
client.print(relayState ? F("0") : F("1"));
client.println(F(" HTTP/1.1"
"Connection: close")); //close 1.1 persistent connection
client.println(); //end of get request
delay(1);
client.stop();
break;
//
case 3: // run lights out scene //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//
client.print(F("GET /data_request?"
"id=action&output_format=xml"
"&DeviceNum=112" /* <<<<< Set Vera Device Number for Alarm */
"&serviceId=urn:upnp-org:"
"serviceId:SwitchPower1"
"&action=SetTarget"
"&newTargetValue="));
client.print(relayState ? F("0") : F("1"));
client.println(F(" HTTP/1.1"
"Connection: close")); //close 1.1 persistent connection
client.println(); //end of get request
delay(1);
client.stop();
break;
//
case 4: // Lower Air Conditioning //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//
client.print(F("GET /data_request?"
"id=action&output_format=xml"
"&DeviceNum=112" /* <<<<< Set Vera Device Number for A/C Control */
"&serviceId=urn:upnp-org:"
"serviceId:SwitchPower1"
"&action=SetTarget"
"&newTargetValue="));
if (airconSetpoint > 72) client.print(airconSetpoint - 1);
else client.print(airconSetpoint - 1);
client.println(F(" HTTP/1.1"
"Connection: close")); //close 1.1 persistent connection
client.println(); //end of get request
delay(1);
client.stop();
break;
//
default:
{
//nothing to do here...
}
}
}
}
//
char *parseString(byte messageNumber)
{
int textLocation = (messagePtr - myString + strlen(messageType[messageNumber]));
myCharBuffer[0] = '\0';
for (byte i = 0; i < 30; i++) // we have room to display only 20 chars, but lets parse 30.
{
if (myString[textLocation + i] != '&')
{
myCharBuffer[i] = myString[textLocation + i];
DEBUG_PRINTLN(myCharBuffer[i]);
}
else
{
DEBUG_PRINTLN(F("got & marker"));
myCharBuffer[i] = '\0';
break;
}
}
DEBUG_PRINTLN(myCharBuffer);
return myCharBuffer;
}
//
char *cleanString(char *targetString, char *searchString)
{
while(strstr(targetString, searchString))
{
char* stringChunk;
stringChunk = strstr(targetString, searchString);
targetString[stringChunk - targetString] = '\0';
strncpy(myCharBuffer, targetString, sizeof myCharBuffer);
strncat(myCharBuffer, " ", sizeof myCharBuffer);
strncat(myCharBuffer, stringChunk + strlen(searchString), sizeof myCharBuffer);
strncpy(targetString, myCharBuffer, sizeof myCharBuffer);
}
return myCharBuffer;
}
//
int parseNumber(byte msgNum)
{
if (strstr(myString, messageType[msgNum]))
{
char *messagePointer;
messagePointer = strtok(myString, "=");
messagePointer = strtok(NULL, "?");
int extractedNumber = atoi(messagePointer);
return extractedNumber;
}
else
{
DEBUG_PRINTLN(F("Fail parseNumber..."));
return -99;
}
}
char *centerString(char *stringToCenter)
{
char centerSpacing[30];
for (byte i = 0; i < ((20 - strlen(myCharBuffer)) / 2); i++)
{
centerSpacing[i] = ' ';
centerSpacing[i+1] = '\0';
}
strncat(centerSpacing, myCharBuffer, sizeof centerSpacing);
strncpy(myCharBuffer, centerSpacing, sizeof myCharBuffer);
return myCharBuffer;
}
void messageTimer()
{
if (millis() - timerStart >= timerDuration * 60000UL)
{
messageFlag = false;
signal = 0;
}
}
//
void fastClearLCD()
{
for (int i = 1; i < 3; i++)
{
lcd.setCursor(0,i);
for (int j = 0; j < 20; j++)
{
lcd.print(F(" "));
}
}
}
//
void timeDate()
{
if (hourFormat12() < 10) lcd.print(F(" "));
lcd.print(hourFormat12());
lcd.print(minute() < 10 ? F(":0") : F(":"));
lcd.print(minute());
lcd.print(isAM() ? "am" : "pm");
lcd.setCursor(11,0);
if (month() < 10) lcd.print(F(" "));
lcd.print(month());
lcd.print(day() < 10 ? F("/0") : F("/"));
lcd.print(day());
lcd.print(F("/"));
lcd.print(year());
}
//
void displayStatus()
{
lcd.setCursor(0,3);
lcd.print(F("A/C:"));
lcd.print(airconSetpoint); //lcd.print(dht.toFahrenheit(dht.getTemperature()), 1);
lcd.print(char(223));
lcd.print(F("F "));
lcd.setCursor(11,3);
if (alarmArmed != 1)
{
lcd.print(F("Not Armed"));
}
else
{
lcd.print(F(" Armed"));
}
}
//
void beepTone()
{
/*
tone(TONE_PIN, 440, 200);
noTone(TONE_PIN);
*/
}
void updateBriteness()
{
if (brightLevel != oldBrightLevel)
{
analogWrite(DIMMER_PIN, brightLevel);
}
oldBrightLevel = brightLevel;
}