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.

182 lines
4.7 KiB

  1. /*
  2. HOME ASSISTANT MODULE
  3. Copyright (C) 2017-2018 by Xose Pérez <xose dot perez at gmail dot com>
  4. */
  5. #if HOMEASSISTANT_SUPPORT
  6. #include <ArduinoJson.h>
  7. bool _haEnabled = false;
  8. bool _haSendFlag = false;
  9. // -----------------------------------------------------------------------------
  10. void _haWebSocketOnSend(JsonObject& root) {
  11. root["haVisible"] = 1;
  12. root["haPrefix"] = getSetting("haPrefix", HOMEASSISTANT_PREFIX);
  13. root["haEnabled"] = getSetting("haEnabled", HOMEASSISTANT_ENABLED).toInt() == 1;
  14. }
  15. #if SENSOR_SUPPORT
  16. void _haSendMagnitude(unsigned char i) {
  17. String output;
  18. if (_haEnabled) {
  19. DynamicJsonBuffer jsonBuffer;
  20. JsonObject& root = jsonBuffer.createObject();
  21. unsigned char type = magnitudeType(i);
  22. root["device_class"] = "sensor";
  23. root["name"] = getSetting("hostname") + String(" ") + magnitudeTopic(type);
  24. root["state_topic"] = mqttTopic(magnitudeTopicIndex(i).c_str(), false);
  25. root["unit_of_measurement"] = magnitudeUnits(type);
  26. root.printTo(output);
  27. }
  28. String topic = getSetting("haPrefix", HOMEASSISTANT_PREFIX) +
  29. "/sensor/" +
  30. getSetting("hostname") + "_" + String(i) +
  31. "/config";
  32. mqttSendRaw(topic.c_str(), output.c_str());
  33. mqttSend(MQTT_TOPIC_STATUS, MQTT_STATUS_ONLINE, true);
  34. }
  35. void _haSendMagnitudes() {
  36. for (unsigned char i=0; i<magnitudeCount(); i++) {
  37. _haSendMagnitude(i);
  38. }
  39. }
  40. #endif
  41. void _haSendSwitch(unsigned char i) {
  42. String output;
  43. if (_haEnabled) {
  44. DynamicJsonBuffer jsonBuffer;
  45. JsonObject& root = jsonBuffer.createObject();
  46. String name = getSetting("hostname");
  47. if (relayCount() > 1) {
  48. name += String(" switch #") + String(i);
  49. }
  50. root["name"] = name;
  51. root["platform"] = "mqtt";
  52. if (relayCount()) {
  53. root["state_topic"] = mqttTopic(MQTT_TOPIC_RELAY, i, false);
  54. root["command_topic"] = mqttTopic(MQTT_TOPIC_RELAY, i, true);
  55. root["payload_on"] = String("1");
  56. root["payload_off"] = String("0");
  57. root["availability_topic"] = mqttTopic(MQTT_TOPIC_STATUS, false);
  58. root["payload_available"] = String("1");
  59. root["payload_not_available"] = String("0");
  60. }
  61. #if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
  62. if (i == 0) {
  63. if (lightHasColor()) {
  64. root["brightness_state_topic"] = mqttTopic(MQTT_TOPIC_BRIGHTNESS, false);
  65. root["brightness_command_topic"] = mqttTopic(MQTT_TOPIC_BRIGHTNESS, true);
  66. root["rgb_state_topic"] = mqttTopic(MQTT_TOPIC_COLOR_RGB, false);
  67. root["rgb_command_topic"] = mqttTopic(MQTT_TOPIC_COLOR_RGB, true);
  68. root["color_temp_command_topic"] = mqttTopic(MQTT_TOPIC_MIRED, true);
  69. }
  70. if (lightChannels() > 3) {
  71. root["white_value_state_topic"] = mqttTopic(MQTT_TOPIC_CHANNEL, 3, false);
  72. root["white_value_command_topic"] = mqttTopic(MQTT_TOPIC_CHANNEL, 3, true);
  73. }
  74. }
  75. #endif // LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
  76. root.printTo(output);
  77. }
  78. #if LIGHT_PROVIDER == LIGHT_PROVIDER_NONE
  79. String component = String("switch");
  80. #else
  81. String component = String("light");
  82. #endif
  83. String topic = getSetting("haPrefix", HOMEASSISTANT_PREFIX) +
  84. "/" + component +
  85. "/" + getSetting("hostname") + "_" + String(i) +
  86. "/config";
  87. mqttSendRaw(topic.c_str(), output.c_str());
  88. mqttSend(MQTT_TOPIC_STATUS, MQTT_STATUS_ONLINE, true);
  89. }
  90. void _haSendSwitches() {
  91. for (unsigned char i=0; i<relayCount(); i++) {
  92. _haSendSwitch(i);
  93. }
  94. }
  95. void _haSend() {
  96. // Pending message to send?
  97. if (!_haSendFlag) return;
  98. // Are we connected?
  99. if (!mqttConnected()) return;
  100. DEBUG_MSG_P(PSTR("[HA] Sending autodiscovery MQTT message\n"));
  101. // Send messages
  102. _haSendSwitches();
  103. #if SENSOR_SUPPORT
  104. _haSendMagnitudes();
  105. #endif
  106. _haSendFlag = false;
  107. }
  108. void _haConfigure() {
  109. bool enabled = getSetting("haEnabled", HOMEASSISTANT_ENABLED).toInt() == 1;
  110. _haSendFlag = (enabled != _haEnabled);
  111. _haEnabled = enabled;
  112. _haSend();
  113. }
  114. // -----------------------------------------------------------------------------
  115. void haSetup() {
  116. _haConfigure();
  117. #if WEB_SUPPORT
  118. wsOnSendRegister(_haWebSocketOnSend);
  119. wsOnAfterParseRegister(_haConfigure);
  120. #endif
  121. // On MQTT connect check if we have something to send
  122. mqttRegister([](unsigned int type, const char * topic, const char * payload) {
  123. if (type == MQTT_CONNECT_EVENT) _haSend();
  124. });
  125. }
  126. #endif // HOMEASSISTANT_SUPPORT