Fork of the espurna firmware for `mhsw` switches
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
4.3 KiB

8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
7 years ago
7 years ago
8 years ago
  1. /*
  2. NTP MODULE
  3. Copyright (C) 2016-2018 by Xose Pérez <xose dot perez at gmail dot com>
  4. */
  5. #if NTP_SUPPORT
  6. #include <TimeLib.h>
  7. #include <NtpClientLib.h>
  8. #include <WiFiClient.h>
  9. #include <Ticker.h>
  10. unsigned long _ntp_start = 0;
  11. bool _ntp_update = false;
  12. bool _ntp_configure = false;
  13. // -----------------------------------------------------------------------------
  14. // NTP
  15. // -----------------------------------------------------------------------------
  16. void _ntpWebSocketOnSend(JsonObject& root) {
  17. root["ntpVisible"] = 1;
  18. root["ntpStatus"] = (timeStatus() == timeSet);
  19. root["ntpServer"] = getSetting("ntpServer", NTP_SERVER);
  20. root["ntpOffset"] = getSetting("ntpOffset", NTP_TIME_OFFSET).toInt();
  21. root["ntpDST"] = getSetting("ntpDST", NTP_DAY_LIGHT).toInt() == 1;
  22. root["ntpRegion"] = getSetting("ntpRegion", NTP_DST_REGION).toInt();
  23. if (ntpSynced()) root["now"] = now();
  24. }
  25. void _ntpStart() {
  26. _ntp_start = 0;
  27. NTP.begin(getSetting("ntpServer", NTP_SERVER));
  28. NTP.setInterval(NTP_SYNC_INTERVAL, NTP_UPDATE_INTERVAL);
  29. NTP.setNTPTimeout(NTP_TIMEOUT);
  30. _ntpConfigure();
  31. }
  32. void _ntpConfigure() {
  33. _ntp_configure = false;
  34. int offset = getSetting("ntpOffset", NTP_TIME_OFFSET).toInt();
  35. int sign = offset > 0 ? 1 : -1;
  36. offset = abs(offset);
  37. int tz_hours = sign * (offset / 60);
  38. int tz_minutes = sign * (offset % 60);
  39. if (NTP.getTimeZone() != tz_hours || NTP.getTimeZoneMinutes() != tz_minutes) {
  40. NTP.setTimeZone(tz_hours, tz_minutes);
  41. _ntp_update = true;
  42. }
  43. bool daylight = getSetting("ntpDST", NTP_DAY_LIGHT).toInt() == 1;
  44. if (NTP.getDayLight() != daylight) {
  45. NTP.setDayLight(daylight);
  46. _ntp_update = true;
  47. }
  48. String server = getSetting("ntpServer", NTP_SERVER);
  49. if (!NTP.getNtpServerName().equals(server)) {
  50. NTP.setNtpServerName(server);
  51. }
  52. uint8_t dst_region = getSetting("ntpRegion", NTP_DST_REGION).toInt();
  53. NTP.setDSTZone(dst_region);
  54. }
  55. void _ntpUpdate() {
  56. _ntp_update = false;
  57. #if WEB_SUPPORT
  58. wsSend(_ntpWebSocketOnSend);
  59. #endif
  60. if (strlen(ntpDateTime().c_str())) {
  61. DEBUG_MSG_P(PSTR("[NTP] Time: %s\n"), (char *) ntpDateTime().c_str());
  62. }
  63. }
  64. void _ntpLoop() {
  65. if (0 < _ntp_start && _ntp_start < millis()) _ntpStart();
  66. if (_ntp_configure) _ntpConfigure();
  67. if (_ntp_update) _ntpUpdate();
  68. now();
  69. #if BROKER_SUPPORT
  70. static unsigned char last_minute = 60;
  71. if (ntpSynced() && (minute() != last_minute)) {
  72. last_minute = minute();
  73. brokerPublish(MQTT_TOPIC_DATETIME, ntpDateTime().c_str());
  74. }
  75. #endif
  76. }
  77. void _ntpBackwards() {
  78. moveSetting("ntpServer1", "ntpServer");
  79. delSetting("ntpServer2");
  80. delSetting("ntpServer3");
  81. int offset = getSetting("ntpOffset", NTP_TIME_OFFSET).toInt();
  82. if (-30 < offset && offset < 30) {
  83. offset *= 60;
  84. setSetting("ntpOffset", offset);
  85. }
  86. }
  87. // -----------------------------------------------------------------------------
  88. bool ntpSynced() {
  89. return (year() > 2017);
  90. }
  91. String ntpDateTime() {
  92. if (!ntpSynced()) return String();
  93. char buffer[20];
  94. time_t t = now();
  95. snprintf_P(buffer, sizeof(buffer),
  96. PSTR("%04d-%02d-%02d %02d:%02d:%02d"),
  97. year(t), month(t), day(t), hour(t), minute(t), second(t)
  98. );
  99. return String(buffer);
  100. }
  101. // -----------------------------------------------------------------------------
  102. void ntpSetup() {
  103. _ntpBackwards();
  104. NTP.onNTPSyncEvent([](NTPSyncEvent_t error) {
  105. if (error) {
  106. #if WEB_SUPPORT
  107. wsSend_P(PSTR("{\"ntpStatus\": false}"));
  108. #endif
  109. if (error == noResponse) {
  110. DEBUG_MSG_P(PSTR("[NTP] Error: NTP server not reachable\n"));
  111. } else if (error == invalidAddress) {
  112. DEBUG_MSG_P(PSTR("[NTP] Error: Invalid NTP server address\n"));
  113. }
  114. } else {
  115. _ntp_update = true;
  116. }
  117. });
  118. wifiRegister([](justwifi_messages_t code, char * parameter) {
  119. if (code == MESSAGE_CONNECTED) _ntp_start = millis() + NTP_START_DELAY;
  120. });
  121. #if WEB_SUPPORT
  122. wsOnSendRegister(_ntpWebSocketOnSend);
  123. wsOnAfterParseRegister([]() { _ntp_configure = true; });
  124. #endif
  125. // Register loop
  126. espurnaRegisterLoop(_ntpLoop);
  127. }
  128. #endif // NTP_SUPPORT