├── .gitignore
├── LICENSE
├── README.md
├── ca-chain.pem
├── googlehome.html
├── googlehome.js
├── icons
├── assistant.png
└── unnamed-color.png
├── package-lock.json
└── package.json
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/*
2 |
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
203 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # node-red-contrib-googlehome
2 |
3 | A set of Node-RED nodes to allow Node-RED to act as a endpoint for
4 | Google Home Smart Home Action
5 |
6 | ## Install
7 |
8 | In the Node-RED user directory (e.g. ~/.node-red) run the following command:
9 |
10 | `npm install node-red-contrib-googlehome`
11 |
12 | or use the palette manager to install the node directly from with in Node-RED
13 |
14 | ## Configuration
15 |
16 | You will need an account [here](https://googlehome.hardill.me.uk). Once you have an
17 | account you can define a number of devices. You can then configure a node to represent
18 | that device in a Node-RED flow.
19 |
20 | The full documentation can be found [here](https://googlehome.hardill.me.uk/docs)
--------------------------------------------------------------------------------
/ca-chain.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIFYTCCA0mgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwNDELMAkGA1UEBhMCR0Ix
3 | EDAOBgNVBAgMB0VuZ2xhbmQxEzARBgNVBAoMCkhhcmRpbGwgQ0EwHhcNMTgxMTIx
4 | MjAwNTU0WhcNMjgxMTE4MjAwNTU0WjBLMQswCQYDVQQGEwJHQjEQMA4GA1UECAwH
5 | RW5nbGFuZDETMBEGA1UECgwKSGFyZGlsbCBDQTEVMBMGA1UEAwwMSW50ZXJtZWRp
6 | YXRlMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9HZQrUTtG9Q1zmWa
7 | SxZbS5u58v95Wx/ztccjSNadu3PPF4QiKDYjS94KYoQdw+HMQ+DNTqlVkmwcT/F6
8 | bM2Hfz6FPFEvBUksPWGcngsUfXlewHIeUd08PFqm+EbQVnfBtH/2mIOqoJT5WNn7
9 | Qg7JCKQzAl6zvwJebzoUtdn7IfUgUPyEqIJddCqonZFzyeYCR+pPsqQ+AVAIJsWT
10 | RThxNg00G4aqoXbtMeD51NbKe/EhdZZvLEdaDPEz51WjAAyA/FBFBMP+07dS4F+v
11 | D7m7B4M/bKepThATCRusyLrTt9Racg5Kwm7ihw1jErwX/beuxj7TOVdB+DfDh09U
12 | k9RLFEbJH0vXrpcl8EuIULxz7By57G2luIBsTHFR0xMLQIMdAn7AVQ8Mh1tsCJ8i
13 | CALGu8c/5kuybR/7I1+nN+idpq/5Fp9kUu1Y/u4vcS6GPTKOyjKqRyQfJVeUa1+y
14 | CnnJM1GLWwQFOQrxU0Xeis1qO96tMg1Y2DyYMkR7VvTZweWcA++HAek7wJB4OSYU
15 | 12g9xRW5CeozF79HXBNvxgkEWr9x6Gvb/1BxUwlruno92wCppASUkbDZThYKqXl7
16 | jJcM0DTQ+JaD0CuMCPkl3V4E95c5O7tkSrwNpaw12mw6gZu+9VI2jjFsvMgYl435
17 | IRzyudwLBIj2oODOIZj5Md7aOs8CAwEAAaNmMGQwHQYDVR0OBBYEFMUUKCfwh4q9
18 | 4qyW6HER3oEeyehMMB8GA1UdIwQYMBaAFHgrCcaNmeGlKpqdlvHw+TQDadhRMBIG
19 | A1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUA
20 | A4ICAQBv8zqAEmGmAIW6YfBOXOzMWCoiPWdqf/Is1BoiIgDQDhZl3kEzylfVgr+P
21 | Rvf8ffHGQV4AeEORbh1VuNwLdf3hq4uJhqs7DKAKFV1/JxkuIgnA1WIi2+5gz0V7
22 | lNqwuMpjjN0VEQIp3LDAzpliRnmJ2PXDYaXHOYoEj/qMpQf8vU4CTqOAQXKazOar
23 | Y2FUUMnhRB3jmZjmP5RrOYywLEHV9WyTUkhq47Srg2kaBfHqRSFOFO1dubWzb9hn
24 | 9KUyXyRp+llJfpYH1WcMFYmlf5CPZcrgjTuBR5zx1LT3VilWzMAzsGXRYeEUhL58
25 | vVkwLXNrQdJnoZBokXxbh1LW5OGTWjo8KTdAZr2o6MI3D+lw3Cfd7jcFFiY6Y1Hn
26 | 0NWkK3H+s7+xLtpiqBJReCRtOIJ41E2Ka38lmDHlC6L1r/Z8JSNZ9AL4n58iqTrW
27 | JAthciWGbOHKZcEoaZw/LT/cql+8wWxF4EHaxcnchv9fUVq9MuP2WzrHJUzDHaCE
28 | LLGWGfU+zDRNNqUgRqLSNNzfdTuKLBVENQCjirOnW7eLJFJ/pCeUu8SJpDby9v14
29 | 4U7JMfCM3Fio/vx89fE8aFqvUePm0BMXrbBblDbBIOZLqqevCqlwl3jeNxU04AOB
30 | 1KJu2i+QQG9KDsRYplX2a32nu8eN7wrQxrMIMjYUr83MxaTW2A==
31 | -----END CERTIFICATE-----
32 | -----BEGIN CERTIFICATE-----
33 | MIIFTjCCAzagAwIBAgIJAP+ggLl9bW/FMA0GCSqGSIb3DQEBCwUAMDQxCzAJBgNV
34 | BAYTAkdCMRAwDgYDVQQIDAdFbmdsYW5kMRMwEQYDVQQKDApIYXJkaWxsIENBMB4X
35 | DTE4MTEyMTE5MjMyOFoXDTM4MTExNjE5MjMyOFowNDELMAkGA1UEBhMCR0IxEDAO
36 | BgNVBAgMB0VuZ2xhbmQxEzARBgNVBAoMCkhhcmRpbGwgQ0EwggIiMA0GCSqGSIb3
37 | DQEBAQUAA4ICDwAwggIKAoICAQD2MEmt68Yc1tkqOdlDTkLpvHdEIQYLE3roIflP
38 | /Ghy+losIyit6xubQaCM552A2d1CmJ2tnQ6Ry6iPAprbWTgjX0ks53DyXt7iyzT6
39 | iYmnpOo8eVcoEO7bG7wLOBYURzg79CnCGKj83/rwa3dG1Abuw/IzE1zAatdByuxO
40 | q4u9zCfyG42WvxIGLs71qDY9SsGsvfkRKzZBX5xCmLTJIP+56Oiz/wy1N9H1dPRf
41 | nRgGUfnlglnbWE7hEfYe3nC63KcDIFpJi9XYlL7G5ExcmUjKoqF2r4bO4qAAFPcW
42 | Zhm0f/xW/3jHK6noDq93NAbarBIadEG9f59Z0F2t9nhSwaS4tSWSP4MPooMVBjNX
43 | +E25zlnCa71R/8J69BtPysNGAVDBaF6Ot7CUM/qPbpP7BGWWujpjt1C47/wFwdB8
44 | m1cnQj8NOjmcFciqyWkrspIPw4HfntjYf3Guz7DC6+QnfxMQhHyE+solvwMZt+XQ
45 | TF9t5lqrxY6J8Szgcn5HMlr7il54mXFTGuZrT9/4FIWn4x6YV1cCODkEOiUlmwRx
46 | SZlb+EI3+DR9uygzikbbiGLSqn1lNft2i8RxX+TiTQcYFNBRslgQDxU0iRZFZF+q
47 | EL0fRm+KZxX2mixIT7c/yreiE6oLAvX7cmd7+EzODeAfIFLziAmn4qVm2g+Dxe/9
48 | 921xKwIDAQABo2MwYTAdBgNVHQ4EFgQUeCsJxo2Z4aUqmp2W8fD5NANp2FEwHwYD
49 | VR0jBBgwFoAUeCsJxo2Z4aUqmp2W8fD5NANp2FEwDwYDVR0TAQH/BAUwAwEB/zAO
50 | BgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBAOVGRmCHDhcTswSLYcj7
51 | wOm7KdS3QBliMThvNJv2TIOxGoQ3r8xURSnPkr5lGMiUXwmWa+1rDdg1dGbkzojT
52 | ME2HXFJaqIPdOZ9vfMdvw/jGQTP/Y8/gfCg7Vh8SnnnV0k+SeZs+gPjViEAjD015
53 | gYgucHqhtdF7XKLT03JvD6tD1S4biW6xSe0zt+2Gjp1MpGJJ2RCo/H42HYeU9vUb
54 | d3fuL7Ojs5PrNNcLIYP/YuFUuBZfjRool/m9+DfwGqfLvKTDcsIPsuNZOqWAxYm5
55 | tYYKig2fWZXq3V/tKq4M7scp4TGOrrQCpav/7sBuz457hkIKasEhoxJ1vHHDK0/K
56 | RtzDgczGWpMX+AbL5Q5miywFofOarUYqJ9Kx8iNAgCv9DngHeA+uO2vDhGDm2OqY
57 | dWdX91kESn989aVNiC8RBn7FkbJVIdbWg7Upwl9ny8CYLxMEr/BEee1ky2OUTJ6w
58 | zdV4o5jP6AAqDKFatwh1y1aPvIg56EXu4A/dS6BQyR49qzfioqVkCnCr2mBgXc7h
59 | hdQF1gAc7yJjy5LlHMZJE9FFzzdYt3Wf2K1pmF0yaElVJv8/kBcovanAoIkH0RID
60 | aT9WLystPsRTyQVlXgUmQTvnqwdXq2hr2GvfXR2wXa59Ot43UAad6UbIwiePdiR9
61 | rq30YzSDBoJDIORj02CT2Dyk
62 | -----END CERTIFICATE-----
63 |
--------------------------------------------------------------------------------
/googlehome.html:
--------------------------------------------------------------------------------
1 |
13 |
23 |
24 |
28 |
29 |
64 |
65 |
90 |
91 |
96 |
97 |
210 |
211 |
227 |
228 |
231 |
232 |
--------------------------------------------------------------------------------
/googlehome.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2017-2020 Ben Hardill
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | var brokerHost = process.env.GOOGLEHOME_BROKER || 'googlehome.hardill.me.uk';
18 | var devicesURL = process.env.GOOGLEHOME_URL || 'https://googlehome.hardill.me.uk/user/api/devices';
19 |
20 | module.exports = function(RED) {
21 |
22 | "use strict";
23 | const fs = require('fs');
24 | const mqtt = require('mqtt');
25 | const path = require('path');
26 | const request = require('request');
27 |
28 | var devices = {};
29 | var status = {};
30 |
31 | var caPath = path.join(__dirname, "ca-chain.pem");
32 |
33 | function googleHomeConf(n) {
34 | RED.nodes.createNode(this,n);
35 | this.username = n.username;
36 | this.password = this.credentials.password;
37 |
38 | this.users = {};
39 |
40 | var node = this;
41 |
42 | var options = {
43 | username: node.username,
44 | password: node.password,
45 | clientId: node.username,
46 | reconnectPeriod: 5000,
47 | ca: [fs.readFileSync(caPath)],
48 | servers:[
49 | {
50 | protocol: 'mqtts',
51 | host: brokerHost,
52 | port: 8883
53 | },
54 | {
55 | protocol: 'mqtt',
56 | host: brokerHost,
57 | port: 1883
58 | }
59 | ]
60 | };
61 |
62 | getDevices(this.username, this.password, node.id);
63 |
64 | this.connect = function() {
65 | node.client = mqtt.connect(options);
66 | node.client.setMaxListeners(0);
67 |
68 | node.client.on('connect', function() {
69 | node.setStatus({text:'connected', shape:'dot', fill:'green'});
70 | node.client.removeAllListeners('message');
71 | node.client.subscribe("command/" + node.username + "/#");
72 | node.client.on('message', function(topic, message) {
73 | //tricky bit
74 | var msg = JSON.parse(message.toString());
75 | var devId = msg.id;
76 | for (var id in node.users) {
77 | if (node.users.hasOwnProperty(id)){
78 | if (node.users[id].device === devId) {
79 | node.users[id].command(msg);
80 | }
81 | }
82 | }
83 | });
84 | }
85 | );
86 |
87 | node.client.on('offline',function() {
88 | node.setStatus({text: 'disconnected', shape: 'dot', fill:'red'});
89 | });
90 |
91 | node.client.on('reconnect', function() {
92 | node.setStatus({text: 'reconnecting', shape: 'ring', fill:'red'});
93 | });
94 |
95 | node.client.on('error', function (err) {
96 | //console.log(err);
97 | node.setStatus({text: 'disconnected', shape: 'dot', fill:'red'});
98 | node.error(err);
99 | });
100 | };
101 |
102 | this.setStatus = function(status) {
103 | for( var id in node.users) {
104 | if (node.users.hasOwnProperty(id)) {
105 | node.users[id].status(status);
106 | }
107 | }
108 | }
109 |
110 | this.register = function(deviceNode) {
111 | node.users[deviceNode.id] = deviceNode;
112 | if (Object.keys(node.users).length === 1) {
113 | node.connect();
114 | } else {
115 | node.setStatus({text:'connected', shape:'dot', fill:'green'});
116 | }
117 | }
118 |
119 | this.unregister = function(deviceNode, done) {
120 | delete node.users[deviceNode.id];
121 |
122 | if (Object.keys(node.users).length === 0) {
123 | if (node.client && node.client.connected) {
124 | node.client.end(done);
125 | } else {
126 | node.client.end();
127 | done();
128 | }
129 | }
130 |
131 | done();
132 | }
133 |
134 | this.acknowledge = function(msg) {
135 | var topic = "response/" + node.username;
136 | node.client.publish(topic, JSON.stringify(msg));
137 | if (msg.status) {
138 | status[msg.id] = RED.util.cloneMessage(msg.execution.params);
139 | }
140 | }
141 |
142 | this.reportState = function(msg) {
143 | var topic = "status/" + node.username;
144 | if (!RED.util.compareObjects(msg.execution.params, status[msg.id])) {
145 | status[msg.id] = RED.util.cloneMessage(msg.execution.params)
146 | node.client.publish(topic, JSON.stringify(msg));
147 | }
148 | }
149 |
150 | this.on('close', function(){
151 | if (node.client && node.client.connected) {
152 | node.client.end();
153 | }
154 | });
155 | }
156 |
157 | RED.nodes.registerType("google-home-conf",googleHomeConf,{
158 | credentials: {
159 | password: {type:"password"}
160 | }
161 | });
162 |
163 | function googleHome(n) {
164 | RED.nodes.createNode(this,n);
165 | this.conf = RED.nodes.getNode(n.conf);
166 | this.confId = n.conf;
167 | this.acknowledge = n.acknowledge;
168 | this.topic = n.topic;
169 | this.device = n.device;
170 | this.name = n.name;
171 |
172 | var node = this;
173 |
174 | node.command = function(msg) {
175 | var m = {
176 | topic: node.topic || "",
177 | name: node.name,
178 | deviceId: msg.id,
179 | _requestId: msg.requestId,
180 | _raw: msg,
181 | _confId: node.confId,
182 | payload: msg.execution
183 | }
184 | node.send(m);
185 | if (node.acknowledge) {
186 | msg.status = true;
187 | node.conf.acknowledge(msg);
188 | }
189 | }
190 |
191 | node.conf.register(node);
192 |
193 | node.on('close', function(done){
194 | node.conf.unregister(node, done);
195 | });
196 | }
197 |
198 | RED.nodes.registerType("google-home", googleHome);
199 |
200 | function googleHomeResponse(n) {
201 | RED.nodes.createNode(this,n);
202 | this.conf = RED.nodes.getNode(n.conf);
203 | this.confId = n.conf;
204 | this.deviceId = n.device;
205 | //this.lastStatus = {};
206 |
207 | var node = this;
208 |
209 | node.on('input', function(msg){
210 | //console.log(msg)
211 | if (msg._confId) {
212 | if (msg._confId == node.confId) {
213 | if (msg._requestId) {
214 | //console.log("replying to a command")
215 | var resp = {
216 | requestId: msg._requestId,
217 | id: msg.deviceId,
218 | execution: msg.payload
219 | }
220 | node.conf.acknowledge(resp);
221 | } else {
222 | // no request id so something wrong
223 | node.error("No _confId but no _requestId",msg);
224 | }
225 | } else {
226 | node.error("Input message confId does not match configuration", msg);
227 | }
228 | } else {
229 | // no conf id in message so must be a report
230 | //console.log("status change");
231 | if (msg.payload.params) {
232 | //if (!RED.util.compareObjects(msg.payload.params, node.lastStatus)) {
233 | //console.log("different status");
234 | //node.lastStatus = RED.util.cloneMessage(msg.payload.params);
235 | var resp = {
236 | id: node.deviceId,
237 | execution: msg.payload
238 | }
239 | node.conf.reportState(resp);
240 | //}
241 | }
242 | }
243 |
244 | })
245 |
246 | node.conf.register(node);
247 |
248 | node.on('close', function(done){
249 | node.conf.unregister(node, done);
250 | });
251 | }
252 |
253 | RED.nodes.registerType("google-home-response", googleHomeResponse);
254 |
255 | function getDevices(username, password, id) {
256 | if (username && password) {
257 | request.get({
258 | url: devicesURL,
259 | auth: {
260 | username: username,
261 | password: password
262 | }
263 | }, function(err,res,body) {
264 | if (!err && res.statusCode == 200) {
265 | var devs = JSON.parse(body);
266 | devices[id] = devs
267 | } else {
268 | //console.("err: " + err);
269 | RED.log.log("Problem looking up " + username + "'s devices");
270 | }
271 | });
272 | }
273 | }
274 |
275 | RED.httpAdmin.post('/google-home/new-account',function(req,res){
276 | var username = req.body.user;
277 | var password = req.body.pass;
278 | var id = req.body.id;
279 | getDevices(username,password,id);
280 | res.status(200).send();
281 | });
282 |
283 | RED.httpAdmin.post('/google-home/refresh/:id', function(req,res){
284 | var id = req.params.id;
285 | var conf = RED.nodes.getNode(id);
286 | if (conf) {
287 | var username = conf.username;
288 | var password = conf.credentials.password;
289 | getDevices(username,password,id);
290 | res.status(200).send();
291 | } else {
292 | //not deployed yet
293 | console.log("Can't refresh until deployed");
294 | res.status(404).send();
295 | }
296 | });
297 |
298 | RED.httpAdmin.get('/google-home/devices/:id', function(req,res){
299 | if (devices[req.params.id]) {
300 | res.send(devices[req.params.id]);
301 | } else {
302 | res.status(404).send();
303 | }
304 | });
305 | }
--------------------------------------------------------------------------------
/icons/assistant.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hardillb/node-red-contrib-googlehome/02d6805f544df41ba86c9a68b2a56446f000bd87/icons/assistant.png
--------------------------------------------------------------------------------
/icons/unnamed-color.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hardillb/node-red-contrib-googlehome/02d6805f544df41ba86c9a68b2a56446f000bd87/icons/unnamed-color.png
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "node-red-contrib-googlehome",
3 | "version": "0.0.15",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "version": "0.0.15",
9 | "license": "Apache-2.0",
10 | "dependencies": {
11 | "mqtt": "^4.2.6",
12 | "request": "^2.83.0"
13 | }
14 | },
15 | "node_modules/ajv": {
16 | "version": "6.12.6",
17 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
18 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
19 | "dependencies": {
20 | "fast-deep-equal": "^3.1.1",
21 | "fast-json-stable-stringify": "^2.0.0",
22 | "json-schema-traverse": "^0.4.1",
23 | "uri-js": "^4.2.2"
24 | },
25 | "funding": {
26 | "type": "github",
27 | "url": "https://github.com/sponsors/epoberezkin"
28 | }
29 | },
30 | "node_modules/asn1": {
31 | "version": "0.2.4",
32 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
33 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
34 | "dependencies": {
35 | "safer-buffer": "~2.1.0"
36 | }
37 | },
38 | "node_modules/assert-plus": {
39 | "version": "1.0.0",
40 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
41 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
42 | "engines": {
43 | "node": ">=0.8"
44 | }
45 | },
46 | "node_modules/asynckit": {
47 | "version": "0.4.0",
48 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
49 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
50 | },
51 | "node_modules/aws-sign2": {
52 | "version": "0.7.0",
53 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
54 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
55 | "engines": {
56 | "node": "*"
57 | }
58 | },
59 | "node_modules/aws4": {
60 | "version": "1.11.0",
61 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
62 | "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA=="
63 | },
64 | "node_modules/balanced-match": {
65 | "version": "1.0.2",
66 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
67 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
68 | },
69 | "node_modules/base64-js": {
70 | "version": "1.5.1",
71 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
72 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
73 | "funding": [
74 | {
75 | "type": "github",
76 | "url": "https://github.com/sponsors/feross"
77 | },
78 | {
79 | "type": "patreon",
80 | "url": "https://www.patreon.com/feross"
81 | },
82 | {
83 | "type": "consulting",
84 | "url": "https://feross.org/support"
85 | }
86 | ]
87 | },
88 | "node_modules/bcrypt-pbkdf": {
89 | "version": "1.0.2",
90 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
91 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
92 | "dependencies": {
93 | "tweetnacl": "^0.14.3"
94 | }
95 | },
96 | "node_modules/bl": {
97 | "version": "4.1.0",
98 | "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
99 | "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
100 | "dependencies": {
101 | "buffer": "^5.5.0",
102 | "inherits": "^2.0.4",
103 | "readable-stream": "^3.4.0"
104 | }
105 | },
106 | "node_modules/brace-expansion": {
107 | "version": "1.1.11",
108 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
109 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
110 | "dependencies": {
111 | "balanced-match": "^1.0.0",
112 | "concat-map": "0.0.1"
113 | }
114 | },
115 | "node_modules/buffer": {
116 | "version": "5.7.1",
117 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
118 | "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
119 | "funding": [
120 | {
121 | "type": "github",
122 | "url": "https://github.com/sponsors/feross"
123 | },
124 | {
125 | "type": "patreon",
126 | "url": "https://www.patreon.com/feross"
127 | },
128 | {
129 | "type": "consulting",
130 | "url": "https://feross.org/support"
131 | }
132 | ],
133 | "dependencies": {
134 | "base64-js": "^1.3.1",
135 | "ieee754": "^1.1.13"
136 | }
137 | },
138 | "node_modules/buffer-from": {
139 | "version": "1.1.2",
140 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
141 | "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
142 | },
143 | "node_modules/caseless": {
144 | "version": "0.12.0",
145 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
146 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
147 | },
148 | "node_modules/combined-stream": {
149 | "version": "1.0.8",
150 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
151 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
152 | "dependencies": {
153 | "delayed-stream": "~1.0.0"
154 | },
155 | "engines": {
156 | "node": ">= 0.8"
157 | }
158 | },
159 | "node_modules/commist": {
160 | "version": "1.1.0",
161 | "resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz",
162 | "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==",
163 | "dependencies": {
164 | "leven": "^2.1.0",
165 | "minimist": "^1.1.0"
166 | }
167 | },
168 | "node_modules/concat-map": {
169 | "version": "0.0.1",
170 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
171 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
172 | },
173 | "node_modules/concat-stream": {
174 | "version": "2.0.0",
175 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
176 | "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
177 | "engines": [
178 | "node >= 6.0"
179 | ],
180 | "dependencies": {
181 | "buffer-from": "^1.0.0",
182 | "inherits": "^2.0.3",
183 | "readable-stream": "^3.0.2",
184 | "typedarray": "^0.0.6"
185 | }
186 | },
187 | "node_modules/core-util-is": {
188 | "version": "1.0.2",
189 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
190 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
191 | },
192 | "node_modules/dashdash": {
193 | "version": "1.14.1",
194 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
195 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
196 | "dependencies": {
197 | "assert-plus": "^1.0.0"
198 | },
199 | "engines": {
200 | "node": ">=0.10"
201 | }
202 | },
203 | "node_modules/debug": {
204 | "version": "4.3.4",
205 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
206 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
207 | "dependencies": {
208 | "ms": "2.1.2"
209 | },
210 | "engines": {
211 | "node": ">=6.0"
212 | },
213 | "peerDependenciesMeta": {
214 | "supports-color": {
215 | "optional": true
216 | }
217 | }
218 | },
219 | "node_modules/delayed-stream": {
220 | "version": "1.0.0",
221 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
222 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
223 | "engines": {
224 | "node": ">=0.4.0"
225 | }
226 | },
227 | "node_modules/duplexify": {
228 | "version": "4.1.2",
229 | "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz",
230 | "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==",
231 | "dependencies": {
232 | "end-of-stream": "^1.4.1",
233 | "inherits": "^2.0.3",
234 | "readable-stream": "^3.1.1",
235 | "stream-shift": "^1.0.0"
236 | }
237 | },
238 | "node_modules/ecc-jsbn": {
239 | "version": "0.1.2",
240 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
241 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
242 | "dependencies": {
243 | "jsbn": "~0.1.0",
244 | "safer-buffer": "^2.1.0"
245 | }
246 | },
247 | "node_modules/end-of-stream": {
248 | "version": "1.4.4",
249 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
250 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
251 | "dependencies": {
252 | "once": "^1.4.0"
253 | }
254 | },
255 | "node_modules/extend": {
256 | "version": "3.0.2",
257 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
258 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
259 | },
260 | "node_modules/extsprintf": {
261 | "version": "1.3.0",
262 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
263 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
264 | "engines": [
265 | "node >=0.6.0"
266 | ]
267 | },
268 | "node_modules/fast-deep-equal": {
269 | "version": "3.1.3",
270 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
271 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
272 | },
273 | "node_modules/fast-json-stable-stringify": {
274 | "version": "2.1.0",
275 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
276 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
277 | },
278 | "node_modules/forever-agent": {
279 | "version": "0.6.1",
280 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
281 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
282 | "engines": {
283 | "node": "*"
284 | }
285 | },
286 | "node_modules/form-data": {
287 | "version": "2.3.3",
288 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
289 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
290 | "dependencies": {
291 | "asynckit": "^0.4.0",
292 | "combined-stream": "^1.0.6",
293 | "mime-types": "^2.1.12"
294 | },
295 | "engines": {
296 | "node": ">= 0.12"
297 | }
298 | },
299 | "node_modules/fs.realpath": {
300 | "version": "1.0.0",
301 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
302 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
303 | },
304 | "node_modules/getpass": {
305 | "version": "0.1.7",
306 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
307 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
308 | "dependencies": {
309 | "assert-plus": "^1.0.0"
310 | }
311 | },
312 | "node_modules/glob": {
313 | "version": "7.2.3",
314 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
315 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
316 | "deprecated": "Glob versions prior to v9 are no longer supported",
317 | "dependencies": {
318 | "fs.realpath": "^1.0.0",
319 | "inflight": "^1.0.4",
320 | "inherits": "2",
321 | "minimatch": "^3.1.1",
322 | "once": "^1.3.0",
323 | "path-is-absolute": "^1.0.0"
324 | },
325 | "engines": {
326 | "node": "*"
327 | },
328 | "funding": {
329 | "url": "https://github.com/sponsors/isaacs"
330 | }
331 | },
332 | "node_modules/har-schema": {
333 | "version": "2.0.0",
334 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
335 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
336 | "engines": {
337 | "node": ">=4"
338 | }
339 | },
340 | "node_modules/har-validator": {
341 | "version": "5.1.5",
342 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
343 | "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
344 | "deprecated": "this library is no longer supported",
345 | "dependencies": {
346 | "ajv": "^6.12.3",
347 | "har-schema": "^2.0.0"
348 | },
349 | "engines": {
350 | "node": ">=6"
351 | }
352 | },
353 | "node_modules/help-me": {
354 | "version": "3.0.0",
355 | "resolved": "https://registry.npmjs.org/help-me/-/help-me-3.0.0.tgz",
356 | "integrity": "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==",
357 | "dependencies": {
358 | "glob": "^7.1.6",
359 | "readable-stream": "^3.6.0"
360 | }
361 | },
362 | "node_modules/http-signature": {
363 | "version": "1.2.0",
364 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
365 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
366 | "dependencies": {
367 | "assert-plus": "^1.0.0",
368 | "jsprim": "^1.2.2",
369 | "sshpk": "^1.7.0"
370 | },
371 | "engines": {
372 | "node": ">=0.8",
373 | "npm": ">=1.3.7"
374 | }
375 | },
376 | "node_modules/ieee754": {
377 | "version": "1.2.1",
378 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
379 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
380 | "funding": [
381 | {
382 | "type": "github",
383 | "url": "https://github.com/sponsors/feross"
384 | },
385 | {
386 | "type": "patreon",
387 | "url": "https://www.patreon.com/feross"
388 | },
389 | {
390 | "type": "consulting",
391 | "url": "https://feross.org/support"
392 | }
393 | ]
394 | },
395 | "node_modules/inflight": {
396 | "version": "1.0.6",
397 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
398 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
399 | "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
400 | "dependencies": {
401 | "once": "^1.3.0",
402 | "wrappy": "1"
403 | }
404 | },
405 | "node_modules/inherits": {
406 | "version": "2.0.4",
407 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
408 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
409 | },
410 | "node_modules/is-typedarray": {
411 | "version": "1.0.0",
412 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
413 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
414 | },
415 | "node_modules/isstream": {
416 | "version": "0.1.2",
417 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
418 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
419 | },
420 | "node_modules/js-sdsl": {
421 | "version": "4.3.0",
422 | "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz",
423 | "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==",
424 | "funding": {
425 | "type": "opencollective",
426 | "url": "https://opencollective.com/js-sdsl"
427 | }
428 | },
429 | "node_modules/jsbn": {
430 | "version": "0.1.1",
431 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
432 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
433 | },
434 | "node_modules/json-schema-traverse": {
435 | "version": "0.4.1",
436 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
437 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
438 | },
439 | "node_modules/json-stringify-safe": {
440 | "version": "5.0.1",
441 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
442 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
443 | },
444 | "node_modules/jsprim": {
445 | "version": "1.4.2",
446 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
447 | "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
448 | "dependencies": {
449 | "assert-plus": "1.0.0",
450 | "extsprintf": "1.3.0",
451 | "json-schema": "0.4.0",
452 | "verror": "1.10.0"
453 | },
454 | "engines": {
455 | "node": ">=0.6.0"
456 | }
457 | },
458 | "node_modules/jsprim/node_modules/json-schema": {
459 | "version": "0.4.0",
460 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
461 | "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
462 | },
463 | "node_modules/leven": {
464 | "version": "2.1.0",
465 | "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
466 | "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==",
467 | "engines": {
468 | "node": ">=0.10.0"
469 | }
470 | },
471 | "node_modules/lru-cache": {
472 | "version": "6.0.0",
473 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
474 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
475 | "dependencies": {
476 | "yallist": "^4.0.0"
477 | },
478 | "engines": {
479 | "node": ">=10"
480 | }
481 | },
482 | "node_modules/mime-db": {
483 | "version": "1.44.0",
484 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
485 | "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
486 | "engines": {
487 | "node": ">= 0.6"
488 | }
489 | },
490 | "node_modules/mime-types": {
491 | "version": "2.1.27",
492 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
493 | "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
494 | "dependencies": {
495 | "mime-db": "1.44.0"
496 | },
497 | "engines": {
498 | "node": ">= 0.6"
499 | }
500 | },
501 | "node_modules/minimatch": {
502 | "version": "3.1.2",
503 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
504 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
505 | "dependencies": {
506 | "brace-expansion": "^1.1.7"
507 | },
508 | "engines": {
509 | "node": "*"
510 | }
511 | },
512 | "node_modules/minimist": {
513 | "version": "1.2.8",
514 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
515 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
516 | "funding": {
517 | "url": "https://github.com/sponsors/ljharb"
518 | }
519 | },
520 | "node_modules/mqtt": {
521 | "version": "4.3.7",
522 | "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.3.7.tgz",
523 | "integrity": "sha512-ew3qwG/TJRorTz47eW46vZ5oBw5MEYbQZVaEji44j5lAUSQSqIEoul7Kua/BatBW0H0kKQcC9kwUHa1qzaWHSw==",
524 | "dependencies": {
525 | "commist": "^1.0.0",
526 | "concat-stream": "^2.0.0",
527 | "debug": "^4.1.1",
528 | "duplexify": "^4.1.1",
529 | "help-me": "^3.0.0",
530 | "inherits": "^2.0.3",
531 | "lru-cache": "^6.0.0",
532 | "minimist": "^1.2.5",
533 | "mqtt-packet": "^6.8.0",
534 | "number-allocator": "^1.0.9",
535 | "pump": "^3.0.0",
536 | "readable-stream": "^3.6.0",
537 | "reinterval": "^1.1.0",
538 | "rfdc": "^1.3.0",
539 | "split2": "^3.1.0",
540 | "ws": "^7.5.5",
541 | "xtend": "^4.0.2"
542 | },
543 | "bin": {
544 | "mqtt": "bin/mqtt.js",
545 | "mqtt_pub": "bin/pub.js",
546 | "mqtt_sub": "bin/sub.js"
547 | },
548 | "engines": {
549 | "node": ">=10.0.0"
550 | }
551 | },
552 | "node_modules/mqtt-packet": {
553 | "version": "6.10.0",
554 | "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz",
555 | "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==",
556 | "dependencies": {
557 | "bl": "^4.0.2",
558 | "debug": "^4.1.1",
559 | "process-nextick-args": "^2.0.1"
560 | }
561 | },
562 | "node_modules/ms": {
563 | "version": "2.1.2",
564 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
565 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
566 | },
567 | "node_modules/number-allocator": {
568 | "version": "1.0.14",
569 | "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz",
570 | "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==",
571 | "dependencies": {
572 | "debug": "^4.3.1",
573 | "js-sdsl": "4.3.0"
574 | }
575 | },
576 | "node_modules/oauth-sign": {
577 | "version": "0.9.0",
578 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
579 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
580 | "engines": {
581 | "node": "*"
582 | }
583 | },
584 | "node_modules/once": {
585 | "version": "1.4.0",
586 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
587 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
588 | "dependencies": {
589 | "wrappy": "1"
590 | }
591 | },
592 | "node_modules/path-is-absolute": {
593 | "version": "1.0.1",
594 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
595 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
596 | "engines": {
597 | "node": ">=0.10.0"
598 | }
599 | },
600 | "node_modules/performance-now": {
601 | "version": "2.1.0",
602 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
603 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
604 | },
605 | "node_modules/process-nextick-args": {
606 | "version": "2.0.1",
607 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
608 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
609 | },
610 | "node_modules/psl": {
611 | "version": "1.8.0",
612 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
613 | "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
614 | },
615 | "node_modules/pump": {
616 | "version": "3.0.0",
617 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
618 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
619 | "dependencies": {
620 | "end-of-stream": "^1.1.0",
621 | "once": "^1.3.1"
622 | }
623 | },
624 | "node_modules/punycode": {
625 | "version": "2.1.1",
626 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
627 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
628 | "engines": {
629 | "node": ">=6"
630 | }
631 | },
632 | "node_modules/qs": {
633 | "version": "6.5.3",
634 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
635 | "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
636 | "engines": {
637 | "node": ">=0.6"
638 | }
639 | },
640 | "node_modules/readable-stream": {
641 | "version": "3.6.2",
642 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
643 | "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
644 | "dependencies": {
645 | "inherits": "^2.0.3",
646 | "string_decoder": "^1.1.1",
647 | "util-deprecate": "^1.0.1"
648 | },
649 | "engines": {
650 | "node": ">= 6"
651 | }
652 | },
653 | "node_modules/reinterval": {
654 | "version": "1.1.0",
655 | "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz",
656 | "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ=="
657 | },
658 | "node_modules/request": {
659 | "version": "2.88.2",
660 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
661 | "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
662 | "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142",
663 | "dependencies": {
664 | "aws-sign2": "~0.7.0",
665 | "aws4": "^1.8.0",
666 | "caseless": "~0.12.0",
667 | "combined-stream": "~1.0.6",
668 | "extend": "~3.0.2",
669 | "forever-agent": "~0.6.1",
670 | "form-data": "~2.3.2",
671 | "har-validator": "~5.1.3",
672 | "http-signature": "~1.2.0",
673 | "is-typedarray": "~1.0.0",
674 | "isstream": "~0.1.2",
675 | "json-stringify-safe": "~5.0.1",
676 | "mime-types": "~2.1.19",
677 | "oauth-sign": "~0.9.0",
678 | "performance-now": "^2.1.0",
679 | "qs": "~6.5.2",
680 | "safe-buffer": "^5.1.2",
681 | "tough-cookie": "~2.5.0",
682 | "tunnel-agent": "^0.6.0",
683 | "uuid": "^3.3.2"
684 | },
685 | "engines": {
686 | "node": ">= 6"
687 | }
688 | },
689 | "node_modules/rfdc": {
690 | "version": "1.3.0",
691 | "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
692 | "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA=="
693 | },
694 | "node_modules/safe-buffer": {
695 | "version": "5.1.2",
696 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
697 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
698 | },
699 | "node_modules/safer-buffer": {
700 | "version": "2.1.2",
701 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
702 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
703 | },
704 | "node_modules/split2": {
705 | "version": "3.2.2",
706 | "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz",
707 | "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==",
708 | "dependencies": {
709 | "readable-stream": "^3.0.0"
710 | }
711 | },
712 | "node_modules/sshpk": {
713 | "version": "1.16.1",
714 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
715 | "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
716 | "dependencies": {
717 | "asn1": "~0.2.3",
718 | "assert-plus": "^1.0.0",
719 | "bcrypt-pbkdf": "^1.0.0",
720 | "dashdash": "^1.12.0",
721 | "ecc-jsbn": "~0.1.1",
722 | "getpass": "^0.1.1",
723 | "jsbn": "~0.1.0",
724 | "safer-buffer": "^2.0.2",
725 | "tweetnacl": "~0.14.0"
726 | },
727 | "bin": {
728 | "sshpk-conv": "bin/sshpk-conv",
729 | "sshpk-sign": "bin/sshpk-sign",
730 | "sshpk-verify": "bin/sshpk-verify"
731 | },
732 | "engines": {
733 | "node": ">=0.10.0"
734 | }
735 | },
736 | "node_modules/stream-shift": {
737 | "version": "1.0.1",
738 | "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
739 | "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ=="
740 | },
741 | "node_modules/string_decoder": {
742 | "version": "1.3.0",
743 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
744 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
745 | "dependencies": {
746 | "safe-buffer": "~5.2.0"
747 | }
748 | },
749 | "node_modules/string_decoder/node_modules/safe-buffer": {
750 | "version": "5.2.1",
751 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
752 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
753 | "funding": [
754 | {
755 | "type": "github",
756 | "url": "https://github.com/sponsors/feross"
757 | },
758 | {
759 | "type": "patreon",
760 | "url": "https://www.patreon.com/feross"
761 | },
762 | {
763 | "type": "consulting",
764 | "url": "https://feross.org/support"
765 | }
766 | ]
767 | },
768 | "node_modules/tough-cookie": {
769 | "version": "2.5.0",
770 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
771 | "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
772 | "dependencies": {
773 | "psl": "^1.1.28",
774 | "punycode": "^2.1.1"
775 | },
776 | "engines": {
777 | "node": ">=0.8"
778 | }
779 | },
780 | "node_modules/tunnel-agent": {
781 | "version": "0.6.0",
782 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
783 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
784 | "dependencies": {
785 | "safe-buffer": "^5.0.1"
786 | },
787 | "engines": {
788 | "node": "*"
789 | }
790 | },
791 | "node_modules/tweetnacl": {
792 | "version": "0.14.5",
793 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
794 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
795 | },
796 | "node_modules/typedarray": {
797 | "version": "0.0.6",
798 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
799 | "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="
800 | },
801 | "node_modules/uri-js": {
802 | "version": "4.4.0",
803 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz",
804 | "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==",
805 | "dependencies": {
806 | "punycode": "^2.1.0"
807 | }
808 | },
809 | "node_modules/util-deprecate": {
810 | "version": "1.0.2",
811 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
812 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
813 | },
814 | "node_modules/uuid": {
815 | "version": "3.4.0",
816 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
817 | "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
818 | "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
819 | "bin": {
820 | "uuid": "bin/uuid"
821 | }
822 | },
823 | "node_modules/verror": {
824 | "version": "1.10.0",
825 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
826 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
827 | "engines": [
828 | "node >=0.6.0"
829 | ],
830 | "dependencies": {
831 | "assert-plus": "^1.0.0",
832 | "core-util-is": "1.0.2",
833 | "extsprintf": "^1.2.0"
834 | }
835 | },
836 | "node_modules/wrappy": {
837 | "version": "1.0.2",
838 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
839 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
840 | },
841 | "node_modules/ws": {
842 | "version": "7.5.10",
843 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
844 | "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
845 | "license": "MIT",
846 | "engines": {
847 | "node": ">=8.3.0"
848 | },
849 | "peerDependencies": {
850 | "bufferutil": "^4.0.1",
851 | "utf-8-validate": "^5.0.2"
852 | },
853 | "peerDependenciesMeta": {
854 | "bufferutil": {
855 | "optional": true
856 | },
857 | "utf-8-validate": {
858 | "optional": true
859 | }
860 | }
861 | },
862 | "node_modules/xtend": {
863 | "version": "4.0.2",
864 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
865 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
866 | "engines": {
867 | "node": ">=0.4"
868 | }
869 | },
870 | "node_modules/yallist": {
871 | "version": "4.0.0",
872 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
873 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
874 | }
875 | }
876 | }
877 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "node-red-contrib-googlehome",
3 | "version": "0.0.15",
4 | "description": "A Smart Home Action for Google Home",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [
10 | "node-red",
11 | "Google Home"
12 | ],
13 | "node-red": {
14 | "nodes": {
15 | "googlehome": "googlehome.js"
16 | }
17 | },
18 | "repository": {
19 | "type": "git",
20 | "url": "https://github.com/hardillb/node-red-contrib-googlehome"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/hardillb/node-red-contrib-googlehome/issues"
24 | },
25 | "homepage": "https://googlehome.hardill.me.uk",
26 | "author": "hardillb@gmail.com",
27 | "license": "Apache-2.0",
28 | "dependencies": {
29 | "mqtt": "^4.2.6",
30 | "request": "^2.83.0"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------