Suggestions for best way to parse a Number state. (deCONZ Xiaomi cube related)

Finally got my side up + gesture events from my Xiaomi cube :slight_smile:

My .item is:

Number Pink1CubeButtonEvent { http="<[MiCubePink1GestureCache:500:JSONPATH($.state.buttonevent)]" }

Rule so far (just logging):

rule "Xiaomi Cube action"
when
    Item Pink1CubeButtonLastUpdated changed
then
    Thread::sleep(20)
    var actionName = Pink1CubeButtonEvent.state

    var name = "Cube P1" 
    logInfo(name, "Event: " + actionName)
/*
    switch(actionName) {
        case "MOVE": {
            <ACTION>
        }
        case "ROTATE_RIGHT": {
            <ACTION>
        }
        case "ROTATE_LEFT": {
            <ACTION>
        }
        case "FLIP90": {
            <ACTION>
        }
        case "FLIP180": {
            <ACTION>
        }
        case "TAP_TWICE": {
            <ACTION>
        }
        case "SHAKE_AIR": {
            <ACTION>
        }
        case "FREE_FALL": {
            <ACTION>
        }
        case "ALERT": {
            <ACTION>
        }
    }
    */
end

The commented out part is what used to be the parsing of the gestures from the Xiaomi Gateway. That did not contain any info about what face of the cube/dice was up.

Now, the numbers received is coded like this:

x000 for push, so 1000, 2000, 3000, 4000, 5000, 6000;
x00x for double tap, so 1001, 2002, 3003, 4004, 5005, 6006;
x00o for 180° flip (where o = 7 - x), so 1006, 2005, 3004, 4003, 5002, 6001;
x00y for 90° flip (where y ≠ x and y ≠ 7 - x), so 1002, 1003, 1004, 1005, 2001, 2003, 2004, 2006, 3001, 3002, 3005, 3006, 4001, 4002, 4005, 4006, 5001, 5003, 5004, 5006, 6002, 6003, 6004, 6005;
7007 for shake.
7008 for free-fall/drop
7000 for wakeup (the cube sends raw value 2 when I just tap it after a while).

Snippet from.

My log looks like this:

2018-06-09 23:57:45.128 [INFO ] [lipse.smarthome.model.script.Cube P1] - Event: 7000
2018-06-09 23:57:48.219 [INFO ] [lipse.smarthome.model.script.Cube P1] - Event: 6003
2018-06-09 23:57:51.339 [INFO ] [lipse.smarthome.model.script.Cube P1] - Event: 2006
2018-06-09 23:57:54.357 [INFO ] [lipse.smarthome.model.script.Cube P1] - Event: 7007
2018-06-09 23:58:02.505 [INFO ] [lipse.smarthome.model.script.Cube P1] - Event: 2000
2018-06-09 23:59:36.117 [INFO ] [lipse.smarthome.model.script.Cube P1] - Event: 5002
2018-06-10 00:01:05.775 [INFO ] [lipse.smarthome.model.script.Cube P1] - Event: 5005

7000 = wake up (Xiaomi named it ALARM)
6003 = face 6 is up, face was previously up - flip90
2006 = face 2 is up, 6 was up - flip90
7007 = shake
2000 = moved, while face 2 is up
5002 = face 5 is up, 2 was up - flip180
5005 = double tap, face 5 up

What would be the most efficient way to parse these values in the rule?
Possible with a switch(), case construct or a bunch of ifs?
Any suggestions most welcome.

Further reading.

The variable actionName is a number so:

        case 1000, case 2000, case 3000, case 4000, case 5000, case 6000: { //push
            //<ACTION>
        }
        case 1001, case 2002, case 3003, case 4004, case 5005, case 6006: { //double tap
            //<ACTION>
        }
        .... AND SO ON

Thanks.
About the flips, I’m only interested in the leftmost digit, the side facing up.
Cannot think of why I would care which face it came from?
So, how to get nxxx were n=1-6 and x is don’t care?

var sideUp = Math::round(actionName/1000)
switch(sideUp) {
    case 1:
    ...

or maybe if that doesn’t work
var sideUp = (actionName/1000).intValue

A drinking game maybe… :laughing:

Thank you @vzorglub for pointing me in this direction.

Just for completion I am posting my working solution:

rule "Xiaomi Cube action"
when
    Item Pink1CubeButtonLastUpdated changed
then
    Thread::sleep(20) // without this, the previos buttonevent is returned
    var P1buttonstate = (Pink1CubeButtonEvent.state as DecimalType).intValue
    var P1face = Math::round(P1buttonstate / 1000)
    var P1prevFace = Math::round(P1buttonstate - P1face*1000)

    var name = "Cube P1" 
    logInfo(name, "Event: " + P1buttonstate)
    logInfo(name, "Face UP: " + P1face)
    logInfo(name, "Last Face: " + P1prevFace)

    switch(P1face) {
        case 1: {            
            switch(P1prevFace) {
                case 0: {                    
                  logInfo(name, "Pushed - w/face"+ P1face+" up")
                }
                case 1: {                    
                  logInfo(name, "DoubleTap - w/face"+ P1face+" up")
                }
                default: {                    
                  logInfo(name, "Face"+ P1face+" action")
                }
            }
        }
        case 2: {            
            switch(P1prevFace) {
                case 0: {                    
                  logInfo(name, "Pushed - w/face"+ P1face+" up")
                }
                case 2: {                    
                  logInfo(name, "DoubleTap - w/face"+ P1face+" up")
                }
                default: {                    
                  logInfo(name, "Face"+ P1face+" action")
                }
            }
        }
        case 3: {            
            switch(P1prevFace) {
                case 0: {                    
                  logInfo(name, "Pushed - w/face"+ P1face+" up")
                }
                case 3: {                    
                  logInfo(name, "DoubleTap - w/face"+ P1face+" up")
                }
                default: {                    
                  logInfo(name, "Face"+ P1face+" action")
                }
            }
        }
        case 4: {            
            switch(P1prevFace) {
                case 0: {                    
                  logInfo(name, "Pushed - w/face"+ P1face+" up")
                }
                case 4: {                    
                  logInfo(name, "DoubleTap - w/face"+ P1face+" up")
                }
                default: {                    
                  logInfo(name, "Face"+ P1face+" action")
                }
            }
        }
        case 5: {            
            switch(P1prevFace) {
                case 0: {                    
                  logInfo(name, "Pushed - w/face"+ P1face+" up")
                }
                case 5: {                    
                  logInfo(name, "DoubleTap - w/face"+ P1face+" up")
                }
                default: {                    
                  logInfo(name, "Face"+ P1face+" action")
                }
            }
        }
        case 6: {            
            switch(P1prevFace) {
                case 0: {                    
                  logInfo(name, "Pushed - w/face"+ P1face+" up")
                }
                case 6: {                    
                  logInfo(name, "DoubleTap - w/face"+ P1face+" up")
                }
                default: {                    
                  logInfo(name, "Face"+ P1face+" action")
                }
            }
        }
        case 7: {
            switch(P1prevFace) {
                case 0: {                    
                  logInfo(name, "Woke up")
                }
                case 7: {                    
                  logInfo(name, "Shaken & stirred")
                }
                case 8: { // from deCONZ 2.05.29               
                  logInfo(name, "Free-falling!!")
                }
            }
        }
    }
end

Log example:

2018-06-10 15:22:58.014 [INFO ] [lipse.smarthome.model.script.Cube P1] - Event: 1006
2018-06-10 15:22:58.015 [INFO ] [lipse.smarthome.model.script.Cube P1] - Face UP: 1
2018-06-10 15:22:58.016 [INFO ] [lipse.smarthome.model.script.Cube P1] - Last Face: 6
2018-06-10 15:22:58.017 [INFO ] [lipse.smarthome.model.script.Cube P1] - Face1 action
2018-06-10 15:23:09.165 [INFO ] [lipse.smarthome.model.script.Cube P1] - Rotation: 711
2018-06-10 15:23:12.175 [INFO ] [lipse.smarthome.model.script.Cube P1] - Event: 6001
2018-06-10 15:23:12.176 [INFO ] [lipse.smarthome.model.script.Cube P1] - Face UP: 6
2018-06-10 15:23:12.176 [INFO ] [lipse.smarthome.model.script.Cube P1] - Last Face: 1
2018-06-10 15:23:12.177 [INFO ] [lipse.smarthome.model.script.Cube P1] - Face6 action
2018-06-10 15:23:17.297 [INFO ] [lipse.smarthome.model.script.Cube P1] - Event: 1006
2018-06-10 15:23:17.298 [INFO ] [lipse.smarthome.model.script.Cube P1] - Face UP: 1
2018-06-10 15:23:17.298 [INFO ] [lipse.smarthome.model.script.Cube P1] - Last Face: 6
2018-06-10 15:23:17.299 [INFO ] [lipse.smarthome.model.script.Cube P1] - Face1 action
2018-06-10 15:23:22.388 [INFO ] [lipse.smarthome.model.script.Cube P1] - Event: 6001
2018-06-10 15:23:22.388 [INFO ] [lipse.smarthome.model.script.Cube P1] - Face UP: 6
2018-06-10 15:23:22.389 [INFO ] [lipse.smarthome.model.script.Cube P1] - Last Face: 1
2018-06-10 15:23:22.390 [INFO ] [lipse.smarthome.model.script.Cube P1] - Face6 action
2018-06-10 15:28:20.318 [INFO ] [lipse.smarthome.model.script.Cube P1] - Event: 6000
2018-06-10 15:28:20.319 [INFO ] [lipse.smarthome.model.script.Cube P1] - Face UP: 6
2018-06-10 15:28:20.319 [INFO ] [lipse.smarthome.model.script.Cube P1] - Last Face: 0
2018-06-10 15:28:20.320 [INFO ] [lipse.smarthome.model.script.Cube P1] - Pushed - w/face6 up
2018-06-10 15:28:29.329 [INFO ] [lipse.smarthome.model.script.Cube P1] - Event: 2006
2018-06-10 15:28:29.329 [INFO ] [lipse.smarthome.model.script.Cube P1] - Face UP: 2
2018-06-10 15:28:29.330 [INFO ] [lipse.smarthome.model.script.Cube P1] - Last Face: 6
2018-06-10 15:28:29.330 [INFO ] [lipse.smarthome.model.script.Cube P1] - Face2 action
2018-06-10 15:28:32.449 [INFO ] [lipse.smarthome.model.script.Cube P1] - Event: 2002
2018-06-10 15:28:32.449 [INFO ] [lipse.smarthome.model.script.Cube P1] - Face UP: 2
2018-06-10 15:28:32.450 [INFO ] [lipse.smarthome.model.script.Cube P1] - Last Face: 2
2018-06-10 15:28:32.450 [INFO ] [lipse.smarthome.model.script.Cube P1] - DoubleTap - w/face2 up
2018-06-10 15:28:35.460 [INFO ] [lipse.smarthome.model.script.Cube P1] - Event: 7007
2018-06-10 15:28:35.460 [INFO ] [lipse.smarthome.model.script.Cube P1] - Face UP: 7
2018-06-10 15:28:35.461 [INFO ] [lipse.smarthome.model.script.Cube P1] - Last Face: 7
2018-06-10 15:28:35.462 [INFO ] [lipse.smarthome.model.script.Cube P1] - Shaken & stirred

Now, for the real fun! :slight_smile:

2 Likes

I would like to evaluate the side up of the controller.

I’m struggling reading the event for a: Aqara Magic Cube Controller.
I’m using only the Xiaomi Mi Smart Home Binding.

In the example there is no event to evaluate.
Only a channel:

Channel 'mihome:sensor_cube:158d00024a4c5c:action' triggered
var actionName = receivedEvent.getEvent()

gives strings independent of the side up.

Any hints?
Where does these item come from:

Since the Xiaomi Gateway, at my time of testing, didn’t support all the cube gestures and the Aqara cubes at all; I ditched the Xiaomi Gateway (and hence the binding) and bought a ConBee USB ZigBee dongle from Dresden Elektronik instead. Running their deconz SW on the same machine as OH2.
Interfaced through their REST API and OH2 http binding.
Details here.

Thanks for the answer - I suspected that. :wink:
I would like to stick with the binding - it’s working smooth.

May be somebody else has an idea how to detect the side up on the Aqara Magic Cube Controller???

I thought I could get the info from receivedEvent.getEvent() or may be link the trigger/action channel:

mihome:sensor_cube:158d00024a4c5c:action

If you cannot see the info in the mi App, then the binding cannot see it either.