Pure fun with Alexa and Alexa Skills

Rich - how did you specify a time to turn something on or off ??
I've tried time and when.
ecolect_time
time_time

ecolect_time
I've used {when} as in the Help and it throws an error.
ecolect_error

I havenā€™t experimented with specific times. Iā€™ve only used an amount of time. So, for example, turn on the {item} for {number} {units} could be "turn on the light for ten minutes."

Thanks for the response.
I've tried all sorts of combinations and can't get the {time} part to work.
Even the example given with the node dosen't work for {time}
I'll have to contact Csongor Varga and see if he can help.

@dynamicdave - For what itā€™s worth if you look at my earlier exampleā€™s from the other day, I had to enumerate all the numbers from text to integers in order for everything to work the way I wanted. In fact, enumeration seems to work best regardless of the variable you're working with. One weird quirk though, "sixty" when turned into an integer ends up becoming "60ty." So far it's the only number I've found that does that.

Solved! After getting some sleep and taking another look at my function node I figured out the problem. The doorOpenCount variable wasn't pointed to the correct place and that seems to have caused the looping. Once I corrected it (as shown below), I'm getting exactly the output I'd expect based on the specific doors open.

Correct

var doorOpenCount = msg.payload.doors.openCount;

Incorrect

var doorOpenCount = msg.payload.doorsOpenCount;

One simple period between "doors" and "openCount." :face_with_raised_eyebrow::joy:

2 Likes

I think we have all been there and done that.

@dynamicdave - Got the time part working within the sample flow. The trick seems to be enumeration. Making it work with Alexa is a whole other can of worms. :wink:

[
    {
        "id": "8a3e1a9f94917518",
        "type": "tab",
        "label": "Flow 1",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "1c806a0702e0e299",
        "type": "group",
        "z": "8a3e1a9f94917518",
        "style": {
            "stroke": "#000000",
            "fill": "#bfdbef",
            "label": true,
            "color": "#000000"
        },
        "nodes": [
            "d94b660d4c06097b",
            "3af5c72edc68cbfd",
            "c58b25d2670efd34",
            "330bf3a3a455c4e2",
            "9818eab5d811720a",
            "9c9deb329865151a",
            "5e9982c26e9ea305",
            "4092a62683178451",
            "e5f738f8c25264ef",
            "7ffe40df25ea571e",
            "76c06ce744c5354b",
            "515e4e3247286d8e",
            "c9a8629d3c52bf71",
            "1478d84283243b35",
            "17bd7d1eb6724ac2",
            "ec833b1127481074",
            "0eea39d7d70d4aa4",
            "23507e15d9bffcf1",
            "937c14576fc208d1",
            "430e3f0bf129ca7d",
            "268e9020e35ad779",
            "6d6d252e7e282d77",
            "31d16e7e6fef907e",
            "fa6b1cd57ec842ad",
            "5860e5482ab8e343",
            "df7e1bec7a8668ba"
        ],
        "x": -6,
        "y": 59,
        "w": 1332,
        "h": 842
    },
    {
        "id": "fa6b1cd57ec842ad",
        "type": "junction",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "x": 580,
        "y": 220,
        "wires": [
            [
                "d94b660d4c06097b"
            ]
        ]
    },
    {
        "id": "5860e5482ab8e343",
        "type": "junction",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "x": 760,
        "y": 460,
        "wires": [
            [
                "9818eab5d811720a",
                "330bf3a3a455c4e2",
                "9c9deb329865151a",
                "4092a62683178451",
                "e5f738f8c25264ef",
                "7ffe40df25ea571e",
                "6d6d252e7e282d77"
            ]
        ]
    },
    {
        "id": "df7e1bec7a8668ba",
        "type": "junction",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "x": 620,
        "y": 800,
        "wires": [
            [
                "937c14576fc208d1",
                "31d16e7e6fef907e"
            ]
        ]
    },
    {
        "id": "d94b660d4c06097b",
        "type": "ecolect",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "name": "Language Processing",
        "topics": [
            {
                "name": "switch",
                "phrases": "turn {state} the {device}\nturn the {device} {state}\nturn the {device} {state} in {timelapse} {timeunit}\nturn {state} the {device} in {timelapse} {timeunit}\nturn {state} the {device} at {hour} {minute}{ampm}\nturn the {device} {state} at {hour} {minute}{ampm}\nturn {state} the {device} at {hour} {minute} {ampm}\nturn the {device} {state} at {hour} {minute} {ampm}",
                "values": [
                    {
                        "name": "device",
                        "type": "enumeration",
                        "enumerations": [
                            "christmas light",
                            "garden light",
                            "planter"
                        ]
                    },
                    {
                        "name": "state",
                        "type": "enumeration",
                        "enumerations": [
                            "off",
                            "on"
                        ]
                    },
                    {
                        "name": "timelapse",
                        "type": "integer",
                        "enumerations": []
                    },
                    {
                        "name": "timeunit",
                        "type": "enumeration",
                        "enumerations": [
                            "minute",
                            "minutes",
                            "hour",
                            "hours"
                        ]
                    },
                    {
                        "name": "hour",
                        "type": "enumeration",
                        "enumerations": [
                            "1:",
                            "2:",
                            "3:",
                            "4:",
                            "5:",
                            "6:",
                            "7:",
                            "8:",
                            "9:",
                            "10:",
                            "11:",
                            "12:"
                        ]
                    },
                    {
                        "name": "minute",
                        "type": "enumeration",
                        "enumerations": [
                            "00",
                            "01",
                            "02",
                            "03",
                            "04",
                            "05",
                            "06",
                            "07",
                            "08",
                            "09",
                            "10",
                            "11",
                            "12",
                            "13",
                            "14",
                            "15",
                            "16",
                            "17",
                            "18",
                            "19",
                            "20",
                            "21",
                            "22",
                            "23",
                            "24",
                            "25",
                            "26",
                            "27",
                            "28",
                            "29",
                            "30",
                            "31",
                            "32",
                            "33",
                            "34",
                            "35",
                            "36",
                            "37",
                            "38",
                            "39",
                            "40",
                            "41",
                            "42",
                            "43",
                            "44",
                            "45",
                            "46",
                            "47",
                            "48",
                            "49",
                            "50",
                            "51",
                            "52",
                            "53",
                            "54",
                            "55",
                            "56",
                            "57",
                            "58",
                            "59"
                        ]
                    },
                    {
                        "name": "ampm",
                        "type": "enumeration",
                        "enumerations": [
                            "AM",
                            "am",
                            "a",
                            "PM",
                            "pm",
                            "p"
                        ]
                    }
                ]
            },
            {
                "name": "query",
                "phrases": "what is the state of the {device}?\nis the {device} {state}?\ntell me the state of the {device}?",
                "values": [
                    {
                        "name": "device",
                        "type": "enumeration",
                        "enumerations": [
                            "christmas light",
                            "garden tree",
                            "planter"
                        ]
                    },
                    {
                        "name": "state",
                        "type": "enumeration",
                        "enumerations": [
                            "on",
                            "off"
                        ]
                    }
                ]
            }
        ],
        "outputs": 3,
        "x": 500,
        "y": 460,
        "wires": [
            [
                "5860e5482ab8e343"
            ],
            [
                "5860e5482ab8e343"
            ],
            [
                "df7e1bec7a8668ba"
            ]
        ]
    },
    {
        "id": "3af5c72edc68cbfd",
        "type": "inject",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "name": "turn off the christmas light",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": "",
        "topic": "",
        "payload": "turn off the christmas light",
        "payloadType": "str",
        "x": 150,
        "y": 100,
        "wires": [
            []
        ]
    },
    {
        "id": "c58b25d2670efd34",
        "type": "inject",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "name": "turn the christmas light off",
        "repeat": "",
        "crontab": "",
        "once": false,
        "topic": "",
        "payload": "turn the christmas light off",
        "payloadType": "str",
        "x": 150,
        "y": 140,
        "wires": [
            [
                "fa6b1cd57ec842ad"
            ]
        ]
    },
    {
        "id": "330bf3a3a455c4e2",
        "type": "function",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "name": "Topic",
        "func": "msg.payload = msg.topic;\nnode.status({fill:\"blue\",shape:\"ring\",text:\"Value: \"+msg.topic});\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 970,
        "y": 400,
        "wires": [
            [
                "c9a8629d3c52bf71"
            ]
        ]
    },
    {
        "id": "9818eab5d811720a",
        "type": "function",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "name": "Device",
        "func": "var value = msg.values.device;\nif (value===undefined) {\n    node.status({fill:\"red\",shape:\"ring\",text:\"No value\"});\n    msg.payload = \"[No value]\";\n} else {\n    node.status({fill:\"blue\",shape:\"ring\",text:\"Value: \"+value});\n    msg.payload = value;\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 970,
        "y": 460,
        "wires": [
            [
                "1478d84283243b35"
            ]
        ]
    },
    {
        "id": "9c9deb329865151a",
        "type": "function",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "name": "State",
        "func": "var value = msg.values.state;\nif (value===undefined) {\n    node.status({fill:\"red\",shape:\"ring\",text:\"No value\"});\n    msg.payload = \"[No value]\";\n} else {\n    node.status({fill:\"blue\",shape:\"ring\",text:\"Value: \"+value});\n    msg.payload = value;\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 970,
        "y": 520,
        "wires": [
            [
                "17bd7d1eb6724ac2"
            ]
        ]
    },
    {
        "id": "5e9982c26e9ea305",
        "type": "inject",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "name": "turn the christmas light off in 10 minutes",
        "repeat": "",
        "crontab": "",
        "once": false,
        "topic": "",
        "payload": "turn the christmas light off in 10 minutes",
        "payloadType": "str",
        "x": 200,
        "y": 180,
        "wires": [
            [
                "fa6b1cd57ec842ad"
            ]
        ]
    },
    {
        "id": "4092a62683178451",
        "type": "function",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "name": "Time lapse",
        "func": "var value = msg.values.timelapse;\nif (value===undefined) {\n    node.status({fill:\"red\",shape:\"ring\",text:\"No value\"});\n    msg.payload = \"[No value]\";\n} else {\n    node.status({fill:\"blue\",shape:\"ring\",text:\"Value: \"+value.value});\n    msg.payload = value.value;\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 990,
        "y": 580,
        "wires": [
            [
                "ec833b1127481074"
            ]
        ]
    },
    {
        "id": "e5f738f8c25264ef",
        "type": "function",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "name": "Time unit",
        "func": "var value = msg.values.timeunit;\nif (value===undefined) {\n    node.status({fill:\"red\",shape:\"ring\",text:\"No value\"});\n    msg.payload = \"[No value]\";\n} else {\n    node.status({fill:\"blue\",shape:\"ring\",text:\"Value: \"+value});\n    msg.payload = value;\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 980,
        "y": 640,
        "wires": [
            [
                "0eea39d7d70d4aa4"
            ]
        ]
    },
    {
        "id": "7ffe40df25ea571e",
        "type": "function",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "name": "Time",
        "func": "var hour = msg.values.hour;\nvar minute = msg.values.minute;\nvar ampm = msg.values.ampm;\nif (hour===undefined) {\n    node.status({fill:\"red\",shape:\"ring\",text:\"No value\"});\n    msg.payload = \"[No value]\";\n} else {\n    node.status({fill:\"blue\",shape:\"ring\",text:\"Value: \"+hour+minute+ampm});\n    msg.payload = hour+minute+ampm;\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 970,
        "y": 700,
        "wires": [
            [
                "23507e15d9bffcf1"
            ]
        ]
    },
    {
        "id": "76c06ce744c5354b",
        "type": "inject",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "name": "turn the garden light on at 6:30",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": "",
        "topic": "",
        "payload": "turn the garden light on at 6:30 pm",
        "payloadType": "str",
        "x": 170,
        "y": 220,
        "wires": [
            [
                "fa6b1cd57ec842ad"
            ]
        ]
    },
    {
        "id": "515e4e3247286d8e",
        "type": "ui_text_input",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "name": "",
        "label": "Phrase",
        "tooltip": "",
        "group": "70e4bcad.afdeb4",
        "order": 0,
        "width": 0,
        "height": 0,
        "passthru": true,
        "mode": "text",
        "delay": "0",
        "topic": "",
        "sendOnBlur": true,
        "className": "",
        "topicType": "str",
        "x": 124.42858014787942,
        "y": 526.8571690150666,
        "wires": [
            [
                "d94b660d4c06097b"
            ]
        ]
    },
    {
        "id": "c9a8629d3c52bf71",
        "type": "ui_text",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "group": "70e4bcad.afdeb4",
        "order": 0,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "Topic",
        "format": "{{msg.payload}}",
        "layout": "row-spread",
        "x": 1170,
        "y": 400,
        "wires": []
    },
    {
        "id": "1478d84283243b35",
        "type": "ui_text",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "group": "70e4bcad.afdeb4",
        "order": 0,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "Device",
        "format": "{{msg.payload}}",
        "layout": "row-spread",
        "x": 1170,
        "y": 460,
        "wires": []
    },
    {
        "id": "17bd7d1eb6724ac2",
        "type": "ui_text",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "group": "70e4bcad.afdeb4",
        "order": 0,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "State",
        "format": "{{msg.payload}}",
        "layout": "row-spread",
        "x": 1170,
        "y": 520,
        "wires": []
    },
    {
        "id": "ec833b1127481074",
        "type": "ui_text",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "group": "70e4bcad.afdeb4",
        "order": 0,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "Time lapse:",
        "format": "{{msg.payload}}",
        "layout": "row-spread",
        "className": "",
        "x": 1190,
        "y": 580,
        "wires": []
    },
    {
        "id": "0eea39d7d70d4aa4",
        "type": "ui_text",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "group": "70e4bcad.afdeb4",
        "order": 0,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "Time unit:",
        "format": "{{msg.payload}}",
        "layout": "row-spread",
        "x": 1180,
        "y": 640,
        "wires": []
    },
    {
        "id": "23507e15d9bffcf1",
        "type": "ui_text",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "group": "70e4bcad.afdeb4",
        "order": 0,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "Time:",
        "format": "{{msg.payload}}",
        "layout": "row-spread",
        "x": 1170,
        "y": 700,
        "wires": []
    },
    {
        "id": "937c14576fc208d1",
        "type": "function",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "name": "Collect unrecognized commands",
        "func": "// Get the previously stored commands\nvar temp = context.get(\"commands\");\nif (temp===undefined) {\n    temp = [];\n}\n\nif (msg.topic===\"--ClearList--\") {\n    // Clear the current list\n    temp = [];\n} else {\n    // Add the new one \n    temp.push(msg.payload);\n}\ncontext.set(\"commands\",temp);\n\n\n//Format the output\nmsg.payload = \"\";\nfor (var i=0; i<temp.length; i++) {\n    msg.payload += temp[i] + \"<br/>\";\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 830,
        "y": 860,
        "wires": [
            [
                "430e3f0bf129ca7d"
            ]
        ]
    },
    {
        "id": "430e3f0bf129ca7d",
        "type": "ui_template",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "group": "88fb57e1.106f98",
        "name": "Log output",
        "order": 2,
        "width": 0,
        "height": 0,
        "format": "<div ng-bind-html=\"msg.payload\" height=\"600\" style=\"height: 600px;\"><br/></div>",
        "storeOutMessages": true,
        "fwdInMessages": true,
        "resendOnRefresh": false,
        "templateScope": "local",
        "className": "",
        "x": 1230,
        "y": 860,
        "wires": [
            []
        ]
    },
    {
        "id": "268e9020e35ad779",
        "type": "ui_button",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "name": "",
        "group": "88fb57e1.106f98",
        "order": 1,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Clear List",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "--ClearList--",
        "x": 504.4285801478794,
        "y": 821.4285714285706,
        "wires": [
            [
                "937c14576fc208d1"
            ]
        ]
    },
    {
        "id": "6d6d252e7e282d77",
        "type": "debug",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "name": "debug 887",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "true",
        "targetType": "full",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 990,
        "y": 340,
        "wires": []
    },
    {
        "id": "31d16e7e6fef907e",
        "type": "debug",
        "z": "8a3e1a9f94917518",
        "g": "1c806a0702e0e299",
        "name": "debug 888",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "true",
        "targetType": "full",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 750,
        "y": 800,
        "wires": []
    },
    {
        "id": "70e4bcad.afdeb4",
        "type": "ui_group",
        "name": "Test Suite",
        "tab": "4711038f.e5a60c",
        "order": 1,
        "disp": true,
        "width": "6"
    },
    {
        "id": "88fb57e1.106f98",
        "type": "ui_group",
        "name": "Unrecognized Commands",
        "tab": "4711038f.e5a60c",
        "order": 2,
        "disp": true,
        "width": "12"
    },
    {
        "id": "4711038f.e5a60c",
        "type": "ui_tab",
        "name": "Ecolect",
        "icon": "mic",
        "disabled": false,
        "hidden": false
    }
]
2 Likes

Well as said now several times: without a proper blueskill catch phrase for Alexa the fancy ecolect node does not make sense at all for me.

@haegar33 - I've been using ecolect for several weeks now. I'm certainly no expert, but I'd be happy to try to answer any questions you have, if I can.

Strangely, I discovered a bug in my light and fan flows today that should have not allowed my lights and celling fans to be controlled with the ecolect node without the Alexa blueprint. I didn't realize it until I tested an exhaust fan and it didn't work. So, for some reason lights and ceiling fans must be processed by Alexa differently than the exhaust fans. My guess is that the specific products I'm using the automate the different fans are integrated into node-red via different methods (alexa vs. hubitat). Anyway, since that isn't how I want to use them (at the moment) I fixed it with a simple junction node. But I was quite surprised the flows worked at all once I found the problem. So, apparently, there is still some serious functionality with Alexa using ecolect without the blueprints.

Never mind. Apparently you dont understand my problem and you are not able to provide the setup of your Alexa Blueskills. I am not interested in Ecolect. Have fun with it!

Hi Rich,
Thanks for sharing your latest flow. It has helped me get the at {time} working by using your at {hour} {minute} method. Very creative.

1 Like

@haegar33 - Iā€™m not sure how to respond to that except to say that I am trying to be as helpful as I can be. Iā€™m not a programmer so a lot of this node-red stuff is just a matter of trial and error for me. I apologize if Iā€™m causing you frustration.

Like I mentioned in post #61, my Alexa blueprint skill is very basic and itā€™s the ecolect node that does the heavy lifting; not the blueprint skill. Here is a screen shot of the exact commands I'm using in the blueprint. I've also set Alexa to brief mode, so I don't even get the "ok" response back from her verbally, just a tone. As you can see, this isn't doing much at all. But from my debug nodes, I do know that this does stop her from giving me the "I don't understand" type responses (most of the time.)

As I mentioned in post #89, there seems to be extra processing by Alexa with lights and ceiling fans going on vs other devices that I don't quite understand. Because even with the blueprint skill she doesn't do well with "turn off the lights in the kitchen," but she always seems to work with "turn off the kitchen lights." So a lot of how the blueprint skill interacts with the entire flow is still a mystery to me.

If you take a look at the example I posted there you'll see I have used some switch nodes to stop Alexa from repeating things I donā€™t want to hear from her and function nodes to get very specific responses from her based on my queries. So the blueprint skill doesn't seem to be either the solution or the problem; it's what I'm doing with the information in Node-RED and whatever is going on inside those Alexa boxes that gets her to answer to these more complex queries. And, to be fair, sometimes she starts to tell me she doesn't understand and then interrupts herself to give me the correct response. This happens frequently on my ceiling fan speeds. So, this solution isn't 100% perfect by any means.

Getting Alexa to cooperate hasn't been a simple thing. It's a combination of several different things I'm using together that is allowing me to tell her to do things like ā€œturn on the kitchen light for five minutesā€ that makes commands like that work. That's why I posted the very large file earlier; to show how all of these components work together to accomplish this seemingly simple task. Perhaps spending some time looking those examples will help you? If you have any specific questions about that which Iā€™m capable of answering, Iā€™m happy to help. My skill level is very limited compared to many other people here though.

2 Likes

This sort of reply, to people trying to post helpful replies to your posts, will not ensure that you get replies at all.

2 Likes

Thank you! Ecloect has a lot of potential but it also has some weird quirks. Seems like it's a balancing act to figure out those two aspects. :joy:

Sorry for my frustration about this topic where after asking the same question 4 times people still seem to misunderstand my specific problem. I can see now(!) from your blueskill phrases that your setup is not much different from mine. And you also get a "I dont understand" response from Alexa if you extend these phrases with additional command words.

I dont think these blueprint phrases are really a mystery. You define the questions and Alexa will only react to each phrase if you speak it precisley as defined. Thats it. And thats why I am so surprised that you can add more flexibly after your words have already been processed by Alexa.

I will take a look at your setup in particular about your "switch nodes" to stop Alexa. So you basically say "shut up" to your Alexa device before it can finish its "I dont understand you.." sentence? So thats a kind of workaround for this problem?

@haegar33 - No worries. I've been so frustrated with Alexa I've wanted to bundle up all 11 of them and drown them in the river a time or two.

So there are really a handful of ways I keep Alexa's silly responses at bay. The first is to set brief mode on each of your Alexa devices. This allows her to just reply with a tone when you set the response to "ok" in your blueprint skill.

Next, I use the following switch to parse her responses back to node-red so that she doesn't keep repeating stuff. This is an updated version that helps a lot with stoping her from repeating herself.

[{"id":"ceb0085438818f56","type":"switch","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"Filter out Alexa Responses","property":"payload.conversionDetails.CUSTOMER_TRANSCRIPT","propertyType":"msg","rules":[{"t":"nnull"}],"checkall":"false","repair":false,"outputs":1,"x":920,"y":2140,"wires":[["842e92730dee4803"]]}]

Of course, I also use ecolect to further process the commands which are then diverted by more switch nodes: 1, to function nodes to tell Alexa what to say and when to say it; 2, to my own version of Alexa saying "I don't understand what you're saying"; and 3, to actually have node-red do the thing I told her to do.

By diverting the unknown commands to a specific Alexa response, I can then go back into ecolect and refine my commands to lessen the chance of her doing her version of "I don't understand" all the time. I think the reason this works (and I could be totally wrong here) is that ecolect is asking Alexa to process the verbal info locally rather than her going out to the mothership on line. Sometimes she will start to say she doesn't understand, but then she will stop herself and respond as expected. I've also seen this behavior with blueprints.

I've attached a simplified version of all of this to (hopefully) make it easier to separate those parts from the specific mess I've made in node-red. The function nodes work from a global array that has the state of each contact sensor set in real time as they are open or closed.

Then, with the commands I've set up in blueprints ("status report on open doors" or "status report on open windows") I get back just the doors or windows that have open contact sensors.

My flows that set times for how long to keep a light or fan on have a bunch more switching to divert the command where I want it. They are significantly more difficult to follow since there is so much happening and I'm using a lot of custom nodes and functions to handling everything. Happy to share those too if you'd like, but they are very similar to what I posted a few days ago.

Anyway, here is the simpler flow of the bunch... (Thank you @dynamicdave for the compact option info!):

[{"id":"8b37d543c7a97c54","type":"group","z":"cd5687adb333d888","name":"Status Report on Open Contact Sensors","style":{"stroke":"#0070c0","fill":"#dbcbe7","label":true,"color":"#000000"},"nodes":["8c8b981d6628a101","5a221ed4c4a363c4","af5f387f5ef406a0","cdd3d29ff2278e09","b051603854c97fd0","2dd12483734091db","c2298c241bdf2ef5","ee288cba76eacbc0","2b96a84b5fdbd0aa","f14697da19adc236","91afcd38950cc86f","0a96bf256340666e","ab5325474a5b508f","e5b2bc642334cf6f","842e92730dee4803","a51e7b08af511a4f","3be6bffb5b2a7cbf","ad9fb511aeb9add4","ceb0085438818f56","302b06e92c834c6a","a830a750a0b3c76c","d752ccef5876a6a2","70e43c2d7274e0b0","afd3c45182139884"],"x":774,"y":1919,"w":1872,"h":362},{"id":"8c8b981d6628a101","type":"change","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"set payload from summary","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.description.summary","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1240,"y":2200,"wires":[["5a221ed4c4a363c4"]]},{"id":"5a221ed4c4a363c4","type":"ecolect","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"Voice Commands for Status Reports","topics":[{"name":"Status","phrases":"status report [on] [the] {item}\ngive me a status report on {item}\n{item} status report\nreport on {item}\nstatus report which {item} are open","values":[{"name":"item","type":"enumeration","enumerations":["doors","open doors","windows","open windows"]}]}],"outputs":2,"x":1310,"y":2140,"wires":[["2b96a84b5fdbd0aa"],["2dd12483734091db"]]},{"id":"af5f387f5ef406a0","type":"switch","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"Status Reports","property":"values.item","propertyType":"msg","rules":[{"t":"cont","v":"doors","vt":"str"},{"t":"cont","v":"windows","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":1760,"y":2060,"wires":[["ab5325474a5b508f","0a96bf256340666e"],["ab5325474a5b508f","3be6bffb5b2a7cbf"]]},{"id":"cdd3d29ff2278e09","type":"debug","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"debug 897","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":1730,"y":2000,"wires":[]},{"id":"b051603854c97fd0","type":"alexa-remote-routine","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"Unknown Command Alexa Response","account":"","routineNode":{"type":"speak","payload":{"type":"regular","text":{"type":"str","value":"Sorry, can you repeat that? Sounds like you said some bull shit about reports."},"devices":{"type":"msg","value":"payload.alexa.deviceSerialNumber"}}},"x":1830,"y":2240,"wires":[[]]},{"id":"2dd12483734091db","type":"join","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":1570,"y":2240,"wires":[["b051603854c97fd0"]]},{"id":"c2298c241bdf2ef5","type":"change","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"alexa","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1220,"y":2080,"wires":[["e5b2bc642334cf6f"]]},{"id":"ee288cba76eacbc0","type":"alexa-remote-routine","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"Alexa device","account":"","routineNode":{"type":"speak","payload":{"type":"regular","text":{"type":"msg","value":"payload"},"devices":{"type":"msg","value":"device_name"}}},"x":2550,"y":2180,"wires":[[]]},{"id":"2b96a84b5fdbd0aa","type":"join","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":1570,"y":2080,"wires":[["af5f387f5ef406a0"]]},{"id":"f14697da19adc236","type":"change","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"set payload","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.status.text","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":2390,"y":2060,"wires":[["a51e7b08af511a4f"]]},{"id":"91afcd38950cc86f","type":"function","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"Open Doors","func":"var device_name = msg.payload.alexa.name;\nvar summary = msg.payload.alexa.description.summary;\nvar doorOpenCount = msg.payload.doors.openCount;\nvar stateFrontDoor = msg.payload.doors.state[0];\nvar stateSlidingGlassDoor = msg.payload.doors.state[1];\nvar stateLaundryRoomDoor = msg.payload.doors.state[2];\nvar stateGarageDoor = msg.payload.doors.state[3];\nvar stateGarageManDoor = msg.payload.doors.state[4];\n\nif ((summary != \"alexa\") && (summary != \"\")) \n{\n    if (stateFrontDoor == \"Front Door open\") \n    {\n        msg.payload = {};\n\n        msg =\n        {\n            topic: \"Front_Door\",\n            device_name: device_name,\n            payload:\n            {\n                \"status\": { text: \"the front door is open\" }\n            } \n        }\n        node.send(msg);   \n    }\n        \n\n    if (stateSlidingGlassDoor == \"Sliding Glass Door open\") \n    {\n        msg.payload = {};\n\n        msg =\n        {\n            topic: \"Sliding_Glass_Door\",\n            device_name: device_name,\n            payload:\n            {\n                \"status\":{ text: \"the sliding glass door is open\"}\n            }   \n        }\n        node.send(msg); \n    }\n\n    if (stateLaundryRoomDoor == \"Laundry Room Door open\") \n    {\n        msg.payload = {};\n\n        msg =\n        {\n            topic: \"Laundry_Room_Door\",\n            device_name: device_name,\n            payload:\n            {\n                \"status\":    { text: \"the laundry room door is open\"}\n            }\n        }\n        node.send(msg);\n    }    \n\n    if (stateGarageDoor == \"Garage Door open\") \n    {\n        msg.payload = {};\n\n        msg =\n        {\n            topic: \"Garage_Door\",\n            device_name: device_name,\n            payload:\n            {\n                \"status\":    { text: \"the garage door is open\"}\n            }\n        }\n        node.send(msg);\n    }\n    \n    if (stateGarageManDoor == \"Garage Man Door open\") \n    {\n        msg.payload = {};\n\n        msg =\n        {\n            topic: \"Garage_Man_Door\",\n            device_name: device_name,\n            payload:\n            {\n                \"status\":    { text: \"the garage man door is open\"}\n            }\n        }\n        node.send(msg);\n    }\n\n    if (doorOpenCount === 0) \n    {\n        msg.payload = {};\n\n        msg =\n        {\n            topic: \"All_Doors\",\n            device_name: device_name,\n            payload:\n            {\n                \"status\":    { text: \"all doors are closed\"}\n            }\n        }\n    node.send(msg);\n    }\n} \n    else \n    {\n        return null;\n    }","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":2210,"y":2020,"wires":[["f14697da19adc236"]]},{"id":"0a96bf256340666e","type":"change","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"","rules":[{"t":"set","p":"payload.doors","pt":"msg","to":"statusReport.doors","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":1980,"y":2020,"wires":[["91afcd38950cc86f"]]},{"id":"ab5325474a5b508f","type":"junction","z":"cd5687adb333d888","g":"8b37d543c7a97c54","x":1820,"y":1960,"wires":[["cdd3d29ff2278e09"]]},{"id":"e5b2bc642334cf6f","type":"junction","z":"cd5687adb333d888","g":"8b37d543c7a97c54","x":1460,"y":2080,"wires":[["2dd12483734091db","2b96a84b5fdbd0aa"]]},{"id":"842e92730dee4803","type":"junction","z":"cd5687adb333d888","g":"8b37d543c7a97c54","x":1080,"y":2140,"wires":[["8c8b981d6628a101","c2298c241bdf2ef5"]]},{"id":"a51e7b08af511a4f","type":"delay","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"","pauseType":"queue","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"5","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"allowrate":false,"outputs":1,"x":2490,"y":2120,"wires":[["ee288cba76eacbc0"]]},{"id":"3be6bffb5b2a7cbf","type":"change","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"","rules":[{"t":"set","p":"payload.windows","pt":"msg","to":"statusReport.windows","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":1990,"y":2100,"wires":[["ad9fb511aeb9add4"]]},{"id":"ad9fb511aeb9add4","type":"function","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"Open Windows","func":"var device_name = msg.payload.alexa.name;\nvar summary = msg.payload.alexa.description.summary;\nvar windowOpenCount = msg.payload.windows.openCount;\nvar stateKitchenWindow = msg.payload.windows.state[0];\nvar stateOfficeWindow = msg.payload.windows.state[1];\nvar stateBedroomWindow = msg.payload.windows.state[2];\nvar stateMasterBathWindow = msg.payload.windows.state[3];\nvar stateGuestRoomWindow = msg.payload.windows.state[4];\nvar stateLivingRoomEastWindow = msg.payload.windows.state[5];\nvar stateLivingRoomWestWindow = msg.payload.windows.state[6];\nvar stateDiningRoomWestWindow = msg.payload.windows.state[7];\nvar stateDiningRoomEastWindow = msg.payload.windows.state[8];\n\nif ((summary != \"alexa\") && (summary != \"\")) \n{\n    if (stateKitchenWindow == \"Kitchen Window open\") \n    {\n        msg.payload = {};\n\n        msg =\n        {\n            topic: \"Kitchen_Window\",\n            device_name: device_name,\n            payload:\n            {\n                \"status\": { text: \"the kitchen window is open\" }\n            } \n        }\n        node.send(msg);   \n    }\n        \n\n    if (stateOfficeWindow == \"Office Window open\") \n    {\n        msg.payload = {};\n\n        msg =\n        {\n            topic: \"Office_Window\",\n            device_name: device_name,\n            payload:\n            {\n                \"status\":{ text: \"the office window is open\"}\n            }   \n        }\n        node.send(msg); \n    }\n\n    if (stateBedroomWindow == \"Bedroom Window open\") \n    {\n        msg.payload = {};\n\n        msg =\n        {\n            topic: \"Bedroom_Window\",\n            device_name: device_name,\n            payload:\n            {\n                \"status\":    { text: \"the bedroom window is open\"}\n            }\n        }\n        node.send(msg);\n    }    \n\n    if (stateMasterBathWindow == \"Master Bath Window open\") \n    {\n        msg.payload = {};\n\n        msg =\n        {\n            topic: \"Master_Bath_Window\",\n            device_name: device_name,\n            payload:\n            {\n                \"status\":    { text: \"the master bath window is open\"}\n            }\n        }\n        node.send(msg);\n    }\n    \n    if (stateGuestRoomWindow == \"Guest Room Window open\") \n    {\n        msg.payload = {};\n\n        msg =\n        {\n            topic: \"Guest_Room_Window\",\n            device_name: device_name,\n            payload:\n            {\n                \"status\":    { text: \"the guest room window is open\"}\n            }\n        }\n        node.send(msg);\n    }\n\n    if (stateLivingRoomEastWindow == \"Living Room East Window open\") {\n        msg.payload = {};\n\n        msg =\n        {\n            topic: \"Living_Room_East_Window\",\n            device_name: device_name,\n            payload:\n            {\n                \"status\": { text: \"the living room east window is open\" }\n            }\n        }\n        node.send(msg);\n    }\n\n    if (stateLivingRoomWestWindow == \"Living Room West Window open\") {\n        msg.payload = {};\n\n        msg =\n        {\n            topic: \"Living_Room_West_Window\",\n            device_name: device_name,\n            payload:\n            {\n                \"status\": { text: \"the living room west window is open\" }\n            }\n        }\n        node.send(msg);\n    }\n\n    if (stateDiningRoomWestWindow == \"Dining Room West Window open\") {\n        msg.payload = {};\n\n        msg =\n        {\n            topic: \"Dining_Room_West_Window\",\n            device_name: device_name,\n            payload:\n            {\n                \"status\": { text: \"the dining room west window is open\" }\n            }\n        }\n        node.send(msg);\n    }\n\n    if (stateDiningRoomEastWindow == \"Dining Room East Window open\") {\n        msg.payload = {};\n\n        msg =\n        {\n            topic: \"Dining_Room_East_Window\",\n            device_name: device_name,\n            payload:\n            {\n                \"status\": { text: \"the dining room east window is open\" }\n            }\n        }\n        node.send(msg);\n    }\n\n    if (windowOpenCount === 0) \n    {\n        msg.payload = {};\n\n        msg =\n        {\n            topic: \"All_windows\",\n            device_name: device_name,\n            payload:\n            {\n                \"status\":    { text: \"all windows are closed\"}\n            }\n        }\n    node.send(msg);\n    }\n} \n    else \n    {\n        return null;\n    }","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":2200,"y":2100,"wires":[["f14697da19adc236"]]},{"id":"ceb0085438818f56","type":"switch","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"Filter out Alexa Responses","property":"payload.conversionDetails.CUSTOMER_TRANSCRIPT","propertyType":"msg","rules":[{"t":"nnull"}],"checkall":"false","repair":false,"outputs":1,"x":920,"y":2140,"wires":[["842e92730dee4803"]]},{"id":"302b06e92c834c6a","type":"rbe","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"","func":"rbe","gap":"","start":"","inout":"out","septopics":true,"property":"payload","topi":"topic","x":850,"y":2080,"wires":[["ceb0085438818f56"]]},{"id":"a830a750a0b3c76c","type":"alexa-remote-event","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"","account":"","event":"ws-device-activity","x":890,"y":2020,"wires":[["302b06e92c834c6a"]]},{"id":"d752ccef5876a6a2","type":"comment","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"Double Click here for specifc node info","info":"You'll need to set up your Alexa Account.\nThe Alexa nodes are from \nnode-red-contrib-alexa-remote2-applestrudel\n\nEcolect is from node-red-contrib-ecolect\n\nall other nodes are standard Node-RED nodes","x":950,"y":1960,"wires":[]},{"id":"70e43c2d7274e0b0","type":"comment","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"Setting topic here is another trick for stopping unwanted Alexa responses","info":"basically by setting the topic, it allows\nme to stop any messages I don't want leaking \nthrough at the adjacent join nodes. ","x":1340,"y":2040,"wires":[]},{"id":"afd3c45182139884","type":"comment","z":"cd5687adb333d888","g":"8b37d543c7a97c54","name":"direct specific verbal data to ecolect","info":"This node is how I send the verbal request \nand only the verbal request to ecolect","x":1260,"y":2240,"wires":[]}]```

That's easy - just select the Compact option when you use Export and Copy the flow to the clipboard.
compact_option

1 Like

Oh Rich - that looks so neat and tidy now.

Yes! Much better. Thank you! And, thank you for the inspiration for all this. Taming Alexa is a pain in the butt, but it's a fun challenge that yields some great results when it works.

This little flow has been particularly helpful with testing commands...

[{"id":"c131c2dd74b75d97","type":"group","z":"cd5687adb333d888","style":{"stroke":"#0070c0","fill":"#dbcbe7","label":true,"color":"#000000"},"nodes":["153c31c0a32dcf78","7d95339f23adc2a4","9060560e14cd4a36","6f9b23e184774ad4","7fa0a3d66068de67","93e1d730eddb5265","71e3a9607d2e7ee1","14339966fcdfc810","8b3f9ed8f0f6d4d6"],"x":768.4285801478795,"y":2339,"w":907.5714198521205,"h":202},{"id":"153c31c0a32dcf78","type":"function","z":"cd5687adb333d888","g":"c131c2dd74b75d97","name":"Collect unrecognized commands","func":"// Get the previously stored commands\nvar temp = context.get(\"commands\");\nif (temp===undefined) {\n    temp = [];\n}\n\nif (msg.topic===\"--ClearList--\") {\n    // Clear the current list\n    temp = [];\n} else {\n    // Add the new one \n    temp.push(msg.payload);\n}\ncontext.set(\"commands\",temp);\n\n\n//Format the output\nmsg.payload = \"\";\nfor (var i=0; i<temp.length; i++) {\n    msg.payload += temp[i] + \"<br/>\";\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1180,"y":2500,"wires":[["7d95339f23adc2a4"]]},{"id":"7d95339f23adc2a4","type":"ui_template","z":"cd5687adb333d888","g":"c131c2dd74b75d97","group":"88fb57e1.106f98","name":"Log output","order":2,"width":0,"height":0,"format":"<div ng-bind-html=\"msg.payload\" height=\"600\" style=\"height: 600px;\"><br/></div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","className":"","x":1580,"y":2500,"wires":[[]]},{"id":"9060560e14cd4a36","type":"ui_button","z":"cd5687adb333d888","g":"c131c2dd74b75d97","name":"","group":"88fb57e1.106f98","order":1,"width":0,"height":0,"passthru":false,"label":"Clear List","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"","payloadType":"str","topic":"--ClearList--","topicType":"str","x":854.4285801478795,"y":2461.4285714285706,"wires":[["153c31c0a32dcf78"]]},{"id":"6f9b23e184774ad4","type":"debug","z":"cd5687adb333d888","g":"c131c2dd74b75d97","name":"debug 898","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":1100,"y":2440,"wires":[]},{"id":"7fa0a3d66068de67","type":"link in","z":"cd5687adb333d888","g":"c131c2dd74b75d97","name":"Unredognized Commands","links":["220057e35ceffd56","8c341e57310f7f33","b6e327a0789e626f","e9e46d01e24115c3","e097c88cece2d890","fff19b4e971a4c71"],"x":815,"y":2420,"wires":[["93e1d730eddb5265"]]},{"id":"93e1d730eddb5265","type":"junction","z":"cd5687adb333d888","g":"c131c2dd74b75d97","x":970,"y":2440,"wires":[["153c31c0a32dcf78","6f9b23e184774ad4"]]},{"id":"71e3a9607d2e7ee1","type":"change","z":"cd5687adb333d888","g":"c131c2dd74b75d97","name":"","rules":[{"t":"move","p":"payload","pt":"msg","to":"payload.description.summary","tot":"msg"},{"t":"set","p":"payload.deviceSerialNumber","pt":"msg","to":"deviceSerialNumberGoesHere","tot":"str"},{"t":"set","p":"payload.name","pt":"msg","to":"Family Room Echo Show 8","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1140,"y":2380,"wires":[["8b3f9ed8f0f6d4d6"]]},{"id":"14339966fcdfc810","type":"ui_text_input","z":"cd5687adb333d888","g":"c131c2dd74b75d97","name":"","label":"Phrase","tooltip":"","group":"70e4bcad.afdeb4","order":0,"width":0,"height":0,"passthru":true,"mode":"text","delay":"0","topic":"","sendOnBlur":true,"className":"","topicType":"str","x":930,"y":2380,"wires":[["71e3a9607d2e7ee1"]]},{"id":"8b3f9ed8f0f6d4d6","type":"link out","z":"cd5687adb333d888","g":"c131c2dd74b75d97","name":"Phrase Out to ecloect","mode":"link","links":[],"x":1295,"y":2380,"wires":[]},{"id":"88fb57e1.106f98","type":"ui_group","name":"Unrecognized Commands","tab":"4711038f.e5a60c","order":1,"disp":true,"width":"12"},{"id":"70e4bcad.afdeb4","type":"ui_group","name":"Test Suite","tab":"4711038f.e5a60c","order":2,"disp":true,"width":"6"},{"id":"4711038f.e5a60c","type":"ui_tab","name":"Ecolect","icon":"mic","disabled":false,"hidden":false}]

I've told two of my grandsons about the Ecolect node and promised them they can have some fun working out some settings and matching phrases at the weekend (when they visit me).

1 Like