Project tutorial

Home Automation with Self-learning 433 Power Switches © LGPL

The project itself was based on a static sketch running for several months in 2016 with a handful of lights following sunrise/-set.

  • 2,869 views
  • 0 comments
  • 11 respects

Components and supplies

Apps and online services

About this project

The move to Cayenne MQTT

A required update! When I added some new switches in December 2017 I slowly reaslised I needed to move to the MQTT environment of Cayenne. This was in a way a blessing in disguise; the sketch I used at that moment had sometimes difficulties to connect (and restarted often duing the timer loop). It was also a good moment to make some additional changes:

  • So the 'biggest' change was to move from the Arduino Library to the Cayenne MQTT environment; in the sketch use channels over virtual 'pins' and rebuilding the dashboard. And here is one of the real good benefits of MQTT; sensor appears automatic in the dashboard. Because I do for switches (=custom widget ‘button’ as actuator) also some displaywrites to reflect present state of a switch it is possible you need to delete the automatic create ones
  • Replaced the RST-sensor with online query to the NTP-server
  • Refreshed Summer Time (DST) check based upon the NTP data and used in Tardis routine for Sunrise and sunset
  • Added DHT22-sensor
  • Added Wi-Fi signal and system uptime information on the dashboard
  • Added obsolete scheduling routines in "some Rube Goldberg logic" style (whatever that is) to tackle present misbehavior of scheduling and triggers. Hope at some point in time this part is really obsolete and we can relay on Cayenne's Triggers and Scheduling!!!! The dashboard has an actuator to (de-)activate this.

Please do not consider this as completely original work. I work according to the C&P-T&E principles. What do I want, get inspired by others try to implement them in my own projects.

I try to document as best as possible, references, keeps things together and sometime simplify. I know for myself that a few weeks later I might be clueless about something I have done or were I found it and at that moment; some additional info in the sketch can be very helpful at that point. Any suggestions are welcome.

Learnings of this version.

  • Invert logic is simply achieved by ! (no need for a routine)
  • For sunset/sunrise small trick to see if we are in DST (summertime)

The MQTT environment feels a bit ‘slower’ than the Arduino version but is surely more stable. So the downside can be that the action of the actuator is not directly done/visible. But where is this problem? We need to realise a lot of ‘middleware’ is between the request and action: finger – WiFi – lan – wan – Cayenne server (MQTT broker) – wan – lan – wifi – sensor – action.

Next version might be with an ESP32;)

About This Project (the old story)

This is my 2nd project with Cayenne. First published in December 2016. I revised it a bit and also corrected a stupid error in the DST-calculation which only became evident when DST started in 2017. The project itself is based on a static sketch running for several months now where a handful of lights follow sunset to go on; major objective here is that there is no need to adjust time over the months (the farther you are away from the equator, the more you will require this). In December 2016 I converted this to Cayenne because I was missing manual controls (or have to use three different remotes), the sketch does not need to be updated when switches are added because they can be programmed from inside the dashboard and on/off actions can be scheduled and/or triggered!

What's Connected

See the "things" section. Off course you only need the Wemos or the UNO+W5100. There are also a lot of Self-learning power switches and I surely will not promise you they all will work with the Flamingo library. Finding out the proper codes will be cumbersome but I found them too.

Remarks:

  • 433MHz Wireless Transmitter will improve if you add an antenna. Still need to solder the included cupper one but about 17 cm will do the trick too.
  • How to recognise a self-learning switch? Self-learning switches do not have any dipswitches but when plugged in power you get some time to program them with either the supplied remote or now with Cayenne. In the Netherlands the switches are sold with names like Flamingo F500, some “klik aan klik uit" variants, Elro 8-serie and the cheapest from Action 3 for 10 euro. The Action switches are also easy because they give you more time for programming the switch.
  • Older 433 switches will have dip, rotery switches and depending on the brand require different libraries to operate.

For the older 433 switches and a different variant of self-learning switches use the library from Randy Simons (other libraries are available). With the NewRemoteTransmitter you will be able to address the Flamingo SF-501PWD outdoor switch.

Some Functionality Explained:

  • Flamingo library is created by others who invested their time to understand what kind of 433 sequences the remote controls were sending to activate a switch. These codes are converted again by someone into the flamingo library. My contribution is limited with some simplification to make this library more Cayenne friendly; It used to have a remote-unit key, I converted it to (virtual) single code key so it can respond on the Cayenne’s’ virtual channel V0 to V7. More codes might be available.
  • Time library. Why use the time library? In the old project the device was instable this is solved with the timer function which only communicates with the Cayenne server in a 10 seconds interval. In this section the present time (V20) is calculated, DST, sunrise (V21), sunset V22) and “night time” (V25).
  • The RTC-module (DS3231) is added for two reasons. • Unaware if the time can be retrieved from Cheyenne • Use the alarm function for DST (second only) Some lines are set to comment, you can use this section to reset your RTC-module and/or to set a new time. Please note that the present time will be about 20 seconds of (differences caused due time lapse between the compile time and actual reset of RTC-time in sketch, you might want to program the RTC-time in a simple sketch.
  • Display of the values: How to display the sunset and sunrise time as best as possible? In the absence of the colon make a point (Amerika likely sees a comma).
  • Daylight Saving Time (DST) for CET.
  • Sunset/Sunrise calculation and display; The Sunset/Sunrise is calculated with “TimeLord tardis” in combination with the GPS location. It also uses the variable “DST_check” to add hours for the DST-offset in summer.
  • Offset Slider creates a delay and lights can be switch e.g. 30 minutes after sunset (or 30 minutes before sunrise).

Dashboard Screenshots

The dashboard has the following items:

  • V0 to V7; 8 switches for self learning devices
  • V15 and V16; two older elro-switches (dip-switches)
  • Time displayed; sunset, sunrise, present time (redundent info) which are used to see if we are in "night time or "day time".
  • Offset slider to influence the extended night time (ignore that it is in degrees).
  • Offset; The result of this offset slider (redundent)

Scheduling, Triggers & Alerts

Basicly this is nothing nothing more than switching lights on and off. When do you want to do this?

  • Lights on at sunset
  • Lights on at x minutes before sunset
  • Lights off at midnight or so
  • Lights off at sunrise
  • Lights off at x minutes before sunrise

Video

Video of project f.y.i. Using my Android phone only for display here. With my desktop I select the widget, this will result that the status of the widget and the light on the switch will change.

Small Improvements over time

Added a slider to the device in order to have more flexibility in the twilight zone. Ok, think a bit more explanation might be justified. In the Netherlands the sunset is changing daily with about 3 minutes (or so). But when the sun sets it is not dark yet! So I wanted to introduce an offset to this sunset. The perfect way to do this is to add a slider and adjust the sunset with for example 30 minutes and lights can be switched automatic 30 minutes after sunset. The actual automation is done with a trigger (V24). The offset widget (V19) is in principle obselete but in the past useful to see if values came through truely.

if (time_now >= time_sunset + time_offset || time_now <= time_sunrise - time_offset) { //delay for twilight offset set by slider
    Cayenne.virtualWrite(V24, 1);    
} else {
    Cayenne.virtualWrite(V24, 0); 

Another very, very small improvement was achieved when I realized something better with "invert logic". Benefit is mostly a more condensed sketch (because this part is repeated 8 times). Especially the UNO+W5100 combination is lacking memory with this sketch. This:

CAYENNE_IN(V0) // action switch lamp V0
{
if (getValue.asInt() == 1) {
    Flamingo_Send(V0, 0); // ON
} else {
    Flamingo_Send(V0, 1); // OFF
}

is replayced by:

CAYENNE_IN(V0) // action switch lamp V0
{
Flamingo_Send(V0, getValue.asInt()); // ON or OFF
}

is the MQTT-version this is replaced by:

CAYENNE_IN(0) // action switch lamp 0
{
Flamingo_Send(0, !getValue.asInt()); // ON or OFF
}

Please observe the "!" before getvalue to invert result!

Some remarks

Cayenne/Mydevices is also evolving and solutions (read workarounds) in this sketch maybe integrated in the Cayenne/Mydevices functionality.

Dec '17 Sketches, etc updated to reflect latest MQTT version!

Code

Main SketchArduino
Compile this sketch to your wemos; likely you need to install additional file manager in Arduino application
 /*
 * Initally based upon a sketch from Nick Gammon
 * Collected various values for the switches and adapted for Cayenne By Wouter-Jan 
 * Info DS323-hardware: http://www.dx.com/p/ds3231-at24c32-iic-high-precision-real-time-clock-module-for-arduino-3pcs-408743
 * Info Wemos D1 R2: https://wiki.wemos.cc/tutorials:get_started:get_started_in_arduino\
 *                   http://arduino.esp8266.com/versions/1.6.5-947-g39819f0/doc/reference.html
 * Install additional Device Manager for Wemos: file - preferences - additional boardmanager: http://arduino.esp8266.com/stable/package_esp8266com_index.json
 * 
 * Some additional useful links:
 * http://www.instructables.com/id/Programming-the-WeMos-Using-Arduino-SoftwareIDE/
 * http://community.mydevices.com/t/data-types-for-cayenne-mqtt-api/3714
 * http://community.mydevices.com/t/converting-cayenne-arduino-library-sketches-to-cayenne-mqtt-arduino/5759
 * https://github.com/myDevicesIoT/Cayenne-MQTT-ESP8266
 * https://roboticboyer.files.wordpress.com/2016/03/wemos_pins_00.pdf
 * https://opencircuit.nl/ProductInfo/1000178/WeMos-D1-Handleiding.pdf
 * 
Versions
0.01 Moved from the Arduino Library to Cayenne MQTT
  Replaced the RST-sensor with online query with the NTP-server; refreshed Summer Time (DST) check based upon the NTP data and used in Tardis routine for Sunrise and sunset
  Added DHT22-sensor: 1st working MQTT example
  Added Wi-Fi signal and system uptime information on the dashboard
  Added obsolete scheduling routines in "some Rube Goldberg logic" style to tackle misbehavior of scheduling and triggers (including actuator) including switch to (de-)activate
*/

// WiFi network & Cayenne authentication info.
#include <CayenneMQTTESP8266.h>
char ssid[] = "ssid";
char wifiPassword[] = "password";
char username[] = "user";
char password[] = "pw";
char clientID[] = "id"; // Device abf-testing

// some Cayenne stuff for Wemos D1 R2 with MQTT
#include <CayenneDefines.h>
#define CAYANNE_DEBUG
#define CAYANNE_PRINT Serial

// library, variables for DHT22 (Temperature and Huminity)
#include <DHT.h>
#define DHTPIN D6
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
float h;
float t;
DHT dht(DHTPIN, DHTTYPE);

// library, variables for Flaminco Switches)
#define rfPin D7       // uses digital 7 (the D is important)
//const int rfPin = 13;    // Pin Digital D7 on Wemos D1 R2                 
#include "flamingo.h"  // library in seperate tab for Action switch (self-learning)
//int tmp_switch_value, tmp_switch; //used to invert logic

/*
#include <RemoteTransmitter.h>
KaKuTransmitter kaKuTransmitter(7); //data-pin 433 on pin 7
*/

// for elro switches (if not in use please remove complete sketch low memory on W5100)
#include <RCSwitch.h> //using library: https://github.com/sui77/rc-switch (version 2.6.2)          
RCSwitch mySwitch = RCSwitch();


// for Flamingo SF-501PWD (among others)
#include <NewRemoteTransmitter.h> //library can be found on https://bitbucket.org/fuzzillogic/433mhzforarduino/wiki/Home
NewRemoteTransmitter transmitter(14727168, rfPin, 260, 3); //values are transmittercode, pin, miliseconds, repeat

// Library to connnect to time-servers in NL https://github.com/SensorsIot/SNTPtime
#include <SNTPtime.h>
SNTPtime NTPnl("nl.pool.ntp.org");
strDateTime dateTime;
strDateTime dateTime_wo_DST;
int check_DST;

//timelord tardis libary for sunset/sunrise Info Tardis http://forum.arduino.cc/index.php?topic=129249.msg972860#msg972860
#include <TimeLord.h>

// various variables
unsigned long lastMillis = 0;
int time_now = 0;             //set time funtion
int time_sunset = 0;          //sunset time funtion
int time_sunrise = 0;         //sunrise time funtion
int time_offset = 0;          //to calculate the twilight zone
float time_now_d, time_sunset_d, time_sunrise_d; //to display time without a colon only a point
float uptime;                 // time system is up and running
int int_scheduling = 1;       // actuator to activate internal sceduling
//int systemUpTimeMn, systemUpTimeHr, systemUpTimeDy; //used in calculation system uptime
//int ActualCounter = 0;

void setup() {
  
  Serial.begin(115200);
  Serial.println("sketch: MQTT_433_Switches");
  Serial.print("compiled: ");
  Serial.print(__DATE__);
  Serial.print(" ");
  Serial.println(__TIME__);
  Serial.println("Following sensors are/should be connected");
  //Serial.println("-> Analog 4 = SCL RTC DC3231");
  //Serial.println("-> Analog 5 = SDA RTC DC3231");
  Serial.println("-> Digital 6 = DHT22");
  Serial.println("-> Digital 7 = Data 433");

  dht.begin();
  
  Serial.println("Booted");
  Serial.println("Connecting to Wi-Fi");
  Cayenne.begin(username, password, clientID, ssid, wifiPassword);
  while (WiFi.status() != WL_CONNECTED) {
         Serial.print(".");
         delay(500);
  }
  Serial.println("WiFi connected");

  //refresh time and DST
  Time_DST_refresh();
  Cayenne.virtualWrite(43, check_DST, "digital_sensor", "d");

  // Set internal scheduling to true
  Serial.print("int_scheduling : " );
  Serial.println(int_scheduling);
  Cayenne.virtualWrite(26, int_scheduling);
}

void loop() {
  Cayenne.loop();
  //Publish data every 10 seconds (10000 milliseconds). Change this value to publish at a different interval.
  if (millis() - lastMillis > 10000) {
    lastMillis = millis();
    
    //Misc
      Cayenne.virtualWrite(32, WiFi.RSSI()); //display signal WiFi connection
      //source: https://diyprojects.io/portable-wifi-scanner-oled-display-esp8266-signal-strength-connection-test-server/#.Whacbjco-Uk
    //refresh present time
    Timeroutine();
    Cayenne.virtualWrite(40, time_now_d);

    if ( dateTime.dayofWeek == 1 && dateTime.hour == 3 && dateTime.minute == 0 ) { // monthly reset of time based upon NTP-servers and DST-check
       Time_DST_refresh();
       Cayenne.virtualWrite(43, check_DST, "digital_sensor", "d");
    }

    if ( dateTime.hour == 0 && dateTime.minute == 0 ) {      // daily reset of sunrise and sunsut   
       sunsetrise();
       Cayenne.virtualWrite(38, time_sunset_d);
       Cayenne.virtualWrite(39, time_sunrise_d);
    }
    
    publishSystemUpTime();                        //calculate and display system up time
      //Cayenne.virtualWrite(35, systemUpTimeDy);
      //Cayenne.virtualWrite(36, systemUpTimeHr);
      Cayenne.virtualWrite(37, uptime);
    
    DHTroutine();

    Serial.print("int_scheduling : " );
    Serial.println(int_scheduling);
    if ( int_scheduling == 1) { // is the internal scheduling requested?
       obsolete_scheduling();
    }
  }
}

//Default function for processing actuator commands from the Cayenne Dashboard.
//You can also use functions for specific channels, e.g CAYENNE_IN(1) for channel 1 commands.
CAYENNE_IN_DEFAULT()
{
  CAYENNE_LOG("CAYENNE_IN_DEFAULT(%u) - %s, %s", request.channel, getValue.getId(), getValue.asString());
  //Process message here. If there is an error set an error message using getValue.setError(), e.g getValue.setError("Error message");
}

CAYENNE_IN(0) // action switch lamp V0
{
  Flamingo_Send(0, !getValue.asInt());
}
CAYENNE_IN(1) // action switch lamp V1
{
  Flamingo_Send(1, !getValue.asInt());
}
CAYENNE_IN(2) // action switch lamp V2
{
  Flamingo_Send(2, !getValue.asInt());
}
CAYENNE_IN(3) // action switch lamp V3
{
  Flamingo_Send(3, !getValue.asInt());
}
CAYENNE_IN(4) // action switch lamp V4
{
  Flamingo_Send(4, !getValue.asInt());
}
CAYENNE_IN(5) // action switch lamp V5
{
  Flamingo_Send(5, !getValue.asInt());
}
CAYENNE_IN(6) // action switch lamp V6
{
  Flamingo_Send(6, !getValue.asInt());
}
CAYENNE_IN(7) // action switch lamp V7
{
  Flamingo_Send(7, !getValue.asInt());
}
CAYENNE_IN(13) // Flamingo SF-501PWD unit 1
{
  transmitter.sendUnit(1, getValue.asInt()); // Flamingo SF-501PWD unit 1
  Cayenne.virtualWrite(13, getValue.asInt());
}
CAYENNE_IN(14) // Flamingo SF-501PWD unit 2
{
  transmitter.sendUnit(2, getValue.asInt()); // Flamingo SF-501PWD unit 2
  Cayenne.virtualWrite(14, getValue.asInt());
}
CAYENNE_IN(25) // Because 2 is a crowd for triggers, 1 trigger for all Night Time events GO-GO-GO in testing
{
  int tmp_switch_val = getValue.asInt();
  Serial.println("tmp_switch_val : ");
  Serial.println(tmp_switch_val);
  flamingo_2actions(0, tmp_switch_val);
  flamingo_2actions(1, tmp_switch_val);
  flamingo_2actions(2, tmp_switch_val);
  //flamingo_2actions(3, tmp_switch_val);
  flamingo_2actions(4, tmp_switch_val);
  flamingo_2actions(5, tmp_switch_val);
  flamingo_2actions(6, tmp_switch_val);
  flamingo_2actions(7, tmp_switch_val);
  transmitter.sendUnit(1, tmp_switch_val); // Flamingo SF-501PWD unit 1
  Cayenne.virtualWrite(13, tmp_switch_val);
  transmitter.sendUnit(2, tmp_switch_val); // Flamingo SF-501PWD unit 2
  Cayenne.virtualWrite(14, tmp_switch_val);
}
CAYENNE_IN(26) // activate internal scheduling
{
   int_scheduling = getValue.asInt();
   Serial.print("int_scheduling : " );
   Serial.println(int_scheduling);
}
CAYENNE_IN(27) // set offset
{
   time_offset = getValue.asInt();
   Serial.print("time_offset : " );
   Serial.println(time_offset);
}
Flamingo LibaryArduino
Should be in the same folder as the main sketch
/*********************************************************************************************************
 * Based upon collective works by an unknown author, adapted for Cayenne (or Blynck) by Wouter-Jan       *
 * Info Flamingo: http://forum.arduino.cc/index.php?topic=201771.0                                       *
 * Info 433: a self-learning 433 libary in wording: https://forum.fhem.de/index.php/topic,36399.60.html  *
 * *******************************************************************************************************

******************************************************************************** 
** Flamingo_send                                                              **
**                                                                            **
**       Flamingo device commands (on/off)hard coded (not deciphered yet)     **
**       code is 28 byte long. To transfer it in 32 bit code 4 *0             **
**       is added to the left. For programming reason hex code representation **
**       of device code is used. E.g. Remote 0,C,On:                          **
**         code 28 bits: 0001100110111111110100100110                         **
**         code 32 bits: 00011001101111111101001001100000                     **
**         Hex:          19BFD260                                             **
**                                                                            **
**        "Sync" 1 pulse High, 15 pulse low                                   **
**        "1"    1 pulse High, 3 pulse low                                    **
**        "0"    3 pulse High, 1 pulse low                                    **
**        "end"  N/A                                                          **
**                                                                            **
**       For internal ref: Unit 0 = white remote , unit 1 = black remote      **
**                                                                            **
*******************************************************************************/

// Compiler only coding
#define FUNITS  12                                 /* Amount of units supported */
#define FCMDN   2                                  /* Amount of CMD 0 = On, 1 = Off */

// int rfPin = D7;                                 /* with ethernet shield D4 = SS (for SD card) (now in main sketch)*/

// define device codes:

uint32_t fdev[FUNITS][FCMDN] = {0xD9762A10, 0xDAA47850, /* Remote 0 */ 
                                0xDBDA22E0, 0xDBA27220, /* Remote 1 */
                                0x19BFD260, 0x195EEAA0, /* Remote 2 */
                                0x984CC650, 0x9A8C1050, /* Remote 3 */
                                0xDBFFFE90, 0xD91CEF10, /* Remote 4 */
                                0xDBC52FA0, 0xD9E35160, /* Remote 5 */
                                0x19B0FE60, 0x19682B20, /* Remote 6 */
                                0x9924E7D0, 0x9BA928D0, /* Remote 7 */                                        
                                0x25B25B60, 0x24DC2060, /* Remote 8  (not tested) */
                                0x2717B510, 0x275BADD0, /* Remote 9  (not tested) */
                                0xE56BF910, 0xE4D49F50, /* Remote 10 (not tested) */
                                0x65F1C2A0, 0x65B67B60  /* Remote 11 (not tested) */ 
           };                                         


// Define Flamingo_send variables / constants

int fpulse = 300;                              /* Pulse witdh in microseconds */
int fretrans = 5;                              /* Code retransmission         */
uint32_t fsendbuff;
uint32_t fdatabit;
uint32_t fdatamask = 0x80000000;

void Flamingo_Send(int funitc, int fcmd)
{

 // Test if used codes are valid

 if ((funitc < 0) || (funitc >  11)) {                  // check if unit code between 0-11 (Remote 0 to 11)
   Serial.print("Unit error: ");
   Serial.println(funitc);
   return;
 }

 if ((fcmd < 0) || (fcmd > 1)) {                       // check if command = 0 (off) or 1 (on)
   Serial.print("Command error: ");
   Serial.println(fcmd);
   return;
 }
 
 //End test used codes
 Serial.println("");
 Serial.println("Send Flamingo command: ");
 Serial.print("Flamingo Unit = :");
 Serial.println(funitc);
 Serial.print("command = :");
 Serial.println(fcmd);
 // Send Command

 for (int nRepeat = 0; nRepeat <= fretrans; nRepeat++) {

   fsendbuff = fdev[funitc][fcmd];

   // send SYNC 1P High, 15P low
   Serial.println("Send sync");

   digitalWrite(rfPin, HIGH);
   delayMicroseconds(fpulse * 1);
   digitalWrite(rfPin, LOW);
   delayMicroseconds(fpulse * 15);

   // end send SYNC

   // Send command

   for (int i = 0; i < 28; i++)                                 // Flamingo command is only 28 bits */
   {
     // read data bit
     fdatabit = fsendbuff & fdatamask;                         // Get most left bit
     fsendbuff = (fsendbuff << 1);                             // Shift left

     if (fdatabit != fdatamask)
     { // Write 0
       digitalWrite(rfPin, HIGH);
       delayMicroseconds(fpulse * 3);
       digitalWrite(rfPin, LOW);
       delayMicroseconds(fpulse * 1);
     }
     else
     { // Write 1
       digitalWrite(rfPin, HIGH);
       delayMicroseconds(fpulse * 1);
       digitalWrite(rfPin, LOW);
       delayMicroseconds(fpulse * 3);
     }
   }
 }
   //Serial.println("send code = :");
   //Serial.println(fsendbuff);
   Serial.println(rfPin);
}
RoutinesArduino
Should be in the same folder as the main sketch
void sunsetrise() {

/*  Calculate when sunrises and sunsets based upon GSP-coordinates and date of the year
 *  using TimeLord.h library.
 *  dates are stores as integer and float whereas float simulates a time-notation without semi-column. 
 */
  
  float const LONGITUDE = 4.26; //change this according to your own location
  float const LATITUDE = 52.08; //ditto 

  TimeLord tardis; 
  tardis.TimeZone((60) + check_DST * 60); // tell TimeLord what timezone your RTC / NTP-server is synchronized to. You can ignore DST
  // as long as the RTC never changes back and forth between DST and non-DST
  tardis.Position(LATITUDE, LONGITUDE); // tell TimeLord where in the world we are
  //byte today[] = {  0, 0, 12, 21, 8, 2017    }; // store manual date (at noon) in an array for TimeLord to use
  byte today[] = {  0, 0, 12, dateTime.day, dateTime.month, dateTime.year }; // store RTC date (at noon) in an array for TimeLord to use
  
  if (tardis.SunRise(today)) // if the sun will rise today (it might not, in the [ant]arctic)
     {
     time_sunrise = today[tl_hour] * 60 + today[tl_minute];
     time_sunrise_d = today[tl_hour] * 1.0 + today[tl_minute] / 100.0;
     }
  if (tardis.SunSet(today)) // if the sun will set today (it might not, in the [ant]arctic)
     {
     time_sunset = today[tl_hour] * 60 + today[tl_minute];
     time_sunset_d = today[tl_hour] * 1.0 + today[tl_minute] / 100.0;
     }
  }
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  
  void publishSystemUpTime(){ 
    //source: http://community.mydevices.com/t/system-uptime-millis-to-dd-hh-mm-code-optimization-question-esp8266/4434
    long millisecs = millis();
    //systemUpTimeMn = int((millisecs / (1000*60)) % 60);
    //systemUpTimeHr = int((millisecs / (1000*60*60)) % 24);
    //systemUpTimeDy = int((millisecs / (1000*60*60*24)) % 365);
    uptime = int((millisecs / (1000*60*60)) % 24) + int((millisecs / (1000*60)) % 60) / 100.0;
    //Serial.println(uptime);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

void DHTroutine() {
    h = dht.readHumidity();
    t = dht.readTemperature();
    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.println(" %\t");
    Serial.print("Temperature: ");
    Serial.print(t);
    Serial.println(" Celcius ");
    Cayenne.virtualWrite(30, t, "temp", "c");
    Cayenne.virtualWrite(31, h, "rel_hum", "p");
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

void flamingo_2actions(int tmp_switch, int tmp_switch_value){ //used to invert the flamingo switch

  Cayenne.virtualWrite(tmp_switch, tmp_switch_value);
  Flamingo_Send(tmp_switch, !tmp_switch_value); // ON/OFF

}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

void Timeroutine() {
     
    // first parameter: Time zone; second parameter: 1 for European summer time; 2 for US daylight saving time (not implemented yet)
    dateTime = NTPnl.getTime(1.0, 1); // get time from internal clock
    //NTPnl.printDateTime(dateTime);
    time_now = dateTime.hour * 60 + dateTime.minute;
    time_now_d = dateTime.hour * 1.0 + ( dateTime.minute / 100.0);
    
    if (time_now >= time_sunset || time_now <= time_sunrise) {
       Cayenne.virtualWrite(41, 1, "digital_sensor", "d");
       //Serial.println("Night time = 1");
       } else {
       Cayenne.virtualWrite(41, 0, "digital_sensor", "d");
       //Serial.println("Night time = 0");
  }
    if (time_now >= time_sunset + time_offset || time_now <= time_sunrise - time_offset) { //delay for twilight offset set by slider
       Cayenne.virtualWrite(42, 1, "digital_sensor", "d");
       //Cayenne.virtualWrite(42, 1);
       //Serial.println("Twilight = 1");
       } else {
       //Cayenne.virtualWrite(42, 0);
       Cayenne.virtualWrite(42, 0, "digital_sensor", "d");
       //Serial.println("Twilight = 0");
       }
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

void Time_DST_refresh(){ //monthly reset of time based upon NTP-servers

  Serial.println("inside Time_DST_refresh()");
  // NTP-server part
  Serial.println("Connecting to NTP-server NL");
  while (!NTPnl.setSNTPtime()) Serial.print("."); // set internal clock
  Serial.print("Time set : ");
  // first parameter: Time zone; second parameter: 1 for European summer time; 2 for US daylight saving time (not implemented yet)
  dateTime = NTPnl.getTime(1.0, 1); // get time from internal clock
  NTPnl.printDateTime(dateTime);
  byte actualHour = dateTime.hour;
  /*
  byte actualMinute = dateTime.minute;
  byte actualsecond = dateTime.second;
  int actualyear = dateTime.year;
  byte actualMonth = dateTime.month;
  byte actualday = dateTime.day;
  byte actualdayofWeek = dateTime.dayofWeek;
  */
  // DST-part
  dateTime_wo_DST = NTPnl.getTime(1.0, 0); // get time from internal clock with out DST correction
  byte Hour_wo_DST =  dateTime_wo_DST.hour;
  if (Hour_wo_DST == dateTime.hour) {
    check_DST = 0;
  } else {
    check_DST = 1;
  }
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
schedulingArduino
Should be in the same folder as the main sketch

Some obsolete scheduling because Cayenne's Triggers and scheduling was not working end 2017 as desired. Might be working now though;)
void obsolete_scheduling() {
Serial.println("inside obsolete_scheduling");

//setting switches on !!!!
  if(time_now == time_sunset + time_offset + 11) {
      Cayenne.virtualWrite(13, 1);
      transmitter.sendUnit(1, 1); // Flamingo SF-501PWD unit 1
      Cayenne.virtualWrite(14, 1);
      transmitter.sendUnit(2, 1); // Flamingo SF-501PWD unit 2
  }
  
  if(time_now == time_sunset + time_offset + 1) {
     flamingo_2actions(0, 1);
     flamingo_2actions(2, 1);
     flamingo_2actions(4, 1);
     flamingo_2actions(7, 1);
  }

  if(time_now == time_sunset + time_offset + 24) {
     flamingo_2actions(1, 1);
     flamingo_2actions(3, 1);
  }

  //kerstverlichting
  if(time_now == 8 * 60 ) {
     flamingo_2actions(5, 1);
     flamingo_2actions(6, 1);
  }
  if(time_now == 2 * 60 ) {
     flamingo_2actions(6, 0);
  }

  if(time_now == 22 * 60 + 30 ) {
     flamingo_2actions(3, 0);
  }
  
  if(time_now == 23 * 60 + 40 ) {
     flamingo_2actions(0, 0);
     flamingo_2actions(1, 0);
     flamingo_2actions(2, 0);
     flamingo_2actions(3, 0);
     flamingo_2actions(4, 0);
     flamingo_2actions(5, 0);
     flamingo_2actions(7, 0);
  }
  
  //turn light off by sleeping time
  if(time_now == 5) {
      //Serial.println("inside time_now == (24*60 - 5)");
      Cayenne.virtualWrite(13, 0);
      transmitter.sendUnit(1, 0); // Flamingo SF-501PWD unit 1
  }
  
  // turn lights off by sunrise
  if(time_now == time_sunrise - 30) { // half hour for actual sunrise light switches out
      Cayenne.virtualWrite(14, 0);
      transmitter.sendUnit(2, 0); // Flamingo SF-501PWD unit 2
  }

  if(time_now == 8 * 60 + 15 ) { // turning on some christmas lights by scheduling overide by remote only
    mySwitch.enableTransmit(rfPin);
    mySwitch.switchOn("11111", "10000");
    mySwitch.switchOn("11111", "01000");
    mySwitch.switchOn("11111", "00010");
    mySwitch.disableTransmit();
  }
  
  if(time_now ==  23 * 60 + 5 ) { // turning on some christmas lights by scheduling overide by remote only
  //Serial.println("Switch: woodpile");
    mySwitch.enableTransmit(rfPin);
    mySwitch.switchOff("11111", "10000");
    mySwitch.switchOff("11111", "00100");
    mySwitch.switchOff("11111", "00010");
    mySwitch.disableTransmit();
  }
}

Schematics

Simple Schematics
Dsc00590 hyp0expl4m

Comments

Similar projects you might like

Home Automation with Fire Safety, Intruder Detection

Project showcase by proton029

  • 3,576 views
  • 0 comments
  • 4 respects

Home automation V1 (Arduino, Raspberry Pi, ESP8266)

Project showcase by Tadeas Dvoracek

  • 11,016 views
  • 2 comments
  • 18 respects

Universal Power Variator

Project tutorial by ming huang

  • 2,554 views
  • 1 comment
  • 16 respects

Android App-Based Home Automation System Using IOT

Project tutorial by Team Autoshack

  • 49,261 views
  • 22 comments
  • 141 respects

Octopod: Smart IoT Home/Industry Automation Project

Project tutorial by Saksham Bhutani

  • 13,403 views
  • 11 comments
  • 44 respects

Bluetooth Home Automation

Project tutorial by TATCO

  • 9,120 views
  • 4 comments
  • 20 respects
Add projectSign up / Login