int x2i(char *s)
{
int x = 0;
for(;;) {
char c = *s;
if (c >= '0' && c <= '9') {
x *= 16;
x += c - '0';
}
else if (c >= 'A' && c <= 'F') {
x *= 16;
x += (c - 'A') + 10;
}
else if (c >= 'a' && c <= 'f') {
x *= 16;
x += (c - 'a') + 10;
}
else break;
s++;
}
return x;
}
void explode(String s, String delimiter, String arr[], int ARR_LEN) {
// by timemage on #arduino/freenode
unsigned part_begin = 0;
for (size_t i = 0; i < ARR_LEN; ++i) {
const auto delim_index = s.indexOf(delimiter, part_begin);
const auto part_end = (delim_index >= 0) ? delim_index : s.length();
arr[i] = s.substring(part_begin, part_end);
if (delim_index >= 0) {
part_begin = delim_index + delimiter.length();
}
}
}
int pin2gpio(String in) {
in.toUpperCase();
if (in == "A0") return int(A0);
if (in == "D0") return int(D0);
if (in == "D1") return int(D1);
if (in == "D2") return int(D2);
if (in == "D3") return int(D3);
if (in == "D4") return int(D4);
if (in == "D5") return int(D5);
if (in == "D6") return int(D6);
if (in == "D7") return int(D7);
if (in == "D8") return int(D8);
return in.toInt();// fallback to gpio
}
String getContentType(String filename) { // convert the file extension to the MIME type
if (filename.endsWith(".html")) return "text/html";
else if (filename.endsWith(".css")) return "text/css";
else if (filename.endsWith(".js")) return "application/javascript";
else if (filename.endsWith(".ico")) return "image/x-icon";
else if (filename.endsWith(".jpg")) return "image/jpeg";
else if (filename.endsWith(".jpeg")) return "image/jpeg";
else if (filename.endsWith(".txt")) return "text/plain";
else if (filename.endsWith(".pdf")) return "application/pdf";
else if (filename.endsWith(".png")) return "image/png";
else if (filename.endsWith(".zip")) return "application/zip";
else if (filename.endsWith(".ttf")) return "font/ttf";
else if (filename.endsWith(".gif")) return "image/gif";
else if (filename.endsWith(".mp3")) return "application/ogg";
else if (filename.endsWith(".ogg")) return "application/ogg";
else if (filename.endsWith(".mp4")) return "application/ogg";
else if (filename.endsWith(".gz")) return "application/x-gzip";
else if (filename.endsWith(".xml")) return "text/xml";
else if (filename.endsWith(".svg")) return "text/svg+xml";
else if (filename.endsWith(".csv")) return "text/csv";
return "application/octet-stream";
}
bool writefile(String filepath, String contents) {
File file = SPIFFS.open(filepath, "w");
if (!file) {
return false;
}
int bytesWritten = file.print(String(contents));
if (bytesWritten == 0) {
return false;
}
file.close();
return true;
}
String readfile(String filepath) {
File file = SPIFFS.open(filepath, "r");
if (!file) {
return "";
}
String filecontents;
while (file.available()) {
filecontents += char(file.read());
}
file.close();
return filecontents;
}
String fihr(int code, String text) { // format inline html response
return "
"+program_ime+"/"+String(verzija[0])+"."+String(verzija[1])+"."+String(verzija[2])
+"
";
}
const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets
time_t getHttpTime() {
const char * headerKeys[] = {"date"} ;
const size_t numberOfHeaders = 1;
HTTPClient http;
http.begin("http://razor.arnes.si/.well-known/time");
http.collectHeaders(headerKeys, numberOfHeaders);
int httpCode = http.GET();
String headerDate;
if (httpCode > 0) {
for(int i = 0; i< http.headers(); i++){
Serial.println(http.header(i));
}
headerDate = http.header("date");
} else {
if(razhroscevanje) Serial.println("unable to get http time");
return 0;
}
http.end();
// string, delimeter, array, length
String locenoSPresledki[5];
String locenoZDvopicjem[3];
explode(headerDate, " ", locenoSPresledki, 5);
int dan = locenoSPresledki[1].toInt();
String mesc = locenoSPresledki[2];
int leto = locenoSPresledki[3].toInt();
explode(locenoSPresledki[4], ":", locenoZDvopicjem, 3);
int ura = locenoZDvopicjem[0].toInt();
int minuta = locenoZDvopicjem[1].toInt();
int sekund = locenoZDvopicjem[2].toInt();
int mesec;
if(mesc == "Jan") mesec=1;
else if(mesc == "Feb") mesec=2;
else if(mesc == "Mar") mesec=3;
else if(mesc == "Apr") mesec=4;
else if(mesc == "May") mesec=5;
else if(mesc == "Jun") mesec=6;
else if(mesc == "Jul") mesec=7;
else if(mesc == "Aug") mesec=8;
else if(mesc == "Sep") mesec=9;
else if(mesc == "Oct") mesec=10;
else if(mesc == "Nov") mesec=11;
else if(mesc == "Dec") mesec=12;
tmElements_t tm;
tm.Hour = ura;
tm.Minute = minuta;
tm.Second = sekund;
tm.Day = dan;
tm.Month = mesec;
tm.Year = leto-1970;
if(razhroscevanje) Serial.println("httpUpdate ("+mesc+","+mesec+"): "+String(makeTime(tm)));
return makeTime(tm);
}
time_t getNtpTime()
{
IPAddress ntpServerIP; // NTP server's ip address
while (Udp.parsePacket() > 0) ; // discard any previously received packets
Serial.println("Transmit NTP Request");
// get a random server from the pool
WiFi.hostByName(ntpServerName, ntpServerIP);
Serial.print(ntpServerName);
Serial.print(": ");
Serial.println(ntpServerIP);
sendNTPpacket(ntpServerIP);
uint32_t beginWait = millis();
while (millis() - beginWait < 1500) {
int size = Udp.parsePacket();
if (size >= NTP_PACKET_SIZE) {
Serial.println("Receive NTP Response");
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer
unsigned long secsSince1900;
// convert four bytes starting at location 40 to a long integer
secsSince1900 = (unsigned long)packetBuffer[40] << 24;
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
secsSince1900 |= (unsigned long)packetBuffer[43];
return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
}
}
Serial.println("No NTP Response :-(");
return 0; // return 0 if unable to get the time
}
// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address)
{
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
time_t timeSyncProvider() {
return getHttpTime();
}