A while back I used 433Mhz plug to control the lights in the upstairs and downstairs hallways to come on in the morning before work and evenings until 11pm.
I did not want a light sensor as the locations have odd light levels due to the layout of the windows.
I wanted accurate on at Sunset / Off at Sunrise + / - an offset and I wanted it to be fully aware of season changed.
This worked really well I had a simple web server running in an ESP8266 with the 433Mhz transmitter and web service calls to turn the lights on and off. On my home server (Orange Pi) ARMBIAN used a Python script to calculate sunrise / sunset adding my offset and logic to control lights coming on off. Eg. in the summer as its light before 6am there is NO NEED to power on the lights in the morning.
This set up replace my time switch based with its fixed on / off hours. BigClive.Com did a teardown of a mechanical version of my Python script from a season aware mechanical timer!
One last thing I wanted was to have a PIR (not microwave too many false positives for my layout) motion sensor to turn on both lights AFTER 11pm. This design made the separation of Automated operation dawn / dusk off at 11pm then 11pm to 4am PIR triggered lighting using the same lights.
The unit has 2 inputs the time via NTP and the PIR trigger. I used a Wemos Mini clone and a stock PIR. I set the PIR during and sensitivity to midpoint seems to work. The software powers on the lights for 7 mins and then turns them off if there is no activity. I put a delay AFTER the power on command to ensure frequent triggers from the PIR are masked out so the lights come on, stay on for as long as needed and then turn off after 7 min inactivity. The serial print code shows the logic variables and makes this clear for debugging.
I use a HTTPGET to call the ESP with the 433 Transmitter so this unit is small = Wimos Mini + PIR
I used the NTP code from " the Guy with a Swiss Accent" to use NTP to grab the time and this is what drives the logic for this unit as its all based on time. The code works and is being tested.
/*
Code for PIR to turn on lights after 11pm
*/
#include
#define DEBUG_ON
#include
#include
#include
#include
#define USE_SERIAL Serial
ESP8266WiFiMulti WiFiMulti;
NTPtime NTPch("ch.pool.ntp.org"); // Choose server pool as required
char *ssid = "WIFI"; // Set you WiFi SSID
char *password = "secret"; // Set you WiFi password
/*
* The structure contains following fields:
* struct strDateTime
{
byte hour;
byte minute;
byte second;
int year;
byte month;
byte day;
byte dayofWeek;
boolean valid;
};
*/
strDateTime dateTime;
int oldval=0, val = 0;
const int pirPin=D5;
boolean enable_pir = false;
void poweron() {
HTTPClient http;
USE_SERIAL.print("[HTTP] begin...\n");
// configure traged server and url
//http.begin("https://192.168.1.12/test.html", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS
http.begin("http://192.168.0.237/HALLON"); //HTTP
USE_SERIAL.print("[HTTP] GET...\n");
// start connection and send HTTP header
int httpCode = http.GET();
// httpCode will be negative on error
if(httpCode > 0) {
// HTTP header has been send and Server response header has been handled
USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server
if(httpCode == HTTP_CODE_OK) {
String payload = http.getString();
USE_SERIAL.println(payload);
}
} else {
USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
delay(420000);
}
void poweroff() {
HTTPClient http;
USE_SERIAL.print("[HTTP] begin...\n");
// configure traged server and url
//http.begin("https://192.168.1.12/test.html", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS
http.begin("http://192.168.0.237/HALLOFF"); //HTTP
USE_SERIAL.print("[HTTP] GET...\n");
// start connection and send HTTP header
int httpCode = http.GET();
// httpCode will be negative on error
if(httpCode > 0) {
// HTTP header has been send and Server response header has been handled
USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server
if(httpCode == HTTP_CODE_OK) {
String payload = http.getString();
USE_SERIAL.println(payload);
}
} else {
USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
delay(500);
}
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println("Booted");
Serial.println("Connecting to Wi-Fi");
pinMode(pirPin, INPUT);
WiFi.mode(WIFI_STA);
WiFi.begin (ssid, password);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.println("WiFi connected");
delay(3000);
}
void loop() {
// first parameter: Time zone in floating point (for India); second parameter: 1 for European summer time; 2 for US daylight saving time (contributed by viewwer, not tested by me)
dateTime = NTPch.getNTPtime(0.0, 1);
// check dateTime.valid before using the returned time
// Use "setSendInterval" or "setRecvTimeout" if required
if(dateTime.valid){
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;
switch (dateTime.hour) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
enable_pir=true;
break;
case 23:
enable_pir=true;
break;
default:
enable_pir=false;
}
NTPch.printDateTime(dateTime);
val = digitalRead(pirPin);
//Now we have read the status of the PIR has it changed?
boolean turn_off=false, turn_on=false, samestate=false;
//Turn Off ?
if (oldval==1 && val==0)
{
turn_off=true;
}
//Turn On?
if(oldval==0 && val==1)
{
turn_on=true;
}
//No Change?
if(oldval==val)
{
samestate=true;
}
Serial.print("Time to Enable PIR=");
Serial.print(enable_pir);
Serial.print(", PIR=");
Serial.print(val);
Serial.print(" ,OLDVAL=");
Serial.println(oldval);
oldval=val;
if (enable_pir){
//Process state change
if (turn_on){
Serial.print("Turn on light");
poweron();
}
if (turn_off){
Serial.print("Turn off light");
poweroff();
}
if (!samestate)
{if (enable_pir)
{Serial.println(", Enable PIR");}
else
{Serial.println(", Automated control no need for PIR");
}
}
}
}
}
I did not want a light sensor as the locations have odd light levels due to the layout of the windows.
I wanted accurate on at Sunset / Off at Sunrise + / - an offset and I wanted it to be fully aware of season changed.
This worked really well I had a simple web server running in an ESP8266 with the 433Mhz transmitter and web service calls to turn the lights on and off. On my home server (Orange Pi) ARMBIAN used a Python script to calculate sunrise / sunset adding my offset and logic to control lights coming on off. Eg. in the summer as its light before 6am there is NO NEED to power on the lights in the morning.
This set up replace my time switch based with its fixed on / off hours. BigClive.Com did a teardown of a mechanical version of my Python script from a season aware mechanical timer!
One last thing I wanted was to have a PIR (not microwave too many false positives for my layout) motion sensor to turn on both lights AFTER 11pm. This design made the separation of Automated operation dawn / dusk off at 11pm then 11pm to 4am PIR triggered lighting using the same lights.
The unit has 2 inputs the time via NTP and the PIR trigger. I used a Wemos Mini clone and a stock PIR. I set the PIR during and sensitivity to midpoint seems to work. The software powers on the lights for 7 mins and then turns them off if there is no activity. I put a delay AFTER the power on command to ensure frequent triggers from the PIR are masked out so the lights come on, stay on for as long as needed and then turn off after 7 min inactivity. The serial print code shows the logic variables and makes this clear for debugging.
I use a HTTPGET to call the ESP with the 433 Transmitter so this unit is small = Wimos Mini + PIR
I used the NTP code from " the Guy with a Swiss Accent" to use NTP to grab the time and this is what drives the logic for this unit as its all based on time. The code works and is being tested.
/*
Code for PIR to turn on lights after 11pm
*/
#include
#define DEBUG_ON
#include
#include
#include
#include
#define USE_SERIAL Serial
ESP8266WiFiMulti WiFiMulti;
NTPtime NTPch("ch.pool.ntp.org"); // Choose server pool as required
char *ssid = "WIFI"; // Set you WiFi SSID
char *password = "secret"; // Set you WiFi password
/*
* The structure contains following fields:
* struct strDateTime
{
byte hour;
byte minute;
byte second;
int year;
byte month;
byte day;
byte dayofWeek;
boolean valid;
};
*/
strDateTime dateTime;
int oldval=0, val = 0;
const int pirPin=D5;
boolean enable_pir = false;
void poweron() {
HTTPClient http;
USE_SERIAL.print("[HTTP] begin...\n");
// configure traged server and url
//http.begin("https://192.168.1.12/test.html", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS
http.begin("http://192.168.0.237/HALLON"); //HTTP
USE_SERIAL.print("[HTTP] GET...\n");
// start connection and send HTTP header
int httpCode = http.GET();
// httpCode will be negative on error
if(httpCode > 0) {
// HTTP header has been send and Server response header has been handled
USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server
if(httpCode == HTTP_CODE_OK) {
String payload = http.getString();
USE_SERIAL.println(payload);
}
} else {
USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
delay(420000);
}
void poweroff() {
HTTPClient http;
USE_SERIAL.print("[HTTP] begin...\n");
// configure traged server and url
//http.begin("https://192.168.1.12/test.html", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS
http.begin("http://192.168.0.237/HALLOFF"); //HTTP
USE_SERIAL.print("[HTTP] GET...\n");
// start connection and send HTTP header
int httpCode = http.GET();
// httpCode will be negative on error
if(httpCode > 0) {
// HTTP header has been send and Server response header has been handled
USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server
if(httpCode == HTTP_CODE_OK) {
String payload = http.getString();
USE_SERIAL.println(payload);
}
} else {
USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
delay(500);
}
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println("Booted");
Serial.println("Connecting to Wi-Fi");
pinMode(pirPin, INPUT);
WiFi.mode(WIFI_STA);
WiFi.begin (ssid, password);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.println("WiFi connected");
delay(3000);
}
void loop() {
// first parameter: Time zone in floating point (for India); second parameter: 1 for European summer time; 2 for US daylight saving time (contributed by viewwer, not tested by me)
dateTime = NTPch.getNTPtime(0.0, 1);
// check dateTime.valid before using the returned time
// Use "setSendInterval" or "setRecvTimeout" if required
if(dateTime.valid){
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;
switch (dateTime.hour) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
enable_pir=true;
break;
case 23:
enable_pir=true;
break;
default:
enable_pir=false;
}
NTPch.printDateTime(dateTime);
val = digitalRead(pirPin);
//Now we have read the status of the PIR has it changed?
boolean turn_off=false, turn_on=false, samestate=false;
//Turn Off ?
if (oldval==1 && val==0)
{
turn_off=true;
}
//Turn On?
if(oldval==0 && val==1)
{
turn_on=true;
}
//No Change?
if(oldval==val)
{
samestate=true;
}
Serial.print("Time to Enable PIR=");
Serial.print(enable_pir);
Serial.print(", PIR=");
Serial.print(val);
Serial.print(" ,OLDVAL=");
Serial.println(oldval);
oldval=val;
if (enable_pir){
//Process state change
if (turn_on){
Serial.print("Turn on light");
poweron();
}
if (turn_off){
Serial.print("Turn off light");
poweroff();
}
if (!samestate)
{if (enable_pir)
{Serial.println(", Enable PIR");}
else
{Serial.println(", Automated control no need for PIR");
}
}
}
}
}