WebThingsIO / gateway

WebThings Gateway - a self-hosted web application for monitoring and controlling a building over the web
http://webthings.io/gateway
Mozilla Public License 2.0
2.61k stars 339 forks source link

Yandex SmartHome support (Yandex dialogs) #2248

Closed Kozloff closed 5 years ago

Kozloff commented 5 years ago

It would be nice to have Yandex API support because it has a great voice interface for IOT. Also it is easy to implement (5 endpoints + auth, 5 actions and 16 device types)

(in Russian) https://yandex.ru/alice/smart-home https://yandex.ru/dev/dialogs/alice/doc/smart-home/concepts/general-concept-docpage/

I am ready to start do this as an add-on if I can register API Handler (something like <your-gateway>/addons/<this-add-on>/<external API endpoint>)

Similar add-on for Home Assistant https://github.com/dmitry-k/yandex_smart_home

abhijitnathwani commented 5 years ago

Hi @Kozloff you can look at extensions. These allow exposing APIs through the Mozilla Gateway interface. You can have a look if it serves the purpose.

mrstegeman commented 5 years ago

@Kozloff Yes, with the upcoming 0.10 release you'll be able to create an API Handler, which should allow you to do what you want. Looking forward to seeing your work!

The example extension has an example API Handler. If you want one in Python, see here.

I'm going to close this issue, since there's no real work necessary from us. Feel free to open more issues if you have questions!

Kozloff commented 5 years ago

@mrstegeman thank you very much, I checked the extension and it matches for me. I have another question (I ask it in this thread so as not to lose context): I need OAuth to this API Handler, but now access hardcoded with one endpoint - "/things". How to get around this limitation? (not hardcoded)

mrstegeman commented 5 years ago

Ah, yes, that will be a problem. Currently, OAuth tokens only allow access to resources under /things, no other APIs.

It may be possible to run your software outside of the gateway, though. That's what we're doing for the Mycroft skill.

Kozloff commented 5 years ago

Currently I done Horrible piece of shit

/src/oauth-types.ts

-    if (!requestPath.startsWith(Constants.THINGS_PATH)) {
+    if (!requestPath.startsWith(Constants.THINGS_PATH) || !requestPath.startsWith(Constants.EXTENSIONS_PATH)) {

/src/views/authorize.handlebars

+          <li class="authorize-extension-alice">
+            <input id="authorize-extension-alice" type="checkbox" class="generic-checkbox">
+            <label for="authorize-extension-alice" data-l10n-id="authorize-allow-all">
+            </label>
+          </li>

/static/js/authorize.js

+  const authorizeExtensionAlice = document.getElementById('authorize-extension-alice');
+  const alice = scope.split(':')[0] === '/extensions/alice/api';
+  if (alice) {
+    authorizeExtensionAlice.setAttribute('checked', '');
+  }
+    } else if (authorizeExtensionAlice.checked) {
+      urls.push('/extensions/alice/api');

It seems to work, it makes sense to wait for what to fix or is it better to do as in Mycroft skill?

Kozloff commented 5 years ago

@Kozloff Yes, with the upcoming 0.10 release you'll be able to create an API Handler, which should allow you to do what you want. Looking forward to seeing your work!

The example extension has an example API Handler. If you want one in Python, see here.

I'm going to close this issue, since there's no real work necessary from us. Feel free to open more issues if you have questions!

And I have no time to check error in pyhton-extension:

mozilla-iot-gateway | 2019-11-04 21:18:50.097 ERROR  : Failed to start plugin example-extension
mozilla-iot-gateway | 2019-11-04 21:18:50.097 ERROR  : Command: python3 {path}/main.py
mozilla-iot-gateway | 2019-11-04 21:18:50.098 ERROR  : { Error: spawn python3 ENOENT
mozilla-iot-gateway |     at Process.ChildProcess._handle.onexit (internal/child_process.js:190:19)
mozilla-iot-gateway |     at onErrorNT (internal/child_process.js:362:16)
mozilla-iot-gateway |     at _combinedTickCallback (internal/process/next_tick.js:139:11)
mozilla-iot-gateway |     at process._tickCallback (internal/process/next_tick.js:181:9)
mozilla-iot-gateway |   errno: 'ENOENT',
mozilla-iot-gateway |   code: 'ENOENT',
mozilla-iot-gateway |   syscall: 'spawn python3',
mozilla-iot-gateway |   path: 'python3',
mozilla-iot-gateway |   spawnargs: [ '/root/.mozilla-iot/addons/example-extension/main.py' ] }

It seems to add some ENV variables to .Dockerfile, is't it?

Kozloff commented 5 years ago

@mrstegeman, and the last question: any good way to add a new OAuth client from a configuration file that is not hard-coded

diff --git a/src/models/oauthclients.ts b/src/models/oauthclients.ts

+oauthClients.register(
+  new ClientRegistry(new URL('https://social.yandex.net/broker/redirect'), 'yandex',
+                     'Yandex Dialogs OAuth', '<he-he>', '/extensions/alice/api:readwrite')
+);

thank you very much, you really helped!

mrstegeman commented 5 years ago

Currently I done Horrible piece of shit

/src/oauth-types.ts

-    if (!requestPath.startsWith(Constants.THINGS_PATH)) {
+    if (!requestPath.startsWith(Constants.THINGS_PATH) || !requestPath.startsWith(Constants.EXTENSIONS_PATH)) {

/src/views/authorize.handlebars

+          <li class="authorize-extension-alice">
+            <input id="authorize-extension-alice" type="checkbox" class="generic-checkbox">
+            <label for="authorize-extension-alice" data-l10n-id="authorize-allow-all">
+            </label>
+          </li>

/static/js/authorize.js

+  const authorizeExtensionAlice = document.getElementById('authorize-extension-alice');
+  const alice = scope.split(':')[0] === '/extensions/alice/api';
+  if (alice) {
+    authorizeExtensionAlice.setAttribute('checked', '');
+  }
+    } else if (authorizeExtensionAlice.checked) {
+      urls.push('/extensions/alice/api');

It seems to work, it makes sense to wait for what to fix or is it better to do as in Mycroft skill?

Whatever works! It's going to be at least another 3-4 months before we make any OAuth changes, so it all depends on your time frame. If you want something now, it would be easiest to run something separately (or keep your gateway hack).

mrstegeman commented 5 years ago

@Kozloff Yes, with the upcoming 0.10 release you'll be able to create an API Handler, which should allow you to do what you want. Looking forward to seeing your work! The example extension has an example API Handler. If you want one in Python, see here. I'm going to close this issue, since there's no real work necessary from us. Feel free to open more issues if you have questions!

And I have no time to check error in pyhton-extension:

mozilla-iot-gateway | 2019-11-04 21:18:50.097 ERROR  : Failed to start plugin example-extension
mozilla-iot-gateway | 2019-11-04 21:18:50.097 ERROR  : Command: python3 {path}/main.py
mozilla-iot-gateway | 2019-11-04 21:18:50.098 ERROR  : { Error: spawn python3 ENOENT
mozilla-iot-gateway |     at Process.ChildProcess._handle.onexit (internal/child_process.js:190:19)
mozilla-iot-gateway |     at onErrorNT (internal/child_process.js:362:16)
mozilla-iot-gateway |     at _combinedTickCallback (internal/process/next_tick.js:139:11)
mozilla-iot-gateway |     at process._tickCallback (internal/process/next_tick.js:181:9)
mozilla-iot-gateway |   errno: 'ENOENT',
mozilla-iot-gateway |   code: 'ENOENT',
mozilla-iot-gateway |   syscall: 'spawn python3',
mozilla-iot-gateway |   path: 'python3',
mozilla-iot-gateway |   spawnargs: [ '/root/.mozilla-iot/addons/example-extension/main.py' ] }

It seems to add some ENV variables to .Dockerfile, is't it?

This is because your environment doesn't have python3 available.

mrstegeman commented 5 years ago

@mrstegeman, and the last question: any good way to add a new OAuth client from a configuration file that is not hard-coded

diff --git a/src/models/oauthclients.ts b/src/models/oauthclients.ts

+oauthClients.register(
+  new ClientRegistry(new URL('https://social.yandex.net/broker/redirect'), 'yandex',
+                     'Yandex Dialogs OAuth', '<he-he>', '/extensions/alice/api:readwrite')
+);

thank you very much, you really helped!

No, that's the proper way to add clients right now.