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.

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