dawidchyrzynski / arduino-home-assistant

ArduinoHA allows to integrate an Arduino/ESP based device with Home Assistant using MQTT.
https://dawidchyrzynski.github.io/arduino-home-assistant/
GNU Affero General Public License v3.0
463 stars 112 forks source link

FR: option to publish the device availability topic as a binary sensor #206

Open erkr opened 8 months ago

erkr commented 8 months ago

Hi,

Thanks for this great library. As an experiment, I ported one of my projects (a board with 6 relays with both a MQTT and a web interface) to this library. Reason: mainly the Discovery feature, as my projects require manual MQTT configurations.

In my projects I always configure the availability topic as a binary "connection" sensor. But in this library, that topic is not configured as a sensor for HA. I still have to add it manually like this:

binary_sensor:
  - name: connection
    unique_id: RELAIS_CTRL_166864_connection
    state_topic: "aha/RELAIS-CTRL_166864/avty_t"
    payload_on: "online"
    payload_off: "offline"
    device_class: connectivity
    device:
      name: RELAIS-CTRL
      identifiers: 
       - RELAIS-CTRL_166864

It would be great when this binary_sensor could be added automatically via discovery as well

Best Eric

erkr commented 8 months ago

Update; I created a "ugly' but 'simple' workaround to get the config discovery topic for an Availability binary sensor published without modifying the library. I derived a new small new device type from the base device type class. Just instantiate one instance and it will published the config (works only if shared availablity is configured). The header part:

class HAConnectionBinarySensor : HABaseDeviceType
{
public:
  HAConnectionBinarySensor(const char *name);

protected:
  virtual void buildSerializer() override;
  virtual void onMqttConnected() override;
};

And the cpp part:

//////////////////////////
// Special discovery device type only for publishing the config (doesn't do anything else)
// for a binary sensor that represents the connection state 
HAConnectionBinarySensor::HAConnectionBinarySensor(const char* uniqueId) : HABaseDeviceType( AHATOFSTR(HAComponentBinarySensor), uniqueId )
{
}

void HAConnectionBinarySensor::buildSerializer()
{
    const HADevice* device = mqtt()->getDevice();
    if ( !device ||
         !(device->isSharedAvailabilityEnabled()) || 
         _serializer || 
         !uniqueId()  ) {
        return;
    }
    // publish a binary sensor that represents the availablity of this device
    _serializer = new HASerializer(this, 7); 
    _serializer->set(AHATOFSTR(HANameProperty),uniqueId());
    _serializer->set(AHATOFSTR(HAUniqueIdProperty), _configUniqueID);
    _serializer->set(AHATOFSTR(HADeviceClassProperty), "connectivity");
    _serializer->set(AHATOFSTR("pl_on"),"online");
    _serializer->set(AHATOFSTR("pl_off"),"offline"); // payload_off was not defined in lib
    _serializer->set(AHATOFSTR(HAStateTopic), device->getAvailabilityTopic());
    _serializer->set(HASerializer::WithDevice);
}

void HAConnectionBinarySensor::onMqttConnected() {
    if (!uniqueId()) {
        return;
    }
    publishConfig();
}

Example of the binary sensor configuration published in the MQTT broker: The topic: homeassistant/binary_sensor/RCTRL_198e31/Connection/config The payload:

{
  "name": "Connection",
  "uniq_id": "RCTRL_198e31_Connection",
  "dev_cla": "connectivity",
  "pl_on": "online",
  "pl_off": "offline",
  "stat_t": "aha/RCTRL_198e31/avty_t",
  "dev": {
    "ids": "RCTRL_198e31",
    "name": "RCTRL",
    "sw": "v1.2",
    "mdl": "ESP8266",
  }
}

And what is added to MQTT device in Home assistant: image

Have fun :-)