ThreadedRubyPrivateFunctions
Appearance
| 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 | |||
#######################################
# Threaded RubyCommand
# Written by Dan Damron
#######################################
class Device #Child Device Holder
attr_accessor :devdata, :deviceid, :template, :parent, :onoff, :level
def initialize()
@onoff = 'OFF' #State
@level = 0 #Level
@devdata = Hash.new #to hold devdata
@deviceid = @template = @parent = 0
end
end
class Devices #holder for Child Devices
def initialize
@devices = Hash.new
end
def append(device) #Device Object
@devices[device.deviceid] = device
end
def find(value) #this method finds the devdata[12] and returns the child ID
@result = 0
log('Looking up:' + value.to_s)
@devices.each_key{|d|
if @devices[d].devdata[12] == value
@result = @devices[d].deviceid
end}
log('In Devices:find() result:' + @result.to_s)
return @result
end
def [](value) #return the device.
return @devices[value]
end
def log(line) #logger
@log = File.open("/var/log/pluto/" + $me.deviceid.to_s + "_Generic_Serial_Device.log", "a")
@log.putc '('[0]
@log.putc 'D'[0]
@log.putc 'E'[0]
@log.putc 'V'[0]
@log.putc 'I'[0]
@log.putc 'C'[0]
@log.putc 'E'[0]
@log.putc 'S'[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
end
RED = 0x1b.chr + '[31m'
GREEN = 0x1b.chr + '[32m'
YELLOW = 0x1b.chr + '[33m'
BLUE = 0x1b.chr + '[34m'
PURPLE = 0x1b.chr + '[35m'
AQUA = 0x1b.chr + '[36m'
GREY = 0x1b.chr + '[37m'
REDBACK = 0x1b.chr + '[41m'
GREENBACK = 0x1b.chr + '[42m'
YELLOWBACK = 0x1b.chr + '[43m'
BLUEBACK = 0x1b.chr + '[44m'
PURPLEBACK = 0x1b.chr + '[45m'
AQUABACK = 0x1b.chr + '[46m'
GREYBACK = 0x1b.chr + '[47m'
BLACKBACK = 0x1b.chr + '[48m'
DCEtoGSD = 10
GSDtoDCE = 20
NotReady = 1
SendReady = 2
ReceiveReady = 3
Complete = 4
Failed = 5
##############################
# Methods for $commands[] queue
##############################
def dataIn(value)
#log('DataIn Entered:')
$commands.each{|cmd|
if cmd.state == ReceiveReady #only ReceiveReady cmds.
if cmd.dataIn(value) == true #this data was accepted if TRUE
@newcmd = cmd.commandHolder #check for new command
if @newcmd != nil
log(YELLOW + 'This command is spawning!!!' + GREY)
$commands.push @newcmd #if so, push it onto the queue
end
if cmd.state == SendReady
log('DataIn: Ready to Send.')
dataOutSingleCmd(cmd)
end
if cmd.state == Complete
if cmd.threaded == false
log(YELLOW + 'Threading RESUMED' + GREY)
$threadingSuspended = false #allow other commands to now transmit.
end
log(PURPLE + 'DataIn:Command Complete!' + GREY)
$commands.delete(cmd) #remove command if complete
end
if cmd.state == Failed
log(RED + 'DataIn:This Command FAILED:' + GREY)
log(YELLOW + cmd.inspect + GREY) #inspect the failed command
log('Command Deleted.')
$commands.delete(cmd) #remove command if failed
end
return
end
end
}
#if we hit here, the data has been rejected by all current commands.
log('dataIn: New Command:')
c = RubyCommand.new
c.dataIn(value) # sets up the command.
dataOutSingleCmd(c) if c.state == SendReady #check to see if it's ready to send
$commands.push c.clone #push a copy of it onto the queue.
c = nil
#dataOut() #safer to call it in turn.
#log('DataIn Exited:')
end
def dataOut() #replaces send()
log('dataOut Entered:')
#Send out all the commands...
$commands.each{|cmd|
dataOutSingleCmd(cmd)
if cmd.state == Complete
log(PURPLE + 'DataOut:Command Complete!' + GREY)
$commands.delete(cmd)
end
if cmd.state == Failed
log(RED + 'DataOut:This Command FAILED:' + GREY)
log(YELLOW + cmd.inspect + GREY) #inspect the failed command
log('Command Deleted.')
$commands.delete(cmd) #remove command if failed
end
}
#log('dataOut Exited:')
end
def dataOutSingleCmd(cmd)
log('dataOutSingleCmd Entered:')
if cmd.state == SendReady #send out only if ready.
@out = cmd.dataOut
log('got past cmd.dataOut')
log('@out is type:' + @out.class.to_s)
case @out.class.to_s
when 'String'
log('Threading Suspended = FALSE') if $threadingSuspended == false
log('Threading Suspended = TRUE') if $threadingSuspended == true
if $threadingSuspended == false
conn_.Reconnect()
log('Sending to GSD...')
debugout(@out)
conn_.Send(@out)
debugout(@out)
conn_.Send(@out)
sleep $delayBetweenTransmits
if cmd.threaded == false
log(YELLOW + 'THREADING SUSPENDED!!!' + GREY)
$threadingSuspended == true
end
else
#cannot send data out while waiting for a NON threaded response.
end
when 'Command'
log('Sending to DCE...')
SendCommand(@out)
when 'NilClass' #safety first!
log('This command not ready to send.')
end
end
#log('dataOutSingleCmd Exited:')
end
def log(line)
$log = File.open("/var/log/pluto/" + device_.devid_.to_s + "_Generic_Serial_Device.log", "a")
$log.putc '('[0]
$log.putc '*'[0]
$log.putc '*'[0]
$log.putc '*'[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
end
def debugout(text)
work = 'OUT:'
for c in 1..text.length
work += padhex("%X" %text[c-1]) + ' '
end
log(GREEN + work + "Length:" + text.length.to_s + GREY)
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 debugin(text)
work = 'IN:'
for c in 1..text.length
work += padhex("%X" %text[c-1]) + ' '
end
log(RED + work + "Length:" + text.length.to_s + GREY)
end
def padhex(hex)
if hex.length==1
hex = "0" + hex
end
return hex
end
##############################
#Initialization Routine
##############################
def initDevices() #Loads Child Devices into Devices
$threadingSuspended = false
$timeout = 1 #Global timeout
$retryAttempts = 10 #Global Retry Attempts
$delayBetweenTransmits = 0.4
log(YELLOW + 'Loading Child Devices...' + GREY)
$devices = Devices.new
device_.childdevices_.keys.each{|c| #Populate children
d = Device.new() #create a new device
d.deviceid = c
d.template = device_.childdevices_[c].devtemplid_
d.parent = device_.childdevices_[c].parent_
d.devdata = device_.childdevices_[c].devdata_
$devices.append(d) #add d to $devices
log('Device:' + d.deviceid.to_s)}
$me = Device.new() #get MY info
$me.deviceid = device_.devid_
$me.parent = device_.parent_
$me.devdata = []
$me.devdata = device_.devdata_
$me.onoff = "ON"
$me.level = 100
myusercode = "My Usercode: %X" %$me.devdata[59].to_i #show in hex form
log(myusercode)
log(YELLOW + 'Done.' + GREY) #devdata[59] = usercode
log(YELLOW + 'Setting up Command Queue' + GREY) #dedata[249] = 3phase (boolean)
$commands = Array.new
log(YELLOW + 'Done.' + GREY)
#TODO: read all the PLC devices to get initial status.
#TODO: and report status back to lmce.
end
def errorHandler # threaded errorhandler
#Error handling is now handled at the RubyCommand Level.
if $commands.nitems != 0 #log out the commands waiting to be processed, if any.
@work = YELLOW + 'Command Queue:' + $commands.nitems.to_s
$commands.each{|cm| @work += ', State:'
@work += 'NEW' if cm.state == 1
@work += 'SendReady' if cm.state == 2
@work += 'ReceiveReady' if cm.state == 3
@work += 'Complete' if cm.state == 4
@work += 'Failed' if cm.state == 5
@work += GREY + ' '}
log(@work)
end
$commands.each{|cmd|
case cmd.state #possible to clear out commands here..
when Complete
$commands.delete(cmd)
# when SendReady
# dataOutSingleCmd(cmd)
when ReceiveReady
if cmd.timeout == true #call the timeout and get back error.
log(RED + 'This Command Timed Out!:' + GREY)
log(RED + cmd.inspect + GREY)
$commands.delete(cmd)
else
dataOutSingleCmd(cmd)
end
end
}
end
##############################
#Class RubyCommand
##############################
class RubyCommand
# This class is a container for a protocolObject Instance.
# This class is responsible for the DIRECTION of communication of a specific command.
#
# Error Handling is also handled in the timeout method.
#
# If this command creates a NEW command, this object will allow only ONE creation.
# This class also controls the state information.
# Constants:
DCEtoGSD = 10
GSDtoDCE = 20
#Object States:
NEW = 1
SendReady = 2
ReceiveReady = 3
Complete = 4
Failed = 5
def initialize
#log('Initialize Entered:')
@protocolObject = PLCBUS.new()
@direction = nil
@timeoutCounter = 0
@timeoutRetries = 0
@state = NEW
@serialNumber = rand(10000).to_s #for DCE object
@newCommandSent = false
#log('Initialize Exited:')
end
def dataIn(cmd) #Returns TRUE if accepted, FALSE if not.
#log('dataIn Entered:')
case @state
when NEW
log('dataIn: creating NEW command')
@savedCommand = cmd
case cmd.class.to_s
when 'String' # new Command from GSD
@direction = GSDtoDCE
@protocolObject.gsdCommandIn(cmd)
@state = SendReady #This command is ready to send.
when 'Command' # new Command from DCE
@direction = DCEtoGSD
@protocolObject.dceCommandIn(cmd)
@state = SendReady #This command is ready to send.
else
log('FAILURE IN dataIn - cmd.class not recognized!')
log('Direction: nil')
log('class is:' + cmd.class.to_s)
@state = Failed #fail this command. (remove it)
end
@result = true #returns datain Accepted.
when ReceiveReady #Possible Response
log('dataIn: Possible Response')
@result = false
@class = cmd.class.to_s #get this only once.
case @direction
when DCEtoGSD
case @class
when 'String' # from GSD
#log('dataIn: class is STRING')
#pass the data to the protocol Object and check for accepted.
#log('dataIn: executing gsdResponseIn')
if @protocolObject.gsdResponseIn(cmd) == true
log('response Accepted.')
@result = true
if @protocolObject.responseNeeded == true
log('Command not yet complete.')
@state = ReceiveReady # ProtocolObject needs another response.
else
log('Command Complete.')
@state = Complete # ProtocolObject is complete.
end
else
log('response Rejected!')
end
when 'Command' # from DCE
#log('dataIn: class is COMMAND')
@result = false # cmd is NOT for me.
else
log('FAILURE IN dataIn - cmd.class not recognised!')
log('Direction: DCEtoGSD')
log('class is:' + @class.to_s)
@result = false
end
when GSDtoDCE
case @class
when 'String' # from GSD
@result = false # not for me.
when 'Command' # POSSIBLE when sending commands to self.
if cmd.params_[999] == @serialNumber
@result = true #I sent this command!
log('Caught Command Sent to Self!')
end
else
log('FAILURE IN dataIn - cmd.class not recognised!')
log('Direction: GSDtoDCE')
log('class is:' + @class.to_s)
end
end
#log('dataIn: returning TRUE (exited)') if @result == true
#log('dataIn: returning FALSE (exited)') if @result == false
return @result
end
end
def dataOut
log('dataOut Entered:')
if @state == SendReady
case @direction
when DCEtoGSD #Send GSD String
@work = @protocolObject.gsdout
log('dataOut: Setting @state to Receive Ready')
@state = ReceiveReady
when GSDtoDCE
@work = @protocolObject.dceout
if @work.class.to_s == 'Command' #check for valid Object (returns nil if not ready)
if @work.devidto_ == @work.devidfrom_ #check for command to self
log('Detected attempting to send to self')
@work.devdata_[999] = @serialNumber #this command is to self. Serialize it.
end
end
log('dataOut: Setting @state to Complete')
@state = Complete #DCE does not send responses. (yet)
else
log('Attempted DataOut with uninitialized Object')
@state = Failed
@work = nil
end
log('dataOut: Returning @work')
return @work
else
log('This command is not ready to send.')
end
log('DataOut Exited:')
end
def timeout #called ONLY when @state == ReceiveReady
@result = false #returns TRUE if command times out.
@timeoutCounter +=1 #ticker += 1
if @timeoutCounter == $timeout #global variable defined in init.
@timeoutCounter = 0 #reset ticker
@timeoutRetries += 1 #increment Retries..
if @timeoutRetries == $retryAttempts #global variable defined in init.
@state = Failed
@result = true
else
log('Attempt:' + (@timeoutRetries + 1).to_s)
if @state == ReceiveReady
@state = SendReady
end
end
end
log('Tick...')
return @result
end
def state
return @state
end
def direction()
return @direction
end
def responseNeeded()
return @protocolObject.responseNeeded
end
def commandHolder() #This is a holder of self. Used when inserting another command.
#allow only ONE command to be returned.
@holder = @protocolObject.commandHolder
if @holder != nil
if @newCommandSent == false
#we can send the command here.
@newCommandSent = true
return @holder
end
end
return nil
end
def threaded
return @protocolObject.threaded
end
# def packCommand(value) # this is used by protocolObject to pack a command.
# if value.class.to_s == 'Command'
# #packing a DCE Object..
# self.dcein(value)
# #override the direction...
# @direction = GSDtoDCE
# #flag the command ready to be sent.
# @sendReady = true
# end
# if value.class.to_s == 'String'
# #packing a GSD object
# self.gsdin(value)
# #override the direction...
# @direction = DCEtoGSD
# #flag the command ready to be sent.
# @sendReady = true
# end
# end
# def hasNewCommand()
# return @hasNewCommand
# end
def log(line) #support method.
@log = File.open("/var/log/pluto/" + $me.deviceid.to_s + "_Generic_Serial_Device.log", "a")
@log.putc '('[0]
@log.putc 'C'[0]
@log.putc 'o'[0]
@log.putc 'm'[0]
@log.putc 'm'[0]
@log.putc 'a'[0]
@log.putc 'n'[0]
@log.putc 'd'[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
end
#####################
### PLCBUS OBJECT ###
#####################
# This is a generic replaceable object
# This object needs the following 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:
#
# @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