Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. My Project
  3. Weather Station with Scene Activator!!!

Weather Station with Scene Activator!!!

Scheduled Pinned Locked Moved My Project
51 Posts 3 Posters 30.2k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • korttomaK Offline
    korttomaK Offline
    korttoma
    Hero Member
    wrote on last edited by
    #40

    You are stil not giving HTtemp any value!

    • Tomas
    C 1 Reply Last reply
    0
    • korttomaK korttoma

      You are stil not giving HTtemp any value!

      C Offline
      C Offline
      cleight
      wrote on last edited by cleight
      #41

      @korttoma Can you elaborate on HTTemp not getting any value? I am not following what HTTemp should be either changed to or how to give it value.

      Here is a snippet of the debug window:
      Indoor Temp:20F
      Hot Tub:0Fsend: 11-11-0-0 s=255,c=3,t=1,pt=0,l=0,st=ok:
      read: 0-0-11 s=255,c=3,t=1,pt=0,l=10:1423665003
      Time value received:
      1423665003

      1 Reply Last reply
      0
      • korttomaK Offline
        korttomaK Offline
        korttoma
        Hero Member
        wrote on last edited by
        #42

        Try replacing the last section with this:

        local HTTemp = luup.variable_get("urn:upnp-micasaverde-com:serviceId:TemperatureSensor1","CurrentTemperature", 98)
        luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;4", variableId="VAR_4", value=HTTemp}, 105)
        luup.sleep(750)
        
        • Tomas
        C 1 Reply Last reply
        1
        • korttomaK korttoma

          Try replacing the last section with this:

          local HTTemp = luup.variable_get("urn:upnp-micasaverde-com:serviceId:TemperatureSensor1","CurrentTemperature", 98)
          luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;4", variableId="VAR_4", value=HTTemp}, 105)
          luup.sleep(750)
          
          C Offline
          C Offline
          cleight
          wrote on last edited by
          #43

          @korttoma said:

          local HTTemp = luup.variable_get("urn:upnp-micasaverde-com:serviceId:TemperatureSensor1","CurrentTemperature", 98)
          luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;4", variableId="VAR_4", value=HTTemp}, 105)

          I tried this luup code and get the same results, at this point I have to believe it is an issue in my sketch as I have pushed a known working device to 105, VAR_4 and it isn't working either.

          BulldogLowellB 1 Reply Last reply
          0
          • C cleight

            @korttoma said:

            local HTTemp = luup.variable_get("urn:upnp-micasaverde-com:serviceId:TemperatureSensor1","CurrentTemperature", 98)
            luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;4", variableId="VAR_4", value=HTTemp}, 105)

            I tried this luup code and get the same results, at this point I have to believe it is an issue in my sketch as I have pushed a known working device to 105, VAR_4 and it isn't working either.

            BulldogLowellB Offline
            BulldogLowellB Offline
            BulldogLowell
            Contest Winner
            wrote on last edited by BulldogLowell
            #44

            @cleight

            check your return with the equivalent http command in this format in your browser:

            http://ip_address:3480/data_request?id=variableget&DeviceNum=98&serviceId=urn:upnp-micasaverde-com:serviceId:TemperatureSensor1&Variable=CurrentTemperature

            just replace ip_address with your vera's IP address...

            look here

            C 1 Reply Last reply
            0
            • BulldogLowellB BulldogLowell

              @cleight

              check your return with the equivalent http command in this format in your browser:

              http://ip_address:3480/data_request?id=variableget&DeviceNum=98&serviceId=urn:upnp-micasaverde-com:serviceId:TemperatureSensor1&Variable=CurrentTemperature

              just replace ip_address with your vera's IP address...

              look here

              C Offline
              C Offline
              cleight
              wrote on last edited by
              #45

              @BulldogLowell Thanks for this information this helped me to get the variables I needed to pull the alarm status, I also fixed the above issue with not being able to pull the Temperature from the device I was trying to. Once I tweak my code and adjust the display the way I like I will post the final sketch and a video.

              One more thing how easy would it be to have semi-static data, like the temp or time in one corner of the screen while it is cycling through all the screens?

              BulldogLowellB 1 Reply Last reply
              0
              • C cleight

                @BulldogLowell Thanks for this information this helped me to get the variables I needed to pull the alarm status, I also fixed the above issue with not being able to pull the Temperature from the device I was trying to. Once I tweak my code and adjust the display the way I like I will post the final sketch and a video.

                One more thing how easy would it be to have semi-static data, like the temp or time in one corner of the screen while it is cycling through all the screens?

                BulldogLowellB Offline
                BulldogLowellB Offline
                BulldogLowell
                Contest Winner
                wrote on last edited by
                #46

                @cleight

                like this?

                link text

                C 1 Reply Last reply
                1
                • BulldogLowellB BulldogLowell

                  @cleight

                  like this?

                  link text

                  C Offline
                  C Offline
                  cleight
                  wrote on last edited by
                  #47

                  @BulldogLowell yes like that example, I posted on you other thread a week or so ago. I will see if I can put my current sketch and parts of that one together to get it how I want.

                  BulldogLowellB 1 Reply Last reply
                  0
                  • C cleight

                    @BulldogLowell yes like that example, I posted on you other thread a week or so ago. I will see if I can put my current sketch and parts of that one together to get it how I want.

                    BulldogLowellB Offline
                    BulldogLowellB Offline
                    BulldogLowell
                    Contest Winner
                    wrote on last edited by
                    #48

                    @cleight

                    I have it all in here, if you are patient enough to get through all this...

                    look at the centerString() function to help you center your weather conditions... you can ignore cleanString() cuz MySensors handles spaces in the strings... my Ethernet version needs to handle spaces differently.

                    look at updateLCD() and its called functions.

                    let me know if you have questions... I'm going to post this project later, though not strictly a MySensors implementation. ;)

                    /*
                     Vera Auxilliary Controller a.k.a. Arduino/Vera Ethernet Device
                     
                     December, 2014
                     
                     Version .98
                     
                     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 brightness
                     * 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
                     * Displays unread email count
                     
                     INSTRUCTIONS:
                     
                    HARDWARE:
                     * Enter your Vera's IP address where indicated
                     * Attach a 20x4 LCD display using I2C, remove the jumper from the backlight led and connect it to DIMMER_PIN (pwm pin)
                     * Connect DHT11 to Vcc, ground and DHT_SENSOR_PIN
                     * Connect optional Pushbuttons to your ACTION pins
                     * That's IT!!!
                     Software:
                     * Scroll down this sketch and enter your preferences of mac and IP addresses, pinouts, etc.
                     * There are multiple debug serial prints that can be monitored to assure that it is operating properly.  to enable DEBUG printing, uncomment accordingly
                     * 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
                    
                     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"
                    //
                    // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<  Setup Area
                    //
                    //#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 8                 // Relay control output
                    #define DISPLAY_UPDATE_TIME 3000UL  // 3.0 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 }; //<<<<<<<<<<<<<<< Select your arduino's mac address
                    IPAddress ip(192,168,1,50); // <<<<<<<<<<<<<<<<<<<<<<<<<< Select your arduino's IP address if not using DHCP
                    //
                    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;
                    byte veraServer[] = { 
                      192,168,1,59 }; //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Vera's IP Address
                    //
                    const char *dayOfWeek[] = { 
                      "       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);
                      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);
                      analogWrite(DIMMER_PIN,255);
                      startupSyncVera();
                    }
                    //
                    void loop()
                    {
                      updateLCD();
                      getNTPtime();
                      webControl();
                      messageTimer();
                      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() - 1]);
                          lcd.print(dayOfWeek[weekday() - 1]);
                          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 && brightLevel > 0)
                          {
                            for (int i = 0; i < 20; i++)
                            {
                              digitalWrite(DIMMER_PIN, HIGH);
                              delay(50);
                              digitalWrite(DIMMER_PIN,LOW);
                              delay(50);
                            }
                            analogWrite(DIMMER_PIN,brightLevel);
                          }
                          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() - 1()]);
                      }
                      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>&copy; 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);
                        if (brightLevel != oldBrightLevel)
                        {
                          analogWrite(DIMMER_PIN, brightLevel);
                        }
                        oldBrightLevel = 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:  // adjust backlight brightness down
                          {
                          int brite = brightLevel;
                          brite -= 25;
                          if (brite < 0) brite = 0;
                          client.print(F("GET /data_request?"
                            "id=action&output_format=xml"
                            "&DeviceNum=111"
                            "&serviceId=urn:upnp-org:"
                            "serviceId:Dimmer1"
                            "&action=SetTarget"
                            "&newTargetValue="));
                          client.println(brite);
                          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:  // adjust backlight brightness up
                          {
                          int brite = brightLevel;
                          brite += 25;
                          if (brite > 255) brite = 255;
                          client.print(F("GET /data_request?"
                            "id=action&output_format=xml"
                            "&DeviceNum=111"
                            "&serviceId=urn:upnp-org:"
                            "serviceId:Dimmer1"
                            "&action=SetTarget"
                            "&newTargetValue="));
                          client.println(brite);
                          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(9,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(emailCount < 0? 0 : emailCount);
                      if (emailCount == 1)
                      {
                        lcd.print(F(" eMail   "));
                      }
                      else
                      {
                        lcd.print(F(" eMails   "));
                      }
                      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 startupSyncVera() // RUNS A VERA SCENE ON STARTUP... Push the dimmer value from this scene
                    {
                      if (client.connect(veraServer, 3480)) //starts client connection, checks for connection
                      {  
                        DEBUG_PRINTLN(F("asking for dimmer level"));
                        client.println(F("GET /data_request?id=action&output_format=xml&serviceId=urn:micasaverde-com:serviceId:HomeAutomationGateway1&action=RunScene&SceneNum=40"
                        " HTTP/1.1"));
                        client.println(F("Connection: close"));  //close 1.1 persistent connection  
                        client.println(); //end of get request
                        delay(1);
                        client.stop();
                      }
                    }
                    
                    C 1 Reply Last reply
                    0
                    • BulldogLowellB BulldogLowell

                      @cleight

                      I have it all in here, if you are patient enough to get through all this...

                      look at the centerString() function to help you center your weather conditions... you can ignore cleanString() cuz MySensors handles spaces in the strings... my Ethernet version needs to handle spaces differently.

                      look at updateLCD() and its called functions.

                      let me know if you have questions... I'm going to post this project later, though not strictly a MySensors implementation. ;)

                      /*
                       Vera Auxilliary Controller a.k.a. Arduino/Vera Ethernet Device
                       
                       December, 2014
                       
                       Version .98
                       
                       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 brightness
                       * 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
                       * Displays unread email count
                       
                       INSTRUCTIONS:
                       
                      HARDWARE:
                       * Enter your Vera's IP address where indicated
                       * Attach a 20x4 LCD display using I2C, remove the jumper from the backlight led and connect it to DIMMER_PIN (pwm pin)
                       * Connect DHT11 to Vcc, ground and DHT_SENSOR_PIN
                       * Connect optional Pushbuttons to your ACTION pins
                       * That's IT!!!
                       Software:
                       * Scroll down this sketch and enter your preferences of mac and IP addresses, pinouts, etc.
                       * There are multiple debug serial prints that can be monitored to assure that it is operating properly.  to enable DEBUG printing, uncomment accordingly
                       * 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
                      
                       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"
                      //
                      // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<  Setup Area
                      //
                      //#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 8                 // Relay control output
                      #define DISPLAY_UPDATE_TIME 3000UL  // 3.0 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 }; //<<<<<<<<<<<<<<< Select your arduino's mac address
                      IPAddress ip(192,168,1,50); // <<<<<<<<<<<<<<<<<<<<<<<<<< Select your arduino's IP address if not using DHCP
                      //
                      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;
                      byte veraServer[] = { 
                        192,168,1,59 }; //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Vera's IP Address
                      //
                      const char *dayOfWeek[] = { 
                        "       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);
                        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);
                        analogWrite(DIMMER_PIN,255);
                        startupSyncVera();
                      }
                      //
                      void loop()
                      {
                        updateLCD();
                        getNTPtime();
                        webControl();
                        messageTimer();
                        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() - 1]);
                            lcd.print(dayOfWeek[weekday() - 1]);
                            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 && brightLevel > 0)
                            {
                              for (int i = 0; i < 20; i++)
                              {
                                digitalWrite(DIMMER_PIN, HIGH);
                                delay(50);
                                digitalWrite(DIMMER_PIN,LOW);
                                delay(50);
                              }
                              analogWrite(DIMMER_PIN,brightLevel);
                            }
                            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() - 1()]);
                        }
                        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>&copy; 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);
                          if (brightLevel != oldBrightLevel)
                          {
                            analogWrite(DIMMER_PIN, brightLevel);
                          }
                          oldBrightLevel = 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:  // adjust backlight brightness down
                            {
                            int brite = brightLevel;
                            brite -= 25;
                            if (brite < 0) brite = 0;
                            client.print(F("GET /data_request?"
                              "id=action&output_format=xml"
                              "&DeviceNum=111"
                              "&serviceId=urn:upnp-org:"
                              "serviceId:Dimmer1"
                              "&action=SetTarget"
                              "&newTargetValue="));
                            client.println(brite);
                            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:  // adjust backlight brightness up
                            {
                            int brite = brightLevel;
                            brite += 25;
                            if (brite > 255) brite = 255;
                            client.print(F("GET /data_request?"
                              "id=action&output_format=xml"
                              "&DeviceNum=111"
                              "&serviceId=urn:upnp-org:"
                              "serviceId:Dimmer1"
                              "&action=SetTarget"
                              "&newTargetValue="));
                            client.println(brite);
                            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(9,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(emailCount < 0? 0 : emailCount);
                        if (emailCount == 1)
                        {
                          lcd.print(F(" eMail   "));
                        }
                        else
                        {
                          lcd.print(F(" eMails   "));
                        }
                        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 startupSyncVera() // RUNS A VERA SCENE ON STARTUP... Push the dimmer value from this scene
                      {
                        if (client.connect(veraServer, 3480)) //starts client connection, checks for connection
                        {  
                          DEBUG_PRINTLN(F("asking for dimmer level"));
                          client.println(F("GET /data_request?id=action&output_format=xml&serviceId=urn:micasaverde-com:serviceId:HomeAutomationGateway1&action=RunScene&SceneNum=40"
                          " HTTP/1.1"));
                          client.println(F("Connection: close"));  //close 1.1 persistent connection  
                          client.println(); //end of get request
                          delay(1);
                          client.stop();
                        }
                      }
                      
                      C Offline
                      C Offline
                      cleight
                      wrote on last edited by
                      #49

                      @BulldogLowell I finally am getting somewhere with my project, however after some time working with it I have found that I would rather send data from other Arduino sensors to the LCD project directly rather than send it to Vera and then run a piece of Luup code every 15 minutes to then populate the variables the screen uses. I have looked all over the forums and cannot seem to find the right bit on information on MySensors 1.4 and how to send data from one node to the other, any assistance would be great.

                      BulldogLowellB 1 Reply Last reply
                      0
                      • C cleight

                        @BulldogLowell I finally am getting somewhere with my project, however after some time working with it I have found that I would rather send data from other Arduino sensors to the LCD project directly rather than send it to Vera and then run a piece of Luup code every 15 minutes to then populate the variables the screen uses. I have looked all over the forums and cannot seem to find the right bit on information on MySensors 1.4 and how to send data from one node to the other, any assistance would be great.

                        BulldogLowellB Offline
                        BulldogLowellB Offline
                        BulldogLowell
                        Contest Winner
                        wrote on last edited by
                        #50

                        @cleight

                        I've got a vera-centric build, so I haven't messed with this in a while, but there are send( ) and request( ) functions in the API... have you explored that yet?

                        I would have the remote sensor repeat every so often (e.g. one minute) and add the that node's specifics to the incoming message callback function for the display device.

                        We should have an example of Node-to-Node communication in the examples...

                        C 1 Reply Last reply
                        0
                        • BulldogLowellB BulldogLowell

                          @cleight

                          I've got a vera-centric build, so I haven't messed with this in a while, but there are send( ) and request( ) functions in the API... have you explored that yet?

                          I would have the remote sensor repeat every so often (e.g. one minute) and add the that node's specifics to the incoming message callback function for the display device.

                          We should have an example of Node-to-Node communication in the examples...

                          C Offline
                          C Offline
                          cleight
                          wrote on last edited by
                          #51

                          @BulldogLowell I agree I think it would benefit the community to have a node to node example on the site.

                          1 Reply Last reply
                          0
                          Reply
                          • Reply as topic
                          Log in to reply
                          • Oldest to Newest
                          • Newest to Oldest
                          • Most Votes


                          14

                          Online

                          11.7k

                          Users

                          11.2k

                          Topics

                          113.1k

                          Posts


                          Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                          • Login

                          • Don't have an account? Register

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • MySensors
                          • OpenHardware.io
                          • Categories
                          • Recent
                          • Tags
                          • Popular