All pastes #1021509 Raw Edit

BlkHtBrigade

public text v1 · immutable
#1021509 ·published 2008-05-18 01:45 UTC
rendered paste body
(***):[31mreceive timeout=3[37m
(***):Third attempt, Failing Command!
(***):in RemoveCurrentCommand
(***):Current Command:{"Parameter1"=>"40", "Command"=>"SetCfg"}
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
Return code: 2
2	05/17/08 21:39:25	69 (spawning-device)	[1;33mDevice requests restart... count=1/50 dev=69[1;00m
Sat May 17 21:39:25 EDT 2008 Restart
========== NEW LOG SECTION ==========
1	05/17/08 21:39:34	69 (spawning-device)	[1;00mStarting... 1[1;00m
1	05/17/08 21:39:34	69 (spawning-device)	[1;00mFound /usr/pluto/bin/Generic_Serial_Device[1;00m
RCODE:
   0:require 'Ruby_Generic_Serial_Device'
   1:class Command < Ruby_Generic_Serial_Device::RubyCommandWrapper
   2:end
   3:class Device_69 < Ruby_Generic_Serial_Device::RubySerialIOWrapper
   4:#### 350 ####################################################################
   5:def cmd_350(cmd=nil)
   6:@returnParamArray.clear
   7:#### Written by Dan Damron
   8:#### #350 Process Incoming Data ####
   9:buff = ''
  10:#$recvbuff = ""
  11:while(true)
  12:buff=conn_.Recv(128,50)
  13:if(buff.length() == 0)
  14:break
  15:end
  16:$recvbuff = $recvbuff + buff
  17:end
  18:debugin($recvbuff)
  19:$recvbuff = plmparse($recvbuff)
  20:return @returnParamArray
  21:end
  22:#### 351 ####################################################################
  23:def cmd_351(cmd=nil)
  24:@returnParamArray.clear
  25:#### Written by Dan Damron
  26:#### #351 Process IDLE ####
  27:############################ RECEIVE Error Trap ###########################
  28:if  $cmdqueue.length != 0
  29:  if $resetNext != 0
  30:    log($red + 'receive timeout='+$resetNext.to_s + $grey)
  31:  end
  32:  if $cmdqueue.to_s == $savedstate
  33:    if $resetNext == $timeout
  34:	if $attempts == 2 then
  35:		#Third attempt.. fail the command.
  36:		log('Third attempt, Failing Command!')
  37:		$recvbuff = ''
  38:		$currentcmd = 0
  39:		$attempts = 0
  40:                #Here, I should remove the child
  41:                removecurrentcommand
  42:		
  43:		
  44:	else
  45:	      #Command has stalled. Reset wait flag and resend command.
  46:	      log('Command Stalled!  resetting and retrying')
  47:
  48:	      log('Current Command:' + $currentcmd.to_s)
  49:	      $recvbuff = ''
  50:	      $currentcmd = 0
  51:	      $attempts += 1
  52:	      #hack to reset the command
  53:	      if $cmdqueue[0]['Command'] == 'InsStdMsg'
  54:	        $cmdqueue[0]['Command'] = 'SndIns'
  55:	      end
  56:	end
  57:      $wAIT = false
  58:      $resetNext = 0
  59:      SndIns()
  60:    else
  61:      $resetNext +=1
  62:    end
  63:  else
  64:    $resetNext = 0
  65:    $savedstate = $cmdqueue.to_s
  66:    $attempts = 0
  67:  end
  68:end
  69:return @returnParamArray
  70:end
  71:#### 355 ####################################################################
  72:def cmd_355(cmd=nil)
  73:@returnParamArray.clear
  74:#### Written by Dan Damron
  75:#### #355 Process Initialize ####
  76:$red = 0x1b.chr + '[31m'
  77:$green = 0x1b.chr + '[32m'
  78:$yellow = 0x1b.chr + '[33m'
  79:$blue = 0x1b.chr + '[34m'
  80:$purple = 0x1b.chr + '[35m'
  81:$aqua = 0x1b.chr + '[36m'
  82:$grey = 0x1b.chr + '[37m'
  83:$redBack = 0x1b.chr + '[41m'
  84:$greenBack = 0x1b.chr + '[42m'
  85:$yellowBack = 0x1b.chr + '[43m'
  86:$blueBack = 0x1b.chr + '[44m'
  87:$purpleBack = 0x1b.chr + '[45m'
  88:$aquaBack = 0x1b.chr + '[46m'
  89:$greyBack = 0x1b.chr + '[47m'
  90:$blackBack = 0x1b.chr + '[48m'
  91:$remoteLinkRecord = ''
  92:#$remoteRecordReady = 0
  93:$configstring = ''
  94:$configparams = []
  95:$childdatabases = {}
  96:$newdevices = {}
  97:$state = {}
  98:$devicetemplate = {}
  99:$plmdatabase = []
 100:$plmlastrecord = true
 101:$log = ''
 102:$cmdTo = ''
 103:$cmdFrom = ''
 104:$cmdPriority = ''
 105:$cmdType = ''
 106:$cmdID = ''
 107:$cmdParams = {}
 108:$children = {}
 109:$recvbuff = ''
 110:$wAIT = false
 111:$currentCmd = {}
 112:$flagsBroadcastMessage = 128
 113:$flagsDirectMessage = 0
 114:$flagsAckDirectMessage = 32
 115:$flagsNackDirectMessage = 160
 116:$flagsGroupBroadcaseMessage = 192
 117:$flagsGroupCleanupDirectMessage = 64
 118:$flagsGroupAckDirectMessage =96
 119:$flagsGroupNackDirectMessage = 224
 120:$cmdqueue = []
 121:$currentcmd = 0 # to save state of command when receiving more data.
 122:$resetNext = 0 # used in Process IDLE to trap stalled responses.
 123:$savedstate = nil
 124:$dcequeue = []
 125:$rerun = false
 126:$reported = false
 127:$X10HouseCodes = {
 128:  '6', 'A',
 129:  'E', 'B', 
 130:  '2', 'C', 
 131:  'A', 'D', 
 132:  '1', 'E', 
 133:  '9', 'F', 
 134:  '5', 'G', 
 135:  'D', 'H', 
 136:  '7', 'I', 
 137:  'F', 'J', 
 138:  '3', 'K', 
 139:  'B', 'L', 
 140:  '0', 'M', 
 141:  '8', 'N', 
 142:  '4', 'O', 
 143:  'C', 'P'}
 144:$X10UnitCodes = {
 145:  '6', '1', 
 146:  'E', '2', 
 147:  '2', '3', 
 148:  'A', '4', 
 149:  '1', '5', 
 150:  '9', '6', 
 151:  '5', '7', 
 152:  'D', '8', 
 153:  '7', '9', 
 154:  'F', '10', 
 155:  '3', '11', 
 156:  'B', '12', 
 157:  '0', '13', 
 158:  '8', '14', 
 159:  '4', '15', 
 160:  'C', '16'}
 161:$X10CommandCodes = {
 162:  '6', 'All Lights Off', 
 163:  'E', 'Status = off',
 164:  '2', 'On', 
 165:  'A', 'Pre-Set Dim',
 166:  '1', 'All Lights On', 
 167:  '9', 'Hail Ack',
 168:  '5', 'Bright', 
 169:  'D', 'Status=on',
 170:  '7', 'Extended Code',
 171:  'F', 'Status Request',
 172:  '3', 'Off', 
 173:  'B', 'Pre-set Dim', 
 174:  '0', 'All Units Off', 
 175:  '8', 'Hail Request', 
 176:  '4', 'Dim', 
 177:  'C', 'Extended Data(analog)'}
 178:$responseString = '<' + '/' + 'Response>'
 179:
 180:############################## TEST Code below #################################
 181:# testing Reading a devices Database
 182:#	Common Insteon Device Memory Locations:
 183:#	0x0001 EESize - MSB of size of EEPROM chip in device
 184:#	0x0002 EEVersion - Firmware Revision number
 185:#	0x0020 EEOnLevel - Preset On-Level for lighting control
 186:#	0x0021 EERampRate - Ramp Rate for Lighting Control
 187:#	0x0030 EEX10BaseHouse - Base X10 House Code for device
 188:#	0x0031 EEX10BaseUnit - Base X10 Unit Code for device
 189:#	
 190:#	ALDB/L
 191:#	Starts at the top of external serial eeprom and grows downward.
 192:#	most limited-memory INSTEON devices, top of memory is 0x0FFF
 193:#	Each Record is 8 bytes long, so the first record starts at
 194:#	0x0FF8, the second record starts at 0x0FF0
 195:#
 196:#	ALDB/L Record Format:
 197:#	Record Control:	1 byte
 198:#	Group:		1 Byte
 199:#	ID:		3 Bytes HB MB LB
 200:#	Data1:		1 Byte Link-specific data (eg. On-Level)
 201:#	Data2:		1 Byte Link specific data (eg. Ramp Rates)
 202:#	Data3:		1 Byte Link specific data (normally unused)
 203:#
 204:#	Record Control Byte Bitmap:
 205:#	7: 1=Record in use, 0=Record is available
 206:#	6: 1=Controller of ID, 0=Responder of ID
 207:#	5: Product Dependant
 208:#	4: Product Dependant
 209:#	3: Product Dependant
 210:#	2: Product Dependant
 211:#	1: 1=Record has been used before, 0=High water mark (last record)
 212:#	0: Reserved
 213:#PLM cat 03 subcat 05
 214:# param = {'Command' => 'StLnk',
 215:#'Parameter1' => '01', #Link code 0x01=controller
 216:#'Parameter2' => '8F' #All Link Group
 217:#}
 218:#$cmdqueue << param
 219:# param = {'Command' => 'CancelLnk'}
 220:#$cmdqueue << param
 221:#SndIns()
 222:#
 223:#Lets try the Assign to ALL-Link Group ### SUCCESS!!!
 224:#param = {'Command' => 'SndIns',
 225:#'Parameter1' => '0A', #HB
 226:#'Parameter2' => '8F', #MB
 227:#'Parameter3' => '5A', #LB
 228:#'Parameter4' => '0F', #Flags
 229:#'Parameter5' => '01', #Cmd1
 230:#'Parameter6' => '8F' #Cmd2
 231:#}
 232:#
 233:#
 234:#param = {'Command' => 'MngLnk',
 235:#'Parameter1' => '00', # Control Code 
 236:#'Parameter2' => 'C2', #All Link Record Flags AKA Record Control Byte
 237:#'Parameter3' => '01', #All Link Group
 238:#'Parameter4' => '0A', #HB
 239:#'Parameter5' => '97', #MB
 240:#'Parameter6' => '0B', #LB
 241:#'Parameter7' => '01', #Link Data 1 ON-Level
 242:#'Parameter8' => '01', #Link Data 2 Ramp Rate
 243:#'Parameter9' => '00'} #Link Data 3 not used
 244:#$cmdqueue << param
 245:#
 246:#
 247:## Test Device: LampLinc ID:0A.97.0B
 248:# Assign Test device to Group
 249:#param = {'Command' => 'SndIns',
 250:#'Parameter1' => '0A', #HB
 251:#'Parameter2' => '97', #MB
 252:#'Parameter3' => '0B', #LB
 253:#'Parameter4' => '0F', #Flags
 254:#'Parameter5' => '01', #Cmd1
 255:#'Parameter6' => '01' #Cmd2
 256:#}
 257:#$cmdqueue << param
 258:#
 259:#
 260:############################## Real Code below #################################
 261:log('MY DEVICE:' + device_.devid_.to_s)
 262:
 263:#################################################
 264:#What I need to do and the order I need to do it.
 265:#done	read PLM database
 266:#done	get child devices
 267:#done	read child devices configuration
 268:#done1	all child devices in the PLM database?
 269:#done	if not, add their ID to the PLM database (new group numbers?)
 270:#	get the status of each (child) device
 271:#	compare the Database delta with the value stored in the configuration
 272:#		Different?
 273:#			read the child database 
 274:#			update configuration
 275:#			check devices links to see if any are new
 276:#			new link found, what to do?? send a message?
 277:#				create new child device?
 278:#				PING the new device and back to 1
 279:###
 280:# easiest way?.. create hash for PLM records
 281:# 		create hash for child devices is needed 
 282:#		(not needed if DBDelta is same)
 283:
 284:
 285:#reset the PLM
 286:$timeout = 3
 287:#param = {'Command' => 'RstPLM'}
 288:#$cmdqueue << param
 289:#SndIns()
 290:
 291:#put IM in monitor mode..
 292:param = {'Command' => 'SetCfg', 'Parameter1' => '40'}
 293:$cmdqueue << param
 294:SndIns()
 295:mainStart()
 296:
 297:
 298:
 299:
 300:##children found... get the status of each child...
 301:#$children.keys.each{|c|
 302:#	if c.length > 2 #filter out X10 for now
 303:#	  	#pack insteon message here, and send it out!
 304:#		# receive message in parsemessage and relay commands back in it.
 305:#		insteonID = c.chomp.split('.')
 306:#		param = {'Command' => 'SndIns', 
 307:#		'Parameter1' => insteonID[0], 
 308:#		'Parameter2' => insteonID[1],
 309:#		'Parameter3' => insteonID[2],
 310:#		'Parameter4' => '0F', #flags
 311:#		'Parameter5' => '19', #Status Request
 312:#		'Parameter6' => '00'} #not used.
 313:#		$cmdqueue << param
 314:## below gets the device Cat/SubCat/Firmware
 315:#		param = {'Command' => 'SndIns', 
 316:#		'Parameter1' => insteonID[0], 
 317:#		'Parameter2' => insteonID[1],
 318:#		'Parameter3' => insteonID[2],
 319:#		'Parameter4' => '0F', #flags
 320:#		'Parameter5' => '10', #PING
 321:#		'Parameter6' => '00'} #not used.
 322:#		$cmdqueue << param
 323:#
 324:#	end
 325:#	}
 326:return @returnParamArray
 327:end
 328:#### PRIVATE METHODS ####################################################################
 329:#### Written by Dan Damron
 330:#### #373 Private Method Listing ####
 331:
 332:def mainStart() ## This is called FIRST, reruns cannot call this.
 333:  #Register Message Interceptor
 334:  @interceptor = Command.new(device_.devid_, -1000, 1, 5, 37)
 335:  @interceptor.params_[2] = device_.devid_.to_s
 336:  SendCommand(@interceptor)
 337:  #Get the PLM Database
 338:  sendGetLink
 339:  #get Child devices
 340:  log('Finding Children..')
 341:  device_.childdevices_.each{|c| $children[device_.childdevices_[c.to_s.to_i].devdata_[12].chomp.lstrip.rstrip] = c.to_s.to_i}
 342:  $children.keys.each{|c| log(c + ' = ' + $children[c].to_s)
 343:  }
 344:  log('reading stored Child configuration:')
 345:
 346:  $children.keys.each{|c|
 347:    #Get each Childs configuration
 348:    $state[c] = 0
 349:    getdeviceconfig(c) #
 350:
 351:    #the above getdeviceconfig packs $configparams array
 352:    log('Configuration for ' + c + ' = ' + $configparams.inspect.to_s)
 353:  }
 354:
 355:  log('********************************************************')
 356:  #get childs actual configuation and status
 357:  $children.keys.each{|c| sendGetChildStatus(c)}
 358:  SndIns()
 359:
 360:end
 361:def mainRestart()
 362:  #We have hashes already set up.
 363:  $childdatabases.each_key{|@insteonID|
 364:    $state[@insteonID] = 0
 365:    sendGetChildStatus(@insteonID)}
 366:  SndIns()
 367:end
 368:
 369:def setdeviceconfig(insteonid, configurestring)
 370:  @deviceid = $children[insteonid]
 371:  @cmdfrom = device_.devid_
 372:  @cmdto = 4 #general info plugin
 373:  @priority = 1
 374:  @type=1 #command
 375:  @cmdid = 246
 376:
 377:  #set up command..
 378:  @cmd = Command.new(@cmdfrom, @cmdto, @priority, @type, @cmdid)
 379:  @cmd.params_[2] = @deviceid.to_s
 380:  @cmd.params_[52] = '59' # Configuration
 381:  @cmd.params_[5] = configurestring
 382:  SendCommand(@cmd)
 383:  #log('SetDeviceConfig:' + configurestring)
 384:  #log('Configuration Saved - will be available on next reload')
 385:end
 386:
 387:def getdeviceconfig(insteonid)
 388:  @deviceid = $children[insteonid]
 389:  @configstring = ''
 390:  begin
 391:    @configstring = device_.childdevices_[@deviceid].devdata_[59].to_s
 392:  rescue
 393:    log('Device ID = ' + @deviceid.to_s)
 394:    log($red + 'Error - Child has no configuration'+ $grey)
 395:    log('Setting initial value of "****************"')
 396:    setdeviceconfig(insteonid, ('*' * 16))
 397:    @configstring = '*' * 16
 398:    sendPing(insteonid)
 399:  end
 400:  if @configstring == ''
 401:    $configparams = ['****************']
 402:    log('CAUGHT BLANK RECORD')
 403:    setdeviceconfig(insteonid, ('*' * 16))
 404:    sendPing(insteonid)
 405:  else
 406:    $configparams = @configstring.unpack('a16' * (@configstring.length / 16))
 407:    $devicetemplate[insteonid] = getdevicetemplate($configparams[0][0..1], $configparams[0][2..3])
 408:  end
 409:  #log($yellow + 'getdeviceconfig:' + $configparams.inspect + $grey)
 410:  #add the configuration parameters to the child database
 411:  $childdatabases[insteonid] = $configparams
 412:  #get the device type
 413:
 414:end
 415:
 416:def sendGetLink()
 417:  #lets just see exactly what is in the PLM database
 418:  param = {'Command' => 'GetLnk'}
 419:  $cmdqueue << param
 420:  SndIns()
 421:end
 422:
 423:def sendGetNext()
 424:  param = {'Command' => 'GetNext'}
 425:  if $wAIT == true
 426:    $cmdqueue.insert(1, param)
 427:  else
 428:    $cmdqueue.insert(0,param)
 429:  end
 430:  SndIns()
 431:end
 432:
 433:def sendRemoteGetLink(insteonID)
 434:  # Read First ALDB Record
 435:  # a few variables need to be set up here..
 436:  $recordof = insteonID # save the insteon ID
 437:  insID = insteonID.chomp.split('.') # get the seperate bytes
 438:  $remoteDBOffsetMSB = 0x0F # initial offset
 439:  $remoteDBOffsetLSB = 0xF8 # initial LSB offset
 440:  param = {'Command' => 'SndIns',
 441:    'Parameter1' => insID[0], #HB
 442:    'Parameter2' => insID[1], #MB
 443:    'Parameter3' => insID[2], #LB
 444:    'Parameter4' => '0F', #Flags
 445:    'Parameter5' => '28', #Cmd1
 446:    'Parameter6' => "%X" %$remoteDBOffsetMSB #Cmd2 Set MSB Offset
 447:  }
 448:  $cmdqueue << param
 449:  # repeat last param for each byte to read (F8..FF)=first record
 450:
 451:  for x in 0..7
 452:    param = {'Command' => 'SndIns',
 453:      'Parameter1' => insID[0], #HB
 454:      'Parameter2' => insID[1], #MB
 455:      'Parameter3' => insID[2], #LB
 456:      'Parameter4' => '0F', #Flags
 457:      'Parameter5' => '2B', #Cmd1 Peek
 458:      'Parameter6' => "%X" %($remoteDBOffsetLSB + x) #Cmd2
 459:    }
 460:
 461:    $cmdqueue << param
 462:  end
 463:
 464:end
 465:
 466:def sendRemoteGetNext(insteonID)
 467:  insID = insteonID.chomp.split('.') # get the seperate bytes
 468:  ### Do NOT forget to check to see if we need to decrease the MSB
 469:
 470:  if $remoteDBOffsetLSB == 0x00
 471:    #OffsetMSB needs to be decreased, and LSB needs reset.
 472:    $remoteDBOffsetMSB = $remoteDBOffsetMSB - 1
 473:    $remoteDBOffsetLSN = 0xFF # the next line will decrease this by 8
 474:  end
 475:  # decrease DBOffsetLSB by 0x08
 476:  $remoteDBOffsetLSB = $remoteDBOffsetLSB - 0x08
 477:
 478:  for x in 0..7
 479:    param = {'Command' => 'SndIns',
 480:      'Parameter1' => insID[0], #HB
 481:      'Parameter2' => insID[1], #MB
 482:      'Parameter3' => insID[2], #LB
 483:      'Parameter4' => '0F', #Flags
 484:      'Parameter5' => '2B', #Cmd1 Peek
 485:      'Parameter6' => "%X" %($remoteDBOffsetLSB + x) #Cmd2
 486:    }
 487:    #log('sendRemoteGetNet:added to queue:' + param.inspect)
 488:    if $wAIT == true
 489:      $cmdqueue.insert(x + 1, param)
 490:    else
 491:      $cmdqueue.insert(x,param)
 492:    end
 493:
 494:
 495:  end
 496:end
 497:
 498:### Main command parsing routine is EZToDCE
 499:def EZToDCE(param)
 500:  #param contains a hash of EZBridge command structure
 501:  #log($blue + 'Queue:' + $cmdqueue[0].inspect + $grey)
 502:  #log($blue + 'Param:' + param.inspect + $grey)
 503:  #log($blue + 'currentcmd:' + $currentcmd.to_s + $grey)
 504:  #checkWait(param)
 505:  case param['Response']
 506:    # Standard RESPONSES (to commands)
 507:  when 'GetRevision' # Special Response
 508:    log('-----|---------GetRevision:' + param['Parameter1'])
 509:
 510:  when 'GetLatLong' # Special Response
 511:    log('-----|---------GetLatLong: Lat=' + param['Lat'] + ', Long=' + param['Long'])
 512:
 513:  when 'SetLatLong'
 514:    if param['Parameter1'] == 'True' then
 515:      log('-----|---------SetLatLong: Ok')
 516:    else
 517:      log('-----X---------SetLatLong: FAILED!')
 518:    end
 519:  when 'SetPasswd'
 520:
 521:  when 'SetTimeZone'
 522:
 523:  when 'GetClock' # Special Response
 524:
 525:  when 'SetClock'
 526:
 527:  when 'SetNTPServer'
 528:
 529:  when 'Upgrade'
 530:
 531:  when 'NetCfg'
 532:
 533:  when 'Reset'
 534:    #Reset Response
 535:
 536:    cmdComplete
 537:    SndIns()
 538:  when 'LstTimers' # Special Response
 539:
 540:
 541:  when 'ClrTimers'
 542:
 543:  when 'AddTimer'
 544:
 545:  when 'GetTimer' # Special Response
 546:
 547:  when 'SetTimer'
 548:
 549:  when 'DelTimer'
 550:
 551:  when 'GetVersion' # Special Response
 552:
 553:  when 'SndGrp'
 554:
 555:  when 'SndIns' # response from SndIns
 556:    ### BUG FOUND ### When the EZBridge receives a command from an EXTERNAL source
 557:    ### ie not from this device, cmdqueue will be nil, and the code below
 558:    ### fails. Have to check against that.
 559:    if $cmdqueue.length > 0
 560:      #First, check the response to make sure the command made it ok.
 561:      if param['Parameter9'].to_i == 6 #Ack received
 562:        #log('Sending to ProcessACK')
 563:        processACK(param)
 564:      else # NACK received - command failed.
 565:        log('Command NACKED')
 566:      end
 567:    else
 568:      #Response received for another device.
 569:      log('Response detected for a command that was not sent by me')
 570:    end
 571:  when 'SndX10'
 572:    log('Response detected for SndX10')
 573:    if param['Parameter5'].to_i == 6 #ack
 574:      log('X10 Command Successfull')
 575:
 576:      cmdComplete
 577:      SndIns()
 578:    else
 579:      log('X10 Command FAILED')
 580:      cmdComplete
 581:      SndIns()
 582:
 583:    end
 584:  when 'StLnk'
 585:
 586:  when 'CancelLnk'
 587:
 588:  when 'SetDev'
 589:
 590:  when 'RstPLM'
 591:    #Reset Response
 592:    $timeout = 1
 593:    cmdComplete
 594:    SndIns()
 595:
 596:  when 'GetLnk'
 597:    if param['Parameter3'].to_i == 6 #ack
 598:      log('GetLnk ACKED')
 599:      #if we get this, we should get a AllLink Record Response next
 600:    else
 601:      log('GetLnk NACKED')
 602:      # The PLM is BLANK
 603:      #have to add records to the PLM here.
 604:      cmdComplete
 605:      ### FINISHED WITH GetLnk
 606:      checkChildRecordsinPLM()
 607:      SndIns()
 608:    end
 609:  when 'GetNext'
 610:    if param['Parameter3'].to_i == 6 #ack
 611:      log('sendGetNext ACKED')
 612:      #if we get this, we should get a AllLink Record Response next
 613:    else
 614:      log('sendGetNext NACKED')
 615:      #we get this when there are no more records
 616:      cmdComplete
 617:      #FINISHED with GetNext
 618:      # if we are here, we are in config mode
 619:      # so, next is to check to make sure the
 620:      # childrens insteon ID is in the PLM
 621:      checkChildRecordsinPLM()
 622:      # now, to make sure that all the records in the PLM are sensed as children
 623:      
 624:      SndIns()
 625:    end
 626:
 627:  when 'SetCfg' # response from Setcfg command
 628:    if param['Parameter4'].to_i == 6 #ack
 629:      log('SetCfg Completed')
 630:      cmdComplete
 631:      SndIns()
 632:    else
 633:      log('SetCfg NACKED')
 634:    end
 635:  when 'GetLnkData'
 636:
 637:  when 'LEDON'
 638:
 639:  when 'LEDOFF'
 640:
 641:  when 'MngLnk'
 642:    if param['Parameter12'].to_i == 6
 643:      log('MngLnk => ACK')
 644:    else
 645:      log('MngLnk => NACK')
 646:    end
 647:    cmdComplete
 648:    SndIns()
 649:
 650:  when 'GetCfg' # Special Response
 651:
 652:  when 'LstMacros' # Special Response
 653:
 654:  when 'ClrMacros'
 655:
 656:  when 'AddMacro'
 657:
 658:  when 'GetMacro' # Special Response
 659:
 660:  when 'SetMacro'
 661:
 662:  when 'DelMacro'
 663:
 664:  when 'LstDevices' # Special Response
 665:
 666:  when 'ClrDevices'
 667:
 668:  when 'AddDevice'
 669:
 670:  when 'GetDevice' # Special Response
 671:
 672:  when 'SetDevice'
 673:
 674:  when 'DelDevice'
 675:
 676:  when 'LstZones'
 677:
 678:  when 'ClrZones'
 679:
 680:  when 'AddZone'
 681:
 682:  when 'GetZone'
 683:
 684:  when 'SetZone'
 685:
 686:  when 'DelZone'
 687:
 688:  when 'AddDevZone'
 689:
 690:  when 'DelDevZone'
 691:
 692:    # Response Messages
 693:  when 'InsExtMsg'
 694:
 695:  when 'InsStdMsg'
 696:    case $currentcmd # if this msg is part of a response, the Insteon Cmd1 will be saved here.
 697:    when 0x0
 698:      #log('REROUTING to processExternalCommand(param)')
 699:      processExternalCommand(param)
 700:    when 0x1 #Assign to Group
 701:      ### This is a broadcast message sent
 702:      # from a PING command
 703:      # or from a StartLink...
 704:      log('Caught Assign to Group Message from Device')
 705:      ### BUG HERE
 706:      #have to check flags to see if this is a broadcast message
 707:      log('Checking if this is a broadcast message')
 708:      log('Flags:' + param['Parameter9'])
 709:      if (param['Parameter9'].hex & 0x80) == 0x80
 710:        log('Message IS BROADCAST')
 711:        #recvComplete
 712:        processDeviceInfo(param)
 713:
 714:        # check to see if current cmd is for this broadcast..
 715:        log('Current Command:' + $cmdqueue[0]['Parameter5'])
 716:        if $cmdqueue[0]['Parameter5'] == '10'
 717:          #log('Clearing PING Command')
 718:          $currentcmd = 0
 719:          cmdComplete
 720:          SndIns()
 721:        else
 722:          log('CURRENT CMD IS NOT PING - NOT CLEARING')
 723:        end
 724:
 725:      else
 726:        log('Message is NOT Broadcast')
 727:      end
 728:    when 0x2 #Delete from Group
 729:    when 0x10 # PING
 730:      #this is where I catch the InsStdMsg for ping.
 731:      log('Caught PING Message from Device')
 732:      $currentcmd = 1
 733:
 734:    when 0x11 # ON
 735:      log('Caught Insteon ON from INTERNAL source')
 736:      insHb = param['Parameter3'] # From
 737:      insMb = param['Parameter4']
 738:      insLb = param['Parameter5']
 739:
 740:      insID = insHb + "." + insMb + "." + insLb
 741:      myDevFrom = $children[insID]
 742:      log('Current DIM level:' + param['Parameter11'])
 743:
 744:      reportStatus(myDevFrom, hextopercent(param['Parameter11']))
 745:
 746:      $currentcmd = 0
 747:      cmdComplete
 748:
 749:      SndIns()
 750:    when 0x13 # OFF
 751:      insHb = param['Parameter3'] # From
 752:      insMb = param['Parameter4']
 753:      insLb = param['Parameter5']
 754:      insID = insHb + "." + insMb + "." + insLb
 755:      myDevFrom = $children[insID]
 756:      reportStatus(myDevFrom, 0)
 757:
 758:      $currentcmd = 0
 759:      cmdComplete
 760:      #log('EVENT and state SENT!!!.48:[10]=0')
 761:      SndIns()
 762:    when 0x19 # Status Report
 763:      # now to clear the currentcmd and remove command from the queue
 764:      $currentcmd = 0
 765:      cmdComplete
 766:
 767:      log('Processing 0x19 Status Report')
 768:      #This is where I get the database delta (in cmd1)
 769:      insHb = param['Parameter3'] # From
 770:      insMb = param['Parameter4']
 771:      insLb = param['Parameter5']
 772:      insID = insHb + "." + insMb + "." + insLb
 773:      #First, to compare the DB Delta with current config.
 774:      #Database Delta...
 775:      delta = param['Parameter10'].to_s
 776:      log($blue + 'Database Delta=' + delta + $grey)
 777:      log($blue + 'Configuration is:' + getdeltafromconfig(insID) + $grey)
 778:      if delta == getdeltafromconfig(insID)
 779:        if $children[insID] != nil
 780:          myDevFrom = $children[insID]
 781:          myDevTo = -1000 #DCE Router
 782:          myPriority = 1
 783:          myType = 2 #Event
 784:
 785:          #Send an EVENT to report STATE ONLY if database has not changed
 786:          # AND child exists in pluto
 787:          reportStatus(myDevFrom, hextopercent(param['Parameter11']))
 788:        end
 789:      else
 790:        log('Databse CHANGED -getting remote database')
 791:        #here, I have to WIPE the databse
 792:        # to prepare it for new data
 793:        ### here is where the DAMN CONFIG was reset!!!
 794:        oldconfigstring = $childdatabases[insID][0]
 795:        $childdatabases[insID] = [oldconfigstring]
 796:        log('Setting Database Config')
 797:        $childdatabases[insID][0][6..7] = delta
 798:        savechilddatabases(insID)
 799:        sendRemoteGetLink(insID)
 800:      end
 801:      # finally, to check execute next command...
 802:      SndIns()
 803:    when 0x28 # Set Address MSB
 804:      log('Received SET Address MSB from remote device')
 805:      $currentcmd = 0
 806:      $remoteLinkRecord = ''
 807:      cmdComplete
 808:      SndIns()
 809:    when 0x2B # peek
 810:      ### BUG HERE... have to verify response is a PEEK command
 811:      #response command is stored in parameter10
 812:      if param['Parameter10'].hex == 0x2B # this is the peek command
 813:        cmdComplete
 814:        log('Received PEEK from remote Device! DATA=' + param['Parameter11'])
 815:        checkPeekData(param)
 816:        $currentcmd = 0
 817:        SndIns()
 818:      else
 819:        log('Waiting for remote PEEK response, but got :' + param['Parameter10'])
 820:      end
 821:    else
 822:    end
 823:
 824:  when 'X10Msg'
 825:    log($purple + 'X10 Message Received' + $grey)
 826:    if param['Parameter4'].hex == 0x00
 827:      log('This byte is a House/Unit Code')
 828:      hn = param['Parameter3'][0].chr
 829:      ln = param['Parameter3'][1].chr
 830:      $x10byte1 = $X10HouseCodes[hn]
 831:      $x10byte1 += $X10UnitCodes[ln]
 832:      log('Translated X10 House/Unit Code:' + $x10byte1)
 833:    else
 834:      log('This byte is a House/Command Code')
 835:      hn = param['Parameter3'][0].chr
 836:      ln = param['Parameter3'][1].chr
 837:      $x10byte2 = $X10HouseCodes[hn]
 838:      $x10byte2 += $X10CommandCodes[ln]
 839:      log('Translated X10 Command Code:' + $x10byte2)
 840:      log('X10 Command ready to send:' + $x10byte1 + ' ' + $x10byte2)
 841:      case $X10CommandCodes[ln]
 842:      when 'On'
 843:        #Send ON to lmnce
 844:        if $children[$x10byte1] == nil
 845:          log('I do not control this X10 device')
 846:        else
 847:          cmd = Command.new($children[$x10byte1].to_i, -1000, 1, 1, 192)
 848:          cmd.params_[120] = "1"
 849:          SendCommand(cmd)
 850:        end
 851:      when 'Off'
 852:        #Send OFF to lmnce
 853:        if $children[$x10byte1] == nil
 854:          log('I do not control this X10 device')
 855:        else
 856:          cmd = Command.new($children[$x10byte1].to_i, -1000, 1, 1, 193)
 857:          cmd.params_[120] = "1"
 858:          SendCommand(cmd)
 859:        end
 860:      when 'Bright'
 861:        if $children[$x10byte1] == nil
 862:          log('I do not control this X10 device')
 863:        else
 864:          #send a command to set the state + 1
 865:          @curstate = ($state[$x10byte1] / 100) * 32 #get equal 32 steps
 866:          $state[$x10byte1] = ((@curstate + 1) / 32) * 100
 867:          cmd = Command.new($children[$x10byte1].to_i, -1000, 1, 1, 184)
 868:          cmd.params_[76] = $state[$x10byte1].to_s
 869:          cmd.params_[120] = "1"
 870:          SendCommand(cmd)
 871:          #$state[$x10byte1] = ($state[$x10byte1] / 100) * 32
 872:        end
 873:      when 'Dim'
 874:        @curstate = ($state[$x10byte1] / 100) * 32 #get equal 32 steps
 875:        $state[$x10byte1] = ((@curstate - 1) / 32) * 100
 876:        cmd = Command.new($children[$x10byte1].to_i, -1000, 1, 1, 184)
 877:        cmd.params_[76] = $state[$x10byte1].to_s
 878:        cmd.params_[120] = "1"
 879:        SendCommand(cmd)
 880:      when 'All Lights Off'
 881:        log('ALL Lights OFF Command not implemented')
 882:      when 'All Lights On'
 883:        log('All Lights ON Command not implemented')
 884:      when 'Status Request'
 885:        log('Status Request Command not implemented')
 886:      when 'Hail Ack'
 887:        log('Hail Ack Command not implemented')
 888:      end
 889:
 890:    end
 891:  when 'InsLnkSts'
 892:    log('InsLnkSts Received')
 893:
 894:  when 'BtnRpt'
 895:    log('Button Report Received')
 896:  when 'UsrRst'
 897:    log('User Reset Response Received')
 898:  when 'GrpEvntRpt'
 899:    log('Group Event Report Received')
 900:
 901:  when 'LnkData'
 902:    processLnkData(param)
 903:    # Other messages
 904:  when 'PLMTimeout'
 905:    log('PLM Timeout detected.. resetting EZBridge')
 906:    resetcmd = {'Command' => 'Reset'}
 907:    if $wAIT == true
 908:      $cmdqueue.insert(1, resetcmd)
 909:    else
 910:      $cmdqueue.insert(0,resetcmd)
 911:    end
 912:    sleep 15
 913:    $wAIT = false
 914:    SndIns()
 915:  when 'PLMEchoError' # Have not seen this since a1.23
 916:    # error sending command to PLM, reset command and try again
 917:    log('-----XXXXXXX' + param['Response'])
 918:    resetcmd = {'Command' => 'Reset'}
 919:    if $wAIT == true
 920:      $cmdqueue.insert(1, resetcmd)
 921:    else
 922:      $cmdqueue.insert(0,resetcmd)
 923:    end
 924:
 925:    sleep 15
 926:    $wAIT = false
 927:    SndIns()
 928:  when 'LongAck'
 929:    log('-----XXXXXXX' + param['Response'])
 930:    # Error - seems to show up after PLMEchoError
 931:    resetcmd = {'Command' => 'Reset'}
 932:    if $wAIT == true
 933:      $cmdqueue.insert(1, resetcmd)
 934:    else
 935:      $cmdqueue.insert(0,resetcmd)
 936:    end
 937:    sleep 15
 938:    $wAIT = false
 939:    SndIns()
 940:  else
 941:    log('-----XXXXXXX UNKNOWN Response Received')
 942:  end
 943:
 944:end
 945:
 946:### Support routine for EZToDCE
 947:def processLnkData(param)
 948:  #Caught a LnkData Response
 949:  log('LnkData Message Received')
 950:  log(param.inspect)
 951:  if param['Parameter6'] == '00' and param['Parameter7'] == '00'
 952:    log('FOUND X10 DEVICE!!!')
 953:    insteonID = padhex(param['Parameter5'])
 954:  else
 955:    insteonID = padhex(param['Parameter5']) + '.' + padhex(param['Parameter6']) + '.' + padhex(param['Parameter7'])
 956:  end
 957:  group = param['Parameter4']
 958:  recflags = param['Parameter3']
 959:  lnkdata1 = param['Parameter8']
 960:  lnkdata2 = param['Parameter9']
 961:  lnkdata3 = param['Parameter10']
 962:  #pack string to store for PLM Database
 963:  @currentrecord = recflags + group
 964:  @currentrecord += param['Parameter5'] + param['Parameter6'] + param['Parameter7']
 965:  @currentrecord += lnkdata1 + lnkdata2 + lnkdata3
 966:
 967:  #Add to plmdatabase
 968:  $plmdatabase << @currentrecord
 969:  log('record Flags:' + recflags)
 970:  #log('PLM database=' +$plmdatabase.inspect)
 971:  if (recflags[0] & 0x80) == 0x80 # Record is in use if true
 972:  end
 973:  if (recflags[0] & 0x40) == 0x40 # Controller if true
 974:    log('Controller')
 975:  else
 976:    log('Responder')
 977:  end
 978:
 979:  log('Insteon ID:' + insteonID + ', Group:' + group)
 980:
 981:  cmdComplete
 982:  sendGetNext()
 983:
 984:end
 985:### Support Routine for EZToDCE
 986:def processExternalCommand(param)
 987:  #there is no current command
 988:  # THIS IS COMING FROM AN OUTSIDE SOURCE
 989:  #EG: Manually turning Light Switch On/Off
 990:  # process this command.
 991:  # Note, this is a standard message
 992:  ### have to check here if child is mine!
 993:
 994:  # This is where I have to check for a broadcast command..
 995:  #if so, search the child databases for responders,
 996:  #and fire events for each responder.
 997:  #Message flag is in parameter9 Group command 0xCx (All-Link Broadcast Message Pg 42.)
 998:  #Group is in parameter8
 999:  #From InsteonID is parameters 3, 4, 5
1000:  if (param['Parameter9'].hex & 0xC0) == 0xC0 # Message is Broadcast
1001:    log('Rerouting to processBroadcastMessage')
1002:    processBroadcastMessage(param)
1003:  else
1004:    log('Process External Command:')
1005:    log('Param:' + param.inspect)
1006:
1007:    # there is no ack here. Simply Send COMMANDS back to DCE
1008:    # and Complete the recv..
1009:    case param['Parameter10'].hex #this is the command
1010:    when 0x01 #Assign to Group
1011:      log('Caught EXTERNAL Assign to Group')
1012:      processDeviceInfo(param)
1013:      recvComplete
1014:    when 0x02 #Delete from Group
1015:      log('Caught EXTERNAL Delete from Group')
1016:      recvComplete
1017:    when 0x10 # PING
1018:      log('Caught EXTERNAL Insteon PING result')
1019:      recvComplete
1020:
1021:
1022:    when 0x11 #ON
1023:      log('Caught EXTERNAL Insteon ON command result')
1024:      #on level is in cmd2
1025:      insHb = param['Parameter3'] # From
1026:      insMb = param['Parameter4']
1027:      insLb = param['Parameter5']
1028:      insID = insHb + "." + insMb + "." + insLb
1029:      log('From:' +insID)
1030:      log('Device:' + $children[insID].to_s)
1031:      myDevFrom = $children[insID]
1032:      # check to see if I own child
1033:      if myDevFrom == nil
1034:        log('I do not control this device.')
1035:      else
1036:        reportStatus(myDevFrom, hextopercent(param['Parameter11']))
1037:        $currentcmd = 0
1038:      end
1039:      recvComplete
1040:
1041:
1042:
1043:    when 0x13 #OFF
1044:      log('Caught EXTERNAL Insteon OFF result')
1045:      #on level is in cmd2
1046:      insHb = param['Parameter3'] # From
1047:      insMb = param['Parameter4']
1048:      insLb = param['Parameter5']
1049:      insID = insHb + "." + insMb + "." + insLb
1050:      myDevFrom = $children[insID]
1051:      if myDevFrom == nil
1052:        log('I do not control this device.')
1053:      else
1054:
1055:        reportStatus(myDevFrom, 0)
1056:
1057:        $currentcmd = 0
1058:        #log('EVENT and state SENT!!!.48:[10]=0')
1059:      end
1060:      recvComplete
1061:    when 0x15; log('Caught EXTERNAL Insteon Brighten Result')
1062:    when 0x16; log('Caught EXTERNAL Insteon DIM Result')
1063:    when 0x24; log('Caught EXTERNAL Insteon DO EE READ')
1064:    when 0x28; log('Caught EXTERNAL Insteon SET ADDRESS MSB')
1065:    when 0x29; log('Caught EXTERNAL Insteon POKE')
1066:    when 0x2A; log('Caught EXTERNAL Insteon POKE EXTENDED')
1067:    when 0x2B; log('Caught EXTERNAL Insteon PEEK')
1068:    when 0x2C; log('Caught EXTERNAL Insteon PEEK INTERNAL')
1069:    when 0x2D; log('Caught EXTERNAL Insteon POKE INTERNAL')
1070:    else
1071:      log('Unknown EXTERNAL Insteon Command.')
1072:    end
1073:  end
1074:end
1075:### Support Routine for EZToDCE
1076:def processACK(param)
1077:  #log('In ProcessACK: Param7:' + param['Parameter7'])
1078:  #log('CurrentCmd=' + $currentcmd.to_s)
1079:  case param['Parameter7'].hex #Received an ack to THIS command
1080:  when 0x1 #Assign to Group
1081:    log('Got Assign to Group ACK')
1082:    $currentcmd = 0x01
1083:    $cmdqueue[0]['Command'] = 'InsStdMsg'
1084:    #processDeviceInfo(param)
1085:    #cmdComplete
1086:  when 0x2 #Delete from Group
1087:  when 0x10 # PING
1088:    log('Got PING ACK')
1089:    #cmdComplete
1090:    $currentcmd = 0x1
1091:    $cmdqueue[0]['Command'] = 'InsStdMsg'
1092:  when 0x11 #ON
1093:    $currentcmd = 0x11
1094:    $cmdqueue[0]['Command'] = 'InsStdMsg'
1095:  when 0x13 #OFF
1096:    $currentcmd = 0x13
1097:    $cmdqueue[0]['Command'] = 'InsStdMsg'
1098:  when 0x15 #Bright
1099:    $currentcmd = 0x15
1100:    $cmdqueue[0]['Command'] = 'InsStdMsg'
1101:  when 0x16 #DIM
1102:    $currentcmd = 0x16
1103:    $cmdqueue[0]['Command'] = 'InsStdMsg'
1104:  when 0x17 #Start Manual Change
1105:  when 0x18 #Stop Manual Change
1106:  when 0x19 #Status Request
1107:    # Status Request Acked - get ready for InsStdMsg
1108:    $currentcmd = 0x19
1109:    # change cmd to reflect InsStdMsg
1110:    $cmdqueue[0]['Command'] = 'InsStdMsg'
1111:  when 0x24
1112:    log('Caught ACK for Insteon DO EE READ')
1113:    $currentcmd = 0x24
1114:    $cmdqueue[0]['Command'] = 'InsStdMsg'
1115:  when 0x28
1116:    log('Caught ACK for Insteon SET ADDRESS MSB')
1117:    $currentcmd = 0x28
1118:    $cmdqueue[0]['Command'] = 'InsStdMsg'
1119:
1120:  when 0x29
1121:    log('Caught ACK for Insteon POKE')
1122:    $currentcmd = 0x29
1123:    $cmdqueue[0]['Command'] = 'InsStdMsg'
1124:
1125:  when 0x2A
1126:    log('Caught ACK for Insteon POKE EXTENDED')
1127:    $currentcmd = 0x2A
1128:    $cmdqueue[0]['Command'] = 'InsStdMsg'
1129:
1130:  when 0x2B
1131:    #log('Caught ACK for Insteon PEEK')
1132:    $currentcmd = 0x2B
1133:    $cmdqueue[0]['Command'] = 'InsStdMsg'
1134:
1135:  when 0x2C
1136:    log('Caught ACK for Insteon PEEK INTERNAL')
1137:    $currentcmd = 0x2C
1138:    $cmdqueue[0]['Command'] = 'InsStdMsg'
1139:
1140:  when 0x2D
1141:    log('Caught ACK for Insteon POKE INTERNAL')
1142:    $currentcmd = 0x2D
1143:    $cmdqueue[0]['Command'] = 'InsStdMsg'
1144:
1145:  else
1146:    log('Unknown Insteon Cmd1')
1147:  end
1148:end
1149:
1150:
1151:def checkPeekData(param)
1152:
1153:  $remoteLinkRecord += param['Parameter11'].hex.chr
1154:  log('CURRENT REMOTE RECORD IS:')
1155:  debug($remoteLinkRecord)
1156:  if $remoteLinkRecord.length == 8
1157:    log('REMOTE RECORD COMPLETE!')
1158:    processRemoteRecord(param)
1159:    $remoteLinkRecord = ''
1160:  end
1161:end
1162:
1163:
1164:def processRemoteRecord(param)
1165:  #have to find MY address
1166:  insHb = param['Parameter3'] # From
1167:  insMb = param['Parameter4']
1168:  insLb = param['Parameter5']
1169:  insID = padhex(insHb) + "." + padhex(insMb) + "." + padhex(insLb)
1170:
1171:  log('Processing remote Record below:')
1172:
1173:  @flags = "\nFrom Device:" + insID + "\nFlags:\n"
1174:
1175:  if ($remoteLinkRecord[0] & 0x02) == 0x02 # High water mark
1176:    @flags += "Not the last record\n"
1177:  else
1178:    @flags += "This IS the last record\n"
1179:  end
1180:
1181:  if ($remoteLinkRecord[0] & 0x80) == 0x80 # Record is in use
1182:    @flags += "Record In Use\n"
1183:    if ($remoteLinkRecord[0] & 0x40) == 0x40 # Controller/Responder
1184:      @flags += "I am a Controller of "
1185:    else
1186:      @flags += "I am a Responder of "
1187:    end
1188:    @insteonID = padhex("%X" %$remoteLinkRecord[2]) + '.'
1189:    @insteonID += padhex("%X" %$remoteLinkRecord[3]) + '.'
1190:    @insteonID += padhex("%X" %$remoteLinkRecord[4])
1191:
1192:    @group = "%X" %$remoteLinkRecord[1]
1193:    @flags += @insteonID + " Group:" + @group
1194:    @work = padhex("%X" %$remoteLinkRecord[0]) #Control byte
1195:    @work += padhex("%X" %$remoteLinkRecord[1]) # Group
1196:    @work += padhex("%X" %$remoteLinkRecord[2]) # ID HB
1197:    @work += padhex("%X" %$remoteLinkRecord[3]) # ID MB
1198:    @work += padhex("%X" %$remoteLinkRecord[4]) # ID LB
1199:    @work += padhex("%X" %$remoteLinkRecord[5]) # Data1
1200:    @work += padhex("%X" %$remoteLinkRecord[6]) # Data2
1201:    @work += padhex("%X" %$remoteLinkRecord[7]) # Data3
1202:    log('adding to:' + insID)
1203:    log('Value:' + @work)
1204:    $childdatabases[insID] << @work #add it to the database
1205:    # log('Current Database:' + $childdatabases.inspect)
1206:    #now to save the database to configuration.
1207:    savechilddatabases(insID)
1208:    # Now to check to see if the child exists as a record
1209:    if $childdatabases[@insteonID] == nil
1210:      log('InsteonID is NEW, adding Child database entry')
1211:      $childdatabases[@insteonID] = ['****************']
1212:      $rerun = true
1213:      sendAddtoPLM(@insteonID)
1214:      sendPing(@insteonID)
1215:    else
1216:      log('InsteonID:' + @insteonID.to_s + 'seems to exist in child databases')
1217:      log('CDB:' + $childdatabases.inspect)
1218:
1219:    end
1220:  else
1221:    @flags += "Record NOT in use\n"
1222:  end
1223:  log($aqua + @flags + $grey)
1224:  log2(@flags)
1225:  if ($remoteLinkRecord[0] & 0x02) == 0x02
1226:    sendRemoteGetNext(insID)
1227:  end
1228:end
1229:
1230:def savechilddatabases(insteonID)
1231:  #This takes the $childdatabase hash+array and encodes it to
1232:  # save it as a string.
1233:  @work = ''
1234:  #log($yellow + 'SaveChildDatabases::nitems:' + $childdatabases[insteonID].nitems.to_s)
1235:  #log($childdatabases[insteonID].inspect + $grey)
1236:  $childdatabases[insteonID].each{|record|
1237:    @work += record
1238:  }
1239:
1240:  #now to save the string...
1241:  setdeviceconfig(insteonID, @work)
1242:
1243:end
1244:def sendPing(insteonID)
1245:  insID = insteonID.split('.')
1246:  param = {'Command' => 'SndIns',
1247:    'Parameter1' => insID[0],
1248:    'Parameter2' => insID[1],
1249:    'Parameter3' => insID[2],
1250:    'Parameter4' => '0F',
1251:    'Parameter5' => '10', #ID Request
1252:    'Parameter6' => '00'}
1253:  $cmdqueue << param
1254:  log('PING Sent!')
1255:end
1256:
1257:def getdevicetemplate(cat, subcat)
1258:
1259:  log('Entered getdevicetemplate, Cat=' + cat.to_s + ', subcat = ' + subcat.to_s)
1260:  @templid = 0
1261:  case cat.hex
1262:  when 0x0 # Generalized Controllers
1263:    case subcat.hex
1264:    when 0x04; log('Found ControLinc [2430]')
1265:    when 0x05; log('Found RemoteLinc [2440]')
1266:    when 0x06; log('Found Icon Tabletop Controller [2830]')
1267:    when 0x09; log('Found SignaLinc RF Signal Enhancer [2442]')
1268:    when 0x0A; log('Found Balboa Instruments Poolux LCD Controller')
1269:    when 0x0B; log('Found Access Point [2443]')
1270:    when 0x0C; log('Found IES Color Touchscreen')
1271:    end
1272:  when 0x01 # Dimmable Lighting Control
1273:    # all these devices are associated with Template 38
1274:    # Light Switch (dimmable)
1275:    @templid = 38
1276:    case subcat.hex
1277:    when 0x00; log('Found LampLinc V2 [2456D3]')
1278:    when 0x01; log('Found SwitchLinc V2 Dimmer 600W [2476D]')
1279:    when 0x02; log('Found In-LineLinc Dimmer [2475D]')
1280:    when 0x03; log('Found Icon Switch Dimmer [2876D]')
1281:    when 0x04; log('Found SwitchLinc V2 Dimmer 1000W [2476DH]')
1282:    when 0x06; log('Found LampLinc 2-pin [2456D2]')
1283:    when 0x07; log('Found Icon LampLinc V2 2-pin [2456D2]')
1284:    when 0x09; log('Found KeypadLinc Dimmer [2486D]')
1285:    when 0x0A; log('Found Icon In-Wall Controller [2886D]')
1286:    when 0x0D; log('Found SocketLinc [2454D]')
1287:    when 0x13; log('Found Icon SwitchLinc Dimmer for Lixar/Bell Canada [2676D-B]')
1288:    when 0x17; log('Found ToggleLinc Dimmer [2466D]')
1289:    end
1290:  when 0x02 # Switched Lighting Control
1291:    # all these devices are associated with Template 37
1292:    # Light Switch (ON/OFF)
1293:    @templid = 37
1294:    case subcat.hex
1295:
1296:    when 0x09; log('Found ApplianceLinc [2456S3]')
1297:    when 0x0A; log('Found SwitchLinc Relay [2476S]')
1298:    when 0x0B; log('Found Icon On Off Switch [2876S]')
1299:    when 0x0C; log('Found Icon Appliance Adapter [2856S3]')
1300:    when 0x0D; log('Found ToggleLinc Relay [2466S]')
1301:    when 0x0E; log('Found Switchlinc Relay Countdown Timer [2476ST]')
1302:    when 0x10; log('Found In-LineLinc Relay [2475D]')
1303:    when 0x13; log('Found Icon SwitchLinc Relay for Lixar/Bell Canada [2676R-B]')
1304:    end
1305:  when 0x03 # Network Bridges
1306:    case subcat.hex
1307:    when 0x01; log('Found PowerLinc Serial [2414S]')
1308:    when 0x02; log('Found PowerLinc USB [2414U]')
1309:    when 0x03; log('Found Icon PowerLinc Serial [2814S]')
1310:    when 0x04; log('Found Icon PowerLinc USB [2814U]')
1311:    when 0x05; log('Found Smartlabs Power Line Modem Serial [2412S]')
1312:    end
1313:  when 0x04 # Irrigation Control
1314:    # all these devices are associated with Template 1780
1315:    # Standard Irrigation Sprinkler
1316:    @templid = 1780
1317:    case subcat.hex
1318:
1319:    when 0x00; log('Found Simplehomenet EZRain1 Sprinkler Controller')
1320:    end
1321:  when 0x05 # Climate Control
1322:    case subcat.hex
1323:    when 0x00; log('Found Broan SMSC080 Exhaust Fan')
1324:    when 0x01; log('Found Simplehomenet EZTherm')
1325:    when 0x02; log('Found Broan SMSC110 Exhaust Fan')
1326:    when 0x03; log('Found Venstar RF Thermostat Module')
1327:    when 0x04; log('Found Simplehomenet EZStat Thermostat')
1328:    end
1329:  when 0x06 # Pool and Spa Control
1330:    case subcat.hex
1331:    when 0x00; log('Found Simplehomenet EZPool')
1332:    end
1333:  when 0x07 # Sensors and Actuators
1334:    case subcat.hex
1335:    when 0x00
1336:    end
1337:  when 0x08 # Home Entertainment
1338:    case subcat.hex
1339:    when 0x00
1340:    end
1341:  when 0x09 # Energy Management
1342:    case subcat.hex
1343:    when 0x00
1344:    end
1345:  when 0x0A # Built-In Appliance Control
1346:    case subcat.hex
1347:    when 0x00
1348:    end
1349:  when 0x0B # Plumbing
1350:    case subcat.hex
1351:    when 0x00
1352:    end
1353:  when 0x0C # Communication
1354:    case subcat.hex
1355:    when 0x00
1356:    end
1357:  when 0x0D # Computer Control
1358:    case subcat.hex
1359:    when 0x00
1360:    end
1361:  when 0x0E # Window Coverings
1362:    case subcat.hex
1363:    when 0x00
1364:    end
1365:  when 0x0F # Access Control
1366:    case subcat.hex
1367:    when 0x00
1368:    end
1369:  when 0x10 # Security, Health, and Safety
1370:  when 0x11 # Surveillance
1371:  when 0x12 # Automotive
1372:  when 0x13 # Pet care
1373:  when 0x14 # Toys
1374:  when 0x15 # Timekeeping
1375:  when 0x16 # Holiday
1376:  end
1377:  return @templid
1378:end
1379:
1380:def processDeviceInfo(param)
1381:  ### temporary
1382:  ### 12-24-07 Adding Device Template compatibility..
1383:  #have to find MY address
1384:  insHb = param['Parameter3'] # From
1385:  insMb = param['Parameter4']
1386:  insLb = param['Parameter5']
1387:
1388:  insID = padhex(insHb) + "." + padhex(insMb) + "." + padhex(insLb)
1389:  #set the devicecat and device subcat in the childdatabases
1390:  # 0-1 Device Category
1391:  # 2-3 Device SubCategory
1392:  # 4-5 Device Firmware
1393:  log('proccessDeviceInfo:Insteon ID' + insID)
1394:  $childdatabases[insID][0][0..1] = param['Parameter6']
1395:  $childdatabases[insID][0][2..3] = param['Parameter7']
1396:  $childdatabases[insID][0][4..5] = param['Parameter8']
1397:  savechilddatabases(insID)
1398:  log('InsteonID: ' + insID)
1399:  #log('Child Config AFTER update:' + $childdatabases[insID][0].to_s)
1400:  log($yellow)
1401:  @template = getdevicetemplate(param['Parameter6'], param['Parameter7'])
1402:  $devicetemplate[insID] = @template
1403:  log('Template ID:' + @template.to_s)
1404:  ### eventually, open a XML configuration script?
1405:  ### or read saved data from mysql?
1406:  ### most likely save this information to sql with device.
1407:  ### eventually, IPKDB will be available to ping.
1408:  log('for Insteon ID:' + insID)
1409:  log($grey)
1410:end
1411:
1412:def recvComplete
1413:  # Clears the wait flag, but does not remove a command from the queue
1414:  $wAIT = false
1415:  log($green + "Receive Completed. Checking command queue" + $grey)
1416:  if $cmdqueue.nitems > 0 then
1417:    log("Queue:" + $aqua + $cmdqueue.nitems.to_s + $grey + " : executing next command")
1418:    SndIns()
1419:  else
1420:    log($yellow + 'Queue Empty.' + $grey)
1421:    if $rerun == true
1422:      log('RERUN=TRUE, RESTARTING')
1423:      $rerun = false
1424:      mainRestart()
1425:    else
1426:      log('RERUN Not needed. Checking if reported..')
1427:      #report Child devices here.
1428:      if $reported == false
1429:        log('Reporting Child Devices')
1430:        @work = ""
1431:        $childdatabases.each_key{
1432:          |insteonID|
1433:          log('Child:' + insteonID)
1434:          log('Config:' + $childdatabases[insteonID].inspect)
1435:          @template = $devicetemplate[insteonID]
1436:          @work += insteonID + "\t\t\t" + @template.to_s + "\t\n"
1437:        }
1438:        log(@work)
1439:        cmd = Command.new(device_.devid_, -1001, 1, 2, 54)
1440:        cmd.params_[13] = @work
1441:        SendCommand(cmd)
1442:
1443:        $reported = true
1444:      else
1445:        log('report not needed')
1446:      end
1447:    end
1448:
1449:  end
1450:end
1451:def removecurrentcommand
1452:  #get the current child
1453:  log('in RemoveCurrentCommand')
1454:  log('Current Command:' + $cmdqueue[0].inspect)
1455:  #id is in param123
1456:  @id = $cmdqueue[0]['Parameter1']
1457:  @id += '.' + $cmdqueue[0]['Parameter2']
1458:  @id += '.' + $cmdqueue[0]['Parameter3']
1459:  log('ID=' + @id)
1460:  #now to remove from child and PLM databases
1461:  removefromchild(@id)
1462:  removefromplm(@id)
1463:  cmdComplete
1464:end
1465:def cmdComplete
1466:  # Clears the wait flag, and removes the command from the queue.
1467:  $wAIT = false
1468:  $resetNext = 0
1469:  $cmdqueue.delete_at(0)
1470:  # now that THAT command is completed, check to see if there is
1471:  # another command ready to transmit.
1472:  log($green + "Command Completed." + $grey)
1473:end
1474:def checkWait(param)
1475:  #Checks for response from current command.
1476:  if $cmdqueue[0] != nil
1477:    if $wAIT == true
1478:      #log('CW:waiting for command to complete')
1479:    else
1480:      #log('CW:reports clear')
1481:    end
1482:  else
1483:    log('------:)----checkWait: command queue is emtpy')
1484:    if $wAIT == true #this should never happen
1485:      log('------:(XXX-CheckWait: TRUE')
1486:    end
1487:  end
1488:end
1489:
1490:def plmparse(value)
1491:  #THIS ROUTINE REPLACES parsestring()
1492:  #this routine will PARSE the incoming stream into valid messages
1493:  # value is the complete command
1494:  param = {}
1495:  #here is a special case, the PLM seems to lock up.
1496:  if value == 0x15.chr
1497:    log('The PLM stopped responding')
1498:    log('Please unplug it, and plug it back in')
1499:    log('and do a quick reload router.')
1500:
1501:  end
1502:  while value.length > 2
1503:    case value[1]
1504:    when 0x62 # Special case, need to look at flags
1505:      if (value[5] & 0x10) == 0x10 # check for extended flag
1506:        cmdlen = 23
1507:      else
1508:        cmdlen = 9
1509:      end
1510:      param['Response'] = 'SndIns'
1511:    when 0x50; cmdlen = 11; param['Response'] = 'InsStdMsg'
1512:    when 0x51; cmdlen = 25; param['Response'] = 'InsExtMsg'
1513:    when 0x68; cmdlen = 4 #Set Insteon ACK Message Byte
1514:    when 0x71; cmdlen = 5 #Set Insteon ACK Message Two Bytes
1515:    when 0x70; cmdlen = 4 #Set Insteon NACK Message Byte
1516:    when 0x63; cmdlen = 5; param['Response'] = 'SndX10'
1517:    when 0x52; cmdlen = 4; param['Response'] = 'X10Msg'
1518:    when 0x61; cmdlen = 6; param['Response'] = 'SndGrp'
1519:    when 0x56; cmdlen = 7; param['Response'] = 'GrpEvntRpt'
1520:    when 0x58; cmdlen = 3 #All-Link Cleanup Status Report
1521:    when 0x64; cmdlen = 5; param['Response'] = 'StLnk'
1522:    when 0x65; cmdlen = 3; param['Response'] = 'CancelLnk'
1523:    when 0x53; cmdlen = 10; param['Response'] = 'InsLnkSts'
1524:    when 0x69; cmdlen = 3; param['Response'] = 'GetLnk'
1525:    when 0x6A; cmdlen = 3; param['Response'] = 'GetNext'
1526:    when 0x6C; cmdlen = 3 #Get All-Link Record for Sender
1527:    when 0x57; cmdlen = 10; param['Response'] = 'LnkData'
1528:    when 0x6F; cmdlen = 12; param['Response'] = 'MngLnk'
1529:    when 0x67; cmdlen = 3; param['Response'] = 'RstPLM'
1530:    when 0x6B; cmdlen = 4; param['Response'] = 'SetCfg'
1531:    when 0x60; cmdlen = 9; param['Response'] = 'GetVersion'
1532:    when 0x66; cmdlen = 6 #Set Host Device Category
1533:    when 0x72; cmdlen = 3 # RF Sleep
1534:    when 0x54; cmdlen = 3; param['Response'] = 'BtnRpt'
1535:    when 0x6D; cmdlen = 3; param['Response'] = 'LEDON'
1536:    when 0x6E; cmdlen = 3; param['Response'] = 'LEDOFF'
1537:    else
1538:
1539:      log('ERROR IN PLMPARSE- Unknown Command')
1540:      debug(value)
1541:
1542:      return ''
1543:    end
1544:
1545:    #Now we know the length the command should be, see if we have it.
1546:    #log('waiting for ' + cmdlen.to_s + ' characters...')
1547:    #log('length of current input is ' + value.length.to_s)
1548:    if value.length >= cmdlen
1549:      #log('GOT whole response')
1550:      #Yes, we have the whole command, Pack it in param
1551:      for byt in 1..cmdlen
1552:        param['Parameter' + byt.to_s] = padhex("%X" %value[byt - 1])
1553:      end
1554:      #now remove it from the string..
1555:      value = value.slice(cmdlen, value.length - cmdlen)
1556:      #Send it off for parsing
1557:      #log('Sending to EZToDCE:' + param.inspect.to_s)
1558:      EZToDCE(param)
1559:    else
1560:      #log('Still waiting...')
1561:      #no, we have NOT received the whole command.
1562:
1563:    end
1564:  end
1565:  return value
1566:end
1567:
1568:def rawX10(value)
1569:
1570:  x10MSN = $X10HouseCodes.index[value[0..0]]
1571:  x10LSN = $X10UnitCodes.index[value[1..1]]
1572:  return x10MSN + x10LSN
1573:end
1574:
1575:def X10Flag(value)
1576:  return + $X10CommandCodes.index[Value] + '0'
1577:end
1578:
1579:def SndIns
1580:  # create a new PLM command for SndIns
1581:  if $wAIT == false
1582:    #log('SndIns:currentcmd=' + $currentcmd.to_s)
1583:
1584:    if $cmdqueue.nitems > 0
1585:      log("SndIns:Queue:" + $aqua + $cmdqueue.nitems.to_s + $grey)
1586:      #log('SndIns:' + $cmdqueue.inspect)
1587:      param = $cmdqueue[0]
1588:      ### have to figure out the command byte 2 here
1589:      work = '02'.hex.chr + plmcommand(param)
1590:      ### PLM command compilation
1591:      for loop in 2..param.keys.nitems
1592:        @dummy = param['Parameter' + (loop - 1).to_s].to_s
1593:        work+= @dummy.hex.chr
1594:      end
1595:      conn_.Reconnect()
1596:      debugout(work)
1597:      conn_.Send(work)
1598:      #sleep 0.1
1599:      $wAIT = TRUE
1600:    else
1601:      log($yellow + 'Queue Empty.' + $grey)
1602:      if $rerun == true
1603:        log('RERUN=TRUE, RESTARTING')
1604:        $rerun = false
1605:        mainRestart()
1606:      else
1607:        log('RERUN Not needed')
1608:        if $reported == false
1609:          log('Reporting Child Devices')
1610:          @work = ""
1611:          $childdatabases.each_key{
1612:            |insteonID|
1613:            log('Child:' + insteonID)
1614:            log('Config:' + $childdatabases[insteonID].inspect)
1615:            @template = $devicetemplate[insteonID]
1616:            @work += insteonID + "\t\t\t" + @template.to_s + "\t\n"
1617:          }
1618:          log(@work)
1619:          cmd = Command.new(device_.devid_, -1001, 1, 2, 54)
1620:          cmd.params_[13] = @work
1621:          SendCommand(cmd)
1622:
1623:          $reported = true
1624:        else
1625:          log('report not needed')
1626:        end
1627:      end
1628:
1629:    end
1630:  else
1631:    log('X-----------SndIns: Waiting for response to:' + $cmdqueue[0]['Command'].to_s)
1632:    log('X-----------SndIns: Current Queue Length:' + $cmdqueue.nitems.to_s)
1633:  end
1634:end
1635:def plmcommand(param)
1636:  ### this returns the proper Byte2 for the command.
1637:  case param['Command']
1638:  when 'GetVersion'; return 0x60.chr
1639:  when 'SndIns'; return 0x62.chr
1640:  when 'SndGrp'; return 0x61.chr
1641:  when 'SndX10'; return 0x63.chr
1642:  when 'GetLnk'; return 0x69.chr
1643:  when 'GetNext'; return 0x6A.chr
1644:  when 'BtnRpt'; return 0x54.chr
1645:  when 'GetCfg'; return 0x73.chr
1646:  when 'StLnk'; return 0x64.chr
1647:  when 'CancelLnk'; return 0x65.chr
1648:  when 'MngLnk'; return 0x6F.chr
1649:  when 'RstPLM'; return 0x67.chr
1650:  when 'SetCfg'; return 0x6B.chr
1651:  when 'LEDON'; return 0x6D.chr
1652:  when 'LEDOFF'; return 0x6E.chr
1653:    ## hack
1654:  when 'InsStdMsg'
1655:    log('ERROR:PLMCommand encountered a COMMAND of INSSTDMSG')
1656:    break
1657:    return 0x62.chr
1658:  end
1659:end
1660:
1661:def debug(text)
1662:  work = 'DEBUG:'
1663:
1664:  for c in 1..text.length
1665:    work += padhex("%X" %text[c-1]) + ' '
1666:  end
1667:  log($yellow + work + "Length:" + text.length.to_s + $grey)
1668:end
1669:def debugout(text)
1670:  work = 'out:'
1671:
1672:  for c in 1..text.length
1673:    work += padhex("%X" %text[c-1]) + ' '
1674:  end
1675:  log($green + work + "Length:" + text.length.to_s + $grey)
1676:end
1677:def debugin(text)
1678:  work = 'IN:'
1679:
1680:  for c in 1..text.length
1681:    work += padhex("%X" %text[c-1]) + ' '
1682:  end
1683:  log($red + work + "Length:" + text.length.to_s + $grey)
1684:end
1685:
1686:def padhex(hex)
1687:  if hex.length==1
1688:    hex = "0" + hex
1689:  end
1690:  return hex
1691:end
1692:
1693:def percenttohex(level)
1694:  # convert from percent to byte
1695:  return "%X" %((level.to_i * 2.55)).to_i
1696:end
1697:
1698:def hextopercent(level)
1699:  return ((level.hex.to_i / 2.55)).to_i
1700:end
1701:
1702:def log(line)
1703:  $log = File.open("/var/log/pluto/" + device_.devid_.to_s + "_Generic_Serial_Device.log", "a")
1704:  $log.puts "(***):" + line.to_s
1705:  $log.close
1706:end
1707:def log2(line)
1708:  #this will send a message out the the orbiters..
1709:  #/usr/pluto/bin/MessageSend localhost 0 20 1 809 9 "Text to Display" 70 "alert" 182 "30" 251 "??"
1710:  cmd = Command.new(device_.devid_, -1000, 1, 1, 809)
1711:  cmd.params_[9] = line #text to display
1712:  cmd.params_[70] = 'PLMMessage' #Token
1713:  cmd.params_[182] = '10' #Timeout in seconds
1714:  cmd.params_[251] = '??'
1715:  SendCommand(cmd)
1716:end
1717:def checkChildRecordsinPLM()
1718:  log('Entered CheckChildRecordsinPLM')
1719:  # log('In CheckChildRecordsinPLM')
1720:  # time to verify all children are in the PLM
1721:  #
1722:  # log('Total PLM Records:' + $plmdatabase.nitems.to_s)
1723:  $plmdatabase.each{|record|
1724:    log('Record: = '+ getIIDfromRecord(record) + ' Group:' + getGroupfromRecord(record))
1725:    log('checking to see if it needs to be added as a child...')
1726:    if existsinchild(getIIDfromRecord(record)) == false
1727:        
1728:      log(getIIDfromRecord(record) + ' needs to be added to the child database')
1729:      addtochild(getIIDfromRecord(record))
1730:    end
1731:  }
1732:
1733:  $childdatabases.each_key {|child|
1734:    if existsinplm(child) == false
1735:      log(child + ' needs to be added to PLM')
1736:      sendAddtoPLM(child)
1737:    else
1738:      log(child + ' exists in PLM')
1739:    end
1740:
1741:    #now to scan the childs database
1742:    for record in 1..($childdatabases[child].nitems - 1)
1743:      @test = $childdatabases[child][record]
1744:      if existsinplm(getIIDfromRecord(@test)) == false
1745:        log(getIIDfromRecord(@test) + ' needs to be added to PLM')
1746:        sendAddtoPLM(getIIDfromRecord(@test))
1747:      else
1748:        log(getIIDfromRecord(@test) + ' exists in PLM')
1749:      end
1750:      #Also check to see if it needs to be added in the childdatabases
1751:    end
1752:  }
1753:
1754:end
1755:def existsinplm(insteonid)
1756:  result = false
1757:  $plmdatabase.each{|record|
1758:    #log(insteonid + '==' + getIIDfromRecord(record))
1759:    if insteonid == getIIDfromRecord(record)
1760:      result = true
1761:    end
1762:  }
1763:  return result
1764:end
1765:def existsinchild(insteonid)
1766:  log('ExistsinChild:InsteonID:' + insteonid)
1767:  result = false
1768:  $childdatabases.each_key{|record|
1769:    if insteonid == record
1770:      result = true
1771:    end
1772:  }
1773:  log('ExistsinChild result:FALSE') if result == false
1774:  log('ExistsinChild result:TRUE') if result == true
1775:  return result
1776:end
1777:def addtochild(insteonID)
1778:  log('addtochild Routne called')
1779:  log('Adding ' + insteonID + ' to the child database...')
1780:  if insteonID.length == 2 then
1781:    log('Child is X10')
1782:    $state[insteonID] = 0
1783:  else
1784:    log('Child is Insteon')
1785:    $childdatabases[insteonID] = ['****************']
1786:    sendPing(insteonID)
1787:    $rerun = true
1788:  end
1789:end
1790:def removefromchild(insteonID)
1791:  log('Removing ' + insteonID + ' from child database')
1792:  $childdatabases.delete(insteonID)
1793:  $state.delete(insteonID)
1794:end
1795:def removefromplm(insteonID)
1796:  log('Removing from plm')
1797:  $plmdatabase.each{|record|
1798:    #log(insteonid + '==' + getIIDfromRecord(record))
1799:    if insteonID == getIIDfromRecord(record)
1800:      debug(record)
1801:      log('Found Record, Deleting')
1802:      $plmdatabase.delete(record)
1803:      
1804:      #now, we have to remove it from the device.
1805:      param = {'Command' =>'MngLnk',
1806:        'Parameter1' => '80', #DELETE
1807:        'Parameter2' => record[0..1], #control byte
1808:        'Parameter3' => record[2..3], #group
1809:        'Parameter4' => record[4..5],#HB
1810:        'Parameter5' => record[6..7],#MB
1811:        'Parameter6' => record[8..9],#LB
1812:        'Parameter7' => record[10..11],#data1
1813:        'Parameter8' => record[12..13],#data2
1814:        'Parameter9' => record[14..15] #data3
1815:        
1816:      }
1817:      log(param.inspect)
1818:      $cmdqueue << param
1819:    end
1820:  }
1821:end
1822:def sendAddtoPLM(insteonID)
1823:  log('Adding ' + insteonID + ' to the PLM database...')
1824:  #This adds a record into the PLM
1825:  @insID = insteonID.split('.')
1826:  param = {'Command' => 'MngLnk',
1827:    'Parameter1' => '40', #control code -- add new record as Controller
1828:    'Parameter2' => 'C2', #All Link Record Flags AKA Record Control Byte
1829:    'Parameter3' => '01', #All Link Group
1830:    'Parameter4' => @insID[0], #HB
1831:    'Parameter5' => @insID[1], #MB
1832:    'Parameter6' => @insID[2], #LB
1833:    'Parameter7' => '01', #Link Data 1 ON-Level
1834:    'Parameter8' => '01', #Link Data 2 Ramp Rate
1835:    'Parameter9' => 'FF'} #Link Data 3 not used
1836:  if $wAIT == true
1837:    $cmdqueue.insert(1, param)
1838:  else
1839:    $cmdqueue.insert(0, param)
1840:  end
1841:
1842:  SndIns()
1843:end
1844:
1845:def getIIDfromRecord(recordstring)
1846:  #this extracts the insteonID string from the record.
1847:  #log('getIIDfromRecord::recordstring:' + recordstring)
1848:  @idhb = recordstring[4..5]
1849:  @idmb = recordstring[6..7]
1850:  @idlb = recordstring[8..9]
1851:  @result = @idhb + '.' + @idmb + '.' +@idlb
1852:  #log('GetIIDfromRecord: Found ID:' + @result)
1853:  return @result
1854:end
1855:
1856:def processBroadcastMessage(param)
1857:  #search the child databases for responders,
1858:  #and fire COMMANDS for each responder. 06Feb08
1859:  #and fire events for each responder.XXXXXXXXXXXXX
1860:  #Message flag is in parameter9 Group command 0xCx (All-Link Broadcast Message Pg 42.)
1861:  #Group is in parameter8
1862:  #From InsteonID is parameters 3, 4, 5
1863:  group = param['Parameter8']
1864:  from = padhex(param['Parameter3']) + '.'
1865:  from += padhex(param['Parameter4']) + '.'
1866:  from += padhex(param['Parameter5'])
1867:  log('Looking for ' + from + ' Group:' + group)
1868:  #Ok, now have to search child databases for from AND group AND responder
1869:  $childdatabases.each_key{|child|
1870:    #log('Searching:' + child)
1871:    for rec in 1..($childdatabases[child].nitems - 1)
1872:      record = $childdatabases[child][rec]
1873:      if getIIDfromRecord(record) == from # First, look for Insteon ID
1874:        #log('Found ID')
1875:        if getGroupfromRecord(record) == group #next, Group
1876:          #log('Found Group')
1877:          if isResponderRecord(record) # is a responder?
1878:            #log('Found Responder')
1879:            #figure out the child devicenum
1880:            from = $children[child]
1881:            #figure out the command
1882:            case param['Parameter10'].hex
1883:            when 0x11 #on
1884:              reportStatus(from, 100)
1885:            when 0x13 #off
1886:              reportStatus(from, 0)
1887:            when 0x17 #dim/brighten -ignore
1888:              level = 0
1889:            when 0x18 # STOP dim/brighten - sendgetstatus
1890:              level = 0
1891:              sendGetChildStatus(child)
1892:            else
1893:              level = 0
1894:              log('Command is other than ON/OFF/Dim/Brighten')
1895:            end
1896:          end
1897:        end
1898:      end
1899:    end
1900:  }
1901:end
1902:
1903:def reportStatus(from, level)
1904:  log('From:' + from.to_s)
1905:  log('current State:' + $state[from].to_s)
1906:  log('Wanted State:' + level.to_s)
1907:  case $state[from]
1908:  when 0
1909:    if level >=1
1910:      cmd = Command.new(from, from, 1, 1, 192) #on
1911:      cmd.params_[120] = "1"
1912:      SendCommand(cmd)
1913:      cmd = Command.new(from, from, 1, 1, 184)
1914:      cmd.params_[76] = level.to_s
1915:      cmd.params_[120] = "1"
1916:      SendCommand(cmd)
1917:    end
1918:  when 100
1919:    if level >= 1
1920:      cmd = Command.new(from, from, 1, 1, 184)
1921:      cmd.params_[76] = level.to_s
1922:      cmd.params_[120] = "1"
1923:      SendCommand(cmd)
1924:    else
1925:      cmd = Command.new(from, from, 1, 1, 193) # off
1926:      cmd.params_[120] = "1"
1927:      SendCommand(cmd)
1928:    end
1929:  else
1930:    if level == 100
1931:      cmd = Command.new(from, from, 1, 1, 193) #off
1932:      cmd.params_[120] = "1"
1933:      SendCommand(cmd)
1934:      cmd = Command.new(from, from, 1, 1, 192) # on
1935:      cmd.params_[120] = "1"
1936:      SendCommand(cmd)
1937:    end
1938:    cmd = Command.new(from, from, 1, 1, 184) #SetLevel
1939:    cmd.params_[76] = level.to_s
1940:    cmd.params_[120] = "1"
1941:    SendCommand(cmd)
1942:  end
1943:  log('ReportStatus: device:' + from.to_s + ' Status:' + level.to_s)
1944:  $state[from] = level
1945:
1946:end
1947:
1948:def isResponderRecord(recordstring)
1949:  work = recordstring[0..1].hex
1950:  if (work & 0x40) == 0x40 #check bit 6
1951:    result = false #signifies Controller record
1952:  else
1953:    result = true #signifies Responder record
1954:  end
1955:  return result
1956:end
1957:
1958:def getGroupfromRecord(recordstring)
1959:  #this extracts the GROUP from the record.
1960:  if recordstring == nil
1961:    return '00'
1962:  else
1963:    return recordstring[2..3]
1964:  end
1965:end
1966:def getdeltafromconfig(insteonID)
1967:  #This returns the delta from the child.
1968:  @work = $childdatabases[insteonID][0] # the settings stored in [0]
1969:  if @work == nil
1970:    return '00'
1971:  else
1972:    return @work[6..7]
1973:  end
1974:end
1975:def sendGetChildStatus(insteonID)
1976:  #log('sendGetChildStatus Called')
1977:  if insteonID.length != 2 #X10 device
1978:    @insID = insteonID.split('.')
1979:    param = {'Command' => 'SndIns',
1980:      'Parameter1' => @insID[0],
1981:      'Parameter2' => @insID[1],
1982:      'Parameter3' => @insID[2],
1983:      'Parameter4' => '0F', #flags
1984:      'Parameter5' => '19', #Status Request
1985:      'Parameter6' => '00'} #not used.
1986:    $cmdqueue << param
1987:    SndIns()
1988:    #Returned response will have cmd1 = DBDelta
1989:    #Returned response will have cmd2 = ON-Level
1990:  else
1991:    log('X10 does not report status')
1992:  end
1993:end
1994:
1995:
1996:# time to define a structure to save the raw data in hex
1997:# starts at [0]
1998:# Bytes Meaning
1999:# 0-1 Device Category
2000:# 2-3 Device SubCategory
2001:# 4-5 Device Firmware
2002:# 6-7 Database Delta
2003:# 8-9 reserved
2004:# 10-11 reserved
2005:# 12-13 reserved
2006:# 14-15 reserved
2007:###### First database record below (in same format its read from the device)
2008:###### This is the same format as an ALL-Link Record Response from the PLM
2009:###### (0x57) bytes 3..10
2010:# 16-17 record control byte
2011:# 18-19 Group
2012:# 20-21 ID HB
2013:# 22-23 ID MB
2014:# 24-25 ID LB
2015:# 26-27 Link Specific Data1
2016:# 28-29 Link Specific Data2
2017:# 30-31 Link Specific Data3
2018:######
2019:# 32-47 next database record...
2020:def cmd_ReceiveCommandForChild(cmd)
2021:#### Written by Dan Damron
2022:#### #384 Process Receive Command for Child ####
2023:#
2024:#Commands needing implementation
2025:# Climate commands:
2026:# 279 (Set Fan)
2027:# 280 (Set Heat/Cool)
2028:# 278 (Set Temperature)
2029:# Climate Events:
2030:# 25 Temperature Changed
2031:# 26 Humidity Changed
2032:# 27 Thermostat Set Point Changed
2033:
2034:# Security Commands:
2035:# 746 Disarm Panel
2036:# 758 Get Sensors List
2037:# 19 Set House Mode
2038:# 387 Verify PIN
2039:# Security Events:
2040:# 9 Sensor Tripped
2041:# 16 Security Breach
2042:# 17 Fire Alarm
2043:# 18 Reset Alarm
2044:# 39 Air Quality
2045:# 40 Doorbell
2046:# 41 Monitor Mode
2047:# 42 Movement Detected
2048:# 43 House Mode Changed
2049:# 44 Presence Detected
2050:# 45 Presence Lost
2051:# 67 Alarm Panel Mode Change
2052:
2053:
2054:
2055:
2056:
2057:
2058:deviceID = device_.childdevices_[cmd.devidto_].devdata_[12]
2059:insteonID = deviceID.chomp.split('.')
2060:$cmdID = cmd.id_
2061:$cmdTo = cmd.devidto_
2062:childType = device_.childdevices_[cmd.devidto_].devtemplid_
2063:$cmdFrom = cmd.devidfrom_
2064:$cmdPriority = cmd.priority_
2065:$cmdType = cmd.type_
2066:$cmdParams = cmd.params_
2067:log('------dce--- cmdID:' + $cmdID.to_s + ', cmdFrom:' + $cmdFrom.to_s + ', cmdTo:' + $cmdTo.to_s + ', cmdType:' + $cmdType.to_s + ', Priority:' + $cmdPriority.to_s)
2068:if $cmdTo == $cmdFrom
2069:	log('Detected Command sent to Self!')
2070:	return
2071:end
2072:	case cmd.id_
2073:	when 192 # ON
2074:	log('Processing ON command')
2075:	  if insteonID.length > 2 then
2076:			
2077:	    param = {'Command' => 'SndIns', 
2078:	      'Parameter1' => insteonID[0], 
2079:	      'Parameter2' => insteonID[1],
2080:	      'Parameter3' => insteonID[2],
2081:	      'Parameter4' => '0F', 
2082:	      'Parameter5' => '11',
2083:	      'Parameter6' => 'FF'}
2084:	    $cmdqueue << param
2085:	    SndIns()
2086:	  else
2087:	    log "------dce--- X10 DEVICE!!!"
2088:		# Send X10 ON command.
2089:		#first, figure out the house code and unit code.
2090:		log('DeviceID=' + deviceID)
2091:		x10Byte1 = $X10HouseCodes.index(deviceID[0].chr)
2092:		x10Byte1 += $X10UnitCodes.index(deviceID[1].chr)
2093:		x10cmd = $X10HouseCodes.index(deviceID[0].chr)
2094:		x10cmd += '2' # command code for ON
2095:		log('X10 Byte1:' + x10Byte1)
2096:		param = {'Command' => 'SndX10', 
2097:	        'Parameter1' => x10Byte1,
2098:	        'Parameter2' => '00'}
2099:		$cmdqueue << param
2100:		param = {'Command' => 'SndX10',
2101:		'Parameter1' => x10cmd,
2102:		'Parameter2' => '80'}
2103:		$cmdqueue << param
2104:	    SndIns()
2105:	  end
2106:	  reportStatus($children[deviceID], 100)
2107:	when 193 #OFF
2108:	  if insteonID.length > 2 then
2109:	
2110:	    param = {'Command' => 'SndIns',
2111:	      'Parameter1' => insteonID[0], 
2112:	      'Parameter2' => insteonID[1],
2113:	      'Parameter3' => insteonID[2],
2114:	      'Parameter4' => '0F', 
2115:	      'Parameter5' => '13',
2116:	      'Parameter6' => '00'}
2117:	    $cmdqueue << param
2118:	    SndIns()
2119:	  else
2120:	    log "------dce--- X10 DEVICE!!!"
2121:		log('DeviceID=' + deviceID)
2122:
2123:		x10Byte1 = $X10HouseCodes.index(deviceID[0].chr)
2124:		x10Byte1 += $X10UnitCodes.index(deviceID[1].chr)
2125:		x10cmd = $X10HouseCodes.index(deviceID[0].chr)
2126:		x10cmd += '3' # command code for OFF
2127:		log('X10 Byte1:' + x10Byte1)
2128:		param = {'Command' => 'SndX10', 
2129:	        'Parameter1' => x10Byte1,
2130:	        'Parameter2' => '00'}
2131:		$cmdqueue << param
2132:		param = {'Command' => 'SndX10',
2133:		'Parameter1' => x10cmd,
2134:		'Parameter2' => '80'}
2135:		$cmdqueue << param
2136:	    SndIns()
2137:	
2138:	  end
2139:	  reportStatus($children[deviceID], 0)
2140:	when 184 #SetLevel
2141:	  # convert from percent to hex
2142:	  dim_level = percenttohex(cmd.params_[76])
2143:	  #log("------dce--- Dim Level:" + dim_level.to_s)
2144:	  if insteonID.length > 2 then
2145:		
2146:	    param = {'Command' => 'SndIns',
2147:	      'Parameter1' => insteonID[0], 
2148:	      'Parameter2' => insteonID[1],
2149:	      'Parameter3' => insteonID[2],
2150:	      'Parameter4' => '0F', 
2151:	      'Parameter5' => '11',
2152:	      'Parameter6' => dim_level}
2153:	    $cmdqueue << param
2154:	    SndIns()
2155:	  else
2156:# In the PRESET DIM X10 command, the lsbit of the command code is the MSB of the
2157:# dim level, and the house code represents the 4 lsbits of the dim level.
2158:# This is why Pre-Set Dim command is A AND B.
2159:	log('Parameter 76 = ' + cmd.params_[76].to_s)
2160:	    log "X10 DEVICE!!! relative Dimming command"
2161:	    log('DeviceID=' + deviceID)
2162:		x10Byte1 = $X10HouseCodes.index(deviceID[0].chr)
2163:		x10Byte1 += $X10UnitCodes.index(deviceID[1].chr)
2164:		x10cmd = $X10HouseCodes.index(deviceID[0].chr)
2165:	    	#first, determine if its UP or Down
2166:
2167:		if $state[deviceID].to_i > hextopercent(dim_level).to_i
2168:			# DOWN
2169:			x10cmd += $X10CommandCodes.index('Dim')
2170:		else
2171:			# UP
2172:			x10cmd += $X10CommandCodes.index('Bright')
2173:		end
2174:
2175:		log('X10 Byte1:' + x10Byte1)
2176:		param = {'Command' => 'SndX10', 
2177:	        'Parameter1' => x10Byte1,
2178:	        'Parameter2' => '00'}
2179:		$cmdqueue << param
2180:		param = {'Command' => 'SndX10',
2181:		'Parameter1' => x10cmd,
2182:		'Parameter2' => '80'}
2183:		$cmdqueue << param
2184:
2185:	    SndIns()
2186:	    log('Dim Level:' + hextopercent(dim_level).to_s)
2187:	    #now send status info (we should not have to to this, but do)
2188:	    reportStatus($children[deviceID], hextopercent(dim_level))
2189:	  end
2190:
2191:end
2192:end
2193:#### 756 ####################################################################
2194:def cmd_756(cmd=nil)
2195:@returnParamArray.clear
2196:#### Written by Dan Damron
2197:#### #756 Report Child Devices ####
2198:
2199:
2200:#here is where I send all my newly discovered children..
2201:
2202:
2203:#I need to fire an event [54]
2204:#with params_:
2205:#12 Error Message (string)
2206:# if this is not empty, that means an error occurred.
2207:#
2208:#13 Text (string)
2209:# a list like this:
2210:# [internal id] \t
2211:# [description] \t
2212:# [room name] \t
2213:# [device template] \t
2214:# [floorplan id] \n
2215:
2216:
2217:#First, Lets see if we actually 'get this command'
2218:log($yellow+ '*#*#*#*#*#*#*#*# GOT #756 Report Child Devices! *#*#*#*#*#*#*#*#*'+ $grey)
2219:
2220:
2221:
2222:@work = ""
2223:$childdatabases.each_key{|insteonID|
2224:
2225:# figure out what type of device to add here..
2226:log('Child:' + insteonID)
2227:log('Config:' + $childdatabases[insteonID].inspect)
2228:@template = $devicetemplate[insteonID]
2229:
2230:@work += insteonID + "\t\t\t" + @template.to_s + "\t\n"
2231:
2232:
2233:}
2234:log(@work)
2235:cmd = Command.new(device_.devid_, -1000, 1, 2, 54)
2236:cmd.params_[13] = @work
2237:SendCommand(cmd)
2238:return @returnParamArray
2239:end
2240:#### 760 ####################################################################
2241:def cmd_760(id, pk_command, parameters, cmd=nil)
2242:@returnParamArray.clear
2243:#### Written by Dan Damron
2244:#### #760 Send Command to Child ####
2245:
2246:
2247:@insteonID = id.chomp.split('.')
2248:@parameters = parameters
2249:@command = pk_command
2250:@cmd = cmd
2251:
2252:log('#760:id=' + id.inspect)
2253:log('#760:parameters=' + parameters.inspect)
2254:log('#760:pk_command=' + pk_command.inspect)
2255:log('#760:cmd=' + cmd.inspect)
2256:### ok, I get the insteonID in @insteonID
2257:# pk_command has one of THREE values, 192, 193, or NOTHING
2258:# when I click 50%, I get in parameters: 76
2259:# but NOTHING in pk_command.
2260:
2261:case pk_command
2262:when '192' #ON
2263:  param = {'Command' => 'SndIns',
2264:    'Parameter1' => @insteonID[0],
2265:    'Parameter2' => @insteonID[1],
2266:    'Parameter3' => @insteonID[2],
2267:    'Parameter4' => 'OF', # Flags
2268:    'Parameter5' => '11', # Insteon SetLevel
2269:    'Parameter6' => 'FF'} # FULL ON
2270:  $cmdqueue << param
2271:  SndIns()
2272:
2273:when '193' #OFF
2274:  param = {'Command' => 'SndIns',
2275:    'Parameter1' => @insteonID[0], 
2276:    'Parameter2' => @insteonID[1],
2277:    'Parameter3' => @insteonID[2],
2278:    'Parameter4' => '0F', 
2279:    'Parameter5' => '13', #OFF
2280:    'Parameter6' => '00'}
2281:  $cmdqueue << param
2282:  SndIns()
2283:
2284:
2285:when ''
2286:  if parameters=='76'
2287:    #SetLevel 50%
2288:    param = {'Command' => 'SndIns',
2289:      'Parameter1' => @insteonID[0],
2290:      'Parameter2' => @insteonID[1],
2291:      'Parameter3' => @insteonID[2],
2292:      'Parameter4' => 'OF', # Flags
2293:      'Parameter5' => '11', # Insteon SetLevel
2294:      'Parameter6' => '76'} # 50%
2295:    $cmdqueue << param
2296:    SndIns()
2297:  end
2298:end
2299:return @returnParamArray
2300:end
2301:#### 776 ####################################################################
2302:def cmd_776(arguments, cmd=nil)
2303:@returnParamArray.clear
2304:#### Written by Dan Damron
2305:### #776 Reset
2306:#First, Lets see if we actually 'get this command'
2307:log($yellow+ '*#*#*#*#*#*#*#*# GOT #776 Reset! *#*#*#*#*#*#*#*#*'+ $grey)
2308:
2309:
2310:myDevFrom = device_.devid_
2311:myDevTo = -1001
2312:myDevPriority = 1
2313:myDevType = 2 #event
2314:myDevID = 65 # Device Detected
2315:#create command
2316:cmd = Command.new(myDevFrom, myDevTo, myDevPriority, myDevType, myDevID)
2317:#Add params...
2318:cmd.params_[28] = '' #IP Address
2319:cmd.params_[5] = '' #MAC Address
2320:cmd.params_[56] = "73" # environment - Lighting Device
2321:cmd.params_[49] = "38" # Light (dimmable) PK_DeviceTemplate
2322:#PK_FloorplanObjectType of 10 is Table Lamp, 9 is ceiling light
2323:#PK_FloorplanObjectType is devicedata #11
2324:#0a.97.0b is test lamp
2325:#0b.71.ab is Office Light
2326:cmd.params_[55] = "11|10|12|0A.97.0B" # test lamp module PK_DeviceData
2327:cmd.params_[13] = "SwitchLinc V2" # text to display
2328:cmd.params_[51] = "0A.97.0B" # VendorModelID
2329:cmd.params_[52] = "11" # PK_CommMethod
2330:cmd.params_[53] = "2" #PK_PnpProtocol
2331:cmd.params_[54] = "0A.97.0B[54]" #PNP_Serial_Number
2332:cmd.params_[59] = "Insteon PLM"
2333:SendCommand(cmd)
2334:##device # 2
2335:#cmd = Command.new(myDevFrom, myDevTo, myDevPriority, myDevType, myDevID)
2336:##Add params...
2337:#cmd.params_[56] = "73" # environment - Lighting Device
2338:#cmd.params_[49] = "38" # Light (dimmable)
2339:#cmd.params_[55] = "12\t11.22.33\n59\tConfiguration\n" # test lamp module
2340:#cmd.params_[13] = "TEST LampLinc V2" # text to display
2341:#cmd.params_[52] = "11"
2342:#cmd.params_[53] = "2"
2343:#cmd.params_[54] = "11.22.33"
2344:#cmd.params_[59] = "Insteon PLM"
2345:#SendCommand(cmd)
2346:  
2347:#Now, Fire the Done Detecting event...
2348:cmd = Command.new(myDevFrom, myDevTo, myDevPriority, myDevType, 74) #Done detecting...
2349:cmd.params_[59] = "Insteon PLM"
2350:SendCommand(cmd)
2351:return @returnParamArray
2352:end
2353:#### 788 ####################################################################
2354:def cmd_788(arguments, cmd=nil)
2355:@returnParamArray.clear
2356:#### Written by Dan Damron
2357:#788
2358:#First, Let's see if we actually 'get this command'
2359:log($yellow+ '*#*#*#*#*#*#*#*# GOT #788 Status Report! *#*#*#*#*#*#*#*#*'+ $grey)
2360:return @returnParamArray
2361:end
2362:#### START SETTERS ####################################################################
2363:def initialize()
2364:super
2365:@returnParamArray=Array.new
2366:end
2367:####  END  SETTERS ####################################################################
2368:end
2370:(***):MY DEVICE:69
(***):SndIns:Queue:[36m1[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):X-----------SndIns: Waiting for response to:SetCfg
(***):X-----------SndIns: Current Queue Length:2
(***):Finding Children..
(***):reading stored Child configuration:
(***):********************************************************
(***):X-----------SndIns: Waiting for response to:SetCfg
(***):X-----------SndIns: Current Queue Length:2
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Third attempt, Failing Command!
(***):in RemoveCurrentCommand
(***):Current Command:{"Parameter1"=>"40", "Command"=>"SetCfg"}
01	05/17/08 21:40:02.344		[31;1mError while calling method: Cannot call class method: cmd_351
error: can't convert nil into String, line: 1457
backtrace: 
	in: (eval): 1457
	from (eval):1457:in `+'
	from (eval):1457:in `removecurrentcommand'
	from (eval):41:in `cmd_351'
[0m <0xb5836b90>
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Third attempt, Failing Command!
(***):in RemoveCurrentCommand
(***):Current Command:{"Parameter1"=>"40", "Command"=>"SetCfg"}
01	05/17/08 21:40:20.456		[31;1mError while calling method: Cannot call class method: cmd_351
error: can't convert nil into String, line: 1457
backtrace: 
	in: (eval): 1457
	from (eval):1457:in `+'
	from (eval):1457:in `removecurrentcommand'
	from (eval):41:in `cmd_351'
	from (eval):1457
[0m <0xb5836b90>
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Third attempt, Failing Command!
(***):in RemoveCurrentCommand
(***):Current Command:{"Parameter1"=>"40", "Command"=>"SetCfg"}
01	05/17/08 21:40:38.529		[31;1mError while calling method: Cannot call class method: cmd_351
error: can't convert nil into String, line: 1457
backtrace: 
	in: (eval): 1457
	from (eval):1457:in `+'
	from (eval):1457:in `removecurrentcommand'
	from (eval):41:in `cmd_351'
	from (eval):1457
[0m <0xb5836b90>
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Third attempt, Failing Command!
(***):in RemoveCurrentCommand
(***):Current Command:{"Parameter1"=>"40", "Command"=>"SetCfg"}
01	05/17/08 21:40:56.569		[31;1mError while calling method: Cannot call class method: cmd_351
error: can't convert nil into String, line: 1457
backtrace: 
	in: (eval): 1457
	from (eval):1457:in `+'
	from (eval):1457:in `removecurrentcommand'
	from (eval):41:in `cmd_351'
	from (eval):1457
[0m <0xb5836b90>
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Third attempt, Failing Command!
(***):in RemoveCurrentCommand
(***):Current Command:{"Parameter1"=>"40", "Command"=>"SetCfg"}
01	05/17/08 21:41:14.652		[31;1mError while calling method: Cannot call class method: cmd_351
error: can't convert nil into String, line: 1457
backtrace: 
	in: (eval): 1457
	from (eval):1457:in `+'
	from (eval):1457:in `removecurrentcommand'
	from (eval):41:in `cmd_351'
	from (eval):1457
[0m <0xb5836b90>
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Third attempt, Failing Command!
(***):in RemoveCurrentCommand
(***):Current Command:{"Parameter1"=>"40", "Command"=>"SetCfg"}
01	05/17/08 21:41:32.734		[31;1mError while calling method: Cannot call class method: cmd_351
error: can't convert nil into String, line: 1457
backtrace: 
	in: (eval): 1457
	from (eval):1457:in `+'
	from (eval):1457:in `removecurrentcommand'
	from (eval):41:in `cmd_351'
	from (eval):1457
[0m <0xb5836b90>
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Third attempt, Failing Command!
(***):in RemoveCurrentCommand
(***):Current Command:{"Parameter1"=>"40", "Command"=>"SetCfg"}
01	05/17/08 21:41:50.810		[31;1mError while calling method: Cannot call class method: cmd_351
error: can't convert nil into String, line: 1457
backtrace: 
	in: (eval): 1457
	from (eval):1457:in `+'
	from (eval):1457:in `removecurrentcommand'
	from (eval):41:in `cmd_351'
	from (eval):1457
[0m <0xb5836b90>
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Third attempt, Failing Command!
(***):in RemoveCurrentCommand
(***):Current Command:{"Parameter1"=>"40", "Command"=>"SetCfg"}
01	05/17/08 21:42:08.861		[31;1mError while calling method: Cannot call class method: cmd_351
error: can't convert nil into String, line: 1457
backtrace: 
	in: (eval): 1457
	from (eval):1457:in `+'
	from (eval):1457:in `removecurrentcommand'
	from (eval):41:in `cmd_351'
	from (eval):1457
[0m <0xb5836b90>
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Third attempt, Failing Command!
(***):in RemoveCurrentCommand
(***):Current Command:{"Parameter1"=>"40", "Command"=>"SetCfg"}
01	05/17/08 21:42:26.949		[31;1mError while calling method: Cannot call class method: cmd_351
error: can't convert nil into String, line: 1457
backtrace: 
	in: (eval): 1457
	from (eval):1457:in `+'
	from (eval):1457:in `removecurrentcommand'
	from (eval):41:in `cmd_351'
	from (eval):1457
[0m <0xb5836b90>
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Third attempt, Failing Command!
(***):in RemoveCurrentCommand
(***):Current Command:{"Parameter1"=>"40", "Command"=>"SetCfg"}
01	05/17/08 21:42:45.032		[31;1mError while calling method: Cannot call class method: cmd_351
error: can't convert nil into String, line: 1457
backtrace: 
	in: (eval): 1457
	from (eval):1457:in `+'
	from (eval):1457:in `removecurrentcommand'
	from (eval):41:in `cmd_351'
	from (eval):1457
[0m <0xb5836b90>
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Third attempt, Failing Command!
(***):in RemoveCurrentCommand
(***):Current Command:{"Parameter1"=>"40", "Command"=>"SetCfg"}
01	05/17/08 21:43:03.095		[31;1mError while calling method: Cannot call class method: cmd_351
error: can't convert nil into String, line: 1457
backtrace: 
	in: (eval): 1457
	from (eval):1457:in `+'
	from (eval):1457:in `removecurrentcommand'
	from (eval):41:in `cmd_351'
	from (eval):1457
[0m <0xb5836b90>
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Third attempt, Failing Command!
(***):in RemoveCurrentCommand
(***):Current Command:{"Parameter1"=>"40", "Command"=>"SetCfg"}
01	05/17/08 21:43:21.198		[31;1mError while calling method: Cannot call class method: cmd_351
error: can't convert nil into String, line: 1457
backtrace: 
	in: (eval): 1457
	from (eval):1457:in `+'
	from (eval):1457:in `removecurrentcommand'
	from (eval):41:in `cmd_351'
	from (eval):1457
[0m <0xb5836b90>
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Third attempt, Failing Command!
(***):in RemoveCurrentCommand
(***):Current Command:{"Parameter1"=>"40", "Command"=>"SetCfg"}
01	05/17/08 21:43:39.263		[31;1mError while calling method: Cannot call class method: cmd_351
error: can't convert nil into String, line: 1457
backtrace: 
	in: (eval): 1457
	from (eval):1457:in `+'
	from (eval):1457:in `removecurrentcommand'
	from (eval):41:in `cmd_351'
	from (eval):1457
[0m <0xb5836b90>
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Third attempt, Failing Command!
(***):in RemoveCurrentCommand
(***):Current Command:{"Parameter1"=>"40", "Command"=>"SetCfg"}
01	05/17/08 21:43:57.363		[31;1mError while calling method: Cannot call class method: cmd_351
error: can't convert nil into String, line: 1457
backtrace: 
	in: (eval): 1457
	from (eval):1457:in `+'
	from (eval):1457:in `removecurrentcommand'
	from (eval):41:in `cmd_351'
	from (eval):1457
[0m <0xb5836b90>
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Third attempt, Failing Command!
(***):in RemoveCurrentCommand
(***):Current Command:{"Parameter1"=>"40", "Command"=>"SetCfg"}
01	05/17/08 21:44:15.429		[31;1mError while calling method: Cannot call class method: cmd_351
error: can't convert nil into String, line: 1457
backtrace: 
	in: (eval): 1457
	from (eval):1457:in `+'
	from (eval):1457:in `removecurrentcommand'
	from (eval):41:in `cmd_351'
	from (eval):1457
[0m <0xb5836b90>
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Third attempt, Failing Command!
(***):in RemoveCurrentCommand
(***):Current Command:{"Parameter1"=>"40", "Command"=>"SetCfg"}
01	05/17/08 21:44:33.510		[31;1mError while calling method: Cannot call class method: cmd_351
error: can't convert nil into String, line: 1457
backtrace: 
	in: (eval): 1457
	from (eval):1457:in `+'
	from (eval):1457:in `removecurrentcommand'
	from (eval):41:in `cmd_351'
	from (eval):1457
[0m <0xb5836b90>
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m
(***):[31mreceive timeout=1[37m
(***):[31mreceive timeout=2[37m
(***):[31mreceive timeout=3[37m
(***):Command Stalled!  resetting and retrying
(***):Current Command:0
(***):SndIns:Queue:[36m2[37m
(***):[32mout:02 6B 40 Length:3[37m