Help with creating MQTT Sensor

Hi,

I managed to fumble my way through some documentation and get an automation trigger working from an MQTT event. How would I translate this into a sensor?

alias: Cat Test
description: ""
trigger:
  - platform: mqtt
    topic: frigate/events
    payload: new
    value_template: "{{ value_json.type }}"
condition:
  - condition: template
    value_template: "{{ trigger.payload_json['after']['label'] == 'cat' }}"

You don’t need to use event triggers or anything like that to create a sensor, just follow the documentation:

I did read that, but couldn’t figure it out

You don’t give much info on what kind of sensor you are hoping to create. So without more context, a generic answer is the best help you can get. So what are you hoping to see in Home Assistant, and based on what in MQTT? Frigate seeing the cat (I assume that is what the event is about) is indeed an event, but it is not a sensor. If you want something to turn on when a cat is seen, when do you want it to turn off? Is there an mqtt topic for that?

I’m just trying to create a very simple MQTT sensor that is triggered when Frigate detects a cat. It has to come from the label under frigate/events.

{
  "type": "update", // new, update, end
  "before": {
    "id": "1607123955.475377-mxklsc",
    "camera": "front_door",
    "frame_time": 1607123961.837752,
    "snapshot_time": 1607123961.837752,
    "label": "person",
    "sub_label": null,
    "top_score": 0.958984375,
    "false_positive": false,
    "start_time": 1607123955.475377,
    "end_time": null,
    "score": 0.7890625,
    "box": [424, 500, 536, 712],
    "area": 23744,
    "ratio": 2.113207,
    "region": [264, 450, 667, 853],
    "current_zones": ["driveway"],
    "entered_zones": ["yard", "driveway"],
    "thumbnail": null,
    "has_snapshot": false,
    "has_clip": false,
    "stationary": false, // whether or not the object is considered stationary
    "motionless_count": 0, // number of frames the object has been motionless
    "position_changes": 2, // number of times the object has moved from a stationary position
    "attributes": {
      "face": 0.64
    }, // attributes with top score that have been identified on the object at any point
    "current_attributes": [] // detailed data about the current attributes in this frame
  },
  "after": {
    "id": "1607123955.475377-mxklsc",
    "camera": "front_door",
    "frame_time": 1607123962.082975,
    "snapshot_time": 1607123961.837752,
    "label": "person",
    "sub_label": ["John Smith", 0.79],
    "top_score": 0.958984375,
    "false_positive": false,
    "start_time": 1607123955.475377,
    "end_time": null,
    "score": 0.87890625,
    "box": [432, 496, 544, 854],
    "area": 40096,
    "ratio": 1.251397,
    "region": [218, 440, 693, 915],
    "current_zones": ["yard", "driveway"],
    "entered_zones": ["yard", "driveway"],
    "thumbnail": null,
    "has_snapshot": false,
    "has_clip": false,
    "stationary": false, // whether or not the object is considered stationary
    "motionless_count": 0, // number of frames the object has been motionless
    "position_changes": 2, // number of times the object has changed position
    "attributes": {
      "face": 0.86
    }, // attributes with top score that have been identified on the object at any point
    "current_attributes": [
      // detailed data about the current attributes in this frame
      {
        "label": "face",
        "box": [442, 506, 534, 524],
        "score": 0.86
      }
    ]
  }
}

Is there an event when the cat leaves the picture? I doubt you want the sensor to remain on forever after the first cat was seen.

A sensor isn’t a trigger, I’m still going under the assumption the sensor is and on/off type sensor (binary_sensor). Because an event is what you already had in the automation. You do not need a sensor for that.

There is a before and after in the event, but if you turn a sensor on and off within a split second based on the same message, it isn’t of much use as a sensor.

I’m not saying a sensor is a trigger, I said I need a sensor that is triggered when Frigate detects a cat. It would need to turn off, but if I could get it to report the state then that would probably be easier.

For a binary sensor it would be something like this added to your configuration.yaml, according to:

mqtt:
  - binary_sensor:
      name: "Cat seen"
      state_topic: "frigate/events"
      off_delay: 10
      value_template: "{{ 'ON' if trigger.payload_json['after']['label'] == 'cat' else 'OFF' }}"

You could also choose to create an event entity, but it would not be dissimilar to what you already had.

It doesn’t seem to work. I had to remove the delay off as it was causing an error.

  - binary_sensor:
      name: Dahua MQTT Cat Occupancy
      state_topic: "frigate/events"
      value_template: "{{ 'ON' if trigger.payload_json['after']['label'] == 'cat' else 'OFF' }}"

Oops, it should be off_delay. I changed it. I do not have frigate, so I cannot test it myself.

I checked via MQTT Explorer and “label” is changing to cat, but the sensor is just stuck on unknown.

image

{
  "before": {
    "id": "1722783536.011894-hg7yy6",
    "camera": "dahua",
    "frame_time": 1722783536.322468,
    "snapshot": {
      "frame_time": 1722783536.237604,
      "box": [
        511,
        323,
        594,
        416
      ],
      "area": 7719,
      "region": [
        512,
        0,
        1280,
        768
      ],
      "score": 0.8125,
      "attributes": []
    },
    "label": "cat",
    "sub_label": null,
    "top_score": 0.806640625,
    "false_positive": false,
    "start_time": 1722783536.011894,
    "end_time": null,
    "score": 0.734375,
    "box": [
      511,
      321,
      594,
      414
    ],
    "area": 7719,
    "ratio": 0.8924731182795699,
    "region": [
      512,
      0,
      1280,
      768
    ],
    "stationary": false,
    "motionless_count": 2,
    "position_changes": 0,
    "current_zones": [
      "overall_detection_dahua"
    ],
    "entered_zones": [
      "overall_detection_dahua"
    ],
    "has_clip": false,
    "has_snapshot": false,
    "attributes": {},
    "current_attributes": []
  },
  "after": {
    "id": "1722783536.011894-hg7yy6",
    "camera": "dahua",
    "frame_time": 1722783536.322468,
    "snapshot": {
      "frame_time": 1722783536.237604,
      "box": [
        511,
        323,
        594,
        416
      ],
      "area": 7719,
      "region": [
        512,
        0,
        1280,
        768
      ],
      "score": 0.8125,
      "attributes": []
    },
    "label": "cat",
    "sub_label": null,
    "top_score": 0.806640625,
    "false_positive": false,
    "start_time": 1722783536.011894,
    "end_time": 1722783537.476176,
    "score": 0.734375,
    "box": [
      511,
      321,
      594,
      414
    ],
    "area": 7719,
    "ratio": 0.8924731182795699,
    "region": [
      512,
      0,
      1280,
      768
    ],
    "stationary": false,
    "motionless_count": 2,
    "position_changes": 0,
    "current_zones": [
      "overall_detection_dahua"
    ],
    "entered_zones": [
      "overall_detection_dahua"
    ],
    "has_clip": false,
    "has_snapshot": false,
    "attributes": {},
    "current_attributes": []
  },
  "type": "end"
}

Ah, ok, sorry. I copied your template, but forgot to replace the trigger.payload_json with value_json. Getting tired, should not code when tired :slight_smile:

      value_template: "{{ 'ON' if value_json['after']['label'] == 'cat' else 'OFF' }}"

Maybe it should also specify (although it was documented as the default)

      payload_on: "ON"
3 Likes

It’s working now. Thank you!

  - binary_sensor:
      name: Dahua MQTT Cat Occupancy
      off_delay: 10
      state_topic: "frigate/events"
      value_template: "{{ 'ON' if value_json['after']['label'] == 'cat' else 'OFF' }}"
1 Like

So after further testing I need to add another parameter to get the desired result.

How would I add and into the template?