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.

147 lines
3.6 KiB

6 years ago
6 years ago
6 years ago
6 years ago
  1. /*
  2. ALEXA MODULE
  3. Copyright (C) 2016-2018 by Xose Pérez <xose dot perez at gmail dot com>
  4. Module key prefix: alx
  5. */
  6. #if ALEXA_SUPPORT
  7. #include <fauxmoESP.h>
  8. fauxmoESP alexa;
  9. #include <queue>
  10. typedef struct {
  11. unsigned char device_id;
  12. bool state;
  13. unsigned char value;
  14. } alexa_queue_element_t;
  15. static std::queue<alexa_queue_element_t> _alexa_queue;
  16. // -----------------------------------------------------------------------------
  17. // ALEXA
  18. // -----------------------------------------------------------------------------
  19. #if WEB_SUPPORT
  20. void _alexaWebSocketOnSend(JsonObject& root) {
  21. root["alxVisible"] = 1;
  22. root["alxEnabled"] = alexaEnabled();
  23. }
  24. #endif
  25. void _alexaConfigure() {
  26. alexa.enable(wifiConnected() && alexaEnabled());
  27. }
  28. bool _alexaKeyCheck(const char * key) {
  29. return (strncmp(key, "alx", 3) == 0);
  30. }
  31. void _alexaBackwards() {
  32. moveSetting("fauxmoEnabled", "alxEnabled"); // 1.9.0 - 2017-08-25
  33. moveSetting("alexaEnabled", "alxEnabled"); // 1.14.0 - 2018-06-27
  34. }
  35. // -----------------------------------------------------------------------------
  36. bool alexaEnabled() {
  37. return (getSetting("alexaEnabled", ALEXA_ENABLED).toInt() == 1);
  38. }
  39. void alexaSetup() {
  40. // Check backwards compatibility
  41. _alexaBackwards();
  42. // Load & cache settings
  43. _alexaConfigure();
  44. // Uses hostname as base name for all devices
  45. // TODO: use custom switch name when available
  46. String hostname = getSetting("hostname");
  47. // Lights
  48. #if RELAY_PROVIDER == RELAY_PROVIDER_LIGHT
  49. // Global switch
  50. alexa.addDevice(hostname.c_str());
  51. // For each channel
  52. for (unsigned char i = 1; i <= lightChannels(); i++) {
  53. alexa.addDevice((hostname + " " + i).c_str());
  54. }
  55. // Relays
  56. #else
  57. unsigned int relays = relayCount();
  58. if (relays == 1) {
  59. alexa.addDevice(hostname.c_str());
  60. } else {
  61. for (unsigned int i=1; i<=relays; i++) {
  62. alexa.addDevice((hostname + " " + i).c_str());
  63. }
  64. }
  65. #endif
  66. // Callback
  67. alexa.onSetState([&](unsigned char device_id, const char * name, bool state, unsigned char value) {
  68. alexa_queue_element_t element;
  69. element.device_id = device_id;
  70. element.state = state;
  71. element.value = value;
  72. _alexa_queue.push(element);
  73. });
  74. // Websockets
  75. #if WEB_SUPPORT
  76. wsOnSendRegister(_alexaWebSocketOnSend);
  77. wsOnAfterParseRegister(_alexaConfigure);
  78. #endif
  79. // Register wifi callback
  80. wifiRegister([](justwifi_messages_t code, char * parameter) {
  81. if ((MESSAGE_CONNECTED == code) || (MESSAGE_DISCONNECTED == code)) {
  82. _alexaConfigure();
  83. }
  84. });
  85. // Settings
  86. settingsRegisterKeyCheck(_alexaKeyCheck);
  87. // Register loop
  88. espurnaRegisterLoop(alexaLoop);
  89. }
  90. void alexaLoop() {
  91. alexa.handle();
  92. while (!_alexa_queue.empty()) {
  93. alexa_queue_element_t element = _alexa_queue.front();
  94. DEBUG_MSG_P(PSTR("[ALEXA] Device #%u state: %s value: %d\n"), element.device_id, element.state ? "ON" : "OFF", element.value);
  95. #if RELAY_PROVIDER == RELAY_PROVIDER_LIGHT
  96. if (0 == element.device_id) {
  97. relayStatus(0, element.state);
  98. } else {
  99. lightState(element.device_id - 1, element.state);
  100. lightChannel(element.device_id - 1, element.value);
  101. lightUpdate(true, true);
  102. }
  103. #else
  104. relayStatus(element.device_id, element.state);
  105. #endif
  106. _alexa_queue.pop();
  107. }
  108. }
  109. #endif