Skip to content

Commit 86dec10

Browse files
committed
added own time keeping
1 parent c96ab0a commit 86dec10

2 files changed

Lines changed: 290 additions & 0 deletions

File tree

src/ArduinoOcpp/Core/OcppTime.cpp

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
// matth-x/ESP8266-OCPP
2+
// Copyright Matthias Akstaller 2019 - 2021
3+
// MIT License
4+
5+
#include <ArduinoOcpp/Core/OcppTime.h>
6+
7+
namespace ArduinoOcpp {
8+
9+
OcppTimestamp::OcppTimestamp() {
10+
11+
}
12+
13+
int noDays(int month, int year) {
14+
return (month == 0 || month == 2 || month == 4 || month == 6 || month == 7 || month == 9 || month == 11) ? 31 :
15+
((month == 3 || month == 5 || month == 8 || month == 10) ? 30 :
16+
((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? 29 : 28));
17+
}
18+
19+
bool OcppTimestamp::setTime(const char *jsonDateString) {
20+
21+
const int JSONDATE_MINLENGTH = 19;
22+
23+
if (strlen(jsonDateString) < JSONDATE_MINLENGTH){
24+
return false;
25+
}
26+
27+
if (!isdigit(jsonDateString[0]) || //2
28+
!isdigit(jsonDateString[1]) || //0
29+
!isdigit(jsonDateString[2]) || //1
30+
!isdigit(jsonDateString[3]) || //3
31+
jsonDateString[4] != '-' || //-
32+
!isdigit(jsonDateString[5]) || //0
33+
!isdigit(jsonDateString[6]) || //2
34+
jsonDateString[7] != '-' || //-
35+
!isdigit(jsonDateString[8]) || //0
36+
!isdigit(jsonDateString[9]) || //1
37+
jsonDateString[10] != 'T' || //T
38+
!isdigit(jsonDateString[11]) || //2
39+
!isdigit(jsonDateString[12]) || //0
40+
jsonDateString[13] != ':' || //:
41+
!isdigit(jsonDateString[14]) || //5
42+
!isdigit(jsonDateString[15]) || //3
43+
jsonDateString[16] != ':' || //:
44+
!isdigit(jsonDateString[17]) || //3
45+
!isdigit(jsonDateString[18])) { //2
46+
//ignore subsequent characters
47+
return false;
48+
}
49+
50+
int year = (jsonDateString[0] - '0') * 1000 +
51+
(jsonDateString[1] - '0') * 100 +
52+
(jsonDateString[2] - '0') * 10 +
53+
(jsonDateString[3] - '0');
54+
int month = (jsonDateString[5] - '0') * 10 +
55+
(jsonDateString[6] - '0') - 1;
56+
int day = (jsonDateString[8] - '0') * 10 +
57+
(jsonDateString[9] - '0') - 1;
58+
int hour = (jsonDateString[11] - '0') * 10 +
59+
(jsonDateString[12] - '0');
60+
int minute = (jsonDateString[14] - '0') * 10 +
61+
(jsonDateString[15] - '0');
62+
int second = (jsonDateString[17] - '0') * 10 +
63+
(jsonDateString[18] - '0');
64+
//ignore fractals
65+
66+
if (year < 1970 || year >= 2038 ||
67+
month < 0 || month >= 12 ||
68+
day < 0 || day >= noDays(month, year) ||
69+
hour < 0 || hour >= 24 ||
70+
minute < 0 || minute >= 60 ||
71+
second < 0 || second > 60) { //tolerate leap seconds -- (23:59:60) can be a valid time
72+
return false;
73+
}
74+
75+
this->year = year;
76+
this->month = month;
77+
this->day = day;
78+
this->hour = hour;
79+
this->minute = minute;
80+
this->second = second;
81+
82+
return true;
83+
}
84+
85+
bool OcppTimestamp::toJsonString(char *jsonDateString, size_t buffsize) {
86+
if (buffsize < OCPP_JSONDATE_LENGTH + 1) return false;
87+
88+
jsonDateString[0] = ((char) ((year / 1000) % 10)) + '0';
89+
jsonDateString[1] = ((char) ((year / 100) % 10)) + '0';
90+
jsonDateString[2] = ((char) ((year / 10) % 10)) + '0';
91+
jsonDateString[3] = ((char) ((year / 1) % 10)) + '0';
92+
jsonDateString[4] = '-';
93+
jsonDateString[5] = ((char) ((month / 10) % 10)) + '0';
94+
jsonDateString[6] = ((char) ((month / 1) % 10)) + '0';
95+
jsonDateString[7] = '-';
96+
jsonDateString[8] = ((char) ((day / 10) % 10)) + '0';
97+
jsonDateString[9] = ((char) ((day / 1) % 10)) + '0';
98+
jsonDateString[10] = 'T';
99+
jsonDateString[11] = ((char) ((hour / 10) % 10)) + '0';
100+
jsonDateString[12] = ((char) ((hour / 1) % 10)) + '0';
101+
jsonDateString[13] = ':';
102+
jsonDateString[14] = ((char) ((minute / 10) % 10)) + '0';
103+
jsonDateString[15] = ((char) ((minute / 1) % 10)) + '0';
104+
jsonDateString[16] = ':';
105+
jsonDateString[17] = ((char) ((second / 10) % 10)) + '0';
106+
jsonDateString[18] = ((char) ((second / 1) % 10)) + '0';
107+
jsonDateString[19] = '.';
108+
jsonDateString[20] = '0'; //ignore fractals
109+
jsonDateString[21] = '0';
110+
jsonDateString[22] = '0';
111+
jsonDateString[23] = 'Z';
112+
113+
return true;
114+
}
115+
116+
OcppTimestamp OcppTimestamp::operator+(int secs) {
117+
OcppTimestamp res = *this;
118+
res.second += secs;
119+
120+
if (res.second >= 0 && res.second < 60) return res;
121+
122+
res.minute += res.second / 60;
123+
res.second %= 60;
124+
if (res.second < 0) {
125+
res.minute--;
126+
res.second += 60;
127+
}
128+
129+
if (res.minute >= 0 && res.minute < 60) return res;
130+
131+
res.hour += res.minute / 60;
132+
res.minute %= 60;
133+
if (res.minute < 0) {
134+
res.hour--;
135+
res.minute += 60;
136+
}
137+
138+
if (res.hour >= 0 && res.hour < 24) return res;
139+
140+
res.day += res.hour / 24;
141+
res.hour %= 24;
142+
if (res.hour < 0) {
143+
res.day--;
144+
res.hour += 24;
145+
}
146+
147+
while (res.day >= noDays(res.month, res.year)) {
148+
res.day -= noDays(res.month, res.year);
149+
res.month++;
150+
151+
if (res.month >= 12) {
152+
res.month -= 12;
153+
res.year++;
154+
}
155+
}
156+
157+
while (res.day < 0) {
158+
res.month--;
159+
if (res.month < 0) {
160+
res.month += 12;
161+
res.year--;
162+
}
163+
res.day += noDays(res.month, res.year);
164+
}
165+
166+
return res;
167+
};
168+
169+
OcppTimestamp OcppTimestamp::operator-(int secs) {
170+
return this->operator+(-secs);
171+
}
172+
173+
bool OcppTime::setOcppTime(const char* jsonDateString) {
174+
175+
OcppTimestamp timestamp = OcppTimestamp();
176+
177+
if (!timestamp.setTime(jsonDateString)) {
178+
return false;
179+
}
180+
181+
system_basetime = system_clock();
182+
ocpp_basetime = timestamp;
183+
184+
return true;
185+
}
186+
187+
otime_t OcppTime::getOcppTimeScalar() {
188+
return system_clock();
189+
}
190+
191+
OcppTimestamp OcppTime::createTimestamp(otime_t scalar) {
192+
OcppTimestamp res = ocpp_basetime + (scalar - system_basetime);
193+
194+
return res;
195+
}
196+
197+
}

src/ArduinoOcpp/Core/OcppTime.h

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// matth-x/ESP8266-OCPP
2+
// Copyright Matthias Akstaller 2019 - 2021
3+
// MIT License
4+
5+
#ifndef OCPPTIME_H
6+
#define OCPPTIME_H
7+
8+
#include <functional>
9+
10+
#include <Arduino.h>
11+
12+
#define OCPP_JSONDATE_LENGTH 24
13+
14+
namespace ArduinoOcpp {
15+
16+
typedef int32_t otime_t; //requires 32bit signed integer or bigger
17+
18+
class OcppTimestamp {
19+
private:
20+
/*
21+
* Internal representation of the current time. The initial values correspond to UNIX-time 0. January
22+
* corresponds to month 0 and the first day in the month is day 0.
23+
*/
24+
int16_t year = 1970;
25+
int16_t month = 0;
26+
int16_t day = 0;
27+
int32_t hour = 0;
28+
int32_t minute = 0;
29+
int32_t second = 0;
30+
31+
public:
32+
33+
OcppTimestamp();
34+
35+
/**
36+
* Expects a date string like
37+
* 2020-10-01T20:53:32.486Z
38+
*
39+
* as generated in JavaScript by calling toJSON() on a Date object
40+
*
41+
* Only processes the first 19 characters. The subsequent are ignored until terminating 0.
42+
*
43+
* Has a semi-sophisticated type check included. Will return true on successful time set and false if
44+
* the given string is not a JSON Date string.
45+
*
46+
* jsonDateString: 0-terminated string
47+
*/
48+
bool setTime(const char* jsonDateString);
49+
50+
bool toJsonString(char *out, size_t buffsize);
51+
52+
OcppTimestamp operator+(int secs);
53+
54+
OcppTimestamp operator-(int secs);
55+
56+
};
57+
58+
class OcppTime {
59+
private:
60+
61+
OcppTimestamp ocpp_basetime;
62+
otime_t system_basetime = 0; //your system clock's time at the moment when the OCPP server's time was taken
63+
64+
std::function<otime_t()> system_clock = [] () {return (otime_t) 0;};
65+
66+
public:
67+
68+
OcppTime(std::function<otime_t()> system_clock);
69+
70+
otime_t getOcppTimeScalar(); //returns current time of the OCPP server in non-UNIX but signed integer format. t2 - t1 is the time difference in seconds.
71+
OcppTimestamp createTimestamp(otime_t scalar); //creates a timestamp in a JSON-serializable format. createTimestamp(getOcppTimeScalar()) will return the current OCPP time
72+
73+
/**
74+
* Expects a date string like
75+
* 2020-10-01T20:53:32.486Z
76+
*
77+
* as generated in JavaScript by calling toJSON() on a Date object
78+
*
79+
* Only processes the first 19 characters. The subsequent are ignored until terminating 0.
80+
*
81+
* Has a semi-sophisticated type check included. Will return true on successful time set and false if
82+
* the given string is not a JSON Date string.
83+
*
84+
* jsonDateString: 0-terminated string
85+
*/
86+
bool setOcppTime(const char* jsonDateString);
87+
88+
89+
};
90+
91+
}
92+
93+
#endif

0 commit comments

Comments
 (0)