Github Boards Devices Community Docs Blog

Creating devices in Home Assistant

Currently, I have 4 xiaomi mijia lywsd03mmc integrated using an esp32 running the development brach of openmqttgateway.

For each device, 5 sensors are created, but they are not tied together, they don’t create a device to tie them together and assign them to an area.

homeassistant/sensor/A4C138C9BC21-LYWSD03MMC-tempc/config

{
   "stat_t":"home/OpenMQTTGateway_ESP32_BLE/BTtoMQTT/A4C138C9BC21",
   "name":"LYWSD03MMC-tempc",
   "uniq_id":"A4C138C9BC21-LYWSD03MMC-tempc",
   "dev_cla":"temperature",
   "val_tpl":"{{ value_json.tempc | is_defined }}",
   "unit_of_meas":"C"
}

homeassistant/sensor/A4C138C9BC21-LYWSD03MMC-tempf/config

{
  "stat_t": "home/OpenMQTTGateway_ESP32_BLE/BTtoMQTT/A4C138C9BC21",
  "name": "LYWSD03MMC-tempf",
  "uniq_id": "A4C138C9BC21-LYWSD03MMC-tempf",
  "dev_cla": "temperature",
  "val_tpl": "{{ value_json.tempf | is_defined }}",
  "unit_of_meas": "F"
}

homeassistant/sensor/A4C138C9BC21-LYWSD03MMC-hum/config

{
  "stat_t": "home/OpenMQTTGateway_ESP32_BLE/BTtoMQTT/A4C138C9BC21",
  "name": "LYWSD03MMC-hum",
  "uniq_id": "A4C138C9BC21-LYWSD03MMC-hum",
  "dev_cla": "humidity",
  "val_tpl": "{{ value_json.hum | is_defined }}",
  "unit_of_meas": "%"
}

homeassistant/sensor/A4C138C9BC21-LYWSD03MMC-batt/config

{
  "stat_t": "home/OpenMQTTGateway_ESP32_BLE/BTtoMQTT/A4C138C9BC21",
  "name": "LYWSD03MMC-batt",
  "uniq_id": "A4C138C9BC21-LYWSD03MMC-batt",
  "dev_cla": "battery",
  "val_tpl": "{{ value_json.batt | is_defined }}",
  "unit_of_meas": "%"
}

homeassistant/sensor/A4C138C9BC21-LYWSD03MMC-volt

{
  "stat_t": "home/OpenMQTTGateway_ESP32_BLE/BTtoMQTT/A4C138C9BC21",
  "name": "LYWSD03MMC-volt",
  "uniq_id": "A4C138C9BC21-LYWSD03MMC-volt",
  "val_tpl": "{{ value_json.volt | is_defined }}",
  "unit_of_meas": "V"
}

I tried to change, in ZmqttDiscovery.ino

#  ifdef ZgatewayBT
void createDiscoveryFromList(char* mac, char* sensorList[][8], int sensorCount) {
  for (int i = 0; i < sensorCount; i++) {
    Log.trace(F("CreateDiscoverySensor %s" CR), sensorList[i][1]);
    String discovery_topic = String(subjectBTtoMQTT) + "/" + String(mac);
    String unique_id = String(mac) + "-" + sensorList[i][1];
    createDiscovery(sensorList[i][0],
                    (char*)discovery_topic.c_str(), sensorList[i][1], (char*)unique_id.c_str(),
                    will_Topic, sensorList[i][3], sensorList[i][4],
                    sensorList[i][5], sensorList[i][6], sensorList[i][7],
                    0, "", "", false, "");
  }
}
#  endif

to

#  ifdef ZgatewayBT
void createDiscoveryFromList(char* mac, char* sensorList[][8], int sensorCount) {
  for (int i = 0; i < sensorCount; i++) {
    Log.trace(F("CreateDiscoverySensor %s" CR), sensorList[i][1]);
    String discovery_topic = String(subjectBTtoMQTT) + "/" + String(mac);
    String unique_id = String(mac) + "-" + sensorList[i][1];
    createDiscovery(sensorList[i][0],
                    (char*)discovery_topic.c_str(), sensorList[i][1], (char*)unique_id.c_str(),
                    will_Topic, sensorList[i][3], sensorList[i][4],
                    sensorList[i][5], sensorList[i][6], sensorList[i][7],
                    0, "", "", true, "");
  }
}
#  endif

But this has not the desired effect, I end up with something like

homeassistant/sensor/A4C138C9BC21-LYWSD03MMC-tempc/config

{
   "stat_t":"home/OpenMQTTGateway_ESP32_BLE/BTtoMQTT/A4C138C9BC21",
   "name":"LYWSD03MMC-tempc",
   "uniq_id":"A4C138C9BC21-LYWSD03MMC-tempc",
   "dev_cla":"temperature",
   "val_tpl":"{{ value_json.tempc | is_defined }}",
   "unit_of_meas":"C"
   "device": {
    "name": "OpenMQTTGateway_ESP32_BLE",
    "manufacturer": "OMG_community",
    "sw_version": "version_tag",
    "identifiers": [
      "4C11AE74F584"
    ]
  }
}

What I want to achieve, is to end up with something like this :
homeassistant/sensor/A4C138C9BC21-LYWSD03MMC-tempc/config

{
   "stat_t":"home/OpenMQTTGateway_ESP32_BLE/BTtoMQTT/A4C138C9BC21",
   "name":"LYWSD03MMC-tempc",
   "uniq_id":"A4C138C9BC21-LYWSD03MMC-tempc",
   "dev_cla":"temperature",
   "val_tpl":"{{ value_json.tempc | is_defined }}",
   "unit_of_meas":"C"
   "device": {
    "name": "LYWSD03MMC",
    "manufacturer": "OMG_community",
    "identifiers": [
      "A4C138C9BC21"
    ]
  }
}

and same device block for all 5 sensors for the same LYWSD03MMC

So I end up with something like this in HA

Got it. My changed function :

void createDiscovery(char* sensor_type,
                     char* st_topic, char* s_name, char* unique_id,
                     char* availability_topic, char* device_class, char* value_template,
                     char* payload_on, char* payload_off, char* unit_of_meas,
                     int off_delay,
                     char* payload_available, char* payload_not_avalaible, bool child_device, char* cmd_topic) {
  const int JSON_MSG_CALC_BUFFER = JSON_OBJECT_SIZE(14) + JSON_OBJECT_SIZE(5) + JSON_ARRAY_SIZE(1);
  StaticJsonBuffer<JSON_MSG_CALC_BUFFER> jsonBuffer;
  JsonObject& sensor = jsonBuffer.createObject();

  char state_topic[mqtt_topic_max_size];
  strcpy(state_topic, mqtt_topic);
  strcat(state_topic, st_topic);
  sensor.set("stat_t", state_topic); //state_topic

  sensor.set("name", s_name); //name
  sensor.set("uniq_id", unique_id); //unique_id
  if (device_class[0])
    sensor.set("dev_cla", device_class); //device_class
  if (value_template[0])
    sensor.set("val_tpl", value_template); //value_template
  if (payload_on[0])
    sensor.set("pl_on", payload_on); // payload_on
  if (payload_off[0])
    sensor.set("pl_off", payload_off); //payload_off
  if (unit_of_meas[0])
    sensor.set("unit_of_meas", unit_of_meas); //unit_of_measurement*/
  if (off_delay != 0)
    sensor.set("off_delay", off_delay); //off_delay
  if (payload_available[0])
    sensor.set("pl_avail", payload_available); // payload_on
  if (payload_not_avalaible[0])
    sensor.set("pl_not_avail", payload_not_avalaible); //payload_off

  if (cmd_topic[0]) {
    char command_topic[mqtt_topic_max_size];
    strcpy(command_topic, mqtt_topic);
    strcat(command_topic, cmd_topic);
    sensor.set("cmd_t", command_topic); //command_topic
  }

  if (child_device) {
    StaticJsonBuffer<JSON_MSG_BUFFER> jsonDeviceBuffer;
    JsonObject& device = jsonDeviceBuffer.createObject();
    device.set("name", gateway_name);
    device.set("manufacturer", DEVICEMANUFACTURER);
    device.set("sw_version", OMG_VERSION);
    JsonArray& identifiers = device.createNestedArray("identifiers");
    identifiers.add(getMacAddress());
    sensor.set("device", device); //device sensor is connected to
  }
  else {
    char deviceid[13];
    char devicename[40];
    int index = 0;
    memcpy(deviceid, &unique_id[0], 12 );    
    deviceid[12]= '\0';
    index = strcspn (s_name,"-");
    memcpy(devicename, &s_name[0], index );    
    devicename[index]= '\0';
    StaticJsonBuffer<JSON_MSG_BUFFER> jsonDeviceBuffer;
    JsonObject& device = jsonDeviceBuffer.createObject();
    device.set("name", devicename);
    device.set("model", devicename);
    device.set("manufacturer", DEVICEMANUFACTURER);
    JsonArray& identifiers = device.createNestedArray("identifiers");
    identifiers.add(deviceid);
    sensor.set("device", device); //device sensor is connected to
  }


  String topic = String(discovery_Topic) + "/" + String(sensor_type) + "/" + String(unique_id) + "/config";
  pub_custom_topic((char*)topic.c_str(), sensor, true);
}

1 Like

Very good! I have 10 sensors and I want apply it on my Hass; have you solved all the problem or have you any other issues?

it is only tested with my 4 LYWSD03MMC’s, but it should work with all BLE sensors.

I have a question, do these lywsd03mmc sensors work for you on the factory sensor software or on the changed software?
At the moment I have 4 lywsd03mmc sensors and I want to have them added to the Home Assistant via the Open Mqtt gate, but also have them in the Xiaomi Home application via the ZNDMWG02LM gate. Can you do that? Can I have a brief description?
Thank you

I don’t think it is possible to have them both on openmqttgateway and the ZNDMWG02LM gate at the same time.

This is what I was afraid of.
Thank you for your answer.

OpenMQTTGateway is great software. Works great. I love the way it works. Great applause!

It’s even better after your modification. Now I have consistency with how devices (sensors) are presented in HA. It is identical to the devices that I have connected via ZHA. And I can finally assign a room to them easily.

My suggestion is to implement this in the official tree. Even as a switchable option: Discovery sensors as devices.

1 Like

This is exactly what I’ve been looking for. I have roughly 10 Xiaomi Cleargrass temperature displays and several MiFlora’s publishing information through several OpenMQTTGateways, but I haven’t been able to add the sensors under each respective device (there is no device, only sensors). Could you please help me on this? Where do I have to add the code @francisp wrote? A step-by-step guide would be greatly appreciated!

If you take the last development branch, this functionnality has been integrated.

Super! You are doing a great job!

So I should flash the the precompiled v0.9.5? Do I have to enable this feature somehow after flashing?

Now that I have you on the line, I’m also looking to disable all beacons that only publish such info:

539DE3916193 = {“id”:“xx:xx:xx:xx:xx:xx”,“rssi”:-72,“distance”:4.287841}

I believe this is also possible in 0.9.5? How do I get rid of the beacon spam?

Thanks again for all your help!

I’ve never compiled the bins myself, always used the precompiled ones :slight_smile:

You have to wait for v0.9.6 or compile the development branch.

You can do it by following these instructions :

1 Like

I’ve compiled development version and this works really nice. Great work! I’m struggling a bit with too slow updates to the readings but that is configurable I think. The one thing I am missing is remaining battery life on the Mi Flower Care. In the app it’s a bit hidden at hardware settings but it is being send. Is it possible to get that working to?

Would be nice if it could be shown on the devices page as well as on the card itself.

This requires a connection to the miflora, I’m thinking on adding it as other connection oriented data retrieval.

That would be great!