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.

167 lines
4.8 KiB

  1. /*
  2. SCHEDULER MODULE
  3. Copyright (C) 2017 by faina09
  4. Adapted by Xose Pérez <xose dot perez at gmail dot com>
  5. */
  6. #if SCHEDULER_SUPPORT
  7. #include <NtpClientLib.h>
  8. #if WEB_SUPPORT
  9. void _schWebSocketOnSend(JsonObject &root){
  10. root["maxScheduled"] = SCHEDULER_MAX_SCHEDULES;
  11. JsonArray &sch = root.createNestedArray("schedule");
  12. for (byte i = 0; i < SCHEDULER_MAX_SCHEDULES; i++) {
  13. if (!hasSetting("schSwitch", i)) break;
  14. JsonObject &scheduler = sch.createNestedObject();
  15. scheduler["schSwitch"] = getSetting("schSwitch", i, "");
  16. scheduler["schAction"] = getSetting("schAction", i, "");
  17. scheduler["schHour"] = getSetting("schHour", i, "");
  18. scheduler["schMinute"] = getSetting("schMinute", i, "");
  19. scheduler["schWDs"] = getSetting("schWDs", i, "");
  20. }
  21. }
  22. #endif // WEB_SUPPORT
  23. void _schConfigure() {
  24. bool delete_flag = false;
  25. for (unsigned char i = 0; i < SCHEDULER_MAX_SCHEDULES; i++) {
  26. int sch_switch = getSetting("schSwitch", i, 0xFF).toInt();
  27. if (sch_switch == 0xFF) delete_flag = true;
  28. if (delete_flag) {
  29. delSetting("schSwitch", i);
  30. delSetting("schAction", i);
  31. delSetting("schHour", i);
  32. delSetting("schMinute", i);
  33. delSetting("schWDs", i);
  34. } else {
  35. #if DEBUG_SUPPORT
  36. int sch_action = getSetting("schAction", i, 0).toInt();
  37. int sch_hour = getSetting("schHour", i, 0).toInt();
  38. int sch_minute = getSetting("schMinute", i, 0).toInt();
  39. String sch_weekdays = getSetting("schWDs", i, "");
  40. DEBUG_MSG_P(
  41. PSTR("[SCH] Schedule #%d: %s switch #%d at %02d:%02d on %s\n"),
  42. i, sch_action == 0 ? "turn OFF" : sch_action == 1 ? "turn ON" : "toggle", sch_switch,
  43. sch_hour, sch_minute, (char *) sch_weekdays.c_str()
  44. );
  45. #endif // DEBUG_SUPPORT
  46. }
  47. }
  48. }
  49. bool _schIsThisWeekday(String weekdays){
  50. // Monday = 1, Tuesday = 2 ... Sunday = 7
  51. int w = weekday(now()) - 1;
  52. if (w == 0) w = 7;
  53. char pch;
  54. char * p = (char *) weekdays.c_str();
  55. unsigned char position = 0;
  56. while (pch = p[position++]) {
  57. if ((pch - '0') == w) return true;
  58. }
  59. return false;
  60. }
  61. int _schMinutesLeft(unsigned char schedule_hour, unsigned char schedule_minute){
  62. unsigned char now_hour;
  63. unsigned char now_minute;
  64. if (ntpConnected()) {
  65. String value = NTP.getTimeDateString();
  66. now_hour = value.substring(0, 2).toInt();
  67. now_minute = value.substring(3, 5).toInt();
  68. } else {
  69. time_t t = now();
  70. now_hour = hour(t);
  71. now_minute = minute(t);
  72. }
  73. return (schedule_hour - now_hour) * 60 + schedule_minute - now_minute;
  74. }
  75. // -----------------------------------------------------------------------------
  76. void schSetup() {
  77. _schConfigure();
  78. // Update websocket clients
  79. #if WEB_SUPPORT
  80. wsOnSendRegister(_schWebSocketOnSend);
  81. wsOnAfterParseRegister(_schConfigure);
  82. #endif
  83. }
  84. void schLoop() {
  85. static unsigned long last_update = 0;
  86. static int update_time = 0;
  87. // Check if we should compare scheduled and actual times
  88. if ((millis() - last_update > update_time) || (last_update == 0)) {
  89. last_update = millis();
  90. // Calculate next update time
  91. unsigned char current_second = ntpConnected() ?
  92. NTP.getTimeDateString().substring(6, 8).toInt() :
  93. second(now())
  94. ;
  95. update_time = (SCHEDULER_UPDATE_SEC + 60 - current_second) * 1000;
  96. for (unsigned char i = 0; i < SCHEDULER_MAX_SCHEDULES; i++) {
  97. int sch_switch = getSetting("schSwitch", i, 0xFF).toInt();
  98. if (sch_switch == 0xFF) break;
  99. String sch_weekdays = getSetting("schWDs", i, "");
  100. if (_schIsThisWeekday(sch_weekdays)) {
  101. int sch_hour = getSetting("schHour", i, 0).toInt();
  102. int sch_minute = getSetting("schMinute", i, 0).toInt();
  103. int minutes_to_trigger = _schMinutesLeft(sch_hour, sch_minute);
  104. if (minutes_to_trigger == 0) {
  105. int sch_action = getSetting("schAction", i, 0).toInt();
  106. if (sch_action == 2) {
  107. relayToggle(sch_switch);
  108. } else {
  109. relayStatus(sch_switch, sch_action);
  110. }
  111. DEBUG_MSG_P(PSTR("[SCH] Schedule #%d TRIGGERED!!\n"), sch_switch);
  112. } else if (minutes_to_trigger > 0) {
  113. DEBUG_MSG_P(
  114. PSTR("[SCH] %d minutes to trigger schedule #%d\n"),
  115. minutes_to_trigger, sch_switch
  116. );
  117. }
  118. }
  119. }
  120. }
  121. }
  122. #endif // SCHEDULER_SUPPORT