Rotate to the left or right in Xiaomi Magic Cube?

Inspired by others, sharing what I’ve ended up with so far:

  • four modes that can be operated from two cubes: Volume mode, Light brightness mode, light warmth mode, temperature mode.
  • Drop a cube and it says it’s current mode
  • shake a cube and it moves to the next mode.
  • I think I might make flip 90 toggle the current entity on/off too.
  • I haven’t implemented temperature mode yet, which will control my dumb aircon via my xiaomi IR remote

It works, but I don’t feel like having the separate automations/conditions is the most elegant implementation. I tried to do clever stuff with passing variables between automations and scripts, and various other approaches, but I couldn’t get them working.
In my config file:

input_select:
  cube_mode:
    name: 'Cube Mode'
    options:
      - volume
      - lighting levels
      - lighting warmth
      - temperature

In my automatons file

- id: '112'
  alias: Change Cube Mode
  trigger:
  - platform: event
    event_type: cube_action
    event_data:
      entity_id: binary_sensor.cube_158d0001038d22
      action_type: shake_air
  - platform: event
    event_type: cube_action
    event_data:
      entity_id: binary_sensor.cube_158d00010fd2a6
      action_type: shake_air
  action:
    - service: input_select.select_next
      entity_id: input_select.cube_mode
    - service: media_player.volume_set
      data:
        entity_id: media_player.living_room_google
        volume_level: '0.3'
    - service: tts.google_say
      data_template:
        entity_id: media_player.living_room_google
        message: '{{states.input_select.cube_mode.state}}'
- id: '121'
  alias: Say current mode
  trigger:
  - platform: event
    event_type: cube_action
    event_data:
      entity_id: binary_sensor.cube_158d0001038d22
      action_type: free_fall
  - platform: event
    event_type: cube_action
    event_data:
      entity_id: binary_sensor.cube_158d00010fd2a6
      action_type: free_fall
  action:
    - service: media_player.volume_set
      data:
        entity_id: media_player.living_room_google
        volume_level: '0.3'
    - service: tts.google_say
      data_template:
        entity_id: media_player.living_room_google
        message: '{{states.input_select.cube_mode.state}}'

- id: '120'
  alias: "Adjust Cube Lighting Levels"
  initial_state: 'on'
  trigger:
    - platform: event
      event_type: cube_action
      event_data:
        entity_id: binary_sensor.cube_158d00010fd2a6
        action_type: rotate
    - platform: event
      event_type: cube_action
      event_data:
        entity_id: binary_sensor.cube_158d0001038d22
        action_type: rotate
  action:
    - condition: state
      entity_id: input_select.cube_mode
      state: 'lighting levels'
    - service: light.turn_on  
      data_template:
        entity_id: light.living_area_lights
        brightness: >
          {%if trigger.event.data.action_value  | float > 0 %} 
          {{states.light.living_area_lights.attributes.brightness| int + 50}}
          {% else %}
          {{states.light.living_area_lights.attributes.brightness| int - 50}}
          {%endif %}
- id: '121'
  alias: "Adjust Cube Volume Levels"
  initial_state: 'on'
  trigger:
    - platform: event
      event_type: cube_action
      event_data:
        entity_id: binary_sensor.cube_158d00010fd2a6
        action_type: rotate
    - platform: event
      event_type: cube_action
      event_data:
        entity_id: binary_sensor.cube_158d0001038d22
        action_type: rotate
  action:
    - condition: state
      entity_id: input_select.cube_mode
      state: 'volume'
    - service: media_player.volume_set
      data_template:
        entity_id: media_player.the_mothership_3
        volume_level: >
          {%if trigger.event.data.action_value  | float > 0 %} 
          {{states.media_player.the_mothership_3.attributes.volume_level| float + 0.02}}
          {% else %}
          {{states.media_player.the_mothership_3.attributes.volume_level| float - 0.02}}
          {%endif %}
- id: '122'
  alias: "Adjust Cube Lighting Warmth"
  initial_state: 'on'
  trigger:
    - platform: event
      event_type: cube_action
      event_data:
        entity_id: binary_sensor.cube_158d00010fd2a6
        action_type: rotate
    - platform: event
      event_type: cube_action
      event_data:
        entity_id: binary_sensor.cube_158d0001038d22
        action_type: rotate
  action:
    - condition: state
      entity_id: input_select.cube_mode
      state: 'lighting warmth'
    - service: light.turn_on  
      data_template:
        entity_id: light.living_area_lights
        color_temp: >
          {%if trigger.event.data.action_value  | float > 0 %} 
          {{states.light.living_area_lights.attributes.color_temp| int + 100}}
          {% else %}
          {{states.light.living_area_lights.attributes.color_temp| int - 100}}
          {%endif %}
1 Like

This is working pretty well, but I got a bit sick of not being able to quickly tell what mode the cube was in (volume, lighting etc) so I changed the change mode action to ‘flip90’ and put some visual indicators on it (the modes are on the four faces that circumnavigate (?) the cube, and the two remaining faces have indicators for which direction to use to change mode (you can’t reverse direction, you have to "go all the way around).

I just used black duck tape and a whiteout pen for the prototype, but I’ll probably have to replace it with something more abrasive resistant.

1 Like

If you pick the cube up and flip it, or very slowly flip it, flip 90 won’t register.

Won’t that then make your labels incorrect?

Your idea inspired me, so I’ve got this working and I’m getting around to the other functions now :slight_smile:

An input_select to hold the devices to control:

   cube_control_devices:
    name: Cube Control Devices
    icon: mdi:cube-send
    options:
      - "media_player.hifi_pi"
      - "media_player.amp_kodi"
      - "light.tradfri_bulb_e27_cws_opal_600lm"

And for the automations:

- alias: Air Shake Changes the Device the Cube Controls
  trigger:
    platform: event
    event_type: cube_action
    event_data:
      entity_id: binary_sensor.cube_158d00010322b3
      action_type: shake_air
  action:
    - service: input_select.select_next
      entity_id: input_select.cube_control_devices


- alias: Play - Pause Media, or Toggle Tradfri Light on Tap Twice
  trigger:
    platform: event
    event_type: cube_action
    event_data:
      entity_id: binary_sensor.cube_158d00010322b3
      action_type: tap_twice
  action:
    service_template: >
      {% if states.input_select.cube_control_devices.state != "light.tradfri_bulb_e27_cws_opal_600lm" -%}
        media_player.media_play_pause
      {% else %}
        light.toggle
      {% endif %}
    data_template:
      entity_id: >
        {% if states.input_select.cube_control_devices.state == "light.tradfri_bulb_e27_cws_opal_600lm" -%}
          light.tradfri_bulb_e27_cws_opal_600lm
        {%-elif states.input_select.cube_control_devices.state == "media_player.hifi_pi" %}
          media_player.hifi_pi
        {%-else %}
          media_player.amp_kodi
        {% endif %}

I thought I could avoid using a data_template for the entity_id in the last automation, and that’s why I have the direct device names in the input_select. I haven’t worked out if that’s possible yet.

It works well nonetheless! So I’ll use rotate for Volume on the Media Players, and Brightness on the Light.

Flip90 for next track, Flip180 for previous - and those gestures for changing the colour range on the bulbs.

It’s still not super streamlined, but it’s getting there :slight_smile:

2 Likes

Yep. it’s a bit limited, but it’s all pretty manageable. Actually the bigger glaring flaw that I should have foreseen was that I have two cubes and they can’t both stay in sync if you turn one (DOH!). But with one cube, it seems to work well “most of the time”, and if it gets out of sync with where it should be then you can correct it by doing as you’ve suggested - move it very slowly etc.

It looks like the homey xiaomi integration also reports the actual orientation of the cube. This would allow for more use cases. Personally I would like to associate each of the sides with a different scene. I only have to turn it to go into sleep, away, home, tv, etc. mode.

Another option would be to have different times on each of the sides to quickly set an alarm for the next morning. Including a shake gesture to turn the alarm off.

This is a link to the Homey code:

1 Like

Has anyone been able to figure out how to transfer this code into node-red?

Does someone here use the rotate feature to dimm a hue lamp? I would be interessted in an example config. I already tried it, but did not work. Here is the code I used.

light.kugellicht is my dimmable hue bulb

- alias: Xiaomi Cube - Brightness [Rotate]
  initial_state: 'on'
  trigger:
    - platform: event
      event_type: cube_action
      event_data:
        entity_id: binary_sensor.cube_158d0002565083
        action_type: rotate
  condition:
    - condition: state
      entity_id: input_select.cubemode
      state: 'Lights'   
  action:         
    - service: light.turn_on
      data_template:
        entity_id: light.kugellicht
        brightness: >-
          {%if trigger.event.data.action_value | float > 0 %}
          {{  states.light.kugellicht.attributes.brightness | int + 50 }}
          {% else %}
          {{  states.light.kugellicht.attributes.brightness | int - 50 }}
          {% endif %}

Mine looks like this for a zwave light but it shouldn’t make any difference…

- alias: Xiaomi Cube - Brightness [Rotate]
  initial_state: 'on'
  trigger:
    - platform: event
      event_type: cube_action
      event_data:
        entity_id: binary_sensor.cube_158d000117d706
        action_type: rotate
  condition:
    - condition: state
      entity_id: input_select.cubemode
      state: 'Lights'   
  action:         
    - service: light.turn_on
      entity_id: light.zw_uplight_dimmer_level
    - service: light.turn_on
      data_template:
        entity_id: light.zw_uplight_dimmer_level
        brightness: >-
          {% if trigger.event.data.action_value | float > 0 %}
          {{  states.light.zw_uplight_dimmer_level.attributes.brightness | int + 15 }}
          {% else %}
          {{  states.light.zw_uplight_dimmer_level.attributes.brightness | int - 15 }}
          {% endif %}  

Please format your code as the big blue box above every forum post shows… then we may be able to debug your code.

1 Like

Could you confirm that light.zw_uplight_dimmer_level is the entitiy of your light?

Where can I change the cubemode?

- alias: Xiaomi Cube - Brightness [Rotate]
  initial_state: 'on'
  trigger:
    - platform: event
      event_type: cube_action
      event_data:
        entity_id: binary_sensor.cube_158d000117d706
        action_type: rotate

@h4nc the cube mode is specified in the trigger. See the last line I have quoted above. (action_type)

I can confirm when it says entity_id: light.name then that’s the entity id of the light I want to control :stuck_out_tongue: . I use this input select to control volume or brightness…

cubemode:
  name: Cube Mode
  options:
    - Music
    - Lights
    - None
  initial: Lights 
  icon: mdi:cube-outline

ahhh. I missed that ‘cubemode’ selector in your other post and went off on a tangent… That’s a really cool idea to give the cube more use. I’m going to give that a try. Thanks!

EDIT: thinking more about that cubemode idea, I might use the doubletap or something to toggle between two cubemodes for rotate :thinking:

little bit offtopic, but maybe someone here can help:

my cube entitity changed from XXXXXX to XXXXXX_2 after a reboot or maybe because of the recent update 0.77
I would look in the entity registry to see if the entity is there, but the entity registry is gone in 0.77

How can I change it back to XXXXXX or do I have to change my settings to _2

@h4nc Mine changed back after deleting ‘core.entity_registry’ in the ‘.storage’ folder, then rebooting

I didn’t find any examples about cube rotate for switches or scripts so I made one and would like to share it for those wondering

- id: cube_rotate_lounge_blinds
  alias: Z Cube Lounge Blinds [Rotate]
  trigger:
  - platform: event
    event_type: cube_action
    event_data:
      entity_id: binary_sensor.cube_158d00010fed30
      action_type: rotate
  action:
  - service_template: >
        {% if trigger.event.data.action_value | float > 0 %}
          script.1527642393137
        {% else %}
          script.1527642440936
        {% endif %}

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?).