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 "

"+String(code)+": "+text+" na koren spletišča (/)" +"


"+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(); }