Using 1.0 denon binding in openhab 2.0

I installed with the Beta Repository not the snapshot release.
After my installation I did not get a conf directory.
I did however have a /etc/openhab2 directory which had the following sub directories;
html icons items persistence rules scripts services sitemaps things transform

The services directory had a denon.cfg file
pi@raspberrypi:/etc/openhab2 $ ls *
html:
index.html readme.txt

icons:
classic

items:
denon.items readme.txt

Content of denon.items
Switch DenonPower “Power” {denon=“avr2000:#PW”}

persistence:
readme.txt

rules:
readme.txt

scripts:
readme.txt

services:
addons.cfg denon.cfg readme.txt runtime.cfg

Content of denon.cfg

IP adress of the Denon receiver instance

avr2000.host=192.168.1.160

sitemaps:
denon.sitemap readme.txt

Conent of denon.sitemap
sitemap denon label="Home’
{
Frame label=“Main Zone”
{
Switch item=DenonPower
}
}

things:
readme.txt

transform:
de.map en.map readme.txt

I then created a /etc/openhab2/items/denon.items and a /etc/openhab2/items/denon.sitermap
This is what I get form the log file
2016-11-14 05:05:12.372 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'denon.sitemap’
2016-11-14 05:05:45.371 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'denon.items’
2016-11-14 05:05:45.382 [ERROR] [nding.AbstractGenericBindingProvider] - Binding org.openhab.binding.denon.internal.DenonBinding threw an exception:
java.lang.NullPointerException
at org.openhab.binding.denon.internal.DenonBinding.getConnector(DenonBinding.java:280)[191:org.openhab.binding.denon:1.9.0.b4]
at org.openhab.binding.denon.internal.DenonBinding.bindingChanged(DenonBinding.java:104)[191:org.openhab.binding.denon:1.9.0.b4]
at org.openhab.model.item.binding.AbstractGenericBindingProvider.notifyListeners(AbstractGenericBindingProvider.java:124)[192:org.openhab.core.compat1x:2.0.0.b4]
at org.openhab.model.item.binding.AbstractGenericBindingProvider.addBindingConfig(AbstractGenericBindingProvider.java:118)[192:org.openhab.core.compat1x:2.0.0.b4]
at org.openhab.binding.denon.internal.DenonGenericBindingProvider.processBindingConfiguration(DenonGenericBindingProvider.java:84)[191:org.openhab.binding.denon:1.9.0.b4]
at org.openhab.core.binding.internal.BindingConfigReaderDelegate.processBindingConfiguration(BindingConfigReaderDelegate.java:48)[192:org.openhab.core.compat1x:2.0.0.b4]
at org.eclipse.smarthome.model.item.internal.GenericItemProvider.internalDispatchBindings(GenericItemProvider.java:312)[117:org.eclipse.smarthome.model.item:0.9.0.b1]
at org.eclipse.smarthome.model.item.internal.GenericItemProvider.internalDispatchBindings(GenericItemProvider.java:284)[117:org.eclipse.smarthome.model.item:0.9.0.b1]
at org.eclipse.smarthome.model.item.internal.GenericItemProvider.processBindingConfigsFromModel(GenericItemProvider.java:167)[117:org.eclipse.smarthome.model.item:0.9.0.b1]
at org.eclipse.smarthome.model.item.internal.GenericItemProvider.modelChanged(GenericItemProvider.java:347)[117:org.eclipse.smarthome.model.item:0.9.0.b1]
at org.eclipse.smarthome.model.core.internal.ModelRepositoryImpl.notifyListeners(ModelRepositoryImpl.java:210)[116:org.eclipse.smarthome.model.core:0.9.0.b1]
at org.eclipse.smarthome.model.core.internal.ModelRepositoryImpl.addOrRefreshModel(ModelRepositoryImpl.java:124)[116:org.eclipse.smarthome.model.core:0.9.0.b1]
at org.eclipse.smarthome.model.core.internal.folder.FolderObserver.checkFile(FolderObserver.java:267)[116:org.eclipse.smarthome.model.core:0.9.0.b1]
at org.eclipse.smarthome.model.core.internal.folder.FolderObserver.access$1(FolderObserver.java:261)[116:org.eclipse.smarthome.model.core:0.9.0.b1]
at org.eclipse.smarthome.model.core.internal.folder.FolderObserver$WatchQueueReader.processWatchEvent(FolderObserver.java:142)[116:org.eclipse.smarthome.model.core:0.9.0.b1]
at org.eclipse.smarthome.core.service.AbstractWatchQueueReader.run(AbstractWatchQueueReader.java:95)[96:org.eclipse.smarthome.core:0.9.0.b1]
at java.lang.Thread.run(Thread.java:745)[:1.8.0_65]

Would you mind sending me your config files?

Thanks,

I do get exceptions on startup as well. I think there is even a ticket for them, but the binding ends up working. My .cfg is pretty simple. I have 2 devices using the binding, so two entries.

# denon:<instance>.<property>=value

# IP adress of the Denon receiver instance
denon:sr7005.host=10.x.x.x
denon:nr1606.host=10.x.x.x

# Optional, set connection method for receiving updates. Can be http or telnet. 
# Denon receivers only support one concurrent telnet connection, so use http if 
# you have any other app using the telnet connection. Default = telnet
denon:sr7005.update=http
denon:nr1606.update=http

# Optional, this sets the refresh interval (in milliseconds) for all instances 
# if you're using the http connection method. Default = 5000 
#denon:refresh=5000

then the corresponding .items (partial for 1 of the devices)

Switch DenonPower           "Marantz 7005 Power"          <receiver>      (ALL,AVR,bs,bsA)        {denon="sr7005#PW"}
Switch DenonMute            "sr7005 Mute [%s]"            <receiver>      (ALL,AVR)               {denon="sr7005#MU"}
String DenonSurround        "sr7005 Surround Mode [%s]"	  <receiver>      (ALL,AVR)               {denon="sr7005#SURROUNDMODE"}
String DenonTrack	    "sr7005 Track playing [%s]"   <receiver>      (ALL,AVR)               {denon="sr7005#TRACK"}
Dimmer DenonVolume          "sr7005 Volume [%.1f]"        <receiver>      (ALL,AVR)               {denon="sr7005#MV"}
String DenonInput           "sr7005 Input [%s]"           <receiver>      (ALL,AVR)               {denon="sr7005#INPUT"}

my sitemap simply uses the AVR group

Group AVR "Audio/Video" <receiver> (bs)

Thanks for help, I’ve gotten a little further. Now my denon.items is parsed correctly.
Also a couple of files were owned by root and I fixed that.
Now I am getting an error that the denon.things file can’t be read, all it has is the ip address.
Do you have a denon.things file?

Thanks,

html:
total 16
drwxr-xr-x 2 openhab openhab 4096 Nov 12 22:33 .
drwxr-xr-x 13 openhab openhab 4096 Nov 13 07:57 …
-rw-r–r-- 1 openhab openhab 36 Sep 14 19:34 index.html

icons:
total 12
drwxr-xr-x 3 openhab openhab 4096 Nov 12 22:33 .
drwxr-xr-x 13 openhab openhab 4096 Nov 13 07:57 …
drwxr-xr-x 2 openhab openhab 4096 Nov 12 22:33 classic

items:
total 16
drwxr-xr-x 2 openhab openhab 4096 Nov 15 05:32 .
drwxr-xr-x 13 openhab openhab 4096 Nov 13 07:57 …
-rw-r–r-- 1 openhab openhab 67 Nov 15 04:18 denon.items
Switch DenonPower “Power” {denon=“avr2000:#PW”}

persistence:
total 12
drwxr-xr-x 2 openhab openhab 4096 Nov 12 22:33 .
drwxr-xr-x 13 openhab openhab 4096 Nov 13 07:57 …

rules:
total 12
drwxr-xr-x 2 openhab openhab 4096 Nov 12 22:33 .
drwxr-xr-x 13 openhab openhab 4096 Nov 13 07:57 …

scripts:
total 12
drwxr-xr-x 2 openhab openhab 4096 Nov 12 22:33 .
drwxr-xr-x 13 openhab openhab 4096 Nov 13 07:57 …

services:
total 32
drwxr-xr-x 2 openhab openhab 4096 Nov 13 08:22 .
drwxr-xr-x 13 openhab openhab 4096 Nov 13 07:57 …
-rw-r–r-- 1 openhab openhab 947 Nov 13 08:22 addons.cfg
-rw-r–r-- 1 openhab openhab 523 Nov 15 04:16 denon.cfg
# IP adress of the Denon receiver instance
denon:avr2000.host=192.168.1.160
denon:avr2000.update=http

-rw-r–r-- 1 openhab openhab 328 Sep 14 19:34 readme.txt
-rw-r–r-- 1 openhab openhab 527 Nov 13 08:22 rrd4j.cfg
-rw-r–r-- 1 openhab openhab 721 Nov 13 08:11 runtime.cfg
-rw-r–r-- 1 openhab openhab 1067 Nov 12 23:06 weather.cfg

sitemaps:
total 12
drwxr-xr-x 2 openhab openhab 4096 Nov 15 05:32 .
drwxr-xr-x 13 openhab openhab 4096 Nov 13 07:57 …

things:
total 16
drwxr-xr-x 2 openhab openhab 4096 Nov 13 09:12 .
drwxr-xr-x 13 openhab openhab 4096 Nov 13 07:57 …
-rw-r–r-- 1 openhab openhab 56 Nov 13 09:18 denon.things
# Denon Receiver
denon:avr2000 [ host=“192.168.1.160” ]

transform:
total 20
drwxr-xr-x 2 openhab openhab 4096 Nov 12 22:33 .
drwxr-xr-x 13 openhab openhab 4096 Nov 13 07:57 …
-rw-r–r-- 1 openhab openhab 38 Sep 14 19:34 de.map
-rw-r–r-- 1 openhab openhab 38 Sep 14 19:34 en.map
-rw-r–r-- 1 openhab openhab 270 Sep 14 19:34 readme.txt

From log file
2016-11-15 06:18:07.627 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'denon.items’
2016-11-15 06:18:11.563 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'denon.things’
2016-11-15 06:18:11.611 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model ‘denon.things’ is either empty or cannot be parsed correctly!
2016-11-15 06:18:15.735 [INFO ] [basic.internal.servlet.WebAppServlet] - Started Basic UI at /basicui/app
2016-11-15 06:18:16.768 [INFO ] [assic.internal.servlet.WebAppServlet] - Started Classic UI at /classicui/app
2016-11-15 06:18:18.046 [INFO ] [arthome.ui.paper.internal.PaperUIApp] - Started Paper UI at /ui
2016-11-15 06:18:18.320 [INFO ] [.dashboard.internal.DashboardService] - Started dashboard at /start
2016-11-15 06:18:19.526 [WARN ] [.weather.internal.bus.WeatherBinding] - Unable to find any configuration settings for weather binding. Check openhab.cfg.
2016-11-15 06:18:19.531 [ERROR] [org.apache.felix.configadmin ] - [org.osgi.service.cm.ManagedService, org.osgi.service.event.EventHandler, id=301, bundle=194/mvn:org.openhab.binding/org.openhab.binding.weather/1.9.0.b4]: Updating property weather of configuration org.openhab.weather caused a problem: Unable to find any configuration settings for weather binding. Check openhab.cfg.
org.osgi.service.cm.ConfigurationException: weather : Unable to find any configuration settings for weather binding. Check openhab.cfg.
at org.openhab.binding.weather.internal.bus.WeatherBinding.updated(WeatherBinding.java:76)[194:org.openhab.binding.weather:1.9.0.b4]
at org.apache.felix.cm.impl.helper.ManagedServiceTracker.updated(ManagedServiceTracker.java:189)[7:org.apache.felix.configadmin:1.8.8]
at org.apache.felix.cm.impl.helper.ManagedServiceTracker.updateService(ManagedServiceTracker.java:152)[7:org.apache.felix.configadmin:1.8.8]
at org.apache.felix.cm.impl.helper.ManagedServiceTracker.provideConfiguration(ManagedServiceTracker.java:85)[7:org.apache.felix.configadmin:1.8.8]
at org.apache.felix.cm.impl.ConfigurationManager$ManagedServiceUpdate.provide(ConfigurationManager.java:1444)[7:org.apache.felix.configadmin:1.8.8]
at org.apache.felix.cm.impl.ConfigurationManager$ManagedServiceUpdate.run(ConfigurationManager.java:1400)[7:org.apache.felix.configadmin:1.8.8]
at org.apache.felix.cm.impl.UpdateThread.run0(UpdateThread.java:143)[7:org.apache.felix.configadmin:1.8.8]
at org.apache.felix.cm.impl.UpdateThread.run(UpdateThread.java:110)[7:org.apache.felix.configadmin:1.8.8]
at java.lang.Thread.run(Thread.java:745)[:1.8.0_65]
2016-11-15 06:18:19.992 [INFO ] [ui.habmin.internal.servlet.HABminApp] - Started HABmin servlet at /habmin
2016-11-15 06:18:24.123 [INFO ] [b.core.service.AbstractActiveService] - Denon Refresh Service has been started

I do not use a denon.things file. Things are introduced in 2.0 and this is a 1.x binding, so you do not need one.

The best I was able to do was test through the rest api and I was getting a success response for both DenonPower On and Off and I was able to query the state but the receiver didn’t actually turn on. So looks like I am stuck.

Thanks for the assistance.

One more question, once you have everything connected do you see Denon items under Control?
I do not. So how did you get to actually execute a command did you use a script? If yes how did you execute the script?

Thanks for the help.

Control (assuming you are using PaperUI) is kind of messy with all my devices and doesn’t do a good job of laying things out, so I tend not to use it. I do use the BasicUI mostly, with sitemaps and groups as mentioned above. As long as you put all your items for a device in the same group (groups are in parenthesis () ), then you can use a single line to display them in BasicUI (or ClassicUI as it uses the same sitemaps).

Thanks, I see that using the classic UI is how it is supposed to work.

I am trying to get the Denon binding to work with 2.0 snapshot, no luck with either a X1000 or X2100W.

Followed this thread in detail, including various permutations. Appears to parse ok, but no items show up in Basic, Classic or Paper UI.

I assume it is ok that the Denon binding (extension) does not show up in Paper UI, even when installed?

Stumped, anybody working on this binding?

Because it is a 1.x binding, you need to do the configuration in .items files. Are you saying you have done that, and still nothing is showing up?

I created a very… very basic 2.0 version of the driver which allows you to turn the received on/off and adjust volume and change the main zone input. All you have to do is provide the IP address of the receiver.
I am not a programmer so the code is pretty basic. I can send you the source code if you want.

1 Like

Im am very interested in the 2.0 Denon binding, too. Could you send me the source code.

Sorry it took so long to post back.
I’ve called the binding esmadja
If you aren’t familiar with the development environment this isn’t going to be too useful.
Unfortunately I won’t be able to help too much.
You should look at the following tutorial. You should be able to figure out where each file belongs.

This is the EsmadjaBindingContstants.java file

/**
 * Copyright (c) 2014-2016 by the respective copyright holders.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package org.openhab.binding.esmadja;

import org.eclipse.smarthome.core.thing.ThingTypeUID;

/**
 * The {@link EsmadjaBinding} class defines common constants, which are
 * used across the whole binding.
 *
 * @author Eric Smadja - Initial contribution
 */
public class EsmadjaBindingConstants {

    public static final String BINDING_ID = "esmadja";

    // List of all Thing Type UIDs
    public final static ThingTypeUID THING_TYPE_SAMPLE = new ThingTypeUID(BINDING_ID, "sample");

    // List of all Channel ids
    public final static String ZONE_1_POWER = "zone1#power";
    public final static String ZONE_1_VOLUME = "zone1#volume";
    public final static String ZONE_1_MUTE = "zone1#mute";
    public final static String ZONE_1_INPUT = "zone1#input";
    public final static String ZONE_2_POWER = "zone2#power";
    public final static String ZONE_2_VOLUME = "zone2#volume";
    public final static String ZONE_2_MUTE = "zone2#mute";
    public final static String ZONE_2_INPUT = "zone2#input";

    // List of input ID
    public final static int INPUT_SAT = 1;
    public final static int INPUT_GAME = 2;
    public final static int INPUT_AUX = 3;
    public final static int INPUT_DVD = 15;
    public final static int INPUT_BLURAY = 16;
    public final static int INPUT_TV_AUDIO = 34;
    public final static int INPUT_CD = 35;
    public final static int INPUT_FMTUNER = 36;
    public final static int INPUT_MEDIA_PLAYER = 39;
    public final static int INPUT_IRADIO = 40;
    public final static int INPUT_USB_IPOD = 41;
    public final static int INPUT_NETWORK = 43;
}

This is the EsmadjaHandler.java file

/**
 * Copyright (c) 2014-2016 by the respective copyright holders.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package org.openhab.binding.esmadja.handler;

import static org.openhab.binding.esmadja.EsmadjaBindingConstants.*;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import org.apache.commons.lang.StringUtils;
import org.eclipse.smarthome.core.thing.ChannelUID;
import org.eclipse.smarthome.core.thing.Thing;
import org.eclipse.smarthome.core.thing.ThingStatus;
import org.eclipse.smarthome.core.thing.binding.BaseThingHandler;
import org.eclipse.smarthome.core.types.Command;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The {@link EsmadjaHandler} is responsible for handling commands, which are
 * sent to one of the channels.
 *
 * @author Eric Smadja - Initial contribution
 */
public class EsmadjaHandler extends BaseThingHandler {

    private Logger logger = LoggerFactory.getLogger(EsmadjaHandler.class);
    public static final String HOST = "ipAddress";

    public EsmadjaHandler(Thing thing) {
        super(thing);
    }

    @Override
    public void handleCommand(ChannelUID channelUID, Command command) {
        if (String.valueOf(command) != "REFRESH") {
            HttpURLConnectionExample http = new HttpURLConnectionExample();
            int retry = 3;
            String status = "";
            switch (channelUID.getId()) {
                case ZONE_1_POWER:
                    logger.debug("Sending Denon Zone 1 Power command.");
                    try {
                        while ((retry > 0) & !status.equals(String.valueOf(command))) {
                            ;
                            retry--;
                            String httpAddress = (String) getConfig().get(HOST);
                            String setState = "PutZone_OnOff%2F" + command;
                            http.sendGet("http://" + httpAddress + "/MainZone/index.put.asp?cmd0=" + setState);
                            String response = http
                                    .sendGet("http://" + httpAddress + "/goform/formMainZone_MainZoneXml.xml");
                            status = StringUtils.substringBetween(response.toString(), "<ZonePower><value>",
                                    "</value></ZonePower>");
                            logger.debug("Input status: " + status);
                        }
                        logger.debug("Try count was " + String.valueOf(3 - retry));
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    break;
                case ZONE_1_VOLUME:
                    logger.debug("Sending Denon Zone 1 Volume command.");
                    try {
                        String httpAddress = (String) getConfig().get(HOST);
                        String volume = command + "";
                        Integer ivolume = Integer.valueOf(volume);

                        if (ivolume.equals(0)) {
                            volume = "--";
                        } else {
                            volume = String.valueOf(ivolume - 18);
                        }
                        String setState = "PutMasterVolumeSet%2F" + volume;
                        http.sendGet("http://" + httpAddress + "/MainZone/index.put.asp?cmd0=" + setState);
                        String response = http
                                .sendGet("http://" + httpAddress + "/goform/formMainZone_MainZoneXml.xml");
                        String stringParser = StringUtils.substringBetween(response.toString(), "<MasterVolume><value>",
                                "</value></MasterVolume>");
                        logger.debug("Input status: " + stringParser);
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    break;
                case ZONE_1_MUTE:
                    logger.debug("Sending Denon Zone 1 mute command.");
                    try {
                        while ((retry > 0) & status.equals(command)) {
                            ;
                        }
                        {
                            retry++;
                        }
                        String httpAddress = (String) getConfig().get(HOST);
                        String setState = "PutVolumeMute%2F" + command;
                        http.sendGet("http://" + httpAddress + "/MainZone/index.put.asp?cmd0=" + setState);
                        String response = http
                                .sendGet("http://" + httpAddress + "/goform/formMainZone_MainZoneXml.xml");
                        String stringParser = StringUtils.substringBetween(response.toString(), "<Mute><value>",
                                "</value></Mute>");
                        logger.debug("Input status: " + stringParser);
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    break;
                case ZONE_1_INPUT:
                    logger.debug("Sending Denon Zone 1 Input command.");
                    try {
                        while ((retry > 0) & status.equals(command)) {
                            ;
                        }
                        {
                            retry++;
                        }
                        String httpAddress = (String) getConfig().get(HOST);
                        String inputValue = "";
                        String execcommand = command + "";
                        Integer excom = Integer.valueOf(command + "");
                        if (execcommand != "REFRESH") {
                            switch (excom) {
                                case INPUT_SAT:
                                    inputValue = "SAT%2FCBL";
                                    break;
                                case INPUT_GAME:
                                    inputValue = "GAME";
                                    break;
                                case INPUT_AUX:
                                    inputValue = "AUX";
                                    break;
                                case INPUT_DVD:
                                    inputValue = "DVD";
                                    break;
                                case INPUT_BLURAY:
                                    inputValue = "BD";
                                    break;
                                case INPUT_TV_AUDIO:
                                    inputValue = "TV";
                                    break;
                                case INPUT_CD:
                                    inputValue = "CD";
                                    break;
                                case INPUT_FMTUNER:
                                    inputValue = "TUNER";
                                    break;
                                case INPUT_MEDIA_PLAYER:
                                    inputValue = "MPLAY";
                                    break;
                                case INPUT_IRADIO:
                                    inputValue = "IRADIO";
                                    break;
                                case INPUT_USB_IPOD:
                                    inputValue = "USB%2FIPOD";
                                    break;
                                case INPUT_NETWORK:
                                    inputValue = "NETHOME";
                                    break;
                            }
                        }
                        String setState = "PutZone_InputFunction%2F" + inputValue;
                        http.sendGet("http://" + httpAddress + "/MainZone/index.put.asp?cmd0=" + setState);
                        String response = http
                                .sendGet("http://" + httpAddress + "/goform/formMainZone_MainZoneXml.xml");
                        String stringParser = StringUtils.substringBetween(response.toString(),
                                "<InputFuncSelect><value>", "</value></InputFuncSelect>");
                        logger.debug("Input status: " + stringParser);
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    break;
                case ZONE_2_POWER:
                    // TODO: handle command
                    logger.debug("Denon Zone 2 command.");
                    // Note: if communication with thing fails for some reason,
                    // indicate that by setting the status with detail information
                    // updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
                    // "Could not control device at IP address x.x.x.x");
                    break;
            }
        }
    }

    @Override
    public void initialize() {
        // TODO: Initialize the thing. If done set status to ONLINE to indicate proper working.
        // Long running initialization should be done asynchronously in background.
        HttpURLConnectionExample http = new HttpURLConnectionExample();
        if (getConfig().get(HOST) != null) {
            try {
                String httpAddress = (String) getConfig().get(HOST);
                String response = http.sendGet("http://" + httpAddress + "/goform/Deviceinfo.xml");
                String stringParser = StringUtils.substringBetween(response.toString(), "<FriendlyName><value>",
                        "</value></FriendlyName>");
                updateStatus(ThingStatus.ONLINE);
                logger.debug("Denon ipAddress is configured at " + httpAddress);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                updateStatus(ThingStatus.OFFLINE);
                logger.debug("Denon ipAddress is incorrect or could not connect.");
            }

        } else {
            updateStatus(ThingStatus.OFFLINE);
            logger.debug("Denon ipAddress not configured.");
        }

        // Note: When initialization can NOT be done set the status with more details for further
        // analysis. See also class ThingStatusDetail for all available status details.
        // Add a description to give user information to understand why thing does not work
        // as expected. E.g.
        // updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
        // "Can not access device as username and/or password are invalid");
    }

    public class HttpURLConnectionExample {

        private final String USER_AGENT = "Mozilla/5.0";

        // HTTP GET request
        private String sendGet(String url) throws Exception {

            URL obj = new URL(url);
            HttpURLConnection con = (HttpURLConnection) obj.openConnection();

            // optional default is GET
            con.setRequestMethod("GET");

            // add request header
            con.setRequestProperty("User-Agent", USER_AGENT);

            int responseCode = con.getResponseCode();
            logger.debug("Sending 'GET' request to URL : " + url);
            logger.debug("Response Code : " + responseCode);

            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuffer response = new StringBuffer();

            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            // print result
            logger.debug(response.toString());
            return response.toString();

        }
    }
}

This is the EsmadjaHandlerFactory.java file

/**
 * Copyright (c) 2014-2016 by the respective copyright holders.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package org.openhab.binding.esmadja.internal;

import static org.openhab.binding.esmadja.EsmadjaBindingConstants.*;

import java.util.Collections;
import java.util.Set;

import org.openhab.binding.esmadja.handler.EsmadjaHandler;
import org.eclipse.smarthome.core.thing.Thing;
import org.eclipse.smarthome.core.thing.ThingTypeUID;
import org.eclipse.smarthome.core.thing.binding.BaseThingHandlerFactory;
import org.eclipse.smarthome.core.thing.binding.ThingHandler;

/**
 * The {@link EsmadjaHandlerFactory} is responsible for creating things and thing 
 * handlers.
 * 
 * @author Eric Smadja - Initial contribution
 */
public class EsmadjaHandlerFactory extends BaseThingHandlerFactory {
    
    private final static Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.singleton(THING_TYPE_SAMPLE);
    
    @Override
    public boolean supportsThingType(ThingTypeUID thingTypeUID) {
        return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
    }

    @Override
    protected ThingHandler createHandler(Thing thing) {

        ThingTypeUID thingTypeUID = thing.getThingTypeUID();

        if (thingTypeUID.equals(THING_TYPE_SAMPLE)) {
            return new EsmadjaHandler(thing);
        }

        return null;
    }
}


This is the binding.xml file

<?xml version="1.0" encoding="UTF-8"?>
<binding:binding id="esmadja"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:binding="http://eclipse.org/smarthome/schemas/binding/v1.0.0"
        xsi:schemaLocation="http://eclipse.org/smarthome/schemas/binding/v1.0.0 http://eclipse.org/smarthome/schemas/binding-1.0.0.xsd">

    <name>Denon Binding</name>
    <description>Netowrk Denon binding</description>
    <author>Eric Smadja</author>

</binding:binding>

This is the thing-types.xml file

<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="esmadja"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:thing="http://eclipse.org/smarthome/schemas/thing-description/v1.0.0"
        xsi:schemaLocation="http://eclipse.org/smarthome/schemas/thing-description/v1.0.0 http://eclipse.org/smarthome/schemas/thing-description-1.0.0.xsd">

    <!-- Sample Thing Type -->
    <thing-type id="sample">
        <label>Denon AVR</label>
        <description>Network enabled Denon AV Receivers</description>

        <channel-groups>
            <channel-group typeId="zone1Controls" id="zone1" />
            <channel-group typeId="zone2Controls" id="zone2" />
        </channel-groups>

	   <config-description>
	       <parameter name="ipAddress" type="text" required="true">
	           <label>Network Address</label>
		          <description>The IP or host name of the Denon Receiver</description>
		          <context>network-address</context>
	           </parameter>
	       </config-description>
    </thing-type>

    <channel-group-type id="zone1Controls">
        <label>Zone 1</label>
        <channels>
            <channel id="power" typeId="power" />
            <channel id="input" typeId="input" />
            <channel id="volume" typeId="volume" />
            <channel id="mute" typeId="mute" />
        </channels>
    </channel-group-type>

    <channel-group-type id="zone2Controls">
        <label>Zone 2</label>
        <channels>
            <channel id="power" typeId="power" />
            <channel id="input" typeId="input" />
            <channel id="volume" typeId="volume" />
            <channel id="mute" typeId="mute" />
        </channels>
    </channel-group-type>
    <!-- Commands -->
    <channel-type id="power">
        <item-type>Switch</item-type>
        <label>Power</label>
        <description>Power on/off your device</description>
    </channel-type>
    <channel-type id="input">
        <item-type>Number</item-type>
        <label>Input Source</label>
        <description>Select the input source of the AVR</description>
        <state>
            <options>
                <option value="00">DVR/VCR</option>
                <option value="01">SATELLITE/CABLE</option>
                <option value="02">GAME</option>
                <option value="03">AUX</option>
                <option value="04">GAME</option>
                <option value="15">DVD</option>
                <option value="16">BLURAY</option>
                <option value="34">TV AUDIO</option>
                <option value="35">CD</option>
                <option value="36">TUNER FM</option>
                <option value="39">MEDIA PLAYER</option>
                <option value="40">INTERET RADIO</option>
                <option value="41">USB</option>
                <option value="43">NETWORK</option>
            </options>
        </state>
    </channel-type>
    <channel-type id="mute">
        <item-type>Switch</item-type>
        <label>Mute</label>
        <description>Mute/unmute your device</description>
    </channel-type>
    <channel-type id="volume">
        <item-type>Dimmer</item-type>
        <label>Volume</label>
        <description>Volume of your device</description>
        <state min="0" max="100" step="1" pattern="%d %%">
        </state>
    </channel-type>
    
</thing:thing-descriptions>

It there any chance we would see a working denon binding in openhab 2?

1 Like

Would also like to be able to control my Denon AVR with openHab 2…

I can’t get the binding works on my OH2, I tried telnet and http mode both with no joy,
I guess it’s due to i am using the old model (AVR-4308), I finally get on/off by make shell script as below and exec the script to active the action

#!/bin/bash
echo -ne $1\r| nc -w1 192.xxx.xxx.xxx 23

change the xxx to your denon ip.

1 Like

Also spent hours in getting the binding to work… with partial success… Telnet doesn’t work for me at all, only http (Marantz SR5008). And only a number of commands / status queries work.
Hope someone will continue to work on this Denon binding.

Hi Jim,

I wonder if you have a hint for me.
I’ve been struggling all day to find a way to make the Denon binder work for me.

I’ve edited the denon.cfg file according to the guidelines and your example.
I’ve modified the addons.cfg:
package = expert
remote = true
legacy = true
binding = denon1
ui = basic

I’ve also edited my items and sitemap, and the items shows correctly on the sitemap, with the selected controls etc.

However it seems like the denon.cfg is never read by the system, which expect the IP address to be 192.168.1.70, which is given in the default example in the file.
Mine looks like this:
#.=value

# IP adress of the Denon receiver instance
# avr2000.host=192.168.1.70
denon:avr2000.host=192.168.0.26

# Optional, set connection method for receiving updates. Can be http or telnet. 
# Denon receivers only support one concurrent telnet connection, so use http if 
# you have any other app using the telnet connection. Default = telnet
#avr2000.update=http
denon:avr2000.update=http

Do you or anyone else in this thread have a clou?

I have not looked at this in a while, but here are some things to look at:

  1. verify your version of the binding. The .items file, the .cfg file, etc are for use with the 1.x binding.
  2. Look at the log file at startup to see if the binding is getting loaded by OpenHAB
  3. If it is getting loaded, the log should also have lines about your .cfg file. Just search it for denon

You can do #1 by running the openHAB client.

openhab> bundle:list | grep Denon
193 | Active   |  80 | 1.11.0.201707160110    | openHAB Denon Binding

You can also run bundle:diag to make sure everything looks good in there.

For 2) above, looking at your log file you should see something like this:

openhab.log.2:2017-11-17 23:08:23.679 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'denon.items'

For 3) above, while in the openHAB command line client, try

openhab:items list | grep -i denon

you shoudl get some output like this depending on your .items file:

openhab> smarthome:items list |grep -i denon
DenonPower (Type=SwitchItem, State=OFF, Label=Marantz 7005 Power, Category=receiver, Groups=[ALL, AVR, bs, bsA])
DenonMute (Type=SwitchItem, State=OFF, Label=sr7005 Mute, Category=receiver, Groups=[ALL, AVR])
DenonSurround (Type=StringItem, State=Standard(DTS), Label=sr7005 Surround Mode, Category=receiver, Groups=[ALL, AVR])
DenonTrack (Type=StringItem, State=NULL, Label=sr7005 Track playing, Category=receiver, Groups=[ALL, AVR])
DenonVolume (Type=DimmerItem, State=62.0, Label=sr7005 Volume, Category=receiver, Groups=[ALL, AVR])
DenonInput (Type=StringItem, State=BD, Label=sr7005 Input, Category=receiver, Groups=[ALL, AVR])

FYI: Working on a new Denon / Marantz 2.0 binding, it is ready for testing:

1 Like