Using Node-Red for Google Home TTS announcements and other stuff eWeLink


This is the switch. It stops the flow if the payload is null

This is the http request

No more than five replies in a row so.

@LibraSun

Tuya is as big in asia as google is in the west. They sell their api access to other companies to make it easier for companies to get there product on a stable platform. They see no money in opening their api to anyone who is not going to pay.

2 Likes

I think I follow. Does that mean Node-RED is paying for access to Tuya products? Or are you saying the opposite, that once you know the correct GET phraseology, object syntax, timing, etc. (and possess an API key), it’s trivial to send commands?

I’m still stuck wondering why Node-RED can and Vera can’t. :-/

I beleive that you have to sniff the handshake/key form your devices. I have not tried Tuya yet, but have read the instructions

Ezlo would have to do this for each client.

1 Like

On another note, you may be able to use the smartlife app (as they have added more communication functions) to send a notification push. You could then use automate/tasker on same device to forward a http request to vera.

1 Like

OK I think have found a simple solution for checking both the DeviceID of the eWeLink device and its current power state, as per your button presses in the eWeLink mobile app.

I’ve added a new Switch node called “DeviceID” in to the chain, before the Switch node “DiffuserOn” which checks if the device is turned “on” ?

This is the new Switch node:

image

I have tested this by entering the incorrect DeviceID.

If I then turn on the Diffuser device in the eWeLink mobile app, the flow does not complete and it does not turn on the “Diffuser” virtual switch in Vera.

However when the DeviceID is correctly entered, then when I turn on the Diffuser device in the eWeLink mobile app, the flow does complete and the virtual device in Vera is also turned to on.

So this tells me that this DeviceID check is working. (I think ?)

I also added a second Switch node for the OFF chain. That is exactly the same as the first “DeviceID” node in the ON chain.

image

So now I can either use the eWeLink mobile app to turn this device on or off, or I can use the virtual switch in Vera / Imperihome or I can issue a voice command to the Google Home speaker and everything works and stays in sync.

I did try installing a AND / NAND module, but I couldn’t get that working it was doing weird stuff looping.

1 Like

A simple example

[
    {
        "id": "428703f9.dabacc",
        "type": "tab",
        "label": "Flow 3",
        "disabled": false,
        "info": ""
    },
    {
        "id": "b17b5476.57a298",
        "type": "http in",
        "z": "428703f9.dabacc",
        "name": "http request from scene",
        "url": "sceneTrigger",
        "method": "get",
        "upload": false,
        "swaggerDoc": "",
        "x": 200,
        "y": 240,
        "wires": [
            [
                "3b703b98.327224"
            ]
        ]
    },
    {
        "id": "532c9cdb.e466dc",
        "type": "http response",
        "z": "428703f9.dabacc",
        "name": "http response",
        "statusCode": "",
        "headers": {},
        "x": 690,
        "y": 240,
        "wires": []
    },
    {
        "id": "3b703b98.327224",
        "type": "function",
        "z": "428703f9.dabacc",
        "name": "create response",
        "func": "msg.payload = msg.payload.test + \" a response\"\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 460,
        "y": 240,
        "wires": [
            [
                "532c9cdb.e466dc"
            ]
        ]
    }
]


View in browser
http://ip_of_node-red:1880/sceneTrigger
You can also add paramater
http://ip_of_node-red:1880/sceneTrigger?test=yes

So this is how I have been getting a Vera scene to do something in node-red.

In this example it sends a TTS to a Google Home speaker, using the node-red-contrib-cast

image

HTTP IN node:

Method is GET
URL: /whatever-you-want

image

Template Node:

Text “OK” response

image

HTTP Response node:

Status Code = 200

image

Cast Node:

Send TTS to a Google Home speaker

So in the actual Vera scene under “Also, execute the following Luup code:”

Send the http command to node-red e.g.

luup.inet.wget("http://NODE-RED-IP:1880/doorbellstatus")

Where “/doorbellstatus” = URL: /whatever-you-want

What you specified the URL as in the “http in” node.

So when you run the Vera scene the URL is sent to node-red and any associated actions in node-red will be carried out.

[
    {
        "id": "f31a24e4.03ee28",
        "type": "tab",
        "label": "Example",
        "disabled": false,
        "info": ""
    },
    {
        "id": "c527d842.2b01f8",
        "type": "http in",
        "z": "f31a24e4.03ee28",
        "name": "",
        "url": "/DoorbellStatus",
        "method": "get",
        "upload": false,
        "swaggerDoc": "",
        "x": 170,
        "y": 120,
        "wires": [
            [
                "a27eaf28.e4129",
                "7a05c16a.a6f9c"
            ]
        ]
    },
    {
        "id": "a27eaf28.e4129",
        "type": "template",
        "z": "f31a24e4.03ee28",
        "name": "OK",
        "field": "payload",
        "fieldType": "msg",
        "format": "handlebars",
        "syntax": "mustache",
        "template": "OK",
        "output": "str",
        "x": 390,
        "y": 120,
        "wires": [
            [
                "6d6b7614.f6fa78"
            ]
        ]
    },
    {
        "id": "6d6b7614.f6fa78",
        "type": "http response",
        "z": "f31a24e4.03ee28",
        "name": "",
        "statusCode": "200",
        "headers": {},
        "x": 560,
        "y": 120,
        "wires": []
    },
    {
        "id": "7a05c16a.a6f9c",
        "type": "cast-to-client",
        "z": "f31a24e4.03ee28",
        "name": "Lounge-Mini-TTS",
        "url": "",
        "contentType": "",
        "message": "There is someone at the door",
        "language": "en",
        "ip": "192.168.1.16",
        "port": "8009",
        "volume": "",
        "x": 430,
        "y": 160,
        "wires": [
            []
        ],
        "icon": "node-red-contrib-cast/google-home-mini2.svg"
    },
    {
        "id": "bc713fcb.51821",
        "type": "comment",
        "z": "f31a24e4.03ee28",
        "name": "HTTP IN Endpoint",
        "info": "",
        "x": 170,
        "y": 80,
        "wires": []
    }
]

You could improve that to make it dynamic

http://ip_of_node-red:1880/scenetrigger?TTSmessage=sometext

Then use msg.payload.TTSmessage to populate the cast message.

then in scenes with multiple triggers, use the Lua trigger code option, and put your inet.wget with individual TTSmessage. That way you could have individual messages for each trigger.

You could also add an IP param to http request and target different Minis/chromecast speakers

2 Likes

Very clever!

I would never of worked that out on my own.

I will give It a try.

1 Like

Hi

Got it working a little bit dynamically, however I don’t know how to setup an IP param to target a particular Google Home device ?

This is what I have gotten working so far, I can send dynamic TTS messages now.

HTTP IN node:

image

Function Node:

image

So in the browser testing I can add any text I want to the URL and the Lounge Mini says it out loud.

http://NODE-RED-IP:1880/scenetrigger?TTSmessage=YOUR-TEXT-HERE

But I am not sure about how to send the IP for the desired Google Home / Cast device ?

Currently as you can see in the first screen shot, I have manually assigned the IP in the Cast node.

Thanks

EDIT:

OK this is a URL with an IP param in it:

http://192.168.0.2:1880/scenetrigger?TTSmessage=TEST&IP=192.168.0.16

But I then don’t know how to pass this IP param to the Cast node etc.

EDIT2: This is from the Cast node help text:

msg.ip / msg.payload.ip the IP address of the device to cast

Could you copy the cast nodes info page from the side bar in node-red, as i do not have thenode installed on my pallete.

image

INPUTS

payload - string | object

the payload of the message to publish.

ip - ip-address

the IP address of the device to cast the media. Could also be defined in the configuration of the node.

port - number

the port of the device (if not given default 8009 will be used). Could also be defined in the configuration of the node.

url - string

url to a media file which should be cast to the cast device. For a chromecast this should be a media or a video file. For a Google Home device without a display this could only be an audio file.

imageUrl - string

url to a image file which represents the artwork for the url which should be cast to the cast device. For a chromecast this should be an image file. For a Google Home device without a display this is irrelevant.

contentType - string

the content type of the file in the url. This property is required if a url is given. Could also be defined in the configuration of the node.

message - string

a text which should be send to the google tts engine to convert to a mp3 file.

language - string

the language which should be used for converting the message to the media file.

volume - number 0-100

will set the device volume to this level. (if left blank, the volume will be unchanged.)

lowerVolumeLimit - number 0-100

will set the volume to this value, if the current volume is below this value.

upperVolumeLimit - number 0-100

will set the volume to this value, if the current volume is above this limit.

muted - boolean

the volume should be muted if set to false, otherwise the volume will be unmuted.

status - boolean

if this property is set to true, only the status will be given as output and nothing else will be done.

OUTPUTS

  1. Standard output

payload - string

the given status result by the cast2-client library.

DETAILS

there are 3 different use cases:

  1. play a media file
    For this the url and the content type needs to be specified. Thus can be done in the configuration or passed as a message property msg.url and msg.contentType or give a payload object with the two properties msg.payload.url and msg.payload.contentType

  2. play a queue of media file
    For this the urlList and the content type needs to be specified. Thus can be done in the configuration or passed as a message property msg.urlList and msg.contentType or give a payload object with the two properties msg.payload.urlList and msg.payload.contentType

  3. speak a given message, converted by google tts
    For this the message needs to be specified. Thus can be done in the configuration or pass as a message property msg.message or give a payload object with the property msg.payload.message

  4. get the state of the cast device
    For this no url or message has to be specified.

If there is a combination of the message and the url, first the media file given by URL will be streamed and then the message.

If the payload is a string and no contentType is defined, the payload will be used as a message which should be spoken.

you need to build the msg object. I think like below should work.

msg.payload = {"message": msg.payload.TTSmessage,
               "ip": msg.payload.IP
              }
return msg;

edit/ corrected the TTSmessage and IP

Thanks for your help btw.

So what would the URL be to send to it ?

http://192.168.0.2:1880/scenetrigger?TTSmessage=TEST&IP=192.168.0.16

Its passing the IP address now to the Cast node.

Testing in Postman.

However in node red its saying “error in TTS”

image

Post a screen shot of cast config page

Its working now !

I restarted node-red on the server.