Generic Denon / Marantz python plugin

Python and python framework

Moderator: leecollings

Szmalu
Posts: 13
Joined: Thursday 02 April 2015 18:50
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Generic Denon / Marantz python plugin

Post by Szmalu »

THX for great plugin.

There is only one issue - you can't turn on Zone 2 alone just by clicking it - If you try to - Zone 1 turns on at the same time.
Artemgy
Posts: 11
Joined: Friday 17 March 2017 17:17
Target OS: Raspberry Pi / ODroid
Domoticz version: v3.7017b
Contact:

Re: Generic Denon / Marantz python plugin

Post by Artemgy »

Dnpwwo wrote:If you update to the latest beta it should create the additional devices.
Thanks for that @Dnpwwo - I was pulling my hair out trying to work out why the latest plugin version didn't behave as expected. I upgraded to latest beta and it worked a treat

Code: Select all

cd ~/domoticz
 ./updatebeta
Now running Domoticz v3.7243 (Compile Date: 2017-04-02) and Selector Switch issue (as per @Boredcat) resolved.
User avatar
Dnpwwo
Posts: 819
Joined: Sunday 23 March 2014 9:00
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Melbourne, Australia
Contact:

Re: Generic Denon / Marantz python plugin

Post by Dnpwwo »

@Szmalu,

That appears to be the way the amplifier API works and not a plugin thing.

When the amp powers on it always turns on the main zone AFAIK
The reasonable man adapts himself to the world; the unreasonable one persists to adapt the world to himself. Therefore all progress depends on the unreasonable man. George Bernard Shaw
Szmalu
Posts: 13
Joined: Thursday 02 April 2015 18:50
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Generic Denon / Marantz python plugin

Post by Szmalu »

@Dnpwwo

Not exactly. When I turn on Zone2 via http command:

Code: Select all

http://DENON_IP/MainZone/index.put.asp?cmd0=PutZone_OnOff%2FON&cmd1=aspMainZone_WebUpdateStatus%2F&ZoneName=ZONE2
It works like it supposed to (Main Zone remains off).
Dropshot
Posts: 44
Joined: Tuesday 20 December 2016 22:29
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Generic Denon / Marantz python plugin

Post by Dropshot »

I don't get the new hardware in the dropdown list. I've followed the guide for installing plugins. I seet this in my log:

Code: Select all

2017-04-28 17:42:11.214 PluginSystem: Started, Python version '3.4.2'.
I use the latest beta version of Domoticz.
I do see one error though, maybe this is related:

Code: Select all

2017-04-28 17:42:16.260 Error: PluginList: Error 'Error document empty.' at line 0 column 0 in XML ''.
Can anyone explain what I'm possibly doing wrong?
User avatar
G3rard
Posts: 669
Joined: Wednesday 04 March 2015 22:15
Target OS: -
Domoticz version: No
Location: The Netherlands
Contact:

Re: Generic Denon / Marantz python plugin

Post by G3rard »

@Dropshot, I see that error message as well, also with other plugins, but it has no effect on the working of the plugin.
The name of the plugin in the dropdown menu is Denon AVR 4306 Amplifier.
Are other plugins working for you?

@Dnpwwo, any ideas what the cause of the error message is? I also have it when my Sony Bravia plugin is restarted after pressing the Update button in the hardware menu.
I see the error is raised on 2 parts of the code https://github.com/domoticz/domoticz/se ... L%22&type=.
Not using Domoticz anymore
User avatar
Dnpwwo
Posts: 819
Joined: Sunday 23 March 2014 9:00
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Melbourne, Australia
Contact:

Re: Generic Denon / Marantz python plugin

Post by Dnpwwo »

@G3rard,

I haven't been able to track down this error yet. I have a permanent breakpoint set on the log line on Windows but it has never gone off. I see this too on Linux but it does not affect functionality it is a lower priority.

I've added the plugin name to the log to help narrow down where this is coming from.
The reasonable man adapts himself to the world; the unreasonable one persists to adapt the world to himself. Therefore all progress depends on the unreasonable man. George Bernard Shaw
User avatar
G3rard
Posts: 669
Joined: Wednesday 04 March 2015 22:15
Target OS: -
Domoticz version: No
Location: The Netherlands
Contact:

Re: Generic Denon / Marantz python plugin

Post by G3rard »

@Dnpwwo, it does not affect the plugin indeed. Let me know if I can do some testing, as it always happens if I update my plugin.
Not using Domoticz anymore
rjblake
Posts: 142
Joined: Friday 21 October 2016 9:25
Target OS: NAS (Synology & others)
Domoticz version:
Location: Netherlands
Contact:

Re: Generic Denon / Marantz python plugin

Post by rjblake »

Thanks for this plugin - works well with my Denon AVR-X2300W. The only thing that puzzles me is the Power ON/OFF. If I use Domoticz to turn on (there is only a power switch for Main Zone created), both Main and Zone 2 are turned on. Is this because it is using the 'PWON' as opposed to 'ZMON' perhaps? I'll do some further tests to see if changing this is perhaps an option and/or to created discrete power switches for each zone instead.
User avatar
Dnpwwo
Posts: 819
Joined: Sunday 23 March 2014 9:00
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Melbourne, Australia
Contact:

Re: Generic Denon / Marantz python plugin

Post by Dnpwwo »

@rjblake,

I tried sending the zone on specific commands but they didn't seem to work for me unless I had turned the power was turned on first. Happy to be corrected if you do some research.

I only have the main zone set up anyway so haven't tested too much for the others.

The next major release of the Python Framework will support multiple connections and I am testing it using this plugin and sending zone on commands via http which other users claim works without turning on the main zone. Will hopefully have this done in a coupe of weeks.
The reasonable man adapts himself to the world; the unreasonable one persists to adapt the world to himself. Therefore all progress depends on the unreasonable man. George Bernard Shaw
rjblake
Posts: 142
Joined: Friday 21 October 2016 9:25
Target OS: NAS (Synology & others)
Domoticz version:
Location: Netherlands
Contact:

Re: Generic Denon / Marantz python plugin

Post by rjblake »

@Dnpwwo - I just tried connecting through Telnet and issuing a ZMON command and it powered on my Main Zone only. I also sent a Z2ON and this powered my Zone2 on only. This is on an AVR-X2300W. I do have to open/close the connection after each command. Looking forward to seeing your updates and will take a look at the code in the mean time
rjblake
Posts: 142
Joined: Friday 21 October 2016 9:25
Target OS: NAS (Synology & others)
Domoticz version:
Location: Netherlands
Contact:

Re: Generic Denon / Marantz python plugin

Post by rjblake »

I've gone and made some simple mods to the code for the AVR-X2300W and now each zone turns on/off when the relevant selector switch is used. The 'main' power switch turns both on/off. I also modified the list of inputs to match those for the AVR and have attached the code for those interested.

Code: Select all

#
#       Denon & Marantz AVR plugin
#
#       Author:     Dnpwwo, 2016 - 2017, Artemgy 2017
#
#   Mode3 ("Sources") needs to have '|' delimited names of sources that the Denon knows about.  
#   The Selector can be changed afterwards to any text and the plugin will still map to the actual Denon name.
#
#   Modified by rjblake for Denon AVR-X2300W. Only powers on the Main Zone or Zone2 when a single zone is selected. Main Power turns both Zone on/off
#   Also changed names of the inputs to match those for the AVR
#
"""
<plugin key="DenonMarantz" version="2.5.5" name="Denon / Marantz AVR Amplifier" author="dnpwwo/artemgy" wikilink="" externallink="http://www.denon.co.uk/uk">
    <description>
Denon & Marantz AVR plugin.<br/><br/>
"Sources" need to have '|' delimited names of sources that the Denon knows about from the technical manual.<br/>
The Sources Selector(s) can be changed after initial creation to any text and the plugin will still map to the actual Denon name.<br/><br/>
Devices will be created in the Devices Tab only and will need to be manually made active.
    </description>
    <params>
        <param field="Address" label="IP Address" width="200px" required="true" default="127.0.0.1"/>
        <param field="Port" label="Port" width="30px" required="true" default="23"/>
        <param field="Mode2" label="Startup Delay" width="50px" required="true">
            <options>
                <option label="2" value="2"/>
                <option label="3" value="3"/>
                <option label="4" value="4" default="true" />
                <option label="5" value="5"/>
                <option label="6" value="6"/>
                <option label="7" value="7"/>
                <option label="10" value="10"/>
            </options>
        </param>
        # Changed for Denon AVR-X2300W
        <param field="Mode3" label="Sources" width="550px" required="true" default="Off|SAT/CBL|DVD|BD|GAME|AUX1|MPLAY|TV|AUX2|TUNER|USB/IPOD|CD|BT|IRP|FVP"/>
        <param field="Mode6" label="Debug" width="75px">
            <options>
                <option label="True" value="Debug"/>
                <option label="False" value="Normal"  default="true" />
            </options>
        </param>
    </params>
</plugin>
"""
import Domoticz
import base64
import datetime

class BasePlugin:
    isConnected = False
    nextConnect = 3
    oustandingPings = 0

    powerOn = False

    mainOn = False
    mainSource = 0
    mainVolume1 = 0
    
    zone2On = False
    zone2Source = 0
    zone2Volume = 0
    
    zone3On = False
    zone3Source = 0
    zone3Volume = 0

    ignoreMessages = "|SS|SV|SD|MS|PS|CV|SY|TP|"
    selectorMap = {}
    pollingDict =  {"PW":"ZM?\r", "ZM":"SI?\r", "SI":"MV?\r", "MV":"MU?\r", "MU":"PW?\r" }
    lastMessage = ""
    lastHeartbeat = datetime.datetime.now()

    SourceOptions = {}
    
    def onStart(self):
        if Parameters["Mode6"] == "Debug":
            Domoticz.Debugging(1)

        self.SourceOptions = {'LevelActions': '|'*Parameters["Mode3"].count('|'),
                             'LevelNames': Parameters["Mode3"],
                             'LevelOffHidden': 'false',
                             'SelectorStyle': '1'}
            
        if (len(Devices) == 0):
            Domoticz.Device(Name="Power", Unit=1, TypeName="Switch",  Image=5).Create()
            Domoticz.Device(Name="Main Zone", Unit=2, TypeName="Selector Switch", Switchtype=18, Image=5, Options=self.SourceOptions).Create()
            Domoticz.Device(Name="Main Volume", Unit=3, Type=244, Subtype=73, Switchtype=7, Image=8).Create()
        else:
            if (2 in Devices and (len(Devices[2].sValue) > 0)):
                self.mainSource = int(Devices[2].sValue)
                self.mainOn = (Devices[2].nValue != 0)
            if (3 in Devices and (len(Devices[3].sValue) > 0)):
                self.mainVolume1 = int(Devices[3].sValue) if (Devices[3].nValue != 0) else int(Devices[3].sValue)*-1
            if (4 in Devices and (len(Devices[4].sValue) > 0)):
                self.zone2Source = int(Devices[4].sValue)
                self.zone2On = (Devices[4].nValue != 0)
            if (5 in Devices and (len(Devices[5].sValue) > 0)):
                self.zone2Volume = int(Devices[5].sValue) if (Devices[5].nValue != 0) else int(Devices[5].sValue)*-1
            if (6 in Devices and (len(Devices[6].sValue) > 0)):
                self.zone3Source = int(Devices[6].sValue)
                self.zone3On = (Devices[6].nValue != 0)
            if (7 in Devices and (len(Devices[7].sValue) > 0)):
                self.zone3Volume = int(Devices[7].sValue) if (Devices[7].nValue != 0) else int(Devices[7].sValue)*-1
            if (1 in Devices):
                self.powerOn = (self.mainOn or self.zone2On or self.zone3On)
                
        DumpConfigToLog()
        dictValue=0
        for item in Parameters["Mode3"].split('|'):
            self.selectorMap[dictValue] = item
            dictValue = dictValue + 10
        Domoticz.Transport("TCP/IP", Parameters["Address"], Parameters["Port"])
        Domoticz.Protocol("Line")
        Domoticz.Connect()
        return

    def onConnect(self, Status, Description):
        if (Status == 0):
            self.isConnected = True
            Domoticz.Log("Connected successfully to: "+Parameters["Address"]+":"+Parameters["Port"])
            Domoticz.Send('PW?\r')
            Domoticz.Send('ZM?\r', Delay=1)
            Domoticz.Send('Z2?\r', Delay=2)
            Domoticz.Send('Z3?\r', Delay=3)
        else:
            self.isConnected = False
            self.powerOn = False
            Domoticz.Log("Failed to connect ("+str(Status)+") to: "+Parameters["Address"]+":"+Parameters["Port"])
            Domoticz.Debug("Failed to connect ("+str(Status)+") to: "+Parameters["Address"]+":"+Parameters["Port"]+" with error: "+Description)
            self.SyncDevices()
        return

    def onMessage(self, Data, Status, Extra):
        self.oustandingPings = self.oustandingPings - 1
        strData = Data.decode("utf-8", "ignore")
        Domoticz.Debug("onMessage called with Data: '"+str(strData)+"'")
        
        strData = strData.strip()
        action = strData[0:2]
        detail = strData[2:]
        if (action in self.pollingDict): self.lastMessage = action

        
        if (action == "PW"):        # Power Status
            if (detail == "STANDBY"):
                self.powerOn = False
            elif (detail == "ON"):
                self.powerOn = True
            else: Domoticz.Debug("Unknown: Action "+action+", Detail '"+detail+"' ignored.")
        elif (action == "ZM"):      # Main Zone on/off
            if (detail == "ON"):
                self.mainOn = True
            elif (detail == "OFF"):
                self.mainOn = False
            else: Domoticz.Debug("Unknown: Action "+action+", Detail '"+detail+"' ignored.")
        elif (action == "SI"):      # Main Zone Source Input
            for key, value in self.selectorMap.items():
                if (detail == value):      self.mainSource = key
        elif (action == "MV"):      # Master Volume
            if (detail.isdigit()):
                if (abs(self.mainVolume1) != int(detail[0:2])): self.mainVolume1 = int(detail[0:2])
            elif (detail[0:3] == "MAX"): Domoticz.Debug("Unknown: Action "+action+", Detail '"+detail+"' ignored.")
            else: Domoticz.Log("Unknown: Action "+action+", Detail '"+detail+"' ignored.")
        elif (action == "MU"):      # Overall Mute
            if (detail == "ON"):         self.mainVolume1 = abs(self.mainVolume1)*-1
            elif (detail == "OFF"):      self.mainVolume1 = abs(self.mainVolume1)
            else: Domoticz.Debug("Unknown: Action "+action+", Detail '"+detail+"' ignored.")
        elif (action == "Z2"):      # Zone 2
            # Zone 2 response, make sure we have Zone 2 devices in Domoticz and they are polled
            if (4 not in Devices):
                LevelActions = '|'*Parameters["Mode3"].count('|')
                Domoticz.Device(Name="Zone 2", Unit=4, TypeName="Selector Switch", Switchtype=18, Image=5, Options=self.SourceOptions).Create()
                Domoticz.Log("Zone 2 responded, devices added.")
            if (5 not in Devices):
                Domoticz.Device(Name="Volume 2", Unit=5, Type=244, Subtype=73, Switchtype=7, Image=8).Create()
            if ("Z2" not in self.pollingDict):
                self.pollingDict = {"PW":"ZM?\r", "ZM":"SI?\r", "SI":"MV?\r", "MV":"MU?\r", "MU":"Z2?\r", "Z2":"PW?\r" }

            if (detail == "ON"):
                self.zone2On = True
            elif (detail == "OFF"):
                self.zone2On = False
            elif (detail == "MUON"):
                self.zone2Volume = abs(self.zone2Volume)*-1
            elif (detail == "MUOFF"):
                self.zone2Volume = abs(self.zone2Volume)
            elif (detail.isdigit()):
                if (abs(self.zone2Volume) != int(detail[0:2])): self.zone2Volume = int(detail[0:2])
            else:
                for key, value in self.selectorMap.items():
                    if (detail == value):      self.zone2Source = key
        elif (action == "Z3"):      # Zone 3
            # Zone 3 response, make sure we have Zone 3 devices in Domoticz and they are polled
            if (6 not in Devices):
                LevelActions = '|'*Parameters["Mode3"].count('|')
                Domoticz.Device(Name="Zone 3", Unit=6, TypeName="Selector Switch", Switchtype=18, Image=5, Options=self.SourceOptions).Create()
                Domoticz.Log("Zone 3 responded, devices added.")
            if (7 not in Devices):
                Domoticz.Device(Name="Volume 3", Unit=7, Type=244, Subtype=73, Switchtype=7, Image=8).Create()
            if ("Z3" not in self.pollingDict):
                self.pollingDict = {"PW":"ZM?\r", "ZM":"SI?\r", "SI":"MV?\r", "MV":"MU?\r", "MU":"Z2?\r", "Z2":"Z3?\r", "Z3":"PW?\r" }
                
            if (detail == "ON"):
                self.zone3On = True
            elif (detail == "OFF"):
                self.zone3On = False
            elif (detail == "MUON"):
                self.zone3Volume = abs(self.zone3Volume)*-1
            elif (detail == "MUOFF"):
                self.zone3Volume = abs(self.zone3Volume)
            elif (detail.isdigit()):
                if (abs(self.zone3Volume) != int(detail[0:2])): self.zone3Volume = int(detail[0:2])
            else:
                for key, value in self.selectorMap.items():
                    if (detail == value):      self.zone3Source = key
        else:
            if (self.ignoreMessages.find(action) < 0):
                Domoticz.Debug("Unknown message '"+action+"' ignored.")
        self.SyncDevices()
        return

    def onCommand(self, Unit, Command, Level, Hue):
        Domoticz.Log("onCommand called for Unit " + str(Unit) + ": Parameter '" + str(Command) + "', Level: " + str(Level))

        Command = Command.strip()
        action, sep, params = Command.partition(' ')
        action = action.capitalize()
        params = params.capitalize()
        delay = 0
        if (self.powerOn == False):
            delay = int(Parameters["Mode2"])
        else:
            # Amp will ignore commands if it is responding to a heartbeat so delay send
            lastHeartbeatDelta = (datetime.datetime.now()-self.lastHeartbeat).total_seconds()
            if (lastHeartbeatDelta < 0.5):
                delay = 1
                Domoticz.Log("Last heartbeat was "+str(lastHeartbeatDelta)+" seconds ago, delaying command send.")

        if (Unit == 1):     # Main power switch
            if (action == "On"):
                Domoticz.Send(Message='ZMON\r')
                Domoticz.Send(Message='Z2ON\r')
            elif (action == "Off"):
                Domoticz.Send(Message='ZMOFF\r', Delay=delay)
                Domoticz.Send(Message='Z2OFF\r', Delay=delay)

        # Main Zone devices
        elif (Unit == 2):     # Main selector
            if (action == "On"):
                Domoticz.Send(Message='ZMON\r')
            elif (action == "Set"):
                if (self.powerOn == False): Domoticz.Send(Message='ZMON\r')
                Domoticz.Send(Message='SI'+self.selectorMap[Level]+'\r', Delay=delay)
            elif (action == "Off"):
                Domoticz.Send(Message='ZMOFF\r', Delay=delay)
        elif (Unit == 3):     # Main Volume control
            if (self.powerOn == False): Domoticz.Send(Message='ZMON\r')
            if (action == "On"):
                Domoticz.Send(Message='MUOFF\r', Delay=delay)
            elif (action == "Set"):
                Domoticz.Send(Message='MV'+str(Level)+'\r', Delay=delay)
            elif (action == "Off"):
                Domoticz.Send(Message='MUON\r', Delay=delay)

        # Zone 2 devices
        elif (Unit == 4):   # Zone 2 selector
            if (action == "On"):
                Domoticz.Send(Message='Z2ON\r', Delay=delay)
            elif (action == "Set"):
                if (self.zone2On == False):
                    Domoticz.Send(Message='Z2ON\r', Delay=delay)
                    delay += 1
                Domoticz.Send(Message='Z2'+self.selectorMap[Level]+'\r', Delay=delay)
                delay += 1
                Domoticz.Send(Message='Z2?\r', Delay=delay)
            elif (action == "Off"):
                Domoticz.Send(Message='Z2OFF\r', Delay=delay)
        elif (Unit == 5):   # Zone 2 Volume control
            # if (self.powerOn == False): Domoticz.Send(Message='PWON\r')
            if (self.zone2On == False):
                Domoticz.Send(Message='Z2ON\r', Delay=delay)
                delay += 1
            if (action == "On"):
                Domoticz.Send(Message='Z2MUOFF\r', Delay=delay)
            elif (action == "Set"):
                Domoticz.Send(Message='Z2'+str(Level)+'\r', Delay=delay)
            elif (action == "Off"):
                Domoticz.Send(Message='Z2MUON\r', Delay=delay)

        # Zone 3 devices
        elif (Unit == 6):   # Zone 3 selector
            if (action == "On"):
                if (self.powerOn == False): Domoticz.Send(Message='PWON\r')
                Domoticz.Send(Message='Z3ON\r', Delay=delay)
            elif (action == "Set"):
                if (self.powerOn == False): Domoticz.Send(Message='PWON\r')
                if (self.zone3On == False):
                    Domoticz.Send(Message='Z3ON\r', Delay=delay)
                    delay += 1
                Domoticz.Send(Message='Z3'+self.selectorMap[Level]+'\r', Delay=delay)
                delay += 1
                Domoticz.Send(Message='Z3?\r', Delay=delay)
            elif (action == "Off"):
                Domoticz.Send(Message='Z3OFF\r', Delay=delay)
        elif (Unit == 7):   # Zone 3 Volume control
            if (self.powerOn == False): Domoticz.Send(Message='PWON\r')
            if (self.zone3On == False):
                Domoticz.Send(Message='Z3ON\r', Delay=delay)
                delay += 1
            if (action == "On"):
                Domoticz.Send(Message='Z3MUOFF\r', Delay=delay)
            elif (action == "Set"):
                Domoticz.Send(Message='Z3'+str(Level)+'\r', Delay=delay)
            elif (action == "Off"):
                Domoticz.Send(Message='Z3MUON\r', Delay=delay)

        return

    def onDisconnect(self):
        self.isConnected = False
        Domoticz.Log("Denon device has disconnected.")
        return

    def onHeartbeat(self):
        if (self.isConnected == True):
            if (self.oustandingPings > 5):
                Domoticz.Disconnect()
                self.nextConnect = 0
            else:
                Domoticz.Send(self.pollingDict[self.lastMessage])
                Domoticz.Debug("onHeartbeat: self.lastMessage "+self.lastMessage+", Sending '"+self.pollingDict[self.lastMessage][0:2]+"'.")
                self.oustandingPings = self.oustandingPings + 1
        else:
            # if not connected try and reconnected every 3 heartbeats
            self.oustandingPings = 0
            self.nextConnect = self.nextConnect - 1
            if (self.nextConnect <= 0):
                self.nextConnect = 3
                Domoticz.Connect()
                
        self.lastHeartbeat = datetime.datetime.now()
        return

    def SyncDevices(self):
        if (self.powerOn == False):
            UpdateDevice(1, 0, "Off")
            UpdateDevice(2, 0, "0")
            UpdateDevice(3, 0, str(abs(self.mainVolume1)))
            UpdateDevice(4, 0, "0")
            UpdateDevice(5, 0, str(abs(self.zone2Volume)))
            UpdateDevice(6, 0, "0")
            UpdateDevice(7, 0, str(abs(self.zone3Volume)))
        else:
            UpdateDevice(1, 1, "On")
            UpdateDevice(2, self.mainSource if self.mainOn else 0, str(self.mainSource if self.mainOn else 0))
            if (self.mainVolume1 <= 0 or self.mainOn == False): UpdateDevice(3, 0, str(abs(self.mainVolume1)))
            else: UpdateDevice(3, 2, str(self.mainVolume1))
            UpdateDevice(4, self.zone2Source if self.zone2On else 0, str(self.zone2Source if self.zone2On else 0))
            if (self.zone2Volume <= 0 or self.zone2On == False): UpdateDevice(5, 0, str(abs(self.zone2Volume)))
            else: UpdateDevice(5, 2, str(self.zone2Volume))
            UpdateDevice(6, self.zone3Source if self.zone3On else 0, str(self.zone3Source if self.zone3On else 0))
            if (self.zone3Volume <= 0 or self.zone3On == False): UpdateDevice(7, 0, str(abs(self.zone3Volume)))
            else: UpdateDevice(7, 2, str(self.zone3Volume))
        return
        
global _plugin
_plugin = BasePlugin()

def onStart():
    global _plugin
    _plugin.onStart()

def onConnect(Status, Description):
    global _plugin
    _plugin.onConnect(Status, Description)

def onMessage(Data, Status, Extra):
    global _plugin
    _plugin.onMessage(Data, Status, Extra)

def onCommand(Unit, Command, Level, Hue):
    global _plugin
    _plugin.onCommand(Unit, Command, Level, Hue)

def onDisconnect():
    global _plugin
    _plugin.onDisconnect()

def onHeartbeat():
    global _plugin
    _plugin.onHeartbeat()

def UpdateDevice(Unit, nValue, sValue):
    # Make sure that the Domoticz device still exists (they can be deleted) before updating it 
    if (Unit in Devices):
        if (Devices[Unit].nValue != nValue) or (Devices[Unit].sValue != sValue):
            Devices[Unit].Update(nValue, str(sValue))
            Domoticz.Log("Update "+str(nValue)+":'"+str(sValue)+"' ("+Devices[Unit].Name+")")
    return

def DumpConfigToLog():
    for x in Parameters:
        if Parameters[x] != "":
            Domoticz.Debug( "'" + x + "':'" + str(Parameters[x]) + "'")
    Domoticz.Debug("Device count: " + str(len(Devices)))
    for x in Devices:
        Domoticz.Debug("Device:           " + str(x) + " - " + str(Devices[x]))
        Domoticz.Debug("Internal ID:     '" + str(Devices[x].ID) + "'")
        Domoticz.Debug("External ID:     '" + str(Devices[x].DeviceID) + "'")
        Domoticz.Debug("Device Name:     '" + Devices[x].Name + "'")
        Domoticz.Debug("Device nValue:    " + str(Devices[x].nValue))
        Domoticz.Debug("Device sValue:   '" + Devices[x].sValue + "'")
        Domoticz.Debug("Device LastLevel: " + str(Devices[x].LastLevel))
    return

def stringToBase64(s):
    return base64.b64encode(s.encode('utf-8')).decode("utf-8")

def base64ToString(b):
    return base64.b64decode(b).decode('utf-8')
Last edited by rjblake on Tuesday 13 June 2017 15:11, edited 1 time in total.
amontillado
Posts: 2
Joined: Saturday 13 May 2017 0:08
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Generic Denon / Marantz python plugin

Post by amontillado »

I have trouble getting the plugin to work.
The plugin is available in the Hardware Dropdown List (Denon / Marantz AVR Amplifier) but when I try to Add it nothing happens.
The log shows no related error messages.

Plugin version 2.5.5 , Domoticz version 3.7450

Any ideas of what might be the cause?
rjblake
Posts: 142
Joined: Friday 21 October 2016 9:25
Target OS: NAS (Synology & others)
Domoticz version:
Location: Netherlands
Contact:

Re: Generic Denon / Marantz python plugin

Post by rjblake »

amontillado wrote:I have trouble getting the plugin to work.
The plugin is available in the Hardware Dropdown List (Denon / Marantz AVR Amplifier) but when I try to Add it nothing happens.
The log shows no related error messages.

Plugin version 2.5.5 , Domoticz version 3.7450

Any ideas of what might be the cause?
Perhaps start with the basics. Can you control the AVR from the official Denon app (IOS/Android), or connect through browser? Is the IP address of your AVR entered correctly and saved? Is the "IP Control" on the AVR set to "Always On"? Does the list of Inputs in the Domoticz Hardware match those for your model AVR (as per the Denon spreadsheet) exactly?
amontillado
Posts: 2
Joined: Saturday 13 May 2017 0:08
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Generic Denon / Marantz python plugin

Post by amontillado »

Thanks for the quick reply.

Yes I can connect to the AVR using the App, as wel as via the XML api, using the IP I entered. The "IP Control" setting on the AVR is "Always on".
I've changed the list of sources, my exact model (Marantz SR6010) isn't listed in one of the sheet, but the previous and subsequent models are.
I didn't add all the sources, and after the unsucessfull first test now only added the Tuner.
From my first (somewhat amateuristic) glance at the code I didnt think all the sources should be added.

The strange thing is that I see absolutly nothing in the log, regardles of the "debug" setting being set to true or not.
All I see that is relevant is some metionins of the pluginsystem (PluginSystem: Started, Python version '3.4.2'. // PluginSystem: Entering work loop.)
but none of the plugin.
Andyyyy
Posts: 29
Joined: Saturday 13 July 2013 23:46
Target OS: -
Domoticz version:
Contact:

Re: Generic Denon / Marantz python plugin

Post by Andyyyy »

Hi all,
can anyone help me with my error ?


2017-05-18 08:49:05.698 Error: PluginList: Error 'Error reading Attributes.' at line 24 column 28 in XML '

Denon AVR plugin.


"Sources" need to have '|' delimited names of sources that the Denon knows about from the technical manual.

The Sources Selector(s) can be changed after initial creation to any text and the plugin will still map to the actual Denon name.


Devices will be created in the Devices Tab only and will need to be manually made active.

# Changed for Denon AVR-X2300W
rjblake
Posts: 142
Joined: Friday 21 October 2016 9:25
Target OS: NAS (Synology & others)
Domoticz version:
Location: Netherlands
Contact:

Re: Generic Denon / Marantz python plugin

Post by rjblake »

Andyyyy wrote:Hi all,
can anyone help me with my error ?


2017-05-18 08:49:05.698 Error: PluginList: Error 'Error reading Attributes.' at line 24 column 28 in XML '

Denon AVR plugin.


"Sources" need to have '|' delimited names of sources that the Denon knows about from the technical manual.

The Sources Selector(s) can be changed after initial creation to any text and the plugin will still map to the actual Denon name.


Devices will be created in the Devices Tab only and will need to be manually made active.

# Changed for Denon AVR-X2300W
Seems you don't have the inputs named to match your specific AV Receiver. What model number do you have?
Andyyyy
Posts: 29
Joined: Saturday 13 July 2013 23:46
Target OS: -
Domoticz version:
Contact:

Re: Generic Denon / Marantz python plugin

Post by Andyyyy »

Hello rjblake,
i copy the plugin.py (with your code) to /domoticz/plugins/denon/plugin.py and then i restart Domoticz.
Next i go to the Hardware Page and then i get this error, i did not see the Denon Plugin in the Hardware pulldown, but i see the error in the log.

Andyyyy
rjblake
Posts: 142
Joined: Friday 21 October 2016 9:25
Target OS: NAS (Synology & others)
Domoticz version:
Location: Netherlands
Contact:

Re: Generic Denon / Marantz python plugin

Post by rjblake »

What platform are you running Domoticz on? What version of Domoticz are you running?
Did you change the owner and/or rights of the plugin.py and the /denon/ folder to Executable (or RWX) if on *nix or Pi?
Andyyyy
Posts: 29
Joined: Saturday 13 July 2013 23:46
Target OS: -
Domoticz version:
Contact:

Re: Generic Denon / Marantz python plugin

Post by Andyyyy »

Hello rjblake,
I use Domoticz 3.7450 on a Raspberr Pi.
I changed to 755 witz user Pi ..
What else i have to change ??

Andyyyy
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest