Difference between revisions of "ThreadedRubyProtocolObject"
From LinuxMCE
Wierdbeard65 (Talk | contribs) m |
|||
(30 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
− | = | + | {{Versioninfo}} |
− | + | {| align="right" | |
− | + | | __TOC__ | |
− | + | |} | |
− | + | [[Category:Tutorials]] | |
− | + | [[Category:GSD]] | |
− | + | [[Category:ThreadedRuby]] | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | Here is my ThreadedRuby code. | |
− | + | I'm trying to add notes and a bit of an explanation as to what each piece of code does. | |
− | + | If you just want to get going, create a class Object for your protocol as per below. | |
− | + | ||
− | + | =ProtocolObject Class= | |
− | + | This is a generic replaceable class. | |
− | + | This object needs the following methods: | |
− | + | ==Methods== | |
− | + | ===Initialize()=== | |
− | + | *'''What it does:''' | |
− | + | ::any Object initialization you may need. | |
− | + | *'''When is this called:''' | |
− | + | ::Upon Object creation. | |
− | + | *'''What you will get:''' | |
− | + | ::nothing. | |
− | + | *'''What you will return:''' | |
− | + | ::nothing. | |
− | + | ===dceCommandIn(cmd)=== | |
− | + | *'''What is does:''' | |
− | + | ::sends you a command object to allow you to create gsdOut(). | |
− | + | *'''What you will get:''' | |
− | + | ::cmd (Command Object) | |
− | + | *'''What you need to return:''' | |
+ | ::nothing (ignored) | ||
+ | *'''When you will get this:''' | ||
+ | ::executed when a new DCE command is sent to you. | ||
+ | ===dceResponseIn(cmd)=== | ||
+ | *'''What it does:''' | ||
+ | ::Sends you a DCE object to compare with the command. | ||
+ | *'''What you will get:''' | ||
+ | ::cmd (Command Object) | ||
+ | *'''What you need to return:''' | ||
+ | ::TRUE if you accept this response. | ||
+ | ::FALSE if you do NOT accept this response. | ||
+ | *'''When you will get this:''' | ||
+ | ::executed when a new DCE response is ready. | ||
+ | ===gsdCommandIn(value)=== | ||
+ | *'''What it does:''' | ||
+ | ::sends you a String to allow you to create a dceOut(). | ||
+ | *'''What you will get:''' | ||
+ | ::value (String Object) | ||
+ | *'''What you need to return:''' | ||
+ | ::nothing (ignored) | ||
+ | *'''When you will get this:''' | ||
+ | ::executed when a new GSD command is sent to you. | ||
+ | ===gsdResponseIn(value)=== | ||
+ | *'''What it does:''' | ||
+ | ::Sends you a GSD Response to compare with the command. | ||
+ | *'''What you will get:''' | ||
+ | ::cmd (Command Object) | ||
+ | *'''What you need to return:''' | ||
+ | ::TRUE if you accept this response. | ||
+ | ::FALSE if you do NOT accept this response. | ||
+ | *'''When you will get this:''' | ||
+ | ::executed when a new GSD response is ready. | ||
+ | ===dceout()=== | ||
+ | *'''What it does:''' | ||
+ | ::Creates a Command Object to send to DCE. | ||
+ | *'''What you will get:''' | ||
+ | ::nothing. | ||
+ | *'''What you need to return:''' | ||
+ | ::a Command Object representing the previous gsdCommandIn. | ||
+ | *'''When is this called:''' | ||
+ | ::After a gsdCommandIn has been sent. | ||
+ | ===gsdout()=== | ||
+ | *'''What it does:''' | ||
+ | ::creates a String Object to send to GSD. | ||
+ | *'''What you will get:''' | ||
+ | ::nothing. | ||
+ | *'''What you will return:''' | ||
+ | ::a String Object representing the previous dceCommandIn. | ||
+ | *'''When is this called:''' | ||
+ | ::After a dceCommandIn has been sent. | ||
+ | ==Properties:== | ||
+ | ===responseAccepted=== | ||
+ | *'''What it does:''' | ||
+ | ::signals that the current response is accepted as valid. | ||
+ | *'''When you should set this: | ||
+ | ::Set this to TRUE if you accept the response as a valid response for this command. | ||
+ | :Set this to FALSE if you do NOT accept this response | ||
− | + | ===responseNeeded=== | |
− | + | ||
− | + | *'''What it does:''' | |
− | + | ::signals when you need a response. | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ===commandHolder=== | |
+ | *'''What it does:''' | ||
+ | ::If you need to create a new command, this is the holder for it. | ||
− | + | ===threaded=== | |
− | + | *'''What it does:''' | |
+ | ::determines if this command is threadable | ||
+ | *'''When you should set this:''' | ||
+ | ::This should be set to TRUE to enable threading. | ||
+ | ::if this is set to FALSE, all threading will be suspended UNTIL this command is complete. (or times out) | ||
+ | ==ProtocolObject Class Template== | ||
<pre> | <pre> | ||
class PLCBUS | class PLCBUS | ||
attr_reader :responseAccepted, :responseNeeded, :commandHolder, :threaded | attr_reader :responseAccepted, :responseNeeded, :commandHolder, :threaded | ||
− | # | + | |
+ | #Constants: Set up any constants here... | ||
STX=0x02.chr | STX=0x02.chr | ||
ETX=0x03.chr | ETX=0x03.chr | ||
− | |||
− | |||
− | |||
− | |||
− | |||
def initialize() | def initialize() | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
@responseAccepted = false | @responseAccepted = false | ||
− | @ | + | @responseNeeded = false |
− | + | ||
@commandHolder = nil | @commandHolder = nil | ||
− | |||
@threaded = true | @threaded = true | ||
+ | |||
+ | #set up any variable initialization here. | ||
+ | |||
end | end | ||
+ | |||
def dceCommandIn(cmd) | def dceCommandIn(cmd) | ||
− | + | ||
+ | #This is fired when a new DCE command is created. | ||
+ | #cmd is a Command object ie Command.new | ||
+ | #eg: | ||
@dcehomeunit = $devices[cmd.devidto_].devdata[12][0..1] | @dcehomeunit = $devices[cmd.devidto_].devdata[12][0..1] | ||
@dcehome = HomeCodes[$devices[cmd.devidto_].devdata[12][0].chr].to_s | @dcehome = HomeCodes[$devices[cmd.devidto_].devdata[12][0].chr].to_s | ||
Line 177: | Line 139: | ||
end | end | ||
− | def dceResponseIn(cmd) | + | |
− | + | def dceResponseIn(cmd) | |
− | + | # Returns TRUE if response is accepted. | |
− | return true | + | #This is a RESPONSE from DCE. Normally, we do not get DCE responses |
+ | #as the DCE commands we send do not need a Reply. | ||
+ | #but if you need it, here is where you get it. | ||
+ | |||
+ | return true #or false | ||
end | end | ||
+ | |||
def gsdCommandIn(value) | def gsdCommandIn(value) | ||
− | + | ||
− | + | ||
@gsdusercode = value[2] | @gsdusercode = value[2] | ||
@gsdhomeunit = ("%X" %value[3]) | @gsdhomeunit = ("%X" %value[3]) | ||
Line 198: | Line 164: | ||
rxtxSwitchRegister(value[7]) #set switches if they exist | rxtxSwitchRegister(value[7]) #set switches if they exist | ||
end | end | ||
+ | |||
end | end | ||
− | def gsdResponseIn(value) | + | def gsdResponseIn(value) |
+ | #returns TRUE if response is accepted. | ||
#no need to store response.. just compare. | #no need to store response.. just compare. | ||
− | |||
@result = true | @result = true | ||
− | # | + | #value is a string from GSD. |
− | + | #validate if you accept this response here.... | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
return @result | return @result | ||
end | end | ||
− | def dceout | + | def dceout |
+ | # Returns the GSD values as a DCE command. | ||
@myfrom = gsdhomeunit | @myfrom = gsdhomeunit | ||
if @myfrom == 0 | if @myfrom == 0 | ||
Line 240: | Line 182: | ||
else | else | ||
@mycommandout = gsdcommand | @mycommandout = gsdcommand | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
@cmdout = Command.new(@myfrom, -1001, 1, 2, @mycommandout) | @cmdout = Command.new(@myfrom, -1001, 1, 2, @mycommandout) | ||
@gsdparams.each_pair{|k,v| @cmdout.params_[k]=v} | @gsdparams.each_pair{|k,v| @cmdout.params_[k]=v} | ||
− | |||
− | |||
return @cmdout | return @cmdout | ||
end | end | ||
end | end | ||
− | def gsdout | + | def gsdout |
− | # | + | # Returns the DCE values as a gsd string |
− | + | @threaded = false #PLCBUS does not support threading | |
− | + | #compile the output string from the values set in dceCommandIn(cmd) | |
+ | |||
@gsdout = @usercode.chr | @gsdout = @usercode.chr | ||
@gsdout += dcehomeunit + dcecommand(@dcecmdid) + @data1.chr + @data2.chr | @gsdout += dcehomeunit + dcecommand(@dcecmdid) + @data1.chr + @data2.chr | ||
@gsdout = @gsdout.length.chr + @gsdout | @gsdout = @gsdout.length.chr + @gsdout | ||
@gsdout = STX + @gsdout + ETX | @gsdout = STX + @gsdout + ETX | ||
− | |||
return @gsdout | return @gsdout | ||
end | end | ||
+ | |||
def checkResponse(cmd) #old?? fired when a response was accepted. | def checkResponse(cmd) #old?? fired when a response was accepted. | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
@responseAccepted = true | @responseAccepted = true | ||
end | end | ||
− | #Support Routines for | + | |
+ | |||
+ | |||
+ | ### Below you can add any kind of support routines you may need for your protocol. | ||
+ | #I've deleted most of the code for brevity of a template. | ||
+ | |||
+ | #Support Routines for PLCBUS | ||
def dcecommand(value) #DCE value is DCE Command. | def dcecommand(value) #DCE value is DCE Command. | ||
#user code is in devdata[59] Configuration | #user code is in devdata[59] Configuration | ||
#devdata[250] 3phase (boolean) | #devdata[250] 3phase (boolean) | ||
− | |||
− | |||
case value | case value | ||
when 192 #ON | when 192 #ON | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
when 193 #OFF | when 193 #OFF | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
when 184 # SETLEVEL | when 184 # SETLEVEL | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
− | + | ||
− | + | ||
return @command.chr | return @command.chr | ||
end | end | ||
− | def gsdcommand #returns DCE EVENT!! and compiles params | + | def gsdcommand |
+ | #returns DCE EVENT!! and compiles params | ||
− | |||
− | |||
case CommandFunctions[@gsdcommand] | case CommandFunctions[@gsdcommand] | ||
when 'ALL UNIT OFF' | when 'ALL UNIT OFF' | ||
Line 443: | Line 258: | ||
@gsdparams[10] = '0' | @gsdparams[10] = '0' | ||
return 48 | return 48 | ||
− | |||
− | |||
when 'PRESETDIM' | when 'PRESETDIM' | ||
@gsdparams[10] = @gsddata1 | @gsdparams[10] = @gsddata1 | ||
return 48 | return 48 | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
else | else | ||
− | |||
return 0 | return 0 | ||
end | end | ||
+ | return 0 | ||
+ | end | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
def rxtxSwitchRegister(value) | def rxtxSwitchRegister(value) | ||
#log('setting RX_TX_SWITCH') | #log('setting RX_TX_SWITCH') | ||
Line 525: | Line 311: | ||
end | end | ||
+ | |||
#Generic Support Routines | #Generic Support Routines | ||
def log(line) | def log(line) |
Latest revision as of 08:33, 3 May 2010
Version | Status | Date Updated | Updated By |
---|---|---|---|
710 | Unknown | N/A | N/A |
810 | Unknown | N/A | N/A |
1004 | Unknown | N/A | N/A |
1204 | Unknown | N/A | N/A |
1404 | Unknown | N/A | N/A |
Usage Information |
Contents |
Here is my ThreadedRuby code. I'm trying to add notes and a bit of an explanation as to what each piece of code does. If you just want to get going, create a class Object for your protocol as per below.
ProtocolObject Class
This is a generic replaceable class. This object needs the following methods:
Methods
Initialize()
- What it does:
- any Object initialization you may need.
- When is this called:
- Upon Object creation.
- What you will get:
- nothing.
- What you will return:
- nothing.
dceCommandIn(cmd)
- What is does:
- sends you a command object to allow you to create gsdOut().
- What you will get:
- cmd (Command Object)
- What you need to return:
- nothing (ignored)
- When you will get this:
- executed when a new DCE command is sent to you.
dceResponseIn(cmd)
- What it does:
- Sends you a DCE object to compare with the command.
- What you will get:
- cmd (Command Object)
- What you need to return:
- TRUE if you accept this response.
- FALSE if you do NOT accept this response.
- When you will get this:
- executed when a new DCE response is ready.
gsdCommandIn(value)
- What it does:
- sends you a String to allow you to create a dceOut().
- What you will get:
- value (String Object)
- What you need to return:
- nothing (ignored)
- When you will get this:
- executed when a new GSD command is sent to you.
gsdResponseIn(value)
- What it does:
- Sends you a GSD Response to compare with the command.
- What you will get:
- cmd (Command Object)
- What you need to return:
- TRUE if you accept this response.
- FALSE if you do NOT accept this response.
- When you will get this:
- executed when a new GSD response is ready.
dceout()
- What it does:
- Creates a Command Object to send to DCE.
- What you will get:
- nothing.
- What you need to return:
- a Command Object representing the previous gsdCommandIn.
- When is this called:
- After a gsdCommandIn has been sent.
gsdout()
- What it does:
- creates a String Object to send to GSD.
- What you will get:
- nothing.
- What you will return:
- a String Object representing the previous dceCommandIn.
- When is this called:
- After a dceCommandIn has been sent.
Properties:
responseAccepted
- What it does:
- signals that the current response is accepted as valid.
- When you should set this:
- Set this to TRUE if you accept the response as a valid response for this command.
- Set this to FALSE if you do NOT accept this response
responseNeeded
- What it does:
- signals when you need a response.
commandHolder
- What it does:
- If you need to create a new command, this is the holder for it.
threaded
- What it does:
- determines if this command is threadable
- When you should set this:
- This should be set to TRUE to enable threading.
- if this is set to FALSE, all threading will be suspended UNTIL this command is complete. (or times out)
ProtocolObject Class Template
class PLCBUS attr_reader :responseAccepted, :responseNeeded, :commandHolder, :threaded #Constants: Set up any constants here... STX=0x02.chr ETX=0x03.chr def initialize() @responseAccepted = false @responseNeeded = false @commandHolder = nil @threaded = true #set up any variable initialization here. end def dceCommandIn(cmd) #This is fired when a new DCE command is created. #cmd is a Command object ie Command.new #eg: @dcehomeunit = $devices[cmd.devidto_].devdata[12][0..1] @dcehome = HomeCodes[$devices[cmd.devidto_].devdata[12][0].chr].to_s @dceunit = UnitCodes[$devices[cmd.devidto_].devdata[12][1].chr].to_s @dcefrom = cmd.devidfrom_ @dceto = cmd.devidto_ @dcepriority = cmd.priority_ @dcecmdtype = cmd.type_ @dcecmdid = cmd.id_ @dceparams = cmd.params_ end def dceResponseIn(cmd) # Returns TRUE if response is accepted. #This is a RESPONSE from DCE. Normally, we do not get DCE responses #as the DCE commands we send do not need a Reply. #but if you need it, here is where you get it. return true #or false end def gsdCommandIn(value) @gsdusercode = value[2] @gsdhomeunit = ("%X" %value[3]) @gsdhome = @gsdhomeunit[0].chr @gsdunit = @gsdhomeunit[1].chr @gsdcommand = value[4] @gsdcmdAckPulse = true if (value[4] & 0x20) == 0x20 @gsdcmdReprq = true if (value[4] & 0x40) == 0x40 @gsdcmdLink = true if (value[4] & 0x80) == 0x80 @gsddata1 = value[5] @gsddata2 = value[6] if value[1] == 6 rxtxSwitchRegister(value[7]) #set switches if they exist end end def gsdResponseIn(value) #returns TRUE if response is accepted. #no need to store response.. just compare. @result = true #value is a string from GSD. #validate if you accept this response here.... return @result end def dceout # Returns the GSD values as a DCE command. @myfrom = gsdhomeunit if @myfrom == 0 log('I DONT KNOW THIS DEVICE ID') else @mycommandout = gsdcommand @cmdout = Command.new(@myfrom, -1001, 1, 2, @mycommandout) @gsdparams.each_pair{|k,v| @cmdout.params_[k]=v} return @cmdout end end def gsdout # Returns the DCE values as a gsd string @threaded = false #PLCBUS does not support threading #compile the output string from the values set in dceCommandIn(cmd) @gsdout = @usercode.chr @gsdout += dcehomeunit + dcecommand(@dcecmdid) + @data1.chr + @data2.chr @gsdout = @gsdout.length.chr + @gsdout @gsdout = STX + @gsdout + ETX return @gsdout end def checkResponse(cmd) #old?? fired when a response was accepted. @responseAccepted = true end ### Below you can add any kind of support routines you may need for your protocol. #I've deleted most of the code for brevity of a template. #Support Routines for PLCBUS def dcecommand(value) #DCE value is DCE Command. #user code is in devdata[59] Configuration #devdata[250] 3phase (boolean) case value when 192 #ON when 193 #OFF when 184 # SETLEVEL end return @command.chr end def gsdcommand #returns DCE EVENT!! and compiles params case CommandFunctions[@gsdcommand] when 'ALL UNIT OFF' @gsdparams[10] = '0' return 48 when 'ALL LTS ON' @gsdparams[10] = '1' return 48 when 'ON' @gsdparams[10] = '1' return 48 when 'OFF' @gsdparams[10] = '0' return 48 when 'DIM' @gsdparams[10] = @gsddata1 # set Brightness return 48 when 'BRIGHT' @gsdparams[10] = @gsddata1 # set Brightness return 48 when 'ALL LIGHT OFF' @gsdparams[10] = '0' return 48 when 'ALL USER LTS ON' @gsdparams[10] = '1' return 48 when 'ALL USER UNIT OFF' @gsdparams[10] = '0' return 48 when 'ALL USER LIGHT OFF' @gsdparams[10] = '0' return 48 when 'PRESETDIM' @gsdparams[10] = @gsddata1 return 48 else return 0 end return 0 end def rxtxSwitchRegister(value) #log('setting RX_TX_SWITCH') if (value & 0x40) == 0x40 #log('r_id_sw is set') @r_id_sw = true else #log('r_id_sw is reset') @r_id_sw = false end if (value & 0x20) == 0x20 #log('r_ack_sw is set') @r_ack_sw = true @responseNeeded = false else #log('ResponseNeeded set to TRUE') @responseNeeded = true #log('r_ack_sw is reset') @r_ack_sw = false end if (value & 0x10) == 0x10 #log('r_itself is set') @r_itself = true log('I heard myself Transmit this command on the PLCBUS.') else #log('r_itself is reset') @r_itself = false log('This Command is transmitted from an OUTSIDE SOURCE!') end if (value & 0x8) == 0x8 #log('r_risc is set') @r_risc = true else #log('r_risc is reset') @r_risc = false end if (value & 0x4) == 0x4 #log('r_sw is set') @r_sw = true else #log('r_sw is reset') @r_sw = false end end #Generic Support Routines def log(line) @log = File.open("/var/log/pluto/" + $me.deviceid.to_s + "_Generic_Serial_Device.log", "a") @log.putc '('[0] @log.putc 'P'[0] @log.putc 'L'[0] @log.putc 'C'[0] @log.putc ')'[0] @l = line.to_s @l.each_byte{|ch| @log.putc ch if ch == 60 @log.putc 32 end } @log.puts @log.close @log = nil end def debug(label, text) work = label + ":" for c in 1..text.length work += padhex("%X" %text[c-1]) + ' ' end log(BLUE + work + "Length:" + text.length.to_s + GREY) end def padhex(hex) if hex.length==1 hex = "0" + hex end return hex end end