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.

150 lines
3.5 KiB

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