Aqara Cube ZHA - Simplified face-based device control

This is just another Blueprint for controlling the Aqara Cube, and I’ve build this inspired by many other Blueprints available:

Zigbee integration: ZHA

I developed this when looking for a remote to control all the devices in my home-office room (and some nearby devices that might bother me during a call), but as this cube have lots of possibilities, the majority of integrations available was too complex to my brain, focusing a lot on which side was moved from… I just wanna one device per face (I will have an stick with the respective icon on each face), and the capabilities to do basic control on those devices.

This is my example (you can set the devices and actions as you want):

Face up Device Knock Counter-clockwise Clockwise
1 Workstation light Toggle light Decrease brightness Increase brightness
2 Workstation power Toggle power N/A N/A
3 Roomba Start/stop cleaning Go home (when stopped) N/A
4 Ceiling lights Toggle light Decrease brightness Increase brightness
5 Curtain Toggle curtain Close 1 step Open 1 step
6 TV Living room Toggle TV Volume down Volume up

So, in order to use this Blueprint you need an Aqara Cube and to create a helper to temporary store the last face up (as the cube don’t report the face up when rotating).
You can create this helper (it’s super easy) going to Configuration > Automation & Scenes, then select the tab “Helpers” (in the top), click on “+ Add Helper” and select “Number”:

You don’t have to spend too much time on this as only the name is required now, but if you want customize something else, make sure to allow numbers from 0 to 6 at least.

When you have the Cube and the helper set, just create a new automation from the Blueprint and have fun.

Change log:

  • 2022-02-05 10:59 UTC:
    • First time published

This is the Blueprint:

Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

blueprint:
  name: Aqara Cube face-based
  description: Control devices based on the cube's face.
  domain: automation
  input:
    last_face_input:
      name: Last face up numeric helper
      description: Please select a Numeric Helper to be used to record the last face up.
      selector:
        entity:
          domain: input_number
    cube:
      name: Aqara Cube
      description: Select the Aqara Cube device
      selector:
        device:
          integration: zha
          manufacturer: LUMI
    face_1_flip:
      name: Flip to face 1
      description: Actions to execute when the cube is flipped to face 1 in the top.
      default: []
      selector:
        action: {}
    face_1_knock:
      name: Knock face 1
      description: Actions to execute when the cube is knocked with face 1 in the top.
      default: []
      selector:
        action: {}
    face_1_rotate_counter_clockwise:
      name: Rotate counter-clockwise face 1
      description: Actions to execute when the cube rotates counter-clockwise with face 1 in the top.
      default: []
      selector:
        action: {}
    face_1_rotate_clockwise:
      name: Rotate clockwise face 1
      description: Actions to execute when the cube rotates clockwise with face 1 in the top.
      default: []
      selector:
        action: {}
    face_1_slide:
      name: Slide face 1
      description: Actions to execute when the cube slides with face 1 in the top.
      default: []
      selector:
        action: {}
    face_2_flip:
      name: Flip to face 2
      description: Actions to execute when the cube is flipped to face 2 in the top.
      default: []
      selector:
        action: {}
    face_2_knock:
      name: Knock face 2
      description: Actions to execute when the cube is knocked with face 2 in the top.
      default: []
      selector:
        action: {}
    face_2_rotate_counter_clockwise:
      name: Rotate counter-clockwise face 2
      description: Actions to execute when the cube rotates counter-clockwise with face 2 in the top.
      default: []
      selector:
        action: {}
    face_2_rotate_clockwise:
      name: Rotate clockwise face 2
      description: Actions to execute when the cube rotates clockwise with face 2 in the top.
      default: []
      selector:
        action: {}
    face_2_slide:
      name: Slide face 2
      description: Actions to execute when the cube slides with face 2 in the top.
      default: []
      selector:
        action: {}
    face_3_flip:
      name: Flip to face 3
      description: Actions to execute when the cube is flipped to face 3 in the top.
      default: []
      selector:
        action: {}
    face_3_knock:
      name: Knock face 3
      description: Actions to execute when the cube is knocked with face 3 in the top.
      default: []
      selector:
        action: {}
    face_3_rotate_counter_clockwise:
      name: Rotate counter-clockwise face 3
      description: Actions to execute when the cube rotates counter-clockwise with face 3 in the top.
      default: []
      selector:
        action: {}
    face_3_rotate_clockwise:
      name: Rotate clockwise face 3
      description: Actions to execute when the cube rotates clockwise with face 3 in the top.
      default: []
      selector:
        action: {}
    face_3_slide:
      name: Slide face 3
      description: Actions to execute when the cube slides with face 3 in the top.
      default: []
      selector:
        action: {}
    face_4_flip:
      name: Flip to face 4
      description: Actions to execute when the cube is flipped to face 4 in the top.
      default: []
      selector:
        action: {}
    face_4_knock:
      name: Knock face 4
      description: Actions to execute when the cube is knocked with face 4 in the top.
      default: []
      selector:
        action: {}
    face_4_rotate_counter_clockwise:
      name: Rotate counter-clockwise face 4
      description: Actions to execute when the cube rotates counter-clockwise with face 4 in the top.
      default: []
      selector:
        action: {}
    face_4_rotate_clockwise:
      name: Rotate clockwise face 4
      description: Actions to execute when the cube rotates clockwise with face 4 in the top.
      default: []
      selector:
        action: {}
    face_4_slide:
      name: Slide face 4
      description: Actions to execute when the cube slides with face 4 in the top.
      default: []
      selector:
        action: {}
    face_5_flip:
      name: Flip to face 5
      description: Actions to execute when the cube is flipped to face 5 in the top.
      default: []
      selector:
        action: {}
    face_5_knock:
      name: Knock face 5
      description: Actions to execute when the cube is knocked with face 5 in the top.
      default: []
      selector:
        action: {}
    face_5_rotate_counter_clockwise:
      name: Rotate counter-clockwise face 5
      description: Actions to execute when the cube rotates counter-clockwise with face 5 in the top.
      default: []
      selector:
        action: {}
    face_5_rotate_clockwise:
      name: Rotate clockwise face 5
      description: Actions to execute when the cube rotates clockwise with face 5 in the top.
      default: []
      selector:
        action: {}
    face_5_slide:
      name: Slide face 5
      description: Actions to execute when the cube slides with face 5 in the top.
      default: []
      selector:
        action: {}
    face_6_flip:
      name: Flip to face 6
      description: Actions to execute when the cube is flipped to face 6 in the top.
      default: []
      selector:
        action: {}
    face_6_knock:
      name: Knock face 6
      description: Actions to execute when the cube is knocked with face 6 in the top.
      default: []
      selector:
        action: {}
    face_6_rotate_counter_clockwise:
      name: Rotate counter-clockwise face 6
      description: Actions to execute when the cube rotates counter-clockwise with face 6 in the top.
      default: []
      selector:
        action: {}
    face_6_rotate_clockwise:
      name: Rotate clockwise face 6
      description: Actions to execute when the cube rotates clockwise with face 6 in the top.
      default: []
      selector:
        action: {}
    face_6_slide:
      name: Slide face 6
      description: Actions to execute when the cube slides with face 6 in the top.
      default: []
      selector:
        action: {}
  source_url: https://community.home-assistant.io/t/aqara-cube-zha-simplified-face-based-device-control/388850
mode: restart
max_exceeded: silent
trigger:
- platform: event
  event_type: zha_event
  event_data:
    device_id: !input cube
action:
- variables:
    command: '{{ trigger.event.data.command }}'
    value: '{{ trigger.event.data.args.value | default(0) }}'
    flip_degrees: '{{ trigger.event.data.args.flip_degrees | default(0) }}'
    temp_last_face_input: !input last_face_input
    activated_face: '{{ iif((command == ''slide'' or command == ''knock'' or command == ''flip''), trigger.event.data.args.activated_face, states(temp_last_face_input)) | int(0) }}'
    #activated_face: |-
      #{% if command == 'slide' or command == 'knock' or command == 'flip' %}
        #{{ trigger.event.data.args.activated_face | int(0) }}
      #{% else %}
        #{{ states(temp_last_face_input) | int(0) }}
      #{% endif %}
- service: input_number.set_value
  target:
    entity_id: !input last_face_input
  data:
    value: '{{ activated_face }}'
- choose:
  - conditions:
      - '{{ activated_face == 1 }}'
    sequence:
      - choose:
        - conditions:
            - '{{ command == ''flip'' }}'
          sequence: !input face_1_flip
        - conditions:
            - '{{ command == ''knock'' }}'
          sequence: !input face_1_knock
        - conditions:
            - '{{ command == ''rotate_left'' }}'
          sequence: !input face_1_rotate_counter_clockwise
        - conditions:
            - '{{ command == ''rotate_right'' }}'
          sequence: !input face_1_rotate_clockwise
        - conditions:
            - '{{ command == ''slide'' }}'
          sequence: !input face_1_slide
        default: []
  - conditions:
      - '{{ activated_face == 2 }}'
    sequence:
      - choose:
        - conditions:
            - '{{ command == ''flip'' }}'
          sequence: !input face_2_flip
        - conditions:
            - '{{ command == ''knock'' }}'
          sequence: !input face_2_knock
        - conditions:
            - '{{ command == ''rotate_left'' }}'
          sequence: !input face_2_rotate_counter_clockwise
        - conditions:
            - '{{ command == ''rotate_right'' }}'
          sequence: !input face_2_rotate_clockwise
        - conditions:
            - '{{ command == ''slide'' }}'
          sequence: !input face_2_slide
        default: []
  - conditions:
      - '{{ activated_face == 3 }}'
    sequence:
      - choose:
        - conditions:
            - '{{ command == ''flip'' }}'
          sequence: !input face_3_flip
        - conditions:
            - '{{ command == ''knock'' }}'
          sequence: !input face_3_knock
        - conditions:
            - '{{ command == ''rotate_left'' }}'
          sequence: !input face_3_rotate_counter_clockwise
        - conditions:
            - '{{ command == ''rotate_right'' }}'
          sequence: !input face_3_rotate_clockwise
        - conditions:
            - '{{ command == ''slide'' }}'
          sequence: !input face_3_slide
        default: []
  - conditions:
      - '{{ activated_face == 4 }}'
    sequence:
      - choose:
        - conditions:
            - '{{ command == ''flip'' }}'
          sequence: !input face_4_flip
        - conditions:
            - '{{ command == ''knock'' }}'
          sequence: !input face_4_knock
        - conditions:
            - '{{ command == ''rotate_left'' }}'
          sequence: !input face_4_rotate_counter_clockwise
        - conditions:
            - '{{ command == ''rotate_right'' }}'
          sequence: !input face_4_rotate_clockwise
        - conditions:
            - '{{ command == ''slide'' }}'
          sequence: !input face_4_slide
        default: []
  - conditions:
      - '{{ activated_face == 5 }}'
    sequence:
      - choose:
        - conditions:
            - '{{ command == ''flip'' }}'
          sequence: !input face_5_flip
        - conditions:
            - '{{ command == ''knock'' }}'
          sequence: !input face_5_knock
        - conditions:
            - '{{ command == ''rotate_left'' }}'
          sequence: !input face_5_rotate_counter_clockwise
        - conditions:
            - '{{ command == ''rotate_right'' }}'
          sequence: !input face_5_rotate_clockwise
        - conditions:
            - '{{ command == ''slide'' }}'
          sequence: !input face_5_slide
        default: []
  - conditions:
      - '{{ activated_face == 6 }}'
    sequence:
      - choose:
        - conditions:
            - '{{ command == ''flip'' }}'
          sequence: !input face_6_flip
        - conditions:
            - '{{ command == ''knock'' }}'
          sequence: !input face_6_knock
        - conditions:
            - '{{ command == ''rotate_left'' }}'
          sequence: !input face_6_rotate_counter_clockwise
        - conditions:
            - '{{ command == ''rotate_right'' }}'
          sequence: !input face_6_rotate_clockwise
        - conditions:
            - '{{ command == ''slide'' }}'
          sequence: !input face_6_slide
        default: []
  default: []

1 Like

ON the first step after the star I am getting Executed: February 12, 2022, 1:20:27 PM
Error: UndefinedError: ‘iif’ is undefined

Could I get that if ever face does not have an action? Also the last face helper is not changing.

Which version of Home Assistant are you running? I believe iif was introduced on v2022.2, but if you are running an older version I can easily change that in order to make it compatible.

That would be why, I’ll upgrade to 2022.2.

1 Like

Works great with 2022.2. Thank you!

1 Like

FINALLY!! A ZHA cube blueprint that works!! Thank you!!

1 Like

Can you use the angle of rotation in ZHA or is that only available in Z2MQTT?

Angle is also available on ZHA.
What is your use case? Maybe I can adjust this Blueprint to use the angle.

Want to use rotation to dim lights/control volume. I think the angle can act as a multiplier for the dimming value.

If you see in this Blueprint, the flip_degrees is available as a local variable. The Blueprint was made to support any action (not only light), so angle is not used as a parameter.
In order to use this, a new Blueprint (or automation) will be needed, with small modification.

Do you have any experience with building your own automation with YAML or do you wanna help building it?

By the way, I’ve used increase/decrease brightness as actions and it works fine. It’s probably better than using degree as you don’t have to calibrate it.

Also, I cannot test right now, but most likely the Blueprint that I’ve created will work as it is if you select “call a service” as an action for one of the turning sides and then adding the variable as a template in YAML mode:

I’ve tried both in automations before and prefer the one using degrees as a multiplier. If you set it right, you can get finer control over the adjustment. Low angle = low change in brightness/volume. High angle = high change. Versus a static X% no matter how much the turn angle.

hi thanks for your blueprint!

I have 3 of these cubes and they control various thongs like blids, fans, lights, etc. I’m currently using the 51 action blueprint one now, besides geting erros messages in the my log files when I rotate the cube:

Template variable warning: 'dict object' has no attribute 'flip_degrees' when rendering '{{ trigger.event.data.args.flip_degrees }}'

2:24:17 PM – (WARNING) helpers/template.py - message first occurred at 2:24:06 PM and shows up 28 times

just curious what your blueprint does that is better than the 51 action one? I’d be happy to change to this!

Have you tried using flip_degrees as in my last example?

Hi @Anto79-ops,
I don’t know which Blueprint you are talking about. Please share the link here and I can try to identify the difference between them.
By the way, this is not a competition between blueprints. :wink:

It’s the wrong zigbee flavor, but if you are able to get the angle into my template, this template logic I suggest for angle actions should work for you… (This is a link to the dimmer control section)

At that level, it’s just an action. You would need to pass the angle in. Z2M gives me pos angles for CW and negative angles for CCW, so the template doesn’t change and called script gets used for multiple sensors.

I also provide in there a scheme to set the R, G, & B Colors using rotation, and another section to use a short rotation for a short press and a larger rotation as a long press. These are all template things you can do regardless of the Zigbee flavor as long as you can get the angle out of the Integrations Data Attributes.

@EdwardTFN thanks!

Here’s what im using now, its in your OP

I tried your blue-print, and it acutally fixes that error in logs that I posted above! so that is great news.

With your blue-print, how does one:

  1. set a command to fire when, for example, something is flipped from side 1 to side 2

@Sir_Goodenough

its sounds like things are greener over at the Z2M side, in terms of features. I’m slowly building up momentum to make the switch. That’s an impressive blue-print for the cube!