Xiaomi switch

Hi @veonua

I downloaded your xiaomi switch driver and made a couple of changes, in particular adding the following lines to the ‘device_init’ in the main ‘init.lua’:

device:remove_monitored_attribute(0x0006, 0x0000)
device:remove_monitored_attribute(0x0012, 0x0055)

This seems to have fixed the problem with the spurious ‘held’, without any loss of functionality. The devices still contact the hub regularly. In fact that is how you pick up the temperature status and energy information.

I have this working with several different older switches, all 1-gang. I haven’t tred a 2-gang case yet.

I know that this regular login doesn’t occur with the newer switches (e.g. opple), but cluster: 0xFCC0 attribute: 0xF7 provides the same functionality as the regular (catchall) login and may be worth using as a monitored function with no unfortunate side effects.


Thank you @aonghusmor, Pull Requests are welcome

I’d recommend replacing numbers with human-readable constants like

device:remove_monitored_attribute(OnOff.ID, OnOff.attributes.OnOff.ID)

As far as I remember old switches are not the problem but the Zigbee3.

Without initial on/off cluster monitoring my WS-EUK01 (lumi.switch.l1aeu1) doesn’t notify the hub about switch changes.
Perhaps removing the monitoring later as you suggest will fix the problem.

I agree, of course, about the constants. I was just trying to do a test, rather than publish anything. My main concern was to get rid of the spurious ‘held’ states.

I vaguely remember I had some correspondence about WS-EUK01 and the corresponding US switch, which did behave in an unusual way. The corresponding 2 and 3 button switches seem more well behaved. There’s a software switch, which I assume you’re aware of, on cluster 0xFCC0 attribute 0x09, which changes the behaviour significantly, including changing the button endpoints. Setting it to 1 gives more ‘normal’ behaviour.

Could you please create a pull request, because a simple paste of the snippet did not fix the spurious ‘held’ for me.

I had it after line 71 of your init.lua
device:set_field(“first_button_ep”, configs.first_button_ep, {persist = true})

the version with your proposal is published.
Everything goes well so far.


I have come across another issue/ I’ll try to find a solution, but I just want to check whether you’re aware of it. It is more apparent with a 2 gang switch.

If I try to use a button in an automation, that seems to work. However, if I use it in an app, such as Smart Lighting or ABC Manager, there seems to be a missing value for the button number. This causes Smart Lighting to crash, whereas ABC Manager gets far enough to show an error message in the IDE logs, which refers to ‘button null’. I note that, in the groovy version, the button number appears as a seperate integer parameter, so I’d guess it may to be the same with edge.

Having most of my devices using Edge I have abandoned cloud apps and happy with responsiveness.

If I understand it right ST is sunsetting these, so there will be no updates for the SmartLights app.

I’m puzzled why it was found necessary to change the interface for buttons such as to make the edge DHs incompatible with Groovy smartapps. It may not have been deliberate, of course.

It seems to me that there is a loss of functionality involved. For example, unless I’ve missed something, there doesn’t seem to be a way to define an automation/routine which when a button is pressed turns on a lamp dimmed and turns it off again on a 2nd press. That only works if I don’t want to do anything with dimming, colour or colour temperature.

I can do it by using the state of the lamp as a precondition and introducing another automation to switch the lamp off. To me that is unnecessarily counter intuitive for an ordinary user.

For your example the state storage is required, which is never easy.

Samsung team wants offload as much as possible to your local hub.
And unfortunately there is no good solution for local apps. So you have to rely on the device state.

Some developrs started to add extended logic to the virtual devices and drivers.

There is a lot of work for ST team to make apps that can interact with both local and cloud devices and keep state even on unreliable connections/devices.
Plus the UI need to be improved to display all the intermediate states and various possibilities.

I don’t know whether you’re aware that the signal strength values can be picked up from the ‘zb_rx’ parameter,which appears in your ‘xiaomi_utils.handler’ using

emit_signal_event(device, zb_rx.rssi.value, zb_rx.lqi.value)

These seem to be more reliable than the versions which come from the ‘xiami_events’ array.

It’s strange that these appear in the ‘ZigbeeMessageRx’, but were not available in the corresponding message in groovy.

I believe the value in the array is the signal quality measured by device. the one in the header might be quality measured by hub.

Anyway I don’t understand these numbers. And I have seen on the forum other users don’t understand them either, “normal” RSSI value gives a poor connection, and lqi value is normalised (0-100) or not (0-255)

My understanding is that RSSI is decibels, which is a logarithmic scale and confusing for many people who are not used to that sort of thing. In any case numbers below -70 are bad. The funny thing is that the xiaomi numbers are unsigned integers. It could be that the minus sign is implied, but, even then, I’ve seen numbers which don’t make sense. It is probable that this only applies to the final link, so the 2 versions should be the same for devices connected directly to the hub, but may be different when routed via another device.

According to Smartthings’ definition of LQI it should have maximum value 255, ie. 0xFF. This is an indication of lost bits, so 255 is good. However, the xiaomi number is a uint40, and usually has the value 1. Obviously a different definition is being used.

I was trying to use your xiaomi-switch code for a QBKG03LM. I can’t get the right hand switch to work by software, either from the app or in an automation. I’ve been playing with the code, but still haven’t found the solution. I just want to check whether you’re aware of the issue.

it seems like there is a bug in a new firmware
the default handler seems to fail to send events to the endpoints

I’ve found the error. There’s no firmware issue.

In your function ‘component_to_endpoint’ the line

local res = ep_num and tonumber(ep_num - 1 + first_switch_ep) or device.fingerprinted_endpoint_id

should be

local res = ep_num and (tonumber(ep_num) - 1 + first_switch_ep) or device.fingerprinted_endpoint_id

The point is that ‘ep_num’ is returned from the previous line as a string.

I first noticed that res was being returned as 3.0 rather than 3, whereas when called with ‘main’ it returned 2 rather than 2.0. It appears that this version of lua does distinguish between integer and floating point, unlike the standard. This makes sense, as most of the zigbee stuff requires integers and wouldn’t understand if passed a floating point number. It would probably interpret it as the integer equivalent of the same bit pattern.
In the current case the addition of a string and an integer is quietly returned as a floating point.

I also found the behaviour of lua confusing when presented with logical operators between 2 numbers.

1 Like

I should also add that I’ve got your code working with

  • id: “QBKG21LM”
    deviceLabel: QBKG21LM Wall Switch (No Neutral, Single Rocker)
    manufacturer: LUMI
    model: lumi.switch.b1lacn02
    deviceProfileName: switch-button
    • id: “QBKG22LM”
      deviceLabel: QBKG22LM Wall Switch (No Neutral, Double Rocker)
      manufacturer: LUMI
      model: lumi.switch.b2lacn02
      deviceProfileName: switch-button-2
    • id: “WXKG06LM”
      deviceLabel: WXKG06LM Wall Switch (Single Rocker)
      manufacturer: LUMI
      model: lumi.remote.b186acn02
      deviceProfileName: button

oh, great finding Aonghus! can you please create a pull request in the github ?

I assume you meant push rather than pull. I’ve pushed these to my fork of your github site. You want the fingerprint.yaml file and the src/init.lua

I’ve done a bit of experimentation with other aspects, so you probably don’t want any of the other files that may inadvertantly have been pushed at the same time.

1 Like

I’ve just noticed that ‘detached’ mode isn’t working on QBKG21LM-QBKG23LM (I don’t have 24). I can see from my groovy version that it uses the same settings as the older switches, which work properly with your code. At the moment I can’t see where in your code the relevant difference is.