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.

157 lines
3.8 KiB

  1. /*
  2. LED MODULE
  3. Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com>
  4. */
  5. // -----------------------------------------------------------------------------
  6. // LED
  7. // -----------------------------------------------------------------------------
  8. #ifdef LED1_PIN
  9. typedef struct {
  10. unsigned char pin;
  11. bool reverse;
  12. } led_t;
  13. std::vector<led_t> _leds;
  14. bool ledAuto;
  15. bool ledStatus(unsigned char id) {
  16. if (id >= _leds.size()) return false;
  17. bool status = digitalRead(_leds[id].pin);
  18. return _leds[id].reverse ? !status : status;
  19. }
  20. bool ledStatus(unsigned char id, bool status) {
  21. if (id >= _leds.size()) return false;
  22. bool s = _leds[id].reverse ? !status : status;
  23. digitalWrite(_leds[id].pin, _leds[id].reverse ? !status : status);
  24. return status;
  25. }
  26. bool ledToggle(unsigned char id) {
  27. if (id >= _leds.size()) return false;
  28. return ledStatus(id, !ledStatus(id));
  29. }
  30. void ledBlink(unsigned char id, unsigned long delayOff, unsigned long delayOn) {
  31. if (id >= _leds.size()) return;
  32. static unsigned long next = millis();
  33. if (next < millis()) {
  34. next += (ledToggle(id) ? delayOn : delayOff);
  35. }
  36. }
  37. #if WIFI_LED
  38. void showStatus() {
  39. if (wifiConnected()) {
  40. if (WiFi.getMode() == WIFI_AP) {
  41. ledBlink(WIFI_LED, 2500, 2500);
  42. } else {
  43. ledBlink(WIFI_LED, 4900, 100);
  44. }
  45. } else {
  46. ledBlink(WIFI_LED, 500, 500);
  47. }
  48. }
  49. #endif
  50. void ledMQTTCallback(unsigned int type, const char * topic, const char * payload) {
  51. static bool isFirstMessage = true;
  52. String mqttSetter = getSetting("mqttSetter", MQTT_USE_SETTER);
  53. if (type == MQTT_CONNECT_EVENT) {
  54. char buffer[strlen(MQTT_LED_TOPIC) + mqttSetter.length() + 3];
  55. sprintf(buffer, "%s/+%s", MQTT_LED_TOPIC, mqttSetter.c_str());
  56. mqttSubscribe(buffer);
  57. }
  58. if (type == MQTT_MESSAGE_EVENT) {
  59. // Match topic
  60. char * t = mqttSubtopic((char *) topic);
  61. if (strncmp(t, MQTT_LED_TOPIC, strlen(MQTT_LED_TOPIC)) != 0) return;
  62. int len = mqttSetter.length();
  63. if (strncmp(t + strlen(t) - len, mqttSetter.c_str(), len) != 0) return;
  64. // Get led ID
  65. unsigned int ledID = topic[strlen(topic) - mqttSetter.length() - 1] - '0';
  66. if (ledID >= ledCount()) {
  67. DEBUG_MSG("[LED] Wrong ledID (%d)\n", ledID);
  68. return;
  69. }
  70. // get value
  71. unsigned int value = (char)payload[0] - '0';
  72. bool bitAuto = (value & 0x02) > 0;
  73. bool bitState = (value & 0x01) > 0;
  74. // Check ledAuto
  75. if (ledID == 0) {
  76. ledAuto = bitAuto ? bitState : false;
  77. setSetting("ledAuto", String() + (ledAuto ? "1" : "0"));
  78. if (bitAuto) return;
  79. }
  80. // Action to perform
  81. ledStatus(ledID, bitState);
  82. }
  83. }
  84. unsigned char ledCount() {
  85. return _leds.size();
  86. }
  87. void ledConfigure() {
  88. ledAuto = getSetting("ledAuto", String() + LED_AUTO).toInt() == 1;
  89. }
  90. void ledSetup() {
  91. #ifdef LED1_PIN
  92. _leds.push_back((led_t) { LED1_PIN, LED1_PIN_INVERSE });
  93. #endif
  94. #ifdef LED2_PIN
  95. _leds.push_back((led_t) { LED2_PIN, LED2_PIN_INVERSE });
  96. #endif
  97. #ifdef LED3_PIN
  98. _leds.push_back((led_t) { LED3_PIN, LED3_PIN_INVERSE });
  99. #endif
  100. #ifdef LED4_PIN
  101. _leds.push_back((led_t) { LED4_PIN, LED4_PIN_INVERSE });
  102. #endif
  103. for (unsigned int i=0; i < _leds.size(); i++) {
  104. pinMode(_leds[i].pin, OUTPUT);
  105. ledStatus(i, false);
  106. }
  107. ledConfigure();
  108. mqttRegister(ledMQTTCallback);
  109. DEBUG_MSG("[LED] Number of leds: %d\n", _leds.size());
  110. DEBUG_MSG("[LED] Led auto indicator is %s\n", ledAuto ? "ON" : "OFF" );
  111. }
  112. void ledLoop() {
  113. #if WIFI_LED
  114. if (ledAuto) showStatus();
  115. #endif
  116. }
  117. #else
  118. void ledSetup() {};
  119. void ledLoop() {};
  120. #endif