Created dependency subfolder

(this eases compilation since all libraries are included except the ESP8266 core and NeoPixelBus)
Disabled serial debug output of Alexa library, may be re-enabled in .h-Files ifneedbe
Added &SR= to set random hue
Added &ST= to manually set time without NTP
Secondary color buttons now functional
Shifted effect by 1, range is now 1-25
Effect 0 is now the default boot setting
Fixed preset function not calling GIO() in js, which caused a delayed action
This commit is contained in:
cschwinne 2017-12-11 23:59:12 +01:00
parent d9587259f3
commit 60530a2931
31 changed files with 1521 additions and 98 deletions

BIN
bin/wled04p_1712111_RGB.bin Normal file

Binary file not shown.

View File

@ -255,12 +255,14 @@ class WS2812FX : public NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp8266Uart800Kb
isLocked(int i);
uint8_t
get_random_wheel_index(uint8_t),
getMode(void),
getSpeed(void),
getBrightness(void),
getModeCount(void);
uint32_t
color_wheel(uint8_t),
getColor(void);
private:
@ -349,7 +351,6 @@ class WS2812FX : public NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp8266Uart800Kb
uint8_t
minval(uint8_t v, uint8_t w),
maxval(uint8_t v, uint8_t w),
get_random_wheel_index(uint8_t),
_mode_index,
_speed,
_cc_i1,
@ -365,7 +366,6 @@ class WS2812FX : public NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp8266Uart800Kb
uint32_t
getPixelColor(uint16_t i),
color_wheel(uint8_t),
_color,
_color_sec,
_counter_mode_call,

File diff suppressed because one or more lines are too long

View File

@ -103,12 +103,12 @@
setHS(Cf.SR.value,Cf.SG.value,Cf.SB.value);
SetHSB();
nlb.style.fill=(nla)?bCol:dC;
switch (nState)
switch(nState)
{
case 0: gId("path1").style.fill = dC; gId("path2").style.fill = dC; break;
case 1: gId("path1").style.fill = bCol; gId("path2").style.fill = dC; break;
case 2: gId("path1").style.fill = dC;gId("path2").style.fill = bCol; break;
case 3: gId("path1").style.fill = bCol; gId("path2").style.fill = bCol; break;
case 0: gId("path1").style.fill = dC; gId("path2").style.fill = dC;break;
case 1: gId("path1").style.fill = bCol; gId("path2").style.fill = dC;break;
case 2: gId("path1").style.fill = dC;gId("path2").style.fill = bCol;break;
case 3: gId("path1").style.fill = bCol; gId("path2").style.fill = bCol;
}
tgb.style.fill=(Cf.SA.value>0)?bCol:dC;
ccX.style.display=(Cf.TF.value>52)?"block":"none";
@ -255,6 +255,7 @@
if(d.Cf.FC.checked){resp+="&PX=";resp+=d.Cf.FF.value;}
}
}
GIO();
}
function OpenSettings()
{
@ -293,16 +294,16 @@
if (nState>3) nState=0;
switch (nState)
{
case 0: resp+="&SN=0&RN=0"; break;
case 1: resp+="&SN=0&RN=1"; break;
case 2: resp+="&SN=1&RN=0"; break;
case 3: resp+="&SN=1&RN=1"; break;
case 0: resp+="&SN=0&RN=0";break;
case 1: resp+="&SN=0&RN=1";break;
case 2: resp+="&SN=1&RN=0";break;
case 3: resp+="&SN=1&RN=1";
}
UV();
GIO();
}
function setHS() {
var rr, gg, bb,
var rr,gg,bb,
r=arguments[0]/255,
g=arguments[1]/255,
b=arguments[2]/255,
@ -351,7 +352,7 @@
case 2: r=p,g=v,b=t;break;
case 3: r=p,g=q,b=v;break;
case 4: r=t,g=p,b=v;break;
case 5: r=v,g=p,b=q;break;
case 5: r=v,g=p,b=q;
}
d.Cf.SR.value=r;
d.Cf.SG.value=g;
@ -368,7 +369,19 @@
resp+=d.Cf.HF.value;
resp+=(d.Cf.SC.checked)?"&CF=1":"&CF=0";
resp+=(d.Cf.EC.checked)?"&CE=1":"&CE=0";
UV();
GIO();
}
function ColSec(i)
{
switch(i)
{
case 0: resp+="&SW";break;
case 1: resp+="&SB";break;
case 2: resp+="&SR=1";break;
case 3: resp+="&SP";break;
case 4: resp+="&SC";break;
case 5: resp+="&SR=0";
}
GIO();
}
</script>
@ -601,11 +614,12 @@
<svg id="fof" onclick="SwitchFX(100)"><use xlink:href="#lnr-rocket"></use></svg>
<br><input id="fxI" name = "TF" type="number" value="0" min="0" max="57" step="1" onchange="GetFX()"><br><br>
Set secondary color to
<button type="button" onclick="colSec(0)">White</button>
<button type="button" onclick="colSec(1)">Black</button>
<button type="button" onclick="colSec(2)">Random</button>
<button type="button" onclick="colSec(3)">Primary</button>
<button type="button" onclick="colSec(4)">Swap P/S</button>
<button type="button" onclick="ColSec(0)">White</button>
<button type="button" onclick="ColSec(1)">Black</button>
<button type="button" onclick="ColSec(2)">Random</button>
<button type="button" onclick="ColSec(3)">Primary</button>
<button type="button" onclick="ColSec(4)">Swap P/S</button>
or <button type="button" onclick="ColSec(5)">Set Primary to Random</button>
<div id="ccX" class = "toolsCC">
<br>Custom Theater Chase<br>
using <input id="ccP" name = "PF" type="number" value="2" min="0" max="255" step="1" onchange="GetCC()"> primary and
@ -620,8 +634,9 @@
<svg id="psp" onclick="SwitchPS(-1)"><use xlink:href="#lnr-arrow-left-circle"></use></svg>
<svg id="psn" onclick="SwitchPS(1)"><use xlink:href="#lnr-arrow-right-circle"></use></svg>
<svg id="pss" onclick="PSIO(true)"><use xlink:href="#lnr-arrow-down-circle"></use></svg>
<br><input id="psI" name = "FF" type="number" value="0" min="0" max="24" step="1"><br><br>
Click checkmark to apply <input type="checkbox" checked="true" name="BC"> brightness, <input type="checkbox" checked="true" name="CC"> color and <input type="checkbox" checked="true" name="FC"> effects.
<br><input id="psI" name = "FF" type="number" value="0" min="0" max="25" step="1"><br><br>
Click checkmark to apply <input type="checkbox" checked="true" name="BC"> brightness, <input type="checkbox" checked="true" name="CC"> color and <input type="checkbox" checked="true" name="FC"> effects.<br>
Effect 0 is the configuration when the light is powered up.
</div>
<div id="slX" class="sliderX">
<input type="range" title="Effect Speed" class="sliders" name="SX" value="0" min="0" max="255" step="1" onchange="GetFX()"> </div> <br>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,23 @@
https://github.com/kakopappa/arduino-esp8266-alexa-multiple-wemo-switch
The MIT License (MIT)
Copyright (c) 2015
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,11 +1,21 @@
#include "Switch.h"
#include "CallbackFunction.h"
//#define DEBUG
#ifdef DEBUG
#define DEBUG_PRINT(x) Serial.print (x)
#define DEBUG_PRINTLN(x) Serial.println (x)
#define DEBUG_PRINTF(x) Serial.printf (x)
#else
#define DEBUG_PRINT(x)
#define DEBUG_PRINTLN(x)
#define DEBUG_PRINTF(x)
#endif
//<<constructor>>
Switch::Switch(){
Serial.println("default constructor called");
DEBUG_PRINTLN("default constructor called");
}
//Switch::Switch(String alexaInvokeName,unsigned int port){
Switch::Switch(String alexaInvokeName, unsigned int port, CallbackFunction oncb, CallbackFunction offcb){
@ -62,12 +72,12 @@ void Switch::startWebServer(){
//server->onNotFound(handleNotFound);
server->begin();
Serial.println("WebServer started on port: ");
Serial.println(localPort);
DEBUG_PRINTLN("WebServer started on port: ");
DEBUG_PRINTLN(localPort);
}
void Switch::handleEventservice(){
Serial.println(" ########## Responding to eventservice.xml ... ########\n");
DEBUG_PRINTLN(" ########## Responding to eventservice.xml ... ########\n");
String eventservice_xml = "<?scpd xmlns=\"urn:Belkin:service-1-0\"?>"
"<actionList>"
@ -101,23 +111,23 @@ void Switch::handleEventservice(){
}
void Switch::handleUpnpControl(){
Serial.println("########## Responding to /upnp/control/basicevent1 ... ##########");
DEBUG_PRINTLN("########## Responding to /upnp/control/basicevent1 ... ##########");
//for (int x=0; x <= HTTP.args(); x++) {
// Serial.println(HTTP.arg(x));
// DEBUG_PRINTLN(HTTP.arg(x));
//}
String request = server->arg(0);
Serial.print("request:");
Serial.println(request);
DEBUG_PRINT("request:");
DEBUG_PRINTLN(request);
if(request.indexOf("<BinaryState>1</BinaryState>") > 0) {
Serial.println("Got Turn on request");
DEBUG_PRINTLN("Got Turn on request");
onCallback();
}
if(request.indexOf("<BinaryState>0</BinaryState>") > 0) {
Serial.println("Got Turn off request");
DEBUG_PRINTLN("Got Turn off request");
offCallback();
}
@ -129,7 +139,7 @@ void Switch::handleRoot(){
}
void Switch::handleSetupXml(){
Serial.println(" ########## Responding to setup.xml ... ########\n");
DEBUG_PRINTLN(" ########## Responding to setup.xml ... ########\n");
IPAddress localIP = WiFi.localIP();
char s[16];
@ -161,8 +171,8 @@ void Switch::handleSetupXml(){
server->send(200, "text/xml", setup_xml.c_str());
Serial.print("Sending :");
Serial.println(setup_xml);
DEBUG_PRINT("Sending :");
DEBUG_PRINTLN(setup_xml);
}
String Switch::getAlexaInvokeName() {
@ -170,11 +180,11 @@ String Switch::getAlexaInvokeName() {
}
void Switch::respondToSearch(IPAddress& senderIP, unsigned int senderPort) {
Serial.println("");
Serial.print("Sending response to ");
Serial.println(senderIP);
Serial.print("Port : ");
Serial.println(senderPort);
DEBUG_PRINTLN("");
DEBUG_PRINT("Sending response to ");
DEBUG_PRINTLN(senderIP);
DEBUG_PRINT("Port : ");
DEBUG_PRINTLN(senderPort);
IPAddress localIP = WiFi.localIP();
char s[16];
@ -197,5 +207,5 @@ void Switch::respondToSearch(IPAddress& senderIP, unsigned int senderPort) {
UDP.write(response.c_str());
UDP.endPacket();
Serial.println("Response sent !");
DEBUG_PRINTLN("Response sent !");
}

View File

@ -1,6 +1,18 @@
#include "UpnpBroadcastResponder.h"
#include "Switch.h"
#include <functional>
//#define DEBUG
#ifdef DEBUG
#define DEBUG_PRINT(x) Serial.print (x)
#define DEBUG_PRINTLN(x) Serial.println (x)
#define DEBUG_PRINTF(x) Serial.printf (x)
#else
#define DEBUG_PRINT(x)
#define DEBUG_PRINTLN(x)
#define DEBUG_PRINTF(x)
#endif
// Multicast declarations
IPAddress ipMulti(239, 255, 255, 250);
@ -24,18 +36,18 @@ UpnpBroadcastResponder::~UpnpBroadcastResponder(){/*nothing to destruct*/}
bool UpnpBroadcastResponder::beginUdpMulticast(){
boolean state = false;
Serial.println("Begin multicast ..");
DEBUG_PRINTLN("Begin multicast ..");
if(UDP.beginMulticast(WiFi.localIP(), ipMulti, portMulti)) {
Serial.print("Udp multicast server started at ");
Serial.print(ipMulti);
Serial.print(":");
Serial.println(portMulti);
DEBUG_PRINT("Udp multicast server started at ");
DEBUG_PRINT(ipMulti);
DEBUG_PRINT(":");
DEBUG_PRINTLN(portMulti);
state = true;
}
else{
Serial.println("Connection failed");
DEBUG_PRINTLN("Connection failed");
}
return state;
@ -44,10 +56,10 @@ bool UpnpBroadcastResponder::beginUdpMulticast(){
//Switch *ptrArray;
void UpnpBroadcastResponder::addDevice(Switch& device) {
Serial.print("Adding switch : ");
Serial.print(device.getAlexaInvokeName());
Serial.print(" index : ");
Serial.println(numOfSwitchs);
DEBUG_PRINT("Adding switch : ");
DEBUG_PRINT(device.getAlexaInvokeName());
DEBUG_PRINT(" index : ");
DEBUG_PRINTLN(numOfSwitchs);
switches[numOfSwitchs] = device;
numOfSwitchs++;
@ -69,7 +81,7 @@ void UpnpBroadcastResponder::serverLoop(){
if(request.indexOf('M-SEARCH') > 0) {
if(request.indexOf("urn:Belkin:device:**") > 0) {
Serial.println("Got UDP Belkin Request..");
DEBUG_PRINTLN("Got UDP Belkin Request..");
// int arrSize = sizeof(switchs) / sizeof(Switch);

View File

@ -0,0 +1,97 @@
/* DateStrings.cpp
* Definitions for date strings for use with the Time library
*
* Updated for Arduino 1.5.7 18 July 2014
*
* No memory is consumed in the sketch if your code does not call any of the string methods
* You can change the text of the strings, make sure the short strings are each exactly 3 characters
* the long strings can be any length up to the constant dt_MAX_STRING_LEN defined in TimeLib.h
*
*/
#if defined(__AVR__)
#include <avr/pgmspace.h>
#else
// for compatiblity with Arduino Due and Teensy 3.0 and maybe others?
#define PROGMEM
#define PGM_P const char *
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) (*(const unsigned char **)(addr))
#define strcpy_P(dest, src) strcpy((dest), (src))
#endif
#include <string.h> // for strcpy_P or strcpy
#include "TimeLib.h"
// the short strings for each day or month must be exactly dt_SHORT_STR_LEN
#define dt_SHORT_STR_LEN 3 // the length of short strings
static char buffer[dt_MAX_STRING_LEN+1]; // must be big enough for longest string and the terminating null
const char monthStr0[] PROGMEM = "";
const char monthStr1[] PROGMEM = "January";
const char monthStr2[] PROGMEM = "February";
const char monthStr3[] PROGMEM = "March";
const char monthStr4[] PROGMEM = "April";
const char monthStr5[] PROGMEM = "May";
const char monthStr6[] PROGMEM = "June";
const char monthStr7[] PROGMEM = "July";
const char monthStr8[] PROGMEM = "August";
const char monthStr9[] PROGMEM = "September";
const char monthStr10[] PROGMEM = "October";
const char monthStr11[] PROGMEM = "November";
const char monthStr12[] PROGMEM = "December";
const PROGMEM char * const PROGMEM monthNames_P[] =
{
monthStr0,monthStr1,monthStr2,monthStr3,monthStr4,monthStr5,monthStr6,
monthStr7,monthStr8,monthStr9,monthStr10,monthStr11,monthStr12
};
const char monthShortNames_P[] PROGMEM = "ErrJanFebMarAprMayJunJulAugSepOctNovDec";
const char dayStr0[] PROGMEM = "Err";
const char dayStr1[] PROGMEM = "Sunday";
const char dayStr2[] PROGMEM = "Monday";
const char dayStr3[] PROGMEM = "Tuesday";
const char dayStr4[] PROGMEM = "Wednesday";
const char dayStr5[] PROGMEM = "Thursday";
const char dayStr6[] PROGMEM = "Friday";
const char dayStr7[] PROGMEM = "Saturday";
const PROGMEM char * const PROGMEM dayNames_P[] =
{
dayStr0,dayStr1,dayStr2,dayStr3,dayStr4,dayStr5,dayStr6,dayStr7
};
const char dayShortNames_P[] PROGMEM = "ErrSunMonTueWedThuFriSat";
/* functions to return date strings */
char* monthStr(uint8_t month)
{
strcpy_P(buffer, (PGM_P)pgm_read_word(&(monthNames_P[month])));
return buffer;
}
char* monthShortStr(uint8_t month)
{
for (int i=0; i < dt_SHORT_STR_LEN; i++)
buffer[i] = pgm_read_byte(&(monthShortNames_P[i+ (month*dt_SHORT_STR_LEN)]));
buffer[dt_SHORT_STR_LEN] = 0;
return buffer;
}
char* dayStr(uint8_t day)
{
strcpy_P(buffer, (PGM_P)pgm_read_word(&(dayNames_P[day])));
return buffer;
}
char* dayShortStr(uint8_t day)
{
uint8_t index = day*dt_SHORT_STR_LEN;
for (int i=0; i < dt_SHORT_STR_LEN; i++)
buffer[i] = pgm_read_byte(&(dayShortNames_P[index + i]));
buffer[dt_SHORT_STR_LEN] = 0;
return buffer;
}

View File

@ -0,0 +1,25 @@
https://github.com/PaulStoffregen/Time/
time.c - low level time and date functions
Copyright (c) Michael Margolis 2009-2014
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1.0 6 Jan 2010 - initial release
1.1 12 Feb 2010 - fixed leap year calculation error
1.2 1 Nov 2010 - fixed setTime bug (thanks to Korman for this)
1.3 24 Mar 2012 - many edits by Paul Stoffregen: fixed timeStatus() to update
status, updated examples for Arduino 1.0, fixed ARM
compatibility issues, added TimeArduinoDue and TimeTeensy3
examples, add error checking and messages to RTC examples,
add examples to DS1307RTC library.
1.4 5 Sep 2014 - compatibility with Arduino 1.5.7

View File

@ -0,0 +1,135 @@
Readme file for Arduino Time Library
Time is a library that provides timekeeping functionality for Arduino.
The code is derived from the Playground DateTime library but is updated
to provide an API that is more flexable and easier to use.
A primary goal was to enable date and time functionality that can be used with
a variety of external time sources with minimum differences required in sketch logic.
Example sketches illustrate how similar sketch code can be used with: a Real Time Clock,
internet NTP time service, GPS time data, and Serial time messages from a computer
for time synchronization.
The functions available in the library include:
hour(); // the hour now (0-23)
minute(); // the minute now (0-59)
second(); // the second now (0-59)
day(); // the day now (1-31)
weekday(); // day of the week (1-7), Sunday is day 1
month(); // the month now (1-12)
year(); // the full four digit year: (2009, 2010 etc)
there are also functions to return the hour in 12 hour format
hourFormat12(); // the hour now in 12 hour format
isAM(); // returns true if time now is AM
isPM(); // returns true if time now is PM
now(); // returns the current time as seconds since Jan 1 1970
The time and date functions can take an optional parameter for the time. This prevents
errors if the time rolls over between elements. For example, if a new minute begins
between getting the minute and second, the values will be inconsistent. Using the
following functions eliminates this probglem
time_t t = now(); // store the current time in time variable t
hour(t); // returns the hour for the given time t
minute(t); // returns the minute for the given time t
second(t); // returns the second for the given time t
day(t); // the day for the given time t
weekday(t); // day of the week for the given time t
month(t); // the month for the given time t
year(t); // the year for the given time t
Functions for managing the timer services are:
setTime(t); // set the system time to the give time t
setTime(hr,min,sec,day,mnth,yr); // alternative to above, yr is 2 or 4 digit yr
// (2010 or 10 sets year to 2010)
adjustTime(adjustment); // adjust system time by adding the adjustment value
timeStatus(); // indicates if time has been set and recently synchronized
// returns one of the following enumerations:
timeNotSet // the time has never been set, the clock started at Jan 1 1970
timeNeedsSync // the time had been set but a sync attempt did not succeed
timeSet // the time is set and is synced
Time and Date values are not valid if the status is timeNotSet. Otherwise values can be used but
the returned time may have drifted if the status is timeNeedsSync.
setSyncProvider(getTimeFunction); // set the external time provider
setSyncInterval(interval); // set the number of seconds between re-sync
There are many convenience macros in the time.h file for time constants and conversion
of time units.
To use the library, copy the download to the Library directory.
The Time directory contains the Time library and some example sketches
illustrating how the library can be used with various time sources:
- TimeSerial.pde shows Arduino as a clock without external hardware.
It is synchronized by time messages sent over the serial port.
A companion Processing sketch will automatically provide these messages
if it is running and connected to the Arduino serial port.
- TimeSerialDateStrings.pde adds day and month name strings to the sketch above
Short (3 character) and long strings are available to print the days of
the week and names of the months.
- TimeRTC uses a DS1307 real time clock to provide time synchronization.
A basic RTC library named DS1307RTC is included in the download.
To run this sketch the DS1307RTC library must be installed.
- TimeRTCSet is similar to the above and adds the ability to set the Real Time Clock
- TimeRTCLog demonstrates how to calculate the difference between times.
It is a vary simple logger application that monitors events on digtial pins
and prints (to the serial port) the time of an event and the time period since
the previous event.
- TimeNTP uses the Arduino Ethernet shield to access time using the internet NTP time service.
The NTP protocol uses UDP and the UdpBytewise library is required, see:
http://bitbucket.org/bjoern/arduino_osc/src/14667490521f/libraries/Ethernet/
- TimeGPS gets time from a GPS
This requires the TinyGPS library from Mikal Hart:
http://arduiniana.org/libraries/TinyGPS
Differences between this code and the playground DateTime library
although the Time library is based on the DateTime codebase, the API has changed.
Changes in the Time library API:
- time elements are functions returning int (they are variables in DateTime)
- Years start from 1970
- days of the week and months start from 1 (they start from 0 in DateTime)
- DateStrings do not require a seperate library
- time elements can be accessed non-atomically (in DateTime they are always atomic)
- function added to automatically sync time with extrnal source
- localTime and maketime parameters changed, localTime renamed to breakTime
Technical notes:
Internal system time is based on the standard Unix time_t.
The value is the number of seconds since Jan 1 1970.
System time begins at zero when the sketch starts.
The internal time can be automatically synchronized at regular intervals to an external time source.
This is enabled by calling the setSyncProvider(provider) function - the provider argument is
the address of a function that returns the current time as a time_t.
See the sketches in the examples directory for usage.
The default interval for re-syncing the time is 5 minutes but can be changed by calling the
setSyncInterval( interval) method to set the number of seconds between re-sync attempts.
The Time library defines a structure for holding time elements that is a compact version of the C tm structure.
All the members of the Arduino tm structure are bytes and the year is offset from 1970.
Convenience macros provide conversion to and from the Arduino format.
Low level functions to convert between system time and individual time elements are provided:
breakTime(time, &tm); // break time_t into elements stored in tm struct
makeTime(&tm); // return time_t from elements stored in tm struct
The DS1307RTC library included in the download provides an example of how a time provider
can use the low level functions to interface with the Time library.

View File

@ -0,0 +1,321 @@
/*
time.c - low level time and date functions
Copyright (c) Michael Margolis 2009-2014
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1.0 6 Jan 2010 - initial release
1.1 12 Feb 2010 - fixed leap year calculation error
1.2 1 Nov 2010 - fixed setTime bug (thanks to Korman for this)
1.3 24 Mar 2012 - many edits by Paul Stoffregen: fixed timeStatus() to update
status, updated examples for Arduino 1.0, fixed ARM
compatibility issues, added TimeArduinoDue and TimeTeensy3
examples, add error checking and messages to RTC examples,
add examples to DS1307RTC library.
1.4 5 Sep 2014 - compatibility with Arduino 1.5.7
*/
#if ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
#include "TimeLib.h"
static tmElements_t tm; // a cache of time elements
static time_t cacheTime; // the time the cache was updated
static uint32_t syncInterval = 300; // time sync will be attempted after this many seconds
void refreshCache(time_t t) {
if (t != cacheTime) {
breakTime(t, tm);
cacheTime = t;
}
}
int hour() { // the hour now
return hour(now());
}
int hour(time_t t) { // the hour for the given time
refreshCache(t);
return tm.Hour;
}
int hourFormat12() { // the hour now in 12 hour format
return hourFormat12(now());
}
int hourFormat12(time_t t) { // the hour for the given time in 12 hour format
refreshCache(t);
if( tm.Hour == 0 )
return 12; // 12 midnight
else if( tm.Hour > 12)
return tm.Hour - 12 ;
else
return tm.Hour ;
}
uint8_t isAM() { // returns true if time now is AM
return !isPM(now());
}
uint8_t isAM(time_t t) { // returns true if given time is AM
return !isPM(t);
}
uint8_t isPM() { // returns true if PM
return isPM(now());
}
uint8_t isPM(time_t t) { // returns true if PM
return (hour(t) >= 12);
}
int minute() {
return minute(now());
}
int minute(time_t t) { // the minute for the given time
refreshCache(t);
return tm.Minute;
}
int second() {
return second(now());
}
int second(time_t t) { // the second for the given time
refreshCache(t);
return tm.Second;
}
int day(){
return(day(now()));
}
int day(time_t t) { // the day for the given time (0-6)
refreshCache(t);
return tm.Day;
}
int weekday() { // Sunday is day 1
return weekday(now());
}
int weekday(time_t t) {
refreshCache(t);
return tm.Wday;
}
int month(){
return month(now());
}
int month(time_t t) { // the month for the given time
refreshCache(t);
return tm.Month;
}
int year() { // as in Processing, the full four digit year: (2009, 2010 etc)
return year(now());
}
int year(time_t t) { // the year for the given time
refreshCache(t);
return tmYearToCalendar(tm.Year);
}
/*============================================================================*/
/* functions to convert to and from system time */
/* These are for interfacing with time serivces and are not normally needed in a sketch */
// leap year calulator expects year argument as years offset from 1970
#define LEAP_YEAR(Y) ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) )
static const uint8_t monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31}; // API starts months from 1, this array starts from 0
void breakTime(time_t timeInput, tmElements_t &tm){
// break the given time_t into time components
// this is a more compact version of the C library localtime function
// note that year is offset from 1970 !!!
uint8_t year;
uint8_t month, monthLength;
uint32_t time;
unsigned long days;
time = (uint32_t)timeInput;
tm.Second = time % 60;
time /= 60; // now it is minutes
tm.Minute = time % 60;
time /= 60; // now it is hours
tm.Hour = time % 24;
time /= 24; // now it is days
tm.Wday = ((time + 4) % 7) + 1; // Sunday is day 1
year = 0;
days = 0;
while((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) {
year++;
}
tm.Year = year; // year is offset from 1970
days -= LEAP_YEAR(year) ? 366 : 365;
time -= days; // now it is days in this year, starting at 0
days=0;
month=0;
monthLength=0;
for (month=0; month<12; month++) {
if (month==1) { // february
if (LEAP_YEAR(year)) {
monthLength=29;
} else {
monthLength=28;
}
} else {
monthLength = monthDays[month];
}
if (time >= monthLength) {
time -= monthLength;
} else {
break;
}
}
tm.Month = month + 1; // jan is month 1
tm.Day = time + 1; // day of month
}
time_t makeTime(tmElements_t &tm){
// assemble time elements into time_t
// note year argument is offset from 1970 (see macros in time.h to convert to other formats)
// previous version used full four digit year (or digits since 2000),i.e. 2009 was 2009 or 9
int i;
uint32_t seconds;
// seconds from 1970 till 1 jan 00:00:00 of the given year
seconds= tm.Year*(SECS_PER_DAY * 365);
for (i = 0; i < tm.Year; i++) {
if (LEAP_YEAR(i)) {
seconds += SECS_PER_DAY; // add extra days for leap years
}
}
// add days for this year, months start from 1
for (i = 1; i < tm.Month; i++) {
if ( (i == 2) && LEAP_YEAR(tm.Year)) {
seconds += SECS_PER_DAY * 29;
} else {
seconds += SECS_PER_DAY * monthDays[i-1]; //monthDay array starts from 0
}
}
seconds+= (tm.Day-1) * SECS_PER_DAY;
seconds+= tm.Hour * SECS_PER_HOUR;
seconds+= tm.Minute * SECS_PER_MIN;
seconds+= tm.Second;
return (time_t)seconds;
}
/*=====================================================*/
/* Low level system time functions */
static uint32_t sysTime = 0;
static uint32_t prevMillis = 0;
static uint32_t nextSyncTime = 0;
static timeStatus_t Status = timeNotSet;
getExternalTime getTimePtr; // pointer to external sync function
//setExternalTime setTimePtr; // not used in this version
#ifdef TIME_DRIFT_INFO // define this to get drift data
time_t sysUnsyncedTime = 0; // the time sysTime unadjusted by sync
#endif
time_t now() {
// calculate number of seconds passed since last call to now()
while (millis() - prevMillis >= 1000) {
// millis() and prevMillis are both unsigned ints thus the subtraction will always be the absolute value of the difference
sysTime++;
prevMillis += 1000;
#ifdef TIME_DRIFT_INFO
sysUnsyncedTime++; // this can be compared to the synced time to measure long term drift
#endif
}
if (nextSyncTime <= sysTime) {
if (getTimePtr != 0) {
time_t t = getTimePtr();
if (t != 0) {
setTime(t);
} else {
nextSyncTime = sysTime + syncInterval;
Status = (Status == timeNotSet) ? timeNotSet : timeNeedsSync;
}
}
}
return (time_t)sysTime;
}
void setTime(time_t t) {
#ifdef TIME_DRIFT_INFO
if(sysUnsyncedTime == 0)
sysUnsyncedTime = t; // store the time of the first call to set a valid Time
#endif
sysTime = (uint32_t)t;
nextSyncTime = (uint32_t)t + syncInterval;
Status = timeSet;
prevMillis = millis(); // restart counting from now (thanks to Korman for this fix)
}
void setTime(int hr,int min,int sec,int dy, int mnth, int yr){
// year can be given as full four digit year or two digts (2010 or 10 for 2010);
//it is converted to years since 1970
if( yr > 99)
yr = yr - 1970;
else
yr += 30;
tm.Year = yr;
tm.Month = mnth;
tm.Day = dy;
tm.Hour = hr;
tm.Minute = min;
tm.Second = sec;
setTime(makeTime(tm));
}
void adjustTime(long adjustment) {
sysTime += adjustment;
}
// indicates if time has been set and recently synchronized
timeStatus_t timeStatus() {
now(); // required to actually update the status
return Status;
}
void setSyncProvider( getExternalTime getTimeFunction){
getTimePtr = getTimeFunction;
nextSyncTime = sysTime;
now(); // this will sync the clock
}
void setSyncInterval(time_t interval){ // set the number of seconds between re-sync
syncInterval = (uint32_t)interval;
nextSyncTime = sysTime + syncInterval;
}

View File

@ -0,0 +1 @@
#include "TimeLib.h"

View File

@ -0,0 +1,144 @@
/*
time.h - low level time and date functions
*/
/*
July 3 2011 - fixed elapsedSecsThisWeek macro (thanks Vincent Valdy for this)
- fixed daysToTime_t macro (thanks maniacbug)
*/
#ifndef _Time_h
#ifdef __cplusplus
#define _Time_h
#include <inttypes.h>
#ifndef __AVR__
#include <sys/types.h> // for __time_t_defined, but avr libc lacks sys/types.h
#endif
#if !defined(__time_t_defined) // avoid conflict with newlib or other posix libc
typedef unsigned long time_t;
#endif
// This ugly hack allows us to define C++ overloaded functions, when included
// from within an extern "C", as newlib's sys/stat.h does. Actually it is
// intended to include "time.h" from the C library (on ARM, but AVR does not
// have that file at all). On Mac and Windows, the compiler will find this
// "Time.h" instead of the C library "time.h", so we may cause other weird
// and unpredictable effects by conflicting with the C library header "time.h",
// but at least this hack lets us define C++ functions as intended. Hopefully
// nothing too terrible will result from overriding the C library header?!
extern "C++" {
typedef enum {timeNotSet, timeNeedsSync, timeSet
} timeStatus_t ;
typedef enum {
dowInvalid, dowSunday, dowMonday, dowTuesday, dowWednesday, dowThursday, dowFriday, dowSaturday
} timeDayOfWeek_t;
typedef enum {
tmSecond, tmMinute, tmHour, tmWday, tmDay,tmMonth, tmYear, tmNbrFields
} tmByteFields;
typedef struct {
uint8_t Second;
uint8_t Minute;
uint8_t Hour;
uint8_t Wday; // day of week, sunday is day 1
uint8_t Day;
uint8_t Month;
uint8_t Year; // offset from 1970;
} tmElements_t, TimeElements, *tmElementsPtr_t;
//convenience macros to convert to and from tm years
#define tmYearToCalendar(Y) ((Y) + 1970) // full four digit year
#define CalendarYrToTm(Y) ((Y) - 1970)
#define tmYearToY2k(Y) ((Y) - 30) // offset is from 2000
#define y2kYearToTm(Y) ((Y) + 30)
typedef time_t(*getExternalTime)();
//typedef void (*setExternalTime)(const time_t); // not used in this version
/*==============================================================================*/
/* Useful Constants */
#define SECS_PER_MIN ((time_t)(60UL))
#define SECS_PER_HOUR ((time_t)(3600UL))
#define SECS_PER_DAY ((time_t)(SECS_PER_HOUR * 24UL))
#define DAYS_PER_WEEK ((time_t)(7UL))
#define SECS_PER_WEEK ((time_t)(SECS_PER_DAY * DAYS_PER_WEEK))
#define SECS_PER_YEAR ((time_t)(SECS_PER_WEEK * 52UL))
#define SECS_YR_2000 ((time_t)(946684800UL)) // the time at the start of y2k
/* Useful Macros for getting elapsed time */
#define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN)
#define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN)
#define numberOfHours(_time_) (( _time_% SECS_PER_DAY) / SECS_PER_HOUR)
#define dayOfWeek(_time_) ((( _time_ / SECS_PER_DAY + 4) % DAYS_PER_WEEK)+1) // 1 = Sunday
#define elapsedDays(_time_) ( _time_ / SECS_PER_DAY) // this is number of days since Jan 1 1970
#define elapsedSecsToday(_time_) (_time_ % SECS_PER_DAY) // the number of seconds since last midnight
// The following macros are used in calculating alarms and assume the clock is set to a date later than Jan 1 1971
// Always set the correct time before settting alarms
#define previousMidnight(_time_) (( _time_ / SECS_PER_DAY) * SECS_PER_DAY) // time at the start of the given day
#define nextMidnight(_time_) ( previousMidnight(_time_) + SECS_PER_DAY ) // time at the end of the given day
#define elapsedSecsThisWeek(_time_) (elapsedSecsToday(_time_) + ((dayOfWeek(_time_)-1) * SECS_PER_DAY) ) // note that week starts on day 1
#define previousSunday(_time_) (_time_ - elapsedSecsThisWeek(_time_)) // time at the start of the week for the given time
#define nextSunday(_time_) ( previousSunday(_time_)+SECS_PER_WEEK) // time at the end of the week for the given time
/* Useful Macros for converting elapsed time to a time_t */
#define minutesToTime_t ((M)) ( (M) * SECS_PER_MIN)
#define hoursToTime_t ((H)) ( (H) * SECS_PER_HOUR)
#define daysToTime_t ((D)) ( (D) * SECS_PER_DAY) // fixed on Jul 22 2011
#define weeksToTime_t ((W)) ( (W) * SECS_PER_WEEK)
/*============================================================================*/
/* time and date functions */
int hour(); // the hour now
int hour(time_t t); // the hour for the given time
int hourFormat12(); // the hour now in 12 hour format
int hourFormat12(time_t t); // the hour for the given time in 12 hour format
uint8_t isAM(); // returns true if time now is AM
uint8_t isAM(time_t t); // returns true the given time is AM
uint8_t isPM(); // returns true if time now is PM
uint8_t isPM(time_t t); // returns true the given time is PM
int minute(); // the minute now
int minute(time_t t); // the minute for the given time
int second(); // the second now
int second(time_t t); // the second for the given time
int day(); // the day now
int day(time_t t); // the day for the given time
int weekday(); // the weekday now (Sunday is day 1)
int weekday(time_t t); // the weekday for the given time
int month(); // the month now (Jan is month 1)
int month(time_t t); // the month for the given time
int year(); // the full four digit year: (2009, 2010 etc)
int year(time_t t); // the year for the given time
time_t now(); // return the current time as seconds since Jan 1 1970
void setTime(time_t t);
void setTime(int hr,int min,int sec,int day, int month, int yr);
void adjustTime(long adjustment);
/* date strings */
#define dt_MAX_STRING_LEN 9 // length of longest date string (excluding terminating null)
char* monthStr(uint8_t month);
char* dayStr(uint8_t day);
char* monthShortStr(uint8_t month);
char* dayShortStr(uint8_t day);
/* time sync functions */
timeStatus_t timeStatus(); // indicates if time has been set and recently synchronized
void setSyncProvider( getExternalTime getTimeFunction); // identify the external time provider
void setSyncInterval(time_t interval); // set the number of seconds between re-sync
/* low level functions to convert to and from system time */
void breakTime(time_t time, tmElements_t &tm); // break time_t into elements
time_t makeTime(tmElements_t &tm); // convert time elements into time_t
} // extern "C++"
#endif // __cplusplus
#endif /* _Time_h */

View File

@ -0,0 +1,34 @@
#######################################
# Syntax Coloring Map For Time
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
time_t KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
now KEYWORD2
second KEYWORD2
minute KEYWORD2
hour KEYWORD2
day KEYWORD2
month KEYWORD2
year KEYWORD2
isAM KEYWORD2
isPM KEYWORD2
weekday KEYWORD2
setTime KEYWORD2
adjustTime KEYWORD2
setSyncProvider KEYWORD2
setSyncInterval KEYWORD2
timeStatus KEYWORD2
TimeLib KEYWORD2
#######################################
# Instances (KEYWORD2)
#######################################
#######################################
# Constants (LITERAL1)
#######################################

View File

@ -0,0 +1,26 @@
{
"name": "Time",
"description": "Time keeping library",
"keywords": "Time, date, hour, minute, second, day, week, month, year, RTC",
"authors": [
{
"name": "Michael Margolis"
},
{
"name": "Paul Stoffregen",
"email": "paul@pjrc.com",
"url": "http://www.pjrc.com",
"maintainer": true
}
],
"repository": {
"type": "git",
"url": "https://github.com/PaulStoffregen/Time"
},
"version": "1.5",
"homepage": "http://playground.arduino.cc/Code/Time",
"frameworks": "Arduino",
"examples": [
"examples/*/*.ino"
]
}

View File

@ -0,0 +1,10 @@
name=Time
version=1.5
author=Michael Margolis
maintainer=Paul Stoffregen
sentence=Timekeeping functionality for Arduino
paragraph=Date and Time functions, with provisions to synchronize to external time sources like GPS and NTP (Internet). This library is often used together with TimeAlarms and DS1307RTC.
category=Timing
url=http://playground.arduino.cc/code/time
architectures=*

View File

@ -0,0 +1,11 @@
#Arduino Timezone Library v1.0
https://github.com/JChristensen/Timezone
LICENSE file
Jack Christensen Mar 2012
![CC BY-SA](http://mirrors.creativecommons.org/presskit/buttons/88x31/png/by-sa.png)
##CC BY-SA
Arduino Timezone Library by Jack Christensen is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to:
Creative Commons
444 Castro Street, Suite 900
Mountain View, CA 94041

View File

@ -0,0 +1,173 @@
#Arduino Timezone Library v1.0
https://github.com/JChristensen/Timezone
ReadMe file
Jack Christensen Mar 2012
![CC BY-SA](http://mirrors.creativecommons.org/presskit/buttons/80x15/png/by-sa.png)
##Introduction
The **Timezone** library is designed to work in conjunction with the [Arduino Time library](http://www.arduino.cc/playground/Code/Time). The Time library must be installed and referenced in your sketch with `#include <Time.h>`. This documentation assumes some familiarity with the Time library.
The primary aim of the **Timezone** library is to convert Universal Coordinated Time (UTC) to the correct local time, whether it is daylight saving time (a.k.a. summer time) or standard time. The time source could be a GPS receiver, an NTP server, or a Real-Time Clock (RTC) set to UTC. But whether a hardware RTC or other time source is even present is immaterial; although the Time library can function as a software RTC without additional hardware, its accuracy is dependent on the accuracy of the microcontroller's system clock.
The **Timezone** library implements two objects to facilitate time zone conversions:
- A **TimeChangeRule** object describes when local time changes to daylight (summer) time, or to standard time, for a particular locale.
- A **Timezone** object uses **TimeChangeRule**s to perform conversions and related functions. It can also write its **TimeChangeRule**s to EEPROM, or read them from EEPROM. Multiple time zones can be represented by defining multiple **Timezone** objects.
##Installation
To use the **Timezone** library:
- Go to https://github.com/JChristensen/Timezone and click the **Download ZIP** button to download the repository as a ZIP file to a convenient location on your PC.
- Uncompress the downloaded file. This will result in a folder containing all the files for the library, that has a name that includes the branch name, for example **Timezone-master**.
- Rename the folder to just **Timezone**.
- Copy the renamed folder to the Arduino sketchbook\libraries folder.
##Examples
The following example sketches are included with the **Timezone** library:
- **Clock:** A simple self-adjusting clock for a single time zone. **TimeChangeRule**s may be optionally read from EEPROM.
- **HardwareRTC:** A self-adjusting clock for one time zone using an external real-time clock, either a DS1307 or DS3231 (e.g. Chronodot) which is set to UTC.
- **WorldClock:** A self-adjusting clock for multiple time zones.
- **WriteRules:** A sketch to write **TimeChangeRule**s to EEPROM.
##Coding TimeChangeRules
Normally these will be coded in pairs for a given time zone: One rule to describe when daylight (summer) time starts, and one to describe when standard time starts.
As an example, here in the Eastern US time zone, Eastern Daylight Time (EDT) starts on the 2nd Sunday in March at 02:00 local time. Eastern Standard Time (EST) starts on the 1st Sunday in November at 02:00 local time.
Define a **TimeChangeRule** as follows:
`TimeChangeRule myRule = {abbrev, week, dow, month, hour, offset};`
Where:
**abbrev** is a character string abbreviation for the time zone; it must be no longer than five characters.
**week** is the week of the month that the rule starts.
**dow** is the day of the week that the rule starts.
**hour** is the hour in local time that the rule starts (0-23).
**offset** is the UTC offset _in minutes_ for the time zone being defined.
For convenience, the following symbolic names can be used:
**week:** First, Second, Third, Fourth, Last
**dow:** Sun, Mon, Tue, Wed, Thu, Fri, Sat
**month:** Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
For the Eastern US time zone, the **TimeChangeRule**s could be defined as follows:
```c++
TimeChangeRule usEDT = {"EDT", Second, Sun, Mar, 2, -240}; //UTC - 4 hours
TimeChangeRule usEST = {"EST", First, Sun, Nov, 2, -300}; //UTC - 5 hours
```
For a time zone that does not change to daylight/summer time, pass the same rule twice to the constructor, for example:
`Timezone usAZ(usMST, usMST);`
##Coding Timezone objects
There are two ways to define **Timezone** objects.
By first defining **TimeChangeRule**s (as above) and giving the daylight time rule and the standard time rule (assuming usEDT and usEST defined as above):
`Timezone usEastern(usEDT, usEST);`
By reading rules previously stored in EEPROM. This reads both the daylight and standard time rules previously stored at EEPROM address 100:
`Timezone usPacific(100);`
Note that **TimeChangeRule**s require 12 bytes of storage each, so the pair of rules associated with a Timezone object requires 24 bytes total. This could possibly change in future versions of the library. The size of a **TimeChangeRule** can be checked with `sizeof(usEDT)`.
##Timezone library methods
Note that the `time_t` data type is defined by the Arduino Time library <Time.h>. See the [Time library documentation](http://www.arduino.cc/playground/Code/Time) for additional details.
###time_t toLocal(time_t utc);
#####Description
Converts the given UTC time to local time, standard or daylight as appropriate.
#####Syntax
`myTZ.toLocal(utc);`
#####Parameters
***utc:*** Universal Coordinated Time *(time_t)*
#####Returns
Local time *(time_t)*
#####Example
```c++
time_t eastern, utc;
TimeChangeRule usEDT = {"EDT", Second, Sun, Mar, 2, -240}; //UTC - 4 hours
TimeChangeRule usEST = {"EST", First, Sun, Nov, 2, -300}; //UTC - 5 hours
Timezone usEastern(usEDT, usEST);
utc = now(); //current time from the Time Library
eastern = usEastern.toLocal(utc);
```
###time_t toLocal(time_t utc, TimeChangeRule **tcr);
#####Description
As above, converts the given UTC time to local time, and also returns a pointer to the **TimeChangeRule** that was applied to do the conversion. This could then be used, for example, to include the time zone abbreviation as part of a time display. The caller must take care not to alter the pointed **TimeChangeRule**, as this will then result in incorrect conversions.
#####Syntax
`myTZ.toLocal(utc, &tcr);`
#####Parameters
***utc:*** Universal Coordinated Time *(time_t)*
***tcr:*** Address of a pointer to a **TimeChangeRule** _(\*\*TimeChangeRule)_
#####Returns
Local time *(time_t)*
Pointer to **TimeChangeRule** _(\*\*TimeChangeRule)_
#####Example
```c++
time_t eastern, utc;
TimeChangeRule *tcr;
TimeChangeRule usEDT = {"EDT", Second, Sun, Mar, 2, -240}; //UTC - 4 hours
TimeChangeRule usEST = {"EST", First, Sun, Nov, 2, -300}; //UTC - 5 hours
Timezone usEastern(usEDT, usEST);
utc = now(); //current time from the Time Library
eastern = usEastern.toLocal(utc, &tcr);
Serial.print("The time zone is: ");
Serial.println(tcr -> abbrev);
```
###boolean utcIsDST(time_t utc);
###boolean locIsDST(time_t local);
#####Description
These functions determine whether a given UTC time or a given local time is within the daylight saving (summer) time interval, and return true or false accordingly.
#####Syntax
`utcIsDST(utc);`
`locIsDST(local);`
#####Parameters
***utc:*** Universal Coordinated Time *(time_t)*
***local:*** Local Time *(time_t)*
#####Returns
true or false *(boolean)*
#####Example
`if (usEastern.utcIsDST(utc)) { /*do something*/ }`
###void readRules(int address);
###void writeRules(int address);
#####Description
These functions read or write a **Timezone** object's two **TimeChangeRule**s from or to EEPROM.
#####Syntax
`myTZ.readRules(address);`
`myTZ.writeRules(address);`
#####Parameters
***address:*** The beginning EEPROM address to write to or read from *(int)*
#####Returns
None.
#####Example
`usEastern.writeRules(100); //write rules beginning at EEPROM address 100`
###time_t toUTC(time_t local);
#####Description
Converts the given local time to UTC time.
**WARNING:** This function is provided for completeness, but should seldom be needed and should be used sparingly and carefully.
Ambiguous situations occur after the Standard-to-DST and the DST-to-Standard time transitions. When changing to DST, there is one hour of local time that does not exist, since the clock moves forward one hour. Similarly, when changing to standard time, there is one hour of local time that occurs twice since the clock moves back one hour.
This function does not test whether it is passed an erroneous time value during the Local-to-DST transition that does not exist. If passed such a time, an incorrect UTC time value will be returned.
If passed a local time value during the DST-to-Local transition that occurs twice, it will be treated as the earlier time, i.e. the time that occurs before the transition.
Calling this function with local times during a transition interval should be
avoided!
#####Syntax
`myTZ.toUTC(local);`
#####Parameters
***local:*** Local Time *(time_t)*
#####Returns
UTC *(time_t)*

View File

@ -0,0 +1,211 @@
/*----------------------------------------------------------------------*
* Arduino Timezone Library v1.0 *
* Jack Christensen Mar 2012 *
* *
* This work is licensed under the Creative Commons Attribution- *
* ShareAlike 3.0 Unported License. To view a copy of this license, *
* visit http://creativecommons.org/licenses/by-sa/3.0/ or send a *
* letter to Creative Commons, 171 Second Street, Suite 300, *
* San Francisco, California, 94105, USA. *
*----------------------------------------------------------------------*/
#include "Timezone.h"
//THIS LINE WAS ADDED FOR COMPATIBILY WITH THE WLED DEPENDENCY STRUCTURE. REMOVE IF YOU USE IT OUTSIDE OF WLED!
#include "../time/Time.h"
#ifdef __AVR__
#include <avr/eeprom.h>
#endif
/*----------------------------------------------------------------------*
* Create a Timezone object from the given time change rules. *
*----------------------------------------------------------------------*/
Timezone::Timezone(TimeChangeRule dstStart, TimeChangeRule stdStart)
{
_dst = dstStart;
_std = stdStart;
}
#ifdef __AVR__
/*----------------------------------------------------------------------*
* Create a Timezone object from time change rules stored in EEPROM *
* at the given address. *
*----------------------------------------------------------------------*/
Timezone::Timezone(int address)
{
readRules(address);
}
#endif
/*----------------------------------------------------------------------*
* Convert the given UTC time to local time, standard or *
* daylight time, as appropriate. *
*----------------------------------------------------------------------*/
time_t Timezone::toLocal(time_t utc)
{
//recalculate the time change points if needed
if (year(utc) != year(_dstUTC)) calcTimeChanges(year(utc));
if (utcIsDST(utc))
return utc + _dst.offset * SECS_PER_MIN;
else
return utc + _std.offset * SECS_PER_MIN;
}
/*----------------------------------------------------------------------*
* Convert the given UTC time to local time, standard or *
* daylight time, as appropriate, and return a pointer to the time *
* change rule used to do the conversion. The caller must take care *
* not to alter this rule. *
*----------------------------------------------------------------------*/
time_t Timezone::toLocal(time_t utc, TimeChangeRule **tcr)
{
//recalculate the time change points if needed
if (year(utc) != year(_dstUTC)) calcTimeChanges(year(utc));
if (utcIsDST(utc)) {
*tcr = &_dst;
return utc + _dst.offset * SECS_PER_MIN;
}
else {
*tcr = &_std;
return utc + _std.offset * SECS_PER_MIN;
}
}
/*----------------------------------------------------------------------*
* Convert the given local time to UTC time. *
* *
* WARNING: *
* This function is provided for completeness, but should seldom be *
* needed and should be used sparingly and carefully. *
* *
* Ambiguous situations occur after the Standard-to-DST and the *
* DST-to-Standard time transitions. When changing to DST, there is *
* one hour of local time that does not exist, since the clock moves *
* forward one hour. Similarly, when changing to standard time, there *
* is one hour of local times that occur twice since the clock moves *
* back one hour. *
* *
* This function does not test whether it is passed an erroneous time *
* value during the Local -> DST transition that does not exist. *
* If passed such a time, an incorrect UTC time value will be returned. *
* *
* If passed a local time value during the DST -> Local transition *
* that occurs twice, it will be treated as the earlier time, i.e. *
* the time that occurs before the transistion. *
* *
* Calling this function with local times during a transition interval *
* should be avoided! *
*----------------------------------------------------------------------*/
time_t Timezone::toUTC(time_t local)
{
//recalculate the time change points if needed
if (year(local) != year(_dstLoc)) calcTimeChanges(year(local));
if (locIsDST(local))
return local - _dst.offset * SECS_PER_MIN;
else
return local - _std.offset * SECS_PER_MIN;
}
/*----------------------------------------------------------------------*
* Determine whether the given UTC time_t is within the DST interval *
* or the Standard time interval. *
*----------------------------------------------------------------------*/
boolean Timezone::utcIsDST(time_t utc)
{
//recalculate the time change points if needed
if (year(utc) != year(_dstUTC)) calcTimeChanges(year(utc));
if (_stdUTC > _dstUTC) //northern hemisphere
return (utc >= _dstUTC && utc < _stdUTC);
else //southern hemisphere
return !(utc >= _stdUTC && utc < _dstUTC);
}
/*----------------------------------------------------------------------*
* Determine whether the given Local time_t is within the DST interval *
* or the Standard time interval. *
*----------------------------------------------------------------------*/
boolean Timezone::locIsDST(time_t local)
{
//recalculate the time change points if needed
if (year(local) != year(_dstLoc)) calcTimeChanges(year(local));
if (_stdLoc > _dstLoc) //northern hemisphere
return (local >= _dstLoc && local < _stdLoc);
else //southern hemisphere
return !(local >= _stdLoc && local < _dstLoc);
}
/*----------------------------------------------------------------------*
* Calculate the DST and standard time change points for the given *
* given year as local and UTC time_t values. *
*----------------------------------------------------------------------*/
void Timezone::calcTimeChanges(int yr)
{
_dstLoc = toTime_t(_dst, yr);
_stdLoc = toTime_t(_std, yr);
_dstUTC = _dstLoc - _std.offset * SECS_PER_MIN;
_stdUTC = _stdLoc - _dst.offset * SECS_PER_MIN;
}
/*----------------------------------------------------------------------*
* Convert the given DST change rule to a time_t value *
* for the given year. *
*----------------------------------------------------------------------*/
time_t Timezone::toTime_t(TimeChangeRule r, int yr)
{
tmElements_t tm;
time_t t;
uint8_t m, w; //temp copies of r.month and r.week
m = r.month;
w = r.week;
if (w == 0) { //Last week = 0
if (++m > 12) { //for "Last", go to the next month
m = 1;
yr++;
}
w = 1; //and treat as first week of next month, subtract 7 days later
}
tm.Hour = r.hour;
tm.Minute = 0;
tm.Second = 0;
tm.Day = 1;
tm.Month = m;
tm.Year = yr - 1970;
t = makeTime(tm); //first day of the month, or first day of next month for "Last" rules
t += (7 * (w - 1) + (r.dow - weekday(t) + 7) % 7) * SECS_PER_DAY;
if (r.week == 0) t -= 7 * SECS_PER_DAY; //back up a week if this is a "Last" rule
return t;
}
#ifdef __AVR__
/*----------------------------------------------------------------------*
* Read the daylight and standard time rules from EEPROM at *
* the given address. *
*----------------------------------------------------------------------*/
void Timezone::readRules(int address)
{
eeprom_read_block((void *) &_dst, (void *) address, sizeof(_dst));
address += sizeof(_dst);
eeprom_read_block((void *) &_std, (void *) address, sizeof(_std));
}
/*----------------------------------------------------------------------*
* Write the daylight and standard time rules to EEPROM at *
* the given address. *
*----------------------------------------------------------------------*/
void Timezone::writeRules(int address)
{
eeprom_write_block((void *) &_dst, (void *) address, sizeof(_dst));
address += sizeof(_dst);
eeprom_write_block((void *) &_std, (void *) address, sizeof(_std));
}
#endif

View File

@ -0,0 +1,61 @@
/*----------------------------------------------------------------------*
* Arduino Timezone Library v1.0 *
* Jack Christensen Mar 2012 *
* *
* This work is licensed under the Creative Commons Attribution- *
* ShareAlike 3.0 Unported License. To view a copy of this license, *
* visit http://creativecommons.org/licenses/by-sa/3.0/ or send a *
* letter to Creative Commons, 171 Second Street, Suite 300, *
* San Francisco, California, 94105, USA. *
*----------------------------------------------------------------------*/
#ifndef Timezone_h
#define Timezone_h
#if ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
#include <Time.h> //http://www.arduino.cc/playground/Code/Time
//convenient constants for dstRules
enum week_t {Last, First, Second, Third, Fourth};
enum dow_t {Sun=1, Mon, Tue, Wed, Thu, Fri, Sat};
enum month_t {Jan=1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};
//structure to describe rules for when daylight/summer time begins,
//or when standard time begins.
struct TimeChangeRule
{
char abbrev[6]; //five chars max
uint8_t week; //First, Second, Third, Fourth, or Last week of the month
uint8_t dow; //day of week, 1=Sun, 2=Mon, ... 7=Sat
uint8_t month; //1=Jan, 2=Feb, ... 12=Dec
uint8_t hour; //0-23
int offset; //offset from UTC in minutes
};
class Timezone
{
public:
Timezone(TimeChangeRule dstStart, TimeChangeRule stdStart);
Timezone(int address);
time_t toLocal(time_t utc);
time_t toLocal(time_t utc, TimeChangeRule **tcr);
time_t toUTC(time_t local);
boolean utcIsDST(time_t utc);
boolean locIsDST(time_t local);
void readRules(int address);
void writeRules(int address);
private:
void calcTimeChanges(int yr);
time_t toTime_t(TimeChangeRule r, int yr);
TimeChangeRule _dst; //rule for start of dst or summer time for any year
TimeChangeRule _std; //rule for start of standard time for any year
time_t _dstUTC; //dst start for given/current year, given in UTC
time_t _stdUTC; //std time start for given/current year, given in UTC
time_t _dstLoc; //dst start for given/current year, given in local time
time_t _stdLoc; //std time start for given/current year, given in local time
};
#endif

View File

@ -0,0 +1,8 @@
TimeChangeRule KEYWORD1
Timezone KEYWORD1
toLocal KEYWORD2
toUTC KEYWORD2
utcIsDST KEYWORD2
locIsDST KEYWORD2
readRules KEYWORD2
writeRules KEYWORD2

View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Harm Aldick
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,4 @@
https://github.com/kitesurfer1404/WS2812FX/
The WS2812FX implementation was heavily altered and differs from its master branch.
Due to regural changes to the library code it is kept in the source dir for now.

View File

@ -8,19 +8,19 @@
#include <ESP8266HTTPUpdateServer.h>
#include <ESP8266mDNS.h>
#include <EEPROM.h>
#include "WS2812FX.h"
#include <WiFiUDP.h>
#include <Time.h>
#include <TimeLib.h>
#include <Timezone.h>
#include "src/dependencies/time/Time.h"
#include "src/dependencies/time/TimeLib.h"
#include "src/dependencies/timezone/Timezone.h"
#include "src/dependencies/alexa-multiple/switch.h"
#include "src/dependencies/alexa-multiple/UpnpBroadcastResponder.h"
#include "src/dependencies/alexa-multiple/CallbackFunction.h"
#include "htmls00.h"
#include "htmls01.h"
#include "switch.h"
#include "UpnpBroadcastResponder.h"
#include "CallbackFunction.h"
#include "WS2812FX.h"
//version in format yymmddb (b = daily build)
#define VERSION 1712090
#define VERSION 1712111
//If you have an RGBW strip, uncomment first line in WS2812FX.h!
@ -142,6 +142,7 @@ byte col_sec[]{0, 0, 0};
byte col_sec_it[]{0, 0, 0};
byte white, white_old, white_t, white_it;
byte white_sec, white_sec_it;
uint8_t lastRandomIndex = 0;
unsigned long transitionStartTime;
unsigned long nightlightStartTime;
float tper_last = 0;

View File

@ -123,7 +123,7 @@ void saveSettingsToEEPROM()
EEPROM.commit();
}
void loadSettingsFromEEPROM()
void loadSettingsFromEEPROM(bool first)
{
if (EEPROM.read(233) != 233) //first boot/reset to default
{
@ -190,7 +190,7 @@ void loadSettingsFromEEPROM()
col_s[1] = EEPROM.read(247); col[1] = col_s[1];
col_s[2] = EEPROM.read(248); col[2] = col_s[2];
bri_s = EEPROM.read(249); bri = bri_s;
if (!EEPROM.read(369))
if (!EEPROM.read(369) && first)
{
bri = 0; bri_last = bri_s;
}
@ -262,6 +262,10 @@ void loadSettingsFromEEPROM()
//400 - 899 reserved
useHSB = useHSBDefault;
strip.setMode(effectCurrent);
strip.setSpeed(effectSpeed);
overlayCurrent = overlayDefault;
}
//PRESET PROTOCOL 20 bytes
@ -270,9 +274,9 @@ void loadSettingsFromEEPROM()
void applyPreset(uint8_t index, bool loadBri, bool loadCol, bool loadFX)
{
if (index == 255) loadSettingsFromEEPROM();//load boot defaults
if (index > 24) return;
uint16_t i = 400 + index*20;
if (index == 255 || index == 0) loadSettingsFromEEPROM(false);//load boot defaults
if (index > 25 || index < 1) return;
uint16_t i = 380 + index*20;
if (EEPROM.read(i) == 0) return;
if (loadBri) bri = EEPROM.read(i+1);
if (loadCol)
@ -303,8 +307,9 @@ void applyPreset(uint8_t index, bool loadBri, bool loadCol, bool loadFX)
void savePreset(uint8_t index)
{
if (index > 24) return;
uint16_t i = 400 + index*20;
if (index > 25) return;
if (index < 1) {saveSettingsToEEPROM();return;}
uint16_t i = 380 + index*20;//min400
EEPROM.write(i, 1);
EEPROM.write(i+1, bri);
EEPROM.write(i+2, col[0]);

View File

@ -2,6 +2,23 @@
* Receives client input
*/
void _setRandomColor(bool _sec)
{
lastRandomIndex = strip.get_random_wheel_index(lastRandomIndex);
uint32_t _color = strip.color_wheel(lastRandomIndex);
if (_sec){
white_sec = ((_color >> 24) & 0xFF);
col_sec[0] = ((_color >> 16) & 0xFF);
col_sec[1] = ((_color >> 8) & 0xFF);
col_sec[2] = (_color & 0xFF);
} else {
white = ((_color >> 24) & 0xFF);
col[0] = ((_color >> 16) & 0xFF);
col[1] = ((_color >> 8) & 0xFF);
col[2] = (_color & 0xFF);
}
}
void handleSettingsSet()
{
if (server.hasArg("CSSID")) clientssid = server.arg("CSSID");
@ -251,24 +268,24 @@ boolean handleSet(String req)
bri = req.substring(pos + 3).toInt();
}
//set red value
pos = req.indexOf("R=");
pos = req.indexOf("&R=");
if (pos > 0) {
col[0] = req.substring(pos + 2).toInt();
col[0] = req.substring(pos + 3).toInt();
}
//set green value
pos = req.indexOf("G=");
pos = req.indexOf("&G=");
if (pos > 0) {
col[1] = req.substring(pos + 2).toInt();
col[1] = req.substring(pos + 3).toInt();
}
//set blue value
pos = req.indexOf("B=");
pos = req.indexOf("&B=");
if (pos > 0) {
col[2] = req.substring(pos + 2).toInt();
col[2] = req.substring(pos + 3).toInt();
}
//set white value
pos = req.indexOf("W=");
pos = req.indexOf("&W=");
if (pos > 0) {
white = req.substring(pos + 2).toInt();
white = req.substring(pos + 3).toInt();
}
//set 2nd red value
pos = req.indexOf("R2=");
@ -290,6 +307,55 @@ boolean handleSet(String req)
if (pos > 0) {
white_sec = req.substring(pos + 3).toInt();
}
//set 2nd to white
pos = req.indexOf("SW");
if (pos > 0) {
if(useRGBW) {
white_sec = 255;
col_sec[0] = 0;
col_sec[1] = 0;
col_sec[2] = 0;
} else {
col_sec[0] = 255;
col_sec[1] = 255;
col_sec[2] = 255;
}
}
//set 2nd to black
pos = req.indexOf("SB");
if (pos > 0) {
white_sec = 0;
col_sec[0] = 0;
col_sec[1] = 0;
col_sec[2] = 0;
}
//set to random hue SR=0->1st SR=1->2nd
pos = req.indexOf("SR");
if (pos > 0) {
_setRandomColor(req.substring(pos + 3).toInt());
}
//set 2nd to 1st
pos = req.indexOf("SP");
if (pos > 0) {
col_sec[0] = col[0];
col_sec[1] = col[1];
col_sec[2] = col[2];
white_sec = white;
}
//swap 2nd & 1st
pos = req.indexOf("SC");
if (pos > 0) {
uint8_t _temp[4];
for (int i = 0; i<3; i++)
{
_temp[i] = col[i];
col[i] = col_sec[i];
col_sec[i] = _temp[i];
}
_temp[3] = white;
white = white_sec;
white_sec = _temp[3];
}
//set current effect index
pos = req.indexOf("FX=");
if (pos > 0) {
@ -322,9 +388,9 @@ boolean handleSet(String req)
strip.unlockAll();
}
//set individual pixel (range) to current color
pos = req.indexOf("I=");
pos = req.indexOf("&I=");
if (pos > 0){
int index = req.substring(pos + 2).toInt();
int index = req.substring(pos + 3).toInt();
pos = req.indexOf("I2=");
if (pos > 0){
int index2 = req.substring(pos + 3).toInt();
@ -397,9 +463,9 @@ boolean handleSet(String req)
if (auxTime == 0) auxActive = false;
}
//main toggle on/off
pos = req.indexOf("T=");
pos = req.indexOf("&T=");
if (pos > 0) {
switch (req.substring(pos + 2).toInt())
switch (req.substring(pos + 3).toInt())
{
case 0: if (bri != 0){bri_last = bri; bri = 0;} break; //off
case 1: bri = bri_last; break; //on
@ -413,6 +479,11 @@ boolean handleSet(String req)
}
}
}
//set time (unix timestamp)
pos = req.indexOf("ST=");
if (pos > 0) {
setTime(req.substring(pos+3).toInt());
}
//set custom chase data
bool _cc_updated = false;
pos = req.indexOf("C0="); if (pos > 0) {cc_start = (req.substring(pos + 3).toInt()); _cc_updated = true;}

View File

@ -23,7 +23,7 @@ void wledInit()
DEBUG_PRINTLN("Init EEPROM");
EEPROM.begin(1024);
loadSettingsFromEEPROM();
loadSettingsFromEEPROM(true);
DEBUG_PRINT("CC: SSID: ");
DEBUG_PRINT(clientssid);
@ -153,7 +153,6 @@ void wledInit()
//Init alexa service
alexaInit();
overlayCurrent = overlayDefault;
// Initialize NeoPixel Strip
strip.init();
strip.setLedCount(ledcount);