Cannot register one entity via MQTT

I am trying to register a particular entity via MQTT but it is not added to the entities list

  • it is visible in MQTT Explorer (it is persistant)
  • simple test entities added the same way do appear correctly

Because of this, I belive that there is a problem in the payload below that I am sending to homeassistant/select/backup_AAA_BBB_CCC/config

{
  "name": "backup AAA_BBB_CCC",
  "unique_id": "backup_AAA_BBB_CCC",
  "state_topic": "backup/AAA_BBB_CCC/state",
  "json_attributes_topic": "backup/AAA_BBB_CCC/state",
  "json_attributes_path": "$.attributes",
  "value_template": "{{ value_json.state }}",
  "device_class": "enum",
  "options": ["success", "error", "cancelled"],
  "entity_category": "diagnostic",
  "device": {
    "identifiers": ["AAA_BBB_CCC"],
    "name": "backup AAA_BBB_CCC",
    "manufacturer": "restic",
    "model": "backup job"
  },
  "availability_topic": "backup/AAA_BBB_CCC/availability"
}

Is there something in this payload that is incorrect for HA?

Look at the payload in MQTT Explorer.
If the text is in color, the JSON is correct.
If not, there is a JSON error.
Next none of those topics are in the homeassistant/ name space. They appear to be in their own topics. In that case you need to set the entities in YAML and tell HA where to look.

Thanks for the answer but I am not sure I understand your points

The JSON I provided is correct

The discovery topic is homeassistant/select/backup_AAA_BBB_CCC/config(which is the namespace provided in the docyumentation and that works for the test cases I mentioned), the state topic can be anything (it does not have to be in the homeassistant namespace – when you look at what actually gets registered you see all kinds of conventions)

Elephant in the room: Did you publish a JSON to that topic? Example?

I fixed the problem, but I do not have a definite solution.

In my initial code I used a sub/pub approach to connecting to the MQTT broker. I connected, subscribed to a topic, checked the subscription and from then on was sending the messages (first discovery, then updates)

The messages were visible in MQTT Explorer in the correct place, but were not used by HA to create the entity.

I changed the approach and decided to just publish one-off (ad-hoc) messages. This is, of course, a very ineffective way, but I only publish individual messages every few hours so this is negligible.

And here, a big change: the messages are visible in MQTT Explorer in exactly the same place, structure and content as above, but this time HA correctly registers the entities.

Why is it so - I do not know. The broker has in both cases the correct, persistent topics published but only in one case HA decides to make use of them.

So my problem is fixed, this can be useful if someone stumbles upon the same issue but I am not happy with the outcome.

Mmmm… Weren’t you consuming the messages yourself, before HA? :wink:
What QOS / retain flags were you using for the actual payload messages?

Not sure I understand why you deem that approach ineffective (it’s the actual way pub-sub works).

But I likely don’t actually understand your architecture, here.

Good try :slight_smile: But they have the retain flag:

    def send_discovery(self) -> None:
        """Send Home Assistant MQTT discovery message to create entity"""
        entity_id = f"backup_{self.profile_device_safe}"
        topic = f"homeassistant/sensor/{entity_id}/config"
        name = f"{self.profile_device_path}"

        discovery_payload: Dict[str, Any] = {
            "name": name,
            "unique_id": f"backup_restic_{self.profile_device_safe}",
            "state_topic": self.state_topic,
            "json_attributes_topic": self.state_topic,
            "json_attributes_path": "$.attributes",
            "value_template": "{{ value_json.state }}",
            "device_class": "enum",
            "options": ["success", "error", "cancelled"],
            "entity_category": "diagnostic",
            "device": {
                "name": "restic",
                "manufacturer": "restic",
                "identifiers": [self.profile_safe],
                "model": "backup job",
            },
        }
        try:
            publish.single(
                topic,
                payload=json.dumps(discovery_payload),
                qos=1,
                retain=True,
                hostname=self.broker,
                port=self.port,
            )
            logger.info(f"📡 Sent MQTT discovery for {name}")
        except Exception as e:
            logger.error(f"Failed to send MQTT discovery: {e}")
            raise e

A pub/sub architecture is optimised for high volume and high velocity events (well, usually at least but then you can have fronts such as Kafka to buffer the flow). This is done by keeping a continuous connection between the client and the broker because the subscription is the most expensive operation.

When you go for ad-hoc messages, you have a synchronous sequence of connection setup → subscription → loop → message → ack → deconnection (again, in a synchronous, expensive mode). This is absolutely fine for setups such as mine, but would not fly for a heavy load.
In some way, the ad-hoc message bypasses the asynchronous nature of MQTT by constantly creating new event loops.

You’re only talking about the discovery message, here.
That one is a one-time publish with retain flag (you could as well do it in MQTT Explorer)

As a publisher of data towards HA, you don’t have to act as a subscriber in any way. HA is the subscriber with permanent connection.

Hence my confusion about why your app would be a subscriber here…

can’t help with the puzzle, just let me clarify:

it doesn’t work like this. It’s not a queue with a message to be consumed only once. The message is published to all clients subscribed at time of publishing.

You can publish to discovery without the retain flag and it will work. The downside is, the entities won’t be recreated after HA or mqtt restart. Thus it’s not advised.

though, what the OP is reporting is quite interesting.

2 Likes

I suspect some confusion between the discovery messages and state messages, here.

I think I noticed before that, although a discovery message exists, the HA entities are not actually created until a state message is published at least once. Not 100% sure, I haven’t done any tests to confirm that…

I’m sure state data are not needed to register entities. I worked with discovery 2 days ago, experiencing immediate entities creation with undefined state until I published the data.
It doesn’t mean, that cases where HA behaves differently are not possible.

1 Like

In normal operations, you are always a subscriber. You do not have to make an active use of the subscription but it is part of the protocol .

HA is another subscriber, to the topic you post to.

This is incorrect. The entity is created at the discovery message reception, it may never receive an update of the state but is still there.

The moment you remove this entry from the broker, HA erases the entity.

This is indeed how HA works. As I mentioned elsewhere, the existence of the homeassistant/... entry is reflected in the existence of the entity.

When you remove it from the broeker, it disappears in HA.

This is also the reason why there is a persistent flag: it works without after a restart of the broker, but the entity is undefined until the next discovery message

Yes, because my problem was in the creation of the entity - driven by the discovery message

Yes, and in this case the entity was created. This discrepancy is the core of the problem.