HomeAutomation

Light control using an Aqara Wireless Remote Switch with Home Assistant and Node-RED

Home automation is nice, sending commands with your voice is very cool, but sometimes, especially at night, you might want to just use traditional methods like a wall switch. You can do it very easily without compromising your cool voice controls, and you can also customize the way it works to suit your needs!

smart_light

Let’s start, this is what you need:

The Aqara Wireless Remote Switch is a switch you can place anywhere because it doesn’t need any wire, it works with a small battery which will last a very long time. To make the following configuration you need to use the double rocker one: it has a lot of different click interactions you can customize.

This is the configuration you can have using the Node-RED flow shown in this post:

  • Left click: turn on/off the lights (toggle)
  • Right click: switch between a predefined set of colors
  • Left long click: decrease brightness
  • Right long click: increase brightness

This Node-RED flow should be pretty straightforward, anyway, let’s have some more details.

The first node is an event state node which reacts to the changes of the Aqara Switch: it can have different values like left, right, left_long, right_long, etc. Home Assistant detects it as a sensor.

The second node is a switch used to take different actions based on the type of click done on the Aqara switch.

Left Click scenario

A service call to toggle the lights, very easy!

Right Click scenario

This is the most interesting part, the state machine node! It is used to create a finite state machine of the colors and transitions you want the lights to have. Unfortunately, I couldn’t find a way to make the state machine move to the next state based only on the current one, without taking care of the input value, so I managed to achieve it with a workaround!

After the state machine node there is a switch node which checks if the state machine already did its transition checking a value which is put into the payload object in the following function node. This function node also put the current state machine value as payload of the message, so the state machine can correctly move. In doing so, the second time the flow will go to another function node which generates the light settings based on the value the state machine now has. Then, the last node simply sets this configuration to the lights.

Left long click scenario

A current state node which gets the current brightness of the light followed by a function node which calculates the increased brightness value. In the function node you can customize the brightness interval and the minimum brightness you would like to reach. The last node is a service call which sets the new brightness to the light.

Right long click scenario

Same as the left long click scenario but this time the light brightness is increased, so the function node calculates the increased value the light will have. Customization for brightness interval and maximum brightness are available here as well.

Enjoy your wireless switch!

smart switch node red flow
[
    {
        "id": "63038ca5.043d84",
        "type": "server-state-changed",
        "z": "ebd2b060.28c27",
        "name": "SmartSwitch1",
        "server": "b0807fb3.bda6d",
        "version": 1,
        "entityidfilter": "sensor.smartswitch1_click",
        "entityidfiltertype": "exact",
        "outputinitially": false,
        "state_type": "str",
        "haltifstate": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "outputs": 1,
        "output_only_on_state_change": true,
        "x": 110,
        "y": 160,
        "wires": [
            [
                "e4f033f6.02139"
            ]
        ]
    },
    {
        "id": "e4f033f6.02139",
        "type": "switch",
        "z": "ebd2b060.28c27",
        "name": "click is",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "left",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "right",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "left_long",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "right_long",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 4,
        "x": 290,
        "y": 160,
        "wires": [
            [
                "c92d98e8.8de858"
            ],
            [
                "bbcdb78.3712348"
            ],
            [
                "752f2116.e5b66"
            ],
            [
                "a10c6932.4ae3a8"
            ]
        ]
    },
    {
        "id": "c92d98e8.8de858",
        "type": "api-call-service",
        "z": "ebd2b060.28c27",
        "name": "toggle living room lights",
        "server": "b0807fb3.bda6d",
        "version": 1,
        "service_domain": "light",
        "service": "toggle",
        "entityId": "group.living_room_lights",
        "data": "",
        "dataType": "json",
        "mergecontext": "",
        "output_location": "",
        "output_location_type": "none",
        "mustacheAltTags": false,
        "x": 530,
        "y": 60,
        "wires": [
            []
        ]
    },
    {
        "id": "515a6b84.e21c54",
        "type": "api-call-service",
        "z": "ebd2b060.28c27",
        "name": "set brightness to living room lights",
        "server": "b0807fb3.bda6d",
        "version": 1,
        "service_domain": "light",
        "service": "turn_on",
        "entityId": "group.living_room_lights",
        "data": "",
        "dataType": "json",
        "mergecontext": "",
        "output_location": "",
        "output_location_type": "none",
        "mustacheAltTags": false,
        "x": 1200,
        "y": 220,
        "wires": [
            []
        ]
    },
    {
        "id": "752f2116.e5b66",
        "type": "api-current-state",
        "z": "ebd2b060.28c27",
        "name": "",
        "server": "b0807fb3.bda6d",
        "version": 1,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "override_topic": false,
        "entity_id": "light.left_living_room",
        "state_type": "str",
        "state_location": "data",
        "override_payload": "msg",
        "entity_location": "data",
        "override_data": "msg",
        "blockInputOverrides": false,
        "x": 560,
        "y": 200,
        "wires": [
            [
                "91a6b4b5.c19558"
            ]
        ]
    },
    {
        "id": "ba574398.cc6a",
        "type": "function",
        "z": "ebd2b060.28c27",
        "name": "calculate increased brightness",
        "func": "const BRIGHTNESS_INTERVAL = 100;\nconst BRIGHTNESS_MAX = 255;\n\nlet brightness = msg.data.attributes.brightness;\nlet entityId = msg.data.entity_id;\nbrightness = brightness + BRIGHTNESS_INTERVAL\nif (brightness > BRIGHTNESS_MAX) {\n    brightness = BRIGHTNESS_MAX\n}\nmsg.payload = {\n    \"data\": {\n        \"brightness\":brightness\n        \n    }\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 870,
        "y": 260,
        "wires": [
            [
                "515a6b84.e21c54"
            ]
        ]
    },
    {
        "id": "91a6b4b5.c19558",
        "type": "function",
        "z": "ebd2b060.28c27",
        "name": "calculate decreased brightness",
        "func": "const BRIGHTNESS_INTERVAL = 100;\nconst BRIGHTNESS_MIN = 1;\n\nlet brightness = msg.data.attributes.brightness;\nlet entityId = msg.data.entity_id;\nbrightness = brightness - BRIGHTNESS_INTERVAL\nif (brightness < BRIGHTNESS_MIN) {\n    brightness = BRIGHTNESS_MIN\n}\nmsg.payload = {\n    \"data\": {\n        \"brightness\":brightness\n        \n    }\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 870,
        "y": 200,
        "wires": [
            [
                "515a6b84.e21c54"
            ]
        ]
    },
    {
        "id": "a10c6932.4ae3a8",
        "type": "api-current-state",
        "z": "ebd2b060.28c27",
        "name": "",
        "server": "b0807fb3.bda6d",
        "version": 1,
        "outputs": 1,
        "halt_if": "",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "override_topic": false,
        "entity_id": "light.left_living_room",
        "state_type": "str",
        "state_location": "data",
        "override_payload": "msg",
        "entity_location": "data",
        "override_data": "msg",
        "blockInputOverrides": false,
        "x": 560,
        "y": 260,
        "wires": [
            [
                "ba574398.cc6a"
            ]
        ]
    },
    {
        "id": "bbcdb78.3712348",
        "type": "state-machine",
        "z": "ebd2b060.28c27",
        "name": "bulb color state",
        "triggerProperty": "payload",
        "triggerPropertyType": "msg",
        "stateProperty": "topic",
        "statePropertyType": "msg",
        "outputStateChangeOnly": false,
        "throwException": false,
        "states": [
            "white",
            "yellow"
        ],
        "transitions": [
            {
                "name": "white",
                "from": "white",
                "to": "yellow"
            },
            {
                "name": "yellow",
                "from": "yellow",
                "to": "white"
            }
        ],
        "x": 540,
        "y": 140,
        "wires": [
            [
                "10c6a2fd.57b7dd"
            ]
        ]
    },
    {
        "id": "f1efc70d.5de9e8",
        "type": "api-call-service",
        "z": "ebd2b060.28c27",
        "name": "set color to living room lights",
        "server": "b0807fb3.bda6d",
        "version": 1,
        "service_domain": "light",
        "service": "turn_on",
        "entityId": "group.living_room_lights",
        "data": "",
        "dataType": "json",
        "mergecontext": "",
        "output_location": "",
        "output_location_type": "none",
        "mustacheAltTags": false,
        "x": 1340,
        "y": 120,
        "wires": [
            []
        ]
    },
    {
        "id": "10c6a2fd.57b7dd",
        "type": "switch",
        "z": "ebd2b060.28c27",
        "name": "has state ben processed",
        "property": "data.attributes.state_machine_processed",
        "propertyType": "msg",
        "rules": [
            {
                "t": "true"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 770,
        "y": 140,
        "wires": [
            [
                "41cecb0c.bbfbe4"
            ],
            [
                "f4044d2d.8f0a6"
            ]
        ]
    },
    {
        "id": "f4044d2d.8f0a6",
        "type": "function",
        "z": "ebd2b060.28c27",
        "name": "set topic as payload",
        "func": "msg.payload = msg.topic\nmsg.data = {\n    \"attributes\": {\n        \"state_machine_processed\" : true\n    }\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 1040,
        "y": 140,
        "wires": [
            [
                "bbcdb78.3712348"
            ]
        ]
    },
    {
        "id": "41cecb0c.bbfbe4",
        "type": "function",
        "z": "ebd2b060.28c27",
        "name": "create color data as payload",
        "func": "whitePayload = {\n    \"data\": {\n        \"kelvin\": 6000\n    }\n}\n\nyellowPayload = {\n    \"data\": {\n        \"kelvin\": 3000\n    }\n}\n\nlet payloadToUse;\nswitch(msg.topic) {\n    case \"white\": \n        payloadToUse = whitePayload;\n        break;\n    case \"yellow\":\n        payloadToUse = yellowPayload;\n        break;\n    default:\n    \n        break;\n}\n\nmsg.payload = payloadToUse;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 1060,
        "y": 100,
        "wires": [
            [
                "f1efc70d.5de9e8"
            ]
        ]
    },
    {
        "id": "b0807fb3.bda6d",
        "type": "server",
        "z": "",
        "name": "Home Assistant"
    }
]