Coder Social home page Coder Social logo

rwpalmer / tzcfg Goto Github PK

View Code? Open in Web Editor NEW
9.0 4.0 1.0 55 KB

Manages local time and DST settings for Particle IOT devices. Sets timezone based on the device's return IP address, by GPS coordinates, or by timezone ID. Data is obtained from public web-sites.

License: GNU General Public License v3.0

C++ 100.00%
zone timezone particle time iot-device time-zone daylight-saving-time timezone-configuration

tzcfg's Introduction

TzCfg

A library to maintain local time settings on Particle IOT devices

Library Functionality ...

TzCfg methods automatically configure a device's local time settings based upon one of the following data elements:

  • IP address (automatically detected)
  • GPS coordinates (which can be obtained from a GPS device, a cellular API, or other source)
  • time zone ID (aka, Olson Name)

In normal usage, TzCfg methods configure local time settings in firmware setup(), but these methods can also be called from firmware loop() to update local time settings for mobile devices, and from a Particle function to change local time settings via network commands.

Time zone information is saved in EEPROM, and the library will configure local time to the last known time zone settings if the device reboots when no network connectivity is available.

Since IANA updates its time zone database on a regular basis, TzCfg performs a periodic "refresh" operation that will update EEPROM if relevant data (like the time of the next DST transition) has changed.

TzCfg automatically performs DST transitions when they are scheduled. This is a local operation.

TzCfg methods expose a number of data elements for public use. These include:

  • Time zone ID
  • Time zone abbreviation
  • Next DST transition time
  • HTTP Status message (useful for debugging when an update fails)

Methods are also available to support various firmware test scenarios ... like to validate that logging and display logic perform properly after a DST transition takes place.

TzCfg strives to keep resource usage to a minimum.

How the Library Works ...

  • IANA maintains the time zone database that communication companies and OS vendors use to manage local time world wide.

  • TzCfg obtains IANA time zone information via timezonedb.com. TzCfg users must register for a timezonedb.com API-key to access the data. The key is free ( for up to 1 lookup per second ). They charge a fee for access above this level. Registration link

  • To enable time zone configuration by IP, TzCfg needs to know the Particle device's IP address and the time zone ID associated with that address. This information is obtained from ip-api.com which does not require an API key for non-commercial access up to 150 lookups per minute. Commercial use requires preapproval ... see the site for more details.

*It should be noted that TzCfg does not use Particle's WiFi.localIP() function to obtain the device's IP address because that would not work. Most IOT devices are configured with non-routable addresses (like 192.168.xxx.xxx, or 10.xxx.xxx.xxx). Non-routable addresses like these CAN NOT be used for time zone lookups. ipapi.com returns data based upon the IP address designated as the "return address" on packets sent from your device. In most cases, this would be the IP address assigned to the Internet side of the IP gateway that your device uses to communicate with the web.

The following code sample configures the device's local time settings based on the device's IP address. It will also perform DST transitions at their scheduled time. This is all that is needed for most implementations.

#include <TzCfg.h>

TzCfg tzCfg;

void Setup() {
    tzCfg.begin();
    tzCfg.setApiKey_timezonedb((char*)"YOUR_TIMEZONEDB_API_KEY");
    tzCfg.setTimezoneByIP();
}

void Loop() {
    tzCfg.maintainLocalTime();
}

One additional command may be required if the device's EEPROM currently stores other data. See the QuickStart Guide for details.

TzCfg Documentation:

TzCfg Documentation:

Firmware Examples

TzCfg is packaged with three firmware examples. All three are designed to be run with a serial console.

  • TzCfg101.ino demonstrates setting local time and displaying local time variables exposed by tzLib and the Particle Time class.
  • TzCfg201.ino demonstrates how TzCfg can perform DST transitions on command ... to enable testing of software that logs or displays data with time related information.
  • TzCfg301.ino demonstrates how a device's time zone can be changed via the web. Particle functions are used to allow users to change timezones by entering a timezone ID, by entering GPS coordinates, and/or by simply clicking "setZonebyIP".

Sample "serial console output" is included in the comments at the the bottom of each example's .ino file.

Current State of the Project ...

  • TzCfg (0.0.1) Beta 1
  • Known defects: 0
  • Second draft of documentation is complete ... see links above.
  • Code has been posted to GitHub

Please report any issues, suggestions, or other comments to the author and maintainer: [email protected].

Many thanks to Wagner Sartori (https://github.com/trunet) for his suggestion to use timezonedb.com as a source for timezone data. Without that suggestion, this library would not exist.

tzcfg's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

briveramelo

tzcfg's Issues

Compile Issue

Hi,

I'm attempting to compile the sample program tzcfg101.ino using the Particle web ide. I'm receiving the following error.

Thanks for the help!

Tim

lib/TzCfg/src/TzCfg.cpp: In member function 'void TzCfg::eraseTzEeprom()':
lib/TzCfg/src/TzCfg.cpp:260:43: warning: 'void* memset(void*, int, size_t)' writing to an object of type 'class TzBlock' with no trivial copy-assignment [-Wclass-memaccess]
260 | memset(&tzBlk, 0xFF, sizeof(tzBlk));
| ^
In file included from lib/TzCfg/src/TzCfg.cpp:1:
lib/TzCfg/src/TzCfg.h:14:7: note: 'class TzBlock' declared here
14 | class TzBlock {
| ^~~~~~~
lib/TzCfg/src/TzCfg.cpp: In member function 'int TzCfg::setLocalTime(uint8_t)':
lib/TzCfg/src/TzCfg.cpp:331:52: error: call of overloaded 'String(time_t&)' is ambiguous
331 | strncat(hostPath, String(tzWeb.tranTime), sizeof(hostPath));
| ^
In file included from ../wiring/inc/spark_wiring_stream.h:30,
from ../wiring/inc/spark_wiring.h:40,
from ./inc/application.h:42,
from lib/TzCfg/src/TzCfg.h:3,
from lib/TzCfg/src/TzCfg.cpp:1:
../wiring/inc/spark_wiring_string.h:85:14: note: candidate: 'String::String(double, int)'
85 | explicit String(double, int decimalPlaces=6);
| ^~~~~~
../wiring/inc/spark_wiring_string.h:84:14: note: candidate: 'String::String(float, int)'
84 | explicit String(float, int decimalPlaces=6);
| ^~~~~~
../wiring/inc/spark_wiring_string.h:83:11: note: candidate: 'String::String(long unsigned int, unsigned char)'
83 | explicit String(unsigned long, unsigned char base=10);
| ^~~~~~
../wiring/inc/spark_wiring_string.h:82:11: note: candidate: 'String::String(long int, unsigned char)'
82 | explicit String(long, unsigned char base=10);
| ^~~~~~
../wiring/inc/spark_wiring_string.h:81:11: note: candidate: 'String::String(unsigned int, unsigned char)'
81 | explicit String(unsigned int, unsigned char base=10);
| ^~~~~~
../wiring/inc/spark_wiring_string.h:80:11: note: candidate: 'String::String(int, unsigned char)'
80 | explicit String(int, unsigned char base=10);
| ^~~~~~
../wiring/inc/spark_wiring_string.h:79:11: note: candidate: 'String::String(unsigned char, unsigned char)'
79 | explicit String(unsigned char, unsigned char base=10);
| ^~~~~~
../wiring/inc/spark_wiring_string.h:78:11: note: candidate: 'String::String(char)'
78 | explicit String(char c);
| ^~~~~~
../wiring/inc/spark_wiring_string.h:76:2: note: candidate: 'String::String(StringSumHelper&&)'
76 | String(StringSumHelper &&rval);
| ^~~~~~
../wiring/inc/spark_wiring_string.h:75:2: note: candidate: 'String::String(String&&)'
75 | String(String &&rval);
| ^~~~~~
../wiring/inc/spark_wiring_string.h:71:2: note: candidate: 'String::String(const String&)'
71 | String(const String &str);
| ^~~~~~
lib/TzCfg/src/TzCfg.cpp:314:16: warning: 'char* strncat(char*, const char*, size_t)' specified bound 193 equals destination size [-Wstringop-overflow=]
314 | strncat(hostPath, "&format=json", sizeof(hostPath));
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lib/TzCfg/src/TzCfg.cpp:318:24: warning: 'char* strncat(char*, const char*, size_t)' specified bound 193 equals destination size [-Wstringop-overflow=]
318 | strncat(hostPath, "&by=zone&zone=", sizeof(hostPath));
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lib/TzCfg/src/TzCfg.cpp:322:24: warning: 'char* strncat(char*, const char*, size_t)' specified bound 193 equals destination size [-Wstringop-overflow=]
322 | strncat(hostPath, "&by=position&lat=", sizeof(hostPath));
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lib/TzCfg/src/TzCfg.cpp:324:24: warning: 'char* strncat(char*, const char*, size_t)' specified bound 193 equals destination size [-Wstringop-overflow=]
324 | strncat(hostPath, "&lng=", sizeof(hostPath));
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lib/TzCfg/src/TzCfg.cpp:330:20: warning: 'char* strncat(char*, const char*, size_t)' specified bound 193 equals destination size [-Wstringop-overflow=]
330 | strncat(hostPath, "&time=", sizeof(hostPath));
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../build/module.mk:286: recipe for target '../build/target/user/platform-6-mTzCfg/src/TzCfg.o' failed
make[2]: *** [../build/target/user/platform-6-mTzCfg/src/TzCfg.o] Error 1
make[2]: Leaving directory '/firmware/user'
../../../build/recurse.mk:11: recipe for target 'user' failed
make[1]: Leaving directory '/firmware/modules/photon/user-part'
make[1]: *** [user] Error 2
../build/recurse.mk:11: recipe for target 'modules/photon/user-part' failed
make: *** [modules/photon/user-part] Error 2

Error when using with VS code and particle workbench

By deafult Intellisense raises and error when trying to #include "TzCfg.h .

I the TzCfg.h file on line 145 there is a declaration using 'uint' that was not recognised - changing this to 'unsigned int and error cleared.
Original:

int getJson(char* hostName, int hostPort, char* hostPath, char*& jsonStr, uint& jsonSize, char* errorMsg, int errMsgSize); // <-- Performs the HTTP processing
Changed:

int getJson(char* hostName, int hostPort, char* hostPath, char*& jsonStr, unsigned int& jsonSize, char* errorMsg, int errMsgSize); // <-- Performs the HTTP processing

I am not familiar with Git/Github enough to do a pull request etc..

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.