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.1 KiB

  1. /*
  2. LIGHT MODULE
  3. Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com>
  4. */
  5. #if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
  6. #include <Ticker.h>
  7. Ticker colorTicker;
  8. #if LIGHT_PROVIDER == LIGHT_PROVIDER_MY9192
  9. #include <my9291.h>
  10. my9291 * _my9291;
  11. #endif
  12. // -----------------------------------------------------------------------------
  13. // UTILS
  14. // -----------------------------------------------------------------------------
  15. void color_rgb2array(const char * rgb, unsigned int * array) {
  16. char * p = (char *) rgb;
  17. if (p[0] == '#') ++p;
  18. unsigned long value = strtol(p, NULL, 16);
  19. array[0] = (value >> 16) & 0xFF;
  20. array[1] = (value >> 8) & 0xFF;
  21. array[2] = (value) & 0xFF;
  22. }
  23. void color_array2rgb(unsigned int * array, char * rgb) {
  24. unsigned long value = array[0];
  25. value = (value << 8) + array[1];
  26. value = (value << 8) + array[2];
  27. sprintf(rgb, "#%06X", value);
  28. }
  29. // -----------------------------------------------------------------------------
  30. // LIGHT MANAGEMENT
  31. // -----------------------------------------------------------------------------
  32. void lightColor(const char * rgb, bool save, bool forward) {
  33. #if LIGHT_PROVIDER == LIGHT_PROVIDER_MY9192
  34. unsigned int array[4] = {0};
  35. color_rgb2array(rgb, array);
  36. // If all set to the same value use white instead
  37. if ((array[0] == array[1]) && (array[1] == array[2])) {
  38. array[3] = array[0];
  39. array[0] = array[1] = array[2] = 0;
  40. }
  41. // Set new color (if light is open it will automatically change)
  42. _my9291->setColor((my9291_color_t) { array[0], array[1], array[2], array[3] });
  43. #endif
  44. // Delay saving to EEPROM 5 seconds to avoid wearing it out unnecessarily
  45. if (save) colorTicker.once(LIGHT_SAVE_DELAY, lightColorSave);
  46. // Report color to MQTT broker
  47. if (forward) mqttSend(MQTT_COLOR_TOPIC, rgb);
  48. // Report color to WS clients
  49. char message[20];
  50. sprintf(message, "{\"color\": \"%s\"}", rgb);
  51. wsSend(message);
  52. }
  53. String lightColor() {
  54. String response;
  55. #if LIGHT_PROVIDER == LIGHT_PROVIDER_MY9192
  56. my9291_color_t color = _my9291->getColor();
  57. unsigned int array[3];
  58. if (color.white > 0) {
  59. array[0] = array[1] = array[2] = color.white;
  60. } else {
  61. array[0] = color.red;
  62. array[1] = color.green;
  63. array[2] = color.blue;
  64. }
  65. char rgb[8];
  66. color_array2rgb(array, rgb);
  67. response = String(rgb);
  68. #endif
  69. return response;
  70. }
  71. void lightState(bool state) {
  72. #if LIGHT_PROVIDER == LIGHT_PROVIDER_MY9192
  73. _my9291->setState(state);
  74. #endif
  75. }
  76. bool lightState() {
  77. bool response = false;
  78. #if LIGHT_PROVIDER == LIGHT_PROVIDER_MY9192
  79. response = _my9291->getState();
  80. #endif
  81. return response;
  82. }
  83. // -----------------------------------------------------------------------------
  84. // PERSISTANCE
  85. // -----------------------------------------------------------------------------
  86. void lightColorSave() {
  87. setSetting("color", lightColor());
  88. saveSettings();
  89. }
  90. void lightColorRetrieve() {
  91. lightColor(getSetting("color", LIGHT_DEFAULT_COLOR).c_str(), false, true);
  92. }
  93. // -----------------------------------------------------------------------------
  94. // MQTT
  95. // -----------------------------------------------------------------------------
  96. void lightMQTTCallback(unsigned int type, const char * topic, const char * payload) {
  97. if (type == MQTT_CONNECT_EVENT) {
  98. mqttSubscribe(MQTT_COLOR_TOPIC);
  99. }
  100. if (type == MQTT_MESSAGE_EVENT) {
  101. // Match topic
  102. String t = mqttSubtopic((char *) topic);
  103. if (!t.equals(MQTT_COLOR_TOPIC)) return;
  104. lightColor(payload, true, mqttForward());
  105. }
  106. }
  107. // -----------------------------------------------------------------------------
  108. // SETUP
  109. // -----------------------------------------------------------------------------
  110. void lightSetup() {
  111. #if LIGHT_PROVIDER == LIGHT_PROVIDER_MY9192
  112. _my9291 = new my9291(MY9291_DI_PIN, MY9291_DCKI_PIN, MY9291_COMMAND);
  113. #endif
  114. lightColorRetrieve();
  115. mqttRegister(lightMQTTCallback);
  116. }
  117. #endif // LIGHT_PROVIDER != LIGHT_PROVIDER_NONE