2022年1月2日 星期日

以Http GET取得網路時間


本文利用D1 mini,連接網路後,截取網路時間。可利用的網路有二,均以http GET取的JSON格式回應。

1. http://worldclockapi.com/api/json/utc/now

此網頁回應的是世界協調時間(UTC, Coordinated Universal Time),與台北的時區不同,需自行+8。該網頁回應的JSON碼如下:

  1. {
  2.   "$id": "1",
  3.   "currentDateTime": "2022-01-02T13:45Z",
  4.   "utcOffset": "00:00:00",
  5.   "isDayLightSavingsTime": false,
  6.   "dayOfTheWeek": "Sunday",
  7.   "timeZoneName": "UTC",
  8.   "currentFileTime": 132856047568459540,
  9.   "ordinalDate": "2022-2",
  10.   "serviceResponse": null
  11. }


2. http://worldtimeapi.org/api/timezone/Asia/Taipei

此網頁回應的資訊較多,可取得Taipei時區目前的時間(datetime)以及UTC時間(utc_datetime),還可取得星期幾(day_of_week)、每年中第幾天(day_of_year)以及每年中第幾周(week_number)的資訊,但在跨年當周的周數計算可能會有出入。

  1. {
  2.   "abbreviation": "CST",
  3.   "client_ip": "112.78.66.92",
  4.   "datetime": "2022-01-02T21:46:12.324416+08:00",
  5.   "day_of_week": 0,
  6.   "day_of_year": 2,
  7.   "dst": false,
  8.   "dst_from": null,
  9.   "dst_offset": 0,
  10.   "dst_until": null,
  11.   "raw_offset": 28800,
  12.   "timezone": "Asia/Taipei",
  13.   "unixtime": 1641131172,
  14.   "utc_datetime": "2022-01-02T13:46:12.324416+00:00",
  15.   "utc_offset": "+08:00",
  16.   "week_number": 52
  17. }


下圖為執行結果。
連網取得時間後的回應

使用Flagblock的圖控程式以及Arduino 程式碼如下。





  1. // Flag's Block 產生的草稿碼

  2. #include <ESP8266WiFi.h>
  3. #include <ESP8266WebServer.h>
  4. #include "data/webpages.h"
  5. #include <FlagHTTPClient.h>
  6. #include <ArduinoJson.h>
  7. #include <FlagJSON.h>

  8. String time_JSON_response;
  9. String datetime;
  10. String day_of_week;
  11. String date;
  12. String time_now;
  13. String week_day;
  14. ESP8266WebServer _esp8266WebServer(80);
  15. FlagHTTPClient _httpClient;
  16. JsonVariant _jsonRoot;
  17. DynamicJsonBuffer _jsonBuffer;

  18. void handleRoot() {
  19. #ifndef WEBPAGE_IN_PROGMEM
  20.   _esp8266WebServer.send(200, "text/html", mainPage);
  21. #else
  22.   _esp8266WebServer.send_P(200, PSTR("text/html"), mainPage);
  23. #endif
  24. }

  25. void handleNotFound() {
  26. #ifndef WEBPAGE_IN_PROGMEM
  27.   _esp8266WebServer.send(404, "text/html", errorPage);
  28. #else
  29.   _esp8266WebServer.send_P(404, PSTR("text/html"), errorPage);
  30. #endif
  31. }

  32. void handleSetting() {
  33. #ifndef WEBPAGE_IN_PROGMEM
  34.   _esp8266WebServer.send(200, "text/html", settingPage);
  35. #else
  36.   _esp8266WebServer.send_P(200, PSTR("text/html"), settingPage);
  37. #endif
  38. }

  39. int _httpGET(String url) {
  40.   _httpClient.end();
  41.   _httpClient.begin(url);
  42.   _httpClient.setTimeout(30000);
  43.   return _httpClient.GET();
  44. }

  45. void Get_Internet_Time() {
  46.   time_JSON_response = _httpClient.getString();
  47.   _jsonBuffer.clear();
  48.   _jsonRoot = _jsonBuffer.parse(time_JSON_response);
  49.   datetime = flagJSON.getJSONDataAsString(_jsonRoot, u8"datetime");
  50.   day_of_week = flagJSON.getJSONDataAsString(_jsonRoot, u8"day_of_week");
  51.   date = datetime.substring(0, 10);
  52.   time_now = datetime.substring(11, 19);
  53.   if (day_of_week == u8"0") {
  54.     week_day = u8"Sunday";
  55.   } else if (day_of_week == u8"1") {
  56.     week_day = u8"Monday";
  57.   } else if (day_of_week == u8"2") {
  58.     week_day = u8"Tuesday";
  59.   } else if (day_of_week == u8"3") {
  60.     week_day = u8"Wednesday";
  61.   } else if (day_of_week == u8"4") {
  62.     week_day = u8"Thursday";
  63.   } else if (day_of_week == u8"5") {
  64.     week_day = u8"Friday";
  65.   } else if (day_of_week == u8"6") {
  66.     week_day = u8"Saturday";
  67.   }
  68.   Serial.println((String(u8"date: ") + String(date)));
  69.   Serial.println((String(u8"day: ") + String(week_day)));
  70.   Serial.println((String(u8"time: ") + String(time_now)));
  71.   Serial.println(u8"");
  72. }


  73. // setup() 會先被執行且只會執行一次
  74. void setup() {
  75.   Serial.begin(9600);

  76.   WiFi.begin(u8"YUPIN", u8"0987654321");
  77.   while (!((WiFi.status() == WL_CONNECTED))) {
  78.     delay(1000);
  79.     Serial.println(u8"connecting ...");
  80.   }
  81.   Serial.println((WiFi.localIP().toString()));
  82.   _esp8266WebServer.on("/", handleRoot);
  83.   _esp8266WebServer.onNotFound(handleNotFound);
  84.   _esp8266WebServer.on("/setting", handleSetting);
  85.   _esp8266WebServer.begin();
  86.   time_JSON_response = u8"";
  87.   datetime = u8"";
  88.   date = u8"";
  89.   time_now = u8"";
  90.   day_of_week = u8"";
  91.   week_day = u8"";

  92. }

  93. // loop() 裡面的程式會不斷重複執行
  94. void loop() {
  95.   if (_httpGET(u8"http://worldtimeapi.org/api/timezone/Asia/Taipei") > 0) {
  96.     Get_Internet_Time();
  97.   }
  98.   delay(500);

  99. }

沒有留言:

張貼留言