Noob Help - Serial Plugin

Do you have questions about writing plugins or scripts in Python? Meet the coders here.
Post Reply
adccon
Posts: 8
Joined: Sun May 23, 2010 8:16 pm

Noob Help - Serial Plugin

Post by adccon » Sun May 23, 2010 8:38 pm

Hello all,

I am in the midst of building a multiroom multi source audio distribution system for my house and need some help. I have a multi-source, multi zone amplifier that is controllable via RS232. Ultimately i want to communicate to this device via event ghost. The front end will be XLobby. I have been trying to do this through girder, but am really having difficulty. Someone on the Xlobby forum suggested EventGhost so here i am.

I tried to attach the protocol (pdf) but was not allowed. The commands are all very similar, but here is one for example:

Power On:

Unit Power On ( zones set to
last state before power off ) CM1 52h 45h 51h 38h 38h 43h 00h 20h 30h 20h 20h 20h 20h FFh

(note all commands begin with 52h and end with FFh)

Any takers on helping me (which may mean holding my hand and practically carrying me) create a plugin for this device?

All help is greatly appreciated.

Thanks,

Rob.

User avatar
jinxdone
Plugin Developer
Posts: 443
Joined: Tue Jan 02, 2007 4:08 pm

Re: Noob Help - Serial Plugin

Post by jinxdone » Sun May 23, 2010 11:11 pm

I would suggest using the Denon Serial plugin as a starting point, basically all you need to do is change the name and description of the plugin and the commands it has defined.

It creates an action for each command which are listed in the cmdList array, so this is where you will define your commands. The third value will be the actual command it will send over the serial, just make sure the data is in the correct encoding. (as byte values represented in hex. for example a string like '\x01\x02\x03'.) Check out what python docs about string literals.

Also set the new command begin and end characters in the CmdAction and ValueAction functions, so something like:

Code: Select all

class CmdAction(eg.ActionClass):
    """Base class for all argumentless actions"""
    
    def __call__(self):
        self.plugin.serial.write(chr(0x52)[/b] + self.cmd + chr(0xff))


    
class ValueAction(eg.ActionWithStringParameter):
    """Base class for all actions with adjustable argument"""
    
    def __call__(self, data):
        self.plugin.serial.write(chr(0x52) + self.cmd + str(data) + chr(0xff))
That should be all there is to it. The fourth variable in each line of the cmdList is a "range" limiter for the commands that take user configurable input values, set to None if your command has takes input.. hopefully you can figure it out. (I didn't look into it)

You can also use use the "Plugins -> Other -> Serial Port" -plugin to do send the commands, which may be useful for testing. (Actually this general purpose serial plugin would be enough to do what you want to, but that's a topic for another discussion...)

Hopefully this was enough to get you started.

-jinxdone

adccon
Posts: 8
Joined: Sun May 23, 2010 8:16 pm

Re: Noob Help - Serial Plugin

Post by adccon » Fri May 28, 2010 2:05 am

Thanks for help. I am working on this, and have incorporated some of your comments, but i have some questions.

1. When i place the begin and end characters in the CmdAction and ValueAction functions do i still need to place these bytes in the command list section. I am assuming i still need to include them as the cmdaction and valueaction just signify to EG the begin and end of the command, not that they are sent along with the command.

2. Im a little unclear on the eg.pluginclass. I have included by py file for review and comment. I havevcommented out some of the volume fade actions but i am not sure what else i need to edit out or revise based on my equipment.

3. I found the snippet below in the protocol for my equipment...what do you make of this. First is the actual command followed by a footnote which is at the end of the table.

Unit Power On ( zones set to last state before power off ) CM1 52h 45h 51h 38h 38h 43h A 20h 30h 20h 20h 20h 20h FFh

Footnote: Where for "type" , CM = control command sent to REQ88, FB = feedback response sent from REQ88


See the FB section below.

Code Bytes in hex

Remote Control trigger #1 input received FB1 52h 45h 51h 38h 38h 46h A 26h 80h 26h 26h 26h 26h FFh



So my question based on this is how i need to deal with this. Do i need to send "CM1" for the power on command in lieu of the hex bytes??? Also i am unclear on exactly what feedback is given to EG and what i need to do or not do with the feedback. The documentation indicates that "All commands received are echoed back to controller". I am including a link to a zip file which includes the pdf with all the information.

http://www.ilabamerica.com/REQ88.zip


Please review and comment. Sorry for such a long post.
Attachments
__init__.py
(20.43 KiB) Downloaded 275 times

User avatar
jinxdone
Plugin Developer
Posts: 443
Joined: Tue Jan 02, 2007 4:08 pm

Re: Noob Help - Serial Plugin

Post by jinxdone » Fri May 28, 2010 3:12 pm

1. When i place the begin and end characters in the CmdAction and ValueAction functions do i still need to place these bytes in the command list section. I am assuming i still need to include them as the cmdaction and valueaction just signify to EG the begin and end of the command, not that they are sent along with the command.
It would be clearer to include them in the cmdList rather than have them hardcoded in CmdAction/ValueAction functions.
2. Im a little unclear on the eg.pluginclass. I have included by py file for review and comment. I havevcommented out some of the volume fade actions but i am not sure what else i need to edit out or revise based on my equipment.
Actually the FadeTo could probably be useful for you too. Probably Denon Serial has no native command for fading volume so he(the person who coded the Denon Serial plugin) made one using volume up/down commands.

http://www.eventghost.org/docs/developer_docs.html Also check out some of the other plugins source code for a reference and search the forum.
3. I found the snippet below in the protocol for my equipment...what do you make of this. First is the actual command followed by a footnote which is at the end of the table.

Unit Power On ( zones set to last state before power off ) CM1 52h 45h 51h 38h 38h 43h A 20h 30h 20h 20h 20h 20h FFh

Footnote: Where for "type" , CM = control command sent to REQ88, FB = feedback response sent from REQ88
Literally the code you should send is '52h 45h 51h 38h 38h 43h 00h 20h 30h 20h 20h 20h 20h FFh', where 00h == A == a byte indicating the unit address

So, since a lot of the commands have variables in them you should make configuration dialogs to your EG plugin / actions to provide values for A...K for those commands that need them. This is what the ValueAction was for in Denon Serial, but some of your commands will need more configurable values so I think you'll have to improve on this.

I would make some of the options configurable when you load the plugin and store them in the plugin instance. Then instead of just sending data from the cmdList you could pass it through a function that fills in all the variables as needed. You should also do error checking for the commands before sending so you don't accidentally set volume to 100dB or something like that.. :) As an example you could have something like string.replace('#UnitAddress#', self.unitAddress) in CmdAction, and in cmdList ('PowerOn', 'Power On', '\x52\x45\x51\x38\x38\x43#UnitAddress#\x20\x30\x20\x20\x20\x20\xFF', None). Another way of doing it is to fill in the replacement values with string indexes (for example self.cmd[6] should always be the position for the unit address byte..). There's lots of room for improvement in this area of the plugin.



And as for the feedback, as far as I can see you dont have to do anything with it, but it's there to allow you to do some error checking. For example you could store the command when you send it, and unless that same command is received back within X seconds throw an exception. (since you know the equipment should always respond..)

-jinxdone

adccon
Posts: 8
Joined: Sun May 23, 2010 8:16 pm

Re: Noob Help - Serial Plugin

Post by adccon » Fri May 28, 2010 4:23 pm

ok, i will try to work with that, but in the cmdaction and valueaction code you posted i placed in the script and i get a syntax error on the following lines (or at least this is where the error is reported)

def __call__(self):
self.plugin.serial.write(chr(0x52)[/b] + self.cmd + chr(0xff))

i dont know enough about the proper syntax to identify the error. do you see anything. If you need it my py file is posted above.

Also i am using SCiTE as my editor. Do you recommend something different for Python?

User avatar
jinxdone
Plugin Developer
Posts: 443
Joined: Tue Jan 02, 2007 4:08 pm

Re: Noob Help - Serial Plugin

Post by jinxdone » Fri May 28, 2010 4:58 pm

Code: Select all

self.plugin.serial.write(self.cmd)
This should do the trick. There was an extra [/b] in there (which is not python al all), I must have messed up something while posting the message on the bulleting board.

I use eclipse ide with pydev for Python coding and for small stuff I just use a text editor. (notepad++) A text editor is all you need for making EG plugins, they usually aren't that complicated.

There is also a pycrust shell in EG (in "Help -> Python Shell"), which can sometimes be very useful.

PS. If you have issues with Python itself, just check the Python docs.

adccon
Posts: 8
Joined: Sun May 23, 2010 8:16 pm

Re: Noob Help - Serial Plugin

Post by adccon » Sat May 29, 2010 2:31 am

I had determined by trial and error that if i removed the [/b] the errors woudl go away, but your response confuses me (not that difficult to accomplish). Are you suggesting the command should be #1 or #2 below?

def __call__(self):
self.plugin.serial.write(chr(0x52) + self.cmd + chr(0xff))

def __call__(self):
self.plugin.serial.write(self.cmd)

User avatar
jinxdone
Plugin Developer
Posts: 443
Joined: Tue Jan 02, 2007 4:08 pm

Re: Noob Help - Serial Plugin

Post by jinxdone » Sat May 29, 2010 10:48 am

Like this.
adccon wrote:def __call__(self):
self.plugin.serial.write(self.cmd)

But, you will still have to modify that part of the plugin a lot if you want to make the actions configurable like i suggested in my earlier post.

adccon
Posts: 8
Joined: Sun May 23, 2010 8:16 pm

Re: Noob Help - Serial Plugin

Post by adccon » Sat May 29, 2010 11:07 am

So then i assume the valueaction class would be as follows also:

[/code]class ValueAction(eg.ActionWithStringParameter):
"""Base class for all actions with adjustable argument"""

def __call__(self, data):
self.plugin.serial.write(self.cmd + str(data))[/code]


Just so i can understand, in your first post you indicated I should have it as follows:

Code: Select all

class CmdAction(eg.ActionClass):
    """Base class for all argumentless actions"""
   
    def __call__(self):
        self.plugin.serial.write(chr(0x52) + self.cmd + chr(0xff))


   
class ValueAction(eg.ActionWithStringParameter):
    """Base class for all actions with adjustable argument"""
   
    def __call__(self, data):
        self.plugin.serial.write(chr(0x52) + self.cmd + str(data) + chr(0xff))
What does the second series do and why did you originally recommend it. Is that what you meant by hardcoding the beginning and end strings into the send commands? Sorry for being any trouble.

adccon
Posts: 8
Joined: Sun May 23, 2010 8:16 pm

Re: Noob Help - Serial Plugin

Post by adccon » Sat May 29, 2010 11:10 am

See above...i apparently got the syntax wrong to get the "code" shown correctly on the forum so disregard the "[/code] at the beginning and end of the first value action class above. it should have been posted as:

Code: Select all

class ValueAction(eg.ActionWithStringParameter):
    """Base class for all actions with adjustable argument"""
   
    def __call__(self, data):
        self.plugin.serial.write(self.cmd + str(data))

adccon
Posts: 8
Joined: Sun May 23, 2010 8:16 pm

Re: Noob Help - Serial Plugin

Post by adccon » Sat May 29, 2010 7:38 pm

Ok,

So i have now tried to a sample command from the script for the first time with no real success.

I am trying to send the string:

Code: Select all

#Power Commands

('PowerOn', 'Power On', '\x52\x45\x51\x38\x38\x43\x00\x20\x30\x20\x20\x20\x20\FF', None),
However on the port monitor i see the following going through:

118 29/05/2010 15:29:25 IRP_MJ_WRITE UP STATUS_SUCCESS 52 45 51 38 38 43 00 20 30 20 20 20 20 5c 46 46

Note it appears "FF" was converted to 5c and "46 46" was added

Any ideas on what is going on here. I am attaching the py file for reference. Also note previous questions in last few posts.

Thanks,

Rob.
Attachments
__init__.py
(20.49 KiB) Downloaded 271 times

adccon
Posts: 8
Joined: Sun May 23, 2010 8:16 pm

Re: Noob Help - Serial Plugin

Post by adccon » Sat May 29, 2010 7:41 pm

got it, i had to add "x" to the FF btyes. Other questions are still unresolved though, see above.

Post Reply