Weather Station with Scene Activator!!!


  • Contest Winner

    you will have a lot of fun building this one.

    ADDED: Check out the youtube video.

    This Weather Station will display your indoor and outdoor environmental conditions but features some hot capabilities...

    Send a Short Message to the LCD from Vera by adding another variable and populating it with whatever you like on Vera.

    Using it in the bedroom and you want to turn the backlight off to get a good night sleep? It has that. Just use scenes or PLEG to toggle a variable on the hygrometer device to turn it on or off at specified times.

    Want to trigger a scene or initiate some other action from PLEG? It has that. Just use PLEG or Luup to monitor a variable on the hygrometer device to do cool things like:

    Put your house into Night mode
    Turn off all your lights
    Open your window coverings
    Turn on your Stereo, TV, or even a tea kettle
    Close your Garage door...
    in fact... this little button can be set up to do whatever you can setup in Vera!!!

    I have attached the sketch, so you are just a few tiny components away from having this all on your nightstand or on your desk.

    1: You will need to hardware debounce your switch but can be done with two extra components available for just a few shekels at your local electronics supplier. diagram attached.
    2: Arduino Nano, Uno or Pro Mini.
    3: Hygrometer/thermometer sensor
    4: LCD display I got mine on ebay
    5: A few wires
    6: A Button
    7: Moisture/Temperature sensor like this

    If you plan on building a simple hygrometer/thermometer... build this one instead, and make it really cool and powerful.

    Have Fun!

    *6-May EDIT
    I was having a couple small issues still with the debounce so added it in the sketch. I took the humidity and temp and put into a function and added the call the to setup. I didn't notice that it was delayed quite a bit getting T&H.

    Debounce.pngWeatherDisplayPBSceneController.ino


  • Hero Member

    Grate to see you got it all to work.
    A few comments came to mind.

    Is the hardware debounce realy necesary? Did you try any software solutions?

    Is the sleep mode really useful for this sketch? I'm guessing you do not have any plans to run this one on battery so I see no reason to put it to sleep to save power.


  • Contest Winner

    @korttoma

    thanks for the feedback.

    I found that it needed debouncing. It was getting into a funny state once in a while where it would lock up. it was so easy for me to add the capacitor on my breadboard, so I did it. A software debounce with a timeout on the button press would work too.

    I started with the sketch that had the radio sleep, never sure if I was going to make it battery version or not, so it was left in. It can be yanked out, do you want to try that?

    I really wanted to do two things, get data in, and push data out. I am working on a project that is reliant on both of those so building this was a major step for me.

    I thought it had a nice practical use given the display and the scene trigger. Plus it is so easy to build, I thought i could get some more people to look at it and help make improvements.

    I'm not a software guy, as you can tell from the sketch...


  • Contest Winner

    @hek

    Cool addition the youtube videos right on the MySensors page... nice improvement.


  • Contest Winner

    @korttoma

    FYI I added the debounce to the sketch. Even with the cap I had a few lockups. I noticed I could get multiples and needed it to go away.


  • Contest Winner

    I thought I would post a few photos of the finished device. While I like all things tech, my wife does not. So you can see, I have added to the list of making 'stuff' have a purpose.

    photo 1.JPG photo 2.JPG photo 3.JPG


  • Hero Member

    Hay @BulldogLowell , I'm trying to make use of your sketch for my own project but I ran in to some issue.

    I had trouble finding the right library. I used the "LiquidCrystal_V1.2.1.zip" from here -> https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads

    But I got some errors when compiling sketch. Then I found the library link under the ebay item you referred to and now it seems to work.
    you could mention this in the first post if possible so others don't fall in the same ditch.

    cheers 😉


  • Hero Member

    Now I ran int to the next issue. How do I know which pin the SDA and SCL should be connected to??

    Is it this line that defines it?

    LiquidCrystal_I2C lcd(0x27,20,4);
    

    So what should it be if I'm using a Pro Mini?


  • Hero Member

    I think I found it now... For the Pro Mini it is like this:

    "I2C: A4 (SDA) and A5 (SCL). Support I2C (TWI) communication using the Wire library."

    I was expecting it to be declared somehow in the sketch so I got confused... Well I learned something once again...


  • Contest Winner

    @korttoma hey, glad you have it figured out.

    I have been very busy and haven't been able to check in here for a while:(

    all working now?


  • Hero Member

    Yepp, all working now. Just need to find some time to make my deviec


  • Hero Member

    Hi @BulldogLowell (or anybody else),I'm hoping you could help me with one last thing to finish this project of mine.

    The issue I'm facing is that I do not know how to send a "string" from Vera using luup. Or basically collecting a string from a variable of one device and sending it to a MySensors node. Here is what I tried:

    local text = luup.variable_get("urn:empuk-net:serviceId:SimpleAlarm1","StatusLabel", 319)
    
    luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_3", value=text}, 276)
    

    If I give the variable "text" a numeric value it is sent and received without problems but how the h**l can I send a string??

    Grateful for any help


  • Hero Member

    One step closer:

    local text = "Test"
    
    luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_3", value=text}, 276)
    

    Instantly prints the text "Test" on my display 😄
    Seems like my issue is that I can not get the text from the SimpleAlarm Variable "StatusLable".

    any suggestions?


  • Hero Member

    Solved! 😄

    local status_label = luup.variable_get("urn:upnp-empuk-net:serviceId:SimpleAlarm1", "StatusLabel", 319)
    luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_3", value=status_label}, 276)
    

    Found my answere from the vera forum:
    http://forum.micasaverde.com/index.php/topic,23942.msg168373.html#msg168373


  • Contest Winner

    @korttoma said:

    Solved! 😄

    local status_label = luup.variable_get("urn:upnp-empuk-net:serviceId:SimpleAlarm1", "StatusLabel", 319)
    luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_3", value=status_label}, 276)
    

    Found my answere from the vera forum:
    http://forum.micasaverde.com/index.php/topic,23942.msg168373.html#msg168373

    Hye korttoma,

    Did you finish this project?

    I have a bit of time and thought I would convert my weather station up to the new mySensors version... was wondering if you could share your work...


  • Hero Member

    @BulldogLowell

    Hi Jim, Yeah I finished it. there is a few posts about it over in heks scene controller thread -> http://forum.mysensors.org/topic/446/scene-controller


  • Contest Winner

    Tomas,

    My business has kept me away from this, I guess I didn't notice how far along you took it... brilliant job!

    I'll check in when it's done.

    Thanks mate.

    jim


  • Contest Winner

    Tomas,

    Again, thanks for your example. I have to say, it helped a lot.

    I am however struggling with radio communication it seems and I am wondering at this point what I am doing wrong, having spent a couple hours trying to find my errors.

    Would you mind to take a look for anything you may see:

    #define STATES 7
    #define HUMIDITY_SENSOR_DIGITAL_PIN 4
    #define DEBUG
    
    #ifdef DEBUG
    #define DEBUG_SERIAL(x) Serial.begin(x)
    #define DEBUG_PRINT(x) Serial.print(x)
    #define DEBUG_PRINTLN(x) Serial.println(x)
    #else
    #define DEBUG_SERIAL(x)
    #define DEBUG_PRINT(x) 
    #define DEBUG_PRINTLN(x) 
    #endif
    
    #include <Wire.h>
    #include <Time.h>
    #include <SPI.h>
    #include <MySensor.h>
    #include <LiquidCrystal_I2C.h>
    #include <DHT.h> 
    //
    #define RADIO_ID 11
    #define CHILD_ID_SCENE 3
    //
    LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x20 for a 16 chars and 2 line display
    //
    void (*lcdDisplay[STATES])();
    //
    byte state = 0;
    byte lastState;
    byte timeCounter = 0;
    unsigned long lastTime;
    unsigned long refreshInterval = 3000UL;
    unsigned long lastClockSet;
    boolean isMessage = false;
    float insideTemperature;
    float humidity;
    int OutdoorTemp = -99;
    int OutdoorHumidity = -99;
    int todayHigh = -99; 
    int todayLow = -99;
    String conditions = "Not yet Reported";
    String FreeMessage = "No Message recieved"; //*****
    int ledStatus = 1;// to toggle LCD backlight led
    //int ledLevel = 254;
    boolean buttonPushed = false;
    //
    MySensor gw;
    DHT dht;
    //
    MyMessage msgOn(CHILD_ID_SCENE, V_SCENE_ON);
    MyMessage msgOff(CHILD_ID_SCENE, V_SCENE_OFF);
    MyMessage msgVAR1(CHILD_ID_SCENE, V_VAR1);
    MyMessage msgVAR2(CHILD_ID_SCENE, V_VAR2);
    MyMessage msgVAR3(CHILD_ID_SCENE, V_VAR3);
    MyMessage msgVAR4(CHILD_ID_SCENE, V_VAR4);
    MyMessage msgVAR5(CHILD_ID_SCENE, V_VAR5);
    //
    void setup()  
    { 
      DEBUG_SERIAL(115200);
      DEBUG_PRINTLN(F("Serial started"));
      attachInterrupt(1, PushButton, CHANGE);
      //
      lcdDisplay[0] = lcdDisplay0;
      lcdDisplay[1] = lcdDisplay1;
      lcdDisplay[2] = lcdDisplay2;
      lcdDisplay[3] = lcdDisplay3;
      lcdDisplay[4] = lcdDisplay4;
      lcdDisplay[5] = lcdDisplay5;
      lcdDisplay[6] = lcdDisplay6;
      //
      dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN);
      gw.begin(TempStatus, RADIO_ID);
      gw.sendSketchInfo("WeatherClock", "1.0");
      gw.present(CHILD_ID_SCENE, S_SCENE_CONTROLLER);
      int clockTimer;
      while(timeStatus() != timeSet && clockTimer < 10)
      {
        gw.requestTime(receiveTime);
        Serial.println("getting Time");
        delay(500);
        clockTimer++;
      }
      //
      lcd.init();
      lcd.clear();
      lcd.backlight();
      lcd.setCursor(0, 0);
      lcd.print("Hello World!!!");
      delay(2000);
      lcd.clear();
      lastTime = millis();
    }
    void loop()      
    {
      gw.process();
      if (millis() - lastClockSet >= 60000UL)
      {
        gw.requestTime(receiveTime);
        lastClockSet = millis();
      }
      if (millis() - lastTime >= refreshInterval)
      {
        state++;
        if (state > STATES - 1) state = 0;
        DEBUG_PRINTLN(F("State:")); 
        DEBUG_PRINTLN(state);
        lastTime += refreshInterval;
        getTempHumidity();
      }
      if (state != lastState) 
      {
        fastClear();
        lcdDisplay[state]();
      }
      lastState = state;
      if (buttonPushed)
      {
        activateScene();
      }
    }
    void fastClear()
    {
      lcd.setCursor(0,0);
      lcd.print("                ");
      lcd.setCursor(0,1);
      lcd.print("                ");
    }
    //
    void lcdDisplay0()
    {
      lcd.setCursor(0,0);
      lcd.print(F("Time: "));
      if (hourFormat12() < 10) lcd.print("0");
      lcd.print(hourFormat12());
      lcd.print(":");
      if (minute() < 10) lcd.print("0");
      lcd.print(minute());
      DEBUG_PRINT(F("Time:"));
      DEBUG_PRINTLN(hourFormat12());
      lcd.setCursor(0,1);
      lcd.print(F("Date: "));
      if (month() < 10) lcd.print("0");
      lcd.print(month());
      lcd.print("/");
      if (day() < 10) lcd.print("0");
      lcd.print(day());
      lcd.print("/");
      lcd.print(year());
      DEBUG_PRINTLN(F("Date: 01.11.2014"));
    }
    void lcdDisplay1()
    {
      lcd.setCursor(0,0);
      lcd.print(F("Indoor Temp:"));
      lcd.print(int(insideTemperature));
      lcd.print(char(223));
      DEBUG_PRINT(F("Indoor Temp:")); 
      DEBUG_PRINT(int(insideTemperature)); 
      DEBUG_PRINTLN(F("F"));
      lcd.setCursor(0,1);
      lcd.print("   Humidity:");
      lcd.print(int(humidity));
      lcd.print(F("%"));
      DEBUG_PRINT("   Humidity:");
      DEBUG_PRINT(int(humidity));
      DEBUG_PRINTLN(F("F"));
    }
    void lcdDisplay2()
    {
      lcd.setCursor(0,0);
      lcd.print("Outdoor Temp:"); 
      lcd.print(OutdoorTemp); 
      lcd.print(char(223));
      DEBUG_PRINT(F("Outdoor Temp:"));
      DEBUG_PRINTLN(OutdoorTemp);
      lcd.setCursor(0,1);
      lcd.print(F("    Humidity:")); 
      lcd.print(OutdoorHumidity); 
      lcd.print(F("%"));
      DEBUG_PRINT(F("    Humidity:"));
      DEBUG_PRINTLN(OutdoorHumidity);
    }
    void lcdDisplay3()
    {
      lcd.setCursor(0,0);
      lcd.print(F("Today's HI:"));
      lcd.print(todayHigh); 
      lcd.print(char(223));
      DEBUG_PRINT(F("Today's HIGH"));
      DEBUG_PRINTLN(todayHigh);
      lcd.setCursor(0,1);
      lcd.print(F("        LO:"));
      lcd.print(todayLow); 
      lcd.print(char(223));
      DEBUG_PRINT(F("Today's LOW"));
      DEBUG_PRINTLN(todayLow);
    }
    void lcdDisplay4()
    {
      lcd.setCursor(0,0);
      lcd.print(F("Today's Weather is"));
      DEBUG_PRINTLN(F("Today's Weather:"));
      lcd.setCursor(0,1);
      lcd.print(conditions);
      DEBUG_PRINTLN(F("EXAMPLE"));
    }
    void lcdDisplay5()
    {
      if (isMessage)
      {
        lcd.setCursor(0,0);
        lcd.print(F("****Message****"));
        DEBUG_PRINTLN(F("****Message****"));
        lcd.setCursor(0,1);
        lcd.print(F("Custom Message"));
        DEBUG_PRINTLN(F("Custom Message"));
      }
      else
      {
        lcd.setCursor(0,0);
        lcd.print(F("****Message****"));
        DEBUG_PRINTLN(F("****Message****"));
        lcd.setCursor(0,1);
        lcd.print(F("Have a Nice Day"));
        DEBUG_PRINTLN(F("Have a Nice Day"));
      }
    }
    void lcdDisplay6()
    {
      lcd.setCursor(0,0);
      lcd.print(F(" Weather & Time "));
      DEBUG_PRINTLN(F(" Weather & Time "));
      lcd.setCursor(0,1);
      lcd.print(F("by BulldogLowell"));
      DEBUG_PRINTLN(F("by BulldogLowell")); 
    }
    
    //
    void getTempHumidity()
    {
      insideTemperature = dht.toFahrenheit(dht.getTemperature());
      if (isnan(insideTemperature)) 
      {
        DEBUG_PRINTLN(F("Failed reading temperature from DHT"));
      } 
      humidity = dht.getHumidity();
      if (isnan(humidity)) 
      {
        DEBUG_PRINTLN(F("Failed reading humidity from DHT"));
      } 
    }
    //
    void receiveTime(unsigned long time)
    {
      DEBUG_PRINTLN(F("Time value received: "));
      DEBUG_PRINTLN(time);
      setTime(time);
    }
    //
    void PushButton()
    {
      static unsigned long last_interrupt_time = 0;
      unsigned long interrupt_time = millis();
      if (interrupt_time - last_interrupt_time > 200)
      {
        buttonPushed = true;
      }
      last_interrupt_time = interrupt_time;
    }
    //
    void activateScene()
    {
      DEBUG_PRINTLN(F("ButtonPushed"));
      fastClear();
      for (byte i = 0; i < 10; i++)
      {
        lcd.noBacklight();
        delay(50);
        lcd.backlight();
        delay(50);
      }
      lcd.setCursor(0,0);
      lcd.print(F(" A/C Boost Mode "));
      lcd.setCursor(0,1);
      lcd.print(F("**** ACTIVE ****"));
      delay(2000);
      buttonPushed = false;
      lastTime = millis(); //Reset the timer to even out display interval
    }
    //
    void TempStatus(const MyMessage &message)
    {
      if (message.type == V_VAR1)
      {
        OutdoorTemp = atoi(message.data);
        DEBUG_PRINTLN(F("OutdoorTemp recieved:"));
        DEBUG_PRINTLN(OutdoorTemp);
      }
      if (message.type == V_VAR2)
      {
        OutdoorHumidity = atoi(message.data);
        DEBUG_PRINT(F("OutdoorHumidity recieved:"));
        DEBUG_PRINTLN(OutdoorHumidity);
      }
      if (message.type == V_VAR3)
      {
        todayLow = atoi(message.data);
        DEBUG_PRINT(F("Today's LOW:"));
        DEBUG_PRINTLN(todayLow);
      }
    
      if (message.type == V_VAR4)
      {
        todayHigh = atoi(message.data);
        DEBUG_PRINT(F("Today's HIGH:"));
        DEBUG_PRINTLN(todayHigh);
      }
      if (message.type == V_VAR5)
      {
        conditions = String(message.data);
      }
    }
    

    my error looks like this:

    Serial started
    sensor started, id 11
    send: 11-11-0-0 s=255,c=0,t=17,pt=0,l=3,st=fail:1.4
    send: 11-11-0-0 s=255,c=3,t=6,pt=1,l=1,st=fail:0
    send: 11-11-0-0 s=255,c=3,t=11,pt=0,l=12,st=fail:WeatherClock
    send: 11-11-0-0 s=255,c=3,t=12,pt=0,l=3,st=fail:1.0
    send: 11-11-0-0 s=3,c=0,t=25,pt=0,l=3,st=fail:1.4
    send: 11-11-0-0 s=255,c=3,t=1,pt=0,l=3,st=fail:1.4
    getting Time
    send: 11-11-0-0 s=255,c=3,t=1,pt=0,l=3,st=fail:1.4
    send: 11-11-255-255 s=255,c=3,t=7,pt=0,l=0,st=fail:
    getting Time
    send: 11-11-0-0 s=255,c=3,t=1,pt=0,l=0,st=fail:
    getting Time
    send: 11-11-0-0 s=255,c=3,t=1,pt=0,l=0,st=fail:
    getting Time
    send: 11-11-0-0 s=255,c=3,t=1,pt=0,l=0,st=fail:
    getting Time
    send: 11-11-0-0 s=255,c=3,t=1,pt=0,l=0,st=fail:
    getting Time
    send: 11-11-0-0 s=255,c=3,t=1,pt=0,l=0,st=fail:
    getting Time
    State:
    1
    Indoor Temp:71F
       Humidity:46F
    State:
    2
    Outdoor Temp:-99
        Humidity:-99
    State:
    3
    Today's HIGH-99
    Today's LOW-99
    State:
    

    My lua code server-side is this:

    local temp = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1","CurrentTemperature", 60)
    luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_1", value=temp}, 85)
    
     local humid = luup.variable_get("urn:micasaverde-com:serviceId:HumiditySensor1","CurrentLevel", 63)
    luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_2", value=humid}, 85)
    
    local low = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1","CurrentTemperature", 61)
    luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_3", value=low}, 85)
    
    local high = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1","CurrentTemperature", 62)
    luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_4", value=high}, 85)
    
    local conditions = luup.variable_get("urn:upnp-org:serviceId:Weather1","CurrentTemperature", 59)
    luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_5", value=conditions}, 85)

  • Contest Winner

    I added delays in the lua code and that seemed to help a lot:

    local temp = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1","CurrentTemperature", 60)
    luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_1", value=temp}, 85)
    
    luup.sleep(750)
    
    local humid = luup.variable_get("urn:micasaverde-com:serviceId:HumiditySensor1","CurrentLevel", 63)
    luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_2", value=humid}, 85)
    
    luup.sleep(750)
    
    local low = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1","CurrentTemperature", 61)
    luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_3", value=low}, 85)
    
    luup.sleep(750)
    
    local high = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1","CurrentTemperature", 62)
    luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_4", value=high}, 85)
    
    luup.sleep(750)
    
    local conditions = luup.variable_get("urn:upnp-org:serviceId:Weather1","CurrentTemperature", 59)
    luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_5", value=conditions}, 85)
    

    still struggling with this, however:

    if (message.type == V_VAR5)
    {
      conditions = String(message.data);
      DEBUG_PRINT(F("Received today's Conditions:"));
      DEBUG_PRINTLN(conditions);
    }
    

    not returning the present conditions....


  • Contest Winner

    also noticed that variable5 (V_VAR5) does not show up here (in device 85):

    Screen Shot 2014-11-02 at 1.19.11 AM.png


  • Hero Member

    @BulldogLowell

    I do have all 5 variables listed under my scene-controler device. Do you still get the failed for getting time in your serial print? Seems like you might have "general" communication issues, you have cap on the radio? Try a different power source or temporarily move your device closer to the gateway. I had some similar problems when trying to use the PA+LNA radio module so I switched to a regular one and that one works fine. I wanted to use the PA+LNA version because the device is quite far from GW and I did not think the regular one could handle the distance but it did.

    Thanks for showing me how to add a delay to the lua code btw, I newer figured that out so I only ewer sent two variables at a time. Btw, does the delay affect vera in any way? I thought I read somewhere that the unit does not do anything during sleep.


  • Contest Winner

    Tomas,

    (and I'm opening this up to anyone who knows how to work messages into more than one device )

    well, I figured out the problem of "conditions" which was the wrong serviceId in the lua coding for that variable.

    Regarding the delay, if you luup.sleep() for anything that approaches a second, your Vera will restart 😞 so I figure that the 750ms would be OK. I am concerned about it being incommunicado so often, so I'll probably put the transmissions into different scenes.

    I definitely have a communication issue... and it bothers me a bit. I have all that, capacitors on the antenna, etc. I think I have a bad node and its likely my PhoneyTV. Whenever I 'manually' toggle the lights using the Vera interface, it seems to lock up the gateway.... More on that to come.

    I really appreciate your sharing the code. In retrospect, it seems that the latest mySensors implementation is a lot more elegant with respect to setting up communications like these, but the example helped immensely.

    I'm now tripping up on using variables in the second device: Can I recycle the variables here (e.g. V_VAR1) or must I create another instance of gw?

    MySensor gw;
    DHT dht;
    //
    MyMessage msgOn(CHILD_ID_SCENE, V_SCENE_ON);
    MyMessage msgOff(CHILD_ID_SCENE, V_SCENE_OFF);
    MyMessage msgVAR1(CHILD_ID_SCENE, V_VAR1);// outdoor temperature
    MyMessage msgVAR2(CHILD_ID_SCENE, V_VAR2);// outdoor humidity
    MyMessage msgVAR3(CHILD_ID_SCENE, V_VAR3);//today's low
    MyMessage msgVAR4(CHILD_ID_SCENE, V_VAR4);// today's high
    MyMessage msgVAR5(CHILD_ID_SCENE, V_VAR5);//conditions
    //
    MyMessage lightMsg(CHILD_ID_LED, V_LIGHT);
    //MyMessage msgMOTD(CHILD_ID_LED, V_VAR1); // message of the day//<<<<<<<<<<<<<<<<<
    //MyMessage msgAlarm(CHILD_ID_LED, V_VAR2); // alarm status//<<<<<<<<<<<<<<<<<<<<<<<<
    //MyMessage msgBrite(CHILD_ID_LED, V_VAR3); // led briteness (nice idea!!!!)<<<<<<<<<<<<<<<
    //
    

    setup() bit:

       //
      dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN);
      gw.begin(getVariables, RADIO_ID);
      gw.sendSketchInfo("WeatherClock", "1.0");
      gw.present(CHILD_ID_SCENE, S_SCENE_CONTROLLER);
      gw.present( CHILD_ID_LED, S_LIGHT);
      int clockTimer;
    

    used here:

    void getVariables(const MyMessage &message)
    {  
      if (message.type == V_VAR1)
      {
        OutdoorTemp = atoi(message.data);
        DEBUG_PRINTLN(F("OutdoorTemp recieved:"));
        DEBUG_PRINTLN(OutdoorTemp);
      }
      if (message.type == V_VAR2)
      {
        OutdoorHumidity = atoi(message.data);
        DEBUG_PRINT(F("OutdoorHumidity recieved:"));
        DEBUG_PRINTLN(OutdoorHumidity);
       }
       if (message.type == V_VAR3)
      etc...
    

    any advice?

    best,

    Jim


  • Hero Member

    Did not try it but how about this:

    void getVariables(const MyMessage &message)
        {
            if (message.sensor==CHILD_ID_SCENE){  
                if (message.type == V_VAR1){
                    OutdoorTemp = atoi(message.data);
                    DEBUG_PRINTLN(F("OutdoorTemp recieved:"));
                    DEBUG_PRINTLN(OutdoorTemp);
               }
               if (message.type == V_VAR2){
                   OutdoorHumidity = atoi(message.data);
                   DEBUG_PRINT(F("OutdoorHumidity recieved:"));
                   DEBUG_PRINTLN(OutdoorHumidity);
              }
              if (message.type == V_VAR3)
                  etc...
    
            if (message.sensor==CHILD_ID_LED){  
                if (message.type == V_VAR1){
                    DayMessage = atoi(message.data);
                    DEBUG_PRINTLN(DayMessage);
               }
               if (message.type == V_VAR2){
                   AlarmStatus = atoi(message.data);
                   DEBUG_PRINT(F("House is:"));
                   DEBUG_PRINTLN(AlarmStatus);
              }
              if (message.type == V_VAR3)
                 etc...

  • Contest Winner

    @korttoma

    thanks, I'll give it a shot.

    another method for dispatching messages (with delays in between) from Vera with this type of lua function:

    (thanks to @RexBeckett for the assistance)

    function SendWeatherData(strstep)
    	local step = tonumber(strstep)
    	if step == 1 then
    		local temp = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1","CurrentTemperature", 60)
    		luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_1", value=temp}, 85)
    	elseif step == 2 then
    		local humid = luup.variable_get("urn:micasaverde-com:serviceId:HumiditySensor1","CurrentLevel", 63)
    		luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_2", value=humid}, 85)
    	elseif step == 3 then
    		local low = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1","CurrentTemperature", 61)
    		luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_3", value=low}, 85)
    	elseif step == 4 then
    		local high = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1","CurrentTemperature", 62)
    		luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_4", value=high}, 85)
    	elseif step == 5 then
    		local conditions = luup.variable_get("urn:upnp-micasaverde-com:serviceId:Weather1","Condition", 59)
    		luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_5", value=conditions}, 85)
    	end
    	step = step + 1
    	if step <= 5 then
    		luup.call_delay(1,tostring(step))
    	end
    end
    
    SendWeatherData("1")

  • Hero Member

    wow, don't understand what that lua function does but I'll give it a try. Thanks @RexBeckett


  • Contest Winner

    @korttoma

    "The following code calls the function SendWeatherData immediately and the function calls itself with a one second delay. Each time the function runs, it uses a step counter to chose a value to be read and sent. The step gets incremented on each run until it exceeds five after which the function stops calling itself." - rex

    This way, it shouldn't affect vera's watchdog.

    Rex is really helpful on matters of lua 😉


  • Contest Winner

    @korttoma

    I was thinking that perhaps it may be easier/better to recycle V_VAR1 and transmit messages to the node with a leading char. then have the arduino sort out the message based on the header:

    for example:

    local conditions = luup.variable_get("urn:upnp-micasaverde-com:serviceId:Weather1","Condition", 59)
    conditions = "#" .. conditions
    luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_5", value=conditions}, 85)
    

    then sort and strip out the char arduino-side... you could move a lot more message types through one variable

    new message types need to be hard coded into Arduino and Vera, so if we want to expand the data flow... it becomes easier this way, no? Perhaps there is a better message type to use for this type of effort...

    This device is in our guest house and since I have it open I want to add capabilities like:

    1: Message of the day
    2: quick SMS type of message
    3: alarm clock settable by mobile app
    4: twitter feed

    stuff like that...


  • Contest Winner

    @korttoma

    Tomas, I just wanted to say thanks for the help. My (almost 100% completed) code is here and a couple of videos showing how it works:

    first

    link text

    #define STATES 7
    #define HUMIDITY_SENSOR_DIGITAL_PIN 4
    #define DEBUG
    
    #ifdef DEBUG
    #define DEBUG_SERIAL(x) Serial.begin(x)
    #define DEBUG_PRINT(x) Serial.print(x)
    #define DEBUG_PRINTLN(x) Serial.println(x)
    #else
    #define DEBUG_SERIAL(x)
    #define DEBUG_PRINT(x) 
    #define DEBUG_PRINTLN(x) 
    #endif
    
    #include <avr/pgmspace.h>
    #include <Wire.h>
    #include <Time.h>
    #include <SPI.h>
    #include <MySensor.h>
    #include <LiquidCrystal_I2C.h>
    #include <DHT.h> 
    //
    #define RADIO_ID 11
    #define CHILD_ID_SCENE 3
    #define CHILD_ID_LED 4
    //
    LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
    //
    void (*lcdDisplay[STATES])();
    //
    byte state = 0;
    byte lastState;
    byte timeCounter = 0;
    unsigned long lastTime;
    unsigned long refreshInterval = 3000UL;
    unsigned long lastClockSet;
    boolean isMessage = false;
    float insideTemperature;
    float humidity;
    int OutdoorTemp = -99;
    int OutdoorHumidity = -99;
    int todayHigh = -99; 
    int todayLow = -99;
    String conditions = "Not yet Reported";
    String tomorrowWeather = "Not yet Reported";
    String messageOfTheDay = "**Hello There!**";
    unsigned long motdTimer;
    int ledStatus;// to toggle LCD backlight led
    boolean buttonPushed = false;
    //
    MySensor gw;
    DHT dht;
    //
    MyMessage msgOn(CHILD_ID_SCENE, V_SCENE_ON);
    MyMessage msgOff(CHILD_ID_SCENE, V_SCENE_OFF);
    MyMessage msgVAR1(CHILD_ID_SCENE, V_VAR1);// outdoor temperature
    MyMessage msgVAR2(CHILD_ID_SCENE, V_VAR2);// outdoor humidity
    MyMessage msgVAR3(CHILD_ID_SCENE, V_VAR3);//today's low
    MyMessage msgVAR4(CHILD_ID_SCENE, V_VAR4);// today's high
    MyMessage msgVAR5(CHILD_ID_SCENE, V_VAR5);//conditions
    //
    MyMessage lightMsg(CHILD_ID_LED, V_LIGHT);
    MyMessage msgMOTD(CHILD_ID_LED, V_VAR1); // message of the day
    MyMessage msgAlarm(CHILD_ID_LED, V_VAR2); // alarm status
    MyMessage msgBrite(CHILD_ID_LED, V_VAR3); // led briteness (nice idea!!!!)
    //
    void setup()  
    { 
      DEBUG_SERIAL(115200);
      DEBUG_PRINTLN(F("Serial started"));
      attachInterrupt(1, PushButton, CHANGE);
      //
      lcdDisplay[0] = lcdDisplay0;
      lcdDisplay[1] = lcdDisplay1;
      lcdDisplay[2] = lcdDisplay2;
      lcdDisplay[3] = lcdDisplay3;
      lcdDisplay[4] = lcdDisplay4;
      lcdDisplay[5] = lcdDisplay5;
      lcdDisplay[6] = lcdDisplay6;
      //
      dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN);
      gw.begin(getVariables, RADIO_ID);
      gw.sendSketchInfo("WeatherClock", "1.0");
      gw.present(CHILD_ID_SCENE, S_SCENE_CONTROLLER);
      gw.present( CHILD_ID_LED, S_LIGHT);
      //
      lcd.init();
      lcd.clear();
      lcd.backlight();
      lcd.setCursor(0, 0);
      lcd.print("Syncing Time");
      lcd.setCursor(0, 1);
      int clockCounter = 0;
      while(timeStatus() == timeNotSet && clockCounter < 60)
      {
        gw.process();
        gw.requestTime(receiveTime);
        Serial.println("getting Time");
        delay(1000);
        lcd.print(".");
        clockCounter++;
        if (clockCounter > 16)
        {
          lcd.clear();
          lcd.print(F("**Failed Clock**"));
          lcd.setCursor(0,1);
          lcd.print(F("*Syncronization*"));
          delay(2000);
          break;
        }
      }
      lcd.clear();
      lastTime = millis();
    }
    void loop()      
    {
      gw.process();
      if (millis() - lastClockSet >= 60000UL)
      {
        gw.requestTime(receiveTime);
        lastClockSet = millis();
      }
      if (millis() - lastTime >= refreshInterval)
      {
        state++;
        if (state > STATES - 1) state = 0;
        DEBUG_PRINTLN(F("State:")); 
        DEBUG_PRINTLN(state);
        lastTime += refreshInterval;
        getTempHumidity();
      }
      if (state != lastState) 
      {
        fastClear();
        lcdDisplay[state]();
      }
      lastState = state;
      if (buttonPushed)
      {
        activateScene();
      }
      if (isMessage)
      {
        if (millis() - motdTimer > 86400 * 1000UL)
        {
          isMessage = false;
        }
      }
    }
    void fastClear()
    {
      lcd.setCursor(0,0);
      lcd.print("                ");
      lcd.setCursor(0,1);
      lcd.print("                ");
    }
    //
    void lcdDisplay0()
    {
      lcd.setCursor(0,0);
      lcd.print(F("Time: "));
      if (hourFormat12() < 10) lcd.print("0");
      lcd.print(hourFormat12());
      lcd.print(":");
      if (minute() < 10) lcd.print("0");
      lcd.print(minute());
      if (isAM()) lcd.print(F("am"));
      else lcd.print(F("pm"));
      DEBUG_PRINT(F("Time:"));
      DEBUG_PRINTLN(hourFormat12());
      lcd.setCursor(0,1);
      lcd.print(F("Date: "));
      if (month() < 10) lcd.print("0");
      lcd.print(month());
      lcd.print("/");
      if (day() < 10) lcd.print("0");
      lcd.print(day());
      lcd.print("/");
      lcd.print(year());
      DEBUG_PRINTLN(F("Date: ")); 
      DEBUG_PRINT(month()); 
      DEBUG_PRINT("/"); 
      DEBUG_PRINT(day()); 
      DEBUG_PRINT("/"); 
      DEBUG_PRINTLN(year());
    }
    void lcdDisplay1()
    {
      lcd.setCursor(0,0);
      lcd.print(F(" Indoor Temp:"));
      lcd.print(int(round(insideTemperature)));
      lcd.print(char(223));
      DEBUG_PRINT(F("Indoor Temp:")); 
      DEBUG_PRINT(int(round(insideTemperature))); 
      DEBUG_PRINTLN(F("F"));
      lcd.setCursor(0,1);
      lcd.print("    Humidity:");
      lcd.print(int(round(humidity)));
      lcd.print(F("%"));
      DEBUG_PRINT("   Humidity:");
      DEBUG_PRINT(int(round(humidity)));
      DEBUG_PRINTLN(F("F"));
    }
    void lcdDisplay2()
    {
      lcd.setCursor(0,0);
      lcd.print("Outdoor Temp:"); 
      lcd.print(OutdoorTemp); 
      lcd.print(char(223));
      DEBUG_PRINT(F("Outdoor Temp:"));
      DEBUG_PRINTLN(OutdoorTemp);
      lcd.setCursor(0,1);
      lcd.print(F("    Humidity:")); 
      lcd.print(OutdoorHumidity); 
      lcd.print(F("%"));
      DEBUG_PRINT(F("    Humidity:"));
      DEBUG_PRINTLN(OutdoorHumidity);
    }
    void lcdDisplay3()
    {
      lcd.setCursor(0,0);
      lcd.print(F("Today's High:"));
      lcd.print(todayHigh); 
      lcd.print(char(223));
      DEBUG_PRINT(F("Today's High: "));
      DEBUG_PRINTLN(todayHigh);
      lcd.setCursor(0,1);
      lcd.print(F("         Low:"));
      lcd.print(todayLow); 
      lcd.print(char(223));
      DEBUG_PRINT(F("Today's Low: "));
      DEBUG_PRINTLN(todayLow);
    }
    void lcdDisplay4()
    {
      lcd.setCursor(0,0);
      lcd.print(F("Today's Weather"));
      DEBUG_PRINTLN(F("Today's Weather: "));
      lcd.setCursor(0,1);
      lcd.print(conditions);
      DEBUG_PRINTLN(conditions);
    }
    void lcdDisplay5()
    {
      lcd.setCursor(0,0);
      lcd.print(F("Forcast Tomorrow"));
      DEBUG_PRINTLN(F("Tomorrow's Forecast: "));
      lcd.setCursor(0,1);
      lcd.print(tomorrowWeather);
      DEBUG_PRINTLN(tomorrowWeather);
    }
    void lcdDisplay6()
    {
      if (isMessage)
      {
        lcd.setCursor(0,0);
        lcd.print(F("**NEW  MESSAGE**"));
        DEBUG_PRINTLN(F("****Message****"));
        lcd.setCursor(0,1);
        lcd.print(messageOfTheDay);
        DEBUG_PRINTLN(messageOfTheDay);
        motdTimer = millis();
      }
      else
      {
        lcd.setCursor(0,0);
        lcd.print(F("****Welcome!****"));
        DEBUG_PRINTLN(F("****Message****"));
        lcd.setCursor(0,1);
        lcd.print(F("Have a Nice Day!"));
        DEBUG_PRINTLN(F("Have a Nice Day"));
      }
    }
    //
    void getTempHumidity()
    {
      insideTemperature = dht.toFahrenheit(dht.getTemperature());
      if (isnan(insideTemperature)) 
      {
        DEBUG_PRINTLN(F("Failed reading temperature from DHT"));
      } 
      humidity = dht.getHumidity();
      if (isnan(humidity)) 
      {
        DEBUG_PRINTLN(F("Failed reading humidity from DHT"));
      } 
    }
    //
    void receiveTime(unsigned long time)
    {
      DEBUG_PRINTLN(F("Time value received: "));
      DEBUG_PRINTLN(time);
      setTime(time);
    }
    //
    void PushButton()
    {
      static unsigned long last_interrupt_time = 0;
      unsigned long interrupt_time = millis();
      if (interrupt_time - last_interrupt_time > 200)
      {
        buttonPushed = true;
      }
      last_interrupt_time = interrupt_time;
    }
    //
    void activateScene()
    {
      DEBUG_PRINTLN(F("ButtonPushed"));
      fastClear();
      for (byte i = 0; i < 10; i++)
      {
        lcd.noBacklight();
        delay(50);
        lcd.backlight();
        delay(50);
      }
      lcd.setCursor(0,0);
      lcd.print(F(" A/C Boost Mode "));
      lcd.setCursor(0,1);
      lcd.print(F("**** ACTIVE ****"));
      delay(2000);
      buttonPushed = false;
      lastTime = millis(); //Reset the timer to even out display interval
      ledStatus = gw.loadState(CHILD_ID_LED);
      if (ledStatus > 0)
      {
        lcd.backlight();
      }
      else
      {
        lcd.noBacklight();
      }
    }
    //
    void getVariables(const MyMessage &message)
    {
      if (message.sensor == CHILD_ID_SCENE)
      { 
        if (message.type == V_VAR1)
        {
          OutdoorTemp = atoi(message.data);
          DEBUG_PRINTLN(F("OutdoorTemp recieved:"));
          DEBUG_PRINTLN(OutdoorTemp);
        }
        if (message.type == V_VAR2)
        {
          OutdoorHumidity = atoi(message.data);
          DEBUG_PRINT(F("OutdoorHumidity recieved:"));
          DEBUG_PRINTLN(OutdoorHumidity);
        }
        if (message.type == V_VAR3)
        {
          todayLow = atoi(message.data);
          DEBUG_PRINT(F("Received Today's LOW:"));
          DEBUG_PRINTLN(todayLow);
        }
    
        if (message.type == V_VAR4)
        {
          todayHigh = atoi(message.data);
          DEBUG_PRINT(F("Received Today's HIGH:"));
          DEBUG_PRINTLN(todayHigh);
        }
        if (message.type == V_VAR5)
        {
          String newMessage = String(message.data);
          int locator = newMessage.indexOf("@");
          newMessage = newMessage.substring(0, locator);
          conditions = newMessage;
          DEBUG_PRINT(F("Received today's Conditions:"));
          DEBUG_PRINTLN(conditions);
        }
      }
      if (message.sensor == CHILD_ID_LED)
      {
        if (message.type == V_LIGHT)
        {
          int ledState = atoi(message.data);
          if (ledState > 0)
          {
            lcd.backlight();
          }
          else
          {
            lcd.noBacklight();
          }
        }
        if (message.type == V_VAR1)
        {
          // led briteness (nice idea!!!!)
        }
        if (message.type == V_VAR2)
        {
          // Extended Forecast
          String newMessage = String(message.data);
          int locator = newMessage.indexOf("@");
          newMessage = newMessage.substring(0, locator);
          tomorrowWeather = newMessage;
          DEBUG_PRINT(F("Received Two Day Forecast:"));
          DEBUG_PRINTLN(tomorrowWeather);
        }
        if (message.type == V_VAR3)
        {
          // message of the day
          String newMessage = String(message.data);
          int locator = newMessage.indexOf("@");
          newMessage = newMessage.substring(0, locator);
          messageOfTheDay = newMessage;
          DEBUG_PRINT(F("Received Message of the Day:"));
          DEBUG_PRINTLN(messageOfTheDay);
          isMessage = true;
        }
      }
    }
    

    fixed it


  • Hero Member

    4 spaces in front of every line will be displayed as code. Please update your post. And I could not play the videos either.


  • Contest Winner

    @korttoma

    all fixed. I had to take the text into another editor

    here is the lua

     local temp = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1","CurrentTemperature", 60)
     luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_1", value=temp}, 85)
    
     luup.sleep(750)
    
     local humid = luup.variable_get("urn:micasaverde-com:serviceId:HumiditySensor1","CurrentLevel", 63)
     luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_2", value=humid}, 85)
    
     luup.sleep(750)
    
     local low = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1","CurrentTemperature", 61)
     luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_3", value=low}, 85)
    
     luup.sleep(750)
    
     local high = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1","CurrentTemperature", 62)
     luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_4", value=high}, 85)
    
     luup.sleep(750)
    
     local conditions = luup.variable_get("urn:upnp-micasaverde-com:serviceId:Weather1","Condition", 59)
     luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_5", value=conditions}, 85)
    
     luup.sleep(750)  
    
     local conditions = luup.variable_get("urn:upnp-micasaverde-com:serviceId:Weather1","Forecast.1.Condition", 59)
     luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;4", variableId="VAR_2", value=conditions}, 85)
    
     luup.sleep(750)

  • Hero Member

    Nice job on the sketch Jim, I especially liked the idea with "#define DEBUG". There were allso some other ideas I will be stealing some day when I find time to update my sketch.

    So I guess you did not use the function by @RexBeckett then? I could not get it to work either. I'll try your suggestion with the delays.


  • Contest Winner

    @korttoma

    Thanks for your help and time, you made it a lot easier! I'm trying to write the code for an audience rather than myself so I'm focused more on what I'm putting into the sketch versus just 'getting it to work.' I'm going to get that led dimming next!

    I messed around with the function but lost patience with it,,. I'll get my lua book out and tackle that one rainy day. Meanwhile, I have been using these delays without any issues (no Vera re-starts) and can probably work on shortening the delay times now that I have my Ethernet gateway working so well!!!

    best network performance ever for me since I started with MySensors 🙂

    I keep looking at your scene controller (and the one Henrik did) and I guess I just have to pick one to make!!


  • Hero Member

    It was all my pleasure Jim, it is nice to have someone to exchange ideas with. I take it you mean the dimming of the backlight right? Let me know if you need some details.

    I have also put together a Ethernet GW some time ago but newer got around to take it in to use. And then there was all this about the SPI issue so I guess I need to take it on again at some point. A bit unclear if it will work with the Ethernet board I have anyway.


  • Contest Winner

    @korttoma

    yeah, I meant dimming the LED backlight, a nice touch to your project.

    your ethernet board uses the same Wiznet chipset, so you may want to try what was posted on the other thread. I got frustrated with my Serial gateway losing its communication with Vera.



  • Hello, I am building this same thing and have used the sketch and luup code above thanks to @BulldogLowell & @korttoma!

    I am having issues though pulling a variable to send to the lcd screen via luup. I put this device under the Light Variable 4 code is at the bottom of the Lua below. This device is another mysensor that is visible in Vera so I am not sure what is wrong, any help someone could provide would be great.

    Luup code:

    local temp = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1","CurrentTemperature", 7)
    luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_1", value=temp}, 103)
    luup.sleep(750)
    local humid = luup.variable_get("urn:micasaverde-com:serviceId:HumiditySensor1","CurrentLevel", 10)
    luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_2", value=humid}, 103)
    luup.sleep(750)
    local low = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1","CurrentTemperature", 61)
        luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_3", value=low}, 103)
     luup.sleep(750)
    local high = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1","CurrentTemperature", 62)
    luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_4", value=high}, 103)
    luup.sleep(750)
    local conditions = luup.variable_get("urn:upnp-micasaverde-com:serviceId:Weather1","Condition", 6)
    luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_5", value=conditions}, 103)
    luup.sleep(750)  
    local conditions = luup.variable_get("urn:upnp-micasaverde-com:serviceId:Weather1","Forecast.1.Condition", 59)
    luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;4", variableId="VAR_2", value=conditions}, 103)
     luup.sleep(750)
      local conditions = 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}, 103)
      luup.sleep(750)
    

    Sketch: weather_station.ino


  • Contest Winner

    @cleight said:

    local conditions = 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}, 103)
    luup.sleep(750)

    it looks like you are making a call for the variable "conditions" and passing "HTTemp" in the two last commands. here:

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

    that could be it...



  • @BulldogLowell I was under the impression that the value could be named what ever you want, is that not the case? changing the value to temp should fix the issue you think?


  • Contest Winner

    @cleight said:

    changing the value to temp should fix the issue you think?

    now I am confused.

    You are (it seems to me) retreiving a value from device 98, no?

    You are then writing that to device 103, at VAR_4... yes?

    please clarify for me.

    (reference the snippet of code in my last post)



  • @BulldogLowell Thanks for pointing that out, I actually need to write VAR4 to device 105. I have made the necessary changes but still isn't working.

     local temp = luup.variable_get("urn:upnp-   org:serviceId:TemperatureSensor1","CurrentTemperature", 7)
     luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1",  "SendCommand", {radioId="11;3", variableId="VAR_1", value=temp}, 103)
    luup.sleep(750)
    local humid = luup.variable_get("urn:micasaverde-com:serviceId:HumiditySensor1","CurrentLevel", 10)
    luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_2", value=humid}, 103)
     luup.sleep(750)
     local low = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1","CurrentTemperature", 8)
     luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_3", value=low}, 103)
     luup.sleep(750)
     local high = luup.variable_get("urn:upnp-org:serviceId:TemperatureSensor1","CurrentTemperature", 9)
     luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_4", value=high}, 103)
     luup.sleep(750)
     local conditions = luup.variable_get("urn:upnp-micasaverde-com:serviceId:Weather1","Condition", 6)
     luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;3", variableId="VAR_5", value=conditions}, 103)
     luup.sleep(750)  
     local conditions = luup.variable_get("urn:upnp-micasaverde-com:serviceId:Weather1","Forecast.1.Condition", 6)
     luup.call_action("urn:upnp-arduino-cc:serviceId:arduino1", "SendCommand", {radioId="11;4", variableId="VAR_2", value=conditions}, 105)
      luup.sleep(750)
      local temp = 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)

  • Hero Member

    You are stil not giving HTtemp any value!



  • @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


  • Hero Member

    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)


  • @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.


  • Contest Winner

    @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



  • @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?


  • Contest Winner

    @cleight

    like this?

    link text



  • @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.


  • Contest Winner

    @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();
      }
    }
    


  • @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.


  • Contest Winner

    @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...



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


 

350
Online

7.5k
Users

8.4k
Topics

90.4k
Posts