Rotate to the left or right in Xiaomi Magic Cube?

I took some code and ideas from this thread. I’d like to show my configuration for this to sum it up for other users.

You can find the code here:
https://github.com/Koenkk/zigbee2mqtt/issues/571#issuecomment-444569654

I think the one idea I came up with is not yet mentioned here. If you add lines like the ones below, you will be able to turn your light off (see complete code in the link above).

- condition: template
  value_template: "{{ states.light.trainingsraum.attributes.brightness == 0 }}"
- service: light.turn_off
  data:
    entity_id: light.trainingsraum

Guys, can you show me how to control volume with cube?

I tried:

- id: '121'
  alias: "Adjust Cube Volume Levels"
  initial_state: 'on'
  trigger:
    - platform: event
      event_type: xiaomi_aqara.cube_action
      event_data:
        entity_id: binary_sensor.cube_158d00027d8e39
        action_type: rotate
  action:
    - service: media_player.volume_set
      data_template:
        entity_id: media_player.vu
        volume_level: >
          {%if trigger.event.data.action_value  | float > 0 %} 
          {{states.media_player.vu.attributes.volume_level| float + 0.10}}
          {% else %}
          {{states.media_player.vu.attributes.volume_level| float - 0.10}}
          {%endif %}

but volume control is not continuous (I must stop between volume changes).

Similar light brightness control is working continuosly:

- id: micube_brightness_rotate
  alias: "MiCube rotate - Master lights"
  initial_state: 'on'
  condition:
    - condition: state
      entity_id: light.yeelight_lights_2
      state: 'on'
  trigger:
    platform: event
    event_type: xiaomi_aqara.cube_action
    event_data:
      entity_id: binary_sensor.cube_158d00027d8e39
      action_type: rotate
  action:
    - service: light.turn_on
      data_template:
        entity_id: light.yeelight_lights_2
        brightness: >
              {% set state = (state_attr('light.yeelight_lights_2','brightness') + trigger.event.data.action_value|int) -%}
              {%-  if state > 255 -%}
                 {%- set state  = 255 -%}
              {%-  elif state < 0 -%}
                 {%- set state  = 0 -%}
              {%- endif %}
              {{ state }}

Bump, maybe someone is around with same Xiaomi Cube.

The two automations works slightly different from each other. On volume you are increasing the value a fixed amount at each cube event (+0.10 or -0.10). While on brightness control you are increasing it by a variable amount based on how much you did rotate the cube. you could use the same idea from brightness to the volume, but you will have to do some math as the range is not the same (brightness 1-255 and volume 0 to 1.0).

You may try something like this:

volume_level: >
      {% set state = (state_attr('media_player.vu',volume_level') + trigger.event.data.action_value|float / 36-%}
      {%-  if state > 1.0 -%}
             {%- set state  = 1.0 -%}
      {%-  elif state < 0 -%}
             {%- set state  = 0 -%}
      {%- endif %}
      {{ state }}

I’m not home and don’t remember well what is the range of values the cube reports, but from a automation that i have, something like 18 is like half turn, so you will have to play with the “36” value to adjust the “sensitivity”. Based on these values a half turn should increase/decrease the volume by 0.50 (too much?).

Hi @clyra,

Thanks for the code, it has two small typos, but I figured out:

- id: '121'
  alias: "Xiaomi Cube Volume Adjust"
  initial_state: 'on'
  trigger:
    - platform: event
      event_type: xiaomi_aqara.cube_action
      event_data:
        entity_id: binary_sensor.cube_158d00027
        action_type: rotate
  action:
    - service: media_player.volume_set
      data_template:
        entity_id: media_player.vu
        volume_level: >
              {% set state = (state_attr('media_player.vu','volume_level') + trigger.event.data.action_value|float / 72) -%}
              {%-  if state > 1.0 -%}
                     {%- set state  = 1.0 -%}
              {%-  elif state < 0 -%}
                     {%- set state  = 0 -%}
              {%- endif %}
              {{ state }}

It is better than previously, but it still has problems, sometimes it doesn’t register movements, sometimes it skips up-down, sometimes I turn right half cm and it goes form 20% to 100% etc . It is not like a good classic analog volume knob.

I use this:

  - alias: Cube - Volume [Rotate]
    initial_state: 'on'
    trigger:
      - platform: event
        event_type: xiaomi_aqara.cube_action
        event_data:
          entity_id: binary_sensor.cube_158d00010fd152_2
          action_type: rotate
    action:
      - service_template: >  
            {%if trigger.event.data.action_value | float > 0 %} 
                 switch.turn_on
            {% else %} 
                  switch.turn_off
            {% endif %}
        entity_id: switch.onkyo_amp_volume_up

I shamelessly stole this from someone else and it works well for me, but I’m not sure it is possible to get a true equivalent to a smooth analogue dial with the cube:

  trigger:
    platform: event
    event_type: xiaomi_aqara.cube_action
    event_data:
      entity_id: binary_sensor.cube_xxxxxxxxxxx
      action_type: rotate
  action:
  - service: media_player.volume_set
    data_template:
      entity_id: media_player.kitchen
      volume_level: >
                  {% set state = states.media_player.kitchen.attributes.volume_level + (trigger.event.data.action_value|float)/90 -%}
                  {%-  if state > 1 -%}
                     {%- set state  = 1 -%}
                  {%-  elif state < 0 -%}
                     {%- set state  = 0 -%}
                  {%- endif %}
                  {{ state }}

Hope this helps

Nice. I should have warned you that have to have typos :-). A long time ago when I was testing my cube I used to “tail -f” the homeassistant log and see what HA reported when I moved the cube. I was expecting something like the angle you moved the cube (90 = quarter turn) but it wasnt, so I had to test/try which values make senses. As you say, it’s not like a good analog volume knob and it will never will, first because the cube does not report values as you are moving it but only when you finish moving and second it’s not that precise with the values.
I use my cube to control the volume of my tv but since I can’t set absolute values (I’m using IR) what I do is increment/decrement a single “unit” when I do a small rotation and increment/decrement 4 units when I do a bigger rotation. Not ideal but acceptable :-).
I still have that idea of using a cheap midi controller with sliders to do that kind of thing…

“you are moving it but only when you finish moving and second it’s not that precise with the values.”
:100:
And this is the downside of the whole cube and should be mentioned everywhere. I thought that it reports continuously. Now I see why it is working like this. :+1::+1::+1:

Hi everyone,
I’m a beginner and I need your help:
I tried this automation to adjust the light of the gateway, but it does not work,
can you tell me where I’m wrong?

- alias: Xiaomi Cube - Brightness [Rotate]
  trigger:
    platform: event
    event_type: cube_action
    event_data:
      entity_id: binary_sensor.cube_158d00029ba5bf
      action_type: rotate  
  action:
    - service: light.turn_on
      data_template:
        entity_id: light.gateway_light_7c49eb88d95a      
        brightness: >
          {%if trigger.event.data.action_value | float > 0 %} 
          {{  states.light.pc.attributes.brightness | int + 10 }}
          {% else %} 
          {{  states.light.pc.attributes.brightness | int - 10 }}
          {% endif %}

thx Michele

Try adding a minus sign after the > like so brightness: >-

Ok thanks tonight I try and let you know.
Michele

Thanks, solved with this automation that posted “madrian”

- id: micube_brightness_rotate
  alias: "MiCube rotate - Master lights"
  initial_state: 'on'
  condition:
    - condition: state
      entity_id: light.yeelight_lights_2
      state: 'on'
  trigger:
    platform: event
    event_type: xiaomi_aqara.cube_action
    event_data:
      entity_id: binary_sensor.cube_158d00027d8e39
      action_type: rotate
  action:
    - service: light.turn_on
      data_template:
        entity_id: light.yeelight_lights_2
        brightness: >
              {% set state = (state_attr('light.yeelight_lights_2','brightness') + trigger.event.data.action_value|int) -%}
              {%-  if state > 255 -%}
                 {%- set state  = 255 -%}
              {%-  elif state < 0 -%}
                 {%- set state  = 0 -%}
              {%- endif %}
              {{ state }}
1 Like

I often wondered about what those signs after brightness do?

Could you explain them?

Could you share that automation, please?

Hi,

I guess I already did it somewhere. But here is it:

automation:
  - id: cube_branco_rotate
    alias: cubo branco rotate
    trigger:
      platform: event
      event_type: xiaomi_aqara.cube_action
      event_data:
        entity_id: binary_sensor.cube_xxxxxx
        action_type: rotate
    action:
      - service: script.turn_on
        data_template:
          entity_id: >-
            {% if trigger.event.data.action_value | float > 18  %}
              script.volupplus
            {% elif trigger.event.data.action_value | float > 0  %}
              script.volup
            {% elif trigger.event.data.action_value | float < -18  %}
              script.voldownplus
            {% elif trigger.event.data.action_value | float < 0  %}
              script.voldown
            {% endif %}

The scripts just calls the service remote.send_command. (twice in the “plus” ones)

1 Like

Thanks, I had something similar.

Could someone tell my why my template fails with < -50 elif?

Changing it to the code from @clyra and it works, but I can’t see why -50 fails at mine, the other 3 worked.

- service: script.turn_on 
  data_template:
    entity_id: >-
      {% set angle = trigger.payload_json.angle|float -%}
      {%-  if angle > 50 -%}
        script.ph_vol_plus_2
      {%-  elif angle > 0 -%}
        script.ph_vol_plus_1
      {%-  elif angle < 0 -%}
        script.ph_vol_down_1
      {%-  elif angle < -50 -%}
        script.ph_vol_down_2
      {%- endif %}

are you sure that the cube can reach the -50 value? I’m not sure if the cube reports degrees or something else.

Yes, I’m sure about that. I checked it in the states.

No more ideas why this did not work, maybe @petro sees the mistake?