Plugin Denon AVR-X2100W Topic is solved

Python and python framework

Moderator: leecollings

User avatar
Dnpwwo
Posts: 820
Joined: Sunday 23 March 2014 9:00
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Melbourne, Australia
Contact:

Re: Plugin Denon AVR-X2100W

Post by Dnpwwo »

@l00pz,

@oohlaf reported the -273.1499 bug in Domoticz (not the plugin) and suggested a fix, a pull request is waiting to be merged.

Can you give the next beta version a go and I will have another look at the plugin if it still doesn't work.
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
gielie
Posts: 290
Joined: Tuesday 12 January 2016 11:40
Target OS: Raspberry Pi / ODroid
Domoticz version: latest β
Location: The Netherlands (Alkmaar)
Contact:

Re: Plugin Denon AVR-X2100W

Post by gielie »

I tried the new beta but still no luck with the volume.

Code: Select all

2017-02-21 16:21:24.073 User: Machiel initiated a switch command (301/Denon AVR X-2100 - Main Volume/Set Level)
2017-02-21 16:21:24.079 (Denon AVR X-2100) Calling message handler 'onCommand'.
2017-02-21 16:21:24.080 (Denon AVR X-2100) onCommand called for Unit 3: Parameter 'Set Level', Level: -273.1499938964844
2017-02-21 16:21:24.080 (Denon AVR X-2100) Sending data: 'MV-273.1499938964844 '.
And neither with the input selector

Code: Select all

2017-02-21 16:22:36.185 User: Machiel initiated a switch command (300/Denon AVR X-2100 - Main Zone/Set Level)
2017-02-21 16:22:36.222 (Denon AVR X-2100) Calling message handler 'onCommand'.
2017-02-21 16:22:36.223 (Denon AVR X-2100) onCommand called for Unit 2: Parameter 'Set Level', Level: -273.1499938964844
2017-02-21 16:22:36.223 Error: (Denon AVR X-2100) 'onCommand' failed 'KeyError'.
2017-02-21 16:22:36.223 Error: (Denon AVR X-2100) ----> Line 213 in /home/pi/domoticz/plugins/Denon/plugin.py, function onCommand 

Another error in the script

Code: Select all

2017-02-21 16:37:17.202 User: Machiel initiated a switch command (300/Denon AVR X-2100 - Main Zone/Set Level)
2017-02-21 16:37:17.247 (Denon AVR X-2100) Calling message handler 'onCommand'.
2017-02-21 16:37:17.247 (Denon AVR X-2100) onCommand called for Unit 2: Parameter 'Set Level', Level: -273.1499938964844
2017-02-21 16:37:17.248 Error: (Denon AVR X-2100) 'onCommand' failed 'KeyError'.
2017-02-21 16:37:17.248 Error: (Denon AVR X-2100) ----> Line 213 in /home/pi/domoticz/plugins/Denon/plugin.py, function onCommand
2017-02-21 16:37:18.450 (Denon AVR X-2100) Calling message handler 'onHeartbeat'.
2017-02-21 16:37:18.451 (Denon AVR X-2100) onHeartbeat: lastMessage PW, Sending 'ZM'.
- Aeon Labs USB Stick met Z-wave plus
- Aeotec MultiSensor 6
- FIBARO FGS223
- FIBARO FGWPE Wall Plug
- Neo CoolCam Power plug
- Popp Smoke Detector
- Toon
- Kodi Media Server
l00pz
Posts: 42
Joined: Wednesday 01 April 2015 11:52
Target OS: Linux
Domoticz version: Beta
Contact:

Re: Plugin Denon AVR-X2100W

Post by l00pz »

@gielie The latest Pull Request hasn't been merged yet, so we need to wait for this.
User avatar
gielie
Posts: 290
Joined: Tuesday 12 January 2016 11:40
Target OS: Raspberry Pi / ODroid
Domoticz version: latest β
Location: The Netherlands (Alkmaar)
Contact:

Re: Plugin Denon AVR-X2100W

Post by gielie »

Oh haha, ill wait.
- Aeon Labs USB Stick met Z-wave plus
- Aeotec MultiSensor 6
- FIBARO FGS223
- FIBARO FGWPE Wall Plug
- Neo CoolCam Power plug
- Popp Smoke Detector
- Toon
- Kodi Media Server
l00pz
Posts: 42
Joined: Wednesday 01 April 2015 11:52
Target OS: Linux
Domoticz version: Beta
Contact:

Re: Plugin Denon AVR-X2100W

Post by l00pz »

@Dnwwwo the Plugin seems to be working now in the latest commit! Thanks :D
User avatar
gielie
Posts: 290
Joined: Tuesday 12 January 2016 11:40
Target OS: Raspberry Pi / ODroid
Domoticz version: latest β
Location: The Netherlands (Alkmaar)
Contact:

Re: Plugin Denon AVR-X2100W

Post by gielie »

I updated to the latest beta and its working, yeah, tanks.

There is only 1 inconvenience, when I turn on the main device, zone 2 turns on. And when I turn off the main device, zone 2 won't turn off. I have to manually turn off zone 2.

I created a script when main zone is off turn zone 2 off.

Is there a better solution?
- Aeon Labs USB Stick met Z-wave plus
- Aeotec MultiSensor 6
- FIBARO FGS223
- FIBARO FGWPE Wall Plug
- Neo CoolCam Power plug
- Popp Smoke Detector
- Toon
- Kodi Media Server
raymond
Posts: 71
Joined: Monday 12 October 2015 15:46
Target OS: Raspberry Pi / ODroid
Domoticz version: V4.10232
Contact:

Re: Plugin Denon AVR-X2100W

Post by raymond »

l00pz wrote:@Dnwwwo the Plugin seems to be working now in the latest commit! Thanks :D
I can confirm the same, briliant !

Any plans to add Surround Modes into a Selector switch too? I'm not up to speed on python, but it would seems possible to do this same way as the Source Input selector.

Have this plugin running on a Marantz NR1602 without flaws now. Previously had a lot of LUA and xml parsing done to get this same result.
Great work ! Save me a bunch.

Ray
User avatar
Dnpwwo
Posts: 820
Joined: Sunday 23 March 2014 9:00
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Melbourne, Australia
Contact:

Re: Plugin Denon AVR-X2100W

Post by Dnpwwo »

@gielie,

Although my amp has 3 zones I only use 1. I just added the other code in there to show what could be done. I've had a look at the code and there is nothing obvious so you will need to post a log with debug turned on to help me spot the problem.

I thought I was treating the zones as separate so the amp shouldn't turn off until all zones are turned off (which seems to line up with what you are seeing) but if the power is off and a command is recieved, I send Power On which I thought would restore it to the last state. This works for one zone but maybe not multi-zone.

Perhaps I should try sending the specific zone on command not Power On to see if that works better. The manual is rubbish unfortunately so I'll need to play a bit.

@raymond,

Didn't realise this would work on Marantz as well. Happy days !

Is that set per zone or just at the amp level? There is no reason it wouldn't work
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
raymond
Posts: 71
Joined: Monday 12 October 2015 15:46
Target OS: Raspberry Pi / ODroid
Domoticz version: V4.10232
Contact:

Re: Plugin Denon AVR-X2100W

Post by raymond »

Yes works on Marantz also :D . The protocol and Parameter list is exactly the same, though SOURCE names are different, but that is also true for different Denon models I believe.

The Selector Switch for SOURCES and the SI command work the same way on my Marantz NR1602, same goes for MV, PW and ZM/Z2 commands.

Selecting the surround mode would work like the SOURCE INPUT you already have implemented. Creating another Selector Switch like the SOURCE INPUT but with different names (DOLBY, DTS, STEREO, AUTO etc.) would do the trick, along with the MS command sent instead of SI (Page 12 and 29 of the protocol.pdf shared earlier)

I'm happy as is, but if you're looking to implement more features, this would be on my list. I've seen folks getting into the PS command which handles all equalizer stuff, but that wouldn't have my initial interest.

Cheers,

Ray
User avatar
G3rard
Posts: 669
Joined: Wednesday 04 March 2015 22:15
Target OS: -
Domoticz version: No
Location: The Netherlands
Contact:

Re: Plugin Denon AVR-X2100W

Post by G3rard »

I am using the script for my Marantz NR1604 and it all seems to work.
I only get the error messages in the log like: Unknown message '@P' ignored. See the detailled log below.

I am using the latest beta v3.6807 and updated the Sources field with the right sources from my Marantz (copied the names from the web gui of the Marantz).

Any ideas how to fix this? Or is this something specific for the Marantz?

Code: Select all

2017-02-28 22:54:12.908 (Marantz) onMessage called with Data: '@PWR:1'
2017-02-28 22:54:12.908 Error: (Marantz) Unknown message '@P' ignored.
2017-02-28 22:54:22.324 (Marantz) Calling message handler 'onHeartbeat'.
2017-02-28 22:54:22.324 (Marantz) onHeartbeat: lastMessage PW, Sending 'ZM'.
2017-02-28 22:54:22.324 (Marantz) Sending data: 'ZM? '.
2017-02-28 22:54:22.375 (Marantz) Calling message handler 'onMessage'.
2017-02-28 22:54:22.375 (Marantz) onMessage called with Data: 'ZMOFF'
2017-02-28 22:54:22.375 (Marantz) Calling message handler 'onMessage'.
2017-02-28 22:54:22.375 (Marantz) onMessage called with Data: '@PWR:1'
2017-02-28 22:54:22.375 Error: (Marantz) Unknown message '@P' ignored.
2017-02-28 22:54:32.359 (Marantz) Calling message handler 'onHeartbeat'.
2017-02-28 22:54:32.359 (Marantz) onHeartbeat: lastMessage ZM, Sending 'SI'.
2017-02-28 22:54:32.359 (Marantz) Sending data: 'SI? '.
2017-02-28 22:54:32.427 (Marantz) Calling message handler 'onMessage'.
2017-02-28 22:54:32.427 (Marantz) onMessage called with Data: 'SITV'
2017-02-28 22:54:32.427 (Marantz) Calling message handler 'onMessage'.
2017-02-28 22:54:32.427 (Marantz) onMessage called with Data: '@SRC:11'
2017-02-28 22:54:32.427 Error: (Marantz) Unknown message '@S' ignored.
2017-02-28 22:54:32.427 (Marantz) Calling message handler 'onMessage'.
2017-02-28 22:54:32.427 (Marantz) onMessage called with Data: 'PSMDAX OFF'
2017-02-28 22:54:32.477 (Marantz) Calling message handler 'onMessage'.
2017-02-28 22:54:32.477 (Marantz) onMessage called with Data: '@MDA:1'
2017-02-28 22:54:32.477 Error: (Marantz) Unknown message '@M' ignored.
2017-02-28 22:54:32.527 (Marantz) Calling message handler 'onMessage'.
2017-02-28 22:54:32.527 (Marantz) onMessage called with Data: 'SVOFF'
2017-02-28 22:54:42.344 (Marantz) Calling message handler 'onHeartbeat'.
2017-02-28 22:54:42.344 (Marantz) onHeartbeat: lastMessage SI, Sending 'MV'.
2017-02-28 22:54:42.344 (Marantz) Sending data: 'MV? '.
2017-02-28 22:54:42.394 (Marantz) Calling message handler 'onMessage'.
2017-02-28 22:54:42.394 (Marantz) onMessage called with Data: 'MV56'
2017-02-28 22:54:42.394 (Marantz) Calling message handler 'onMessage'.
2017-02-28 22:54:42.394 (Marantz) onMessage called with Data: '@VOL:-240'
2017-02-28 22:54:42.394 Error: (Marantz) Unknown message '@V' ignored.
2017-02-28 22:54:42.462 (Marantz) Calling message handler 'onMessage'.
2017-02-28 22:54:42.462 (Marantz) onMessage called with Data: 'MVMAX 97'
2017-02-28 22:54:42.462 (Marantz) Unknown: Action MV, Detail 'MAX 97' ignored.
2017-02-28 22:54:52.329 (Marantz) Calling message handler 'onHeartbeat'.
2017-02-28 22:54:52.329 (Marantz) onHeartbeat: lastMessage MV, Sending 'MU'.
2017-02-28 22:54:52.329 (Marantz) Sending data: 'MU? '.
2017-02-28 22:54:52.379 (Marantz) Calling message handler 'onMessage'.
2017-02-28 22:54:52.379 (Marantz) onMessage called with Data: 'MUOFF'
2017-02-28 22:54:52.379 (Marantz) Calling message handler 'onMessage'.
2017-02-28 22:54:52.379 (Marantz) onMessage called with Data: '@AMT:1'
2017-02-28 22:54:52.379 Error: (Marantz) Unknown message '@A' ignored.
2017-02-28 22:55:02.361 (Marantz) Calling message handler 'onHeartbeat'.
2017-02-28 22:55:02.361 (Marantz) onHeartbeat: lastMessage MU, Sending 'PW'.
2017-02-28 22:55:02.361 (Marantz) Sending data: 'PW? '.
2017-02-28 22:55:02.428 (Marantz) Calling message handler 'onMessage'.
2017-02-28 22:55:02.428 (Marantz) onMessage called with Data: 'PWSTANDBY'
2017-02-28 22:55:02.428 (Marantz) Calling message handler 'onMessage'.
2017-02-28 22:55:02.428 (Marantz) onMessage called with Data: '@PWR:1'
2017-02-28 22:55:02.428 Error: (Marantz) Unknown message '@P' ignored.
Not using Domoticz anymore
raymond
Posts: 71
Joined: Monday 12 October 2015 15:46
Target OS: Raspberry Pi / ODroid
Domoticz version: V4.10232
Contact:

Re: Plugin Denon AVR-X2100W

Post by raymond »

G3rard wrote:I am using the script for my Marantz NR1604 and it all seems to work.
I only get the error messages in the log like: Unknown message '@P' ignored. See the detailled log below.

I am using the latest beta v3.6807 and updated the Sources field with the right sources from my Marantz (copied the names from the web gui of the Marantz).

Any ideas how to fix this? Or is this something specific for the Marantz?
I have the same thing on my NR1602 indeed. I do not know if I did something wrong or if it's just the Marantz. Everything else works flawless.

Ray
User avatar
Dnpwwo
Posts: 820
Joined: Sunday 23 March 2014 9:00
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Melbourne, Australia
Contact:

Re: Plugin Denon AVR-X2100W

Post by Dnpwwo »

@raymond & @G3rard,

The plugin will be fine because this is just the warning when it sees something unexpected and isn't in 'ignoreMessages' on line 57.

Given that it appears more amps than I expected can use this maybe 'ignoreMessages' should be a parameter. I'm a little tied up on something else at the moment and can look at it in a few days maybe.
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
raymond
Posts: 71
Joined: Monday 12 October 2015 15:46
Target OS: Raspberry Pi / ODroid
Domoticz version: V4.10232
Contact:

Re: Plugin Denon AVR-X2100W

Post by raymond »

I don't mind the message, it clogs up the log a bit, but all works fine!

Ray
User avatar
G3rard
Posts: 669
Joined: Wednesday 04 March 2015 22:15
Target OS: -
Domoticz version: No
Location: The Netherlands
Contact:

Re: Plugin Denon AVR-X2100W

Post by G3rard »

@Dnpwwo, I have added @P|@M|@S|@V|@A to the ignoreMessages in the plugin and then it's working fine :D

Also tried to add that field to the parameters by adding

Code: Select all

<param field="Ignore" label="Ignore Messages" width="550px" required="true" default="|SS|SV|SD|MS|PS|CV|@P|@M|@S|@V|@A|"/>
and on line 57

Code: Select all

ignoreMessages = str(Parameters["Ignore"])
but that gives a NameError in the log.

Code: Select all

2017-03-09 00:27:48.637 Error: (Denon4306) failed to load 'plugin.py', Python Path used was '/home/gerard/domoticz/plugins/Denon/:/usr/lib/python3.4/:/usr/lib/python3.4/plat-x86_64-linux-gnu:/usr/lib/python3.4/lib-dynload'.
2017-03-09 00:27:48.637 Error: (Marantz) Module Import failed, exception: 'NameError'
Can you point me in the right direction (sorry no Python knowledge yet...).
Not using Domoticz anymore
User avatar
Dnpwwo
Posts: 820
Joined: Sunday 23 March 2014 9:00
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Melbourne, Australia
Contact:

Re: Plugin Denon AVR-X2100W

Post by Dnpwwo »

@G3rard,

The field name needs to be one that Domoticz knows about. Have a look at http://www.domoticz.com/wiki/Developing ... Definition for the list of valid values.

I'm working on another version and was going to do a simpler fix which was to make it just log the message when debugging was turned on (which is probably when it is more useful than the current one)
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: Plugin Denon AVR-X2100W

Post by G3rard »

Thanks, didn't read that part of the wiki indeed...
However after changing the name to Mode4 or Mode5 I still get the same error :?
I will just wait for your new version.
Not using Domoticz anymore
User avatar
Dnpwwo
Posts: 820
Joined: Sunday 23 March 2014 9:00
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Melbourne, Australia
Contact:

Re: Plugin Denon AVR-X2100W

Post by Dnpwwo »

@G3rard,

You need to do the assignment inside onStart (or any other callback). When Python imports a file it also executes it so everything outside a function is evaluated (standard behaviour I can't stop it) but the Domoticz values have not been set up at that point so the Parameters dictionary does not exist (hence the NameError)

Just initialise it to "" on line 57 and then update it in a callback.
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: Plugin Denon AVR-X2100W

Post by G3rard »

@Dnpwwo,

Thanks, I added the ignoreMessages to onStart and then it works.

However when I click on Update in the Hardware tab I get the following error.

Code: Select all

2017-03-11 23:42:59.671 Error: PluginList: Error 'Error document empty.' at line 0 column 0 in XML ''.
2017-03-11 23:43:02.699 (Marantz) Exiting work loop...
2017-03-11 23:43:02.700 Error: Plugin: Async Read Exception: 125, Operation canceled
2017-03-11 23:43:02.701 (Marantz) Denon device has disconnected.
2017-03-11 23:43:02.783 (Marantz) Stopped.
2017-03-11 23:43:02.845 (Marantz) Initialized version 2.2.0, author 'dnpwwo'
2017-03-11 23:43:02.896 (Marantz) Connected successfully to: 192.168.1.138:23
This is my plugin.py code.
Spoiler: show

Code: Select all

#
#       Denon AVR 4306 Plugin
#
#       Author:     Dnpwwo, 2016
#
#   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.
#
"""
<plugin key="Denon4306" version="2.2.0" name="Denon AVR 4306 Amplifier" author="dnpwwo" wikilink="" externallink="http://www.denon.co.uk/uk">
    <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="Mode1" label="Zone Count" width="50px" required="true">
            <options>
                <option label="1" value="1"/>
                <option label="2" value="2"/>
                <option label="3" value="3"  default="true" />
            </options>
        </param>
        <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>
        <param field="Mode3" label="Sources" width="550px" required="true" default="Off|DVD|VDP|TV|CD|DBS|Tuner|Phono|VCR-1|VCR-2|V.Aux|CDR/Tape|AuxNet|AuxIPod"/>
        <param field="Mode4" label="Ignore Messages" width="550px" required="true" default="|SS|SV|SD|MS|PS|CV|@P|@M|@S|@V|@A|"/>
        <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

isConnected = False
nextConnect = 3
oustandingPings = 0

# Device Status - When off set device values to negative
powerOn = False
mainSource = 0
mainVolume1 = 0
zone2Source = 0
zone2Volume = 0
zone3Source = 0
zone3Volume = 0

# ignoreMessages = "|SS|SV|SD|MS|PS|CV|@P|@M|@S|@V|@A|"
ignoreMessages = ""
selectorMap = {}
pollingDict = {"PW":"ZM?\r", "ZM":"SI?\r", "SI":"MV?\r", "MV":"MU?\r", "MU":"Z2?\r", "Z2":"Z3?\r", "Z3":"PW?\r" }
lastMessage = ""

def onStart():
    global mainSource, mainVolume1, zone2Source, zone2Volume, zone3Source, zone3Volume, ignoreMessages

    ignoreMessages = str(Parameters["Mode4"])
    
    if Parameters["Mode6"] == "Debug":
        Domoticz.Debugging(1)
    LevelActions = '|'*Parameters["Mode3"].count('|')
    # if Zone 3 required make sure at least themain device exists, otherwise suppress polling for it
    if (Parameters["Mode1"] > "2"):
        if (6 not in Devices):
            Domoticz.Device(Name="Zone 3", Unit=6, TypeName="Selector Switch", Switchtype=18, Image=5, \
                            Options="LevelActions:"+stringToBase64(LevelActions)+";LevelNames:"+stringToBase64(Parameters["Mode3"])+";LevelOffHidden:ZmFsc2U=;SelectorStyle:MQ==").Create()
            if (7 not in Devices): Domoticz.Device(Name="Volume 3", Unit=7, Type=244, Subtype=73, Switchtype=7,  Image=8).Create()
            Domoticz.Log("Created Zone 3 device(s) because zone requested in hardware setup but device not found.")
        else:
            zone3Source = Devices[6].nValue
            if (7 in Devices): zone3Volume = int(Devices[7].sValue)
    else:
        pollingDict.pop("Z3")
        pollingDict["Z2"] = "PW?\r"
    
    # if Zone 2 required make sure at least themain device exists, otherwise suppress polling for it
    if (Parameters["Mode1"] > "1"):
        if (4 not in Devices):
            Domoticz.Device(Name="Zone 2", Unit=4, TypeName="Selector Switch", Switchtype=18, Image=5, \
                            Options="LevelActions:"+stringToBase64(LevelActions)+";LevelNames:"+stringToBase64(Parameters["Mode3"])+";LevelOffHidden:ZmFsc2U=;SelectorStyle:MQ==").Create()
            if (5 not in Devices): Domoticz.Device(Name="Volume 2", Unit=5, Type=244, Subtype=73, Switchtype=7,  Image=8).Create()
            Domoticz.Log("Created Zone 2 device(s) because zone requested in hardware setup but device not found.")
        else:
            zone2Source = Devices[4].nValue
            if (5 in Devices): zone2Volume = int(Devices[5].sValue)
    else:
        pollingDict.pop("Z2")
        pollingDict["MU"] = "PW?\r"
        
    if (1 not in Devices):
        Domoticz.Device(Name="Power", Unit=1, TypeName="Switch",  Image=5).Create()
        if (2 not in Devices): Domoticz.Device(Name="Main Zone", Unit=2, TypeName="Selector Switch", Switchtype=18, Image=5, \
                        Options="LevelActions:"+stringToBase64(LevelActions)+";LevelNames:"+stringToBase64(Parameters["Mode3"])+";LevelOffHidden:ZmFsc2U=;SelectorStyle:MQ==").Create()
        if (3 not in Devices): Domoticz.Device(Name="Main Volume", Unit=3, Type=244, Subtype=73, Switchtype=7,  Image=8).Create()
        Domoticz.Log("Created Main Zone devices because they were not found.")
    else:
        mainSource = Devices[2].nValue
        if (3 in Devices): mainVolume1 = int(Devices[3].sValue)
        
    DumpConfigToLog()
    dictValue=0
    for item in Parameters["Mode3"].split('|'):
        selectorMap[dictValue] = item
        dictValue = dictValue + 10
    Domoticz.Transport("TCP/IP", Parameters["Address"], Parameters["Port"])
    Domoticz.Protocol("Line")
    Domoticz.Connect()
    return

def onConnect(Status, Description):
    global isConnected, powerOn
    if (Status == 0):
        isConnected = True
        Domoticz.Log("Connected successfully to: "+Parameters["Address"]+":"+Parameters["Port"])
        Domoticz.Send('PW?\r')
    else:
        isConnected = False
        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)
        SyncDevices()
    return

def onMessage(Data, Status, Extra):
    global oustandingPings, lastMessage, selectorMap, powerOn, pollingDict, ignoreMessages
    global mainSource, mainVolume1, zone2Source, zone2Volume, zone3Source, zone3Volume

    oustandingPings = 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 pollingDict): lastMessage = action

    if (action == "PW"):        # Power Status
        if (detail == "STANDBY"):
            powerOn = False
        elif (detail == "ON"):
            powerOn = True
        else: Domoticz.Debug("Unknown: Action "+action+", Detail '"+detail+"' ignored.")
    elif (action == "ZM"):      # Main Zone on/off
        if (detail == "ON"):
            mainVolume1 = abs(mainVolume1)
        elif (detail == "OFF"):
            mainSource = 0
            mainVolume1 = abs(mainVolume1)*-1
        else: Domoticz.Debug("Unknown: Action "+action+", Detail '"+detail+"' ignored.")
    elif (action == "SI"):      # Main Zone Source Input
        for key, value in selectorMap.items():
            if (detail == value):      mainSource = key
    elif (action == "MV"):      # Master Volume
        if (detail.isdigit()):
            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"):         mainVolume1 = abs(mainVolume1)*-1
        elif (detail == "OFF"):      mainVolume1 = abs(mainVolume1)
        else: Domoticz.Debug("Unknown: Action "+action+", Detail '"+detail+"' ignored.")
    elif (action == "Z2"):      # Zone 2
        if (detail.isdigit()):
            zone2Volume = int(detail[0:2])
        else:
            for key, value in selectorMap.items():
                if (detail == value):      zone2Source = key
            if (zone2Source == 0):  zone2Volume = abs(zone2Volume)*-1
            else:                   zone2Volume = abs(zone2Volume)*-1
    elif (action == "Z3"):      # Zone 3
        if (detail.isdigit()):
            zone3Volume = int(detail[0:2])
        else:
            for key, value in selectorMap.items():
                if (detail == value):      zone3Source = key
            if (zone3Source == 0):  zone3Volume = abs(zone3Volume)*-1
            else:                   zone3Volume = abs(zone3Volume)*-1
    else:
        if (ignoreMessages.find(action) < 0):
            Domoticz.Error("Unknown message '"+action+"' ignored.")
    SyncDevices()
    return

def onCommand(Unit, Command, Level, Hue):
    global selectorMap, powerOn

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

    Command = Command.strip()
    action, sep, params = Command.partition(' ')
    delay = 0
    if (powerOn == False):
        Domoticz.Send('PWON\r')  # Any commands sent within 4 seconds of this will potentially be ignored
        delay = int(Parameters["Mode2"])
    if (action == "On"):
        if (Unit == 1):     Domoticz.Send(Message='ZMON\r', Delay=delay)
        elif (Unit == 2):   Domoticz.Send(Message='ZMON\r', Delay=delay)
        elif (Unit == 3):   Domoticz.Send(Message='MUOFF\r', Delay=delay)
        elif (Unit == 4):   Domoticz.Send(Message='Z2ON\r', Delay=delay)
        elif (Unit == 5):   Domoticz.Send(Message='Z2MUOFF\r', Delay=delay)
        elif (Unit == 6):   Domoticz.Send(Message='Z3ON\r', Delay=delay)
        elif (Unit == 7):   Domoticz.Send(Message='Z3MUOFF\r', Delay=delay)
        else: Domoticz.Error( "Unknown Unit number in command "+str(Unit)+".")
    elif (action == "Set"):
            if (params.capitalize() == 'Level') or (Command.lower() == 'Volume'):
                if (Unit == 2):     # Main selector
                    Domoticz.Send(Message='SI'+selectorMap[Level]+'\r', Delay=delay)
                elif (Unit == 3):   # Volume control
                    Domoticz.Send(Message='MV'+str(Level)+'\r', Delay=delay)
                elif (Unit == 4):   # Zone 2 selector
                    Domoticz.Send(Message='Z2'+selectorMap[Level]+'\r', Delay=delay)
                elif (Unit == 5):   # Zone 2 Volume control
                    Domoticz.Send(Message='Z2'+str(Level)+'\r', Delay=delay)
                elif (Unit == 6):   # Zone 3 selector
                    Domoticz.Send(Message='Z3'+selectorMap[Level]+'\r', Delay=delay)
                elif (Unit == 7):   # Zone 3 Volume control
                    Domoticz.Send(Message='Z3'+str(Level)+'\r', Delay=delay)
                SyncDevices()
    elif (action == "Off"):
        if (Unit == 1):     Domoticz.Send(Message='ZMOFF\r', Delay=delay)
        elif (Unit == 2):   Domoticz.Send(Message='ZMOFF\r', Delay=delay)
        elif (Unit == 3):   Domoticz.Send(Message='MUON\r', Delay=delay)
        elif (Unit == 4):   Domoticz.Send(Message='Z2OFF\r', Delay=delay)
        elif (Unit == 5):   Domoticz.Send(Message='Z2MUON\r', Delay=delay)
        elif (Unit == 6):   Domoticz.Send(Message='Z3OFF\r', Delay=delay)
        elif (Unit == 7):   Domoticz.Send(Message='Z3MUON\r', Delay=delay)
        else: Domoticz.Error( "Unknown Unit number in command "+str(Unit)+".")
    else:
        Domoticz.Error("Unhandled action '"+action+"' ignored, options are On/Set/Off")
    return

def onDisconnect():
    global isConnected, powerOn
    isConnected = False
    powerOn = False
    Domoticz.Log("Denon device has disconnected.")
    SyncDevices()
    return

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

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

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("Device ID:       '" + str(Devices[x].ID) + "'")
        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')
Not using Domoticz anymore
User avatar
Dnpwwo
Posts: 820
Joined: Sunday 23 March 2014 9:00
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Melbourne, Australia
Contact:

Re: Plugin Denon AVR-X2100W

Post by Dnpwwo »

@G3rard,

The "Async Read Exception: 125, Operation canceled" is nothing to worry about, Unix seems to throw that during a plugin forced shutdown sometimes but it isn't a problem.

I haven't seen the "PluginList: Error 'Error document empty.' at line 0 column 0 in XML'." error. How many plugins do you have on your system? Is it just the one?
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: Plugin Denon AVR-X2100W

Post by G3rard »

@Dnpwwo,
I have some other plugins on the system (Sonos, Kodi, Rain prediction (Buienradar)).
The pluginlist error appeared for the first time after I changed the Denon script regarding the ignoredMessages.
Not using Domoticz anymore
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 1 guest