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.

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