-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP][lgwebos] Detection of power on/off with UPnP #7122
Conversation
@sprehn : I let you check but it works very well for me. I tested fully the following cases:
In these cases, I see the Power channel immediately updated when TV switched on or off. |
2675a80
to
6eeb0f1
Compare
on my TV this version does not give any improvement yet. the following method gets called with status false exactly when the websocket connection breakes, 20-30seconds after the screen goes dark.
in thingDiscovered I think we should check for the MediaRenderer with same host as our TV. |
Do you have the UPnP Device Spy app on your PC ? As I told you, in my case, I see the 4 UPnP devices appearing/disappearing immediately when I use the standby button of the remote control. So it does not matter what UPnP device is considered by the discovery service. In my case, the 4 UPnP devices have the same "friendly name". Note that I think we should rather use this "friendly name" to set the model name property. As soon as you confirm that the MediaRenderer UPnP device is the one to consider because it appears/disappears faster, I update the discovery code. This is only a minor change to do in the class LGWebOSUpnpDiscoveryParticipant (mainly in the method getThingUID). All the other code I introduced will remain unchanged. |
Hi, using a macbook and Upnp Analyser, but this does not seem to capture those events nicely so that it actually helps me. To debug the situation I use the shutdown detector code:
I see device urn:schemas-upnp-org:device:MediaRenderer:1 and its services immediatly and only 24 seconds later the service urn:lge-com:service:webos-second-screen:1 go down.
If we changed what we listen for in LGWebOSUpnpDiscoveryParticipant, then it would change the deviceId for all current users, and we know that listening for urn:lge-com:service:webos-second-screen:1 works well for discovery. btw. thingRemoved already got called without registering as UpnpIOParticipant or my ShutdownDetector when webos-second-screen disappears - only too late. I thought the whole point was to use UpnpIOParticipant to react on a different device. But question would remain how we can discover it's UDN. |
Would it be ok to go through all devices in the registry once connected and attempt to find the one which matches MediaRenderer on the same host:
it would be sufficient to store that device's UDN in a property and we could then register the UpnpIOParticipant based on it. |
If we change the UPnP device you are relying on in the discovery service, this will be fully transparent for any user and they will not have to relink channels. The deviceId is only a property of the current thing. It is also used as in the thing UID as default thing id but any user could have changed it. I will update the code this evening, so that at least you can then confirm that it is working better for you. Addtionnaly I will think if the discovery service can rely on the two UPnP devices. This could require to change the representation property to something else. |
6d84479
to
69adaed
Compare
@sprehn : can you please make a new try after my last change ? It is possible that implementing UpnpIOParticipant is finally useless and that implementing DiscoveryListener could be sufficient. |
Additionally I will evaluate if we can keep a simple property to store the UDN, It would avoid the edition of the thing configuration. I have the feeling it could work. |
Hi, |
bc6c02b
to
d84ae46
Compare
I rebased my PR to have in my branch all the recently merged changes. |
Travis tests were successfulHey @lolodomo, |
d84ae46
to
24c0893
Compare
Travis tests were successfulHey @lolodomo, |
@sprehn : I have now terribly simplified my proposal. Everything is based on the discovery service. No need for additional JUPnP stuff, no need to transform the deviceId property into a configuration setting. |
24c0893
to
8bde76d
Compare
Travis tests were successfulHey @lolodomo, |
1 similar comment
Travis tests were successfulHey @lolodomo, |
@sprehn : I integrated two fix:
|
Travis tests were successfulHey @lolodomo, |
Hi @lolodomo Re "Ignore power off command when the TV is already off" So it seams the TV actually starts up again, if it receives a second "ssap://system/turnOff" message, during a specific time window while shutting down. Your proposed fix should prevent that we sent "ssap://system/turnOff" twice, if the user sends two OFF events. Seems to be a counter intuitive response to a "turnOff" request, so maybe it means it aborts shutdown. Now I wonder, will this be the same, if the user sends any another event, e.g. "ssap://tv/channelUp" while shutting down? If so, we should handle this further down in the socket implementation's state. I actually had a state DISCONNECTING at some point, which I later removed. We could use this to ignore any events being sent to the TV during shutdown. |
@sprehn : will you review and validate at least few of my changes if I cut this PR into several separate PRs, even if you have no way to test ? |
I updated my rule that was triggering the issue. I now increase the volume, mute it and set a new channel. I will see what happens after few days but I guess these commands will be just ignored and will not turn on the TV. like "ssap://system/turnOff" can do. |
@sprehn : I created separate PRs with the hope we can merge few fixes quickly without your testing, while the main part of this PR will require your testing. |
929988e
to
b82002c
Compare
Travis tests were successfulHey @lolodomo, |
New rebase done to fix the conflict. |
Travis tests were successfulHey @lolodomo, |
@sprehn : I can confirm that I did not encounter any problem since the change. I thing the problem is really solved now and was only a problem with the "ssap://system/turnOff" command. |
...lgwebos/src/main/java/org/openhab/binding/lgwebos/internal/handler/LGWebOSConfiguration.java
Outdated
Show resolved
Hide resolved
if (host != null && host.equals(getLGWebOSConfig().getHost())) { | ||
// Thing matching the discovery | ||
|
||
// Update the thing properties from the discovery result |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why update properties from discovery result. Isn't this already handled in UpnpDiscoveryParticipant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so the media renderer will not have those additional properties I assume... ok, fine for me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If your thing is declared in a config file, it will have no properties set after startup. And it will not be set by the thing discovery.
Of course, the framework core code will check first if there are any change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And of course, we absolutely need to change (if necessary) the deviceId property.
This allows an automatic update of all existing things when you move from the old code to the new code.
&& device.getDetails().getManufacturerDetails().getManufacturer().toUpperCase() | ||
.contains("LG ELECTRONICS") | ||
&& device.getDetails().getModelDetails().getModelDescription() != null | ||
&& device.getDetails().getModelDetails().getModelDescription().toUpperCase().contains("WEBOSTV")) { | ||
logger.debug("Found LG WebOS TV: {}", device); | ||
return new ThingUID(THING_TYPE_WEBOSTV, device.getIdentity().getUdn().getIdentifierString()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do agree that this will work if in case manufacturer and model descriptor match. I have certainty if all devices will consistently report values this way. If so, it should work.
This will be a different ID compared to the second screen device. and the representational property will be different. So I do think all users will see a new discovery result, next to their previously discovered TV.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll need to test this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not fully sure whether the previous discovery will be kept. Maybe just replaced.
But you certainly understood that the users will have nothing to change on their things. Their deviceId property will be updated automatically by the binding.
// .withProperty(PROPERTY_MODEL_NAME, | ||
// device.getDetails().getModelDetails().getModelName() + " " | ||
// + device.getDetails().getModelDetails().getModelNumber()) | ||
.withProperty(PROPERTY_MODEL_NAME, device.getDetails().getFriendlyName()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure you want friendly name in label and model?
why not use modelname + model number as you proposed earlier?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because they are not what we expect on this device.
For example, in my case:
- modelname = LG TV
- modelNumber = 1.0
friendlyName remains the same on all devices.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Friendly name is what the user sets as the name in the TV settings. It is not necessarily the model.
...nding.lgwebos/src/main/java/org/openhab/binding/lgwebos/internal/handler/LGWebOSHandler.java
Outdated
Show resolved
Hide resolved
...nding.lgwebos/src/main/java/org/openhab/binding/lgwebos/internal/handler/LGWebOSHandler.java
Outdated
Show resolved
Hide resolved
...nding.lgwebos/src/main/java/org/openhab/binding/lgwebos/internal/handler/LGWebOSHandler.java
Outdated
Show resolved
Hide resolved
logger.debug("thingDiscovered: discovery with UID {} matching thing {}", result.getThingUID(), | ||
getThing().getUID()); | ||
|
||
channelHandlers.get(CHANNEL_POWER).onDeviceReady(CHANNEL_POWER, this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
websocket connected iff power on
for users, which don't use upnp this wont work.
it may create a situation, when power channel is on, but we are not connected yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand this part of your comment "for users, which don't use upnp this wont work.". The binding uses UPnP discovery, this is not a user's choice.
And for the few users having UPnP not working in their network, of course this PR will not help them as it is based on UPnP. But it probably concerns only a very small minority.
You are right, it can happen, at startup, that the channel is set to ON just before the websocket is connected and TV is considered as registered, as this is done in parallel by 2 different threads.
But this is required to have a fast update of the channel when you power on the TV while the websocket was still alive and connected.
In fact, the goal of this PR is a fast update of the power channel (ON or OFF), not based on websocket connection status because the websocket remains connected during a certain time after the TV is switched to OFF.
But I agree that this channel represents whether the TV is ON or OFF, not whether the websocket is connected and TV is registered. This is an essential point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Considering the PR #7355, I think that state update to ON will become unnecessary.
public void thingRemoved(DiscoveryService source, ThingUID thingUID) { | ||
if (!udn.isEmpty() && thingUID.getId().equals(udn)) { | ||
logger.debug("thingRemoved: discovery with UID {} matching thing {}", thingUID, getThing().getUID()); | ||
channelHandlers.get(CHANNEL_POWER).onDeviceRemoved(CHANNEL_POWER, this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment as in thing discovered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line is the most important line of this PR. It does what you expect since a long time, that is updating the power channel to OFF as fast as possible, even when the websocket is still connected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Considering the PR #7355, I think that state update to OFF will become unnecessary.
b82002c
to
6c1d7df
Compare
Travis tests were successfulHey @lolodomo, |
Also fix openhab#7119 Signed-off-by: Laurent Garnier <[email protected]>
6c1d7df
to
c884e1b
Compare
New rebase. |
Travis tests were successfulHey @lolodomo, |
In fact, with PR #7355 handling the update of the power channel state, I think this PR could become simply useless. |
The only interest will be the update of few properties we get only through UPnP discovery. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// .withProperty(PROPERTY_MODEL_NAME, | ||
// device.getDetails().getModelDetails().getModelName() + " " | ||
// + device.getDetails().getModelDetails().getModelNumber()) | ||
.withProperty(PROPERTY_MODEL_NAME, device.getDetails().getFriendlyName()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Friendly name is what the user sets as the name in the TV settings. It is not necessarily the model.
The main goal of this PR has disappeared after the merge of the PR #7355 |
Also fix #7119
Signed-off-by: Laurent Garnier [email protected]