Call Home Assistant Service from LG webOS

I currently get a notification on my LG TV if someone rings my Nuki, but it would be great if I could open the door directly from my TV.
It is possible to show actionable notifications on the TV but as far as I can tell, the only option is to run webos commands.
Does anybody know if it is possible (either directly or using a third-party mechanism) to call home assistant services as well?

service: webostv.command
data:
  entity_id: media_player.living_room_tv
  command: system.notifications/createAlert
  payload:
    message: "Someone's at the door"
    buttons:
      - label: Open
        onclick: "???"
      - label: Cancel

I went through the Home assistant add-on documentation and the WebOS notification documentation from LG but could not really find anything. Do the buttons “open” and “cancel” actually show up? Because even this I could not find in the documentation. A way to go could be to use a webhook, the TV sends a HTTP request or opens a webpage which can trigger home assistant. I’am not sure how you can add a “open webpage” action to this notification since it is not mentioned in the documentation but it should be possible I guess. For more information about home assistant webhooks you could check this: Automation Trigger - Home Assistant

I hope this helps.

Yes, the buttons show up:

It’s possible to open a webpage via the webos.command, as documented here

service: webostv.command
data:
  entity_id: media_player.living_room_tv
  command: "system.launcher/open"
  payload:
    target: https://www.google.com

But inside the onclick it works different. There you will need to call an API url (com.webos.service.applicationmanager | webOS Open Source Edition).

And while I was writing and testing, I got it working:

service: webostv.command
data:
  entity_id: media_player.living_room_tv
  command: system.notifications/createAlert
  payload:
    message: "Someone's at the door"
    buttons:
      - label: Open
        onClick: "luna://com.webos.service.applicationmanager/launch"
        params:
          id: "com.webos.app.browser"
          params:
            target: "https://www.google.com"
      - label: Cancel

Inside the target I will now need to call a webhook. Never tried that before, but maybe I can get it to work.
Maybe it’s also possible to call a sequence that opens the webpage with the webhook and closes it immediately.

Great to see, I think that should work. Maybe another app is available for webOS to do an API call or a web hook request without really opening something. I saw some stuff over here: webos-service API Reference | webOS TV Developer

So maybe instead of opening the browser with the onClick command you could run another service that could do an api request to home assistant (with a long live acces token) or the web hook without opening something like a browser.

It already looks quite promising to be honest, I really should have gotten an LG TV for my smart home.
Good luck!

Thank you for your ideas!
The webhook works, but as expected it’s not the prettiest as the browser stays open and tries to start a download (since the webhook is an HTTP GET request).
In fact, it would be better to invoke an HTTP POST from something other than the browser (like a service). That would be the last hurdle for a well-functioning automation, which I have yet to figure out.

Did you found a solution?

Unfortunately not yet.
I tried to write a WebOS service, which calls the Home Assistant Webhook, but I can’t get it to work.

To provide a bit more information, my service test looks like this:

var Service = require('webos-service');
var service = new Service("com.ha.webhook.service");

const url = 'http://[HA_IP]:8123/api/webhook/';

service.register("webhook", function (message) {
    var id = message.payload.id;

    // this does not work!?
    var httpRequest = new XMLHttpRequest();
    httpRequest.open("GET", url + id, true);

    message.respond({
        returnValue: true,
        data: url + id,
    });
});

If I comment out the two lines with the httpRequest, I get the response message. But as soon as I add the code back, my service hangs.
Does anybody know what I can do to make the request work?

To test this, I use ares-shell on my TV where I installed the service + app with the following command: luna-send -n 1 -f luna://com.ha.webhook.service/webhook '{"id":"123"}'

Thanks for your response.
I managed to get the webhook to work. So when I click this button:

      - label: Open
        onClick: "luna://com.webos.service.applicationmanager/launch"
        params:
          id: "com.webos.app.browser"
          params:
            target: "http://[HA_IP]:8123/api/webhook/lgtvwebos"

Home Assistant notices it. Unfortunately the browser on the TV stays open showing a white page, as mentioned above.

Now to you problem.
Are you missing the httpRequest.send() command?

In general node.js doesn’t support XMLHttpRequest natively (see StackOverflow).
Can you switch the commands accordingly with this?
https://nodejs.org/api/http.html#httprequesturl-options-callback

Thanks for your help.
I finally got my service to work!

Adding httpRequest.send() didn’t work, but the following code:

var service = new Service("com.ha.webhook.service");
const http = require('http');

const url = 'http://[HA_IP]:8123/api/webhook/';

service.register("webhook", function (message) {
    var id = message.payload.id;
    http.get(url + id);
});

In a simple WebOS App I can call this service using the following command:

webOS.service.request("luna://com.ha.webhook.service/", {
        method: "webhook",
        parameters: { id: "123"},
        onFailure: showFailure,
        onSuccess: showSuccess,
    });

But I am still not quite sure how I can call the above request inside Home Assistant. I tried the following:

service: webostv.command
data:
  entity_id: media_player.living_room_tv
  command: system.notifications/createAlert
  payload:
    message: "Someone's at the door"
    buttons:
      - label: Open
        onclick: "luna://com.ha.webhook.service/webhook"
        params:
          id: "123"
      - label: Cancel

Any idea?

I found a way to show some debug logs. When pressing the “Open” button I get the following log:

[18:52:37.257][WARNING] ls-hubd LSHUB_NO_NAME_PERMS Can not find match for 'com.ha.webhook.service' in pattern queue '["com.webos.service.*", "com.webos.service.*", "com.webos.*", "com.palm.service.*", "com.palm.*", "com.palm.*", "com.lge.*", "com.lge.*", "airplay.service"]' {}
[18:52:37.257][ERR] ls-hubd LSHUB_NO_OUT_PERMS "com.webos.surfacemanager" does not have sufficient outbound permissions to communicate with "com.ha.webhook.service" (cmdline: /usr/bin/surface-manager -platform starfish) {"DEST_APP_ID":"com.ha.webhook.service","SRC_APP_ID":"com.webos.surfacemanager","EXE":"/usr/bin/surface-manager","PID":1853}
[18:52:37.257][WARNING] ls-hubd LSHUB_NO_SERVICE _LSHubSendQueryNameReplyMessage: Failed Connecting to Service err_code: -2, service_name: "com.ha.webhook.service", unique_name: "(null)", static, fd -1 {}
[18:52:37.260][INFO] VOICEFW VOICEUI_FOREGROUND foreground changed {"foreground":"com.webos.app.hdmi1"}
[18:52:37.262][WARNING] surface-manager LSM Hub error detected for token: 724 "webhook" "PermissionDenied" {}
[18:52:37.262][WARNING] surface-manager LSM Error response for token: 724 -1 "Not permitted to send to com.ha.webhook.service." {}

/edit: I managed to make it work!
The service name must match any of the patterns in the log:

["com.webos.service.*", "com.webos.service.*", "com.webos.*", "com.palm.service.*", "com.palm.*", "com.palm.*", "com.lge.*", "com.lge.*", "airplay.service"]

Unfortunately, the App name “com.webos.ha” with the service name “com.webos.ha.service” does not work:

ares-install ERR! [com.webos.appInstallService failure]: luna-send command failed <Cannnot install privileged app on developer mode>
ares-install ERR! [Tips]: Please change the app id (app id should not start with 'com.lge', 'com.webos', 'com.palm')

So the only name, that works for me, is “com.webos”.
And to be honest, I think this is a bug because based on the error message above, this name shouldn’t work either.
But at least you have the necessary rights to call the service.

Sorry to hijack the thread but I found it pretty similar to what I’m trying to do.

I’m using this:

service: webostv.command
data:
  entity_id: media_player.lg_webos_tv_uh605v
  command: com.webos.applicationManager/launch
  payload:
    id: org.webosbrew.piccap

To open an app in my TV. It works perfect. No complaints.

But I want to launch the service from the app directly, without the TV needing to open the app. This is because my webOS version doesn’t allow autostart so I’m trying to replicate it using HA.

I’ve tried org.webosbrew.piccap.service but it doesn’t work.
Any idea?

I’m not really sure about this, but I’d like to throw in a few ideas and assumptions.

First you would probably have to know the name of the service, because it is not always [appname].service. It could also be called [appname].foo for example. Maybe there are even more services.

In the terminal you would probably start the service like this:
luna-send -n 1 -f luna://com.webos.service.applicationManager/launch '{"id":"org.webosbrew.piccap.ServiceName"}'

Do you have a chance to try this out?
If that works, you would have to think about how to call this command in Home Assistant.
Maybe by using the command_line platform like here: LG webOS change picture setting mode with scripts - #20 by an1uk

Perhaps the service cannot be started on its own, but only provides certain functions for the app.
Then you would probably have to call the function directly:
luna-send -n 1 -f luna://com.webosbrew.piccap.ServiceName/ServiceFunction '{\"anyParameter\":\"anyValue\"}'

Maybe it’s much simpler and your code actually works anyway, except that the ID is wrong. Try to find out what the service is really called.

Maybe you can do something with one of my ideas.
Note again: I pieced together a lot of the things from online searches, which means they don’t necessarily have to be correct.

2 Likes

So, how can I find out the name of the service? Searching into the files I found the service here:

But it doesn’t make it obvious what file or name should I be calling. I think the service must be able to be started without launching the app, as that’s exactly what its “autostart” does (when it works on other webOS versions).

Edit: I actually made it work using:

service: webostv.command
data:
  entity_id: media_player.lg_webos_tv_uh605v
  command: com.webos.applicationManager/launch
  payload:
    id: luna://org.webosbrew.piccap.service/start

It works perfect. However, only if SSH is running. So now I need to find a way to make SSH service run before this one.

I’m glad you found the solution!
Isn’t it enough to simply check “SSH Server” in the homebrew settings?

No. :frowning: That’s the issue. webOS 3.4.0 doesn’t seem to support any type of autostart. That’s what I was told on the lgwebos Discord. That’s why I’m trying to start the services from HA.

Unfortunately, bad news regarding the permissions issue.

I opened a thread in the WebOS Developer Forum (Permissions when creating a service - Web App Development - webOS TV Community) and asked why I was getting the LSHUB_NO_OUT_PERMS error, and if I understood correctly, Home Assistant (or the corresponding WebOS library behind it) does not use the webOS TV API but the webOS OSE API when calling the system.notifications/createAlert command, since the webOS TV API does not support notifications.

And because webOS OSE resources cannot be guaranteed to be compatible with webOS TV apps/services, I think that’s why I’m getting this error, when I try to call my service via the notification button.

Unfortunately, I don’t have a plan what to do about it. :frowning:

I would like your help to make a service work, I would like that when the notification appears on the LG TV and when I click on open, the service would activate input/source hdmi 2.
If I try just like that, it works:

service: media_player.select_source
data:
  source: HDMI 2
target:
  entity_id: media_player.tv_do_casal

But if you try completely, it doesn’t trigger HDMI 2.

service: webostv.command
data:
  entity_id: media_player.tv_do_casal
  command: system.notifications/createAlert
  payload:
    message: Campainha acionada. Deseja ver a Câmera?
    buttons:
      - label: ABRIR CÂMERA
        service: media_player.select_source
        target:
          entity_id: media_player.tv_do_casal
        data:
          source: HDMI 2
      - label: CANCELAR

Does anyone have a solution?

Finally it worked!

service: webostv.command
data:
  entity_id: media_player.tv_do_casal
  command: system.notifications/createAlert
  payload:
    message: "CAMPAINHA ACIONADA! Deseja abrir a Câmera?"
    buttons:
      - label: Sim, abrir Câmera.
        onClick: "luna://com.webos.service.applicationmanager/launch"
        params:
          id: "com.webos.app.hdmi2"
      - label: NÃO

Hijacking his topic to post my solution with the net Webhook Get ability:

message: "Movie Time?"
buttons:
      - label: Yes
        onClick: "luna://com.webos.service.downloadmanager/download"
        params:  
          target: "http://Super-secret webhook"
          targetDir: "/tmp"
      - label: No

In my case this toggles a binary_switch.
Not sure what happens with all the downloads, and if they will fill up the system eventually.

I’m still figuring out what directory could be used to download the file to, so it will get cleaned automatically. If someone has some tips, that would be awesome.

2 Likes

Maybe you should try to set targetDir to /dev/null ?