It's time to fix Aqara battery bug

Following up on this: I see similar behavior for Aqara illuminance sensors (lumi.sen_ill.mgl01): they went down to 0 % regularly - especially those which run for a longer time now (almost 3 years!).

Can we eliminate those 0 % reportings for that hardware too (like we did in Ignore invalid Aqara -100 temperature by amelchio · Pull Request #6723 · dresden-elektronik/deconz-rest-plugin · GitHub)?

Sure, do you know the “bad value” ?
The problem is this DDf use a JS script, so a change in this file will impact all device that use it, so better to create a new one for this device

Use Instead

if (measuredValue > 0 && measuredValue < 0xffff) {

Thinking about this a second time resulted in: maybe I misunderstood something.

  1. Aqara multi sensor (temperature, pressure etc.): had -100 ° values for temperature sensor. Sorted out by filtering those on a DDF level.
  2. Aqara illuminance sensor: it’s not the actual illuminance sensor (like it was the temperature sensor of the other Aqara device at #1), but the battery sensor falling to 0 % regularly for no obvious reason (as shown in It's time to fix Aqara battery bug - #41 by bcutter).

So if I/one would filter `battery: 0 % to be ignored", would that actually be a solution? Because, well… the battery at some day could really be empty, so reported as 0 % (never seen that, as all Aqara devices die way before, usually at 70 to at best 60 %).

Ha ? so you have the problem on the battery too ? Not the luminance ?
So it’s exactly the same code.

Did you read my last post? If I suppress 0 %, what happens if the battery actually is at 0 %? :slight_smile:

You will have the previous value, the one before the 0 value. And like you I never see a 0 value for battery, the device die before.

1 Like

OK, that sound’s good. Now I need a working custom DDF to test this. I’m (still) not really into DDF-ing.

a) Can you give me a kick-start?
b) Do you think this might be helpful for others too (or an individual/custom corner case) so it should make its way into deCONZ?

In the end it’s another workaround for the unreliable Aqara sensor firmware. -100° here, 0 % battery life there…

a) What is your OS ? (You have probably already say it, but I don’t remember all the post).
You can edit fastly the original DDF, or create a new one with the change in the user folder (I will give you the DDF)

b) IDK, on my side I don’t have the issue, and it’s not a common issue for me (I can be wrong), but you can sumbit a PR, we will see other devs decision.

I don’t think it would be allowed. Generally, you dont want to change values other than up/downscaling.

Well, you remember we filtered out the -100 degrees values (see earlier posts in this topic)? :slight_smile:

Using HA OS. I know from earlier custom DDFs how and where to store them so they are persistent (not overwritten on addon/deCONZ container update).

It’s only I have no idea what the content of the DDF should be to suppress/ignore the 0 % value only for the battery values for the „lumi.sen_ill.mgl01“ device.

Yes, but that’s different opposed to the battery percentage. Mine seem to work okay.

Ah OK. Why is it different? Because you’ve seen this (-100 °) with your sensors too? So following that logic now there are two options for the battery values:

  • my Aqara illuminance sensors are the only one in the world behaving like that
  • yours are the only one working perfectly meaning never sending 0 % for some time before switching back

Both cases are very likely not true and therefore not a no-go for a PR to deliver the fix to others. But TBH, once I have a custom DDF with the great help of @Smanar, I will test it for a while. If it works for me, fine. If others don’t need it, fine too :slight_smile:

1 Like

I never had the -100 degree one. Also, as its out its range (-20 as minimal temp, Aqara Temperature and Humidity Sensor T1 - Aqara UK Shop) it can be ignored.

I think i’ve seen the battery on lower than 70%.

IDK, he is right, on my side I never had 0 value for battery, so using a filter for them is an idea to test.

It’s only I have no idea what the content of the DDF should be to suppress/ignore the 0 % value only for the battery values for the „lumi.sen_ill.mgl01“ device

Can try this DDF, based on https://github.com/dresden-elektronik/deconz-rest-plugin/blob/master/devices/xiaomi/xiaomi_gzcgq01lm_light_sensor.json

{
  "schema": "devcap1.schema.json",
  "doc:path": "xiaomi/xiaomi_gzcgq01lm_light_sensor.md",
  "doc:hdr": "Light sensor GZCGQ01LM",
  "manufacturername": ["$MF_XIAOMI", "$MF_LUMI"],
  "modelid": ["lumi.sen_ill.mgl01", "lumi.sen_ill.mgl01"],
  "vendor": "Xiaomi",
  "product": "Mijia Light Sensor GZCGQ01LM",
  "status": "Gold",
  "md:known_issues": [ ],
  "sleeper": true,
  "subdevices": [
    {
      "type": "$TYPE_LIGHT_LEVEL_SENSOR",
      "restapi": "/sensors",
      "uuid": [
        "$address.ext",
        "0x01",
        "0x0400"
      ],
      "fingerprint": {
        "profile": "0x0104",
        "device": "0x0106",
        "endpoint": "0x01",
        "in": [
          "0x0001",
          "0x0400"
        ]
      },
      "items": [
        {
          "name": "attr/lastseen"
        },
        {
          "name": "attr/manufacturername"
        },
        {
          "name": "attr/modelid",
          "awake": true
        },
        {
          "name": "attr/name"
        },
        {
          "name": "attr/swversion",
          "awake": true,
          "parse": {
            "at": "0x00f7",
            "ep": 1,
            "fn": "xiaomi:special",
            "idx": "0x08",
            "script": "xiaomi_swversion.js"
          },
          "read": {
            "fn": "none"
          }
        },
        {
          "name": "attr/type"
        },
        {
          "name": "attr/uniqueid"
        },
        {
          "name": "config/on"
        },
        {
          "name": "config/battery",
          "awake": true,
          "parse": {
            "at": "0x00f7",
            "ep": 1,
            "fn": "xiaomi:special",
            "idx": "0x01",
            "eval": "const vmin = 2700; const vmax = 3000; const v = Math.max(vmin, Math.min(Attr.val, vmax)); const bat = Math.round(((v - vmin) / (vmax - vmin)) * 100); if (bat>0){Item.val = Math.max(0, Math.min(bat, 100));}"
          }
        },
        {
          "name": "config/reachable"
        },
        {
          "name": "config/tholddark"
        },
        {
          "name": "config/tholdoffset"
        },
        {
          "name": "state/lightlevel",
          "parse": {
            "at": "0x0000",
            "cl": "0x0400",
            "ep": 1,
            "script": "../generic/illuminance_cluster/sml_light_level.js"
          }
        },
        {
          "name": "state/dark"
        },
        {
          "name": "state/daylight"
        },
        {
          "name": "state/lux"
        },
        {
          "name": "state/lastupdated"
        }
      ],
      "example": {
        "config": {
          "battery": 100,
          "on": true,
          "reachable": true,
          "tholddark": 12000,
          "tholdoffset": 7000
        },
        "ep": 1,
        "etag": "761fff5a33ee73a8b9e4ec2e8ee5dac2",
        "lastseen": "2021-01-13T12:07Z",
        "manufacturername": "XIAOMI",
        "modelid": "lumi.sen_ill.mgl01",
        "name": "Light Sensor",
        "state": {
          "dark": false,
          "daylight": false,
          "lastupdated": "2021-01-13T12:07:27.511",
          "lightlevel": 13425,
          "lux": 22
        },
        "swversion": "0.0.0_0027",
        "type": "ZHALightLevel",
        "uniqueid": "04:cf:8c:df:3c:7f:1f:80-01-0400"
      }
    }
  ],
  "bindings": [
    {
      "bind": "unicast",
      "src.ep": 1,
      "cl": "0x0400",
      "report": [
        {
          "at": "0x0000",
          "dt": "0x21",
          "min": 10,
          "max": 3600,
          "change": "0x0064"
        }
      ]
    }
  ]
}

The magic is here


        {
          "name": "config/battery",
          "awake": true,
          "parse": {
            "at": "0x00f7",
            "ep": 1,
            "fn": "xiaomi:special",
            "idx": "0x01",
            "eval": "const vmin = 2700; const vmax = 3000; const v = Math.max(vmin, Math.min(Attr.val, vmax)); const bat = Math.round(((v - vmin) / (vmax - vmin)) * 100); if (bat>0){Item.val = Math.max(0, Math.min(bat, 100));}"
          }
        },