Skip to content
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

[upnpcontrol] UPnP control binding initial contribution #7941

Merged
merged 46 commits into from
Aug 13, 2020

Conversation

mherwege
Copy link
Contributor

This binding controls UPnP servers and renderers. It finds UPnP servers and renderers in the network and allows querying the server content directory and sending it to a renderer for playback.
It should be device independent and only implement (a subset of) the UPnP AV Media 1.0 standard. There is no device specific logic, and this should be kept out of this binding. E.g. switching on/off a device is not part of the UPnP standard and should be done using a different mechanism not part of this binding.
It is roughly based on previous work done in the Sonos binding.

All media renderers will also be registered as audio sinks in openHAB.

This binding has been in development for a while and has been discussed on the forum in this thread.

The binding uses DynamicStateDescriptionProvider and DynamicCommandDescriptionProvider extensively. Current UI's have limited support for a dynamic refresh of these option lists. See openhab-core#1505 and openhab/openhab-addons#7396 (comment).
Also, it would benefit from better support of text input fields in UI's, see openhab-core#1523.

Anyway, it has proven useful for a number of users in the current state, therefore submitting this for review.

Signed-off-by: Mark Herwege mark.herwege@telenet.be

@mherwege mherwege requested a review from a team as a code owner June 18, 2020 21:38
@mherwege mherwege changed the title UPnP control binding [upnpcontrol] UPnP control binding initial contribution Jun 18, 2020
@5iver
Copy link

5iver commented Jun 18, 2020

Thank you, Mark! I have used this binding from the time it was made available on the forum and it has worked very well for me with 12 renderers and several media servers.

In case anyone is going to test this build (https://openhab.jfrog.io/openhab/libs-pullrequest-local/org/openhab/addons/bundles/org.openhab.binding.upnpcontrol/2.5.7-SNAPSHOT/org.openhab.binding.upnpcontrol-2.5.7-SNAPSHOT.jar), be sure the remove all of the Things created with older versions of the binding. This may require force removal. If not, you will run into some errors for each renderer.

@Hilbrand Hilbrand added the new binding If someone has started to work on a binding. For a new binding PR. label Jun 19, 2020
Copy link
Member

@Hilbrand Hilbrand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Mark. I did a review. Mostly minor comments.

@mherwege
Copy link
Contributor Author

@Hilbrand Many thanks for your extremely rapid review. I have taken much more time going through it, but learned a lot in doing so. Especially the ListIterator got me stuck. The fit was less natural than anticipated.

@TravisBuddy
Copy link

Travis tests were successful

Hey @mherwege,
we found no major flaws with your code. Still you might want to look at this logfile, as we usually suggest some optional improvements.

Copy link
Member

@Hilbrand Hilbrand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a second review, just some additional comments.

@TravisBuddy
Copy link

Travis tests were successful

Hey @mherwege,
we found no major flaws with your code. Still you might want to look at this logfile, as we usually suggest some optional improvements.

@mherwege
Copy link
Contributor Author

@Hilbrand Thank you again for your very quick review. I believe I have addressed your comments. Can you check? I did not change stop to a trigger channel. Please comment.

@TravisBuddy
Copy link

Travis tests were successful

Hey @mherwege,
we found no major flaws with your code. Still you might want to look at this logfile, as we usually suggest some optional improvements.

1 similar comment
@TravisBuddy
Copy link

Travis tests were successful

Hey @mherwege,
we found no major flaws with your code. Still you might want to look at this logfile, as we usually suggest some optional improvements.

@TravisBuddy
Copy link

Travis tests were successful

Hey @mherwege,
we found no major flaws with your code. Still you might want to look at this logfile, as we usually suggest some optional improvements.

@fwolter fwolter added the cre Coordinated Review Effort label Jul 5, 2020
@fwolter fwolter self-assigned this Jul 9, 2020
Copy link
Member

@fwolter fwolter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two checkstyle warnings left:

[WARNING] .binding.upnpcontrol\README.md:[39]
The line after a Markdown list must be empty.
[WARNING] .binding.upnpcontrol\README.md:[65]
The line after a Markdown list must be empty.

@mherwege
Copy link
Contributor Author

There are two checkstyle warnings left:

[WARNING] .binding.upnpcontrol\README.md:[39]
The line after a Markdown list must be empty.
[WARNING] .binding.upnpcontrol\README.md:[65]
The line after a Markdown list must be empty.

@fwolter Not sure what to do with this. When I insert an empty line, it will create a new list entry. That is not the purpose. There are multiple sentences on each list entry, to be concatenated into one list entry. Guidline is to start each sentence on a new line. That's why I ignored the warning.

@fwolter
Copy link
Member

fwolter commented Jul 13, 2020

@fwolter Not sure what to do with this. When I insert an empty line, it will create a new list entry. That is not the purpose. There are multiple sentences on each list entry, to be concatenated into one list entry. Guidline is to start each sentence on a new line. That's why I ignored the warning.

Ok, that sounds reasonable.

@TravisBuddy
Copy link

Travis tests were successful

Hey @mherwege,
we found no major flaws with your code. Still you might want to look at this logfile, as we usually suggest some optional improvements.

@mherwege
Copy link
Contributor Author

@fwolter Many thanks for your review and help on this.
I believe I have addressed your review comments, but still would like you to carefully review synchronization in the binding. I did not make a change to the currentQueue synchronization. I am not sure it is required, but am happy for you to guide me on this if I don't understand it right. I did introduce some synchronization in other places. Can you check if I did that right?
Let me know what you think. I will run through a few more tests to make sure I didn't break anything in the mean time.

@TravisBuddy
Copy link

Travis tests were successful

Hey @mherwege,
we found no major flaws with your code. Still you might want to look at this logfile, as we usually suggest some optional improvements.

@mherwege
Copy link
Contributor Author

mherwege commented Jul 15, 2020

@fwolter I did test it a few more times and did not discover issues so far. Looking forward to your feedback.

@Hilbrand Hilbrand requested a review from fwolter July 15, 2020 12:46
@5iver
Copy link

5iver commented Jul 17, 2020

@mherwege, I will do some more tests this weekend, but it appears that the states of the Items are not updating properly with this version of the binding. The logs seem to show the subscriptions are OK and being renewed. I'm specifically noticing it with the state of the player. Rolling back to an older version gets them working again.

@mherwege
Copy link
Contributor Author

@openhab-5iver

I will do some more tests this weekend, but it appears that the states of the Items are not updating properly with this version of the binding. The logs seem to show the subscriptions are OK and being renewed. I'm specifically noticing it with the state of the player. Rolling back to an older version gets them working again.

Thanks for reporting. Is it all items? Can you get me a debug log? Any idea when the problem was introduced?

@5iver
Copy link

5iver commented Jul 17, 2020

I've been testing the newer version since you submitted it, but I'd noticed my audio alerts were timing out, since the player Items were not reporting their state. I suspect it is all of the Items though. I plan to do some more testing and debugging this weekend.

Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
@TravisBuddy
Copy link

Travis tests were successful

Hey @mherwege,
we found no major flaws with your code. Still you might want to look at this logfile, as we usually suggest some optional improvements.

Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
@TravisBuddy
Copy link

Travis tests were successful

Hey @mherwege,
we found no major flaws with your code. Still you might want to look at this logfile, as we usually suggest some optional improvements.

@mherwege mherwege requested a review from fwolter August 12, 2020 15:45
Copy link
Member

@fwolter fwolter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, but there are some formatting issues. You can view them with mvn spotless:check -Dspotless.check.skip=false and fix them with mvn spotless:apply.

Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
@mherwege mherwege requested a review from fwolter August 13, 2020 06:16
@mherwege
Copy link
Contributor Author

@fwolter Thank you. Formatting should be OK now.

@TravisBuddy
Copy link

Travis tests were successful

Hey @mherwege,
we found no major flaws with your code. Still you might want to look at this logfile, as we usually suggest some optional improvements.

@fwolter fwolter merged commit 88d9f2a into openhab:2.5.x Aug 13, 2020
@fwolter fwolter removed the cre Coordinated Review Effort label Aug 13, 2020
@fwolter fwolter added this to the 2.5.8 milestone Aug 13, 2020
@mherwege
Copy link
Contributor Author

mherwege commented Aug 13, 2020

@fwolter Thank you for your review.
@openhab-5iver Thank you for testing. I have continued working on this binding and added a number of things I will submit in a follow-up PR. I added a number of channels to the renderer, and volume and mute should now also properly update in openHAB when changed on the device. It is already in my github, a compiled version is here. I would be keen to hear your feedback before submitting the follow-up PR.

@5iver
Copy link

5iver commented Aug 14, 2020

@mherwege, I've tested your updates and the volume works great. Changing the volume though OH works. Changing the volume in another control point or manually on the speaker reflects the new state in OH.

The mute is a little odd though. When it turns on, it immediately turns off, but the message is sent through UPnP and the speaker mutes. You need to turn it on again to be able to turn it off. Possibly an issue with autoupdate?

2020-08-14 18:48:14.742 [INFO ] [smarthome.event.ItemCommandEvent] - Item 'DS_FamilyRoom_Speaker_Mute' received command ON
2020-08-14 18:48:14.744 [INFO ] [smarthome.event.ItemStatePredictedEvent] - DS_FamilyRoom_Speaker_Mute predicted to become ON
2020-08-14 18:48:14.748 [INFO ] [smarthome.event.ItemStateChangedEvent] - DS_FamilyRoom_Speaker_Mute changed from OFF to ON
2020-08-14 18:48:14.886 [INFO ] [smarthome.event.ItemStateChangedEvent] - DS_FamilyRoom_Speaker_Mute changed from ON to OFF
2020-08-14 18:48:14.749 [DEBUG] [org.openhab.binding.upnpcontrol.internal.handler.UpnpRendererHandler] - Handle command ON for channel upnpcontrol:upnprenderer:5f9ec1b3-ed59-1900-4530-0007f522dcaf:mute on renderer Family Room
2020-08-14 18:48:14.757 [DEBUG] [org.openhab.binding.upnpcontrol.internal.handler.UpnpHandler] - Upnp device Family Room invoke upnp action SetMute on service RenderingControl with inputs {InstanceID=0, Channel=Master, DesiredMute=1}
2020-08-14 18:48:14.758 [DEBUG] [org.openhab.binding.upnpcontrol.internal.handler.UpnpHandler] - Upnp device Family Room invoke upnp action SetMute on service RenderingControl reply {}
2020-08-14 18:48:14.884 [DEBUG] [org.openhab.binding.upnpcontrol.internal.handler.UpnpRendererHandler] - Upnp device Family Room received variable LastChange with value <Event xmlns="urn:schemas-upnp-org:metadata-1-0/RCS/">
  <InstanceID val="0">
    <Mute channel="Master" val="1"/>
  </InstanceID>
</Event> from service RenderingControl
2020-08-14 18:48:14.885 [DEBUG] [org.openhab.binding.upnpcontrol.internal.handler.UpnpRendererHandler] - Upnp device Family Room received variable InstanceID with value 0 from service RenderingControl
2020-08-14 18:48:14.885 [DEBUG] [org.openhab.binding.upnpcontrol.internal.handler.UpnpRendererHandler] - Upnp device Family Room received variable MuteMaster with value 1 from service RenderingControl

I see Channels for Volume, LF Volume, and RF Volume. Same for Mute. What are these for? Main, left, and right stereo channels? None of these Channels seemed to change anything on my speakers. A more descriptive name would be helpful.

@mherwege
Copy link
Contributor Author

@openhab-5iver The error with mute should be fixed in my branch.
LF stands for left front, RF stands for right front. These are used in stereo for the left and right channels, but also other setups. In that case more channels for center, left and right back, bass etc. That's why I sticked to the lfvolume and rfvolume naming, matching the upnp channel naming used internally. I might add other channels in the future. leftfrontvolume just looked too long. The channel descriptons and readme contain the full text.

@5iver
Copy link

5iver commented Aug 17, 2020

The channel descriptons and readme contain the full text.

This was my concern... all I saw for the description was LF/RF Volume.

The error with mute should be fixed in my branch.

Excellent. I'll try out the latest. I was also noticing this with Stop. I just spent a few hours learning to Browse and Search. I almost have it working, but I must be doing something wrong, since it always seems to take two tries before a playlist will update, even with long sleeps separating the steps. I'll do more testing and provide more details later.

@mherwege
Copy link
Contributor Author

mherwege commented Aug 17, 2020

This was my concern... all I saw for the description was LF/RF Volume.

The label is abreviated, the description in the channel type definition is not.

I was also noticing this with Stop.

That's a different thing. Stop is not a state, only a command channel. Therefore, you can only give the stop command and the player control channel should then go to pause mode. For that reason, I veto autoupdate for this channel, which means it will pass on the stop command to the renderer, but not update the UI. In the UI, it will act like a pushbutton, see the readme for a sitemap example.

I just spent a few hours learning to Browse and Search. I almost have it working, but I must be doing something wrong, since it always seems to take two tries before a playlist will update, even with long sleeps separating the steps.

I have always tested this from a UI (PaperUI or BasicUI). While you have to refresh the browser each time you change a value (the DynamicState and DynamicCommand Descriptions don't get updated otherwise), this worked for me. However, the thing about a UI is that you wait until all data has been refreshed. Doing it from rules may indeed create timing issues here.

The binding essentially never waits for a response and returns immediately after giving a upnp command. The response is handled as they come in. But that may create issues if a new command is dependent on the previous response. I have solved that in a few instances by introducing some futures, and may have to do the same thing when browsing or searching (i.e. don't browse or search when the previous browse or search didn't return a result yet). I could make everything synchronuous, but I fear this will keep the handlers tight up for too long and make the whole thing less responsive. Using some futures will insert some waits, but only when absolutely required. See how far you get without this before me introducing that.

andrewfg pushed a commit to andrewfg/openhab-addons that referenced this pull request Aug 31, 2020
Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
andrewfg pushed a commit to andrewfg/openhab-addons that referenced this pull request Aug 31, 2020
Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
andrewfg pushed a commit to andrewfg/openhab-addons that referenced this pull request Aug 31, 2020
Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
andrewfg pushed a commit to andrewfg/openhab-addons that referenced this pull request Aug 31, 2020
Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
DaanMeijer pushed a commit to DaanMeijer/openhab-addons that referenced this pull request Sep 1, 2020
Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
Signed-off-by: Daan Meijer <daan@studioseptember.nl>
CSchlipp pushed a commit to CSchlipp/openhab-addons that referenced this pull request Sep 12, 2020
Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
markus7017 pushed a commit to markus7017/openhab-addons that referenced this pull request Sep 19, 2020
Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new binding If someone has started to work on a binding. For a new binding PR.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants