|
|
| (19 intermediate revisions by 8 users not shown) |
| Line 1: |
Line 1: |
| [[Category: Hardware]]
| | {{versioninfo|810Status=Working|810UpdatedDate=1st May 2010|810UpdatedBy=BongoWongo}} |
| [[Category: Automation]] | | [[Category: Automation]] |
| | [[Category: Power Line Control]] |
| | [[Category: PLCBUS]] |
| {| align="right" | | {| align="right" |
| | __TOC__ | | | __TOC__ |
| Line 6: |
Line 8: |
| [[Image:Plcbus-logo.jpg|right]] | | [[Image:Plcbus-logo.jpg|right]] |
| = Status = | | = Status = |
| ddamron wrote a GSD for PLCBUS with ruby. Hari will try to get a c++ dce client running.
| | We've implemented a new C++ driver for 0810b2. More information here: http://forum.linuxmce.org/index.php?topic=11170.0 |
|
| |
|
| = About = | | = About = |
| Line 29: |
Line 31: |
| * http://x10-hk.com/store/manual/plcbus/plcbus-1141.pdf | | * http://x10-hk.com/store/manual/plcbus/plcbus-1141.pdf |
|
| |
|
| = GSD/Ruby Code =
| | |
| * [[ThreadedRuby]]
| |
| * http://wiki.linuxmce.org/index.php/PLCBUScmd776
| |
| * http://wiki.linuxmce.org/index.php/PLCBUScmd373
| |
| * http://wiki.linuxmce.org/index.php/PLCBUScmd351
| |
| * http://wiki.linuxmce.org/index.php/PLCBUScmd484
| |
| * http://wiki.linuxmce.org/index.php/PLCBUScmd760
| |
| * http://wiki.linuxmce.org/index.php/PLCBUScmd776
| |
| <pre>
| |
| RCODE:
| |
| 0:require 'Ruby_Generic_Serial_Device'
| |
| 1:class Command < Ruby_Generic_Serial_Device::RubyCommandWrapper
| |
| 2:end
| |
| 3:class Device_110 < Ruby_Generic_Serial_Device::RubySerialIOWrapper
| |
| 4:#### 350 ####################################################################
| |
| 5:def cmd_350(cmd=nil)
| |
| 6:@returnParamArray.clear
| |
| 7:### #350
| |
| 8:
| |
| 9:while(true)
| |
| 10: @buff = conn_.RecvDelimited(0x02.chr,100) #stx
| |
| 11: if(@buff.length() == 0)
| |
| 12: break
| |
| 13: end
| |
| 14: @buff2 = conn_.Recv(1,10) #Length of message
| |
| 15: @buff +=@buff2
| |
| 16: @length = @buff2[0]
| |
| 17: @buff += conn_.Recv(@length + 1, 100)
| |
| 18: debugin(@buff)
| |
| 19: dataIn(@buff)
| |
| 20:end
| |
| 21:
| |
| 22:
| |
| 23:# this routine needs to be handled better.
| |
| 24:# possibly with regular expressions.
| |
| 25:return @returnParamArray
| |
| 26:end
| |
| 27:#### 351 ####################################################################
| |
| 28:def cmd_351(cmd=nil)
| |
| 29:@returnParamArray.clear
| |
| 30:errorHandler()
| |
| 31:return @returnParamArray
| |
| 32:end
| |
| 33:#### 355 ####################################################################
| |
| 34:def cmd_355(cmd=nil)
| |
| 35:@returnParamArray.clear
| |
| 36:#########################
| |
| 37:# Written by Dan Damron #
| |
| 38:#########################
| |
| 39:
| |
| 40:initDevices()
| |
| 41:return @returnParamArray
| |
| 42:end
| |
| 43:#### PRIVATE METHODS ####################################################################
| |
| 44:#######################################
| |
| 45:# Threaded RubyCommand
| |
| 46:# Written by Dan Damron
| |
| 47:#######################################
| |
| 48:
| |
| 49:class Device #Child Device Holder
| |
| 50: attr_accessor :devdata, :deviceid, :template, :parent, :onoff, :level
| |
| 51: def initialize()
| |
| 52: @onoff = 'OFF' #State
| |
| 53: @level = 0 #Level
| |
| 54: @devdata = Hash.new #to hold devdata
| |
| 55: @deviceid = @template = @parent = 0
| |
| 56: end
| |
| 57:end
| |
| 58:
| |
| 59:class Devices #holder for Child Devices
| |
| 60: def initialize
| |
| 61: @devices = Hash.new
| |
| 62: end
| |
| 63: def append(device) #Device Object
| |
| 64: @devices[device.deviceid] = device
| |
| 65: end
| |
| 66: def find(value) #this method finds the devdata[12] and returns the child ID
| |
| 67: @result = 0
| |
| 68: log('Looking up:' + value.to_s)
| |
| 69: @devices.each_key{|d|
| |
| 70: if @devices[d].devdata[12] == value
| |
| 71: @result = @devices[d].deviceid
| |
| 72: end}
| |
| 73: log('In Devices:find() result:' + @result.to_s)
| |
| 74: return @result
| |
| 75: end
| |
| 76: def [](value) #return the device.
| |
| 77: return @devices[value]
| |
| 78: end
| |
| 79: def log(line) #logger
| |
| 80: @log = File.open("/var/log/pluto/" + $me.deviceid.to_s + "_Generic_Serial_Device.log", "a")
| |
| 81: @log.putc '('[0]
| |
| 82: @log.putc 'D'[0]
| |
| 83: @log.putc 'E'[0]
| |
| 84: @log.putc 'V'[0]
| |
| 85: @log.putc 'I'[0]
| |
| 86: @log.putc 'C'[0]
| |
| 87: @log.putc 'E'[0]
| |
| 88: @log.putc 'S'[0]
| |
| 89: @log.putc ')'[0]
| |
| 90: @l = line.to_s
| |
| 91: @l.each_byte{|ch|
| |
| 92: @log.putc ch
| |
| 93: if ch == 60
| |
| 94: @log.putc 32
| |
| 95: end
| |
| 96: }
| |
| 97: @log.puts
| |
| 98: @log.close
| |
| 99: @log = nil
| |
| 100: end
| |
| 101:end
| |
| 102:
| |
| 103:
| |
| 104:RED = 0x1b.chr + '[31m'
| |
| 105:GREEN = 0x1b.chr + '[32m'
| |
| 106:YELLOW = 0x1b.chr + '[33m'
| |
| 107:BLUE = 0x1b.chr + '[34m'
| |
| 108:PURPLE = 0x1b.chr + '[35m'
| |
| 109:AQUA = 0x1b.chr + '[36m'
| |
| 110:GREY = 0x1b.chr + '[37m'
| |
| 111:REDBACK = 0x1b.chr + '[41m'
| |
| 112:GREENBACK = 0x1b.chr + '[42m'
| |
| 113:YELLOWBACK = 0x1b.chr + '[43m'
| |
| 114:BLUEBACK = 0x1b.chr + '[44m'
| |
| 115:PURPLEBACK = 0x1b.chr + '[45m'
| |
| 116:AQUABACK = 0x1b.chr + '[46m'
| |
| 117:GREYBACK = 0x1b.chr + '[47m'
| |
| 118:BLACKBACK = 0x1b.chr + '[48m'
| |
| 119:DCEtoGSD = 10
| |
| 120:GSDtoDCE = 20
| |
| 121:NotReady = 1
| |
| 122:SendReady = 2
| |
| 123:ReceiveReady = 3
| |
| 124:Complete = 4
| |
| 125:Failed = 5
| |
| 126:
| |
| 127:
| |
| 128:
| |
| 129:
| |
| 130:##############################
| |
| 131:# Methods for $commands[] queue
| |
| 132:##############################
| |
| 133:def dataIn(value)
| |
| 134: #log('DataIn Entered:')
| |
| 135: $commands.each{|cmd|
| |
| 136: if cmd.state == ReceiveReady #only ReceiveReady cmds.
| |
| 137: if cmd.dataIn(value) == true #this data was accepted if TRUE
| |
| 138: @newcmd = cmd.commandHolder #check for new command
| |
| 139: if @newcmd != nil
| |
| 140: log(YELLOW + 'This command is spawning!!!' + GREY)
| |
| 141: $commands.push @newcmd #if so, push it onto the queue
| |
| 142: end
| |
| 143: if cmd.state == SendReady
| |
| 144: log('DataIn: Ready to Send.')
| |
| 145: dataOutSingleCmd(cmd)
| |
| 146: end
| |
| 147: if cmd.state == Complete
| |
| 148: if cmd.threaded == false
| |
| 149: log(YELLOW + 'Threading RESUMED' + GREY)
| |
| 150: $threadingSuspended = false #allow other commands to now transmit.
| |
| 151: end
| |
| 152: log(PURPLE + 'DataIn:Command Complete!' + GREY)
| |
| 153: $commands.delete(cmd) #remove command if complete
| |
| 154: end
| |
| 155: if cmd.state == Failed
| |
| 156: log(RED + 'DataIn:This Command FAILED:' + GREY)
| |
| 157: log(YELLOW + cmd.inspect + GREY) #inspect the failed command
| |
| 158: log('Command Deleted.')
| |
| 159: $commands.delete(cmd) #remove command if failed
| |
| 160: end
| |
| 161: return
| |
| 162: end
| |
| 163: end
| |
| 164: }
| |
| 165: #if we hit here, the data has been rejected by all current commands.
| |
| 166: log('dataIn: New Command:')
| |
| 167: c = RubyCommand.new
| |
| 168: c.dataIn(value) # sets up the command.
| |
| 169: dataOutSingleCmd(c) if c.state == SendReady #check to see if it's ready to send
| |
| 170: $commands.push c.clone #push a copy of it onto the queue.
| |
| 171: c = nil
| |
| 172:
| |
| 173: #dataOut() #safer to call it in turn.
| |
| 174: #log('DataIn Exited:')
| |
| 175:end
| |
| 176:def dataOut() #replaces send()
| |
| 177: log('dataOut Entered:')
| |
| 178: #Send out all the commands...
| |
| 179: $commands.each{|cmd|
| |
| 180: dataOutSingleCmd(cmd)
| |
| 181: if cmd.state == Complete
| |
| 182: log(PURPLE + 'DataOut:Command Complete!' + GREY)
| |
| 183: $commands.delete(cmd)
| |
| 184: end
| |
| 185: if cmd.state == Failed
| |
| 186: log(RED + 'DataOut:This Command FAILED:' + GREY)
| |
| 187: log(YELLOW + cmd.inspect + GREY) #inspect the failed command
| |
| 188: log('Command Deleted.')
| |
| 189: $commands.delete(cmd) #remove command if failed
| |
| 190: end
| |
| 191:
| |
| 192: }
| |
| 193: #log('dataOut Exited:')
| |
| 194:end
| |
| 195:def dataOutSingleCmd(cmd)
| |
| 196: log('dataOutSingleCmd Entered:')
| |
| 197: if cmd.state == SendReady #send out only if ready.
| |
| 198: @out = cmd.dataOut
| |
| 199: log('got past cmd.dataOut')
| |
| 200: log('@out is type:' + @out.class.to_s)
| |
| 201: case @out.class.to_s
| |
| 202: when 'String'
| |
| 203: log('Threading Suspended = FALSE') if $threadingSuspended == false
| |
| 204: log('Threading Suspended = TRUE') if $threadingSuspended == true
| |
| 205:
| |
| 206: if $threadingSuspended == false
| |
| 207: conn_.Reconnect()
| |
| 208: log('Sending to GSD...')
| |
| 209: debugout(@out)
| |
| 210: conn_.Send(@out)
| |
| 211: debugout(@out)
| |
| 212: conn_.Send(@out)
| |
| 213: sleep $delayBetweenTransmits
| |
| 214: if cmd.threaded == false
| |
| 215: log(YELLOW + 'THREADING SUSPENDED!!!' + GREY)
| |
| 216: $threadingSuspended == true
| |
| 217: end
| |
| 218: else
| |
| 219: #cannot send data out while waiting for a NON threaded response.
| |
| 220: end
| |
| 221: when 'Command'
| |
| 222: log('Sending to DCE...')
| |
| 223: SendCommand(@out)
| |
| 224: when 'NilClass' #safety first!
| |
| 225: log('This command not ready to send.')
| |
| 226: end
| |
| 227: end
| |
| 228: #log('dataOutSingleCmd Exited:')
| |
| 229:end
| |
| 230:def log(line)
| |
| 231: $log = File.open("/var/log/pluto/" + device_.devid_.to_s + "_Generic_Serial_Device.log", "a")
| |
| 232: $log.putc '('[0]
| |
| 233: $log.putc '*'[0]
| |
| 234: $log.putc '*'[0]
| |
| 235: $log.putc '*'[0]
| |
| 236: $log.putc ')'[0]
| |
| 237: @l = line.to_s
| |
| 238: @l.each_byte{|ch|
| |
| 239: $log.putc ch
| |
| 240: if ch == 60
| |
| 241: $log.putc 32
| |
| 242: end
| |
| 243: }
| |
| 244: $log.puts
| |
| 245: $log.close
| |
| 246:end
| |
| 247:def debugout(text)
| |
| 248: work = 'OUT:'
| |
| 249:
| |
| 250: for c in 1..text.length
| |
| 251: work += padhex("%X" %text[c-1]) + ' '
| |
| 252: end
| |
| 253: log(GREEN + work + "Length:" + text.length.to_s + GREY)
| |
| 254:end
| |
| 255:def debug(label, text)
| |
| 256: work = label + ":"
| |
| 257: for c in 1..text.length
| |
| 258: work += padhex("%X" %text[c-1]) + ' '
| |
| 259: end
| |
| 260: log(BLUE + work + "Length:" + text.length.to_s + GREY)
| |
| 261:end
| |
| 262:def debugin(text)
| |
| 263: work = 'IN:'
| |
| 264:
| |
| 265: for c in 1..text.length
| |
| 266: work += padhex("%X" %text[c-1]) + ' '
| |
| 267: end
| |
| 268: log(RED + work + "Length:" + text.length.to_s + GREY)
| |
| 269:end
| |
| 270:def padhex(hex)
| |
| 271: if hex.length==1
| |
| 272: hex = "0" + hex
| |
| 273: end
| |
| 274: return hex
| |
| 275:end
| |
| 276:
| |
| 277:##############################
| |
| 278:#Initialization Routine
| |
| 279:##############################
| |
| 280:def initDevices() #Loads Child Devices into Devices
| |
| 281: $threadingSuspended = false
| |
| 282: $timeout = 1 #Global timeout
| |
| 283: $retryAttempts = 10 #Global Retry Attempts
| |
| 284: $delayBetweenTransmits = 0.4
| |
| 285: log(YELLOW + 'Loading Child Devices...' + GREY)
| |
| 286: $devices = Devices.new
| |
| 287: device_.childdevices_.keys.each{|c| #Populate children
| |
| 288: d = Device.new() #create a new device
| |
| 289: d.deviceid = c
| |
| 290: d.template = device_.childdevices_[c].devtemplid_
| |
| 291: d.parent = device_.childdevices_[c].parent_
| |
| 292: d.devdata = device_.childdevices_[c].devdata_
| |
| 293: $devices.append(d) #add d to $devices
| |
| 294: log('Device:' + d.deviceid.to_s)}
| |
| 295: $me = Device.new() #get MY info
| |
| 296: $me.deviceid = device_.devid_
| |
| 297: $me.parent = device_.parent_
| |
| 298: $me.devdata = []
| |
| 299: $me.devdata = device_.devdata_
| |
| 300: $me.onoff = "ON"
| |
| 301: $me.level = 100
| |
| 302: myusercode = "My Usercode: %X" %$me.devdata[59].to_i #show in hex form
| |
| 303: log(myusercode)
| |
| 304:
| |
| 305: log(YELLOW + 'Done.' + GREY) #devdata[59] = usercode
| |
| 306: log(YELLOW + 'Setting up Command Queue' + GREY) #dedata[249] = 3phase (boolean)
| |
| 307: $commands = Array.new
| |
| 308: log(YELLOW + 'Done.' + GREY)
| |
| 309: #TODO: read all the PLC devices to get initial status.
| |
| 310: #TODO: and report status back to lmce.
| |
| 311:end
| |
| 312:def errorHandler # threaded errorhandler
| |
| 313: #Error handling is now handled at the RubyCommand Level.
| |
| 314: if $commands.nitems != 0 #log out the commands waiting to be processed, if any.
| |
| 315: @work = YELLOW + 'Command Queue:' + $commands.nitems.to_s
| |
| 316: $commands.each{|cm| @work += ', State:'
| |
| 317: @work += 'NEW' if cm.state == 1
| |
| 318: @work += 'SendReady' if cm.state == 2
| |
| 319: @work += 'ReceiveReady' if cm.state == 3
| |
| 320: @work += 'Complete' if cm.state == 4
| |
| 321: @work += 'Failed' if cm.state == 5
| |
| 322: @work += GREY + ' '}
| |
| 323: log(@work)
| |
| 324: end
| |
| 325: $commands.each{|cmd|
| |
| 326: case cmd.state #possible to clear out commands here..
| |
| 327: when Complete
| |
| 328: $commands.delete(cmd)
| |
| 329: # when SendReady
| |
| 330: # dataOutSingleCmd(cmd)
| |
| 331: when ReceiveReady
| |
| 332: if cmd.timeout == true #call the timeout and get back error.
| |
| 333: log(RED + 'This Command Timed Out!:' + GREY)
| |
| 334: log(RED + cmd.inspect + GREY)
| |
| 335: $commands.delete(cmd)
| |
| 336: else
| |
| 337: dataOutSingleCmd(cmd)
| |
| 338: end
| |
| 339: end
| |
| 340: }
| |
| 341:end
| |
| 342:
| |
| 343:##############################
| |
| 344:#Class RubyCommand
| |
| 345:##############################
| |
| 346:class RubyCommand
| |
| 347: # This class is a container for a protocolObject Instance.
| |
| 348: # This class is responsible for the DIRECTION of communication of a specific command.
| |
| 349: #
| |
| 350: # Error Handling is also handled in the timeout method.
| |
| 351: #
| |
| 352: # If this command creates a NEW command, this object will allow only ONE creation.
| |
| 353: # This class also controls the state information.
| |
| 354: # Constants:
| |
| 355: DCEtoGSD = 10
| |
| 356: GSDtoDCE = 20
| |
| 357: #Object States:
| |
| 358: NEW = 1
| |
| 359: SendReady = 2
| |
| 360: ReceiveReady = 3
| |
| 361: Complete = 4
| |
| 362: Failed = 5
| |
| 363:
| |
| 364:
| |
| 365: def initialize
| |
| 366: #log('Initialize Entered:')
| |
| 367: @protocolObject = PLCBUS.new()
| |
| 368: @direction = nil
| |
| 369: @timeoutCounter = 0
| |
| 370: @timeoutRetries = 0
| |
| 371: @state = NEW
| |
| 372: @serialNumber = rand(10000).to_s #for DCE object
| |
| 373: @newCommandSent = false
| |
| 374: #log('Initialize Exited:')
| |
| 375: end
| |
| 376: def dataIn(cmd) #Returns TRUE if accepted, FALSE if not.
| |
| 377: #log('dataIn Entered:')
| |
| 378: case @state
| |
| 379: when NEW
| |
| 380: log('dataIn: creating NEW command')
| |
| 381: @savedCommand = cmd
| |
| 382:
| |
| 383: case cmd.class.to_s
| |
| 384: when 'String' # new Command from GSD
| |
| 385: @direction = GSDtoDCE
| |
| 386: @protocolObject.gsdCommandIn(cmd)
| |
| 387: @state = SendReady #This command is ready to send.
| |
| 388: when 'Command' # new Command from DCE
| |
| 389: @direction = DCEtoGSD
| |
| 390: @protocolObject.dceCommandIn(cmd)
| |
| 391: @state = SendReady #This command is ready to send.
| |
| 392: else
| |
| 393: log('FAILURE IN dataIn - cmd.class not recognized!')
| |
| 394: log('Direction: nil')
| |
| 395: log('class is:' + cmd.class.to_s)
| |
| 396: @state = Failed #fail this command. (remove it)
| |
| 397: end
| |
| 398: @result = true #returns datain Accepted.
| |
| 399: when ReceiveReady #Possible Response
| |
| 400: log('dataIn: Possible Response')
| |
| 401: @result = false
| |
| 402: @class = cmd.class.to_s #get this only once.
| |
| 403: case @direction
| |
| 404: when DCEtoGSD
| |
| 405: case @class
| |
| 406: when 'String' # from GSD
| |
| 407: #log('dataIn: class is STRING')
| |
| 408: #pass the data to the protocol Object and check for accepted.
| |
| 409: #log('dataIn: executing gsdResponseIn')
| |
| 410: if @protocolObject.gsdResponseIn(cmd) == true
| |
| 411: log('response Accepted.')
| |
| 412: @result = true
| |
| 413: if @protocolObject.responseNeeded == true
| |
| 414: log('Command not yet complete.')
| |
| 415: @state = ReceiveReady # ProtocolObject needs another response.
| |
| 416: else
| |
| 417: log('Command Complete.')
| |
| 418: @state = Complete # ProtocolObject is complete.
| |
| 419: end
| |
| 420:
| |
| 421: else
| |
| 422: log('response Rejected!')
| |
| 423: end
| |
| 424: when 'Command' # from DCE
| |
| 425: #log('dataIn: class is COMMAND')
| |
| 426: @result = false # cmd is NOT for me.
| |
| 427: else
| |
| 428: log('FAILURE IN dataIn - cmd.class not recognised!')
| |
| 429: log('Direction: DCEtoGSD')
| |
| 430: log('class is:' + @class.to_s)
| |
| 431:
| |
| 432: @result = false
| |
| 433: end
| |
| 434:
| |
| 435: when GSDtoDCE
| |
| 436: case @class
| |
| 437: when 'String' # from GSD
| |
| 438: @result = false # not for me.
| |
| 439: when 'Command' # POSSIBLE when sending commands to self.
| |
| 440: if cmd.params_[999] == @serialNumber
| |
| 441: @result = true #I sent this command!
| |
| 442: log('Caught Command Sent to Self!')
| |
| 443: end
| |
| 444: else
| |
| 445: log('FAILURE IN dataIn - cmd.class not recognised!')
| |
| 446: log('Direction: GSDtoDCE')
| |
| 447: log('class is:' + @class.to_s)
| |
| 448:
| |
| 449: end
| |
| 450: end
| |
| 451: #log('dataIn: returning TRUE (exited)') if @result == true
| |
| 452: #log('dataIn: returning FALSE (exited)') if @result == false
| |
| 453: return @result
| |
| 454: end
| |
| 455: end
| |
| 456: def dataOut
| |
| 457: log('dataOut Entered:')
| |
| 458: if @state == SendReady
| |
| 459: case @direction
| |
| 460: when DCEtoGSD #Send GSD String
| |
| 461: @work = @protocolObject.gsdout
| |
| 462: log('dataOut: Setting @state to Receive Ready')
| |
| 463: @state = ReceiveReady
| |
| 464: when GSDtoDCE
| |
| 465: @work = @protocolObject.dceout
| |
| 466: if @work.class.to_s == 'Command' #check for valid Object (returns nil if not ready)
| |
| 467: if @work.devidto_ == @work.devidfrom_ #check for command to self
| |
| 468: log('Detected attempting to send to self')
| |
| 469: @work.devdata_[999] = @serialNumber #this command is to self. Serialize it.
| |
| 470: end
| |
| 471: end
| |
| 472: log('dataOut: Setting @state to Complete')
| |
| 473: @state = Complete #DCE does not send responses. (yet)
| |
| 474: else
| |
| 475: log('Attempted DataOut with uninitialized Object')
| |
| 476: @state = Failed
| |
| 477: @work = nil
| |
| 478: end
| |
| 479: log('dataOut: Returning @work')
| |
| 480: return @work
| |
| 481: else
| |
| 482: log('This command is not ready to send.')
| |
| 483: end
| |
| 484: log('DataOut Exited:')
| |
| 485: end
| |
| 486: def timeout #called ONLY when @state == ReceiveReady
| |
| 487: @result = false #returns TRUE if command times out.
| |
| 488: @timeoutCounter +=1 #ticker += 1
| |
| 489: if @timeoutCounter == $timeout #global variable defined in init.
| |
| 490: @timeoutCounter = 0 #reset ticker
| |
| 491: @timeoutRetries += 1 #increment Retries..
| |
| 492: if @timeoutRetries == $retryAttempts #global variable defined in init.
| |
| 493: @state = Failed
| |
| 494: @result = true
| |
| 495: else
| |
| 496: log('Attempt:' + (@timeoutRetries + 1).to_s)
| |
| 497: if @state == ReceiveReady
| |
| 498: @state = SendReady
| |
| 499: end
| |
| 500: end
| |
| 501:
| |
| 502: end
| |
| 503: log('Tick...')
| |
| 504: return @result
| |
| 505: end
| |
| 506: def state
| |
| 507: return @state
| |
| 508: end
| |
| 509: def direction()
| |
| 510: return @direction
| |
| 511: end
| |
| 512: def responseNeeded()
| |
| 513: return @protocolObject.responseNeeded
| |
| 514: end
| |
| 515: def commandHolder() #This is a holder of self. Used when inserting another command.
| |
| 516: #allow only ONE command to be returned.
| |
| 517: @holder = @protocolObject.commandHolder
| |
| 518: if @holder != nil
| |
| 519: if @newCommandSent == false
| |
| 520: #we can send the command here.
| |
| 521: @newCommandSent = true
| |
| 522: return @holder
| |
| 523: end
| |
| 524: end
| |
| 525: return nil
| |
| 526: end
| |
| 527: def threaded
| |
| 528: return @protocolObject.threaded
| |
| 529: end
| |
| 530: # def packCommand(value) # this is used by protocolObject to pack a command.
| |
| 531: # if value.class.to_s == 'Command'
| |
| 532: # #packing a DCE Object..
| |
| 533: # self.dcein(value)
| |
| 534: # #override the direction...
| |
| 535: # @direction = GSDtoDCE
| |
| 536: # #flag the command ready to be sent.
| |
| 537: # @sendReady = true
| |
| 538: # end
| |
| 539: # if value.class.to_s == 'String'
| |
| 540: # #packing a GSD object
| |
| 541: # self.gsdin(value)
| |
| 542: # #override the direction...
| |
| 543: # @direction = DCEtoGSD
| |
| 544: # #flag the command ready to be sent.
| |
| 545: # @sendReady = true
| |
| 546: # end
| |
| 547: # end
| |
| 548: # def hasNewCommand()
| |
| 549: # return @hasNewCommand
| |
| 550: # end
| |
| 551: def log(line) #support method.
| |
| 552: @log = File.open("/var/log/pluto/" + $me.deviceid.to_s + "_Generic_Serial_Device.log", "a")
| |
| 553: @log.putc '('[0]
| |
| 554: @log.putc 'C'[0]
| |
| 555: @log.putc 'o'[0]
| |
| 556: @log.putc 'm'[0]
| |
| 557: @log.putc 'm'[0]
| |
| 558: @log.putc 'a'[0]
| |
| 559: @log.putc 'n'[0]
| |
| 560: @log.putc 'd'[0]
| |
| 561:
| |
| 562: @log.putc ')'[0]
| |
| 563: @l = line.to_s
| |
| 564: @l.each_byte{|ch|
| |
| 565: @log.putc ch
| |
| 566: if ch == 60
| |
| 567: @log.putc 32
| |
| 568: end
| |
| 569: }
| |
| 570: @log.puts
| |
| 571: @log.close
| |
| 572: @log = nil
| |
| 573: end
| |
| 574:end
| |
| 575:
| |
| 576:
| |
| 577:
| |
| 578:#####################
| |
| 579:### PLCBUS OBJECT ###
| |
| 580:#####################
| |
| 581:# This is a generic replaceable object
| |
| 582:# This object needs the following methods:
| |
| 583:#
| |
| 584:# Initialize()
| |
| 585:#
| |
| 586:# What it does:
| |
| 587:# any Object initialization you may need.
| |
| 588:#
| |
| 589:# When is this called:
| |
| 590:# Upon Object creation.
| |
| 591:#
| |
| 592:# What you will get:
| |
| 593:# nothing.
| |
| 594:#
| |
| 595:# What you will return:
| |
| 596:# nothing.
| |
| 597:#
| |
| 598:#
| |
| 599:# dceCommandIn(cmd)
| |
| 600:#
| |
| 601:# What is does:
| |
| 602:# sends you a command object to allow you to create gsdOut().
| |
| 603:#
| |
| 604:# What you will get:
| |
| 605:# cmd (Command Object)
| |
| 606:#
| |
| 607:# What you need to return:
| |
| 608:# nothing (ignored)
| |
| 609:#
| |
| 610:# When you will get this:
| |
| 611:# executed when a new DCE command is sent to you.
| |
| 612:#
| |
| 613:#
| |
| 614:# dceResponseIn(cmd)
| |
| 615:#
| |
| 616:# What it does:
| |
| 617:# Sends you a DCE object to compare with the command.
| |
| 618:#
| |
| 619:# What you will get:
| |
| 620:# cmd (Command Object)
| |
| 621:#
| |
| 622:# What you need to return:
| |
| 623:# TRUE if you accept this response.
| |
| 624:# FALSE if you do NOT accept this response.
| |
| 625:#
| |
| 626:# When you will get this:
| |
| 627:# executed when a new DCE response is ready.
| |
| 628:#
| |
| 629:#
| |
| 630:# gsdCommandIn(value)
| |
| 631:#
| |
| 632:# What it does:
| |
| 633:# sends you a String to allow you to create a dceOut().
| |
| 634:#
| |
| 635:# What you will get:
| |
| 636:# value (String Object)
| |
| 637:#
| |
| 638:# What you need to return:
| |
| 639:# nothing (ignored)
| |
| 640:#
| |
| 641:# When you will get this:
| |
| 642:# executed when a new GSD command is sent to you.
| |
| 643:#
| |
| 644:#
| |
| 645:# gsdResponseIn(value)
| |
| 646:#
| |
| 647:# What it does:
| |
| 648:# Sends you a GSD Response to compare with the command.
| |
| 649:# What you will get:
| |
| 650:# cmd (Command Object)
| |
| 651:#
| |
| 652:# What you need to return:
| |
| 653:# TRUE if you accept this response.
| |
| 654:# FALSE if you do NOT accept this response.
| |
| 655:#
| |
| 656:# When you will get this:
| |
| 657:# executed when a new GSD response is ready.
| |
| 658:#
| |
| 659:# dceout()
| |
| 660:#
| |
| 661:# What it does:
| |
| 662:# Creates a Command Object to send to DCE.
| |
| 663:#
| |
| 664:# What you will get:
| |
| 665:# nothing.
| |
| 666:#
| |
| 667:# What you need to return:
| |
| 668:# a Command Object representing the previous gsdCommandIn.
| |
| 669:#
| |
| 670:# When is this called:
| |
| 671:# After a gsdCommandIn has been sent.
| |
| 672:# gsdout()
| |
| 673:#
| |
| 674:# What it does:
| |
| 675:# creates a String Object to send to GSD.
| |
| 676:#
| |
| 677:# What you will get:
| |
| 678:# nothing.
| |
| 679:#
| |
| 680:# What you will return:
| |
| 681:# a String Object representing the previous dceCommandIn.
| |
| 682:#
| |
| 683:# When is this called:
| |
| 684:# After a dceCommandIn has been sent.
| |
| 685:#
| |
| 686:#
| |
| 687:# Properties:
| |
| 688:#
| |
| 689:# @responseAccepted
| |
| 690:#
| |
| 691:# What it does:
| |
| 692:# signals that the current response is accepted as valid.
| |
| 693:#
| |
| 694:# When you should set this:
| |
| 695:#
| |
| 696:# @responseNeeded
| |
| 697:#
| |
| 698:# What it does:
| |
| 699:# signals when you need a response.
| |
| 700:#
| |
| 701:# @commandHolder
| |
| 702:#
| |
| 703:# What it does:
| |
| 704:# If you need to create a new command, this is the holder for it.
| |
| 705:#
| |
| 706:
| |
| 707:class PLCBUS
| |
| 708: attr_reader :responseAccepted, :responseNeeded, :commandHolder, :threaded
| |
| 709: #Conatants:
| |
| 710: STX=0x02.chr
| |
| 711: ETX=0x03.chr
| |
| 712: 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}
| |
| 713: 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}
| |
| 714: 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',
| |
| 715: 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'}
| |
| 716:
| |
| 717:
| |
| 718: def initialize()
| |
| 719: # declare gsd variables
| |
| 720: @home = 0 #these two varianles determine the TO or FROM address
| |
| 721: @unit = 0 #these two variables determine the TO or FROM address
| |
| 722: @command = 0
| |
| 723: @usercode = $me.devdata[59].to_i
| |
| 724: #@cmdReprq = $me.devdata[260] #3Phase on Dan's system
| |
| 725: @cmdReprq = $me.devdata[249] #3Phase on Hari's system
| |
| 726: @data1 = 0
| |
| 727: @data2 = 0
| |
| 728: @cmdAckPulse = false
| |
| 729: @cmdLink = false
| |
| 730: #declare DCE variables
| |
| 731: @dceto = 0
| |
| 732: @dcefrom = 0
| |
| 733: @dcepriority = 0
| |
| 734: @dcecmdtype = 0
| |
| 735: @dcecmdid = 0
| |
| 736: @dceparams = {}
| |
| 737: @responseNeeded = false
| |
| 738: @responseAccepted = false
| |
| 739: @gsdparams = {}
| |
| 740: #@gsdparams[120] = '1' # hack to force command is useless...
| |
| 741: @commandHolder = nil
| |
| 742: #log('Leaving Initialize')
| |
| 743: @threaded = true
| |
| 744: end
| |
| 745: def dceCommandIn(cmd)
| |
| 746: log('dceCommandIn Entered:')
| |
| 747: @dcehomeunit = $devices[cmd.devidto_].devdata[12][0..1]
| |
| 748: @dcehome = HomeCodes[$devices[cmd.devidto_].devdata[12][0].chr].to_s
| |
| 749: @dceunit = UnitCodes[$devices[cmd.devidto_].devdata[12][1].chr].to_s
| |
| 750: @dcefrom = cmd.devidfrom_
| |
| 751: @dceto = cmd.devidto_
| |
| 752: @dcepriority = cmd.priority_
| |
| 753: @dcecmdtype = cmd.type_
| |
| 754: @dcecmdid = cmd.id_
| |
| 755: @dceparams = cmd.params_
| |
| 756:
| |
| 757: end
| |
| 758: def dceResponseIn(cmd) # Returns TRUE if response is accepted.
| |
| 759: log('dceResponseIn Entered:')
| |
| 760: log(cmd.inspect)
| |
| 761: return true #ignored in PLCBUS
| |
| 762: end
| |
| 763: def gsdCommandIn(value)
| |
| 764: log('gsdCommandIn Entered:')
| |
| 765: debug('Value:', value)
| |
| 766: @gsdusercode = value[2]
| |
| 767: @gsdhomeunit = ("%X" %value[3])
| |
| 768: @gsdhome = @gsdhomeunit[0].chr
| |
| 769: @gsdunit = @gsdhomeunit[1].chr
| |
| 770: @gsdcommand = value[4]
| |
| 771: @gsdcmdAckPulse = true if (value[4] & 0x20) == 0x20
| |
| 772: @gsdcmdReprq = true if (value[4] & 0x40) == 0x40
| |
| 773: @gsdcmdLink = true if (value[4] & 0x80) == 0x80
| |
| 774: @gsddata1 = value[5]
| |
| 775: @gsddata2 = value[6]
| |
| 776: if value[1] == 6
| |
| 777: rxtxSwitchRegister(value[7]) #set switches if they exist
| |
| 778: end
| |
| 779: end
| |
| 780: def gsdResponseIn(value) #returns TRUE if response is accepted.
| |
| 781: #no need to store response.. just compare.
| |
| 782: #negative logic here
| |
| 783: @result = true
| |
| 784: #log('gsdResponseIn Entered:')
| |
| 785: #debug('Value:', value)
| |
| 786: if @usercode == value[2]
| |
| 787: #log('Usercode Check!')
| |
| 788: else
| |
| 789: log('Usercode compare failed')
| |
| 790: @result = false
| |
| 791: end
| |
| 792: if dcehomeunit[0] == value[3]
| |
| 793: #log('Home and Unit CHECK!')
| |
| 794: else
| |
| 795: log('Home and Unit compare failed')
| |
| 796: @result = false
| |
| 797: end
| |
| 798: if dcecommand(@dcecmdid)[0] == value[4]
| |
| 799: #log('PLCBus Command CHECK!')
| |
| 800: else
| |
| 801: log('PLCBus Command compare failed')
| |
| 802: @result = false
| |
| 803: end
| |
| 804: if value[1] == 6
| |
| 805: #log('Setting rxtxRegister')
| |
| 806: rxtxSwitchRegister(value[7])
| |
| 807: else
| |
| 808: log('no rxtxRegister')
| |
| 809: @result = false
| |
| 810: end
| |
| 811: #log('gsdResponseIn returning TRUE') if @result == true
| |
| 812: #log('gsdResponseIn returning FALSE') if @result == false
| |
| 813: return @result
| |
| 814: end
| |
| 815: def dceout # Returns the GSD values as a DCE command.
| |
| 816: @myfrom = gsdhomeunit
| |
| 817: if @myfrom == 0
| |
| 818: log('I DONT KNOW THIS DEVICE ID')
| |
| 819: else
| |
| 820: @mycommandout = gsdcommand
| |
| 821: log('IN PLCBUS:DCEOUT')
| |
| 822: log(' From: ' + @myfrom.to_s)
| |
| 823: log(' To: -1001')
| |
| 824: log(' Priority: 1')
| |
| 825: log(' CmdType: 2')
| |
| 826: log(' CmdId: ' + @mycommandout.to_s)
| |
| 827: log('Devdata Below:')
| |
| 828: @gsdparams.each_pair{|k,v|
| |
| 829: log(' devdata_[' + k.to_s + '] = ' + v)
| |
| 830: }
| |
| 831: @cmdout = Command.new(@myfrom, -1001, 1, 2, @mycommandout)
| |
| 832: @gsdparams.each_pair{|k,v| @cmdout.params_[k]=v}
| |
| 833: # @responseNeeded = false
| |
| 834: # @responseAccepted = true
| |
| 835: return @cmdout
| |
| 836: end
| |
| 837: end
| |
| 838: def gsdout # Returns the DCE values as a gsd string
| |
| 839: #log('IN PLCBUS:GSDOUT')
| |
| 840: log('SETTING THREADING to FALSE in PLCBUS:GSDOUT:')
| |
| 841: @threaded = false
| |
| 842: @gsdout = @usercode.chr
| |
| 843: @gsdout += dcehomeunit + dcecommand(@dcecmdid) + @data1.chr + @data2.chr
| |
| 844: @gsdout = @gsdout.length.chr + @gsdout
| |
| 845: @gsdout = STX + @gsdout + ETX
| |
| 846: #debug('Data Out', @gsdout)
| |
| 847: return @gsdout
| |
| 848: end
| |
| 849: def checkResponse(cmd) #old?? fired when a response was accepted.
| |
| 850: log('WARNING: CheckResponse was CALLED')
| |
| 851: # #this routine needs to set ONE flag:
| |
| 852: # #responseNeeded (true/false) if we need more data
| |
| 853: # if cmd.class.to_s == 'String'
| |
| 854: # #we are checking a GSD command.
| |
| 855: #
| |
| 856: # end
| |
| 857: # if cmd.class == Command
| |
| 858: # #we are checking a DCE command.
| |
| 859: # if @r_ack_sw == true
| |
| 860: # #here is a good place to check the data1 and data2 values
| |
| 861: # #to make sure the proper device responded.
| |
| 862: # #
| |
| 863: # #PLCBUS command complete
| |
| 864: # log('Received Ack from PLCBUS device.')
| |
| 865: # @responseNeeded = false
| |
| 866: # # attempt to set device info here.
| |
| 867: # case @dcecmdid
| |
| 868: # when 192 # ON
| |
| 869: # $devices[@dceto].onoff = "ON"
| |
| 870: # if $devices[@dceto].level != 100
| |
| 871: # $devices[@dceto].level = 100
| |
| 872: # log('HAVE TO SEND A SETLEVEL=100')
| |
| 873: # end
| |
| 874: # when 193 # OFF
| |
| 875: # $devices[@dceto].onoff = "OFF"
| |
| 876: # if $devices[@dceto].level != 0
| |
| 877: # $devices[@dceto].level = 0
| |
| 878: # log('HAVE TO SEND A SETLEVEL = 0')
| |
| 879: # log('**************************')
| |
| 880: # log('**************************')
| |
| 881: # log('**************************')
| |
| 882: # log('**************************')
| |
| 883: # @commandHolder = RubyCommand.new()
| |
| 884: # #pack a new DCE command with the Event..
| |
| 885: # @mycmd = Command.new(@dceto, @dceto, 1, 1, 184)
| |
| 886: # @mycmd.params_[76] = '0'
| |
| 887: # @commandHolder.packCommand(@mycmd)
| |
| 888: #
| |
| 889: # end
| |
| 890: # when 184 # SetLevel
| |
| 891: # if @dceparams[76].to_i == 0
| |
| 892: # #dimming to OFF
| |
| 893: # if $devices[@dceto].onoff == 'ON'
| |
| 894: # log('HAVE TO SEND AN OFF to DCE')
| |
| 895: # log('**************************')
| |
| 896: # log('**************************')
| |
| 897: # log('**************************')
| |
| 898: # log('**************************')
| |
| 899: # @commandHolder = RubyCommand.new()
| |
| 900: # #pack a new DCE command with the Event..
| |
| 901: # @mycmd = Command.new(@dceto, -1001, 1, 2, 40)
| |
| 902: # @mycmd.params_[10] = '0'
| |
| 903: # @commandHolder.packCommand(@mycmd)
| |
| 904: # #
| |
| 905: #
| |
| 906: # #@commandHolder = Command.new(@dcefrom, -1001, 1, 2, 40)
| |
| 907: # #@commandHolder.params_[10] = '0'
| |
| 908: # $devices[@dceto].onoff = 'OFF'
| |
| 909: #
| |
| 910: # end
| |
| 911: #
| |
| 912: # else
| |
| 913: # #dimming to ON
| |
| 914: # if $devices[@dceto].onoff == 'OFF'
| |
| 915: # log('HAVE TO SEND AN ON to DCE')
| |
| 916: # log('**************************')
| |
| 917: # log('**************************')
| |
| 918: # log('**************************')
| |
| 919: # log('**************************')
| |
| 920: # @commandHolder = RubyCommand.new()
| |
| 921: # @mycmd = Command.new(@dceto, -1001, 1, 2, 40)
| |
| 922: # @mycmd.params_[10] = '1'
| |
| 923: # @commandHolder.packCommand(@mycmd)
| |
| 924: # #@commandHolder = Command.new(@dcefrom, -1001, 1, 2, 40)
| |
| 925: # #@commandHolder.params_[10] = '1'
| |
| 926: #
| |
| 927: # $devices[@dceto].onoff = 'ON'
| |
| 928: # end
| |
| 929: # end
| |
| 930: # $devices[@dceto].level = @dceparams[76].to_i
| |
| 931: # end
| |
| 932: # log('Device:' + @dceto.to_s)
| |
| 933: # log('on/off:' + $devices[@dceto].onoff)
| |
| 934: # log(' level:' + $devices[@dceto].level.to_s)
| |
| 935: # end
| |
| 936: # if @r_itself == true
| |
| 937: # #heard myself send the response.
| |
| 938: # log('I heard myself send the command properly.')
| |
| 939: # @responseNeeded = true
| |
| 940: # end
| |
| 941: #
| |
| 942: # end
| |
| 943: @responseAccepted = true
| |
| 944: end
| |
| 945: #Support Routines for PLCBUX
| |
| 946: def dcecommand(value) #DCE value is DCE Command.
| |
| 947: #user code is in devdata[59] Configuration
| |
| 948: #devdata[250] 3phase (boolean)
| |
| 949: @work = 0
| |
| 950: #log('DCE Command is' + value.to_s)
| |
| 951: case value
| |
| 952: when 192 #ON
| |
| 953:
| |
| 954: @cmdLink = false
| |
| 955: @cmdReprq = false
| |
| 956: @cmdAckPulse = true
| |
| 957: @data1 = 0 #Fade Rate
| |
| 958: @work = 0x80 if @cmdling == true
| |
| 959: @work += 0x40 if @cmdReprq == true
| |
| 960: @work += 0x20 if @cmdAckPulse == true
| |
| 961: @command =@work + CommandFunctions.index("ON")
| |
| 962: when 193 #OFF
| |
| 963: @cmdLink = false
| |
| 964: @cmdReprq = false
| |
| 965: @cmdAckPulse = true
| |
| 966: @data1 = 0 #Fade Rate
| |
| 967: @work = 0x80 if @cmdling == true
| |
| 968: @work += 0x40 if @cmdReprq == true
| |
| 969: @work += 0x20 if @cmdAckPulse == true
| |
| 970: @command =@work + CommandFunctions.index("OFF")
| |
| 971: when 184 # SETLEVEL
| |
| 972: @cmdLink = false
| |
| 973: @cmdReprq = false
| |
| 974: @cmdAckPulse = true
| |
| 975: @data1 = @dceparams[76].to_i #dim level
| |
| 976: @data2 = 2 #Fade Rate
| |
| 977: @work = 0x80 if @cmdling == true
| |
| 978: @work += 0x40 if @cmdReprq == true
| |
| 979: @work += 0x20 if @cmdAckPulse == true
| |
| 980: @data2 = 2#Fade Rate
| |
| 981: @command =@work + CommandFunctions.index("PRESETDIM")
| |
| 982: end
| |
| 983: #how convert it into a integer - currently it a HEX string.
| |
| 984: #log('PLC Command is:' + @command.to_s + 'DECIMAL')
| |
| 985: return @command.chr
| |
| 986: end
| |
| 987: def gsdcommand #returns DCE EVENT!! and compiles params
| |
| 988:
| |
| 989: #log('IN DCECommand')
| |
| 990:
| |
| 991: case CommandFunctions[@gsdcommand]
| |
| 992: when 'ALL UNIT OFF'
| |
| 993: @gsdparams[10] = '0'
| |
| 994: return 48
| |
| 995: when 'ALL LTS ON'
| |
| 996: @gsdparams[10] = '1'
| |
| 997: return 48
| |
| 998: when 'ON'
| |
| 999: @gsdparams[10] = '1'
| |
| 1000: return 48
| |
| 1001: when 'OFF'
| |
| 1002: @gsdparams[10] = '0'
| |
| 1003: return 48
| |
| 1004: when 'DIM'
| |
| 1005: @gsdparams[10] = @gsddata1 # set Brightness
| |
| 1006: return 48
| |
| 1007:
| |
| 1008: when 'BRIGHT'
| |
| 1009: @gsdparams[10] = @gsddata1 # set Brightness
| |
| 1010: return 48
| |
| 1011:
| |
| 1012: when 'ALL LIGHT OFF'
| |
| 1013: @gsdparams[10] = '0'
| |
| 1014: return 48
| |
| 1015: when 'ALL USER LTS ON'
| |
| 1016: @gsdparams[10] = '1'
| |
| 1017: return 48
| |
| 1018: when 'ALL USER UNIT OFF'
| |
| 1019: @gsdparams[10] = '0'
| |
| 1020: return 48
| |
| 1021: when 'ALL USER LIGHT OFF'
| |
| 1022: @gsdparams[10] = '0'
| |
| 1023: return 48
| |
| 1024: when 'BLINK'
| |
| 1025: when 'FADE STOP'
| |
| 1026: when 'PRESETDIM'
| |
| 1027: @gsdparams[10] = @gsddata1
| |
| 1028: return 48
| |
| 1029: when 'STATUS ON'
| |
| 1030: when 'STATUS OFF'
| |
| 1031: when 'STATUS REQ'
| |
| 1032: when '(R)MASTER ADDRS SETUP'
| |
| 1033: when '(T)MASTER ADDRS SETUP'
| |
| 1034: when 'SCENES ADDRS SETUP'
| |
| 1035: when 'SCENES ADDRS ERASE'
| |
| 1036: when 'ALL SCENES ADDRS ERASE'
| |
| 1037: when 'FOR FUTURE'
| |
| 1038: when 'GET SIGNAL STRENGTH'
| |
| 1039: when 'GET NOISE STRENGTH'
| |
| 1040: when 'REPORT SIGNAL STRENGTH'
| |
| 1041: when 'REPORT NOISE STRENGTH'
| |
| 1042: when 'GET ALL ID PULSE'
| |
| 1043: when 'GET ONLY ON ID PULSE'
| |
| 1044: when 'REPORT ALL ID PULSE'
| |
| 1045: when 'REPORT ONLY ON PULSE'
| |
| 1046: else
| |
| 1047: log('UNKNOWN COMMAND RESPONSE in PLCBUS OBJECT')
| |
| 1048: return 0
| |
| 1049: end
| |
| 1050:
| |
| 1051: end
| |
| 1052: def dcehomeunit() # returns GSD homeunit byte from DCE homeunit
| |
| 1053: @work = @dcehome + @dceunit
| |
| 1054: return (@work.hex.chr)
| |
| 1055: end
| |
| 1056: def gsdhomeunit() #returns DCE Child ID from gsd homeunit
| |
| 1057: #@gsdhomeunit holds the data
| |
| 1058: @work = HomeCodes.index(@gsdhomeunit[0].chr.to_i)
| |
| 1059: @work += UnitCodes.index(@gsdhomeunit[1].chr.to_i)
| |
| 1060: return $devices.find(@work)
| |
| 1061: end
| |
| 1062: def rxtxSwitchRegister(value)
| |
| 1063: #log('setting RX_TX_SWITCH')
| |
| 1064: if (value & 0x40) == 0x40
| |
| 1065: #log('r_id_sw is set')
| |
| 1066: @r_id_sw = true
| |
| 1067: else
| |
| 1068: #log('r_id_sw is reset')
| |
| 1069: @r_id_sw = false
| |
| 1070: end
| |
| 1071: if (value & 0x20) == 0x20
| |
| 1072: #log('r_ack_sw is set')
| |
| 1073: @r_ack_sw = true
| |
| 1074: @responseNeeded = false
| |
| 1075: else
| |
| 1076: #log('ResponseNeeded set to TRUE')
| |
| 1077: @responseNeeded = true
| |
| 1078: #log('r_ack_sw is reset')
| |
| 1079: @r_ack_sw = false
| |
| 1080: end
| |
| 1081: if (value & 0x10) == 0x10
| |
| 1082: #log('r_itself is set')
| |
| 1083: @r_itself = true
| |
| 1084: log('I heard myself Transmit this command on the PLCBUS.')
| |
| 1085: else
| |
| 1086: #log('r_itself is reset')
| |
| 1087: @r_itself = false
| |
| 1088: log('This Command is transmitted from an OUTSIDE SOURCE!')
| |
| 1089: end
| |
| 1090: if (value & 0x8) == 0x8
| |
| 1091: #log('r_risc is set')
| |
| 1092: @r_risc = true
| |
| 1093: else
| |
| 1094: #log('r_risc is reset')
| |
| 1095: @r_risc = false
| |
| 1096: end
| |
| 1097: if (value & 0x4) == 0x4
| |
| 1098: #log('r_sw is set')
| |
| 1099: @r_sw = true
| |
| 1100: else
| |
| 1101: #log('r_sw is reset')
| |
| 1102: @r_sw = false
| |
| 1103: end
| |
| 1104:
| |
| 1105: end
| |
| 1106: #Generic Support Routines
| |
| 1107: def log(line)
| |
| 1108: @log = File.open("/var/log/pluto/" + $me.deviceid.to_s + "_Generic_Serial_Device.log", "a")
| |
| 1109: @log.putc '('[0]
| |
| 1110: @log.putc 'P'[0]
| |
| 1111: @log.putc 'L'[0]
| |
| 1112: @log.putc 'C'[0]
| |
| 1113: @log.putc ')'[0]
| |
| 1114: @l = line.to_s
| |
| 1115: @l.each_byte{|ch|
| |
| 1116: @log.putc ch
| |
| 1117: if ch == 60
| |
| 1118: @log.putc 32
| |
| 1119: end
| |
| 1120: }
| |
| 1121: @log.puts
| |
| 1122: @log.close
| |
| 1123: @log = nil
| |
| 1124: end
| |
| 1125: def debug(label, text)
| |
| 1126: work = label + ":"
| |
| 1127: for c in 1..text.length
| |
| 1128: work += padhex("%X" %text[c-1]) + ' '
| |
| 1129: end
| |
| 1130: log(BLUE + work + "Length:" + text.length.to_s + GREY)
| |
| 1131: end
| |
| 1132: def padhex(hex)
| |
| 1133: if hex.length==1
| |
| 1134: hex = "0" + hex
| |
| 1135: end
| |
| 1136: return hex
| |
| 1137: end
| |
| 1138:end
| |
| 1139:def cmd_ReceiveCommandForChild(cmd)
| |
| 1140:### #484 Process Receive Command for Child
| |
| 1141:log('DCE Command Received')
| |
| 1142:
| |
| 1143:dataIn(cmd)
| |
| 1144:end
| |
| 1145:#### 760 ####################################################################
| |
| 1146:def cmd_760(id, pk_command, parameters, cmd=nil)
| |
| 1147:@returnParamArray.clear
| |
| 1148:log('DCE Send Command to Child 760 Received')
| |
| 1149:
| |
| 1150:dcein760(cmd)
| |
| 1151:return @returnParamArray
| |
| 1152:end
| |
| 1153:#### 776 ####################################################################
| |
| 1154:def cmd_776(arguments, cmd=nil)
| |
| 1155:@returnParamArray.clear
| |
| 1156:#Simulate a gsdin command...
| |
| 1157:#[31mIN:02 06 22 30 02 64 00 0C 03 Length:9
| |
| 1158:@simulation = 0x02.chr + 0x06.chr + 0x22.chr + 0x30.chr + 0x02.chr
| |
| 1159:@simulation += 0x64.chr + 0x00.chr + 0x0C.chr + 0x03.chr
| |
| 1160:log(AQUA + 'sending Simulated PLCBUS Command' + GREY)
| |
| 1161:debugin(@simulation)
| |
| 1162:dataIn(@simulation)
| |
| 1163:return @returnParamArray
| |
| 1164:end
| |
| 1165:#### START SETTERS ####################################################################
| |
| 1166:def initialize()
| |
| 1167:super
| |
| 1168:@returnParamArray=Array.new
| |
| 1169:end
| |
| 1170:#### END SETTERS ####################################################################
| |
| 1171:end
| |
| </pre>
| |
|
| |
|
| = Links = | | = Links = |
| * http://www.plcbus.com.cn/ | | * http://www.plcbus.com.cn/ |
| * http://www.futurehomes.com.sg/PLCBUSinfo.htm | | * http://www.futurehomes.com.sg/PLCBUSinfo.htm |