openhab / openhab-addons

Add-ons for openHAB
https://www.openhab.org/
Eclipse Public License 2.0
1.86k stars 3.57k forks source link

[WIP] Denon/Marantz 2.0 Binding #2204

Closed jwveldhuis closed 6 years ago

jwveldhuis commented 7 years ago

Hi all,

I started to work on a 2.0 Binding for Denon/Marantz AVR's. The 1.x Binding created by @idserda isn't working OK in OH2 and it doesn't seem like an easy upgrade to 2.0 from the existing code base, so I decided to start from scratch (and of course will reuse bits and pieces of the controlling logic were possible, the code of the 1.x Binding is well written). Let me know if someone else already started on this so we can collaborate.

As I did not develop any OH Binding before, so it will take me some time to get acquainted with the development process. Already got the IDE up and running and a skeleton binding working (thanks to the excellent documentation on docs.openhab.org and eclipse.org/smarthome :+1:)

I'm looking at the existing Pioneer, Yamaha and Onkyo Bindings for inspiration. When the time is there I need testers, as I only own 1 Marantz AVR myself ;)

Any advice I should look into before starting the implementation?


Update - 30 December 2017

The binding is almost finished and I'll sent it in for review soon. In the meantime you can install the binding manually:

GRORI commented 7 years ago

Hi jwveldhuis,

I've never did anything like developing a binding, but I have a Denon X4300H and a running OH 2 instance at home. Please contact me if You think Your binding is ready to be tested.

BR GRORI

neohusky commented 7 years ago

Count me in. I have a marantz SR5009

jwveldhuis commented 7 years ago

@orificer @neohusky will do, thanks for the offer! It will take some time before I have something working. Have a Marantz SR5008 myself.

tmrobert8 commented 7 years ago

If you need a tester - I have a denon 5200w that I'd love to automate but haven't had the time to write a binding for. Likewise feel free to bounce stuff off me if you need (I've done 4 bindings now)

idserda commented 7 years ago

The current 1.x binding should work fine with 2.0, what problems are you having? Some minor issues do not really justify a complete rewrite 😃 If you want to add auto discovery and conform to the 2.0 item/channel structure however creating a 2.0 binding sounds like a good plan. I would reuse all the parts off the current binding that handle communication with the receiver (telnet listener and creating/parsing the XML http-messages) and create a new Handler to communicate it all back/from OH2. Let me know if you have any questions, I'd be happy to test the new binding.

jwveldhuis commented 7 years ago

Hi @idserda! Well, the telnet connection didn't work at all for me in OH2 and lot's of others complained in the community about not getting it to work. Not sure what really causes those issues, but thought it would be good anyway to get it 2.0 ready and debug along the way. Working on auto discovery now. My SR5008 responds to mDNS :smile: so I think it will not be that hard.

While I was digging more into the code today I can see your 1.x binding is structured really well, so the 'from scratch' comment is not so much applicable anymore. And the protocol is stable indeed, no need to do any rewrites there. I think 80-90% of the code can be ported with minor modifications (and of course will leave the authors credits :wink: )

idserda commented 7 years ago

Ok great stuff! Telnet works in 2.0 with a Denon AVR-X2000, maybe there are some subtle differences in the Marantz receivers (or something else is using the telnet connection, most receivers only support one concurrent connection).

Very cool that auto discovery is already working! Defining the things/channels probably takes a bit more time 😃

jwveldhuis commented 7 years ago

@idserda @tmrobert8 @orificer if you could do me a favor and collect input for auto discovery? What is the output for the following command (Linux, preferably from the box running OpenHAB): $ avahi-browse -kv _raop._tcp (you might need to install the avahi-utils package)

I hope it is similar to mine, e.g. 'serial number'@{Marantz/Denon} {Model} This is mine:

Server version: avahi 0.6.32-rc; Host name: openhab2.local
E Ifce Prot Name                                          Type                 Domain
+ enp0s10 IPv4 0006781D58B1@Marantz SR5008                   _raop._tcp           local
idserda commented 7 years ago

Here you go, seems to match the format:

Server version: avahi 0.6.32-rc; Host name: fruitschaal.local
E Ifce Prot Name                                          Type                 Domain
+    br0 IPv4 0005CD3AB07D@Denon AVR-X2000                  _raop._tcp           local
GRORI commented 7 years ago

Looks identical:

Server version: avahi 0.6.31; Host name: Pi-Prod.local
E Ifce Prot Name                                          Type                 Domain
+   eth0 IPv4 0005CD75215C@Denon AVR-X4300H                 _raop._tcp           local
jwveldhuis commented 7 years ago

Thanks guys for the prompt response! This is great news, it means both the Denon and Marantz (when 'Airplay capable') can be discovered like this.

jwveldhuis commented 7 years ago

Status update: -Discovery is working like a charm! I'm using the serial number to prevent duplicate results. -Changed the telnet client loop to use a BufferedReader, to prevent chopped / incomplete commands from being processed -Defined channels -Lot's of testing around properly disconnecting / disposing the connection (updating the Thing is triggering a dispose->initialize on the Handler)

Still a lot of work remaining. Due to the different concepts in OH2 a lot of refactoring is needed. E.g. dedicated ThingHandler vs Binding handling multiple instances. Trying to find some way to represent the State of the AVR and trigger the Handler using a 'StateChangeListener', e.g. have an object with all fields with the properties of the AVR. When a property is updated (to a different value) it should trigger the Handler which then can send the appropriate 'sendUpdates'. Something like that was done in the old binding, but it's implementation is scattered over the different parts of the 1.x Binding. That's part of the puzzle that's fun to solve, but it will take some more time to come up with a proper implementation.

Also want to implement telnet as follows: -if telnet is enabled, try to use it. -if it fails, fall back to HTTP polling until telnet is available

With OH1 I was using a telnet multiplexer (simple python script), which I connected to the AVR. The multiplexer can handle multiple concurrent connections, so I had OH1 connected to the mulitplexer and could still use the dedicated remote control apps (requiring telnet) on my phones and tablets (also connected to the multiplexer).

jwveldhuis commented 7 years ago

I'm too busy these days to make good progress on this binding. It is a lot more work than I initially hoped it would be (also because I started to refactor more and more ;) ). I will still continue to work on it, though thought it was a good moment to push some the current work to my own fork ;) https://github.com/jwveldhuis/openhab2-addons/tree/denon-marantz-binding

Commit containing the changes: https://github.com/jwveldhuis/openhab2-addons/commit/99af48b9947071d4d9b0b226f591ad0490b6c4b9

TODO

What should work

It's definitely not ready yet to use 'in production', but if someone wants to test the 'what should work' list above or wants to provide early feedback, don't hesitate ;)

GRORI commented 7 years ago

I do not have a lot of time at the moment, too. But I think I will be able to find the time to to a short test of the "what should work" list.

As this is the first binding where I want to test at an early state of the development: Is there a short summary what I need to do to get the needed jar file out of the two links posted by jwveldhuis?

jacksteraz commented 7 years ago

Server version: avahi 0.6.31; Host name: openHABianPi.local E Ifce Prot Name Type Domain

stotz89 commented 7 years ago

Hello guys, I really want to add the binding to my openHAB2 installation. The problem is, I have no idea how...Could you give me a hint how to do it? I installed openHAB2 on ubuntu. My /usr/share/addons folder contains two files (openhab-addons-2.1.0.kar and openhab-addons-legacy-2.1.0.kar). I cloned the repository already but I have no clue how I can add the new denon/marantz binding so that I can see/use it in PaperUI or HABmin.

I would really appreciate your help, thanks.

jwveldhuis commented 7 years ago

@stotz89 the binding is still needs some work to use it in 'production'. I believe the jar files for bindings under development are generated once a pull request is done against the master repository, hopefully will have time next month to pick up work on this binding.

If you want to try out the current version you need to run OpenHAB using the Eclipse IDE: http://www.eclipse.org/smarthome/documentation/development/ide.html and switch the repository to my fork.

JannikJung commented 6 years ago

@jwveldhuis Did you find time to continue working on the binding?

jwveldhuis commented 6 years ago

@JannikJung not yet, will try to find out how to publish the current version for testing.

idserda commented 6 years ago

I made a small change to the 1.x binding, it now sends commands over the telnet connection too. Before, it would always use the http interface to issue commands, but not all receivers supported this. You might want to use this in the 2.x binding too. PR is here: https://github.com/openhab/openhab1-addons/pull/5342

jwveldhuis commented 6 years ago

@idserda thanks, will also get rid of the Apache TelnetClient as you mentioned to be problematic.

jwveldhuis commented 6 years ago

2859

Just submitted initial PR for the new binding, hope it will generate the required jar files to enable testing by others (because it's not perfect yet). Discovery, Telnet and HTTP control should work, as well as sending a custom command through the 'command' Channel.

jwveldhuis commented 6 years ago

jar file of DenonMarantz 2.0 binding (BETA, work in progress!) https://openhab.jfrog.io/openhab/libs-pullrequest-local/org/openhab/binding/org.openhab.binding.denonmarantz/2.2.0-SNAPSHOT/org.openhab.binding.denonmarantz-2.2.0-SNAPSHOT.jar

Put this jar file in /usr/share/openhab2/addons and go to the Inbox in Paper UI

You all are very welcome to test this binding and let me know any issues or suggestions.

jwveldhuis commented 6 years ago

@orificer @stotz89 @neohusky @tmrobert8 @jacksteraz @JannikJung @idserda

The binding is ready to be tested (finally found time and motivation to continue, sorry for the wait)

Some remarks:

stotz89 commented 6 years ago

@jwveldhuis Thanks a lot for your effort.

I just had a quick look at it. I downloaded it and added it to my add-on-folder. Discovery of my Marantz NR1604 worked perfectly. Both zones were recognized. (Btw my openHAB runs on openHAB 2.1.0 - release build - ) I also linked all channels to an item. Worked also fine. I only tested some commands like switching on/off, volume +/-, mute on/off, mainzone on/off. Everything worked as expected.

As soon as I have some more time to test, I will report. But for the first build looks quiet promising. Thanks!

b8rother commented 6 years ago

@jwveldhuis Great work on the binding.

I have installed the binding on openHAB 2.2.0 and I'm using Denon AVR-X2200W. All the configuration that I'm doing is via PaperUI. Discovery of the Thing works great. Linking of the Channels for Main Zone and Zone2 (AVR-X2200W has got only 2 zones) are working as expected and Controls are working fine. I have tested all switches (Power, Main Volume, Input source) and String fields (Now playing - artist, track, album, Surround program) and they are working fine.

pabloNZ commented 6 years ago

Works very well with my Denon X3200W with auto detection through PaperUI. Do you have any notes on how to set up a .things file appropriately? Thanks for all the hard work!

jwveldhuis commented 6 years ago

@pabloNZ what do you mean with a .things file? Do you mean a .items file? I don't use Paper UI to link items to things, I exclusively use text based files (as I was used to with OpenHAB 1.x and had bad experience with having a mixed approach)

This is my current list of items (you can copy the channels in Paper UI -> Things -> "Your Receiver"). Note some Channels are only shown when clicking Show More, especially the :command channel)

marantz.items

Switch marantz_power    "Receiver" <switch>         {channel="denonmarantz:avr:0006781d58b1:power"}
Dimmer marantz_volume   "Volume"   <soundvolume>    {channel="denonmarantz:avr:0006781d58b1:mainVolume"}
Switch marantz_mute     "Mute"     <mute>           {channel="denonmarantz:avr:0006781d58b1:mute"}
Switch marantz_z2power  "Zone 2"                    {channel="denonmarantz:avr:0006781d58b1:zone2Power"}
String marantz_input    "Input [%s]"                {channel="denonmarantz:avr:0006781d58b1:input" }
String marantz_surround "Surround: [%s]" <surround> {channel="denonmarantz:avr:0006781d58b1:surroundProgram"}
String marantz_command                              {channel="denonmarantz:avr:0006781d58b1:command"}

and this is the relevant part of my sitemap (still trying how to best present the receiver)

default.sitemap

...
Group item=marantz_input label="Receiver" icon="receiver" {
  Default   item=marantz_power
  Default   item=marantz_mute      visibility=[marantz_power==ON]
  Setpoint  item=marantz_volume    label="Volume [%.1f]" minValue=0 maxValue=40 step=0.5  visibility=[marantz_power==ON]
  Selection item=marantz_input     mappings=[TV=TV,MPLAY=Kodi]  visibility=[marantz_power==ON]
  Default   item=marantz_surround  visibility=[marantz_power==ON]
}
...

in a .rules file you can send commands (See reference documents linked at the old binding wiki) Example to switch to MULTI CH STEREO: sendCommand(marantz_command,"MSMCH STEREO") or marantz_command.sendCommand("MSMCH STEREO")

pabloNZ commented 6 years ago

@jwveldhuis With some of my other OH2 bindings you can set up .things files for them so that you don't have to use PaperUI to discover anything.

Your example items are helpful though, thanks for sharing.

jwveldhuis commented 6 years ago

@pabloNZ ahh ok, didn't know about the .things files. Hence I did not do any testing with that. Maybe will do and then add it to the documentation. So far only got positive feedback and the binding in my own 'production' OpenHAB is also working like expected.

Next step is to further work on the pull request to get it approved and merged into OpenHAB 2.2.

idserda commented 6 years ago

Great work on the binding! There does seem to be an issue with auto discovery on my set up, the receiver does not show up in the inbox. This is in the logs:

2017-12-04 20:45:50.274 [DEBUG] [ery.DenonMarantzDiscoveryParticipant] - AVR found: 0005CD3AB07D@Denon AVR-X2000._raop._tcp.local.
2017-12-04 20:45:50.275 [DEBUG] [ery.DenonMarantzDiscoveryParticipant] - This seems like a supported Denon/Marantz AVR!
2017-12-04 20:45:50.275 [DEBUG] [ery.DenonMarantzDiscoveryParticipant] - Could not determine IP address for the Denon/Marantz AVR

This is the output of avahi-browse, where there is an IP-address:

$ avahi-browse -kvr _raop._tcp
=    br0 IPv4 0005CD3AB07D@Denon AVR-X2000                  _raop._tcp           local
   hostname = [Denon-AVR-X2000.local]
   address = [192.168.1.70]
   port = [1032]
   txt = ["fv=s9610.1000.0" "am=AVRX2000" "vs=141.9" "vn=65537" "tp=UDP" "ss=16" "sr=44100" "sv=false" "pw=false" "md=0,1,2" "ft=0x44F8A00" "et=0,4" "da=true" "cn=0,1" "ch=2" "txtvers=1"]

Any idea what's going on? I can try to debug it in the IDE if I have some time later.

jwveldhuis commented 6 years ago

@idserda thank you for testing. I've updated the binding: https://github.com/openhab/openhab2-addons/pull/2859/commits/56e4f5ed478a0189f02954144979e9d65bf5cc76

Changed the way the host is retrieved from the MDNS info (compared with some other bindings), hope it will work now and still works for the others (tested myself and I expect it will remain working).

Binding jar file is updated: https://openhab.jfrog.io/openhab/libs-pullrequest-local/org/openhab/binding/org.openhab.binding.denonmarantz/2.2.0-SNAPSHOT/org.openhab.binding.denonmarantz-2.2.0-SNAPSHOT.jar

nelmi commented 6 years ago

Thank you very much. It work great with Denon AVR-X1400H, but only in Telnet mode.

jwveldhuis commented 6 years ago

@nelmi thank you for your feedback. If you browse to http://<IP of your Denon/ do you see a web interface? Not sure whether this model supports an HTTP API, I expect it would.

nelmi commented 6 years ago

@jwveldhuis no, the new models of Denon (AVR-X..00H) don't support web interface. When i open it in browser i receive Error 403: Forbidden Access Forbidden If you are interested, here is a link to the Denon AVR IP Protocol: https://www.denon.de/de/product/homecinema/avreceiver/avrx5200w?docname=IP_Protocol_AVR-Xx100.pdf

jwveldhuis commented 6 years ago

@nelmi ok, yes it's the same protocol for telnet. The fact that you get a HTTP 403 means it is offering some services over HTTP. Quickly checked the manual, could only find something about /Settings to setup the network settings for the AVR. There is a new Denon iOS/Android app for 2017 models, maybe they've changed the HTTP API.

Well at least it still works with telnet :)

idserda commented 6 years ago

@jwveldhuis I was running an older snapshot version of the OH2 runtime, after upgrading to the latest snapshot auto discovery was working fine 😃

jangrewe commented 6 years ago

I tried the JAR you posted a couple of days ago, unfortunately it didn't detect my AVR. Here's what avahi-browse -kvr _raop._tcp sees:

Server version: avahi 0.6.31; Host name: homebox.local
E Ifce Prot Name                                          Type                 Domain
+  wlan0 IPv4 0005CDA10537@mediabox                         _raop._tcp           local
=  wlan0 IPv4 0005CDA10537@mediabox                         _raop._tcp           local
   hostname = [mediabox.local]
   address = [192.168.0.24]
   port = [1025]
   txt = ["vs=190.9.p6" "vn=65537" "tp=UDP" "sf=0x4" "am=AVRX2300W" "md=0,1,2" "fv=p6.1400.0" "ft=0x444F8A00" "et=0,4" "da=true" "cn=0,1"]
: Cache exhausted
: All for now

This is on openHABian with the current 2.2 Snapshot. Doing a Scan with your binding in the Inbox also doesn't find anything. =(

nick1802 commented 6 years ago

@jwveldhuis , thanks for this binding in testing!!

same as jangrewe it would not auto detect my avr. but i am able to manually add and at time of typing this it is working and in the next 24hrs i will test most of the functions you have setup. below you can see i have 4 denon avr's

i like the idea of it collecting input names from the xml as i have all inputs on my avrs disabled if nothing is used in them and also renamed the ones i do use.

Server version: avahi 0.6.32; Host name: openHABianPi.local
E Ifce Prot Name                                          Type                 Domain
+   eth0 IPv4 0005CDA43706@Master / Gym                     _raop._tcp           local
+   eth0 IPv4 0005CDA413DC@Living / gym                     _raop._tcp           local
+   eth0 IPv4 0005CD41F858@Bed2 / Outside                   _raop._tcp           local
+   eth0 IPv4 0005CD5A6004@Media room                       _raop._tcp           local
=   eth0 IPv4 0005CDA43706@Master / Gym                     _raop._tcp           local
   hostname = [Master-Gym.local]
   address = [192.168.0.11]
   port = [1024]
   txt = ["vs=190.9.p6" "vn=65537" "tp=UDP" "sf=0x4" "am=AVRX3300W" "md=0,1,2" "fv=p6.1400.0" "ft=0x444F8A00" "et=0,4" "da=true" "cn=0,1"]
=   eth0 IPv4 0005CDA413DC@Living / gym                     _raop._tcp           local
   hostname = [Living-gym.local]
   address = [192.168.0.18]
   port = [1028]
   txt = ["vs=190.9.p6" "vn=65537" "tp=UDP" "sf=0x4" "am=AVRX3300W" "md=0,1,2" "fv=p6.1400.0" "ft=0x444F8A00" "et=0,4" "da=true" "cn=0,1"]
=   eth0 IPv4 0005CD41F858@Bed2 / Outside                   _raop._tcp           local
   hostname = [Bed2-Outside.local]
   address = [192.168.0.19]
   port = [1024]
   txt = ["vs=190.9.p6" "vn=65537" "tp=UDP" "sf=0x4" "am=AVRX3100W" "md=0,1,2" "fv=p6.1201.0" "ft=0x444F8A00" "et=0,4" "da=true" "cn=0,1"]
=   eth0 IPv4 0005CD5A6004@Media room                       _raop._tcp           local
   hostname = [Media-room.local]
   address = [192.168.0.10]
   port = [1024]
   txt = ["vs=190.9.p6" "vn=65537" "tp=UDP" "sf=0x4" "am=AVRX2200W" "md=0,1,2" "fv=p6.1300.0" "ft=0x444F8A00" "et=0,4" "da=true" "cn=0,1"]
: All for now
: Cache exhausted

again.. thanks for the binding! trying to add the 1.11.0 version wasn't working for me.

also im using openhabian 1.4v (2.2.0 of openhab2) released 2 days ago

jwveldhuis commented 6 years ago

@jangrewe @nick1802 thank you for testing and reporting this. So, apparantly these models do not publish the vendor name (Denon or Marantz).

I built in detection based on this pattern: 'serial number'@(Marantz|Denon) (Model) that's why it didn't discover yours.

Any suggestions to discover your models? What would be the pattern to recognize these AVRs? And do none of these support the (unofficial) HTTP API (e.g. browse to http://ip-of-avr and see a simplistic interface to control the AVR)?

nick1802 commented 6 years ago

@jwveldhuis the 3 models at i have all have browser interface. maybe cause i have named my avr's it resets the @(Marantz|Denon) (Model) part of the name? looking though the denon site in there avr part all but one start with avrx***# =number, #=2437 and all have 4 number except for the ones ending with BT only have 3.

jwveldhuis commented 6 years ago

@nick1802 ok, you can modify the name.. Good to know..

Found it in the manual of my SR5008 Marantz too:

The Friendly Name is the name of this unit displayed on the network. You can change the Friendly Name according to your preferences

Will see what I can do, maybe using that am=.. string is a better choice then, but then will need to build patterns for both Marantz and Denon in order to prevent false positives. Then we might need to update a list for each new model, not something I like..

Alternatively I could check out UPnP discovery. My Marantz is responding to UPnP as well and it has a clear field 'Manufacturer: Marantz' and a 'Friendly Name'.

jwveldhuis commented 6 years ago

@nick1802 regarding fetching the input names from the XML. That would make the binding a lot more complex. As the input names are not fixed, they can be changed at any time. Hence that should be handled accordingly. Also, not all AVRs support HTTP.

GRORI commented 6 years ago

@jwveldhuis I'm not able to test the binding at the moment because we are renovating our home and that's why my hole setup is offline at the moment.

Just an idea: the string between "IPv4 " and "@" is the mac address of the device. I've searched several databases and i think all mac addresses from denon will start with "0005CD" and all addresses from Marantz will start with "000678".

jwveldhuis commented 6 years ago

@orificer good catch!

jwveldhuis commented 6 years ago

Updated the jar (it is 2.3.0-SNAPSHOT now): https://openhab.jfrog.io/openhab/libs-pullrequest-local/org/openhab/binding/org.openhab.binding.denonmarantz/2.3.0-SNAPSHOT/org.openhab.binding.denonmarantz-2.3.0-SNAPSHOT.jar

Improvements to Discovery:

@nick1802 @jangrewe can you test with this new binding, is discovery now working as expected?

nick1802 commented 6 years ago

hey @jwveldhuis ,

both the 3300 where found but 3100 & 2200 where not.

jangrewe commented 6 years ago

Thanks @jwveldhuis, my X2300W was discovered and shows all channels! <3

jangrewe commented 6 years ago

FYI, i was able to configure it statically with this in a .things file:

Thing denonmarantz:avr:0005cda10537 "Mediabox" @ "Wohnzimmer" [host="192.168.0.24"]
jwveldhuis commented 6 years ago

@nick1802 any idea why 3100 & 2200 are not discovered? From the output you shared from avahi I can't see any difference. Can you share relevant debug log?

@jangrewe thanks, good to know! Will add that syntax to the documentation later.