Yamaha AV Receiver Plugin

Python and python framework
ohnsorge
Posts: 2
Joined: Tuesday 08 December 2015 1:10
Target OS: -
Domoticz version:
Contact:

Re: Yamaha AV Receiver Plugin

Post by ohnsorge » Friday 18 August 2017 17:57

Hi, when i install a plugin after few hours Domoticz show error:
2017-08-18 17:20:56.782 Domoticz V3.8153 (c)2012-2017 GizMoCuz
2017-08-18 17:20:56.783 Build Hash: 494fff7, Date: 2017-07-30 12:19:41
2017-08-18 17:20:56.783 Startup Path: /home/pi/domoticz/
2017-08-18 17:20:56.830 Sunrise: 05:42:00 SunSet:20:10:00
2017-08-18 17:20:56.830 EventSystem: reset all events...
2017-08-18 17:20:56.993 PluginSystem: Started, Python version '3.4.2'.
2017-08-18 17:20:56.994 Using 1-Wire support (OWFS)...
2017-08-18 17:20:57.009 Active notification Subsystems: (0/12)
2017-08-18 17:20:57.018 WebServer(HTTP) started on address: 0.0.0.0 with port 8080
2017-08-18 17:20:57.042 Error: WebServer(SSL) startup failed on address 0.0.0.0 with port: 443: bind: Permission denied
2017-08-18 17:20:57.042 Error: WebServer(SSL) check privileges for opening ports below 1024
2017-08-18 17:20:57.043 Proxymanager started.
2017-08-18 17:20:57.046 Starting shared server on: 0.0.0.0:6144
2017-08-18 17:20:57.046 TCPServer: shared server started...
2017-08-18 17:20:57.047 RxQueue: queue worker started...
2017-08-18 17:20:59.059 Wunderground: Worker started...
2017-08-18 17:20:59.060 EventSystem: reset all events...
2017-08-18 17:20:59.062 EventSystem: reset all device statuses...
2017-08-18 17:20:59.334 PluginSystem: Entering work loop.
2017-08-18 17:20:59.551 (Yamaha RXV) Initialized version 1.0.0, author 'thomasvillagers'
Naruszenie ochrony pamięci

Have you meet something like this?
Sorry for my english :)

EJanus
Posts: 3
Joined: Thursday 24 August 2017 17:15
Target OS: Raspberry Pi
Domoticz version: 3.8153
Location: Netherlands
Contact:

Re: Yamaha AV Receiver Plugin

Post by EJanus » Thursday 24 August 2017 20:02

I've been trying for hours to get this to work, but no success. I hope you can take some time to help me out.

The plugin made by thomasvillagers works really well! But now I want to use zone2 as well. So I took the code that jimtrout87 wrote and tried to put it in the latest update of thomasvillagers plugin.py (because the code that jimtrout87 posted earlier, doesn't work anymore).

What I've been trying to do is this:

Code: Select all

 # Basic Python Plugin 
#
# Author: thomas-villagers
#
"""
<plugin key="YamahaPlug" name="Yamaha AV Receiver" author="thomasvillagers" version="1.0.0" wikilink="http://www.domoticz.com/wiki/plugins/plugin.html" externallink="https://yamaha.com/products/audio_visual/av_receivers_amps/">
    <params>
     <param field="Address" label="IP Address" width="200px" required="true" default="192.168.1.10"/>
     <param field="Port" label="Port" width="50px" required="true" default="50000"/>
     <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

class BasePlugin:
    enabled = False
    isConnected = True
    outstandingPings = 0
    nextConnect = 0
    commandArray = ["@MAIN:VOL=?", "@MAIN:INP=?", "@MAIN:MUTE=?", "@MAIN:SOUNDPRG=?", "@MAIN:SCENE=?", "@MAIN:PWR=?","@ZONE2:VOL=?", "@ZONE2:INP=?", "@MAIN:ZONE2=?", "@ZONE2:SOUNDPRG=?", "@ZONE2:SCENE=?", "@ZONE2:PWR=?"]
    commandIndex = 0 

    def __init__(self):
        #self.var = 123
        return

    def onStart(self):
        if Parameters["Mode6"] == "Debug":
           Domoticz.Debugging(1)
        Domoticz.Debug("onStart called")
        if (len(Devices) == 0):
            Domoticz.Device(Name="Status",  Unit=1, Type=17,  Switchtype=17).Create()          
            Domoticz.Device(Name="Volume",  Unit=2, Type=244, Subtype=73, Switchtype=7,  Image=8).Create()
            LevelActions= "LevelActions:"+stringToBase64("||||")+";"
            LevelNames= "LevelNames:"+stringToBase64("Off|Scene1|Scene2|Scene3|Scene4|Other")+";"
            Other= "LevelOffHidden:ZmFsc2U=;SelectorStyle:MA==" # true is "dHJ1ZQ==", 1 is "MQ=="
            Options=LevelActions+LevelNames+Other
            Domoticz.Device(Name="Source", Unit=3, TypeName="Selector Switch", Options=Options).Create()
            Domoticz.Device(Name="Zone 2 Status",  Unit=4, Type=17,  Switchtype=17).Create()          
            Domoticz.Device(Name="Zone 2 Volume",  Unit=5, Type=244, Subtype=73, Switchtype=7,  Image=8).Create()
            LevelActions= "LevelActions:"+stringToBase64("|||")+";"
            LevelNames= "LevelNames:"+stringToBase64("Off|Main Sync|Input1|Other")+";"
            Other= "LevelOffHidden:ZmFsc2U=;SelectorStyle:MA==" # true is "dHJ1ZQ==", 1 is "MQ=="
            Options=LevelActions+LevelNames+Other
            Domoticz.Device(Name="Zone 2 Source", Unit=6, TypeName="Selector Switch", Options=Options).Create()

        self.connection = Domoticz.Connection(Name="Yamaha connection", Transport="TCP/IP", Protocol="Line", Address=Parameters["Address"], Port=Parameters["Port"])
        self.connection.Connect()
        Domoticz.Heartbeat(20)

    def onStop(self):
        Domoticz.Log("onStop called")

    def onConnect(self, Connection, Status, Description):
        Domoticz.Debug("onConnect called. Status: " + str(Status))
        if (Status == 0): 
          self.isConnected = True
#         UpdateDevice(1,1,"")
          self.onHeartbeat()
        else: 
          self.isConnected = False

    def onMessage(self, Connection, Data, Status, Extra):
        Domoticz.Debug("onMessage called")
        self.outstandingPings = self.outstandingPings - 1
        strData = Data.decode("utf-8", "ignore")
        arrData = strData.split('=')
        for x in arrData:
            Domoticz.Debug(x)
        if (arrData[0] == "@MAIN:VOL"):
            vol = float(arrData[1])
            sliderValue = int(vol*5/4 + 100)
			if (Devices[1].sValue == "On"):
                UpdateDevice(2,2,str(sliderValue)) 
        elif (arrData[0] == "@MAIN:INP"): 
            s = arrData[1]
            if (Devices[1].sValue == "On"):
                if (s == "HDMI1"):
                    UpdateDevice(3,2,str(10))
                elif (s == "HDMI2"):
                    UpdateDevice(3,2,str(20))
                elif (s == "AUDIO1"):
                    UpdateDevice(3,2,str(30))
                elif (s == "TUNER"):
                    UpdateDevice(3,2,str(40))
                else: 
                    UpdateDevice(3,2,str(50))
        elif (arrData[0] == "@MAIN:PWR"):
            p = arrData[1]
            Domoticz.Log(p)
            if (p == "On"):
                UpdateDevice(1,1,"On")            
            elif (p == "Standby"):
                UpdateDevice(1,0,"Standby")
                UpdateDevice(2,0,Devices[2].sValue)
                UpdateDevice(3,0,Devices[3].sValue)
        elif (arrData[0] == "@ZONE2:VOL"):
            vol = float(arrData[1])
            sliderValue = int(vol*5/4 + 100)
            if (Devices[4].sValue == "On"):
                UpdateDevice(5,2,str(sliderValue)) 
        elif (arrData[0] == "@ZONE2:INP"): 
            s = arrData[1]
            if (Devices[4].sValue == "On"):
                if (s == "Main Zone Sync"):
                    UpdateDevice(6,2,str(10))
                elif (s == "AUDIO1"):
                    UpdateDevice(6,2,str(20))
                else: 
                    UpdateDevice(6,2,str(30))
        elif (arrData[0] == "@ZONE2:PWR"):
            p = arrData[1]
            Domoticz.Log(p)
            if (p == "On"):
                UpdateDevice(4,1,"On")                
            elif (p == "Standby"):
                UpdateDevice(4,0,"Standby")
                UpdateDevice(5,0,Devices[5].sValue)
                UpdateDevice(6,0,Devices[6].sValue)

    def onCommand(self, Unit, Command, Level, Hue):
        Domoticz.Debug("onCommand called for Unit " + str(Unit) + ": Parameter '" + str(Command) + "', Level: " + str(Level))
        if (self.isConnected == False):
            self.connection.Connect() 
            return
        if (Unit == 1):
            if (Command == "Off"):
                UpdateDevice(1,0,Devices[1].sValue) # TODO remove
                self.connection.Send("@MAIN:PWR=Standby\r\n")
            elif (Command == "On"): 
               self.connection.Send("@MAIN:PWR=On\r\n")
        elif (Unit == 2): 
            if (Command == "Set Level"): 
                volume = int(Level)*4/5 - 80
                volumeToSend = round(2*volume)/2
                self.connection.Send("@MAIN:VOL="+str(volumeToSend)+"\r\n") 
        elif (Unit == 3): 
            input = str(int(int(Level)/10))
            self.connection.Send("@MAIN:SCENE=Scene " + input + "\r\n")
        elif (Unit == 4):
            if (Command == "Off"):
                UpdateDevice(4,0,Devices[1].sValue) # TODO remove
                self.connection.Send("@ZONE2:PWR=Standby\r\n")
            elif (Command == "On"): 
                self.connection.Send("@ZONE2:PWR=On\r\n")
        elif (Unit == 5): 
            if (Command == "Set Level"): 
                volume = int(Level)*4/5 - 80
                volumeToSend = round(2*volume)/2
                self.connection.Send("@ZONE2:VOL="+str(volumeToSend)+"\r\n")
        elif (Unit == 6): 
            input = str(int(int(Level)/10))
            if (input == "1"):
                self.connection.Send("@ZONE2:INP=Main Zone Sync" + "\r\n")
            elif (input == "2"):
                self.connection.Send("@ZONE2:INP=AUDIO1" + "\r\n")

    def onNotification(self, Data):
        Domoticz.Debug("onNotification: " + str(Data))

    def onDisconnect(self, Connection):
        Domoticz.Debug("onDisconnect called")
        self.isConnected = False 
 #       UpdateDevice(1,0,"")
 #       UpdateDevice(2,0,Devices[2].sValue)
 #       UpdateDevice(3,0,Devices[3].sValue)

    def onHeartbeat(self):
        Domoticz.Debug("onHeartbeat called. Connected: " + str(self.isConnected))
        if (self.isConnected == True):
            if (self.outstandingPings > 6):
                Domoticz.Debug("Missed more than 6 pings - disconnect")
                self.connection.Disconnect()  # obsolete 
                self.nextConnect = 0
            else:   
                self.connection.Send(self.commandArray[self.commandIndex] + "\r\n")
                self.commandIndex = (self.commandIndex + 1 ) % len(self.commandArray)
                self.outstandingPings = self.outstandingPings + 1
        else: 
            self.outstandingPings = 0
            self.nextConnect = self.nextConnect - 1
            if (self.nextConnect <= 0):
                self.nextConnect = 3
                self.connection.Connect()  # obsolete 

global _plugin
_plugin = BasePlugin()

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

def onStop():
    global _plugin
    _plugin.onStop()

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

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

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

def onNotification(Data):
    global _plugin
    _plugin.onNotification(Data)

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

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

    # Generic helper functions
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')
 

It doesn't work. When I add hardware in Domoticz it seems to work after selecting this plugin, but when i go to the Devices nothing shows up. Domoticz log tells me that there is an error in line 80, but I don't understand how I should fix this.

Line 80: if (Devices[1].sValue == "On"):

Please help me out.

EJanus
Posts: 3
Joined: Thursday 24 August 2017 17:15
Target OS: Raspberry Pi
Domoticz version: 3.8153
Location: Netherlands
Contact:

Re: Yamaha AV Receiver Plugin

Post by EJanus » Friday 01 September 2017 16:56

jimtrout87 wrote:
Monday 06 March 2017 11:36
Ok so i tried this myself and managed to get the scenes working if anyone is interested...
Hi Jim,

As you can read in my last post, your code doesn't work anymore. I tried to fix it by combining your code with the newest plugin of thomas, but I failed (becourse I have no programming skills). Can you help me out? I really would like to be able to use zone2 etc. like you posted before.

EJanus
Posts: 3
Joined: Thursday 24 August 2017 17:15
Target OS: Raspberry Pi
Domoticz version: 3.8153
Location: Netherlands
Contact:

Re: Yamaha AV Receiver Plugin

Post by EJanus » Wednesday 06 September 2017 17:28

I Think I solved it. Right now I'm testing if and how everything works. Will report back later.

Remicade
Posts: 5
Joined: Friday 15 September 2017 21:43
Target OS: Raspberry Pi
Domoticz version:
Contact:

Re: Yamaha AV Receiver Plugin

Post by Remicade » Friday 15 September 2017 22:00

Hi, on my rx-v677 it is sort of running. I o not use any additional scripts, only the plugin.
Volume works. Selector works. But when I power off the amp Domoticz still says the it is on.
How to get the Yamaha logos is my other question.
Thanks Paul

Remicade
Posts: 5
Joined: Friday 15 September 2017 21:43
Target OS: Raspberry Pi
Domoticz version:
Contact:

Re: Yamaha AV Receiver Plugin

Post by Remicade » Friday 15 September 2017 22:00

Hi, on my rx-v677 it is sort of running. I do not use any additional scripts, only the plugin.
Volume works. Selector works. But when I power off the amp Domoticz still says that it is on.
How to get the Yamaha logos is my other question.
Thanks Paul
Last edited by Remicade on Saturday 16 September 2017 10:30, edited 1 time in total.

Goldwing1973
Posts: 104
Joined: Monday 08 August 2016 22:55
Target OS: Linux
Domoticz version: Stable
Location: Netherlands, Alphen aan den Rijn
Contact:

Re: Yamaha AV Receiver Plugin

Post by Goldwing1973 » Friday 15 September 2017 23:26

2017-09-15 23:23:26.617 Error: (Yamaha Reciever Woonkamer) 'onMessage' failed 'TypeError':'onMessage() missing 2 required positional arguments: 'Status' and 'Extra''.

Thats what i'm getting with my Yamaha RX-V477, it would be nice to get it working.
Over 50 Z-Wave Devices (Fibaro and Neo), 4xLogitech Hub, 2xPhilips Hue Bridge+55 Lights, 1x Nest Thermostat, 2xNetatmo Weather Station, 1xSkybell v1 Doorbell, 3 Kwikset KEVO Doorlocks and Domoticz running on a Intel NUC

Remicade
Posts: 5
Joined: Friday 15 September 2017 21:43
Target OS: Raspberry Pi
Domoticz version:
Contact:

Re: Yamaha AV Receiver Plugin

Post by Remicade » Saturday 16 September 2017 14:15

Hi,
After a restart, (Domoticz hangs some times, I have to copy the auto restart and monitoring script) in my log I find this...

2017-09-16 14:12:51.793 Error: (Yamaha) 'onMessage' failed 'ValueError':'invalid literal for int() with base 10: 'y''.
2017-09-16 14:12:51.793 Error: (Yamaha) ----> Line 159 in /home/pi/domoticz/plugins/Yamaha/plugin.py, function onMessage
2017-09-16 14:12:51.793 Error: (Yamaha) ----> Line 85 in /home/pi/domoticz/plugins/Yamaha/plugin.py, function onMessage

What could this be?
Thanks Paul

Remicade
Posts: 5
Joined: Friday 15 September 2017 21:43
Target OS: Raspberry Pi
Domoticz version:
Contact:

Re: Yamaha AV Receiver Plugin

Post by Remicade » Sunday 17 September 2017 17:30

Could this be an answer to my earlier question:
The error is "invalid literal for int() with base 10:". This just means that the argument that you passed to int doesn't look like a number. In other words it's either empty, or has a character in it other than a digit.

This can be reproduced in a python shell.

>>> int("x")
ValueError: invalid literal for int() with base 10: 'x'

But change int into what?
Thanks Paul

Damnet
Posts: 14
Joined: Friday 24 February 2017 21:43
Target OS: Raspberry Pi
Domoticz version:
Contact:

Re: Yamaha AV Receiver Plugin

Post by Damnet » Friday 29 September 2017 22:27

Goldwing1973 wrote:
Friday 15 September 2017 23:26
2017-09-15 23:23:26.617 Error: (Yamaha Reciever Woonkamer) 'onMessage' failed 'TypeError':'onMessage() missing 2 required positional arguments: 'Status' and 'Extra''.

Thats what i'm getting with my Yamaha RX-V477, it would be nice to get it working.
Agree im getting the same errors fyi. 'onMessage' failed 'TypeError':'onMessage() missing 2 required positional arguments: 'Status' and 'Extra''.

HTR4065 receiver with Domoticz Version: 3.8209 on RPi.

thomasvillagers
Posts: 16
Joined: Monday 06 February 2017 16:57
Target OS: Raspberry Pi
Domoticz version:
Contact:

Re: Yamaha AV Receiver Plugin

Post by thomasvillagers » Saturday 07 October 2017 15:01

Hi!
Agree im getting the same errors fyi. 'onMessage' failed 'TypeError':'onMessage() missing 2 required positional arguments: 'Status' and 'Extra''.
fixed.
The error is "invalid literal for int() with base 10:". This just means that the argument that you passed to int doesn't look like a number. In other words it's either empty, or has a character in it other than a digit.
hm, cannot confirm this one ...

In addition, I refactored a few things and added a new device for controlling your AV inputs.

You can rename the input names in the two selector switches and you can delete unused ones. But you MUST keep them in order. That means, you can delete the unused inputs HDMI7, HDMI6 etc. but you CAN'T delete i. e. HDMI1 and keep the others.

You can find the updated version on Github. Hope "most" of the bugs are fixed (there are still plenty, sorry ...).

Icon images attached!

- thomas
Attachments
yamaha.zip
(8.83 KiB) Downloaded 17 times

Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests