Git Product home page Git Product logo

smart-home-local's Introduction

Local Home SDK Sample

This sample demonstrates integrating a smart home Action with the Local Home SDK. The Local Home SDK allow developers to add a local path to handle smart home intents by running TypeScript (or JavaScript) directly on Google Home smart speakers and Nest smart displays. The sample supports the following protocols along with the companion virtual device:

  • Device Discovery: UDP, mDNS or UPnP
  • Control: UDP, TCP, or HTTP

Prerequisites

Configure the Actions project

Note: This project uses Cloud Functions for Firebase, which requires you to associate a billing account with your project. Actions projects do not create a billing account by default. See Create a new billing account for more information.

  • Create a new Smart Home project in the Actions console
  • Deploy the placeholder smart home provider to Cloud Functions for Firebase using the same Project ID:
    npm install --prefix functions/
    npm run firebase --prefix functions/ -- use ${PROJECT_ID}
    npm run deploy --prefix functions/
    
  • In Develop > Actions, set the following configuration values that matches the Cloud Functions for Firebase deployment:
    • Fulfillment: https://${REGION}-${PROJECT_ID}.cloudfunctions.net/smarthome
  • In Develop > Account linking, set the following configuration values:
    • Client ID:: placeholder-client-id
    • Client secret: placeholder-client-secret
    • Authorization URL: https://${REGION}-${PROJECT_ID}.cloudfunctions.net/authorize
    • Token URL: https://${REGION}-${PROJECT_ID}.cloudfunctions.net/token
  • Click Save

Select a discovery protocol

Choose one of the supported the discovery protocols that you would like to test, and create a new scan configuration in the Actions console.

Note: These are the default values used by the virtual device for discovery. If you choose to use different values, you will need to supply those parameters when you set up the virtual device.

  • In Develop > Actions > Configure local home SDK > Add device scan configuration, Click in New scan config.

UDP

  • Broadcast address: 255.255.255.255
  • Discovery packet: A5A5A5A5
  • Listen port: 3312
  • Broadcast port: 3311

mDNS

  • mDNS service name: _sample._tcp.local

  • Name: .*\._sample\._tcp\.local

    Note: The Name attribute value is a regular expression.

UPnP

  • UPNP service type: urn:sample:service:light:1

  • Click Save

Select a control protocol

Choose one of the supported control protocols that you would like to test. You will use this value to configure both the cloud fulfillment and the virtual device.

  • UDP: Send execution commands to the target device as a UDP payload.
  • TCP: Send execution commands to the target device as a TCP payload.
  • HTTP: Send execution commands to the target device as an HTTP request.

Choose a device type

The local fulfillment sample supports running as a single end device or a hub/proxy device. This is determined by the number of channels you configure. A device with more than one channel will be treated as a hub by the local fulfillment sample code.

Set up cloud fulfillment

Configure the cloud service to report the correct device SYNC metadata based on your chosen device type and control protocol. Here are some examples for configuring the service for different use cases:

  • Report a single device (strand1) controlled via UDP commands:

    npm run firebase --prefix functions/ -- functions:config:set \
        strand1.leds=16 strand1.channel=1 \
        strand1.control_protocol=UDP
    npm run deploy --prefix functions/
    
  • Report three individual light strands connected through a proxy (hub1) and controlled via HTTP commands:

    npm run firebase --prefix functions/ -- functions:config:set \
        hub1.leds=16 hub1.channel=1,2,3 \
        hub1.control_protocol=HTTP
    npm run deploy --prefix functions/
    

Set up the virtual device

The companion virtual device is a Node.js app that emulates strands of RGB LEDs controllable using the Open Pixel Control protocol and displays the results to the terminal in a colorful way.

  • Virtual device discovery settings must match the attributes provided in Device Scan Configuration in Develop > Actions > Configure local home SDK.
    • If you modify the attributes in your Device Scan Configuration, you must configure the virtual device accordingly. See the virtual device README for more details on configuring the discovery attributes.
  • Virtual device control protocol should match control_protocol used with functions:config:set when setting up cloud fulfillment.
  • Configure the device type as end device or hub/proxy based on the number of --channel parameters provided. A device with more than one channel will be treated as a hub.

Note: The virtual device needs to listen on the same local network as the Home device.

Here are some examples for configuring the virtual device for different use cases:

  • Start the virtual device as a single device (strand1) discovered via UDP broadcast and controlled with UDP commands:

    npm install --prefix device/
    npm start --prefix device/ -- \
        --device_id strand1 \
        --discovery_protocol UDP \
        --control_protocol UDP \
        --channel 1
    
  • Start the virtual device as a hub (hub1) discovered via mDNS and controlling three individual strands with HTTP commands:

    npm install --prefix device/
    npm start --prefix device/ -- \
        --device_id hub1 \
        --discovery_protocol MDNS \
        --control_protocol HTTP \
        --channel 1 \
        --channel 2 \
        --channel 3
    

Note: See the virtual device README for more details on the supported configuration options.

Deploy the local execution app

Serve the sample app locally from the same local network as the Home device, or deploy it to a publicly reacheable URL endpoint.

Deploy locally

  • Start the local development server:

    npm install --prefix app/
    npm start --prefix app/
    

    Note: The local development server needs to listen on the same local network as the Home device in order to be able to load the Local Home SDK application.

  • Go to the smart home project in the Actions console

  • In Develop > Actions > Configure local home SDK

    • Set the testing URL for Chrome to the one displayed in the local development server logs.
    • Set the testing URL for Node to the one displayed in the local development server logs.
    • Under Add capabilities
      • Check Support local query.
  • Click Save

Deploy to Firebase Hosting

npm install --prefix app/
npm run build --prefix app/
npm run deploy --prefix app/ -- --project ${FIREBASE_PROJECT_ID}
  • Go to the smart home project in the Actions console
  • In Develop > Actions > Configure local home SDK
    • Set the testing URL for Chrome to: http://${FIREBASE_PROJECT_ID}.firebaseapp.com/web/index.html
    • Set the testing URL for Node to: http://${FIREBASE_PROJECT_ID}.firebaseapp.com/node/bundle.js
    • Under Add capabilities
      • Check Support local query.
  • Click Save

Test the local execution app

  • In Develop > Invocation, set the Display name for the smart home Action.
  • In Test, click Start testing
  • In the Google Home app
    • Click the '+' sign
    • Select Work with Google
    • In the list of providers, select your smart home Action by Display name prefixed with [test]
    • Click Link
    • Click Complete Account Link
  • Select the linked devices and click on Add to a room.
  • Reboot the Google Home Device
  • Open chrome://inspect
  • Locate the Local Home SDK application and click inspect to launch the Chrome developer tools.
  • Try the following query
    • Set the light color to magenta
  • It should display the light strand(s) in a colorful way:
    ◉◉◉◉◉◉◉◉◉◉◉◉◉◉◉◉
    

Troubleshooting

  • Make sure the Google Home device, the virtual device and your workstation are on the same network.
  • Make sure to disable any firewall running on your workstation.

Test and Lint

npm test --prefix app/
npm run lint --prefix device/

License

See LICENSE

smart-home-local's People

Contributors

dependabot[bot] avatar proppy avatar taycaldwell avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

smart-home-local's Issues

https with self-signed certificates

Hi, is it possible to make https requests using DeviceManager on server with self-signed certificate? I get COMMAND_FAILED error code with "Did not receive HTTP response.". I don't know if it is related to the self-signed certificate problem?

Local Execution App Error; Uncaught ReferenceError: aogh is not defined

I try to follow the instructions, and deploy the execution app locally. No error is encountered in terminal, as far as I can see, but when I try to open the index.html in chrome I get the following error:

smarthome_sdk.js:44 Could not find platform channel.
Ia @ smarthome_sdk.js:44
Rb @ smarthome_sdk.js:63
V @ smarthome_sdk.js:166
ae @ smarthome_sdk.js:169
m.getDeviceManager @ smarthome_sdk.js:169
m.onIdentify @ smarthome_sdk.js:169
(anonymous) @ bundle.js:10
r @ bundle.js:1
(anonymous) @ bundle.js:1
(anonymous) @ bundle.js:1
smarthome_sdk.js:44 Please re-run the application on a Google Home platform.
Ia @ smarthome_sdk.js:44
Rb @ smarthome_sdk.js:63
V @ smarthome_sdk.js:166
ae @ smarthome_sdk.js:169
m.getDeviceManager @ smarthome_sdk.js:169
m.onIdentify @ smarthome_sdk.js:169
(anonymous) @ bundle.js:10
r @ bundle.js:1
(anonymous) @ bundle.js:1
(anonymous) @ bundle.js:1
smarthome_sdk.js:44 Uncaught ReferenceError: aogh is not defined
at Ia (smarthome_sdk.js:44:323)
at new Rb (smarthome_sdk.js:63:308)
at new V (smarthome_sdk.js:166:638)
at ae (smarthome_sdk.js:169:27)
at m.getDeviceManager (smarthome_sdk.js:169:630)
at m.onIdentify (smarthome_sdk.js:169:781)
at Module. (bundle.js:10:25070)
at r (bundle.js:1:110)
at bundle.js:1:902
at bundle.js:1:913

This seems to be an error in the local-home-sdk, and I can trace it to the usage of www.gstatic.com/eureka/smarthome/smarthome_sdk.js.

I don't know much more than this and is stuck.

Jest issues : smarthome is not defined

Hi,
I use Jest to test my code but when i run a test, the error: "ReferrenceError: smarthome is not defined" occurs when I try to import the tested function. Did you face this isssue with ava ?

UDP Discovery doesnt work

Hi,

i dont see google home trying to do a UDP discovery, for my local device. I see that @GatienB had the same issue, which was resolved by retrying the setup, but i am wondering if there is some other issue, and people trying it for the first time are misssing something. Can you please help?

Thanks

decoding not working for python device

Hi,

So i am writing my local device in python, with the same fields as in discoverData in javascript device. i encoded it using cbor and sent it, the client cant parse it. i thought maybe the object is python dictionary, so i even converted it to json and encoded and sent it, again. Nothing worked.

Am i missing something here?

Thanks

App debug in VS Code

In addition to the chrome://inspect page it is possible to debug directly in VS Code with the following configuration in the launch.json file:

{
      "name": "Attach to Chrome",
      "address": "<Google Home address>",
      "port": 9222,
      "request": "attach",
      "type": "chrome",
      "webRoot": "${workspaceFolder}/app",
      "urlFilter": "<app server>/web/index.html?"
}

Execute Handler not getting called for Proxy device

I'm trying to build a Proxy device and initially ran into #1.

Following @ballob's comment and using the Home Assistant code as a guide I've managed to get past the Handler for PROXY_SELECTED not implemented problem (would still be nice to get the TypeScript bindings updated).

The reachableDeviceHandler is getting called regularly but when I issue a command for the test device the onExecute handler is never getting called. There are no errors when I attach chrome console and the console.log on the first line is not getting called.

It is also not trying to send the command via the cloud path

My app is checked in here

udpScanData access in REACHABLE_DEVICES ?

Any way to access udpScanData in REACHABLE_DEVICES ? I need to get the port that was provided by udpScanData. I can access it in IDENTIFY but not in REACHABLE_DEVICES. It does not seem to be possible to return custom data with IDENTIFY response ? REACHABLE_DEVICES seems to have customData property but the code comments say it is not present for hub devices. I could just put it as a global variable, but is this the way to go?

Local server not receiving any request on identity handler or execute handler

Screen Shot 2019-10-08 at 2 22 24 AM

I have setup everything right according to the readme. And initially i got one or 2 requests in the identifyhandler in which i threw error. But now no matter what i do, i am not seeing any request coming to the local server. Even though google home is loading the local server web page. Should i do something else ? or this is a bug with google home itself ?

Also this is my response in the sync request -

{
    "requestId": "12942802761996814011",
    "payload": {
        "agentUserId": "1234",
        "devices": [
            {
                "id": "1xj9",
                "type": "action.devices.types.SWITCH",
                "traits": [
                    "action.devices.traits.OnOff"
                ],
                "name": {
                    "defaultNames": [
                        "Smart Switch"
                    ],
                    "name": "Smart Switch",
                    "nicknames": [
                        "smart switch"
                    ]
                },
                "deviceInfo": {
                    "manufacturer": "L",
                    "model": "L",
                    "hwVersion": "1.0.0",
                    "swVersion": "2.0.0"
                },
                "willReportState": true,
                "otherDeviceIds": [
                    {
                        "deviceId": "5678"
                    }
                ]
            },
            {
                "id": "22bn",
                "type": "action.devices.types.OUTLET",
                "traits": [
                    "action.devices.traits.OnOff"
                ],
                "name": {
                    "defaultNames": [
                        "Smart Outlet"
                    ],
                    "name": "Smart Outlet",
                    "nicknames": [
                        "smart plug"
                    ]
                },
                "deviceInfo": {
                    "manufacturer": "L",
                    "model": "L",
                    "hwVersion": "1.0.0",
                    "swVersion": "2.0.0"
                },
                "willReportState": true,
                "otherDeviceIds": [
                    {
                        "deviceId": "1234"
                    }
                ]
            }
        ]
    }
}

UDP discovery doesn't start

I setup up the sample as a single end device but it seems that the Google Home doesn't start the udp discovery.

When I connect to http://local-dev-server-hostname-or-ip:8080/, the only log is :

Uncaught ReferenceError: cast is not defined
    at new pc (smarthome_sdk.js:54)
    at new V (smarthome_sdk.js:197)
    at Pg (smarthome_sdk.js:200)
    at W.l.getDeviceManager (smarthome_sdk.js:200)
    at W.l.onExecute (smarthome_sdk.js:201)
    at Module../index.ts (index.ts:22)
    at __webpack_require__ (bootstrap:19)
    at bootstrap:83
    at bootstrap:83

It appears at this line : if (cast.platform && cast.platform.channel) in the Local Home SDK : //www.gstatic.com/eureka/smarthome/smarthome_sdk.js Maybe you know what's wrong ?

If the local sdk support CameraStream traits

We tried the local sdk and handled the SYNC response with otherDeviceIds.
The scan config should be ok because our local app already received the IDENTITY request with with expected udp payload.
The IDENTITY response should be ok, because the local platform should already passed check the "verificationId", becasuse if I set the verificationId to some string else it says not passed verification.

The problem is when I tried "show the camera", the local fulfilment execute callback function not triggered.

I tried the lamp straits sample, it looks like it works well.
Does the local sdk not support CameraStream traits ????

unable to control local device, request still going to cloud

Hi,

So i can see the UDP discovery happening, but i cant see to have local execution for my device. i tried to run app locally(didnt see any console logs being printed for IdentifyResponse) and also tried to host in on firebase and use the firbase URL for device testing, that didnt work either. what am i missing here? also cant see my device in chrome://inspect.
Any Ideas?
Thanks

npm run deploy --prefix functions happen some error

HI!

when i run "npm run deploy --prefix functions", and happening problem.

node_modules/@google-cloud/firestore/types/firestore.d.ts:1629:8 - error TS2304: Cannot find name 'AsyncIterable'.

1629     ): AsyncIterable<QueryPartition<T>>;
            ~~~~~~~~~~~~~

detail:

0 info it worked if it ends with ok
1 verbose cli [ '/usr/bin/node', '/usr/local/bin/npm', 'run', 'build' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'prebuild', 'build', 'postbuild' ]
5 info lifecycle [email protected]~prebuild: [email protected]
6 info lifecycle [email protected]~build: [email protected]
7 verbose lifecycle [email protected]~build: unsafe-perm in lifecycle true
8 verbose lifecycle [email protected]~build: PATH: /usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin:/mnt/usb2/smart-home-local/functions/node_modules/.bin:/usr/share/npm/node_modules/npm-lifecycle/node-gyp-bin:/mnt/usb2/smart-home-local/functions/node_modules/.bin:/mnt/usb2/esp-idf/components/esptool_py/esptool:/mnt/usb2/esp-idf/components/espcoredump:/mnt/usb2/esp-idf/components/partition_table:/mnt/usb2/esp-idf/components/app_update:/home/an/.espressif/tools/xtensa-esp32-elf/esp-2020r3-8.4.0/xtensa-esp32-elf/bin:/home/an/.espressif/tools/xtensa-esp32s2-elf/esp-2020r3-8.4.0/xtensa-esp32s2-elf/bin:/home/an/.espressif/tools/xtensa-esp32s3-elf/esp-2020r3-8.4.0/xtensa-esp32s3-elf/bin:/home/an/.espressif/tools/esp32ulp-elf/2.28.51-esp-20191205/esp32ulp-elf-binutils/bin:/home/an/.espressif/tools/esp32s2ulp-elf/2.28.51-esp-20191205/esp32s2ulp-elf-binutils/bin:/home/an/.espressif/tools/openocd-esp32/v0.10.0-esp32-20200709/openocd-esp32/bin:/home/an/.espressif/python_env/idf4.3_py2.7_env/bin:/mnt/usb2/esp-idf/tools:/opt/sifive/JLink_Linux_V686g_x86_64:/opt/sifive/JLink_Linux_V686g_x86_64:/opt/sifive/JLink_Linux_V686g_x86_64:/opt/sifive/riscv-qemu-4.2.0-2020.04.0-x86_64-linux-ubuntu14:/opt/ros/noetic/bin:/home/an/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/an/.dotnet/tools
9 verbose lifecycle [email protected]~build: CWD: /mnt/usb2/smart-home-local/functions
10 silly lifecycle [email protected]~build: Args: [ '-c', 'tsc' ]
11 silly lifecycle [email protected]~build: Returned: code: 2  signal: null
12 info lifecycle [email protected]~build: Failed to exec build script
13 verbose stack Error: [email protected] build: `tsc`
13 verbose stack Exit status 2
13 verbose stack     at EventEmitter.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/index.js:332:16)
13 verbose stack     at EventEmitter.emit (events.js:198:13)
13 verbose stack     at ChildProcess.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/npm-lifecycle/lib/spawn.js:55:14)
13 verbose stack     at ChildProcess.emit (events.js:198:13)
13 verbose stack     at maybeClose (internal/child_process.js:982:16)
13 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:259:5)
14 verbose pkgid [email protected]
15 verbose cwd /mnt/usb2/smart-home-local/functions
16 verbose Linux 5.4.0-58-generic
17 verbose argv "/usr/bin/node" "/usr/local/bin/npm" "run" "build"
18 verbose node v10.19.0
19 verbose npm  v6.14.10
20 error code ELIFECYCLE
21 error errno 2
22 error [email protected] build: `tsc`
22 error Exit status 2
23 error Failed at the [email protected] build script.
23 error This is probably not a problem with npm. There is likely additional logging output above.
24 verbose exit [ 2, true ]

I have no idea to solve it.
Thanks in advance.

HTTP Error: 403 on deply

Getting this deploy error when running npm run deploy --prefix functions.

⚠  functions: Upload Error: HTTP Error: 403, Unknown Error

Error: HTTP Error: 403, Unknown Error
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] deploy: `firebase deploy --only functions`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] deploy script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

Any ideas on why this happens?

Execute intents

Hi,
I am working on integration of Google Smart Home services for our PLC system used in "smart homes". Now I am implementing the local execution path. Everything goes ok when I'm testing with usual number of emulated lights. But I wanted to make some boundary tests, so I emulated e.g. 30-100 lights. When I try to set them all using Google Home speaker, the local execution intent is processed and the promise is resolved in few seconds. It resolves even earlier then the speaker starts responding. But the response from the speaker is in 99% cases: "Device is not reachable...". The strange thing is, that in the same time when the local execution starts, it is processed the same execute intent using cloud fulfillment - is this some backup path if local device is not accessible? But why it is running concurrently? Are there any timeouts for resolving local execute intents?

Thank you

UDP discovery doesn't start

Hi,

I setup up this sample but it seems that the Google Home doesn't start the udp discovery so it calls every time the server (running with ngrok) to execute a command.

Race condition Query\Execute

Execute and Query requests come almost in the same moment, so
the Nest hub is not able to finish the UDP request.

image

Concurrent UDP commands to the same port are not allowed!
"Error: NOT_ALLOWED
at new P (https://www.gstatic.com/eureka/smarthome/smarthome_sdk.js:98:84)
at R.complete (https://www.gstatic.com/eureka/smarthome/smarthome_sdk.js:111:196)
at T.onMessage_ (https://www.gstatic.com/eureka/smarthome/smarthome_sdk.js:130:194)
at https://www.gstatic.com/eureka/smarthome/smarthome_sdk.js:67:319"

Missing local sync

hi,

the last days i intensivly studied the new local home sdk. but i'm wondering why there is no local sync request. how GA should detect new installed local devices (may be behind a hub device)? or i'm missing something?

Local execution on Google Home optional device

Hello,

I was wondering if I can deploy this solution without a Google Home or Google Nest but instead with a Raspberry PI that simulates a Google Home with the Google Assistant SDK?

Thank you, in advance.

IDENTIFY requests for googlerpc._googlerpc._tcp.local

Hi,
I use MDNS discovery service for discovering my devices for local API. I use MDNS service name as a filter but after rebooting I have requests for Identification of device with googlerpc._googlerpc._tcp.local and sometimes other google's services
Is it ok? Why my filter is not respected here?
It is not big problem for me to check correct service name in the processing of the IDENTIFY request and reject it.

mdnsScanData: {serviceName: "googlerpc._googlerpc._tcp.local", name: "googlerpc", type: "googlerpc", protocol: "tcp", data: Array(1), …}
...
smarthome_sdk.js:122 [ 0.074s] [smarthome.DeviceManager] Got a rejected promise Invalid service name

Provide actual setup instructions

This project makes too many assumptions that the user knows what they are doing. For example:

Deploy the placeholder smart home provider to Cloud Functions for Firebase using the same Project ID:

I have no idea what that means, I assume it's what the commands do. Except what folder am I supposed to run the listed commands? From the root of the project doesn't work:

npm install --prefix functions/
npm ERR! code ENOLOCAL
npm ERR! Could not install from "" as it does not contain a package.json file.

So I need to run the command where there is a package.json? The app, device, and functions folders have a package.json. Which do I use? OK the command succeeds in the app subfolder but the next command does not:

npm run firebase --prefix functions/ -- use ${PROJECT_ID}
npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path [snip]\app\functions\package.json
npm ERR! errno -4058
npm ERR! enoent ENOENT: no such file or directory, open '[snip]\app\functions\package.json'

I have no idea. Please provide instructions that can be followed to get the desired result.

Can't find out index.html page

When I have executed the following instructions:
npm install --prefix app/
npm run build --prefix app/
npm run deploy --prefix app/ -- --project ${FIREBASE_PROJECT_ID}

I found that I couldn't visit http://${FIREBASE_PROJECT_ID}.firebaseapp.com/web/index.html (Back to 404)

http://${FIREBASE_ PROJECT_ ID}. firebaseapp.com/node/bundle .js
http://${FIREBASE_ PROJECT_ ID}. firebaseapp.com/web/bundle .js
Both addresses are accessible

Starting virtual device fails

Starting the virtual device with the command

npm start --prefix device/ -- --device_id strand1 --discovery_protocol UDP --control_protocol TCP --channel 1

Fails with the error:

/home/pi/www/smart-home-local/device/server.ts:30
import {IOPCMessage} from './types';
    ^
TypeError: Cannot redefine property: default
    at Function.defineProperty (<anonymous>)
    at /home/pi/www/smart-home-local/device/server.ts:22:12
    at __importStar (/home/pi/www/smart-home-local/device/server.ts:30:5)
    at Object.<anonymous> (/home/pi/www/smart-home-local/device/server.ts:26:1)
    at Module._compile (internal/modules/cjs/loader.js:1138:30)
    at Module.m._compile (/home/pi/www/smart-home-local/device/node_modules/ts-node/src/index.ts:439:23)
    at Module._extensions..js (internal/modules/cjs/loader.js:1158:10)
    at Object.require.extensions.<computed> [as .ts] (/home/pi/www/smart-home-local/device/node_modules/ts-node/src/index.ts:442:12)
    at Module.load (internal/modules/cjs/loader.js:986:32)
    at Function.Module._load (internal/modules/cjs/loader.js:879:14)
    at Module.require (internal/modules/cjs/loader.js:1026:19)
    at require (internal/modules/cjs/helpers.js:72:18)
    at Object.<anonymous> (/home/pi/www/smart-home-local/device/main.ts:16:1)
    at Module._compile (internal/modules/cjs/loader.js:1138:30)
    at Module.m._compile (/home/pi/www/smart-home-local/device/node_modules/ts-node/src/index.ts:439:23)

Pubsub failed with 1500ms timeout

I need to run a query on my firestore database at executeHandler before I run this.app.getDeviceManager().send(deviceCommand).

This will give me timeout errors sometimes as below.
Screen Shot 2021-01-13 at 5 24 33 PM

Is there a way I can set the timeout more than 1500ms?

The following is my code of executeHandler:

executeHandler(request: IntentFlow.ExecuteRequest): Promise<IntentFlow.ExecuteResponse> {
// TODO: Implement local execution
console.log("EXECUTE intent: " + JSON.stringify(request, null, 2));

const command = request.inputs[0].payload.commands[0];
const execution = command.execution[0];
const response = new Execute.Response.Builder().setRequestId(request.requestId);

const promises: Array<Promise<void>> = command.devices.map(async (device) => {
  console.log("Handling EXECUTE intent for device: " + JSON.stringify(device));

  // Convert execution params to a string for the local device
  const params = execution.params as IFireplaceParams;
  const tcpMsg = 'MWIB2,02';
  const payload = this.stringToHex(tcpMsg);

  const firebaseDataObj = await this.queryFirebase(device.id);
  console.log("firebaseDataObj:", JSON.stringify(firebaseDataObj));

  // Construct a local device command over TCP
  const deviceCommand = new DataFlow.TcpRequestData();
  deviceCommand.requestId = request.requestId;
  deviceCommand.deviceId = device.id;
  deviceCommand.data = payload;
  deviceCommand.port = SERVER_PORT;
  deviceCommand.operation = Constants.TcpOperation.WRITE;

  try {
    const result = await this.app.getDeviceManager().send(deviceCommand);
    console.log("Sending deviceCommand result:", JSON.stringify(result));
    const state = { online: true };
    response.setSuccessState(result.deviceId, Object.assign(state, params));
  } catch (err) {
    err.errorCode = err.errorCode || 'invalid_request';
    response.setErrorState(device.id, err.errorCode);
    console.error('An error occurred sending the command', err.errorCode);
  }
});

return Promise.all(promises)
  .then(() => {
    return response.build();
  })
  .catch((e) => {
    const err = new IntentFlow.HandlerError(request.requestId, 'invalid_request', e.message);
    return Promise.reject(err);
  });

}

UDP Discovery Packet

1、In the documentation, I see that I want to fill in a fixed discovery packet. However, the data received by my gateway is encrypted. Each gateway needs to receive a different discovery device packet.What should I do in this situation?
2、IntentFlow.IdentifyResponse Can return multiple device data at a time, what should I do?
Thanks.

action.devices.commands.selectChannel empty json

When using Local fulfillment | Actions on Google Smart Home, the device is unable to process the request because the command payload is empty

action.devices.commands.OnOff:

URI: /
Method: POST
Arguments: 1
plain: {"on":false}
or
plain: {"on":true}

{"inputs":[{"context":{"locale_country":"US","locale_language":"en"},"intent":"action.devices.EXECUTE","payload":{"commands":[{"devices":[{"id":"1"}],"execution":[{"command":"action.devices.commands.OnOff","params":{"on":true}}]}]}}],"requestId":"2684167294084643688"}

action.devices.commands.selectChannel:

URI: /
Method: POST
Arguments: 1
plain: {}

{"inputs":[{"context":{"locale_country":"US","locale_language":"es"},"intent":"action.devices.EXECUTE","payload":{"commands":[{"devices":[{"id":"1"}],"execution":[{"command":"action.devices.commands.selectChannel","params":{"channelNumber":"200"}}]}]}}],"requestId":"13659619173073600206"}

Googlehome device delete - interacts with node code: "expressApp.post('/smarthome/delete'" ?

I´m trying to allow user to delete an specific device from home app / firestore collection. Case is the only way to remove a device from home app is deleting it from firestore. I don´t want do delete the entire colletion and do a relink/discovery again.

Within smarthome Node code there is the call: "expressApp.post('/smarthome/delete', (req, res) =>...."
This is to delete an specific device, however i don´t know if this call is done from Google home app "remove device" icon inside device settings.

Also, my home app do not show device delete option inside device settings. Not sure if is a JSON message problem during device creation discovery phase.

Thank you if can help!

development URL

Is the URL README file correct?

In Develop > Actions > On device testing set the development URL to http://local-dev-server-hostname-or-ip:8080/

It seems that the google home device is sending a get request to "/"

Frame 19273: 694 bytes on wire (5552 bits), 694 bytes captured (5552 bits) on interface 0
Ethernet II, Src: f0:72:ea:88:8b:30 (f0:72:ea:88:8b:30), Dst: Raspberr_7e:77:5d (dc:a6:32:7e:77:5d)
Internet Protocol Version 4, Src: 192.168.101.63, Dst: 192.168.101.69
Transmission Control Protocol, Src Port: 38838, Dst Port: 8080, Seq: 138161, Ack: 85361, Len: 628
Hypertext Transfer Protocol
GET / HTTP/1.1\r\n
[Expert Info (Chat/Sequence): GET / HTTP/1.1\r\n]
[GET / HTTP/1.1\r\n]
[Severity level: Chat]
[Group: Sequence]
Request Method: GET
Request URI: /
Request Version: HTTP/1.1
Host: 192.168.101.69:8080\r\n
Connection: keep-alive\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (X11; Linux aarch64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.81 Safari/537.36 CrKey/1.42.180404\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3\r\n
CAST-DEVICE-CAPABILITIES: {"audio_assistant":true,"bluetooth_supported":true,"display_supported":false,"hi_res_audio_supported":false,"remote_control_input_supported":false,"touch_input_supported":false}\r\n
Accept-Encoding: gzip, deflate\r\n
Accept-Language: en-us,en\r\n
\r\n
[Full request URI: http://192.168.101.69:8080/]
[HTTP request 221/222]
[Prev request in frame: 19227]
[Response in frame: 19274]
[Next request in frame: 19312]

BT BLE device discovery

Hi,
I have add new scan config in my Google Action local home SDK. that includes : BLE Provisioned and BLE Unprovisioned. but google nest mini always does UDP for device discovery. Does anyone have idea where has wrong?
the field I add for both Provisioned and Unprovisioned
BLE complete 16-bit service class UUIDs(0x03) 0xA00A

My google nest seems does not know it should use bluetooth to scan my home device.
Does anyone have idea?
or where I have to add/modify code? such that google nest mini know to turn bluetooth for scan device?

When stream security camera on TV using Google Home speaker, does the stream go through Google home?

How does Google home manage the connection to stream security camera video to a smart TV?
here

Does Google home work as a proxy when camera is streaming the video, or somehow it commands the TV to pull stream directly from the camera without Google home in the middle?

I know that Google home SDK can bypass the cloud, but how it works locally?

Is it?

Security camera -> Google home -> smart TV
or Google home manage to make a direct connection? if yes, then How?

Security camera -> smart TV

Add sample for hub device

The sample should show:

  • what to return in IDENTIFY for the hub device
  • how to retrieve and return vericationIds in REACHABLE_DEVICES
  • how to handle PROXY_SELECTED
  • how to forward opc message in EXECUTE to the hub w/ additional metadata so that the hub can reach the appropriate target devices
  • how the local home app can discover the hub, and how the hub can discover child devices

Updated Version on the Local SDK

Hello,

As per the release of the local home sdk 1.4.0 queries can be supported locally now.

However, from the Chrome debug logs i see that the SDK version which is fetched from here is "1.3.1".

Can we have the latest version of the SDK please to check if the queries are working locally or is there any other way to get the latest version?

Thanks

How to send multiple headers with DataFlow.HttpRequestData

Sending a single one works fine:

  const httpRequest = new DataFlow.HttpRequestData();
...
  httpRequest.headers = `custom-token:${data.token}`;
...

The issue is when I try to send two:

  const httpRequest = new DataFlow.HttpRequestData();
...
  httpRequest.headers = [
      `custom-token:${data.token}`,
      `custom-uuid:${data.uuid}`,
  ].join("; ");
...

According to the docs headers is a string, but the description is a List of HTTP headers for the request.

How do I send multiple headers?
I already tested multiple .join() options, including \n that causes the headers to be not sent at all, but throws no error.

Any ideas?

q

q

Problem with data encoding

Hi,

I'm trying to adapt this sample to use the local home sdk to interact with an STB.
I'm using the http request flow but i'm having some problems sending the correct data on a post request.
I'm not sure wha is happening, but it seems somehow my data is being changed before being sent in the request.

I have the data i need to sen in a buffer, that is returned by an encryption function from a lib provided by the STB manufacturer
In node.js app i simple do
req.write(buff.toString('latin1'), 'latin1')
or
req.write(buff)
and it works well.

With this this lib i've tried both:
radioCommand.data = buff.toString('latin1');
and
radioCommand.data = buff.toString();

But the data sent is different from the original. Besides the request failing on the STB, i can see on the device that the content-length header value is different from the buffer length.
Here's the log of the request (on the device side) from working request made from a simple node.js ap:

Content-Length:  24                                                                                                                                                                
Content-Type:    text/plain                                                                                                                                       
Host:            192.168.1.66                                                                                                                                                      
Connection:      close                                                                                                                                                             
Hex                                                                                                                                                                           [m:hex]
0000000000 71 5a 8c 73 b4 60 2b 89 6b 6a 3d 28 51 d9 34 ce   qZ.s.`+.kj=(Q.4.
0000000010 0c 59 b0 57 b3 1c 7f 3b                           .Y.W...;

And the log from a request, with the same data, made using the local home sdk with radioCommand.data = buff.toString('latin1');:

Host:            192.168.1.66                                                                                                                                                      
Connection:      keep-alive                                                                                                                                                        
Content-Length:  31                                                                                                                                                                
Content-Type:    text/plain                                                                                                                                                        
Hex                                                                                                                                                                           [m:hex]
0000000000 71 5a c2 8c 73 c2 b4 60 2b c2 89 6b 6a 3d 28 51   qZ..s..`+..kj=(Q
0000000010 c3 99 34 c3 8e 0c 59 c2 b0 57 c2 b3 1c 7f 3b      ..4...Y..W....;

And the log from a request, with the same data, made using the local home sdk with radioCommand.data = buff.toString();:

Host:            192.168.1.66                                                                                                                                                      
Connection:      keep-alive                                                                                                                                                        
Content-Length:  38                                                                                                                                                                
Content-Type:    text/plain                                                                                                                                                        
Hex                                                                                                                                                                           [m:hex]
0000000000 71 5a ef bf bd 73 ef bf bd 60 2b ef bf bd 6b 6a   qZ...s...`+...kj
0000000010 3d 28 51 ef bf bd 34 ef bf bd 0c 59 ef bf bd 57   =(Q...4....Y...W
0000000020 ef bf bd 1c 7f 3b                                 .....;

if i use radioCommand.data = buff.toString('ascii');, the length is preserved but the data is not the same:

Host:            192.168.1.66                                                                                                                                                      
Connection:      keep-alive                                                                                                                                                        
Content-Length:  24                                                                                                                                                                
Content-Type:    text/plain                                                                                                                                                        
Hex                                                                                                                                                                           [m:hex]
0000000000 71 5a 0c 73 34 60 2b 09 6b 6a 3d 28 51 59 34 4e   qZ.s4`+.kj=(QY4N
0000000010 0c 59 30 57 33 1c 7f 3b                           .Y0W3..;

Any idea on what might be the problem and on how to solve it?
Thanks in advance

Use local connection with proxy

Hello,

I tried to use local connection with hub but it does not work. I view IDENTIFY request, my response is :
image
This is my first question, why I need verificationId, doc say it's necessary but reference say it's optionnal (https://developers.google.com/actions/smarthome/reference/local/interfaces/smarthome.intentflow.identifyresponsepayload). For me in my case it's not need because I send isLocalOnly true (True if this device does not appear in the `SYNC response. This is common for hub devices.). So i device is not in SYNC response it's does not need a verificationId, no ?

After that I receveid REACHABLE_DEVICES, I said all device it's reachable (home is proxy for all my device in google home).

After that I get "action.devices.PROXY_SELECTED", I don't know what I have to do with that... I can't find anything about that in documentation... I try to resend same response as REACHABLE_DEVICES and it's seem ok.

So according to the console all it's ok but I don't received any local execute exept if I test on verifcationId device.

Did anyone success with local api and hub systeme ?

Thank in advance for your reply

TypeError: handler is not a function

I am getting this error in the cloud console when setting this local home fulfillment example app:

"TypeError: handler is not a function
at Function. (/srv/node_modules/actions-on-google/dist/service/smarthome/smarthome.js:180:29)
at Generator.next ()
at /srv/node_modules/actions-on-google/dist/service/smarthome/smarthome.js:22:71
at new Promise ()
at __awaiter (/srv/node_modules/actions-on-google/dist/service/smarthome/smarthome.js:18:12)
at Function.handler (/srv/node_modules/actions-on-google/dist/service/smarthome/smarthome.js:174:16)
at Object. (/srv/node_modules/actions-on-google/dist/assistant.js:55:32)
at Generator.next ()
at /srv/node_modules/actions-on-google/dist/assistant.js:22:71
at new Promise ()"

Throws a 500 and everything stops at that point.

Local Home app IDENTIFY requests not showing up

I'm going through the README and got to the last section of trying to test that the local home SDK works with the virtual device.

When going into the Chrome inspector however, I'm not receiving any IDENTIFY requests at all per the attached image.

Screen Shot 2020-12-30 at 6 36 20 AM

Things I've confirmed and tried:

  • I've got the UDP scan config configured on the AOG console, the virtual device running with the discovery protocol as UDP, and the cloud fulfillment control protocol and virtual device control protocol matching one another (currently HTTP for the hub example).
  • Unlinking/linking the virtual device in my Google Home App (though every time I tap on them, it says they're offline)
  • Rebooting my Nest Mini (by plugging/unplugging)

It looks like the cloud fallback is happening according to the logs:

Screen Shot 2020-12-30 at 6 49 18 AM

It seems like local discovery isn't happening...not sure if the SYNC request is being sent (I'm assuming that the SYNC request happens in the cloud functions in the sample code), or my virtual device is configured incorrectly when I run it (is the address supposed to be 0.0.0.0?):

Screen Shot 2020-12-30 at 6 57 34 AM

Any thoughts on the issue?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.