ThreadedRubyProtocolObject
From LinuxMCE
Contents
PLCBUS OBJECT
- This is a generic replaceable object
- 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.
class PLCBUS attr_reader :responseAccepted, :responseNeeded, :commandHolder, :threaded #Conatants: STX=0x02.chr ETX=0x03.chr HomeCodes = {'A'=>0b0000,'B'=>0b0001,'C'=>0b0010,'D'=>0b0011,'E'=>0b0100,'F'=>0b0101,'G'=>0b0110,'H'=>0b0111,'I'=>0b1000,'J'=>0b1001,'K'=>0b1010,'L'=>0b1011,'M'=>0b1100,'N'=>0b1101,'O'=>0b1110,'P'=>0b1111} UnitCodes = {'1'=>0b0000,'2'=>0b0001,'3'=>0b0010,'4'=>0b0011,'5'=>0b0100,'6'=>0b0101,'7'=>0b0110,'8'=>0b0111,'9'=>0b1000,'10'=>0b1001,'11'=>0b1010,'12'=>0b1011,'13'=>0b1100,'14'=>0b1101,'15'=>0b1110,'16'=>0b1111} CommandFunctions = {0x00=>'ALL UNIT OFF',0x01=>'ALL LTS ON',0x02=>'ON',0x03=>'OFF',0x04=>'DIM',0x05=>'BRIGHT',0x06=>'ALL LIGHT OFF',0x07=>'ALL USER LTS ON',0x08=>'ALL USER UNIT OFF',0x09=>'ALL USER LIGHT OFF',0x0A=>'BLINK',0x0B=>'FADE STOP',0x0C=>'PRESETDIM',0x0D=>'STATUS ON',0x0E=>'STATUS OFF',0x0F=>'STATUS REQ',0x10=>'(R)MASTER ADDRS SETUP',0x11=>'(T)MASTER ADDRS SETUP', 0x12=>'SCENES ADDRS SETUP',0x13=>'SCENES ADDRS ERASE',0x14=>'ALL SCENES ADDRS ERASE',0x15=>'FOR FUTURE',0x16=>'FOR FUTURE',0x17=>'FOR FUTURE',0x18=>'GET SIGNAL STRENGTH',0x19=>'GET NOISE STRENGTH',0x1A=>'REPORT SIGNAL STRENGTH',0x1B=>'REPORT NOISE STRENGTH',0x1C=>'GET ALL ID PULSE',0x1D=>'GET ONLY ON ID PULSE',0x1E=>'REPORT ALL ID PULSE',0x1F=>'REPORT ONLY ON PULSE'} def initialize() # declare gsd variables @home = 0 #these two varianles determine the TO or FROM address @unit = 0 #these two variables determine the TO or FROM address @command = 0 @usercode = $me.devdata[59].to_i #@cmdReprq = $me.devdata[260] #3Phase on Dan's system @cmdReprq = $me.devdata[249] #3Phase on Hari's system @data1 = 0 @data2 = 0 @cmdAckPulse = false @cmdLink = false #declare DCE variables @dceto = 0 @dcefrom = 0 @dcepriority = 0 @dcecmdtype = 0 @dcecmdid = 0 @dceparams = {} @responseNeeded = false @responseAccepted = false @gsdparams = {} #@gsdparams[120] = '1' # hack to force command is useless... @commandHolder = nil #log('Leaving Initialize') @threaded = true end def dceCommandIn(cmd) log('dceCommandIn Entered:') @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. log('dceResponseIn Entered:') log(cmd.inspect) return true #ignored in PLCBUS end def gsdCommandIn(value) log('gsdCommandIn Entered:') debug('Value:', 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. #negative logic here @result = true #log('gsdResponseIn Entered:') #debug('Value:', value) if @usercode == value[2] #log('Usercode Check!') else log('Usercode compare failed') @result = false end if dcehomeunit[0] == value[3] #log('Home and Unit CHECK!') else log('Home and Unit compare failed') @result = false end if dcecommand(@dcecmdid)[0] == value[4] #log('PLCBus Command CHECK!') else log('PLCBus Command compare failed') @result = false end if value[1] == 6 #log('Setting rxtxRegister') rxtxSwitchRegister(value[7]) else log('no rxtxRegister') @result = false end #log('gsdResponseIn returning TRUE') if @result == true #log('gsdResponseIn returning FALSE') if @result == false 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 log('IN PLCBUS:DCEOUT') log(' From: ' + @myfrom.to_s) log(' To: -1001') log(' Priority: 1') log(' CmdType: 2') log(' CmdId: ' + @mycommandout.to_s) log('Devdata Below:') @gsdparams.each_pair{|k,v| log(' devdata_[' + k.to_s + '] = ' + v) } @cmdout = Command.new(@myfrom, -1001, 1, 2, @mycommandout) @gsdparams.each_pair{|k,v| @cmdout.params_[k]=v} # @responseNeeded = false # @responseAccepted = true return @cmdout end end def gsdout # Returns the DCE values as a gsd string #log('IN PLCBUS:GSDOUT') log('SETTING THREADING to FALSE in PLCBUS:GSDOUT:') @threaded = false @gsdout = @usercode.chr @gsdout += dcehomeunit + dcecommand(@dcecmdid) + @data1.chr + @data2.chr @gsdout = @gsdout.length.chr + @gsdout @gsdout = STX + @gsdout + ETX #debug('Data Out', @gsdout) return @gsdout end def checkResponse(cmd) #old?? fired when a response was accepted. log('WARNING: CheckResponse was CALLED') # #this routine needs to set ONE flag: # #responseNeeded (true/false) if we need more data # if cmd.class.to_s == 'String' # #we are checking a GSD command. # # end # if cmd.class == Command # #we are checking a DCE command. # if @r_ack_sw == true # #here is a good place to check the data1 and data2 values # #to make sure the proper device responded. # # # #PLCBUS command complete # log('Received Ack from PLCBUS device.') # @responseNeeded = false # # attempt to set device info here. # case @dcecmdid # when 192 # ON # $devices[@dceto].onoff = "ON" # if $devices[@dceto].level != 100 # $devices[@dceto].level = 100 # log('HAVE TO SEND A SETLEVEL=100') # end # when 193 # OFF # $devices[@dceto].onoff = "OFF" # if $devices[@dceto].level != 0 # $devices[@dceto].level = 0 # log('HAVE TO SEND A SETLEVEL = 0') # log('**************************') # log('**************************') # log('**************************') # log('**************************') # @commandHolder = RubyCommand.new() # #pack a new DCE command with the Event.. # @mycmd = Command.new(@dceto, @dceto, 1, 1, 184) # @mycmd.params_[76] = '0' # @commandHolder.packCommand(@mycmd) # # end # when 184 # SetLevel # if @dceparams[76].to_i == 0 # #dimming to OFF # if $devices[@dceto].onoff == 'ON' # log('HAVE TO SEND AN OFF to DCE') # log('**************************') # log('**************************') # log('**************************') # log('**************************') # @commandHolder = RubyCommand.new() # #pack a new DCE command with the Event.. # @mycmd = Command.new(@dceto, -1001, 1, 2, 40) # @mycmd.params_[10] = '0' # @commandHolder.packCommand(@mycmd) # # # # #@commandHolder = Command.new(@dcefrom, -1001, 1, 2, 40) # #@commandHolder.params_[10] = '0' # $devices[@dceto].onoff = 'OFF' # # end # # else # #dimming to ON # if $devices[@dceto].onoff == 'OFF' # log('HAVE TO SEND AN ON to DCE') # log('**************************') # log('**************************') # log('**************************') # log('**************************') # @commandHolder = RubyCommand.new() # @mycmd = Command.new(@dceto, -1001, 1, 2, 40) # @mycmd.params_[10] = '1' # @commandHolder.packCommand(@mycmd) # #@commandHolder = Command.new(@dcefrom, -1001, 1, 2, 40) # #@commandHolder.params_[10] = '1' # # $devices[@dceto].onoff = 'ON' # end # end # $devices[@dceto].level = @dceparams[76].to_i # end # log('Device:' + @dceto.to_s) # log('on/off:' + $devices[@dceto].onoff) # log(' level:' + $devices[@dceto].level.to_s) # end # if @r_itself == true # #heard myself send the response. # log('I heard myself send the command properly.') # @responseNeeded = true # end # # end @responseAccepted = true end #Support Routines for PLCBUX def dcecommand(value) #DCE value is DCE Command. #user code is in devdata[59] Configuration #devdata[250] 3phase (boolean) @work = 0 #log('DCE Command is' + value.to_s) case value when 192 #ON @cmdLink = false @cmdReprq = false @cmdAckPulse = true @data1 = 0 #Fade Rate @work = 0x80 if @cmdling == true @work += 0x40 if @cmdReprq == true @work += 0x20 if @cmdAckPulse == true @command =@work + CommandFunctions.index("ON") when 193 #OFF @cmdLink = false @cmdReprq = false @cmdAckPulse = true @data1 = 0 #Fade Rate @work = 0x80 if @cmdling == true @work += 0x40 if @cmdReprq == true @work += 0x20 if @cmdAckPulse == true @command =@work + CommandFunctions.index("OFF") when 184 # SETLEVEL @cmdLink = false @cmdReprq = false @cmdAckPulse = true @data1 = @dceparams[76].to_i #dim level @data2 = 2 #Fade Rate @work = 0x80 if @cmdling == true @work += 0x40 if @cmdReprq == true @work += 0x20 if @cmdAckPulse == true @data2 = 2#Fade Rate @command =@work + CommandFunctions.index("PRESETDIM") end #how convert it into a integer - currently it a HEX string. #log('PLC Command is:' + @command.to_s + 'DECIMAL') return @command.chr end def gsdcommand #returns DCE EVENT!! and compiles params #log('IN DCECommand') 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 'BLINK' when 'FADE STOP' when 'PRESETDIM' @gsdparams[10] = @gsddata1 return 48 when 'STATUS ON' when 'STATUS OFF' when 'STATUS REQ' when '(R)MASTER ADDRS SETUP' when '(T)MASTER ADDRS SETUP' when 'SCENES ADDRS SETUP' when 'SCENES ADDRS ERASE' when 'ALL SCENES ADDRS ERASE' when 'FOR FUTURE' when 'GET SIGNAL STRENGTH' when 'GET NOISE STRENGTH' when 'REPORT SIGNAL STRENGTH' when 'REPORT NOISE STRENGTH' when 'GET ALL ID PULSE' when 'GET ONLY ON ID PULSE' when 'REPORT ALL ID PULSE' when 'REPORT ONLY ON PULSE' else log('UNKNOWN COMMAND RESPONSE in PLCBUS OBJECT') return 0 end end def dcehomeunit() # returns GSD homeunit byte from DCE homeunit @work = @dcehome + @dceunit return (@work.hex.chr) end def gsdhomeunit() #returns DCE Child ID from gsd homeunit #@gsdhomeunit holds the data @work = HomeCodes.index(@gsdhomeunit[0].chr.to_i) @work += UnitCodes.index(@gsdhomeunit[1].chr.to_i) return $devices.find(@work) 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