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.

179 lines
5.1 KiB

7 years ago
  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 <TimeLib.h>
  8. // -----------------------------------------------------------------------------
  9. #if WEB_SUPPORT
  10. void _schWebSocketOnSend(JsonObject &root){
  11. root["maxScheduled"] = SCHEDULER_MAX_SCHEDULES;
  12. JsonArray &sch = root.createNestedArray("schedule");
  13. for (byte i = 0; i < SCHEDULER_MAX_SCHEDULES; i++) {
  14. if (!hasSetting("schSwitch", i)) break;
  15. JsonObject &scheduler = sch.createNestedObject();
  16. scheduler["schSwitch"] = getSetting("schSwitch", i, "");
  17. scheduler["schAction"] = getSetting("schAction", i, "");
  18. scheduler["schHour"] = getSetting("schHour", i, "");
  19. scheduler["schMinute"] = getSetting("schMinute", i, "");
  20. scheduler["schWDs"] = getSetting("schWDs", i, "");
  21. }
  22. }
  23. #endif // WEB_SUPPORT
  24. // -----------------------------------------------------------------------------
  25. void _schConfigure() {
  26. bool delete_flag = false;
  27. for (unsigned char i = 0; i < SCHEDULER_MAX_SCHEDULES; i++) {
  28. int sch_switch = getSetting("schSwitch", i, 0xFF).toInt();
  29. if (sch_switch == 0xFF) delete_flag = true;
  30. if (delete_flag) {
  31. delSetting("schSwitch", i);
  32. delSetting("schAction", i);
  33. delSetting("schHour", i);
  34. delSetting("schMinute", i);
  35. delSetting("schWDs", i);
  36. } else {
  37. #if DEBUG_SUPPORT
  38. int sch_action = getSetting("schAction", i, 0).toInt();
  39. int sch_hour = getSetting("schHour", i, 0).toInt();
  40. int sch_minute = getSetting("schMinute", i, 0).toInt();
  41. String sch_weekdays = getSetting("schWDs", i, "");
  42. DEBUG_MSG_P(
  43. PSTR("[SCH] Schedule #%d: %s switch #%d at %02d:%02d on %s\n"),
  44. i, sch_action == 0 ? "turn OFF" : sch_action == 1 ? "turn ON" : "toggle", sch_switch,
  45. sch_hour, sch_minute, (char *) sch_weekdays.c_str()
  46. );
  47. #endif // DEBUG_SUPPORT
  48. }
  49. }
  50. }
  51. bool _schIsThisWeekday(String weekdays){
  52. // Convert from Sunday to Monday as day 1
  53. int w = weekday(now()) - 1;
  54. if (w == 0) w = 7;
  55. char pch;
  56. char * p = (char *) weekdays.c_str();
  57. unsigned char position = 0;
  58. while (pch = p[position++]) {
  59. if ((pch - '0') == w) return true;
  60. }
  61. return false;
  62. }
  63. int _schMinutesLeft(unsigned char schedule_hour, unsigned char schedule_minute){
  64. time_t t = now();
  65. unsigned char now_hour = hour(t);
  66. unsigned char now_minute = minute(t);
  67. return (schedule_hour - now_hour) * 60 + schedule_minute - now_minute;
  68. }
  69. void _schCheck() {
  70. // Check schedules
  71. for (unsigned char i = 0; i < SCHEDULER_MAX_SCHEDULES; i++) {
  72. int sch_switch = getSetting("schSwitch", i, 0xFF).toInt();
  73. if (sch_switch == 0xFF) break;
  74. String sch_weekdays = getSetting("schWDs", i, "");
  75. if (_schIsThisWeekday(sch_weekdays)) {
  76. int sch_hour = getSetting("schHour", i, 0).toInt();
  77. int sch_minute = getSetting("schMinute", i, 0).toInt();
  78. int minutes_to_trigger = _schMinutesLeft(sch_hour, sch_minute);
  79. if (minutes_to_trigger == 0) {
  80. int sch_action = getSetting("schAction", i, 0).toInt();
  81. if (sch_action == 2) {
  82. relayToggle(sch_switch);
  83. } else {
  84. relayStatus(sch_switch, sch_action);
  85. }
  86. DEBUG_MSG_P(PSTR("[SCH] Schedule #%d TRIGGERED!!\n"), sch_switch);
  87. // Show minutes to trigger every 15 minutes
  88. // or every minute if less than 15 minutes to scheduled time.
  89. // This only works for schedules on this same day.
  90. // For instance, if your scheduler is set for 00:01 you will only
  91. // get one notification before the trigger (at 00:00)
  92. } else if (minutes_to_trigger > 0) {
  93. #if DEBUG_SUPPORT
  94. if ((minutes_to_trigger % 15 == 0) || (minutes_to_trigger < 15)) {
  95. DEBUG_MSG_P(
  96. PSTR("[SCH] %d minutes to trigger schedule #%d\n"),
  97. minutes_to_trigger, sch_switch
  98. );
  99. }
  100. #endif
  101. }
  102. }
  103. }
  104. }
  105. void _schLoop() {
  106. // Check time has been sync'ed
  107. if (!ntpSynced()) return;
  108. // Check schedules every minute at hh:mm:00
  109. static unsigned long last_minute = 60;
  110. unsigned char current_minute = minute();
  111. if (current_minute != last_minute) {
  112. last_minute = current_minute;
  113. _schCheck();
  114. }
  115. }
  116. // -----------------------------------------------------------------------------
  117. void schSetup() {
  118. _schConfigure();
  119. // Update websocket clients
  120. #if WEB_SUPPORT
  121. wsOnSendRegister(_schWebSocketOnSend);
  122. wsOnAfterParseRegister(_schConfigure);
  123. #endif
  124. // Register loop
  125. espurnaRegisterLoop(_schLoop);
  126. }
  127. #endif // SCHEDULER_SUPPORT