Advertisement
phoenixdigital

Wemos Philips Hue Light Trigger

Nov 30th, 2017
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 22.19 KB | None | 0 0
  1. /*
  2.  * ################################################################
  3.  * Sensor Software 1.1 (https://imgur.com/a/xK1eu)
  4.  *
  5.  * Changelog 1.1
  6.  *  - Move PIR to another PIN
  7.  *  - Invert blue LED and only have on when motion detected
  8.  *  - Only turn on display when motion detected
  9.  *  - Don't syslog timeout when it is zero
  10.  *  - Modify all syslog calls to be Splunk firendly
  11.  *  - Increase size of display and rotate through sensors only when Timer is active. Include timer
  12.  *  - Merge all rooms into one file based on define
  13.  *  
  14.  
  15.  * TODO
  16.  *  - Include switch to deactivate schedule mode and possibly manually trigger lights
  17.  *  - Look into ability to have lights as part of schedule
  18.  *  - Check if Lights are on before turning on
  19.  *  - If lights are on and no timer just turn on don't set hue also double the timeout (allows custom manual hue)
  20.  *  - Keep track of when last turned on. If it has been less than 15 minutes don't set hue just turn on. Allows for custom hue
  21.  *  - Look into interrupts for PIR and sensor syslogging
  22.  *  - Look into HTTP Event Collector
  23.  *  - Implement UBER sensor!!!
  24.  *
  25.  */
  26.  
  27. #include <Adafruit_SSD1306.h>
  28. #include <Adafruit_GFX.h>
  29. #include <gfxfont.h>
  30. #include <Wire.h>
  31. #include <Adafruit_Sensor.h>
  32. #include <Adafruit_TSL2561_U.h>
  33. #include <pgmspace.h>
  34. #include <DHT.h>
  35.  
  36. #include <ESP8266WiFi.h>
  37. #include <ESP8266mDNS.h>
  38. #include <WiFiUdp.h>
  39. #include <TimeLib.h>
  40. #include "RestClient.h"
  41.  
  42.  
  43. ////////////////////////////////////////////////////////////////////////////////////////
  44. // Device Specific Settings
  45.  
  46. #define ROOM_BATHROOM 1
  47. #define ROOM_BEDROOM 2
  48. #define ROOM_KITCHEN 3
  49.  
  50. #define ROOM_TYPE ROOM_KITCHEN  // CHANGE THIS ONE!!!!
  51.  
  52. ////////
  53. // Bedroom configs
  54. #if ROOM_TYPE == ROOM_BEDROOM
  55.  
  56.   #define ROOM_NAME "Bedroom"
  57.   #define ESP8266_HOSTNAME "esp8266-bedroom"
  58.   // {4,9}
  59.   #define LIGHTS_ARRAY {4}
  60.   #define LIGHTS_SCHEDULE_TIMES_ARRAY {7,17,21,23}
  61.   #define LIGHTS_SCHEDULE_ACTIONS_ARRAY { \
  62.       "{\"xy\":[0.669,0.314], \"on\": true, \"bri\": 48}", \
  63.       "{\"ct\": 153, \"on\": false, \"bri\": 153}", \
  64.       "{\"ct\": 479, \"on\": true, \"bri\": 231}", \
  65.       "{\"xy\":[0.87,0.294], \"on\": true, \"bri\": 144}" \
  66.       }
  67.   #define LIGHTS_SCHEDULE_TIMEOUT_ARRAY {1,5,2,2}
  68.   #define SYSLOG_SERVER_NAME "device=esp8266-bedroom,"
  69.  
  70. ////////
  71. // Kitchen configs
  72. #elif ROOM_TYPE == ROOM_KITCHEN
  73.  
  74.   #define ROOM_NAME "Kitchen"
  75.   #define ESP8266_HOSTNAME "esp8266-kitchen"
  76.   #define LIGHTS_ARRAY {7}
  77.   #define LIGHTS_SCHEDULE_TIMES_ARRAY {7,17,21,23}
  78.   #define LIGHTS_SCHEDULE_ACTIONS_ARRAY { \
  79.     "{\"ct\": 495, \"on\": true, \"bri\": 1}", \
  80.     "{\"ct\": 153, \"on\": true, \"bri\": 153}", \
  81.     "{\"ct\": 447, \"on\": true, \"bri\": 255}", \
  82.     "{\"xy\":[0.658,0.3134], \"on\": true, \"bri\": 109}" \
  83.     }
  84.   #define LIGHTS_SCHEDULE_TIMEOUT_ARRAY {1,10,5,2}
  85.   #define SYSLOG_SERVER_NAME "device=esp8266-kitchen,"
  86.  
  87. ////////
  88. // Bathroom configs
  89. #elif ROOM_TYPE == ROOM_BATHROOM
  90.  
  91.   #define ROOM_NAME "Bathroom"
  92.   #define ESP8266_HOSTNAME "esp8266-bathroom"
  93.   #define LIGHTS_ARRAY {5}
  94.   #define LIGHTS_SCHEDULE_TIMES_ARRAY {7,18,21,23}
  95.   #define LIGHTS_SCHEDULE_ACTIONS_ARRAY { \
  96.       "{\"ct\": 495, \"on\": true, \"bri\": 1}", \
  97.       "{\"ct\": 153, \"on\": true, \"bri\": 153}", \
  98.       "{\"ct\": 447, \"on\": true, \"bri\": 255}", \
  99.       "{\"xy\":[0.658,0.3134], \"on\": true, \"bri\": 109}" \
  100.       }
  101.   #define LIGHTS_SCHEDULE_TIMEOUT_ARRAY {1,5,5,2}
  102.   #define SYSLOG_SERVER_NAME "device=esp8266-bathroom,"
  103.  
  104. #endif
  105.  
  106. #define SYSLOG_SERVER_IP "192.168.1.64"
  107. #define SYSLOG_SERVER_OCTET 192,168,1,64
  108. #define SYSLOG_SERVER_PORT 8888
  109.  
  110. #define HUE_HUB_IP "192.168.1.60"
  111. #define HUB_AUTH "8VHGiAtOw**********************6AIv8"
  112.  
  113. #define WIFI_ACCESS_POINT "YOUR_AP_NAME"
  114. #define WIFI_PWD "YOUR_AP_WIRELESS_PASSWORD"
  115.  
  116. ////////////////////////////////////////////////////////////////////////////////////////
  117. // Sensors
  118.  
  119. // LUX
  120. Adafruit_TSL2561_Unified tsl = Adafruit_TSL2561_Unified(TSL2561_ADDR_FLOAT, 12345);
  121. int globalLux = 0;
  122.  
  123. // Define DHT Pin
  124. #define DHTPIN D6
  125. #define DHTTYPE DHT22    // DHT 22 (AM2302)
  126. DHT dht(DHTPIN, DHTTYPE);
  127. static char globalTemp[10];
  128. static char globalHumidity[10];
  129.  
  130. // Define PIR
  131. #define PIRPIN D5
  132. int globalPIR = 0;
  133.  
  134. // Define onboard LED
  135. # define LEDPIN D4
  136.  
  137. // Variable to remember the previous value of the motion sensor
  138. int PIR_PrevValue = 0;
  139.  
  140. //////////////////////
  141. // WiFi and Network Settings
  142.  
  143. const char* ssid = WIFI_ACCESS_POINT;  
  144. const char* password = WIFI_PWD;
  145.  
  146. const char* syslogServerIP = SYSLOG_SERVER_IP;
  147. unsigned int localPort = SYSLOG_SERVER_PORT;
  148.  
  149. ///////////////////////////
  150. // Syslog Server: https://gist.github.com/chaeplin/8f4b06aa2bd454232892
  151.  
  152. IPAddress syslogServer(SYSLOG_SERVER_OCTET);
  153. char syslogMessage[512];
  154. const char* syslogServerName = SYSLOG_SERVER_NAME;
  155.  
  156. WiFiUDP Udp;
  157.  
  158. void sendUdpSyslog(String msgtosend)
  159. {
  160.   Serial.println(msgtosend);
  161.   unsigned int msg_length = msgtosend.length();
  162.   byte* p = (byte*)malloc(msg_length);
  163.   memcpy(p, (char*) msgtosend.c_str(), msg_length);
  164.  
  165.   Udp.beginPacket(syslogServer, 514);
  166.   Udp.write(syslogServerName);
  167.   Udp.write(p, msg_length);
  168.   Udp.endPacket();
  169.   free(p);
  170. }
  171.  
  172. ///////////////////////////
  173. // NTP Servers:
  174.  
  175. const int timeZone = 10;     // Australian EST Time
  176. const char* ntpServerName = "time.nist.gov";
  177. IPAddress timeServerIP;
  178.  
  179. time_t prevDisplay = 0; // when the digital clock was displayed
  180.  
  181. const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
  182. byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets
  183.  
  184. time_t last_motion_time = 0; // The last time motion was detected
  185.  
  186. ///////////////////////////
  187. // OLED
  188.  
  189. #define OLED_RESET 0  // GPIO0
  190. Adafruit_SSD1306 display(OLED_RESET);
  191.  
  192. #define NUMFLAKES 10
  193. #define XPOS 0
  194. #define YPOS 1
  195. #define DELTAY 2
  196.  
  197. #define LOGO16_GLCD_HEIGHT 16
  198. #define LOGO16_GLCD_WIDTH  16
  199.  
  200. //////////////////////
  201. // Light Settings
  202.  
  203. // REST Client for Hue Hub Control
  204. RestClient client = RestClient(HUE_HUB_IP);
  205. String HTTP_response;
  206.  
  207. // Lights to turn on/off
  208. // int lights[] = {6,7};
  209. int lights[] = LIGHTS_ARRAY;
  210. int lightCount = sizeof(lights)/sizeof(int);
  211.  
  212. // Fill this array with the hour you want a schedule to trigger for.
  213. // If the current hour is less than the hour in this array it will set the lights to the associated lightScheduleTrigger
  214. int lightScheduleTimes[] = LIGHTS_SCHEDULE_TIMES_ARRAY;
  215. int scheduleCount = sizeof(lightScheduleTimes)/sizeof(int);
  216.  
  217. // Fill this array with the light settings you want to use.
  218. // The first element in the array will be used if no schedule time is matched
  219. char *lightScheduleTriggers[] = LIGHTS_SCHEDULE_ACTIONS_ARRAY;
  220.  
  221. // Sets the timeout in minutes for each schedule as defined in lightScheduleTimes
  222. int lightTimers[] = LIGHTS_SCHEDULE_TIMEOUT_ARRAY;
  223.  
  224. // global variables to store the timeout and number of motion triggers detected during a lightOn state.
  225. time_t lightTimeout = 0;
  226. time_t lastOnTime = 0;
  227. time_t lastOffTime = 0;
  228. int currentExpectedLightState = 0;
  229. int lightTriggers = 0;
  230.  
  231.  
  232. //////////////////////
  233. // NTP Functions for ensuring the time remains accurate for determining the hour of the day
  234.  
  235.  
  236. // send an NTP request to the time server at the given address
  237. void sendNTPpacket(IPAddress &address)
  238. {
  239.   // set all bytes in the buffer to 0
  240.   memset(packetBuffer, 0, NTP_PACKET_SIZE);
  241.   // Initialize values needed to form NTP request
  242.   // (see URL above for details on the packets)
  243.   packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  244.   packetBuffer[1] = 0;     // Stratum, or type of clock
  245.   packetBuffer[2] = 6;     // Polling Interval
  246.   packetBuffer[3] = 0xEC;  // Peer Clock Precision
  247.   // 8 bytes of zero for Root Delay & Root Dispersion
  248.   packetBuffer[12]  = 49;
  249.   packetBuffer[13]  = 0x4E;
  250.   packetBuffer[14]  = 49;
  251.   packetBuffer[15]  = 52;
  252.   // all NTP fields have been given values, now
  253.   // you can send a packet requesting a timestamp:                
  254.   Udp.beginPacket(address, 123); //NTP requests are to port 123
  255.   Udp.write(packetBuffer, NTP_PACKET_SIZE);
  256.   Udp.endPacket();
  257. }
  258.  
  259. time_t getNtpTime()
  260. {
  261.   while (Udp.parsePacket() > 0) ; // discard any previously received packets
  262.   Serial.println("Transmit NTP Request");
  263.   sendNTPpacket(timeServerIP);
  264.   uint32_t beginWait = millis();
  265.   while (millis() - beginWait < 1500) {
  266.     int size = Udp.parsePacket();
  267.     if (size >= NTP_PACKET_SIZE) {
  268.       Serial.println("Receive NTP Response");
  269.       Udp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer
  270.       unsigned long secsSince1900;
  271.       // convert four bytes starting at location 40 to a long integer
  272.       secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
  273.       secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
  274.       secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
  275.       secsSince1900 |= (unsigned long)packetBuffer[43];
  276.       return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
  277.     }
  278.   }
  279.   Serial.println("No NTP Response :-(");
  280.   return 0; // return 0 if unable to get the time
  281. }
  282.  
  283. void printDigits(int digits){
  284.   // utility for digital clock display: prints preceding colon and leading 0
  285.   Serial.print(":");
  286.   if(digits < 10)
  287.     Serial.print('0');
  288.   Serial.print(digits);
  289. }
  290.  
  291. void digitalClockDisplay(){
  292.   // digital clock display of the time
  293.   Serial.print(hour());
  294.   printDigits(minute());
  295.   printDigits(second());
  296.   Serial.print(" ");
  297.   Serial.print(day());
  298.   Serial.print(".");
  299.   Serial.print(month());
  300.   Serial.print(".");
  301.   Serial.print(year());
  302.   Serial.println();
  303. }
  304.  
  305. //////////////////////
  306. // Send to Splunk HTTP Event Collector
  307.  
  308. /*
  309. const char* splunkHost = "192.168.64.64";
  310. const int splunkHecPort = 8088;
  311.  
  312. // Use web browser to view and copy
  313. // SHA1 fingerprint of the certificate
  314. const char* splunkFingerprint = "‎a8 d9 bb 87 d2 dd 97 06 66 34 a3 15 9c c1 78 3b f7 75 01 d1";
  315.  
  316. sendHttpEventCollectorMessage(){
  317.  
  318.   char httpPostPayload[512];
  319.  
  320.   // Use WiFiClientSecure class to create TLS connection
  321.   WiFiClientSecure client;
  322.   Serial.print("connecting to ");
  323.   Serial.println(splunkHost);
  324.   if (!client.connect(splunkHost, httpsPort)) {
  325.     Serial.println("connection failed");
  326.     return;
  327.   }
  328.  
  329.   if (client.verify(splunkFingerprint, splunkHecPort)) {
  330.     Serial.println("certificate matches");
  331.   } else {
  332.     Serial.println("certificate doesn't match");
  333.   }
  334.  
  335.   String url = "/services/collector/event";
  336.   Serial.print("requesting URL: ");
  337.   Serial.println(url);
  338.  
  339.   sprintf(httpPostPayload, "{\"event\":\"device=%s,version=%02d","esp8266-kitchen",1);
  340.  
  341.   client.print(String("POST ") + url + " HTTP/1.1\r\n" +
  342.                "Host: " + host + "\r\n" +
  343.                "Accept: *\/*" +
  344.                "Authorization: Splunk 21d02a08-25cf-4eaa-9787-0395a50151a2" +
  345.                "User-Agent: ESP8266_Sensors\r\n" +
  346.                "Connection: close\r\n\r\n");
  347.   Serial.println("Payload: %s",httpPostPayload);
  348.  
  349.   Serial.println("request sent");
  350.   while (client.connected()) {
  351.     String line = client.readStringUntil('\n');
  352.     if (line == "\r") {
  353.       Serial.println("headers received");
  354.       break;
  355.     }
  356.   }
  357.   String line = client.readStringUntil('\n');
  358.   if (line.startsWith("{\"state\":\"success\"")) {
  359.     Serial.println("esp8266/Arduino CI successfull!");
  360.   } else {
  361.     Serial.println("esp8266/Arduino CI has failed");
  362.   }
  363.   Serial.println("reply was:");
  364.   Serial.println("==========");
  365.   Serial.println(line);
  366.   Serial.println("==========");
  367.   Serial.println("closing connection");
  368.  
  369. }
  370.  
  371. */
  372.  
  373. //////////////////////
  374. // Set timeouts
  375. int setLightTimeouts(int timeoutMinutes){
  376.  
  377.   sprintf(syslogMessage, "type=info,func=setLightTimeouts,msg=Started");
  378.   sendUdpSyslog(syslogMessage);
  379.  
  380.   // Check if timer still set
  381.   if (now() < lightTimeout) {
  382.  
  383.     sprintf(syslogMessage, "type=info,func=setLightTimeouts,msg=Timer still active");
  384.     sendUdpSyslog(syslogMessage);
  385.  
  386.     // check if trigger counter warrants an increase in the timer (Never greater than 3 times the timeout)
  387.    
  388.     // Reset timer and increase trigger counter
  389.     lightTimeout = now() + (timeoutMinutes * 60);
  390.     lightTriggers = lightTriggers + 1;
  391.  
  392.   }
  393.  
  394.   // Timer is not set
  395.   else {
  396.  
  397.     sprintf(syslogMessage, "type=info,func=setLightTimeouts,msg=Timer not set");
  398.     sendUdpSyslog(syslogMessage);
  399.    
  400.     // Set timer and zero trigger counter
  401.     lightTimeout = now() + (timeoutMinutes * 60);
  402.     lightTriggers = 1;
  403.   }
  404.  
  405.   sprintf(syslogMessage, "type=timeoutSet,func=setLightTimeouts,timeoutMins=%d,timeoutSetTime=%02d:%02d,triggers=%d", timeoutMinutes, hour(lightTimeout), minute(lightTimeout),lightTriggers);
  406.   sendUdpSyslog(syslogMessage);
  407.  
  408. }
  409. //////////////////////
  410. // Trigger Lights
  411.  
  412. int triggerLights(char* strTriggerState){
  413.  
  414.   int j = 0;
  415.   char lightURI[255];
  416.   char HTTP_response_buffer[255];
  417.  
  418.   // Turn on all lights in lights array
  419.   for (j = 0; j < lightCount; j = j + 1) {
  420.  
  421.     sprintf(lightURI, "/api/%s/lights/%d/state", HUB_AUTH, lights[j]);
  422.  
  423.     sprintf(syslogMessage, "type=hue_comms_out,func=triggerLights,light=%d,setJson=\"%s\",msg=\"Sending light trigger", lights[j], strTriggerState);
  424.     sendUdpSyslog(syslogMessage);
  425.  
  426.     HTTP_response = "";
  427.     int statusCode = client.put(lightURI, strTriggerState, &HTTP_response);
  428.     HTTP_response.toCharArray(HTTP_response_buffer,255);
  429.     sprintf(syslogMessage, "type=hue_comms_in,func=triggerLights,status=%d,response=\"%s\"", statusCode, HTTP_response_buffer);
  430.     sendUdpSyslog(syslogMessage);
  431.   }
  432. }
  433.  
  434. //////////////////////
  435. // Trigger Light On
  436.  
  437. int lightsOn() {
  438.  
  439.   // GET HOUR OF DAY
  440.   int  currentHour = hour();
  441.   sprintf(syslogMessage, "type=info,func=lightsOn,msg=\"Triggering light for current hour %d\"", currentHour);
  442.   sendUdpSyslog(syslogMessage);
  443.  
  444.   String hueHubURI = "";
  445.   int i, j;
  446.   int triggered = 0;
  447.  
  448.   // Loop through schedules until we find one that matches the current hour
  449.   for (i = 0; i < scheduleCount; i = i + 1) {
  450.  
  451.     if (currentHour < lightScheduleTimes[i]) {
  452.  
  453.       sprintf(syslogMessage, "type=info,func=lightsOn,msg=\"Hour match for scheduled hour %d (%d)\"", lightScheduleTimes[i],i);
  454.       sendUdpSyslog(syslogMessage);
  455.  
  456.       // TODO: check light on was a success
  457.       triggerLights(lightScheduleTriggers[i]);
  458.       setLightTimeouts(lightTimers[i]);
  459.       triggered = 1;
  460.  
  461.       // Break out of loop we have turned on the light and set the timers
  462.       last_motion_time = now();
  463.       break;
  464.     }
  465.   }
  466.  
  467.   // Hour not present in lightScheduleTimes array use default schedule light settings
  468.   if (triggered == 0) {
  469.  
  470.     sprintf(syslogMessage, "type=info,func=lightsOn,msg=\"Hour didn't match schedule so trigger default light config.\"");
  471.     sendUdpSyslog(syslogMessage);
  472.  
  473.     triggerLights(lightScheduleTriggers[0]);
  474.     setLightTimeouts(lightTimers[0]);
  475.   }
  476.  
  477.   lastOnTime = now();
  478.   currentExpectedLightState = 1;
  479. }
  480.  
  481. //////////////////////
  482. // Trigger Light Off
  483.  
  484. int lightsOff() {
  485.  
  486.   char lightURI[255];
  487.   int i, j;
  488.   int triggered = 0;
  489.   char* strTriggerStateOff = "{\"on\": false}";
  490.  
  491.   sprintf(syslogMessage, "type=info,func=lightsOff,msg=\"Triggered turning off lights and resetting timeout.\"");
  492.   sendUdpSyslog(syslogMessage);
  493.  
  494.   triggerLights(strTriggerStateOff);
  495.   lightTimeout = 0;
  496.   lastOffTime = now();
  497.   currentExpectedLightState = 0;
  498.   lightTriggers = 0;
  499.  
  500. }
  501.  
  502. //////////////////////
  503. // Display routines
  504.  
  505. int currentDisplayValue = 0;
  506.  
  507. int displayOn() {
  508.  
  509.   // text display tests
  510.   display.setTextSize(2);
  511.   display.setTextColor(WHITE);
  512.   display.clearDisplay();  
  513.   sprintf(syslogMessage, "type=info,func=displayRotate,msg=\"Showing Room Type.\"");
  514.   sendUdpSyslog(syslogMessage);
  515.   display.setCursor(0,0);
  516.   display.println(ROOM_NAME);
  517.   display.display();
  518.   delay(1000);
  519. }
  520.  
  521. int displayRotate() {
  522.  
  523. //  sprintf(syslogMessage, "type=info,func=displayRotate,msg=\"Clearing display current value %d.\"",currentDisplayValue);
  524. //  sendUdpSyslog(syslogMessage);
  525.  
  526.   // Clear the display buffer.
  527.   display.clearDisplay();
  528.  
  529.   switch (currentDisplayValue) {
  530.  
  531.     case 1:
  532. //      sprintf(syslogMessage, "type=info,func=displayRotate,msg=\"Showing Triggers.\"");
  533. //      sendUdpSyslog(syslogMessage);
  534.       display.setCursor(0,0);
  535.       display.print("Trig: ");
  536.       display.println(lightTriggers);
  537.       display.print("TO: ");
  538.       if (lightTimeout < 0)
  539.         display.println(0);
  540.       else
  541.         display.println(lightTimeout - now());
  542.       break;
  543.  
  544.     default:
  545. //      sprintf(syslogMessage, "type=info,func=displayRotate,msg=\"Showing Temp.\"");
  546. //      sendUdpSyslog(syslogMessage);
  547.       display.setCursor(0,0);
  548.       display.print("Temp: ");
  549.       display.println(globalTemp);
  550.       display.print("Hum: ");
  551.       display.print(globalHumidity);
  552.       display.print(" %");
  553.       currentDisplayValue = 0;
  554.       break;
  555.  
  556.   }
  557.   display.display();
  558.   currentDisplayValue = currentDisplayValue + 1;
  559.  
  560. }
  561.  
  562. int displayOff() {
  563.  
  564.   // Clear the buffer.
  565.   display.clearDisplay();
  566.   display.display();
  567.  
  568. }
  569.  
  570.  
  571. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  572. // SETUP
  573. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  574. void setup() {
  575.  
  576.   // Start up serial
  577.   Serial.begin(9600);
  578.   delay(10);
  579.  
  580.   // Init Lux sensor
  581.   if(!tsl.begin())
  582.   {
  583.     Serial.print("No TSL2561 detected");
  584.     while(1);
  585.   }
  586.  
  587.   tsl.enableAutoRange(true);
  588.   tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_13MS);
  589.  
  590.   // set humidity/temp pin
  591.   pinMode(DHTPIN, INPUT);
  592.  
  593.   // set motion pin
  594.   pinMode(PIRPIN, INPUT);
  595.  
  596.   // set motion LED signal pin and clear with default
  597.   pinMode(LEDPIN, OUTPUT);
  598.   digitalWrite(LEDPIN,1);
  599.  
  600.   ///////////////////////
  601.   // Connect to WiFi network
  602.   Serial.println();
  603.   Serial.println();
  604.   Serial.print("Connecting to ");
  605.   Serial.println(ssid);
  606.  
  607.   WiFi.mode(WIFI_STA);
  608.   WiFi.begin(ssid, password);
  609.  
  610.   while (WiFi.status() != WL_CONNECTED) {
  611.     delay(500);
  612.     Serial.print(".");
  613.   }
  614.  
  615.   WiFi.hostname(ESP8266_HOSTNAME);
  616.  
  617.  
  618.   // Open up port for NTP and Syslog Server Response
  619.   Udp.begin(localPort);
  620.  
  621.   sendUdpSyslog("type=info,func=start,msg=\"WiFi connected\"");
  622.  
  623.   // Print the IP address
  624.   Serial.print("Local IP Address = ");
  625.   Serial.println(WiFi.localIP());
  626.  
  627.   // Get IP address for time server and set at NTP server
  628.   sprintf(syslogMessage, "type=info,func=start,msg=\"Setting time server %s\"",ntpServerName);
  629.   sendUdpSyslog(syslogMessage);
  630.  
  631.   WiFi.hostByName(ntpServerName, timeServerIP);
  632.   IPAddress timeServer(timeServerIP); // time-a.timefreq.bldrdoc.gov
  633.  
  634.   sprintf(syslogMessage, "type=info,func=start,msg=\"Setting up NTP %s\"",ntpServerName);
  635.   sendUdpSyslog(syslogMessage);
  636.   Serial.print("Local port: ");
  637.   Serial.println(Udp.localPort());
  638.   Serial.println("waiting for sync");
  639.   setSyncProvider(getNtpTime);
  640.   setSyncInterval(3600);
  641.  
  642.   sendUdpSyslog("type=info,func=start,msg=\"esp8266-02-syslog started\"");
  643.  
  644.   ///////////////////////
  645.   // INIT OLED
  646.   display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 64x48)
  647.   display.display();
  648.   delay(2000);
  649.  
  650.   // Clear the buffer.
  651.   display.clearDisplay();
  652.  
  653.   // text display tests
  654.   displayOn();
  655.  
  656.   ///////////////////////
  657.   // REST Client for Hue Hub Control
  658.   client = RestClient("192.168.64.69");
  659.   HTTP_response = "";
  660.  
  661. }
  662.  
  663. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  664. // MAIN LOOP
  665. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  666. int loopCounter = 0;
  667. void loop() {
  668.  
  669.   Serial.println("Starting Loop");
  670.  
  671.   if (timeStatus() != timeNotSet) {
  672.     if (now() != prevDisplay) { //update the display only if time has changed
  673.       prevDisplay = now();
  674.       digitalClockDisplay();  
  675.     }
  676.   }
  677.  
  678.   ///////////////////////
  679.   // READ DHT
  680.   float humidity = dht.readHumidity();
  681.   if (humidity > 0) {
  682.     dtostrf(humidity,2, 0, globalHumidity);
  683.   }
  684.   float temp = dht.readTemperature();
  685.   if (temp > 0) {
  686.     dtostrf(temp,2, 0, globalTemp);
  687.   }  
  688.  
  689.   ///////////////////////
  690.   // READ PIR MOTION
  691.   int PIR_value = digitalRead(PIRPIN);
  692.   digitalWrite(LEDPIN,!PIR_value); // set onboard LED to value of PIR pin
  693.   Serial.print("PIR_Value = ");
  694.   Serial.println(PIR_value);
  695.   Serial.print("PIR_PrevValue = ");
  696.   Serial.println(PIR_PrevValue);
  697.   if (PIR_value == 1 && PIR_PrevValue == 0) {
  698.     Serial.println("Triggering lights");
  699.     lightsOn();
  700.  
  701.     // turn on display only if timeout not set. If timeout set then the display is already on
  702.     if (lightTimeout <  0) {
  703.       displayOn();
  704.     }
  705.   }
  706.   PIR_PrevValue = PIR_value;
  707.  
  708.   ///////////////////////
  709.   // READ LUX
  710.   /* Get a new sensor event */
  711.   sensors_event_t event;
  712.   tsl.getEvent(&event);
  713.  
  714.   ///////////////////////
  715.   // READ AIR
  716.  
  717.   ///////////////////////
  718.   // Loop counter to only put a syslog message out every 5 seconds
  719.   loopCounter = loopCounter + 1;
  720.   if (loopCounter > 5) {
  721.     sprintf(syslogMessage, "type=metrics,func=loop,temp=%s,humidity=%s,pir=%d,lux=%d,triggers=%d,lightState=%d,lightLastOn=%02d:%02d,lightLastOff=%02d:%02d,timeoutSetTime=%02d:%02d,nowTime=%02d:%02d,msg=\"Sensor Values\"\"",globalTemp,globalHumidity,PIR_value,(int)event.light,lightTriggers,currentExpectedLightState,hour(lastOnTime), minute(lastOnTime),hour(lastOffTime), minute(lastOffTime),hour(lightTimeout), minute(lightTimeout), hour(), minute());
  722.     sendUdpSyslog(syslogMessage);
  723.     loopCounter = 0;
  724.   }
  725.  
  726.   if (lightTimeout > 0) {
  727.     displayRotate();
  728.   }
  729.  
  730.   ///////////////////////
  731.   // Check light timeouts
  732.   if (lightTimeout > 0) {
  733.     if (now() > lightTimeout) {
  734.       sprintf(syslogMessage, "type=info,func=loop,action=timeout_triggered,timeoutSetTime=%02d:%02d,nowTime=%02d:%02d,msg=\"Timeout triggered\"\"",hour(lightTimeout), minute(lightTimeout), hour(), minute());
  735.       sendUdpSyslog(syslogMessage);
  736.  
  737.       lightsOff();
  738.       displayOff();      
  739.     }  
  740.   }
  741.  
  742.   Serial.println("Finished");
  743.   Serial.println("-----------------");
  744.  
  745.   if (PIR_value > 0)
  746.   {
  747.    
  748.    
  749.   }
  750.    
  751.   delay(1000);
  752.  
  753. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement