DDF for SONOFF SNZB-02 multi sensor

DDF for this device. I didn’t test it too extensively, but seems to work after one day.

I would create a PR after the community had a look.


{
  "schema": "devcap1.schema.json",
  "manufacturername": "eWeLink",
  "modelid": "TH01",
  "vendor": "SONOFF",
  "product": "SNZB-02",
  "sleeper": false,
  "status": "Gold",
  "path": "/devices/Sonoff-snzb-02.json",
  "subdevices": [
    {
      "type": "$TYPE_TEMPERATURE_SENSOR",
      "restapi": "/sensors",
      "uuid": [
        "$address.ext",
        "0x01",
        "0x0402"
      ],
      "fingerprint": {
        "profile": "0x0104",
        "device": "0x0302",
        "endpoint": "0x01",
        "in": [
          "0x0000",
          "0x0001",
          "0x0402"
        ]
      },
      "items": [
        {
          "name": "attr/id"
        },
        {
          "name": "attr/lastannounced"
        },
        {
          "name": "attr/lastseen"
        },
        {
          "name": "attr/manufacturername"
        },
        {
          "name": "attr/modelid"
        },
        {
          "name": "attr/name"
        },
        {
          "name": "attr/swversion"
        },
        {
          "name": "attr/type"
        },
        {
          "name": "attr/uniqueid"
        },
        {
          "name": "config/battery",
          "read": {
            "at": "0x0021",
            "cl": "0x0001",
            "ep": 1,
            "fn": "zcl"
          },
          "parse": {
            "at": "0x0021",
            "cl": "0x0001",
            "cppsrc": "power_configuration.cpp:198",
            "ep": 1,
            "eval": "Item.val = Attr.val / 2"
          },
          "default": 0
        },
        {
          "name": "config/offset",
          "description": "Relative offset to the main measured value.",
          "default": 0
        },
        {
          "name": "config/on"
        },
        {
          "name": "config/reachable"
        },
        {
          "name": "state/lastupdated"
        },
        {
          "name": "state/temperature",
          "default": 0
        }
      ]
    },
    {
      "type": "$TYPE_HUMIDITY_SENSOR",
      "restapi": "/sensors",
      "uuid": [
        "$address.ext",
        "0x01",
        "0x0405"
      ],
      "fingerprint": {
        "profile": "0x0104",
        "device": "0x0302",
        "endpoint": "0x01",
        "in": [
          "0x0000",
          "0x0001",
          "0x0405"
        ]
      },
      "items": [
        {
          "name": "attr/id"
        },
        {
          "name": "attr/lastannounced"
        },
        {
          "name": "attr/lastseen"
        },
        {
          "name": "attr/manufacturername"
        },
        {
          "name": "attr/modelid"
        },
        {
          "name": "attr/name"
        },
        {
          "name": "attr/swversion"
        },
        {
          "name": "attr/type"
        },
        {
          "name": "attr/uniqueid"
        },
        {
          "name": "config/battery",
          "read": {
            "at": "0x0021",
            "cl": "0x0001",
            "ep": 1,
            "fn": "zcl"
          },
          "parse": {
            "at": "0x0021",
            "cl": "0x0001",
            "cppsrc": "power_configuration.cpp:198",
            "ep": 1,
            "eval": "Item.val = Attr.val / 2"
          },
          "default": 0
        },
        {
          "name": "config/offset",
          "description": "Relative offset to the main measured value.",
          "default": 0
        },
        {
          "name": "config/on"
        },
        {
          "name": "config/reachable"
        },
        {
          "name": "state/humidity",
          "default": 0
        },
        {
          "name": "state/lastupdated"
        }
      ]
    }
  ],
  "bindings": [
    {
      "bind": "unicast",
      "src.ep": 1,
      "dst.ep": 1,
      "cl": "0x0001",
      "report": [
        {
          "at": "0x0021",
          "dt": "0x20",
          "min": 60,
          "max": 3600,
          "change": "0x00000001"
        }
      ]
    },
    {
      "bind": "unicast",
      "src.ep": 1,
      "dst.ep": 1,
      "cl": "0x0405",
      "report": [
        {
          "at": "0x0000",
          "dt": "0x21",
          "min": 60,
          "max": 300,
          "change": "0x0000000A"
        }
      ]
    },
    {
      "bind": "unicast",
      "src.ep": 1,
      "cl": "0x0402",
      "report": [
        {
          "at": "0x0000",
          "dt": "0x29",
          "min": 60,
          "max": 300,
          "change": "0x00000005"
        }
      ]
    }
  ]
}

2 Likes

Regarding another issue (How to adjust Sonoff snzb-02 humidity sensitivity / frequency? - #5 by woodhead) I think that

     "cl": "0x0402",
      "report": [
        {
          "at": "0x0000",
          "dt": "0x29",
          "min": 60,
          "max": 300,
          "change": "0x00000005"

are perhaps not the best values (if they are considered by this sensor).

1 Like

“cl”: “0x0402” is the temperature. Your value are good, but on my side I m using

    {
      "bind": "unicast",
      "src.ep": 1,
      "cl": "0x0402",
      "report": [
        {
          "at": "0x0000",
          "dt": "0x29",
          "min": 60,
          "max": 300,
          "change": "0x00000032"
        }
      ]
    },

To have a report every 0.2°C

About your DDf I think you can remove "cppsrc": "power_configuration.cpp:198",, all "description" and "path"

Thanks both. I did some updates on the reportable changes and set sleeper value to true. Indeed, the output graph of this device is quite shaky, let’s see what happens with the new settings.


{
  "schema": "devcap1.schema.json",
  "manufacturername": "eWeLink",
  "modelid": "TH01",
  "vendor": "SONOFF",
  "product": "SNZB-02",
  "sleeper": true,
  "status": "Gold",
  "subdevices": [
    {
      "type": "$TYPE_TEMPERATURE_SENSOR",
      "restapi": "/sensors",
      "uuid": [
        "$address.ext",
        "0x01",
        "0x0402"
      ],
      "fingerprint": {
        "profile": "0x0104",
        "device": "0x0302",
        "endpoint": "0x01",
        "in": [
          "0x0000",
          "0x0001",
          "0x0402"
        ]
      },
      "items": [
        {
          "name": "attr/id"
        },
        {
          "name": "attr/lastannounced"
        },
        {
          "name": "attr/lastseen"
        },
        {
          "name": "attr/manufacturername"
        },
        {
          "name": "attr/modelid"
        },
        {
          "name": "attr/name"
        },
        {
          "name": "attr/swversion"
        },
        {
          "name": "attr/type"
        },
        {
          "name": "attr/uniqueid"
        },
        {
          "name": "config/battery",
          "awake": true,
          "read": {
            "at": "0x0021",
            "cl": "0x0001",
            "ep": 1,
            "fn": "zcl"
          },
          "parse": {
            "at": "0x0021",
            "cl": "0x0001",
            "ep": 1,
            "eval": "Item.val = Attr.val / 2"
          },
          "default": 0
        },
        {
          "name": "config/offset",
          "default": 0
        },
        {
          "name": "config/on"
        },
        {
          "name": "config/reachable"
        },
        {
          "name": "state/lastupdated"
        },
        {
          "name": "state/temperature",
          "awake": true,
          "default": 0
        }
      ]
    },
    {
      "type": "$TYPE_HUMIDITY_SENSOR",
      "restapi": "/sensors",
      "uuid": [
        "$address.ext",
        "0x01",
        "0x0405"
      ],
      "fingerprint": {
        "profile": "0x0104",
        "device": "0x0302",
        "endpoint": "0x01",
        "in": [
          "0x0000",
          "0x0001",
          "0x0405"
        ]
      },
      "items": [
        {
          "name": "attr/id"
        },
        {
          "name": "attr/lastannounced"
        },
        {
          "name": "attr/lastseen"
        },
        {
          "name": "attr/manufacturername"
        },
        {
          "name": "attr/modelid"
        },
        {
          "name": "attr/name"
        },
        {
          "name": "attr/swversion"
        },
        {
          "name": "attr/type"
        },
        {
          "name": "attr/uniqueid"
        },
        {
          "name": "config/battery",
          "awake": true,
          "read": {
            "at": "0x0021",
            "cl": "0x0001",
            "ep": 1,
            "fn": "zcl"
          },
          "parse": {
            "at": "0x0021",
            "cl": "0x0001",
            "ep": 1,
            "eval": "Item.val = Attr.val / 2"
          },
          "default": 0
        },
        {
          "name": "config/offset",
          "default": 0
        },
        {
          "name": "config/on"
        },
        {
          "name": "config/reachable"
        },
        {
          "name": "state/humidity",
          "awake": true,
          "default": 0
        },
        {
          "name": "state/lastupdated"
        }
      ]
    }
  ],
  "bindings": [
    {
      "bind": "unicast",
      "src.ep": 1,
      "dst.ep": 1,
      "cl": "0x0001",
      "report": [
        {
          "at": "0x0021",
          "dt": "0x20",
          "min": 60,
          "max": 3600,
          "change": "0x00000001"
        }
      ]
    },
    {
      "bind": "unicast",
      "src.ep": 1,
      "dst.ep": 1,
      "cl": "0x0405",
      "report": [
        {
          "at": "0x0000",
          "dt": "0x21",
          "min": 60,
          "max": 300,
          "change": "0x00000100"
        }
      ]
    },
    {
      "bind": "unicast",
      "src.ep": 1,
      "cl": "0x0402",
      "report": [
        {
          "at": "0x0000",
          "dt": "0x29",
          "min": 60,
          "max": 300,
          "change": "0x00000032"
        }
      ]
    }
  ]
}

The graph still looks the same even after deCONZ restart/re-pair of the sensor. I think this was also found to be the case in this thread reported above by @BabalsYou. Does the device simply ignore the settings for reporting tolerance?

image

If I m right setting used by Z2M are

        {
          "at": "0x0000",
          "dt": "0x21",
          "min": 60,
          "max": 300,
          "change": "0x00000064"
        }

So a change every 1°C, ATM you have “change”: “0x00000032” so every 0.5°C (and still have one every 0.1°C)

Based on the propsed DDF by @Finne75, here is the one I currently use

{
  "schema": "devcap1.schema.json",
  "manufacturername": "eWeLink",
  "modelid": "TH01",
  "vendor": "SONOFF",
  "product": "SNZB-02",
  "sleeper": true,
  "status": "Silver",
  "path": "/devices/snzb-02.json",
  "subdevices": [
    {
      "type": "$TYPE_TEMPERATURE_SENSOR",
      "restapi": "/sensors",
      "uuid": [
        "$address.ext",
        "0x01",
        "0x0402"
      ],
      "fingerprint": {
        "profile": "0x0104",
        "device": "0x0302",
        "endpoint": "0x01",
        "in": [
          "0x0000",
          "0x0001",
          "0x0402"
        ]
      },
      "items": [
        {
          "name": "attr/id"
        },
        {
          "name": "attr/lastannounced"
        },
        {
          "name": "attr/lastseen"
        },
        {
          "name": "attr/manufacturername"
        },
        {
          "name": "attr/modelid"
        },
        {
          "name": "attr/name"
        },
        {
          "name": "attr/swversion"
        },
        {
          "name": "attr/type"
        },
        {
          "name": "attr/uniqueid"
        },
        {
          "name": "config/battery",
          "awake": true,
          "read": {
            "at": "0x0021",
            "cl": "0x0001",
            "ep": 1,
            "fn": "zcl"
          },
          "parse": {
            "at": "0x0021",
            "cl": "0x0001",
            "ep": 1,
            "eval": "Item.val = Attr.val / 2"
          },
          "default": 0
        },
        {
          "name": "config/offset",
          "default": 0
        },
        {
          "name": "config/on"
        },
        {
          "name": "config/reachable"
        },
        {
          "name": "state/lastupdated"
        },
        {
          "name": "state/temperature",
          "awake": true,
          "parse": {
            "at": "0x0000",
            "cl": "0x0402",
            "ep": 1,
            "eval": "Item.val = Attr.val + R.item('config/offset').val",
            "fn": "zcl"
          },
          "default": 0
        }
      ]
    },
    {
      "type": "$TYPE_HUMIDITY_SENSOR",
      "restapi": "/sensors",
      "uuid": [
        "$address.ext",
        "0x01",
        "0x0405"
      ],
      "fingerprint": {
        "profile": "0x0104",
        "device": "0x0302",
        "endpoint": "0x01",
        "in": [
          "0x0000",
          "0x0001",
          "0x0405"
        ]
      },
      "items": [
        {
          "name": "attr/id"
        },
        {
          "name": "attr/lastannounced"
        },
        {
          "name": "attr/lastseen"
        },
        {
          "name": "attr/manufacturername"
        },
        {
          "name": "attr/modelid"
        },
        {
          "name": "attr/name"
        },
        {
          "name": "attr/swversion"
        },
        {
          "name": "attr/type"
        },
        {
          "name": "attr/uniqueid"
        },
        {
          "name": "config/battery",
          "awake": true,
          "read": {
            "at": "0x0021",
            "cl": "0x0001",
            "ep": 1,
            "fn": "zcl"
          },
          "parse": {
            "at": "0x0021",
            "cl": "0x0001",
            "ep": 1,
            "eval": "Item.val = Attr.val / 2"
          },
          "default": 0
        },
        {
          "name": "config/offset",
          "default": 0
        },
        {
          "name": "config/on"
        },
        {
          "name": "config/reachable"
        },
        {
          "name": "state/humidity",
          "awake": true,
          "parse": {
            "at": "0x0000",
            "cl": "0x0405",
            "ep": 1,
            "eval": "Item.val = Attr.val + R.item('config/offset').val",
            "fn": "zcl"
          },
          "default": 0
        },
        {
          "name": "state/lastupdated"
        }
      ]
    }
  ],
  "bindings": [
    {
      "bind": "unicast",
      "src.ep": 1,
      "dst.ep": 1,
      "cl": "0x0001",
      "report": [
        {
          "at": "0x0021",
          "dt": "0x20",
          "min": 60,
          "max": 3600,
          "change": "0x00000001"
        }
      ]
    },
    {
      "bind": "unicast",
      "src.ep": 1,
      "cl": "0x0405",
      "report": [
        {
          "at": "0x0000",
          "dt": "0x21",
          "min": 60,
          "max": 300,
          "change": "0x000001F4"
        }
      ]
    },
    {
      "bind": "unicast",
      "src.ep": 1,
      "cl": "0x0402",
      "report": [
        {
          "at": "0x0000",
          "dt": "0x29",
          "min": 60,
          "max": 300,
          "change": "0x00000064"
        }
      ]
    }
  ]
}

I arrive to the same conclusion as others … it seems that SNZB-02 doesn’t care at all at the values we can put in the “change” items. It continues to report at 0,1C temperature variation.

And “min” and “max” are used or ignored too ?

Not esay to say as temperature and humidity sensors seems to have a 2 digits after commas they report quickly at any 0.01 change ;-/

But if I m right if you set min = 60 s, event your trigger the “change” value, you can have only 1 report every 60s.

Not sure about it, here is log for my 3 SNZB-02 between 12h28 and 12h32 a few minutes after restarting deConz-GUI, with of course same DDF :wink:

12:28:04:839 00:12:4b:00:24:fc:2c:65-01-0402/config/battery expression: Item.val = Attr.val / 2 --> 100
12:28:04:840 00:12:4b:00:24:fc:2c:65-01-0405/config/battery expression: Item.val = Attr.val / 2 --> 100
12:28:05:832 00:12:4b:00:24:fc:2c:65-01-0402/config/battery expression: Item.val = Attr.val / 2 --> 100
12:28:05:833 00:12:4b:00:24:fc:2c:65-01-0405/config/battery expression: Item.val = Attr.val / 2 --> 100
12:28:06:891 00:12:4b:00:24:fc:2c:65-01-0402/config/battery expression: Item.val = Attr.val / 2 --> 100
12:28:06:892 00:12:4b:00:24:fc:2c:65-01-0405/config/battery expression: Item.val = Attr.val / 2 --> 100
12:28:11:239 00:12:4b:00:24:fc:2c:65-01-0405/state/humidity expression: Item.val = Attr.val + R.item('config/offset').val --> 4892
12:28:12:295 00:12:4b:00:24:fc:2c:65-01-0402/config/battery expression: Item.val = Attr.val / 2 --> 100
12:28:12:297 00:12:4b:00:24:fc:2c:65-01-0405/config/battery expression: Item.val = Attr.val / 2 --> 100
12:28:13:349 00:12:4b:00:24:fc:2c:65-01-0402/config/battery expression: Item.val = Attr.val / 2 --> 100
12:28:13:350 00:12:4b:00:24:fc:2c:65-01-0405/config/battery expression: Item.val = Attr.val / 2 --> 100
12:29:16:288 00:12:4b:00:24:fc:2c:65-01-0402/state/temperature expression: Item.val = Attr.val + R.item('config/offset').val --> 2278
12:29:17:329 00:12:4b:00:24:fc:2c:65-01-0402/config/battery expression: Item.val = Attr.val / 2 --> 100
12:29:17:332 00:12:4b:00:24:fc:2c:65-01-0405/config/battery expression: Item.val = Attr.val / 2 --> 100
12:29:18:384 00:12:4b:00:24:fc:2c:65-01-0402/config/battery expression: Item.val = Attr.val / 2 --> 100
12:29:18:386 00:12:4b:00:24:fc:2c:65-01-0405/config/battery expression: Item.val = Attr.val / 2 --> 100

and nothing more for 2 others minutes, then second one

12:28:25:300 00:12:4b:00:25:10:54:27-01-0402/state/temperature expression: Item.val = Attr.val + R.item('config/offset').val --> 2080
12:28:58:673 00:12:4b:00:25:10:54:27-01-0405/state/humidity expression: Item.val = Attr.val + R.item('config/offset').val --> 5695

and last one

12:31:23:027 00:12:4b:00:24:fc:57:a1-01-0402/state/temperature expression: Item.val = Attr.val + R.item('config/offset').val --> 2047

12:29:16:288 00:12:4b:00:24:fc:2c:65-01-0402/state/temperature
12:28:25:300 00:12:4b:00:25:10:54:27-01-0402/state/temperature
12:31:23:027 00:12:4b:00:24:fc:57:a1-01-0402/state/temperature

So one every 60s and more.
If you set the min to 300 and the max to 3600 ?
(remember you need deconz reconfigue the device, and the device is a lazy one, so can take time)

Indeed, the issue is probably the too low value for “max”. In my logs, the reports come in every 300s but due to the scale of the graph I look on (2 days or so) it looks quite “shaky” compared to other sensors (Aqara, Tuya) which seem to follow the delta settings. So, I guess for temperature/humidity kind of sensors, the maximum reporting rate should be 1800s or 3600s or even longer as you said, Smanar. I will test this now.

Looks much better now, I used min 300 and max 1800. I will create the PR.
image

1 Like

I updated the PR (this one) to include the values BabaIsYou suggested.

In general, it would be good to document some guidance for DDF developers on how to set these values for this kind of devices, so that we have a more or less homogeneous behaviour for sensor of different vendors. @Smanar, what do you think?

1 Like

Sure, and It’s what I m doing no ? ^^

But yes, you can found information, but need to travel on forum.
for the moment the better link on DDF is DDF cheat sheet · dresden-elektronik/deconz-rest-plugin Wiki · GitHub

And the better method is using existing one.

Yes, and your guidance is very much appreciated :slight_smile: What I mean is, should we add a page or a section to this wiki and start collecting some best practices for parameter setting in DDFs?

The wiki is “open space”, you can add/edit what you want.

But to find the parameter, my personnal method is
1 - Use standard one (based on existing device)
2 - check other forum on other zigbee project
3 - try and retry ^^

I haven’t a “best procedure” to use on my side :slight_smile: