Jump to content

Insteon PLM Ruby Code 373: Difference between revisions

From LinuxMCE
Ddamron (talk | contribs)
No edit summary
 
RayBe (talk | contribs)
Added category: GSD
 
(9 intermediate revisions by 5 users not shown)
Line 1: Line 1:
<pre>
{{Versioninfo}}
#### Written by Dan Damron
[[category: Insteon]]
[[Category: GSD]]
<pre>#### Written by Dan Damron
#### #373 Private Method Listing ####
#### #373 Private Method Listing ####


def mainStart() ## This is called FIRST, reruns cannot call this.
def mainStart() ## This is called FIRST, reruns cannot call this.
  #Get the PLM Database
#Register Message Interceptor
  sendGetLink
@interceptor = Command.new(device_.devid_, -1000, 1, 5, 37)
  #get Child devices
@interceptor.params_[2] = device_.devid_.to_s
  log('Finding Children..')
SendCommand(@interceptor)
  device_.childdevices_.each{|c| $children[device_.childdevices_[c.to_s.to_i].devdata_[12].chomp.lstrip.rstrip] = c.to_s.to_i}
  $children.keys.each{|c| log(c + ' = ' + $children[c].to_s)}
  log('reading stored Child configuration:')


  $children.keys.each{|c|
#Get the PLM Database
    #Get each Childs configuration
sendGetLink
    getdeviceconfig(c) #
#get Child devices
    #the above getdeviceconfig packs $configparams array
log('Finding Children..')
    log('Configuration for ' + c + ' = ' + $configparams.inspect.to_s)
device_.childdevices_.each{|c|
  }
if device_.childdevices_[c.to_s.to_i].devdata_[12].include? "Group"
log('FOUND A GROUP')
else
$children[device_.childdevices_[c.to_s.to_i].devdata_[12].chomp.lstrip.rstrip] = c.to_s.to_i
end}
$children.keys.each{|c| log(c + ' = ' + $children[c].to_s)
}
log('reading stored Child configuration:')
 
$children.keys.each{|c|
#Get each Childs configuration
$state[$children[c]] = 0
getdeviceconfig(c) #
 
#the above getdeviceconfig packs $configparams array
log('Configuration for ' + c + ' = ' + $configparams.inspect.to_s)
}
 
log('********************************************************')
#get childs actual configuation and status
$children.keys.each{|c| sendGetChildStatus(c)}
SndIns()


  log('********************************************************')
  #get childs actual configuation and status
  $children.keys.each{|c| sendGetChildStatus(c)}
  SndIns()
end
end
def mainRestart()
def mainRestart()
  #We have hashes already set up.
#We have hashes already set up.
  $childdatabases.each_key{|@insteonID|
$childdatabases.each_key{|@insteonID|
    sendGetChildStatus(@insteonID)}
$state[$children[@insteonID]] = 0
  SndIns()
sendGetChildStatus(@insteonID)}
SndIns()
end
end


def setdeviceconfig(insteonid, configurestring)
def setdeviceconfig(insteonid, configurestring)
  @deviceid = $children[insteonid]
@deviceid = $children[insteonid]
  @cmdfrom = device_.devid_
@cmdfrom = device_.devid_
  @cmdto = 4 #general info plugin
@cmdto = 4 #general info plugin
  @priority = 1
@priority = 1
  @type=1 #command
@type=1 #command
  @cmdid = 246
@cmdid = 246


  #set up command..
#set up command..
  @cmd = Command.new(@cmdfrom, @cmdto, @priority, @type, @cmdid)
@cmd = Command.new(@cmdfrom, @cmdto, @priority, @type, @cmdid)
  @cmd.params_[2] = @deviceid.to_s
@cmd.params_[2] = @deviceid.to_s
  @cmd.params_[52] = '59' # Configuration
@cmd.params_[52] = '59' # Configuration
  @cmd.params_[5] = configurestring
@cmd.params_[5] = configurestring
  SendCommand(@cmd)
SendCommand(@cmd)
  #log('SetDeviceConfig:' + configurestring)
log('SetDeviceConfig:' + @cmd.to_s)
  #log('Configuration Saved - will be available on next reload')
#log('SetDeviceConfig:' + configurestring)
#log('Configuration Saved - will be available on next reload')
end
end


def getdeviceconfig(insteonid)
def getdeviceconfig(insteonid)
  @deviceid = $children[insteonid]
@deviceid = $children[insteonid]
  @configstring = ''
@configstring = ''
  begin
begin
    @configstring = device_.childdevices_[@deviceid].devdata_[59].to_s
@configstring = device_.childdevices_[@deviceid].devdata_[59].to_s
  rescue
rescue
    log('Device ID = ' + @deviceid.to_s)
log('Device ID = ' + @deviceid.to_s)
    log($red + 'Error - Child has no configuration'+ $grey)
log($red + 'Error - Child has no configuration'+ $grey)
    log('Setting initial value of "****************"')
log('Setting initial value of "****************"')
    setdeviceconfig(insteonid, ('*' * 16))
setdeviceconfig(insteonid, ('*' * 16))
    @configstring = '*' * 16
@configstring = '*' * 16
    sendPing(insteonid)
sendPing(insteonid)
  end
end
  if @configstring == ''
if @configstring == ''
    $configparams = ['****************']
$configparams = ['****************']
    log('CAUGHT BLANK RECORD')
log('CAUGHT BLANK RECORD')
    setdeviceconfig(insteonid, ('*' * 16))
setdeviceconfig(insteonid, ('*' * 16))
    sendPing(insteonid)
sendPing(insteonid)
  else
else
    $configparams = @configstring.unpack('a16' * (@configstring.length / 16))
$configparams = @configstring.unpack('a16' * (@configstring.length / 16))
 
$devicetemplate[insteonid] = getdevicetemplate($configparams[0][0..1], $configparams[0][2..3])
  end
end
  #log($yellow + 'getdeviceconfig:' + $configparams.inspect + $grey)
#log($yellow + 'getdeviceconfig:' + $configparams.inspect + $grey)
  #add the configuration parameters to the child database
#add the configuration parameters to the child database
  $childdatabases[insteonid] = $configparams
$childdatabases[insteonid] = $configparams
  #get the device type
#get the device type


end
end


def sendGetLink()
def sendGetLink()
  #lets just see exactly what is in the PLM database
#lets just see exactly what is in the PLM database
  param = {'Command' => 'GetLnk'}
param = {'Command' => 'GetLnk'}
  $cmdqueue << param
$cmdqueue << param
  SndIns()
SndIns()
end
end


def sendGetNext()
def sendGetNext()
  param = {'Command' => 'GetNext'}
param = {'Command' => 'GetNext'}
  if $wAIT == true
if $wAIT == true
    $cmdqueue.insert(1, param)
$cmdqueue.insert(1, param)
  else
else
    $cmdqueue.insert(0,param)
$cmdqueue.insert(0,param)
  end
end
  SndIns()
SndIns()
end
end


def sendRemoteGetLink(insteonID)
def sendRemoteGetLink(insteonID)
  # Read First ALDB Record
# Read First ALDB Record
  # a few variables need to be set up here..
# a few variables need to be set up here..
  $recordof = insteonID # save the insteon ID
$recordof = insteonID # save the insteon ID
  insID = insteonID.chomp.split('.') # get the seperate bytes
insID = insteonID.chomp.split('.') # get the seperate bytes
  $remoteDBOffsetMSB = 0x0F # initial offset
$remoteDBOffsetMSB = 0x0F # initial offset
  $remoteDBOffsetLSB = 0xF8 # initial LSB offset
$remoteDBOffsetLSB = 0xF8 # initial LSB offset
  param = {'Command' => 'SndIns',
param = {'Command' => 'SndIns',
    'Parameter1' => insID[0], #HB
'Parameter1' => insID[0], #HB
    'Parameter2' => insID[1], #MB
'Parameter2' => insID[1], #MB
    'Parameter3' => insID[2], #LB
'Parameter3' => insID[2], #LB
    'Parameter4' => '0F', #Flags
'Parameter4' => '0F', #Flags
    'Parameter5' => '28', #Cmd1
'Parameter5' => '28', #Cmd1
    'Parameter6' => "%X" %$remoteDBOffsetMSB #Cmd2 Set MSB Offset
'Parameter6' => "%X" %$remoteDBOffsetMSB #Cmd2 Set MSB Offset
  }
}
  $cmdqueue << param
$cmdqueue << param
  # repeat last param for each byte to read (F8..FF)=first record
# repeat last param for each byte to read (F8..FF)=first record


  for x in 0..7
for x in 0..7
    param = {'Command' => 'SndIns',
param = {'Command' => 'SndIns',
      'Parameter1' => insID[0], #HB
'Parameter1' => insID[0], #HB
      'Parameter2' => insID[1], #MB
'Parameter2' => insID[1], #MB
      'Parameter3' => insID[2], #LB
'Parameter3' => insID[2], #LB
      'Parameter4' => '0F', #Flags
'Parameter4' => '0F', #Flags
      'Parameter5' => '2B', #Cmd1 Peek
'Parameter5' => '2B', #Cmd1 Peek
      'Parameter6' => "%X" %($remoteDBOffsetLSB + x) #Cmd2
'Parameter6' => "%X" %($remoteDBOffsetLSB + x) #Cmd2
    }
}


    $cmdqueue << param
$cmdqueue << param
  end
end


end
end


def sendRemoteGetNext(insteonID)
def sendRemoteGetNext(insteonID)
  insID = insteonID.chomp.split('.') # get the seperate bytes
insID = insteonID.chomp.split('.') # get the seperate bytes
  ### Do NOT forget to check to see if we need to decrease the MSB
### Do NOT forget to check to see if we need to decrease the MSB
 
if $remoteDBOffsetLSB == 0x00
#OffsetMSB needs to be decreased, and LSB needs reset.
$remoteDBOffsetMSB = $remoteDBOffsetMSB - 1
$remoteDBOffsetLSN = 0xFF # the next line will decrease this by 8
end
# decrease DBOffsetLSB by 0x08
$remoteDBOffsetLSB = $remoteDBOffsetLSB - 0x08


  if $remoteDBOffsetLSB == 0x00
for x in 0..7
    #OffsetMSB needs to be decreased, and LSB needs reset.
param = {'Command' => 'SndIns',
    $remoteDBOffsetMSB = $remoteDBOffsetMSB - 1
'Parameter1' => insID[0], #HB
    $remoteDBOffsetLSN = 0xFF # the next line will decrease this by 8
'Parameter2' => insID[1], #MB
  end
'Parameter3' => insID[2], #LB
  # decrease DBOffsetLSB by 0x08
'Parameter4' => '0F', #Flags
  $remoteDBOffsetLSB = $remoteDBOffsetLSB - 0x08
'Parameter5' => '2B', #Cmd1 Peek
'Parameter6' => "%X" %($remoteDBOffsetLSB + x) #Cmd2
}
#log('sendRemoteGetNet:added to queue:' + param.inspect)
if $wAIT == true
$cmdqueue.insert(x + 1, param)
else
$cmdqueue.insert(x,param)
end


  for x in 0..7
    param = {'Command' => 'SndIns',
      'Parameter1' => insID[0], #HB
      'Parameter2' => insID[1], #MB
      'Parameter3' => insID[2], #LB
      'Parameter4' => '0F', #Flags
      'Parameter5' => '2B', #Cmd1 Peek
      'Parameter6' => "%X" %($remoteDBOffsetLSB + x) #Cmd2
    }
    #log('sendRemoteGetNet:added to queue:' + param.inspect)
    if $wAIT == true
      $cmdqueue.insert(x +  1, param)
    else
      $cmdqueue.insert(x,param)
    end


   
end
  end
end
end


### Main command parsing routine is EZToDCE
### Main command parsing routine is EZToDCE
def EZToDCE(param)
def EZToDCE(param)
  #param contains a hash of EZBridge command structure
#param contains a hash of EZBridge command structure
  #log($blue + 'Queue:' + $cmdqueue[0].inspect + $grey)
#log($blue + 'Queue:' + $cmdqueue[0].inspect + $grey)
  #log($blue + 'Param:' + param.inspect + $grey)
#log($blue + 'Param:' + param.inspect + $grey)
  #log($blue + 'currentcmd:' + $currentcmd.to_s + $grey)
#log($blue + 'currentcmd:' + $currentcmd.to_s + $grey)
  #checkWait(param)
#checkWait(param)
  case param['Response']
case param['Response']
    # Standard RESPONSES (to commands)
# Standard RESPONSES (to commands)
  when 'GetRevision' # Special Response
when 'GetRevision' # Special Response
    log('-----|---------GetRevision:' + param['Parameter1'])
log('-----|---------GetRevision:' + param['Parameter1'])
 
when 'GetLatLong' # Special Response
log('-----|---------GetLatLong: Lat=' + param['Lat'] + ', Long=' + param['Long'])
 
when 'SetLatLong'
if param['Parameter1'] == 'True' then
log('-----|---------SetLatLong: Ok')
else
log('-----X---------SetLatLong: FAILED!')
end
when 'SetPasswd'
 
when 'SetTimeZone'
 
when 'GetClock' # Special Response
 
when 'SetClock'
 
when 'SetNTPServer'
 
when 'Upgrade'
 
when 'NetCfg'
 
when 'Reset'
#Reset Response
 
cmdComplete
SndIns()
when 'LstTimers' # Special Response
 
 
when 'ClrTimers'
 
when 'AddTimer'
 
when 'GetTimer' # Special Response


  when 'GetLatLong' # Special Response
when 'SetTimer'
    log('-----|---------GetLatLong: Lat=' + param['Lat'] + ', Long=' + param['Long'])


  when 'SetLatLong'
when 'DelTimer'
    if param['Parameter1'] = 'True' then
      log('-----|---------SetLatLong: Ok')
    else
      log('-----X---------SetLatLong: FAILED!')
    end
  when 'SetPasswd'


  when 'SetTimeZone'
when 'GetVersion' # Special Response


  when 'GetClock' # Special Response
when 'SndGrp'


  when 'SetClock'
when 'SndIns' # response from SndIns
### BUG FOUND ### When the EZBridge receives a command from an EXTERNAL source
### ie not from this device, cmdqueue will be nil, and the code below
### fails. Have to check against that.
if $cmdqueue.length > 0
#First, check the response to make sure the command made it ok.
if param['Parameter9'].to_i == 6 #Ack received
#log('Sending to ProcessACK')
processACK(param)
else # NACK received - command failed.
log('Command NACKED')
end
else
#Response received for another device.
log('Response detected for a command that was not sent by me')
end
when 'SndX10'
log('Response detected for SndX10')
if param['Parameter5'].to_i == 6 #ack
log('X10 Command Successfull')


  when 'SetNTPServer'
cmdComplete
SndIns()
else
log('X10 Command FAILED')
cmdComplete
SndIns()


  when 'Upgrade'
end
when 'StLnk'


  when 'NetCfg'
when 'CancelLnk'


  when 'Reset'
when 'SetDev'
    #Reset Response


    cmdComplete
when 'RstPLM'
    SndIns()
#Reset Response
  when 'LstTimers'  # Special Response
$timeout = 1
cmdComplete
SndIns()


when 'GetLnk'
if param['Parameter3'].to_i == 6 #ack
log('GetLnk ACKED')
#if we get this, we should get a AllLink Record Response next
else
log('GetLnk NACKED')
# The PLM is BLANK
#have to add records to the PLM here.
cmdComplete
### FINISHED WITH GetLnk
checkChildRecordsinPLM()
SndIns()
end
when 'GetNext'
if param['Parameter3'].to_i == 6 #ack
log('sendGetNext ACKED')
#if we get this, we should get a AllLink Record Response next
else
log('sendGetNext NACKED')
#we get this when there are no more records
cmdComplete
#FINISHED with GetNext
# if we are here, we are in config mode
# so, next is to check to make sure the
# childrens insteon ID is in the PLM
checkChildRecordsinPLM()
# now, to make sure that all the records in the PLM are sensed as children


  when 'ClrTimers'
SndIns()
end


  when 'AddTimer'
when 'SetCfg' # response from Setcfg command
if param['Parameter4'].to_i == 6 #ack
log('SetCfg Completed')
cmdComplete
SndIns()
else
log('SetCfg NACKED')
end
when 'GetLnkData'


  when 'GetTimer'   # Special Response
when 'LEDON'


  when 'SetTimer'
when 'LEDOFF'


  when 'DelTimer'
when 'MngLnk'
if param['Parameter12'].to_i == 6
log('MngLnk => ACK')
else
log('MngLnk => NACK')
end
cmdComplete
SndIns()


  when 'GetVersion' # Special Response
when 'GetCfg' # Special Response


  when 'SndGrp'
when 'LstMacros' # Special Response


  when 'SndIns' # response from SndIns
when 'ClrMacros'
    ### BUG FOUND ### When the EZBridge receives a command from an EXTERNAL source
    ### ie not from this device, cmdqueue will be nil, and the code below
    ### fails.  Have to check against that.
    if $cmdqueue.length > 0
      #First, check the response to make sure the command made it ok.
      if param['Parameter9'].to_i == 6 #Ack received
#log('Sending to ProcessACK')
        processACK(param)
      else # NACK received - command failed.
        log('Command NACKED')
      end
    else
      #Response received for another device.
      log('Response detected for a command that was not sent by me')
    end
  when 'SndX10'
    log('Response detected for SndX10')


  when 'StLnk'
when 'AddMacro'


  when 'CancelLnk'
when 'GetMacro' # Special Response


  when 'SetDev'
when 'SetMacro'


  when 'RstPLM'
when 'DelMacro'
    #Reset Response
    $timeout = 3
    cmdComplete
    SndIns()


  when 'GetLnk'
when 'LstDevices' # Special Response
    if param['Parameter3'].to_i == 6 #ack
      log('GetLnk ACKED')
      #if we get this, we should get a AllLink Record Response next
    else
      log('GetLnk NACKED')
      # The PLM is BLANK
      #have to add records to the PLM here.
      cmdComplete
      ### FINISHED WITH GetLnk
      checkChildRecordsinPLM()
    end
  when 'GetNext'
    if param['Parameter3'].to_i == 6 #ack
      log('sendGetNext ACKED')
      #if we get this, we should get a AllLink Record Response next
    else
      log('sendGetNext NACKED')
      #we get this when there are no more records
      cmdComplete
      #FINISHED with GetNext
      # if we are here, we are in config mode
      # so, next is to check to make sure the
      # childrens insteon ID is in the PLM
      checkChildRecordsinPLM()
      SndIns()
    end


  when 'SetCfg' # response from Setcfg command
when 'ClrDevices'
    if param['Parameter4'].to_i == 6 #ack
      log('SetCfg Completed')
      cmdComplete
      SndIns()
    else
      log('SetCfg NACKED')
    end
  when 'GetLnkData'


  when 'LEDON'
when 'AddDevice'


  when 'LEDOFF'
when 'GetDevice' # Special Response


  when 'MngLnk'
when 'SetDevice'
    if param['Parameter12'].to_i == 6
      log('MngLnk => ACK')
    else
      log('MngLnk => NACK')
    end
    cmdComplete
    SndIns()


  when 'GetCfg' # Special Response
when 'DelDevice'


  when 'LstMacros' # Special Response
when 'LstZones'


  when 'ClrMacros'
when 'ClrZones'


  when 'AddMacro'
when 'AddZone'


  when 'GetMacro' # Special Response
when 'GetZone'


  when 'SetMacro'
when 'SetZone'


  when 'DelMacro'
when 'DelZone'


  when 'LstDevices' # Special Response
when 'AddDevZone'


  when 'ClrDevices'
when 'DelDevZone'


  when 'AddDevice'
# Response Messages
when 'InsExtMsg'


  when 'GetDevice' # Special Response
when 'InsStdMsg'
case $currentcmd # if this msg is part of a response, the Insteon Cmd1 will be saved here.
when 0x0
#log('REROUTING to processExternalCommand(param)')
processExternalCommand(param)
when 0x1 #Assign to Group
### This is a broadcast message sent
# from a PING command
# or from a StartLink...
log('Caught Assign to Group Message from Device')
### BUG HERE
#have to check flags to see if this is a broadcast message
log('Checking if this is a broadcast message')
log('Flags:' + param['Parameter9'])
if (param['Parameter9'].hex & 0x80) == 0x80
log('Message IS BROADCAST')
#recvComplete
processDeviceInfo(param)


  when 'SetDevice'
# check to see if current cmd is for this broadcast..
log('Current Command:' + $cmdqueue[0]['Parameter5'])
if $cmdqueue[0]['Parameter5'] == '10'
#log('Clearing PING Command')
$currentcmd = 0
cmdComplete
SndIns()
else
log('CURRENT CMD IS NOT PING - NOT CLEARING')
end


  when 'DelDevice'
else
log('Message is NOT Broadcast')
end
when 0x2 #Delete from Group
when 0x10 # PING
#this is where I catch the InsStdMsg for ping.
log('Caught PING Message from Device')
$currentcmd = 1


  when 'LstZones'
when 0x11 # ON
log('Caught Insteon ON from INTERNAL source')
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']


  when 'ClrZones'
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
log('Current DIM level:' + param['Parameter11'])


  when 'AddZone'
reportStatus(myDevFrom, hextopercent(param['Parameter11']))


  when 'GetZone'
$currentcmd = 0
cmdComplete


  when 'SetZone'
SndIns()
when 0x13 # OFF
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
reportStatus(myDevFrom, 0)


  when 'DelZone'
$currentcmd = 0
cmdComplete
#log('EVENT and state SENT!!!.48:[10]=0')
SndIns()
#####Thermostat Does Not report Status correctly Yet. Have to figure out reportStatus###
when 0x6A #Thermostat Control Get Zone Data (Temp, Setpoint,Humidity)
log('Thermostat returned Zone Info: ' + param['Parameter11'].to_s)
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
#reportStatus(myDevFrom, hextopercent(param['Parameter11']))
$currentcmd = 0
cmdComplete
SndIns()


  when 'AddDevZone'
when 0x6B #Thermostat Control Command Handle Response
log('Thermostat returned: ' + param['Parameter11'].to_s)
case param['Parameter11'].to_s
when '06' # ON/Auto
# $ThermostatStatus = 'ON/Auto' ##not used
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
#log('Current Thermostat State:' + $ThermostatStatus)
#reportStatus(myDevFrom, 6)
$currentcmd = 0
cmdComplete
SndIns()


  when 'DelDevZone'
when '09' #OFF
# $ThermostatStatus = 'OFF' ## not used may be for reportstatus
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
#log('Current Thermostat State:' + $ThermostatStatus)
#reportStatus(myDevFrom, 9)
$currentcmd = 0
cmdComplete
SndIns()


    # Response Messages
when '04' # Heat
  when 'InsExtMsg'  
#$ThermostatStatus = 'HEAT'
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
#log('Current Thermostat State:' + $ThermostatStatus)
#reportStatus(myDevFrom, 4)
$currentcmd = 0
cmdComplete
SndIns()


  when 'InsStdMsg'
when '05' # Cool
    case $currentcmd # if this msg is part of a response, the Insteon Cmd1 will be saved here.
#$ThermostatStatus = 'COOL'
    when 0x0
insHb = param['Parameter3'] # From
      #log('REROUTING to processExternalCommand(param)')
insMb = param['Parameter4']
      processExternalCommand(param)
insLb = param['Parameter5']
    when 0x1 #Assign to Group
insID = insHb + "." + insMb + "." + insLb
      ### This is a broadcast message sent
myDevFrom = $children[insID]
      # from a PING command
#log('Current Thermostat State:' + $ThermostatStatus)
      # or from a StartLink...
#reportStatus(myDevFrom, 5)
      log('Caught Assign to Group Message from Device')
$currentcmd = 0
      ### BUG HERE
cmdComplete
      #have to check flags to see if this is a broadcast message
SndIns()
      log('Checking  if this is a broadcast message')
      log('Flags:' + param['Parameter9'])
      if (param['Parameter9'].hex & 0x80) == 0x80
        log('Message IS BROADCAST')
        #recvComplete
        processDeviceInfo(param)
       
        # check to see if current cmd is for this broadcast..
        log('Current Command:' + $cmdqueue[0]['Parameter5'])
        if $cmdqueue[0]['Parameter5'] == '10'
          #log('Clearing PING Command')
          $currentcmd = 0
          cmdComplete
          SndIns()
        else
          log('CURRENT CMD IS NOT PING - NOT CLEARING')
        end


      else
        log('Message is NOT Broadcast')
      end
    when 0x2 #Delete from Group
    when 0x10 # PING
      #this is where I catch the InsStdMsg for ping.
      log('Caught PING Message from Device')
      $currentcmd = 1
    when 0x11 # ON
      log('Caught Insteon ON from INTERNAL source')
      insHb = param['Parameter3'] # From
      insMb = param['Parameter4']
      insLb = param['Parameter5']


      insID = insHb + "." + insMb + "." + insLb
when '07' # Fan On
      myDevFrom = $children[insID]
2#$ThermostatStatus = 'COOL'
      log('Current DIM level:' + param['Parameter11'])
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
#log('Current Thermostat State:' + $ThermostatStatus)
#reportStatus(myDevFrom, 5)
$currentcmd = 0
cmdComplete
SndIns()


      reportStatus(myDevFrom, hextopercent(param['Parameter11']))


      $currentcmd = 0
when '08' # Fan Off
      cmdComplete
#$ThermostatStatus = 'COOL'
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
#log('Current Thermostat State:' + $ThermostatStatus)
#reportStatus(myDevFrom, 5)
$currentcmd = 0
cmdComplete
SndIns()
end


      SndIns()
    when 0x13 # OFF
      insHb = param['Parameter3'] # From
      insMb = param['Parameter4']
      insLb = param['Parameter5']
      insID = insHb + "." + insMb + "." + insLb
      myDevFrom = $children[insID]
      reportStatus(myDevFrom, 0)


      $currentcmd = 0
when 0x6C #Thermostat Control Get Zone Cool Point Data
      cmdComplete
log('Thermostat returned Zone Info: ' + param['Parameter11'].to_s)
      log('EVENT and state SENT!!!.48:[10]=0')
insHb = param['Parameter3'] # From
      SndIns()
insMb = param['Parameter4']
    when 0x19 # Status Report
insLb = param['Parameter5']
      # now to clear the currentcmd and remove command from the queue
insID = insHb + "." + insMb + "." + insLb
      $currentcmd = 0
myDevFrom = $children[insID]
      cmdComplete
log('Current Zone level:' + param['Parameter11'].to_s)
#reportStatus(myDevFrom, hextopercent(param['Parameter11']))
$currentcmd = 0
cmdComplete
SndIns()


      log('Processing 0x19 Status Report')
when 0x6D #Thermostat Control Get Zone Heat Point Data
      #This is where I get the database delta (in cmd1)
log('Thermostat returned Zone Info: ' + param['Parameter11'].to_s)
      insHb = param['Parameter3'] # From
insHb = param['Parameter3'] # From
      insMb = param['Parameter4']
insMb = param['Parameter4']
      insLb = param['Parameter5']
insLb = param['Parameter5']
      insID = insHb + "." + insMb + "." + insLb
insID = insHb + "." + insMb + "." + insLb
      #First, to compare the DB Delta with current config.
myDevFrom = $children[insID]
      #Database Delta...
log('Current Zone level:' + param['Parameter11'].to_s)
      delta = param['Parameter10'].to_s
#reportStatus(myDevFrom, hextopercent(param['Parameter11']))
      log($redBack + 'Database Delta=' + delta + $blackBack)
$currentcmd = 0
      log($redBack + 'Configuration is:' + getdeltafromconfig(insID) + $blackBack)
cmdComplete
      if delta == getdeltafromconfig(insID)
SndIns()
if $children[insID] != nil
          myDevFrom = $children[insID]
          myDevTo = -1000 #DCE Router
          myPriority = 1
          myType = 2 #Event


          #Send an EVENT to report STATE ONLY if database has not changed
          # AND child exists in pluto
          reportStatus(myDevFrom, hextopercent(param['Parameter11']))
end
      else
        log('Databse CHANGED -getting remote database')
        #here, I have to WIPE the databse
        # to prepare it for new data
### here is where the DAMN CONFIG was reset!!!
oldconfigstring = $childdatabases[insID][0]
        $childdatabases[insID] = [oldconfigstring]
        log('Setting Database Config')
        $childdatabases[insID][0][6..7] = delta
        savechilddatabases(insID)
        sendRemoteGetLink(insID)
      end
      # finally, to check execute next command...
      SndIns()
    when 0x28 # Set Address MSB
      log('Received SET Address MSB from remote device')
      $currentcmd = 0
      $remoteLinkRecord = ''
      cmdComplete
      SndIns()
    when 0x2B # peek
      ### BUG HERE... have to verify response is a PEEK command
      #response command is stored in parameter10
      if param['Parameter10'].hex == 0x2B # this is the peek command
        cmdComplete
        log('Received PEEK from remote Device! DATA=' + param['Parameter11'])
        checkPeekData(param)
        $currentcmd = 0
        SndIns()
      else
        log('Waiting for remote PEEK response, but got :' + param['Parameter10'])
      end
    else
    end


  when 'X10Msg'
when 0x19 # Status Report
    log($purple + 'X10 Message Received' + $grey)
# now to clear the currentcmd and remove command from the queue
    if param['Parameter4'].hex == 0x00
$currentcmd = 0
      log('This byte is a House/Unit Code')
cmdComplete
      hn = param['Parameter3'][0].chr
      ln = param['Parameter3'][1].chr
      $x10byte1 = $X10HouseCodes[hn]
      $x10byte1 += $X10UnitCodes[ln]
      log('Translated X10 House/Unit Code:' + $x10byte1)
    else
      log('This byte is a House/Command Code')
      hn = param['Parameter3'][0].chr
      ln = param['Parameter3'][1].chr
      #$x10byte2 = $X10HouseCodes[hn]
      $x10byte2 = $X10CommandCodes[ln]
      log('Translated X10 Command Code:' + $x10byte2)
      log('X10 Command ready to send:' + $x10byte1 + ' ' + $x10byte2)
      case $x10byte2
      when 'On'
        #Send ON to lmnce
        if $children[$x10byte1] == nil
          log('I do not control this X10 device')
        else
          cmd = Command.new(device_.devid, -1000, 1, 1, 192)
          SendCommand(cmd)
        end
        $x10byte1 = ''
        $x10byte2 = ''
      when 'Off'
        #Send OFF to lmnce
        if $children[$x10byte1] == nil
          log('I do not control this X10 device')
        else
          cmd = Command.new(device_.devid, -1000, 1, 1, 193)
          SendCommand(cmd)
        end
        $x10byte1 = ''
        $x10byte2 = ''
      when 'Bright'
      when 'Dim'
      when 'All Lights Off'
      when 'All Lights On'
      when 'Status Request'
      when 'Hail Ack'
      end
    end
  when 'InsLnkSts'
    log('InsLnkSts Received')


  when 'BtnRpt'
log('Processing 0x19 Status Report')
    log('Button Report Received')
#This is where I get the database delta (in cmd1)
  when 'UsrRst'
insHb = param['Parameter3'] # From
    log('User Reset Response Received')
insMb = param['Parameter4']
  when 'GrpEvntRpt'
insLb = param['Parameter5']
    log('Group Event Report Received')
insID = insHb + "." + insMb + "." + insLb
#First, to compare the DB Delta with current config.
#Database Delta...
delta = param['Parameter10'].to_s
log($blue + 'Database Delta=' + delta + $grey)
log($blue + 'Configuration is:' + getdeltafromconfig(insID) + $grey)
if delta == getdeltafromconfig(insID)
if $children[insID] != nil
myDevFrom = $children[insID]
myDevTo = -1000 #DCE Router
myPriority = 1
myType = 2 #Event


  when 'LnkData'
#Send an EVENT to report STATE ONLY if database has not changed
    processLnkData(param)
# AND child exists in pluto
    # Other messages
reportStatus(myDevFrom, hextopercent(param['Parameter11']))
  when 'PLMTimeout'
end
    log('PLM Timeout detected.. resetting EZBridge')
else
    resetcmd = {'Command' => 'Reset'}
log('Databse CHANGED -getting remote database')
    if $wAIT == true
#here, I have to WIPE the databse
      $cmdqueue.insert(1, resetcmd)
# to prepare it for new data
    else
### here is where the DAMN CONFIG was reset!!!
      $cmdqueue.insert(0,resetcmd)
oldconfigstring = $childdatabases[insID][0]
    end
$childdatabases[insID] = [oldconfigstring]
    sleep 15
log('Setting Database Config')
    $wAIT = false
$childdatabases[insID][0][6..7] = delta
    SndIns()
savechilddatabases(insID)
  when 'PLMEchoError' # Have not seen this since a1.23
sendRemoteGetLink(insID)
    # error sending command to PLM, reset command and try again
end
    log('-----XXXXXXX' + param['Response'])
# finally, to check execute next command...
    resetcmd = {'Command' => 'Reset'}
SndIns()
    if $wAIT == true
when 0x28 # Set Address MSB
      $cmdqueue.insert(1, resetcmd)
log('Received SET Address MSB from remote device')
    else
$currentcmd = 0
      $cmdqueue.insert(0,resetcmd)
$remoteLinkRecord = ''
    end
cmdComplete
SndIns()
when 0x2B # peek
### BUG HERE... have to verify response is a PEEK command
#response command is stored in parameter10
if param['Parameter10'].hex == 0x2B # this is the peek command
cmdComplete
log('Received PEEK from remote Device! DATA=' + param['Parameter11'])
checkPeekData(param)
$currentcmd = 0
SndIns()
else
log('Waiting for remote PEEK response, but got :' + param['Parameter10'])
end
else
end


    sleep 15
when 'X10Msg'
    $wAIT = false
log($purple + 'X10 Message Received' + $grey)
    SndIns()
if param['Parameter4'].hex == 0x00
  when 'LongAck'
log('This byte is a House/Unit Code')
    log('-----XXXXXXX' + param['Response'])
hn = param['Parameter3'][0].chr
    # Error - seems to show up after PLMEchoError
ln = param['Parameter3'][1].chr
    resetcmd = {'Command' => 'Reset'}
$x10byte1 = $X10HouseCodes[hn]
    if $wAIT == true
$x10byte1 += $X10UnitCodes[ln]
      $cmdqueue.insert(1, resetcmd)
log('Translated X10 House/Unit Code:' + $x10byte1)
    else
else
      $cmdqueue.insert(0,resetcmd)
log('This byte is a House/Command Code')
    end
hn = param['Parameter3'][0].chr
    sleep 15
ln = param['Parameter3'][1].chr
    $wAIT = false
$x10byte2 = $X10HouseCodes[hn]
    SndIns()
$x10byte2 += $X10CommandCodes[ln]
  else
log('Translated X10 Command Code:' + $x10byte2)
    log('-----XXXXXXX UNKNOWN Response Received:' + param['Response'])
log('X10 Command ready to send:' + $x10byte1 + ' ' + $x10byte2)
  end
case $X10CommandCodes[ln]
when 'On'
#Send ON to lmnce
if $children[$x10byte1] == nil
log('I do not control this X10 device')
else
cmd = Command.new($children[$x10byte1].to_i, -1000, 1, 1, 192)
cmd.params_[120] = "1"
SendCommand(cmd)
end
when 'Off'
#Send OFF to lmnce
if $children[$x10byte1] == nil
log('I do not control this X10 device')
else
cmd = Command.new($children[$x10byte1].to_i, -1000, 1, 1, 193)
cmd.params_[120] = "1"
SendCommand(cmd)
end
when 'Bright'
if $children[$x10byte1] == nil
log('I do not control this X10 device')
else
#send a command to set the state + 1
@curstate = ($state[$x10byte1] / 100) * 32 #get equal 32 steps
$state[$x10byte1] = ((@curstate + 1) / 32) * 100
cmd = Command.new($children[$x10byte1].to_i, -1000, 1, 1, 184)
cmd.params_[76] = $state[$x10byte1].to_s
cmd.params_[120] = "1"
SendCommand(cmd)
#$state[$x10byte1] = ($state[$x10byte1] / 100) * 32
end
when 'Dim'
@curstate = ($state[$x10byte1] / 100) * 32 #get equal 32 steps
$state[$x10byte1] = ((@curstate - 1) / 32) * 100
cmd = Command.new($children[$x10byte1].to_i, -1000, 1, 1, 184)
cmd.params_[76] = $state[$x10byte1].to_s
cmd.params_[120] = "1"
SendCommand(cmd)
when 'All Lights Off'
log('ALL Lights OFF Command not implemented')
when 'All Lights On'
log('All Lights ON Command not implemented')
when 'Status Request'
log('Status Request Command not implemented')
when 'Hail Ack'
log('Hail Ack Command not implemented')
end
 
end
when 'InsLnkSts'
log('InsLnkSts Received')
 
when 'BtnRpt'
log('Button Report Received')
when 'UsrRst'
log('User Reset Response Received')
when 'GrpEvntRpt'
log('Group Event Report Received')
 
when 'LnkData'
processLnkData(param)
# Other messages
when 'PLMTimeout'
log('PLM Timeout detected.. resetting EZBridge')
resetcmd = {'Command' => 'Reset'}
if $wAIT == true
$cmdqueue.insert(1, resetcmd)
else
$cmdqueue.insert(0,resetcmd)
end
sleep 15
$wAIT = false
SndIns()
when 'PLMEchoError' # Have not seen this since a1.23
# error sending command to PLM, reset command and try again
log('-----XXXXXXX' + param['Response'])
resetcmd = {'Command' => 'Reset'}
if $wAIT == true
$cmdqueue.insert(1, resetcmd)
else
$cmdqueue.insert(0,resetcmd)
end
 
sleep 15
$wAIT = false
SndIns()
when 'LongAck'
log('-----XXXXXXX' + param['Response'])
# Error - seems to show up after PLMEchoError
resetcmd = {'Command' => 'Reset'}
if $wAIT == true
$cmdqueue.insert(1, resetcmd)
else
$cmdqueue.insert(0,resetcmd)
end
sleep 15
$wAIT = false
SndIns()
else
log('-----XXXXXXX UNKNOWN Response Received')
end


end
end
Line 577: Line 753:
### Support routine for EZToDCE
### Support routine for EZToDCE
def processLnkData(param)
def processLnkData(param)
  #Caught a LnkData Response
#Caught a LnkData Response
  log('LnkData Message Received')
log('LnkData Message Received')
  insteonID = padhex(param['Parameter5']) + '.' + padhex(param['Parameter6']) + '.' + padhex(param['Parameter7'])
log(param.inspect)
  group = param['Parameter4']
if param['Parameter6'] == '00' and param['Parameter7'] == '00'
  recflags = param['Parameter3']
log('FOUND X10 DEVICE!!!')
  lnkdata1 = param['Parameter8']
insteonID = padhex(param['Parameter5'])
  lnkdata2 = param['Parameter9']
else
  lnkdata3 = param['Parameter10']
insteonID = padhex(param['Parameter5']) + '.' + padhex(param['Parameter6']) + '.' + padhex(param['Parameter7'])
  #pack string to store for PLM Database
end
  @currentrecord = recflags + group
group = param['Parameter4']
  @currentrecord += param['Parameter5'] + param['Parameter6'] + param['Parameter7']
recflags = param['Parameter3']
  @currentrecord += lnkdata1 + lnkdata2 + lnkdata3
lnkdata1 = param['Parameter8']
lnkdata2 = param['Parameter9']
lnkdata3 = param['Parameter10']
#pack string to store for PLM Database
@currentrecord = recflags + group
@currentrecord += param['Parameter5'] + param['Parameter6'] + param['Parameter7']
@currentrecord += lnkdata1 + lnkdata2 + lnkdata3


  #Add to plmdatabase
#Add to plmdatabase
  $plmdatabase << @currentrecord
$plmdatabase << @currentrecord
  log('PLM database=' +$plmdatabase.inspect)
log('record Flags:' + recflags)
  if (recflags[0] & 0x80) == 0x80 # Record is in use if true  
#log('PLM database=' +$plmdatabase.inspect)
  end
if (recflags[0] & 0x80) == 0x80 # Record is in use if true
  if (recflags[0] & 0x40) == 0x40 # Controller if true
end
    log('Controller')
if (recflags[0] & 0x40) == 0x40 # Controller if true
  else
log('Controller')
    log('Responder')
else
  end
log('Responder')
end


  log('Insteon ID:' + insteonID + ', Group:' + group)
log('Insteon ID:' + insteonID + ', Group:' + group)


  cmdComplete
cmdComplete
  sendGetNext()
sendGetNext()


end
end
### Support Routine for EZToDCE
### Support Routine for EZToDCE
def processExternalCommand(param)
def processExternalCommand(param)
  #there is no current command  
#there is no current command
  # THIS IS COMING FROM AN OUTSIDE SOURCE
# THIS IS COMING FROM AN OUTSIDE SOURCE
  #EG: Manually turning Light Switch On/Off
#EG: Manually turning Light Switch On/Off
  # process this command.
# process this command.
  # Note, this is a standard message
# Note, this is a standard message
  ### have to check here if child is mine!
### have to check here if child is mine!
 
# This is where I have to check for a broadcast command..
#if so, search the child databases for responders,
#and fire events for each responder.
#Message flag is in parameter9 Group command 0xCx (All-Link Broadcast Message Pg 42.)
#Group is in parameter8
#From InsteonID is parameters 3, 4, 5
if (param['Parameter9'].hex & 0xC0) == 0xC0 # Message is Broadcast
log('Rerouting to processBroadcastMessage')
processBroadcastMessage(param)
else
log('Process External Command:')
log('Param:' + param.inspect)
 
# there is no ack here. Simply Send COMMANDS back to DCE
# and Complete the recv..
case param['Parameter10'].hex #this is the command
when 0x01 #Assign to Group
log('Caught EXTERNAL Assign to Group')
processDeviceInfo(param)
recvComplete
when 0x02 #Delete from Group
when 0x02 #Delete from Group
log('Caught EXTERNAL Delete from Group')
recvComplete
when 0x10 # PING
log('Caught EXTERNAL Insteon PING result')
recvComplete
 
 
when 0x11 #ON
log('Caught EXTERNAL Insteon ON command result')
#on level is in cmd2
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
log('From:' +insID)
log('Device:' + $children[insID].to_s)
myDevFrom = $children[insID]
# check to see if I own child
if myDevFrom == nil
log('I do not control this device.')
else
reportStatus(myDevFrom, hextopercent(param['Parameter11']))
$currentcmd = 0
end
recvComplete
 
 


  # This is where I have to check for a broadcast command..
when 0x13 #OFF
  #if so, search the child databases for responders,
log('Caught EXTERNAL Insteon OFF result')
  #and fire events for each responder.
#on level is in cmd2
  #Message flag is in parameter9 Group command 0xCx (All-Link Broadcast Message Pg 42.)
insHb = param['Parameter3'] # From
  #Group is in parameter8
insMb = param['Parameter4']
  #From InsteonID is parameters 3, 4, 5
insLb = param['Parameter5']
  if (param['Parameter9'].hex & 0xC0) == 0xC0 # Message is Broadcast
insID = insHb + "." + insMb + "." + insLb
    log('Rerouting to processBroadcastMessage')
myDevFrom = $children[insID]
    processBroadcastMessage(param)
if myDevFrom == nil
  else
log('I do not control this device.')
    log('Process External Command:')
else
    log('Param:' + param.inspect)


    # there is no ack here.  Simply Send EVENTS back to DCE
reportStatus(myDevFrom, 0)
    # and Complete the recv..
 
    case param['Parameter10'].hex #this is the command
$currentcmd = 0
    when 0x01 #Assign to Group
#log('EVENT and state SENT!!!.48:[10]=0')
      log('Caught EXTERNAL Assign to Group')
end
      processDeviceInfo(param)
recvComplete
      recvComplete
    when 0x02 #Delete from Group
      log('Caught EXTERNAL Delete from Group')
      recvComplete
    when 0x10 # PING
      log('Caught EXTERNAL Insteon PING result')
      recvComplete


when 0x6A #Thermostat Zone Command
log('Caught EXTERNAL Insteon Thermostat result')
#on level is in cmd2
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
if myDevFrom == nil
log('I do not control this device.')
else
#case param['Parameter11'].to_s
#when '00'
reportStatus(myDevFrom, hextoTempurature(param['Parameter11']))
$currentcmd = 0
#when '60' #humidity
#when '20'#setpoint
#log('EVENT and state SENT!!!.48:[10]=0')
end


    when 0x11 #ON
when 0x6B #Thermostat Mode Command
      log('Caught EXTERNAL Insteon ON command result')
log('Caught EXTERNAL Insteon Thermostat result')
      #on level is in cmd2
#on level is in cmd2 ie( HEAT(0x04), COOL(0x05), or AUTO(0x06))
      insHb = param['Parameter3'] # From
insHb = param['Parameter3'] # From
      insMb = param['Parameter4']
insMb = param['Parameter4']
      insLb = param['Parameter5']
insLb = param['Parameter5']
      insID = insHb + "." + insMb + "." + insLb
insID = insHb + "." + insMb + "." + insLb
      log('From:' +insID)
myDevFrom = $children[insID]
      log('Device:' + $children[insID].to_s)
if myDevFrom == nil
      myDevFrom = $children[insID]
log('I do not control this device.')
      # check to see if I own child
else
      if myDevFrom == nil
#reportStatus(myDevFrom, 0)
        log('I do not control this device.')
$currentcmd = 0
      else
#log('EVENT and state SENT!!!.48:[10]=0')
reportStatus(myDevFrom, hextopercent(param['Parameter11']))
end
        $currentcmd = 0
      end
      recvComplete


when 0x6C #Thermostat Zone Cool Command
log('Caught EXTERNAL Insteon Thermostat result')
#on level is in cmd2
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
if myDevFrom == nil
log('I do not control this device.')
else
reportStatus(myDevFrom, hextoTempurature(param['Parameter11']))
$currentcmd = 0
#log('EVENT and state SENT!!!.48:[10]=0')
end


when 0x6D #Thermostat Zone Heat Command
log('Caught EXTERNAL Insteon Thermostat result')
#on level is in cmd2
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
if myDevFrom == nil
log('I do not control this device.')
else
reportStatus(myDevFrom, hextoTempurature(param['Parameter11']))
$currentcmd = 0
#log('EVENT and state SENT!!!.48:[10]=0')
end


    when 0x13 #OFF
      log('Caught EXTERNAL Insteon OFF result')
      #on level is in cmd2
      insHb = param['Parameter3'] # From
      insMb = param['Parameter4']
      insLb = param['Parameter5']
      insID = insHb + "." + insMb + "." + insLb
      myDevFrom = $children[insID]
      if myDevFrom == nil
        log('I do not control this device.')
      else


reportStatus(myDevFrom, 0)


        $currentcmd = 0
when 0x15; log('Caught EXTERNAL Insteon Brighten Result')
        log('EVENT and state  SENT!!!.48:[10]=0')
when 0x16; log('Caught EXTERNAL Insteon DIM Result')
      end
when 0x24; log('Caught EXTERNAL Insteon DO EE READ')
      recvComplete
when 0x28; log('Caught EXTERNAL Insteon SET ADDRESS MSB')
    when 0x15; log('Caught EXTERNAL Insteon Brighten Result')
when 0x29; log('Caught EXTERNAL Insteon POKE')
    when 0x16; log('Caught EXTERNAL Insteon DIM Result')
when 0x2A; log('Caught EXTERNAL Insteon POKE EXTENDED')
    when 0x24; log('Caught EXTERNAL Insteon DO EE READ')
when 0x2B; log('Caught EXTERNAL Insteon PEEK')
    when 0x28; log('Caught EXTERNAL Insteon SET ADDRESS MSB')
when 0x2C; log('Caught EXTERNAL Insteon PEEK INTERNAL')
    when 0x29; log('Caught EXTERNAL Insteon POKE')
when 0x2D; log('Caught EXTERNAL Insteon POKE INTERNAL')
    when 0x2A; log('Caught EXTERNAL Insteon POKE EXTENDED')
else
    when 0x2B; log('Caught EXTERNAL Insteon PEEK')
log('Unknown EXTERNAL Insteon Command.')
    when 0x2C; log('Caught EXTERNAL Insteon PEEK INTERNAL')
end
    when 0x2D; log('Caught EXTERNAL Insteon POKE INTERNAL')
end
    else
      log('Unknown EXTERNAL Insteon Command.')
    end
  end
end
end
### Support Routine for EZToDCE
### Support Routine for EZToDCE
def processACK(param)
def processACK(param)
  #log('In ProcessACK: Param7:' + param['Parameter7'])
#log('In ProcessACK: Param7:' + param['Parameter7'])
  #log('CurrentCmd=' + $currentcmd.to_s)
#log('CurrentCmd=' + $currentcmd.to_s)
  case param['Parameter7'].hex #Received an ack to THIS command
case param['Parameter7'].hex #Received an ack to THIS command
  when 0x1 #Assign to Group
when 0x1 #Assign to Group
    log('Got Assign to Group ACK')
log('Got Assign to Group ACK')
    $currentcmd = 0x01
$currentcmd = 0x01
    $cmdqueue[0]['Command'] = 'InsStdMsg'
$cmdqueue[0]['Command'] = 'InsStdMsg'
    #processDeviceInfo(param)
#processDeviceInfo(param)
    #cmdComplete
#cmdComplete
  when 0x2 #Delete from Group
when 0x2 #Delete from Group
  when 0x10 # PING
when 0x10 # PING
    log('Got PING ACK')
log('Got PING ACK')
    #cmdComplete
#cmdComplete
    $currentcmd = 0x1
$currentcmd = 0x1
    $cmdqueue[0]['Command'] = 'InsStdMsg'
$cmdqueue[0]['Command'] = 'InsStdMsg'
  when 0x11 #ON
when 0x11 #ON
    $currentcmd = 0x11
$currentcmd = 0x11
    $cmdqueue[0]['Command'] = 'InsStdMsg'
$cmdqueue[0]['Command'] = 'InsStdMsg'
  when 0x13 #OFF
when 0x13 #OFF
    $currentcmd = 0x13
$currentcmd = 0x13
    $cmdqueue[0]['Command'] = 'InsStdMsg'
$cmdqueue[0]['Command'] = 'InsStdMsg'
  when 0x15 #Bright
when 0x6A #Thermostat Zone Command
    $currentcmd = 0x15
$currentcmd = 0x6A
    $cmdqueue[0]['Command'] = 'InsStdMsg'
$cmdqueue[0]['Command'] = 'InsStdMsg'
  when 0x16 #DIM
when 0x6B #Thermostat Control Command
    $currentcmd = 0x16
$currentcmd = 0x6B
    $cmdqueue[0]['Command'] = 'InsStdMsg'
$cmdqueue[0]['Command'] = 'InsStdMsg'
  when 0x17 #Start Manual Change
when 0x6C #Thermostat Cool Command
  when 0x18 #Stop Manual Change
$currentcmd = 0x6C
  when 0x19 #Status Request
$cmdqueue[0]['Command'] = 'InsStdMsg'
    # Status Request Acked - get ready for InsStdMsg
when 0x6D #Thermostat Cool Command
    $currentcmd = 0x19
$currentcmd = 0x6D
    # change cmd to reflect InsStdMsg
$cmdqueue[0]['Command'] = 'InsStdMsg'
    $cmdqueue[0]['Command'] = 'InsStdMsg'
when 0x15 #Bright
  when 0x24
$currentcmd = 0x15
    log('Caught ACK for Insteon DO EE READ')
$cmdqueue[0]['Command'] = 'InsStdMsg'
    $currentcmd = 0x24
when 0x16 #DIM
    $cmdqueue[0]['Command'] = 'InsStdMsg'
$currentcmd = 0x16
  when 0x28
$cmdqueue[0]['Command'] = 'InsStdMsg'
    log('Caught ACK for Insteon SET ADDRESS MSB')
when 0x17 #Start Manual Change
    $currentcmd = 0x28
when 0x18 #Stop Manual Change
    $cmdqueue[0]['Command'] = 'InsStdMsg'
when 0x19 #Status Request
     
# Status Request Acked - get ready for InsStdMsg
  when 0x29
$currentcmd = 0x19
    log('Caught ACK for Insteon POKE')
# change cmd to reflect InsStdMsg
    $currentcmd = 0x29
$cmdqueue[0]['Command'] = 'InsStdMsg'
    $cmdqueue[0]['Command'] = 'InsStdMsg'
when 0x24
     
log('Caught ACK for Insteon DO EE READ')
  when 0x2A
$currentcmd = 0x24
    log('Caught ACK for Insteon POKE EXTENDED')
$cmdqueue[0]['Command'] = 'InsStdMsg'
    $currentcmd = 0x2A
when 0x28
    $cmdqueue[0]['Command'] = 'InsStdMsg'
log('Caught ACK for Insteon SET ADDRESS MSB')
     
$currentcmd = 0x28
  when 0x2B
$cmdqueue[0]['Command'] = 'InsStdMsg'
    #log('Caught ACK for Insteon PEEK')
 
    $currentcmd = 0x2B
when 0x29
    $cmdqueue[0]['Command'] = 'InsStdMsg'
log('Caught ACK for Insteon POKE')
     
$currentcmd = 0x29
  when 0x2C
$cmdqueue[0]['Command'] = 'InsStdMsg'
    log('Caught ACK for Insteon PEEK INTERNAL')
 
    $currentcmd = 0x2C
when 0x2A
    $cmdqueue[0]['Command'] = 'InsStdMsg'
log('Caught ACK for Insteon POKE EXTENDED')
     
$currentcmd = 0x2A
  when 0x2D
$cmdqueue[0]['Command'] = 'InsStdMsg'
    log('Caught ACK for Insteon POKE INTERNAL')
 
    $currentcmd = 0x2D
when 0x2B
    $cmdqueue[0]['Command'] = 'InsStdMsg'
#log('Caught ACK for Insteon PEEK')
     
$currentcmd = 0x2B
  else
$cmdqueue[0]['Command'] = 'InsStdMsg'
    log('Unknown Insteon Cmd1')
 
  end
when 0x2C
log('Caught ACK for Insteon PEEK INTERNAL')
$currentcmd = 0x2C
$cmdqueue[0]['Command'] = 'InsStdMsg'
 
when 0x2D
log('Caught ACK for Insteon POKE INTERNAL')
$currentcmd = 0x2D
$cmdqueue[0]['Command'] = 'InsStdMsg'
 
else
log('Unknown Insteon Cmd1')
end
end
end


Line 775: Line 1,042:
def checkPeekData(param)
def checkPeekData(param)


  $remoteLinkRecord += param['Parameter11'].hex.chr
$remoteLinkRecord += param['Parameter11'].hex.chr
  log('CURRENT REMOTE RECORD IS:')
log('CURRENT REMOTE RECORD IS:')
  debug($remoteLinkRecord)
debug($remoteLinkRecord)
  if $remoteLinkRecord.length == 8
if $remoteLinkRecord.length == 8
    log('REMOTE RECORD COMPLETE!')
log('REMOTE RECORD COMPLETE!')
    processRemoteRecord(param)
processRemoteRecord(param)
    $remoteLinkRecord = ''
$remoteLinkRecord = ''
  end
end
end
end




def processRemoteRecord(param)
def processRemoteRecord(param)
  #have to find MY address
#have to find MY address
  insHb = param['Parameter3'] # From
insHb = param['Parameter3'] # From
  insMb = param['Parameter4']
insMb = param['Parameter4']
  insLb = param['Parameter5']
insLb = param['Parameter5']
  insID = padhex(insHb) + "." + padhex(insMb) + "." + padhex(insLb)
insID = padhex(insHb) + "." + padhex(insMb) + "." + padhex(insLb)
 
log('Processing remote Record below:')


  log('Processing remote Record below:')
@flags = "\nFrom Device:" + insID + "\nFlags:\n"


  @flags = "\nFrom Device:" + insID + "\nFlags:\n"
if ($remoteLinkRecord[0] & 0x02) == 0x02 # High water mark
@flags += "Not the last record\n"
else
@flags += "This IS the last record\n"
end


  if ($remoteLinkRecord[0] & 0x02) == 0x02 # High water mark
if ($remoteLinkRecord[0] & 0x80) == 0x80 # Record is in use
    @flags += "Not the last record\n"
@flags += "Record In Use\n"
  else
if ($remoteLinkRecord[0] & 0x40) == 0x40 # Controller/Responder
    @flags += "This IS the last record\n"
@flags += "I am a Controller of "
  end
else
@flags += "I am a Responder of "
end
@insteonID = padhex("%X" %$remoteLinkRecord[2]) + '.'
@insteonID += padhex("%X" %$remoteLinkRecord[3]) + '.'
@insteonID += padhex("%X" %$remoteLinkRecord[4])


  if ($remoteLinkRecord[0] & 0x80) == 0x80 # Record is in use
@group = "%X" %$remoteLinkRecord[1]
    @flags += "Record In Use\n"
@flags += @insteonID + " Group:" + @group
    if ($remoteLinkRecord[0] & 0x40) == 0x40 # Controller/Responder
@work = padhex("%X" %$remoteLinkRecord[0]) #Control byte
      @flags += "I am a Controller of "
@work += padhex("%X" %$remoteLinkRecord[1]) # Group
    else
@work += padhex("%X" %$remoteLinkRecord[2]) # ID HB
      @flags += "I am a Responder of "
@work += padhex("%X" %$remoteLinkRecord[3]) # ID MB
    end
@work += padhex("%X" %$remoteLinkRecord[4]) # ID LB
    @insteonID = padhex("%X" %$remoteLinkRecord[2]) + '.'
@work += padhex("%X" %$remoteLinkRecord[5]) # Data1
    @insteonID += padhex("%X" %$remoteLinkRecord[3]) + '.'
@work += padhex("%X" %$remoteLinkRecord[6]) # Data2
    @insteonID += padhex("%X" %$remoteLinkRecord[4])
@work += padhex("%X" %$remoteLinkRecord[7]) # Data3
log('adding to:' + insID)
    @group = "%X" %$remoteLinkRecord[1]
log('Value:' + @work)
    @flags += @insteonID + " Group:" + @group
$childdatabases[insID] << @work #add it to the database
    @work = padhex("%X" %$remoteLinkRecord[0]) #Control byte
# log('Current Database:' + $childdatabases.inspect)
    @work += padhex("%X" %$remoteLinkRecord[1]) # Group
#now to save the database to configuration.
    @work += padhex("%X" %$remoteLinkRecord[2]) # ID HB
savechilddatabases(insID)
    @work += padhex("%X" %$remoteLinkRecord[3]) # ID MB
# Now to check to see if the child exists as a record
    @work += padhex("%X" %$remoteLinkRecord[4]) # ID LB
if $childdatabases[@insteonID] == nil
    @work += padhex("%X" %$remoteLinkRecord[5]) # Data1
log('InsteonID is NEW, adding Child database entry')
    @work += padhex("%X" %$remoteLinkRecord[6]) # Data2
$childdatabases[@insteonID] = ['****************']
    @work += padhex("%X" %$remoteLinkRecord[7]) # Data3
$rerun = true
    log('adding to:' + insID)
sendAddtoPLM(@insteonID)
    log('Value:' + @work)
sendPing(@insteonID)
    $childdatabases[insID] << @work #add it to the database
else
    log('Current Database:' + $childdatabases.inspect)
log('InsteonID:' + @insteonID.to_s + 'seems to exist in child databases')
    #now to save the database to configuration.
log('CDB:' + $childdatabases.inspect)
    savechilddatabases(insID)
    # Now to check to see if the child exists as a record
    if $childdatabases[@insteonID] == nil
      log('InsteonID is NEW, adding Child database entry')
      $childdatabases[@insteonID] = ['****************']
      $rerun = true
      sendAddtoPLM(@insteonID)
      sendPing(@insteonID)
    else
      log('InsteonID:' + @insteonID.to_s + 'seems to exist in child databases')
      log('CDB:' + $childdatabases.inspect)


    end
end
  else
else
    @flags += "Record NOT in use\n"
@flags += "Record NOT in use\n"
  end
end
  log($aqua + @flags + $grey)
log($aqua + @flags + $grey)
  log2(@flags)
log2(@flags)
  if ($remoteLinkRecord[0] & 0x02) == 0x02
if ($remoteLinkRecord[0] & 0x02) == 0x02
    sendRemoteGetNext(insID)
sendRemoteGetNext(insID)
  end
end
end
end


def savechilddatabases(insteonID)
def savechilddatabases(insteonID)
  #This takes the $childdatabase hash+array and encodes it to
#This takes the $childdatabase hash+array and encodes it to
  # save it as a string.
# save it as a string.
  @work = ''
@work = ''
  #log($yellow + 'SaveChildDatabases::nitems:' + $childdatabases[insteonID].nitems.to_s)
#log($yellow + 'SaveChildDatabases::nitems:' + $childdatabases[insteonID].nitems.to_s)
  #log($childdatabases[insteonID].inspect + $grey)
#log($childdatabases[insteonID].inspect + $grey)
  $childdatabases[insteonID].each{|record|
$childdatabases[insteonID].each{|record|
    @work += record
@work += record
  }
}


  #now to save the string...
#now to save the string...
  setdeviceconfig(insteonID, @work)
setdeviceconfig(insteonID, @work)


end
end
def sendPing(insteonID)
def sendPing(insteonID)
  insID = insteonID.split('.')
insID = insteonID.split('.')
  param = {'Command' => 'SndIns',
param = {'Command' => 'SndIns',
    'Parameter1' => insID[0],
'Parameter1' => insID[0],
    'Parameter2' => insID[1],
'Parameter2' => insID[1],
    'Parameter3' => insID[2],
'Parameter3' => insID[2],
    'Parameter4' => '0F',
'Parameter4' => '0F',
    'Parameter5' => '10', #ID Request
'Parameter5' => '10', #ID Request
    'Parameter6' => '00'}
'Parameter6' => '00'}
  $cmdqueue << param
$cmdqueue << param
  log('PING Sent!')
log('PING Sent!')
end
 
def getdevicetemplate(cat, subcat)
 
log('Entered getdevicetemplate, Cat=' + cat.to_s + ', subcat = ' + subcat.to_s)
@templid = 0
case cat.hex
when 0x0 # Generalized Controllers
case subcat.hex
when 0x04; log('Found ControLinc [2430]')
when 0x05; log('Found RemoteLinc [2440]')
when 0x06; log('Found Icon Tabletop Controller [2830]')
when 0x09; log('Found SignaLinc RF Signal Enhancer [2442]')
when 0x0A; log('Found Balboa Instruments Poolux LCD Controller')
when 0x0B; log('Found Access Point [2443]')
when 0x0C; log('Found IES Color Touchscreen')
end
when 0x01 # Dimmable Lighting Control
# all these devices are associated with Template 38
# Light Switch (dimmable)
@templid = 38
case subcat.hex
when 0x00; log('Found LampLinc V2 [2456D3]')
when 0x01; log('Found SwitchLinc V2 Dimmer 600W [2476D]')
when 0x02; log('Found In-LineLinc Dimmer [2475D]')
when 0x03; log('Found Icon Switch Dimmer [2876D]')
when 0x04; log('Found SwitchLinc V2 Dimmer 1000W [2476DH]')
when 0x06; log('Found LampLinc 2-pin [2456D2]')
when 0x07; log('Found Icon LampLinc V2 2-pin [2456D2]')
when 0x09; log('Found KeypadLinc Dimmer [2486D]')
when 0x0A; log('Found Icon In-Wall Controller [2886D]')
when 0x0D; log('Found SocketLinc [2454D]')
when 0x13; log('Found Icon SwitchLinc Dimmer for Lixar/Bell Canada [2676D-B]')
when 0x17; log('Found ToggleLinc Dimmer [2466D]')
end
when 0x02 # Switched Lighting Control
# all these devices are associated with Template 37
# Light Switch (ON/OFF)
@templid = 37
case subcat.hex
 
when 0x09; log('Found ApplianceLinc [2456S3]')
when 0x0A; log('Found SwitchLinc Relay [2476S]')
when 0x0B; log('Found Icon On Off Switch [2876S]')
when 0x0C; log('Found Icon Appliance Adapter [2856S3]')
when 0x0D; log('Found ToggleLinc Relay [2466S]')
when 0x0E; log('Found Switchlinc Relay Countdown Timer [2476ST]')
when 0x10; log('Found In-LineLinc Relay [2475D]')
when 0x13; log('Found Icon SwitchLinc Relay for Lixar/Bell Canada [2676R-B]')
end
when 0x03 # Network Bridges
case subcat.hex
when 0x01; log('Found PowerLinc Serial [2414S]')
when 0x02; log('Found PowerLinc USB [2414U]')
when 0x03; log('Found Icon PowerLinc Serial [2814S]')
when 0x04; log('Found Icon PowerLinc USB [2814U]')
when 0x05; log('Found Smartlabs Power Line Modem Serial [2412S]')
end
when 0x04 # Irrigation Control
# all these devices are associated with Template 1780
# Standard Irrigation Sprinkler
@templid = 1780
case subcat.hex
 
when 0x00; log('Found Simplehomenet EZRain1 Sprinkler Controller')
end
when 0x05 # Climate Control
case subcat.hex
when 0x00; log('Found Broan SMSC080 Exhaust Fan')
when 0x01; log('Found Simplehomenet EZTherm')
when 0x02; log('Found Broan SMSC110 Exhaust Fan')
when 0x03
log('Found Venstar RF Thermostat Module')
@templid = 2198 #Set Template
when 0x04; log('Found Simplehomenet EZStat Thermostat')
end
when 0x06 # Pool and Spa Control
case subcat.hex
when 0x00; log('Found Simplehomenet EZPool')
end
when 0x07 # Sensors and Actuators
case subcat.hex
when 0x00
end
when 0x08 # Home Entertainment
case subcat.hex
when 0x00
end
when 0x09 # Energy Management
case subcat.hex
when 0x00
end
when 0x0A # Built-In Appliance Control
case subcat.hex
when 0x00
end
when 0x0B # Plumbing
case subcat.hex
when 0x00
end
when 0x0C # Communication
case subcat.hex
when 0x00
end
when 0x0D # Computer Control
case subcat.hex
when 0x00
end
when 0x0E # Window Coverings
case subcat.hex
when 0x00
end
when 0x0F # Access Control
case subcat.hex
when 0x00
end
when 0x10 # Security, Health, and Safety
when 0x11 # Surveillance
when 0x12 # Automotive
when 0x13 # Pet care
when 0x14 # Toys
when 0x15 # Timekeeping
when 0x16 # Holiday
end
return @templid
end
end


def processDeviceInfo(param)
def processDeviceInfo(param)
  ### temporary
### temporary
  ### 12-24-07 Adding Device Template compatibility..
### 12-24-07 Adding Device Template compatibility..
  #have to find MY address
#have to find MY address
  insHb = param['Parameter3'] # From
insHb = param['Parameter3'] # From
  insMb = param['Parameter4']
insMb = param['Parameter4']
  insLb = param['Parameter5']
insLb = param['Parameter5']


  insID = padhex(insHb) + "." + padhex(insMb) + "." + padhex(insLb)
insID = padhex(insHb) + "." + padhex(insMb) + "." + padhex(insLb)
  #set the devicecat and device subcat in the childdatabases
#set the devicecat and device subcat in the childdatabases
  # 0-1 Device Category
# 0-1 Device Category
  # 2-3 Device SubCategory
# 2-3 Device SubCategory
  # 4-5 Device Firmware
# 4-5 Device Firmware
  $childdatabases[insID][0][0..1] = param['Parameter6']
log('proccessDeviceInfo:Insteon ID' + insID)
  $childdatabases[insID][0][2..3] = param['Parameter7']
$childdatabases[insID][0][0..1] = param['Parameter6']
  $childdatabases[insID][0][4..5] = param['Parameter8']
$childdatabases[insID][0][2..3] = param['Parameter7']
  savechilddatabases(insID)
$childdatabases[insID][0][4..5] = param['Parameter8']
  log('InsteonID: ' + insID)
savechilddatabases(insID)
  #log('Child Config AFTER update:' + $childdatabases[insID][0].to_s)
log('InsteonID: ' + insID)
  log($yellow)
#log('Child Config AFTER update:' + $childdatabases[insID][0].to_s)
  case param['Parameter6'].hex
log($yellow)
  when 0x0 # Generalized Controllers
@template = getdevicetemplate(param['Parameter6'], param['Parameter7'])
    case param['Parameter7'].hex
$devicetemplate[insID] = @template
    when 0x04; log('Found ControLinc [2430]')
log('Template ID:' + @template.to_s)
    when 0x05; log('Found RemoteLinc [2440]')
### eventually, open a XML configuration script?
    when 0x06; log('Found Icon Tabletop Controller [2830]')
### or read saved data from mysql?
    when 0x09; log('Found SignaLinc RF Signal Enhancer [2442]')
### most likely save this information to sql with device.
    when 0x0A; log('Found Balboa Instruments Poolux LCD Controller')
### eventually, IPKDB will be available to ping.
    when 0x0B; log('Found Access Point [2443]')
log('for Insteon ID:' + insID)
    when 0x0C; log('Found IES Color Touchscreen')
log($grey)
    end
  when 0x01 # Dimmable Lighting Control
    case param['Parameter7'].hex
      # all these devices are associated with Template 38
      # Light Switch (dimmable)
    when 0x00; log('Found LampLinc V2 [2456D3]')
    when 0x01; log('Found SwitchLinc V2 Dimmer 600W [2476D]')
    when 0x02; log('Found In-LineLinc Dimmer [2475D]')
    when 0x03; log('Found Icon Switch Dimmer [2876D]')
    when 0x04; log('Found SwitchLinc V2 Dimmer 1000W [2476DH]')
    when 0x06; log('Found LampLinc 2-pin [2456D2]')
    when 0x07; log('Found Icon LampLinc V2 2-pin [2456D2]')
    when 0x09; log('Found KeypadLinc Dimmer [2486D]')
    when 0x0A; log('Found Icon In-Wall Controller [2886D]')
    when 0x0D; log('Found SocketLinc [2454D]')
    when 0x13; log('Found Icon SwitchLinc Dimmer for Lixar/Bell Canada [2676D-B]')
    when 0x17; log('Found ToggleLinc Dimmer [2466D]')
    end
  when 0x02 # Switched Lighting Control
    case param['Parameter7'].hex
      # all these devices are associated with Template 37
      # Light Switch (ON/OFF)
    when 0x09; log('Found ApplianceLinc [2456S3]')
    when 0x0A; log('Found SwitchLinc Relay [2476S]')
    when 0x0B; log('Found Icon On Off Switch [2876S]')
    when 0x0C; log('Found Icon Appliance Adapter [2856S3]')
    when 0x0D; log('Found ToggleLinc Relay [2466S]')
    when 0x0E; log('Found Switchlinc Relay Countdown Timer [2476ST]')
    when 0x10; log('Found In-LineLinc Relay [2475D]')
    when 0x13; log('Found Icon SwitchLinc Relay for Lixar/Bell Canada [2676R-B]')
    end
  when 0x03 # Network Bridges
    case param['Parameter7'].hex
    when 0x01; log('Found PowerLinc Serial [2414S]')
    when 0x02; log('Found PowerLinc USB [2414U]')
    when 0x03; log('Found Icon PowerLinc Serial [2814S]')
    when 0x04; log('Found Icon PowerLinc USB [2814U]')
    when 0x05; log('Found Smartlabs Power Line Modem Serial [2412S]')
    end
  when 0x04 # Irrigation Control
    case param['Parameter7'].hex
      # all these devices are associated with Template 1780
      # Standard Irrigation Sprinkler
 
    when 0x00; log('Found Simplehomenet EZRain1 Sprinkler Controller')
    end
  when 0x05 # Climate Control
    case param['Parameter7'].hex
    when 0x00; log('Found Broan SMSC080 Exhaust Fan')
    when 0x01; log('Found Simplehomenet EZTherm')
    when 0x02; log('Found Broan SMSC110 Exhaust Fan')
    when 0x03; log('Found Venstar RF Thermostat Module')
    when 0x04; log('Found Simplehomenet EZStat Thermostat')
    end
  when 0x06 # Pool and Spa Control
    case param['Parameter7'].hex
    when 0x00; log('Found Simplehomenet EZPool')
    end
  when 0x07 # Sensors and Actuators
    case param['Parameter7'].hex
    when 0x00
    end
  when 0x08 # Home Entertainment
    case param['Parameter7'].hex
    when 0x00
    end
  when 0x09 # Energy Management
    case param['Parameter7'].hex
    when 0x00
    end
  when 0x0A # Built-In Appliance Control
    case param['Parameter7'].hex
    when 0x00
    end
  when 0x0B # Plumbing
    case param['Parameter7'].hex
    when 0x00
    end
  when 0x0C # Communication
    case param['Parameter7'].hex
    when 0x00
    end
  when 0x0D # Computer Control
    case param['Parameter7'].hex
    when 0x00
    end
  when 0x0E # Window Coverings
    case param['Parameter7'].hex
    when 0x00
    end
  when 0x0F # Access Control
    case param['Parameter7'].hex
    when 0x00
    end
  when 0x10 # Security, Health, and Safety
  when 0x11 # Surveillance
  when 0x12 # Automotive
  when 0x13 # Pet care
  when 0x14 # Toys
  when 0x15 # Timekeeping
  when 0x16 # Holiday
  end
  ### eventually, open a XML configuration script?
  ### or read saved data from mysql?
  ### most likely save this information to sql with device.
  ### eventually, IPKDB will be available to ping.
  log ('for Insteon ID:' + insID)
  log($grey)
end
end


def recvComplete
def recvComplete
  # Clears the wait flag, but does not remove a command from the queue
# Clears the wait flag, but does not remove a command from the queue
  $wAIT = false
$wAIT = false
  log($green + "Receive Completed. Checking command queue" + $grey)
log($green + "Receive Completed. Checking command queue" + $grey)
  if $cmdqueue.nitems > 0 then
if $cmdqueue.nitems > 0 then
    log("Queue:" + $aqua + $cmdqueue.nitems.to_s + $grey + " : executing next command")
log("Queue:" + $aqua + $cmdqueue.nitems.to_s + $grey + " : executing next command")
    SndIns()
SndIns()
  else
else
    log($yellow + 'Queue Empty.' + $grey)
log($yellow + 'Queue Empty.' + $grey)
    if $rerun == true
if $rerun == true
      log('RERUN=TRUE, RESTARTING')
log('RERUN=TRUE, RESTARTING')
      $rerun = false
$rerun = false
      mainRestart()
mainRestart()
    else
else
      log('RERUN Not needed')
log('RERUN Not needed. Checking if reported..')
      #report Child devices here.
#report Child devices here.
      if $reported == false
if $reported == false
        cmd = Command.new(device_.devid_, device_.devid_, 1, 1, 756)
log('Reporting Child Devices')
        $reported = true
@work = ""
        SendCommand(cmd)
$childdatabases.each_key{
      end
|insteonID|
    end
log('Child:' + insteonID)
log('Config:' + $childdatabases[insteonID].inspect)
@template = $devicetemplate[insteonID]
@work += insteonID + "\t\t\t" + @template.to_s + "\t\n"
}
log(@work)
cmd = Command.new(device_.devid_, -1001, 1, 2, 54)
cmd.params_[13] = @work
SendCommand(cmd)
 
$reported = true
else
log('report not needed')
end
end


  end
end
end
def removecurrentcommand
#get the current child
log('in RemoveCurrentCommand')
log('Current Command:' + $cmdqueue[0].inspect)
#id is in param123
@id = $cmdqueue[0]['Parameter1']
@id += '.' + $cmdqueue[0]['Parameter2']
@id += '.' + $cmdqueue[0]['Parameter3']
log('ID=' + @id)
#now to remove from child and PLM databases
removefromchild(@id)
removefromplm(@id)
cmdComplete
end
end
def cmdComplete
def cmdComplete
  # Clears the wait flag, and removes the command from the queue.
# Clears the wait flag, and removes the command from the queue.
  $wAIT = false
$wAIT = false
  $resetNext = 0
$resetNext = 0
  $cmdqueue.delete_at(0)
$cmdqueue.delete_at(0)
  # now that THAT command is completed, check to see if there is
# now that THAT command is completed, check to see if there is
  # another command ready to transmit.
# another command ready to transmit.
  log($green + "Command Completed." + $grey)
log($green + "Command Completed." + $grey)
end
end
def checkWait(param)
def checkWait(param)
  #Checks for response from current command.
#Checks for response from current command.
  if $cmdqueue[0] != nil
if $cmdqueue[0] != nil
    if $wAIT == true
if $wAIT == true
      #log('CW:waiting for command to complete')
#log('CW:waiting for command to complete')
    else
else
      #log('CW:reports clear')
#log('CW:reports clear')
    end
end
  else
else
    log('------:)----checkWait: command queue is emtpy')
log('------:)----checkWait: command queue is emtpy')
    if $wAIT == true #this should never happen
if $wAIT == true #this should never happen
      log('------:(XXX-CheckWait: TRUE')
log('------:(XXX-CheckWait: TRUE')
    end
end
  end
end
end
end


def plmparse(value)
def plmparse(value)
  #THIS ROUTINE REPLACES parsestring()
#THIS ROUTINE REPLACES parsestring()
  #this routine will PARSE the incoming stream into valid messages
#this routine will PARSE the incoming stream into valid messages
  # value is the complete command
# value is the complete command
  param = {}
param = {}
  #here is a special case, the PLM seems to lock up.
#here is a special case, the PLM seems to lock up.
  if value == 0x15.chr  
if value == 0x15.chr
    log('The PLM stopped responding')
log('The PLM stopped responding')
    log('Please unplug it, and plug it back in')
log('Please unplug it, and plug it back in')
    log('and do a quick reload router.')
log('and do a quick reload router.')
 
end
while value.length > 2
case value[1]
when 0x62 # Special case, need to look at flags
if (value[5] & 0x10) == 0x10 # check for extended flag
cmdlen = 23
else
cmdlen = 9
end
param['Response'] = 'SndIns'
when 0x50; cmdlen = 11; param['Response'] = 'InsStdMsg'
when 0x51; cmdlen = 25; param['Response'] = 'InsExtMsg'
when 0x68; cmdlen = 4 #Set Insteon ACK Message Byte
when 0x71; cmdlen = 5 #Set Insteon ACK Message Two Bytes
when 0x70; cmdlen = 4 #Set Insteon NACK Message Byte
when 0x63; cmdlen = 5; param['Response'] = 'SndX10'
when 0x52; cmdlen = 4; param['Response'] = 'X10Msg'
when 0x61; cmdlen = 6; param['Response'] = 'SndGrp'
when 0x56; cmdlen = 7; param['Response'] = 'GrpEvntRpt'
when 0x58; cmdlen = 3 #All-Link Cleanup Status Report
when 0x64; cmdlen = 5; param['Response'] = 'StLnk'
when 0x65; cmdlen = 3; param['Response'] = 'CancelLnk'
when 0x53; cmdlen = 10; param['Response'] = 'InsLnkSts'
when 0x69; cmdlen = 3; param['Response'] = 'GetLnk'
when 0x6A; cmdlen = 3; param['Response'] = 'GetNext'
when 0x6C; cmdlen = 3 #Get All-Link Record for Sender
when 0x57; cmdlen = 10; param['Response'] = 'LnkData'
when 0x6F; cmdlen = 12; param['Response'] = 'MngLnk'
when 0x67; cmdlen = 3; param['Response'] = 'RstPLM'
when 0x6B; cmdlen = 4; param['Response'] = 'SetCfg'
when 0x60; cmdlen = 9; param['Response'] = 'GetVersion'
when 0x66; cmdlen = 6 #Set Host Device Category
when 0x72; cmdlen = 3 # RF Sleep
when 0x54; cmdlen = 3; param['Response'] = 'BtnRpt'
when 0x6D; cmdlen = 3; param['Response'] = 'LEDON'
when 0x6E; cmdlen = 3; param['Response'] = 'LEDOFF'
else


  end
log('ERROR IN PLMPARSE- Unknown Command')
  while value.length > 2
debug(value)
    case value[1]
    when 0x62 # Special case, need to look at flags
      if (value[5] & 0x10) == 0x10 # check for extended flag
        cmdlen = 23
      else
        cmdlen = 9
      end
      param['Response'] = 'SndIns'
    when 0x50; cmdlen = 11; param['Response'] = 'InsStdMsg'
    when 0x51; cmdlen = 25; param['Response'] = 'InsExtMsg'
    when 0x68; cmdlen = 4 #Set Insteon ACK Message Byte
    when 0x71; cmdlen = 5 #Set Insteon ACK Message Two Bytes
    when 0x70; cmdlen = 4 #Set Insteon NACK Message Byte
    when 0x63; cmdlen = 5; param['Response'] = 'SndX10'
    when 0x52; cmdlen = 4; param['Response'] = 'X10Msg'
    when 0x61; cmdlen = 6; param['Response'] = 'SndGrp'
    when 0x56; cmdlen = 7; param['Response'] = 'GrpEvntRpt'
    when 0x58; cmdlen = 3 #All-Link Cleanup Status Report
    when 0x64; cmdlen = 5; param['Response'] = 'StLnk'
    when 0x65; cmdlen = 3; param['Response'] = 'CancelLnk'
    when 0x53; cmdlen = 10; param['Response'] = 'InsLnkSts'
    when 0x69; cmdlen = 3; param['Response'] = 'GetLnk'
    when 0x6A; cmdlen = 3; param['Response'] = 'GetNext'
    when 0x6C; cmdlen = 3 #Get All-Link Record for Sender
    when 0x57; cmdlen = 10; param['Response'] = 'LnkData'
    when 0x6F; cmdlen = 12; param['Response'] = 'MngLnk'
    when 0x67; cmdlen = 3; param['Response'] = 'RstPLM'
    when 0x6B; cmdlen = 4; param['Response'] = 'SetCfg'
    when 0x60; cmdlen = 9; param['Response'] = 'GetVersion'
    when 0x66; cmdlen = 6 #Set Host Device Category
    when 0x72; cmdlen = 3 # RF Sleep
    when 0x54; cmdlen = 3; param['Response'] = 'BtnRpt'
    when 0x6D; cmdlen = 3; param['Response'] = 'LEDON'
    when 0x6E; cmdlen = 3; param['Response'] = 'LEDOFF'
    else


      log('ERROR IN PLMPARSE- Unknown Command')
return ''
      debug(value)
end
      return ''
    end


    #Now we know the length the command should be, see if we have it.
#Now we know the length the command should be, see if we have it.
    #log('waiting for ' + cmdlen.to_s + ' characters...')
#log('waiting for ' + cmdlen.to_s + ' characters...')
    #log('length of current input is ' + value.length.to_s)
#log('length of current input is ' + value.length.to_s)
    if value.length >= cmdlen
if value.length >= cmdlen
      #log('GOT whole response')
#log('GOT whole response')
      #Yes, we have the whole command, Pack it in param
#Yes, we have the whole command, Pack it in param
      for byt in 1..cmdlen
for byt in 1..cmdlen
        param['Parameter' + byt.to_s] = padhex("%X" %value[byt - 1])
param['Parameter' + byt.to_s] = padhex("%X" %value[byt - 1])
      end
end
      #now remove it from the string..
#now remove it from the string..
      value = value.slice(cmdlen, value.length - cmdlen)
value = value.slice(cmdlen, value.length - cmdlen)
      #Send it off for parsing
#Send it off for parsing
      #log('Sending to EZToDCE:' + param.inspect.to_s)
#log('Sending to EZToDCE:' + param.inspect.to_s)
      EZToDCE(param)
EZToDCE(param)
    else
else
      #log('Still waiting...')
#log('Still waiting...')
      #no, we have NOT received the whole command.
#no, we have NOT received the whole command.


    end
end
  end
end
  return value
return value
end
end


def rawX10(value)
def rawX10(value)


  x10MSN = $X10HouseCodes.index[value[0..0]]
x10MSN = $X10HouseCodes.index[value[0..0]]
  x10LSN = $X10UnitCodes.index[value[1..1]]
x10LSN = $X10UnitCodes.index[value[1..1]]
  return x10MSN + x10LSN
return x10MSN + x10LSN
end
end


def X10Flag(value)
def X10Flag(value)
  return + $X10CommandCodes.index[Value] + '0'
return + $X10CommandCodes.index[Value] + '0'
end
end


def SndIns
def SndIns
  # create a new PLM command for SndIns
# create a new PLM command for SndIns
  if $wAIT == false
if $wAIT == false
    #log('SndIns:currentcmd=' + $currentcmd.to_s)
#log('SndIns:currentcmd=' + $currentcmd.to_s)
 
if $cmdqueue.nitems > 0
log("SndIns:Queue:" + $aqua + $cmdqueue.nitems.to_s + $grey)
#log('SndIns:' + $cmdqueue.inspect)
param = $cmdqueue[0]
### have to figure out the command byte 2 here
work = '02'.hex.chr + plmcommand(param)
### PLM command compilation
for loop in 2..param.keys.nitems
@dummy = param['Parameter' + (loop - 1).to_s].to_s
work+= @dummy.hex.chr
end
conn_.Reconnect()
debugout(work)
conn_.Send(work)
#sleep 0.1
$wAIT = TRUE
else
log($yellow + 'Queue Empty.' + $grey)
if $rerun == true
log('RERUN=TRUE, RESTARTING')
$rerun = false
mainRestart()
else
log('RERUN Not needed')
if $reported == false
log('Reporting Child Devices')
@work = ""
$childdatabases.each_key{
|insteonID|
log('Child:' + insteonID)
log('Config:' + $childdatabases[insteonID].inspect)
@template = $devicetemplate[insteonID]
@work += insteonID + "\t\t\t" + @template.to_s + "\t\n"
}
log(@work)
cmd = Command.new(device_.devid_, -1001, 1, 2, 54)
cmd.params_[13] = @work
SendCommand(cmd)


    if $cmdqueue.nitems > 0
$reported = true
      log("SndIns:Queue:" + $aqua + $cmdqueue.nitems.to_s + $grey)
else
      #log('SndIns:' + $cmdqueue.inspect)
log('report not needed')
      param = $cmdqueue[0]
end
      ### have to figure out the command byte 2 here
end
      work = '02'.hex.chr + plmcommand(param)
      ### PLM command compilation
      for loop in 2..param.keys.nitems
        @dummy = param['Parameter' + (loop - 1).to_s].to_s
        work+= @dummy.hex.chr
      end
      conn_.Reconnect()
      debug(work)
      conn_.Send(work)
      #sleep 0.1
      $wAIT = TRUE
    else
      log($yellow + 'Queue Empty.' + $grey)
      if $rerun == true
        log('RERUN=TRUE, RESTARTING')
        $rerun = false
        mainRestart()
      else
        log('RERUN Not needed')
      end


    end
end
  else
else
    log('X-----------SndIns: Waiting for response to:' + $cmdqueue[0]['Command'].to_s)
log('X-----------SndIns: Waiting for response to:' + $cmdqueue[0]['Command'].to_s)
    log('X-----------SndIns: Current Queue Length:' + $cmdqueue.nitems.to_s)
log('X-----------SndIns: Current Queue Length:' + $cmdqueue.nitems.to_s)
  end
end
end
end
def plmcommand(param)
def plmcommand(param)
  ### this returns the proper Byte2 for the command.
### this returns the proper Byte2 for the command.
  case param['Command']
case param['Command']
  when 'GetVersion'; return 0x60.chr
when 'GetVersion'; return 0x60.chr
  when 'SndIns'; return 0x62.chr
when 'SndIns'; return 0x62.chr
  when 'SndGrp'; return 0x61.chr
when 'SndGrp'; return 0x61.chr
  when 'SndX10'; return 0x63.chr
when 'SndX10'; return 0x63.chr
  when 'GetLnk'; return 0x69.chr
when 'GetLnk'; return 0x69.chr
  when 'GetNext'; return 0x6A.chr
when 'GetNext'; return 0x6A.chr
  when 'BtnRpt'; return 0x54.chr
when 'BtnRpt'; return 0x54.chr
  when 'GetCfg'; return 0x73.chr
when 'GetCfg'; return 0x73.chr
  when 'StLnk'; return 0x64.chr
when 'StLnk'; return 0x64.chr
  when 'CancelLnk'; return 0x65.chr
when 'CancelLnk'; return 0x65.chr
  when 'MngLnk'; return 0x6F.chr  
when 'MngLnk'; return 0x6F.chr
  when 'RstPLM'; return 0x67.chr
when 'RstPLM'; return 0x67.chr
  when 'SetCfg'; return 0x6B.chr
when 'SetCfg'; return 0x6B.chr
  when 'LEDON'; return 0x6D.chr
when 'LEDON'; return 0x6D.chr
  when 'LEDOFF'; return 0x6E.chr
when 'LEDOFF'; return 0x6E.chr
    ## hack
## hack
  when 'InsStdMsg'
when 'InsStdMsg'
    log('ERROR:PLMCommand encountered a COMMAND of INSSTDMSG')
log('ERROR:PLMCommand encountered a COMMAND of INSSTDMSG')
    break
break
    return 0x62.chr
return 0x62.chr
  end
end
end
end


def debug(text)
def debug(text)
  work = 'OUT:'
work = 'DEBUG:'


  for c in 1..text.length
for c in 1..text.length
    work += padhex("%X" %text[c-1]) + ' '
work += padhex("%X" %text[c-1]) + ' '
  end
end
  log($green + work + "Length:" + text.length.to_s + $grey)
log($yellow + work + "Length:" + text.length.to_s + $grey)
end
end
def debugout(text)
work = 'out:'


for c in 1..text.length
work += padhex("%X" %text[c-1]) + ' '
end
log($green + work + "Length:" + text.length.to_s + $grey)
end
def debugin(text)
def debugin(text)
  work = 'IN:'
work = 'IN:'


  for c in 1..text.length
for c in 1..text.length
    work += padhex("%X" %text[c-1]) + ' '
work += padhex("%X" %text[c-1]) + ' '
  end
end
  log($red + work + "Length:" + text.length.to_s + $grey)
log($red + work + "Length:" + text.length.to_s + $grey)
end
end


def padhex(hex)
def padhex(hex)
  if hex.length==1
if hex.length==1
    hex = "0" + hex
hex = "0" + hex
  end
end
  return hex
return hex
end
end


def percenttohex(level)
def percenttohex(level)
  # convert from percent to byte
# convert from percent to byte
  return "%X" %((level.to_i * 2.55)).to_i
return "%X" %((level.to_i * 2.55)).to_i
end
end


def hextopercent(level)
def hextopercent(level)
  return ((level.hex.to_i / 2.55)).to_i
return ((level.hex.to_i / 2.55)).to_i
end
 
def hextoTempurature(degree) #Thermostat change hex to tempurature
return ((degree.hex.to_i / 2)).to_i
end
def Tempuraturetohex (degree) #Thermostat Cahnge tempurature to hex
return ((degree.to_1 * 2)).hex
end
end


def log(line)
def log(line)
  $log = File.open("/var/log/pluto/" + device_.devid_.to_s + "_Generic_Serial_Device.log", "a")
$log = File.open("/var/log/pluto/" + device_.devid_.to_s + "_Generic_Serial_Device.log", "a")
  $log.puts "(***):" + line.to_s
$log.puts "(***):" + line.to_s
  $log.close
$log.close
end
end
def log2(line)
def log2(line)
  #this will send a message out the the orbiters..
#this will send a message out the the orbiters..
  #/usr/pluto/bin/MessageSend localhost 0 20 1 809 9 "Text to Display" 70 "alert" 182 "30" 251 "??"
#/usr/pluto/bin/MessageSend localhost 0 20 1 809 9 "Text to Display" 70 "alert" 182 "30" 251 "??"
  cmd = Command.new(device_.devid_, -1000, 1, 1, 809)
cmd = Command.new(device_.devid_, -1000, 1, 1, 809)
  cmd.params_[9] = line #text to display
cmd.params_[9] = line #text to display
  cmd.params_[70] = 'PLMMessage' #Token
cmd.params_[70] = 'PLMMessage' #Token
  cmd.params_[182] = '10' #Timeout in seconds
cmd.params_[182] = '10' #Timeout in seconds
  cmd.params_[251] = '??'
cmd.params_[251] = '??'
  SendCommand(cmd)
SendCommand(cmd)
end
end
def checkChildRecordsinPLM()
def checkChildRecordsinPLM()
  # log('In CheckChildRecordsinPLM')
log('Entered CheckChildRecordsinPLM')
  # time to verify all children are in the PLM
# log('In CheckChildRecordsinPLM')
  #
# time to verify all children are in the PLM
  # log('Total PLM Records:' + $plmdatabase.nitems.to_s)
#
  # $plmdatabase.each{|record|
# log('Total PLM Records:' + $plmdatabase.nitems.to_s)
  # log('Record: = '+ getIIDfromRecord(record) + ' Group:' + getGroupfromRecord(record))
$plmdatabase.each{|record|
  # }
log('Record: = '+ getIIDfromRecord(record) + ' Group:' + getGroupfromRecord(record))
log('checking to see if it needs to be added as a child...')
if existsinchild(getIIDfromRecord(record)) == false
 
log(getIIDfromRecord(record) + ' needs to be added to the child database')
addtochild(getIIDfromRecord(record))
end
}


  $childdatabases.each_key {|child|
$childdatabases.each_key {|child|
    if existsinplm(child) == false
if existsinplm(child) == false
      #log(child + ' needs to be added to PLM')
log(child + ' needs to be added to PLM')
      sendAddtoPLM(child)
sendAddtoPLM(child)
    else
else
      log(child + ' exists in PLM')
log(child + ' exists in PLM')
    end
end
    @result = 'Child: ' + child + "\n"
 
    #now to scan the childs database
#now to scan the childs database
    for record in 1..($childdatabases[child].nitems - 1)
for record in 1..($childdatabases[child].nitems - 1)
      @test = $childdatabases[child][record]
@test = $childdatabases[child][record]
      if existsinplm(getIIDfromRecord(@test)) == false
if existsinplm(getIIDfromRecord(@test)) == false
        log(getIIDfromRecord(@test) + ' needs to be added to PLM')
log(getIIDfromRecord(@test) + ' needs to be added to PLM')
        sendAddtoPLM(getIIDfromRecord(@test))
sendAddtoPLM(getIIDfromRecord(@test))
      else
else
        log(getIIDfromRecord(@test) + ' exists in PLM')
log(getIIDfromRecord(@test) + ' exists in PLM')
      end
end
      #Also check to see if it needs to be added in the childdatabases
#Also check to see if it needs to be added in the childdatabases
      if existsinchild(getIIDfromRecord(@test)) == false
end
        log(getIIDfromRecord(@test) + ' needs to be added to the child database')
}
        addtochild(getIIDfromRecord(@test))
      end
    end
  }


end
end
def existsinplm(insteonid)
def existsinplm(insteonid)
  result = false
result = false
  $plmdatabase.each{|record|
$plmdatabase.each{|record|
    #log(insteonid + '==' + getIIDfromRecord(record))
#log(insteonid + '==' + getIIDfromRecord(record))
    if insteonid == getIIDfromRecord(record)
if insteonid == getIIDfromRecord(record)
      #log('TRUE')
result = true
      result = true
end
    end
}
  }
return result
  return result
end
end
def existsinchild(insteonid)
def existsinchild(insteonid)
  result = false
log('ExistsinChild:InsteonID:' + insteonid)
  $childdatabases.each_key{|record|
result = false
    if insteonid == record
$childdatabases.each_key{|record|
      result = true
if insteonid == record
    end
result = true
  }
end
  return result
}
log('ExistsinChild result:FALSE') if result == false
log('ExistsinChild result:TRUE') if result == true
return result
end
end
def addtochild(insteonID)
def addtochild(insteonID)
  log('addtochild Routne called')
log('addtochild Routne called')
  log('Adding ' + insteonID + ' to the child database...')
log('Adding ' + insteonID + ' to the child database...')
  $childdatabases[insteonID] = ['****************']
if insteonID.length == 2 then
  sendPing(insteonID)
log('Child is X10')
  $rerun = true
$state[insteonID] = 0
else
log('Child is Insteon')
$childdatabases[insteonID] = ['****************']
sendPing(insteonID)
$rerun = true
end
end
 
 
def removefromchild(insteonID)
log('Removing ' + insteonID + ' from child database')
$childdatabases.delete(insteonID)
$state.delete(insteonID)
end
def removefromplm(insteonID)
log('Removing from plm')
$plmdatabase.each{|record|
#log(insteonid + '==' + getIIDfromRecord(record))
if insteonID == getIIDfromRecord(record)
debug(record)
log('Found Record, Deleting')
$plmdatabase.delete(record)
 
#now, we have to remove it from the device.
param = {'Command' =>'MngLnk',
'Parameter1' => '80', #DELETE
'Parameter2' => record[0..1], #control byte
'Parameter3' => record[2..3], #group
'Parameter4' => record[4..5],#HB
'Parameter5' => record[6..7],#MB
'Parameter6' => record[8..9],#LB
'Parameter7' => record[10..11],#data1
'Parameter8' => record[12..13],#data2
'Parameter9' => record[14..15] #data3
 
}
log(param.inspect)
$cmdqueue << param
end
}
end
end
def sendAddtoPLM(insteonID)
def sendAddtoPLM(insteonID)
  log('Adding ' + insteonID + ' to the PLM database...')
log('Adding ' + insteonID + ' to the PLM database...')
  #This adds a record into the PLM
#This adds a record into the PLM
  @insID = insteonID.split('.')
@insID = insteonID.split('.')
  param = {'Command' => 'MngLnk',
param = {'Command' => 'MngLnk',
    'Parameter1' => '40', #control code -- add new record as Controller
'Parameter1' => '40', #control code -- add new record as Controller
    'Parameter2' => 'C2', #All Link Record Flags AKA Record Control Byte
'Parameter2' => 'C2', #All Link Record Flags AKA Record Control Byte
    'Parameter3' => '01', #All Link Group
'Parameter3' => '01', #All Link Group
    'Parameter4' => @insID[0], #HB
'Parameter4' => @insID[0], #HB
    'Parameter5' => @insID[1], #MB
'Parameter5' => @insID[1], #MB
    'Parameter6' => @insID[2], #LB
'Parameter6' => @insID[2], #LB
    'Parameter7' => '01', #Link Data 1 ON-Level
'Parameter7' => '01', #Link Data 1 ON-Level
    'Parameter8' => '01', #Link Data 2 Ramp Rate
'Parameter8' => '01', #Link Data 2 Ramp Rate
    'Parameter9' => 'FF'} #Link Data 3 not used
'Parameter9' => 'FF'} #Link Data 3 not used
  if $wAIT == true
if $wAIT == true
    $cmdqueue.insert(1, param)
$cmdqueue.insert(1, param)
  else
else
    $cmdqueue.insert(0, param)
$cmdqueue.insert(0, param)
  end
end


  SndIns()
SndIns()
end
end


def getIIDfromRecord(recordstring)
def getIIDfromRecord(recordstring)
  #this extracts the insteonID string from the record.
#this extracts the insteonID string from the record.
  #log('getIIDfromRecord::recordstring:' + recordstring)
#log('getIIDfromRecord::recordstring:' + recordstring)
  @idhb = recordstring[4..5]
@idhb = recordstring[4..5]
  @idmb = recordstring[6..7]
@idmb = recordstring[6..7]
  @idlb = recordstring[8..9]
@idlb = recordstring[8..9]
  @result = @idhb + '.' + @idmb + '.' +@idlb
@result = @idhb + '.' + @idmb + '.' +@idlb
  #log('GetIIDfromRecord: Found ID:' + @result)
#log('GetIIDfromRecord: Found ID:' + @result)
  return @result
return @result
end
end


def processBroadcastMessage(param)
def processBroadcastMessage(param)
  #search the child databases for responders,
#search the child databases for responders,
  #and fire events for each responder.
#and fire COMMANDS for each responder. 06Feb08
  #Message flag is in parameter9 Group command 0xCx (All-Link Broadcast Message Pg 42.)
#and fire events for each responder.XXXXXXXXXXXXX
  #Group is in parameter8
#Message flag is in parameter9 Group command 0xCx (All-Link Broadcast Message Pg 42.)
  #From InsteonID is parameters 3, 4, 5
#Group is in parameter8
  group = param['Parameter8']
#From InsteonID is parameters 3, 4, 5
  from = padhex(param['Parameter3']) + '.'
group = param['Parameter8']
  from += padhex(param['Parameter4']) + '.'
from = padhex(param['Parameter3']) + '.'
  from += padhex(param['Parameter5'])
from += padhex(param['Parameter4']) + '.'
  log('Looking for ' + from + ' Group:' + group)
from += padhex(param['Parameter5'])
  #Ok, now have to search child databases for from AND group AND responder
log('Looking for ' + from + ' Group:' + group)
  $childdatabases.each_key{|child|
log('Showing Parameter10:' + param['Parameter10'].to_s)
    #log('Searching:' + child)
#Ok, now have to search child databases for from AND group AND responder
    for rec in 1..($childdatabases[child].nitems - 1)
$childdatabases.each_key{|child|
      record = $childdatabases[child][rec]
#log('Searching:' + child)
      if getIIDfromRecord(record) == from # First, look for Insteon ID
for rec in 1..($childdatabases[child].nitems - 1)
        #log('Found ID')
record = $childdatabases[child][rec]
        if getGroupfromRecord(record) == group #next, Group
if getIIDfromRecord(record) == from # First, look for Insteon ID
          #log('Found Group')
#log('Found ID')
          if isResponderRecord(record) # is a responder?
if getGroupfromRecord(record) == group #next, Group
            #log('Found Responder')
#log('Found Group')
            #figure out the child devicenum
if isResponderRecord(record) # is a responder?
            from = $children[child]
#log('Found Responder')
            #figure out the command
#figure out the child devicenum
            case param['Parameter10'].hex
from = $children[child]
            when 0x11 #on
#figure out the command
              reportStatus(from, 100)
case param['Parameter10'].hex
            when 0x13 #off
when 0x11 #on
              reportStatus(from, 0)
reportStatus(from, 100)
            when 0x17 #dim/brighten -ignore
when 0x13 #off
              level = 0
reportStatus(from, 0)
            when 0x18 # STOP dim/brighten - sendgetstatus
when 0x6B # Thermostat Command On/OFF/AUTO
              level = 0
case param['Parameter11'].to_s
              sendGetChildStatus(child)
when '09' #status to OFF
            else
#need to set current temp
              level = 0
reportStatus(from, 0)
              log('Command is other than ON/OFF/Dim/Brighten')
else
            end
#check thermostat for state and update and set current temp
          end
#reportStatus(from, 100)
        end
      end
      #log(record)
      #log(getIIDfromRecord(record))
      #log(getGroupfromRecord(record))
      #if isResponderRecord(record)
      # log('Responder')
      #else
      # log('Controller')
      #end
    end
  }
end
end


def reportStatus(from, level)
when 0x6C # Thermostat Command Cool Point
  #Bug found: when a devices state is OFF, it ignores the setlevel?
tempurature =param['Parameter11'] /2 #temp in hex need to devide by 2 = current cool point
#reportStatus(from,tempurature)
when 0x6D# Thermostat Command Heat Point
tempurature =param['Parameter11'] /2 #temp in hex need to devide by 2 = current heat point
#reportStatus(from,tempurature)


when 0x17 #dim/brighten -ignore
level = 0
when 0x18 # STOP dim/brighten - sendgetstatus
level = 0
sendGetChildStatus(child)
else
level = 0
log('Command is other than ON/OFF/Dim/Brighten')
end
end
end
end
end
}
end


  log('Entered reportStatus:' + from.to_s + ', ' + level.to_s)
def reportStatus(from, level)
  #this routine sends both a cmd[192,193] and sets the STATE via cmd[184][76]
log('From:' + from.to_s) #shows child id
  #from is the deviceid and level is percentage
log('current State:' + $state[from].to_s)
log('Wanted State:' + level.to_s)
  #first, send
case $state[from]
  if level == 0 then
when 0
    #have to first send an ON cmd to be sure the off cmd gets processed
if level >=1
    cmd = Command.new(from, from, 1, 1, 192)
cmd = Command.new(from, from, 1, 1, 192) #on
    $ignorecmdon = true
cmd.params_[120] = "1"
    SendCommand(cmd)
SendCommand(cmd)
  else
cmd = Command.new(from, from, 1, 1, 184)
    #have to first send an OFF cmd...
cmd.params_[76] = level.to_s
    cmd = Command.new(from, from, 1, 1, 193)
cmd.params_[120] = "1"
    $ignorecmdoff = true
SendCommand(cmd)
    SendCommand(cmd)
end
    $ignorecmdon = true
when 100
    cmd = Command.new(from, from, 1, 1, 192)
if level >= 1
    SendCommand(cmd)
cmd = Command.new(from, from, 1, 1, 184)
  end
cmd.params_[76] = level.to_s
 
cmd.params_[120] = "1"
  #now, send command for state
SendCommand(cmd)
  cmd = Command.new(from, from, 1, 1, 184) #SetLevel
else
  cmd.params_[76] = level.to_s
cmd = Command.new(from, from, 1, 1, 193) # off
  $ignoresetlevel = true # to stop infinate loop
cmd.params_[120] = "1"
  SendCommand(cmd)
SendCommand(cmd)
  log('ReportStatus: device:' + from.to_s + ' Status:' + level.to_s)
end
  if level == 0 then
else
    #now send the OFF command
if level == 100
    cmd = Command.new(from, from, 1, 1, 193)
cmd = Command.new(from, from, 1, 1, 193) #off
    $ignorecmdoff = true
cmd.params_[120] = "1"
    SendCommand(cmd)
SendCommand(cmd)
  end
cmd = Command.new(from, from, 1, 1, 192) # on
cmd.params_[120] = "1"
SendCommand(cmd)
end
cmd = Command.new(from, from, 1, 1, 184) #SetLevel
cmd.params_[76] = level.to_s
cmd.params_[120] = "1"
SendCommand(cmd)
end
log('ReportStatus: device:' + from.to_s + ' Status:' + level.to_s)
$state[from] = level
end
end


def isResponderRecord(recordstring)
def isResponderRecord(recordstring)
  work = recordstring[0..1].hex
work = recordstring[0..1].hex
  if (work & 0x40) == 0x40 #check bit 6
if (work & 0x40) == 0x40 #check bit 6
    result = false #signifies Controller record
result = false #signifies Controller record
  else
else
    result = true #signifies Responder record
result = true #signifies Responder record
  end
end
  return result  
return result
end
end


def getGroupfromRecord(recordstring)
def getGroupfromRecord(recordstring)
  #this extracts the GROUP from the record.
#this extracts the GROUP from the record.
  if recordstring == nil
if recordstring == nil
    return '00'
return '00'
  else
else
    return recordstring[2..3]
return recordstring[2..3]
  end
end
end
end
def getdeltafromconfig(insteonID)
def getdeltafromconfig(insteonID)
  #This returns the delta from the child.
#This returns the delta from the child.
  @work = $childdatabases[insteonID][0] # the settings stored in [0]
@work = $childdatabases[insteonID][0] # the settings stored in [0]
  if @work == nil
if @work == nil
    return '00'
return '00'
  else
else
    return @work[6..7]
return @work[6..7]
  end
end
end
end
def sendGetChildStatus(insteonID)
def sendGetChildStatus(insteonID)
  #log('sendGetChildStatus Called')
#log('sendGetChildStatus Called')
  @insID = insteonID.split('.')
if insteonID.length != 2 #X10 device
  param = {'Command' => 'SndIns',
@insID = insteonID.split('.')
    'Parameter1' => @insID[0],  
param = {'Command' => 'SndIns',
    'Parameter2' => @insID[1],
'Parameter1' => @insID[0],
    'Parameter3' => @insID[2],
'Parameter2' => @insID[1],
    'Parameter4' => '0F', #flags
'Parameter3' => @insID[2],
    'Parameter5' => '19', #Status Request
'Parameter4' => '0F', #flags
    'Parameter6' => '00'} #not used.
'Parameter5' => '19', #Status Request
  $cmdqueue << param
'Parameter6' => '00'} #not used.
  SndIns()
$cmdqueue << param
  #Returned response will have cmd1 = DBDelta
SndIns()
  #Returned response will have cmd2 = ON-Level
#Returned response will have cmd1 = DBDelta
#Returned response will have cmd2 = ON-Level
else
log('X10 does not report status')
end
end
def islast(record)
#high water mark
return false if (record[0..1].hex & 0x02) == 0x02
return true
end
 
def isinuse(record)
return true if (record[0..1].hex & 0x80) == 0x80
return false
end
end


def iscontroller(record)
return true if (record[0..1].hex & 0x40) == 0x40
return false
end
def group(record)
return record[2..3]
end
def remoteid(record)
@insteonID = record[4..5] + '.'
@insteonID += record[6..7] + '.'
@insteonID += record[8..9]
return @insteonID
end
def findresponderrecord(masterid, slaveid, groupid)
# log(masterid + ':' + slaveid + ':' + groupid)
$childdatabases[slaveid].each{|check|
# log('Record:' + check.to_s)
if iscontroller(check.to_s) == false #responder record
# log('found responder record')
# log('remoteid:' + remoteid(check.to_s))
if remoteid(check.to_s) == masterid # found
# log('Found Controller ID in responder record')
if group(check.to_s) == groupid
# log('Group Matches')
#found group
return true
end
end
end
}
return false
end
def findcontrollerrecord(masterid, slaveid, groupid)
# log(masterid + ':' + slaveid + ':' + groupid)
$childdatabases[masterid].each{|check|
# log('Record:' + check.to_s)
if iscontroller(check.to_s) == true #controller
# log('found controller record')
if remoteid(check.to_s) == slaveid # found
# log('found Responder ID in Controller record')
if group(check.to_s) == groupid
# log('Group Matches')
#found group
return true
end
end
end
}
return false
end


# time to define a structure to save the raw data in hex
# time to define a structure to save the raw data in hex
# starts at [0]
# starts at [0]
# Bytes Meaning
# Bytes Meaning
# 0-1 Device Category
# 0-1 Device Category
# 2-3 Device SubCategory
# 2-3 Device SubCategory
# 4-5 Device Firmware
# 4-5 Device Firmware
# 6-7 Database Delta
# 6-7 Database Delta
# 8-9 reserved
# 8-9 reserved
# 10-11 reserved
# 10-11 reserved
# 12-13 reserved
# 12-13 reserved
# 14-15 reserved
# 14-15 reserved
###### First database record below (in same format its read from the device)
###### First database record below (in same format its read from the device)
###### This is the same format as an ALL-Link Record Response from the PLM
###### This is the same format as an ALL-Link Record Response from the PLM
###### (0x57) bytes 3..10
###### (0x57) bytes 3..10
# 16-17 record control byte
# 16-17 record control byte
# 18-19 Group
# 18-19 Group
# 20-21 ID HB
# 20-21 ID HB
# 22-23 ID MB
# 22-23 ID MB
# 24-25 ID LB
# 24-25 ID LB
# 26-27 Link Specific Data1
# 26-27 Link Specific Data1
# 28-29 Link Specific Data2
# 28-29 Link Specific Data2
# 30-31 Link Specific Data3
# 30-31 Link Specific Data3
######
######
# 32-47 next database record...
# 32-47 next database record...
 


</pre>
</pre>

Latest revision as of 09:30, 3 July 2016

Version Status Date Updated Updated By
710 Unknown N/A N/A
810 Unknown N/A N/A
1004 Unknown N/A N/A
1204 Unknown N/A N/A
1404 Unknown N/A N/A
Usage Information
#### Written by Dan Damron
#### #373 Private Method Listing ####

def mainStart() ## This is called FIRST, reruns cannot call this.
#Register Message Interceptor
@interceptor = Command.new(device_.devid_, -1000, 1, 5, 37)
@interceptor.params_[2] = device_.devid_.to_s
SendCommand(@interceptor)

#Get the PLM Database
sendGetLink
#get Child devices
log('Finding Children..')
device_.childdevices_.each{|c|
if device_.childdevices_[c.to_s.to_i].devdata_[12].include? "Group"
log('FOUND A GROUP')
else
$children[device_.childdevices_[c.to_s.to_i].devdata_[12].chomp.lstrip.rstrip] = c.to_s.to_i
end}
$children.keys.each{|c| log(c + ' = ' + $children[c].to_s)
}
log('reading stored Child configuration:')

$children.keys.each{|c|
#Get each Childs configuration
$state[$children[c]] = 0
getdeviceconfig(c) #

#the above getdeviceconfig packs $configparams array
log('Configuration for ' + c + ' = ' + $configparams.inspect.to_s)
}

log('********************************************************')
#get childs actual configuation and status
$children.keys.each{|c| sendGetChildStatus(c)}
SndIns()

end
def mainRestart()
#We have hashes already set up.
$childdatabases.each_key{|@insteonID|
$state[$children[@insteonID]] = 0
sendGetChildStatus(@insteonID)}
SndIns()
end

def setdeviceconfig(insteonid, configurestring)
@deviceid = $children[insteonid]
@cmdfrom = device_.devid_
@cmdto = 4 #general info plugin
@priority = 1
@type=1 #command
@cmdid = 246

#set up command..
@cmd = Command.new(@cmdfrom, @cmdto, @priority, @type, @cmdid)
@cmd.params_[2] = @deviceid.to_s
@cmd.params_[52] = '59' # Configuration
@cmd.params_[5] = configurestring
SendCommand(@cmd)
log('SetDeviceConfig:' + @cmd.to_s)
#log('SetDeviceConfig:' + configurestring)
#log('Configuration Saved - will be available on next reload')
end

def getdeviceconfig(insteonid)
@deviceid = $children[insteonid]
@configstring = ''
begin
@configstring = device_.childdevices_[@deviceid].devdata_[59].to_s
rescue
log('Device ID = ' + @deviceid.to_s)
log($red + 'Error - Child has no configuration'+ $grey)
log('Setting initial value of "****************"')
setdeviceconfig(insteonid, ('*' * 16))
@configstring = '*' * 16
sendPing(insteonid)
end
if @configstring == ''
$configparams = ['****************']
log('CAUGHT BLANK RECORD')
setdeviceconfig(insteonid, ('*' * 16))
sendPing(insteonid)
else
$configparams = @configstring.unpack('a16' * (@configstring.length / 16))
$devicetemplate[insteonid] = getdevicetemplate($configparams[0][0..1], $configparams[0][2..3])
end
#log($yellow + 'getdeviceconfig:' + $configparams.inspect + $grey)
#add the configuration parameters to the child database
$childdatabases[insteonid] = $configparams
#get the device type

end

def sendGetLink()
#lets just see exactly what is in the PLM database
param = {'Command' => 'GetLnk'}
$cmdqueue << param
SndIns()
end

def sendGetNext()
param = {'Command' => 'GetNext'}
if $wAIT == true
$cmdqueue.insert(1, param)
else
$cmdqueue.insert(0,param)
end
SndIns()
end

def sendRemoteGetLink(insteonID)
# Read First ALDB Record
# a few variables need to be set up here..
$recordof = insteonID # save the insteon ID
insID = insteonID.chomp.split('.') # get the seperate bytes
$remoteDBOffsetMSB = 0x0F # initial offset
$remoteDBOffsetLSB = 0xF8 # initial LSB offset
param = {'Command' => 'SndIns',
'Parameter1' => insID[0], #HB
'Parameter2' => insID[1], #MB
'Parameter3' => insID[2], #LB
'Parameter4' => '0F', #Flags
'Parameter5' => '28', #Cmd1
'Parameter6' => "%X" %$remoteDBOffsetMSB #Cmd2 Set MSB Offset
}
$cmdqueue << param
# repeat last param for each byte to read (F8..FF)=first record

for x in 0..7
param = {'Command' => 'SndIns',
'Parameter1' => insID[0], #HB
'Parameter2' => insID[1], #MB
'Parameter3' => insID[2], #LB
'Parameter4' => '0F', #Flags
'Parameter5' => '2B', #Cmd1 Peek
'Parameter6' => "%X" %($remoteDBOffsetLSB + x) #Cmd2
}

$cmdqueue << param
end

end

def sendRemoteGetNext(insteonID)
insID = insteonID.chomp.split('.') # get the seperate bytes
### Do NOT forget to check to see if we need to decrease the MSB

if $remoteDBOffsetLSB == 0x00
#OffsetMSB needs to be decreased, and LSB needs reset.
$remoteDBOffsetMSB = $remoteDBOffsetMSB - 1
$remoteDBOffsetLSN = 0xFF # the next line will decrease this by 8
end
# decrease DBOffsetLSB by 0x08
$remoteDBOffsetLSB = $remoteDBOffsetLSB - 0x08

for x in 0..7
param = {'Command' => 'SndIns',
'Parameter1' => insID[0], #HB
'Parameter2' => insID[1], #MB
'Parameter3' => insID[2], #LB
'Parameter4' => '0F', #Flags
'Parameter5' => '2B', #Cmd1 Peek
'Parameter6' => "%X" %($remoteDBOffsetLSB + x) #Cmd2
}
#log('sendRemoteGetNet:added to queue:' + param.inspect)
if $wAIT == true
$cmdqueue.insert(x + 1, param)
else
$cmdqueue.insert(x,param)
end


end
end

### Main command parsing routine is EZToDCE
def EZToDCE(param)
#param contains a hash of EZBridge command structure
#log($blue + 'Queue:' + $cmdqueue[0].inspect + $grey)
#log($blue + 'Param:' + param.inspect + $grey)
#log($blue + 'currentcmd:' + $currentcmd.to_s + $grey)
#checkWait(param)
case param['Response']
# Standard RESPONSES (to commands)
when 'GetRevision' # Special Response
log('-----|---------GetRevision:' + param['Parameter1'])

when 'GetLatLong' # Special Response
log('-----|---------GetLatLong: Lat=' + param['Lat'] + ', Long=' + param['Long'])

when 'SetLatLong'
if param['Parameter1'] == 'True' then
log('-----|---------SetLatLong: Ok')
else
log('-----X---------SetLatLong: FAILED!')
end
when 'SetPasswd'

when 'SetTimeZone'

when 'GetClock' # Special Response

when 'SetClock'

when 'SetNTPServer'

when 'Upgrade'

when 'NetCfg'

when 'Reset'
#Reset Response

cmdComplete
SndIns()
when 'LstTimers' # Special Response


when 'ClrTimers'

when 'AddTimer'

when 'GetTimer' # Special Response

when 'SetTimer'

when 'DelTimer'

when 'GetVersion' # Special Response

when 'SndGrp'

when 'SndIns' # response from SndIns
### BUG FOUND ### When the EZBridge receives a command from an EXTERNAL source
### ie not from this device, cmdqueue will be nil, and the code below
### fails. Have to check against that.
if $cmdqueue.length > 0
#First, check the response to make sure the command made it ok.
if param['Parameter9'].to_i == 6 #Ack received
#log('Sending to ProcessACK')
processACK(param)
else # NACK received - command failed.
log('Command NACKED')
end
else
#Response received for another device.
log('Response detected for a command that was not sent by me')
end
when 'SndX10'
log('Response detected for SndX10')
if param['Parameter5'].to_i == 6 #ack
log('X10 Command Successfull')

cmdComplete
SndIns()
else
log('X10 Command FAILED')
cmdComplete
SndIns()

end
when 'StLnk'

when 'CancelLnk'

when 'SetDev'

when 'RstPLM'
#Reset Response
$timeout = 1
cmdComplete
SndIns()

when 'GetLnk'
if param['Parameter3'].to_i == 6 #ack
log('GetLnk ACKED')
#if we get this, we should get a AllLink Record Response next
else
log('GetLnk NACKED')
# The PLM is BLANK
#have to add records to the PLM here.
cmdComplete
### FINISHED WITH GetLnk
checkChildRecordsinPLM()
SndIns()
end
when 'GetNext'
if param['Parameter3'].to_i == 6 #ack
log('sendGetNext ACKED')
#if we get this, we should get a AllLink Record Response next
else
log('sendGetNext NACKED')
#we get this when there are no more records
cmdComplete
#FINISHED with GetNext
# if we are here, we are in config mode
# so, next is to check to make sure the
# childrens insteon ID is in the PLM
checkChildRecordsinPLM()
# now, to make sure that all the records in the PLM are sensed as children

SndIns()
end

when 'SetCfg' # response from Setcfg command
if param['Parameter4'].to_i == 6 #ack
log('SetCfg Completed')
cmdComplete
SndIns()
else
log('SetCfg NACKED')
end
when 'GetLnkData'

when 'LEDON'

when 'LEDOFF'

when 'MngLnk'
if param['Parameter12'].to_i == 6
log('MngLnk => ACK')
else
log('MngLnk => NACK')
end
cmdComplete
SndIns()

when 'GetCfg' # Special Response

when 'LstMacros' # Special Response

when 'ClrMacros'

when 'AddMacro'

when 'GetMacro' # Special Response

when 'SetMacro'

when 'DelMacro'

when 'LstDevices' # Special Response

when 'ClrDevices'

when 'AddDevice'

when 'GetDevice' # Special Response

when 'SetDevice'

when 'DelDevice'

when 'LstZones'

when 'ClrZones'

when 'AddZone'

when 'GetZone'

when 'SetZone'

when 'DelZone'

when 'AddDevZone'

when 'DelDevZone'

# Response Messages
when 'InsExtMsg'

when 'InsStdMsg'
case $currentcmd # if this msg is part of a response, the Insteon Cmd1 will be saved here.
when 0x0
#log('REROUTING to processExternalCommand(param)')
processExternalCommand(param)
when 0x1 #Assign to Group
### This is a broadcast message sent
# from a PING command
# or from a StartLink...
log('Caught Assign to Group Message from Device')
### BUG HERE
#have to check flags to see if this is a broadcast message
log('Checking if this is a broadcast message')
log('Flags:' + param['Parameter9'])
if (param['Parameter9'].hex & 0x80) == 0x80
log('Message IS BROADCAST')
#recvComplete
processDeviceInfo(param)

# check to see if current cmd is for this broadcast..
log('Current Command:' + $cmdqueue[0]['Parameter5'])
if $cmdqueue[0]['Parameter5'] == '10'
#log('Clearing PING Command')
$currentcmd = 0
cmdComplete
SndIns()
else
log('CURRENT CMD IS NOT PING - NOT CLEARING')
end

else
log('Message is NOT Broadcast')
end
when 0x2 #Delete from Group
when 0x10 # PING
#this is where I catch the InsStdMsg for ping.
log('Caught PING Message from Device')
$currentcmd = 1

when 0x11 # ON
log('Caught Insteon ON from INTERNAL source')
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']

insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
log('Current DIM level:' + param['Parameter11'])

reportStatus(myDevFrom, hextopercent(param['Parameter11']))

$currentcmd = 0
cmdComplete

SndIns()
when 0x13 # OFF
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
reportStatus(myDevFrom, 0)

$currentcmd = 0
cmdComplete
#log('EVENT and state SENT!!!.48:[10]=0')
SndIns()
#####Thermostat Does Not report Status correctly Yet. Have to figure out reportStatus###
when 0x6A #Thermostat Control Get Zone Data (Temp, Setpoint,Humidity)
log('Thermostat returned Zone Info: ' + param['Parameter11'].to_s)
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
#reportStatus(myDevFrom, hextopercent(param['Parameter11']))
$currentcmd = 0
cmdComplete
SndIns()

when 0x6B #Thermostat Control Command Handle Response
log('Thermostat returned: ' + param['Parameter11'].to_s)
case param['Parameter11'].to_s
when '06' # ON/Auto
# $ThermostatStatus = 'ON/Auto' ##not used
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
#log('Current Thermostat State:' + $ThermostatStatus)
#reportStatus(myDevFrom, 6)
$currentcmd = 0
cmdComplete
SndIns()

when '09' #OFF
# $ThermostatStatus = 'OFF' ## not used may be for reportstatus
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
#log('Current Thermostat State:' + $ThermostatStatus)
#reportStatus(myDevFrom, 9)
$currentcmd = 0
cmdComplete
SndIns()

when '04' # Heat
#$ThermostatStatus = 'HEAT'
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
#log('Current Thermostat State:' + $ThermostatStatus)
#reportStatus(myDevFrom, 4)
$currentcmd = 0
cmdComplete
SndIns()

when '05' # Cool
#$ThermostatStatus = 'COOL'
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
#log('Current Thermostat State:' + $ThermostatStatus)
#reportStatus(myDevFrom, 5)
$currentcmd = 0
cmdComplete
SndIns()


when '07' # Fan On
2#$ThermostatStatus = 'COOL'
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
#log('Current Thermostat State:' + $ThermostatStatus)
#reportStatus(myDevFrom, 5)
$currentcmd = 0
cmdComplete
SndIns()


when '08' # Fan Off
#$ThermostatStatus = 'COOL'
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
#log('Current Thermostat State:' + $ThermostatStatus)
#reportStatus(myDevFrom, 5)
$currentcmd = 0
cmdComplete
SndIns()
end


when 0x6C #Thermostat Control Get Zone Cool Point Data
log('Thermostat returned Zone Info: ' + param['Parameter11'].to_s)
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
log('Current Zone level:' + param['Parameter11'].to_s)
#reportStatus(myDevFrom, hextopercent(param['Parameter11']))
$currentcmd = 0
cmdComplete
SndIns()

when 0x6D #Thermostat Control Get Zone Heat Point Data
log('Thermostat returned Zone Info: ' + param['Parameter11'].to_s)
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
log('Current Zone level:' + param['Parameter11'].to_s)
#reportStatus(myDevFrom, hextopercent(param['Parameter11']))
$currentcmd = 0
cmdComplete
SndIns()


when 0x19 # Status Report
# now to clear the currentcmd and remove command from the queue
$currentcmd = 0
cmdComplete

log('Processing 0x19 Status Report')
#This is where I get the database delta (in cmd1)
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
#First, to compare the DB Delta with current config.
#Database Delta...
delta = param['Parameter10'].to_s
log($blue + 'Database Delta=' + delta + $grey)
log($blue + 'Configuration is:' + getdeltafromconfig(insID) + $grey)
if delta == getdeltafromconfig(insID)
if $children[insID] != nil
myDevFrom = $children[insID]
myDevTo = -1000 #DCE Router
myPriority = 1
myType = 2 #Event

#Send an EVENT to report STATE ONLY if database has not changed
# AND child exists in pluto
reportStatus(myDevFrom, hextopercent(param['Parameter11']))
end
else
log('Databse CHANGED -getting remote database')
#here, I have to WIPE the databse
# to prepare it for new data
### here is where the DAMN CONFIG was reset!!!
oldconfigstring = $childdatabases[insID][0]
$childdatabases[insID] = [oldconfigstring]
log('Setting Database Config')
$childdatabases[insID][0][6..7] = delta
savechilddatabases(insID)
sendRemoteGetLink(insID)
end
# finally, to check execute next command...
SndIns()
when 0x28 # Set Address MSB
log('Received SET Address MSB from remote device')
$currentcmd = 0
$remoteLinkRecord = ''
cmdComplete
SndIns()
when 0x2B # peek
### BUG HERE... have to verify response is a PEEK command
#response command is stored in parameter10
if param['Parameter10'].hex == 0x2B # this is the peek command
cmdComplete
log('Received PEEK from remote Device! DATA=' + param['Parameter11'])
checkPeekData(param)
$currentcmd = 0
SndIns()
else
log('Waiting for remote PEEK response, but got :' + param['Parameter10'])
end
else
end

when 'X10Msg'
log($purple + 'X10 Message Received' + $grey)
if param['Parameter4'].hex == 0x00
log('This byte is a House/Unit Code')
hn = param['Parameter3'][0].chr
ln = param['Parameter3'][1].chr
$x10byte1 = $X10HouseCodes[hn]
$x10byte1 += $X10UnitCodes[ln]
log('Translated X10 House/Unit Code:' + $x10byte1)
else
log('This byte is a House/Command Code')
hn = param['Parameter3'][0].chr
ln = param['Parameter3'][1].chr
$x10byte2 = $X10HouseCodes[hn]
$x10byte2 += $X10CommandCodes[ln]
log('Translated X10 Command Code:' + $x10byte2)
log('X10 Command ready to send:' + $x10byte1 + ' ' + $x10byte2)
case $X10CommandCodes[ln]
when 'On'
#Send ON to lmnce
if $children[$x10byte1] == nil
log('I do not control this X10 device')
else
cmd = Command.new($children[$x10byte1].to_i, -1000, 1, 1, 192)
cmd.params_[120] = "1"
SendCommand(cmd)
end
when 'Off'
#Send OFF to lmnce
if $children[$x10byte1] == nil
log('I do not control this X10 device')
else
cmd = Command.new($children[$x10byte1].to_i, -1000, 1, 1, 193)
cmd.params_[120] = "1"
SendCommand(cmd)
end
when 'Bright'
if $children[$x10byte1] == nil
log('I do not control this X10 device')
else
#send a command to set the state + 1
@curstate = ($state[$x10byte1] / 100) * 32 #get equal 32 steps
$state[$x10byte1] = ((@curstate + 1) / 32) * 100
cmd = Command.new($children[$x10byte1].to_i, -1000, 1, 1, 184)
cmd.params_[76] = $state[$x10byte1].to_s
cmd.params_[120] = "1"
SendCommand(cmd)
#$state[$x10byte1] = ($state[$x10byte1] / 100) * 32
end
when 'Dim'
@curstate = ($state[$x10byte1] / 100) * 32 #get equal 32 steps
$state[$x10byte1] = ((@curstate - 1) / 32) * 100
cmd = Command.new($children[$x10byte1].to_i, -1000, 1, 1, 184)
cmd.params_[76] = $state[$x10byte1].to_s
cmd.params_[120] = "1"
SendCommand(cmd)
when 'All Lights Off'
log('ALL Lights OFF Command not implemented')
when 'All Lights On'
log('All Lights ON Command not implemented')
when 'Status Request'
log('Status Request Command not implemented')
when 'Hail Ack'
log('Hail Ack Command not implemented')
end

end
when 'InsLnkSts'
log('InsLnkSts Received')

when 'BtnRpt'
log('Button Report Received')
when 'UsrRst'
log('User Reset Response Received')
when 'GrpEvntRpt'
log('Group Event Report Received')

when 'LnkData'
processLnkData(param)
# Other messages
when 'PLMTimeout'
log('PLM Timeout detected.. resetting EZBridge')
resetcmd = {'Command' => 'Reset'}
if $wAIT == true
$cmdqueue.insert(1, resetcmd)
else
$cmdqueue.insert(0,resetcmd)
end
sleep 15
$wAIT = false
SndIns()
when 'PLMEchoError' # Have not seen this since a1.23
# error sending command to PLM, reset command and try again
log('-----XXXXXXX' + param['Response'])
resetcmd = {'Command' => 'Reset'}
if $wAIT == true
$cmdqueue.insert(1, resetcmd)
else
$cmdqueue.insert(0,resetcmd)
end

sleep 15
$wAIT = false
SndIns()
when 'LongAck'
log('-----XXXXXXX' + param['Response'])
# Error - seems to show up after PLMEchoError
resetcmd = {'Command' => 'Reset'}
if $wAIT == true
$cmdqueue.insert(1, resetcmd)
else
$cmdqueue.insert(0,resetcmd)
end
sleep 15
$wAIT = false
SndIns()
else
log('-----XXXXXXX UNKNOWN Response Received')
end

end

### Support routine for EZToDCE
def processLnkData(param)
#Caught a LnkData Response
log('LnkData Message Received')
log(param.inspect)
if param['Parameter6'] == '00' and param['Parameter7'] == '00'
log('FOUND X10 DEVICE!!!')
insteonID = padhex(param['Parameter5'])
else
insteonID = padhex(param['Parameter5']) + '.' + padhex(param['Parameter6']) + '.' + padhex(param['Parameter7'])
end
group = param['Parameter4']
recflags = param['Parameter3']
lnkdata1 = param['Parameter8']
lnkdata2 = param['Parameter9']
lnkdata3 = param['Parameter10']
#pack string to store for PLM Database
@currentrecord = recflags + group
@currentrecord += param['Parameter5'] + param['Parameter6'] + param['Parameter7']
@currentrecord += lnkdata1 + lnkdata2 + lnkdata3

#Add to plmdatabase
$plmdatabase << @currentrecord
log('record Flags:' + recflags)
#log('PLM database=' +$plmdatabase.inspect)
if (recflags[0] & 0x80) == 0x80 # Record is in use if true
end
if (recflags[0] & 0x40) == 0x40 # Controller if true
log('Controller')
else
log('Responder')
end

log('Insteon ID:' + insteonID + ', Group:' + group)

cmdComplete
sendGetNext()

end
### Support Routine for EZToDCE
def processExternalCommand(param)
#there is no current command
# THIS IS COMING FROM AN OUTSIDE SOURCE
#EG: Manually turning Light Switch On/Off
# process this command.
# Note, this is a standard message
### have to check here if child is mine!

# This is where I have to check for a broadcast command..
#if so, search the child databases for responders,
#and fire events for each responder.
#Message flag is in parameter9 Group command 0xCx (All-Link Broadcast Message Pg 42.)
#Group is in parameter8
#From InsteonID is parameters 3, 4, 5
if (param['Parameter9'].hex & 0xC0) == 0xC0 # Message is Broadcast
log('Rerouting to processBroadcastMessage')
processBroadcastMessage(param)
else
log('Process External Command:')
log('Param:' + param.inspect)

# there is no ack here. Simply Send COMMANDS back to DCE
# and Complete the recv..
case param['Parameter10'].hex #this is the command
when 0x01 #Assign to Group
log('Caught EXTERNAL Assign to Group')
processDeviceInfo(param)
recvComplete
when 0x02 #Delete from Group
when 0x02 #Delete from Group
log('Caught EXTERNAL Delete from Group')
recvComplete
when 0x10 # PING
log('Caught EXTERNAL Insteon PING result')
recvComplete


when 0x11 #ON
log('Caught EXTERNAL Insteon ON command result')
#on level is in cmd2
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
log('From:' +insID)
log('Device:' + $children[insID].to_s)
myDevFrom = $children[insID]
# check to see if I own child
if myDevFrom == nil
log('I do not control this device.')
else
reportStatus(myDevFrom, hextopercent(param['Parameter11']))
$currentcmd = 0
end
recvComplete



when 0x13 #OFF
log('Caught EXTERNAL Insteon OFF result')
#on level is in cmd2
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
if myDevFrom == nil
log('I do not control this device.')
else

reportStatus(myDevFrom, 0)

$currentcmd = 0
#log('EVENT and state SENT!!!.48:[10]=0')
end
recvComplete

when 0x6A #Thermostat Zone Command
log('Caught EXTERNAL Insteon Thermostat result')
#on level is in cmd2
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
if myDevFrom == nil
log('I do not control this device.')
else
#case param['Parameter11'].to_s
#when '00'
reportStatus(myDevFrom, hextoTempurature(param['Parameter11']))
$currentcmd = 0
#when '60' #humidity
#when '20'#setpoint
#log('EVENT and state SENT!!!.48:[10]=0')
end

when 0x6B #Thermostat Mode Command
log('Caught EXTERNAL Insteon Thermostat result')
#on level is in cmd2 ie( HEAT(0x04), COOL(0x05), or AUTO(0x06))
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
if myDevFrom == nil
log('I do not control this device.')
else
#reportStatus(myDevFrom, 0)
$currentcmd = 0
#log('EVENT and state SENT!!!.48:[10]=0')
end

when 0x6C #Thermostat Zone Cool Command
log('Caught EXTERNAL Insteon Thermostat result')
#on level is in cmd2
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
if myDevFrom == nil
log('I do not control this device.')
else
reportStatus(myDevFrom, hextoTempurature(param['Parameter11']))
$currentcmd = 0
#log('EVENT and state SENT!!!.48:[10]=0')
end

when 0x6D #Thermostat Zone Heat Command
log('Caught EXTERNAL Insteon Thermostat result')
#on level is in cmd2
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = insHb + "." + insMb + "." + insLb
myDevFrom = $children[insID]
if myDevFrom == nil
log('I do not control this device.')
else
reportStatus(myDevFrom, hextoTempurature(param['Parameter11']))
$currentcmd = 0
#log('EVENT and state SENT!!!.48:[10]=0')
end



when 0x15; log('Caught EXTERNAL Insteon Brighten Result')
when 0x16; log('Caught EXTERNAL Insteon DIM Result')
when 0x24; log('Caught EXTERNAL Insteon DO EE READ')
when 0x28; log('Caught EXTERNAL Insteon SET ADDRESS MSB')
when 0x29; log('Caught EXTERNAL Insteon POKE')
when 0x2A; log('Caught EXTERNAL Insteon POKE EXTENDED')
when 0x2B; log('Caught EXTERNAL Insteon PEEK')
when 0x2C; log('Caught EXTERNAL Insteon PEEK INTERNAL')
when 0x2D; log('Caught EXTERNAL Insteon POKE INTERNAL')
else
log('Unknown EXTERNAL Insteon Command.')
end
end
end
### Support Routine for EZToDCE
def processACK(param)
#log('In ProcessACK: Param7:' + param['Parameter7'])
#log('CurrentCmd=' + $currentcmd.to_s)
case param['Parameter7'].hex #Received an ack to THIS command
when 0x1 #Assign to Group
log('Got Assign to Group ACK')
$currentcmd = 0x01
$cmdqueue[0]['Command'] = 'InsStdMsg'
#processDeviceInfo(param)
#cmdComplete
when 0x2 #Delete from Group
when 0x10 # PING
log('Got PING ACK')
#cmdComplete
$currentcmd = 0x1
$cmdqueue[0]['Command'] = 'InsStdMsg'
when 0x11 #ON
$currentcmd = 0x11
$cmdqueue[0]['Command'] = 'InsStdMsg'
when 0x13 #OFF
$currentcmd = 0x13
$cmdqueue[0]['Command'] = 'InsStdMsg'
when 0x6A #Thermostat Zone Command
$currentcmd = 0x6A
$cmdqueue[0]['Command'] = 'InsStdMsg'
when 0x6B #Thermostat Control Command
$currentcmd = 0x6B
$cmdqueue[0]['Command'] = 'InsStdMsg'
when 0x6C #Thermostat Cool Command
$currentcmd = 0x6C
$cmdqueue[0]['Command'] = 'InsStdMsg'
when 0x6D #Thermostat Cool Command
$currentcmd = 0x6D
$cmdqueue[0]['Command'] = 'InsStdMsg'
when 0x15 #Bright
$currentcmd = 0x15
$cmdqueue[0]['Command'] = 'InsStdMsg'
when 0x16 #DIM
$currentcmd = 0x16
$cmdqueue[0]['Command'] = 'InsStdMsg'
when 0x17 #Start Manual Change
when 0x18 #Stop Manual Change
when 0x19 #Status Request
# Status Request Acked - get ready for InsStdMsg
$currentcmd = 0x19
# change cmd to reflect InsStdMsg
$cmdqueue[0]['Command'] = 'InsStdMsg'
when 0x24
log('Caught ACK for Insteon DO EE READ')
$currentcmd = 0x24
$cmdqueue[0]['Command'] = 'InsStdMsg'
when 0x28
log('Caught ACK for Insteon SET ADDRESS MSB')
$currentcmd = 0x28
$cmdqueue[0]['Command'] = 'InsStdMsg'

when 0x29
log('Caught ACK for Insteon POKE')
$currentcmd = 0x29
$cmdqueue[0]['Command'] = 'InsStdMsg'

when 0x2A
log('Caught ACK for Insteon POKE EXTENDED')
$currentcmd = 0x2A
$cmdqueue[0]['Command'] = 'InsStdMsg'

when 0x2B
#log('Caught ACK for Insteon PEEK')
$currentcmd = 0x2B
$cmdqueue[0]['Command'] = 'InsStdMsg'

when 0x2C
log('Caught ACK for Insteon PEEK INTERNAL')
$currentcmd = 0x2C
$cmdqueue[0]['Command'] = 'InsStdMsg'

when 0x2D
log('Caught ACK for Insteon POKE INTERNAL')
$currentcmd = 0x2D
$cmdqueue[0]['Command'] = 'InsStdMsg'

else
log('Unknown Insteon Cmd1')
end
end


def checkPeekData(param)

$remoteLinkRecord += param['Parameter11'].hex.chr
log('CURRENT REMOTE RECORD IS:')
debug($remoteLinkRecord)
if $remoteLinkRecord.length == 8
log('REMOTE RECORD COMPLETE!')
processRemoteRecord(param)
$remoteLinkRecord = ''
end
end


def processRemoteRecord(param)
#have to find MY address
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']
insID = padhex(insHb) + "." + padhex(insMb) + "." + padhex(insLb)

log('Processing remote Record below:')

@flags = "\nFrom Device:" + insID + "\nFlags:\n"

if ($remoteLinkRecord[0] & 0x02) == 0x02 # High water mark
@flags += "Not the last record\n"
else
@flags += "This IS the last record\n"
end

if ($remoteLinkRecord[0] & 0x80) == 0x80 # Record is in use
@flags += "Record In Use\n"
if ($remoteLinkRecord[0] & 0x40) == 0x40 # Controller/Responder
@flags += "I am a Controller of "
else
@flags += "I am a Responder of "
end
@insteonID = padhex("%X" %$remoteLinkRecord[2]) + '.'
@insteonID += padhex("%X" %$remoteLinkRecord[3]) + '.'
@insteonID += padhex("%X" %$remoteLinkRecord[4])

@group = "%X" %$remoteLinkRecord[1]
@flags += @insteonID + " Group:" + @group
@work = padhex("%X" %$remoteLinkRecord[0]) #Control byte
@work += padhex("%X" %$remoteLinkRecord[1]) # Group
@work += padhex("%X" %$remoteLinkRecord[2]) # ID HB
@work += padhex("%X" %$remoteLinkRecord[3]) # ID MB
@work += padhex("%X" %$remoteLinkRecord[4]) # ID LB
@work += padhex("%X" %$remoteLinkRecord[5]) # Data1
@work += padhex("%X" %$remoteLinkRecord[6]) # Data2
@work += padhex("%X" %$remoteLinkRecord[7]) # Data3
log('adding to:' + insID)
log('Value:' + @work)
$childdatabases[insID] << @work #add it to the database
# log('Current Database:' + $childdatabases.inspect)
#now to save the database to configuration.
savechilddatabases(insID)
# Now to check to see if the child exists as a record
if $childdatabases[@insteonID] == nil
log('InsteonID is NEW, adding Child database entry')
$childdatabases[@insteonID] = ['****************']
$rerun = true
sendAddtoPLM(@insteonID)
sendPing(@insteonID)
else
log('InsteonID:' + @insteonID.to_s + 'seems to exist in child databases')
log('CDB:' + $childdatabases.inspect)

end
else
@flags += "Record NOT in use\n"
end
log($aqua + @flags + $grey)
log2(@flags)
if ($remoteLinkRecord[0] & 0x02) == 0x02
sendRemoteGetNext(insID)
end
end

def savechilddatabases(insteonID)
#This takes the $childdatabase hash+array and encodes it to
# save it as a string.
@work = ''
#log($yellow + 'SaveChildDatabases::nitems:' + $childdatabases[insteonID].nitems.to_s)
#log($childdatabases[insteonID].inspect + $grey)
$childdatabases[insteonID].each{|record|
@work += record
}

#now to save the string...
setdeviceconfig(insteonID, @work)

end
def sendPing(insteonID)
insID = insteonID.split('.')
param = {'Command' => 'SndIns',
'Parameter1' => insID[0],
'Parameter2' => insID[1],
'Parameter3' => insID[2],
'Parameter4' => '0F',
'Parameter5' => '10', #ID Request
'Parameter6' => '00'}
$cmdqueue << param
log('PING Sent!')
end

def getdevicetemplate(cat, subcat)

log('Entered getdevicetemplate, Cat=' + cat.to_s + ', subcat = ' + subcat.to_s)
@templid = 0
case cat.hex
when 0x0 # Generalized Controllers
case subcat.hex
when 0x04; log('Found ControLinc [2430]')
when 0x05; log('Found RemoteLinc [2440]')
when 0x06; log('Found Icon Tabletop Controller [2830]')
when 0x09; log('Found SignaLinc RF Signal Enhancer [2442]')
when 0x0A; log('Found Balboa Instruments Poolux LCD Controller')
when 0x0B; log('Found Access Point [2443]')
when 0x0C; log('Found IES Color Touchscreen')
end
when 0x01 # Dimmable Lighting Control
# all these devices are associated with Template 38
# Light Switch (dimmable)
@templid = 38
case subcat.hex
when 0x00; log('Found LampLinc V2 [2456D3]')
when 0x01; log('Found SwitchLinc V2 Dimmer 600W [2476D]')
when 0x02; log('Found In-LineLinc Dimmer [2475D]')
when 0x03; log('Found Icon Switch Dimmer [2876D]')
when 0x04; log('Found SwitchLinc V2 Dimmer 1000W [2476DH]')
when 0x06; log('Found LampLinc 2-pin [2456D2]')
when 0x07; log('Found Icon LampLinc V2 2-pin [2456D2]')
when 0x09; log('Found KeypadLinc Dimmer [2486D]')
when 0x0A; log('Found Icon In-Wall Controller [2886D]')
when 0x0D; log('Found SocketLinc [2454D]')
when 0x13; log('Found Icon SwitchLinc Dimmer for Lixar/Bell Canada [2676D-B]')
when 0x17; log('Found ToggleLinc Dimmer [2466D]')
end
when 0x02 # Switched Lighting Control
# all these devices are associated with Template 37
# Light Switch (ON/OFF)
@templid = 37
case subcat.hex

when 0x09; log('Found ApplianceLinc [2456S3]')
when 0x0A; log('Found SwitchLinc Relay [2476S]')
when 0x0B; log('Found Icon On Off Switch [2876S]')
when 0x0C; log('Found Icon Appliance Adapter [2856S3]')
when 0x0D; log('Found ToggleLinc Relay [2466S]')
when 0x0E; log('Found Switchlinc Relay Countdown Timer [2476ST]')
when 0x10; log('Found In-LineLinc Relay [2475D]')
when 0x13; log('Found Icon SwitchLinc Relay for Lixar/Bell Canada [2676R-B]')
end
when 0x03 # Network Bridges
case subcat.hex
when 0x01; log('Found PowerLinc Serial [2414S]')
when 0x02; log('Found PowerLinc USB [2414U]')
when 0x03; log('Found Icon PowerLinc Serial [2814S]')
when 0x04; log('Found Icon PowerLinc USB [2814U]')
when 0x05; log('Found Smartlabs Power Line Modem Serial [2412S]')
end
when 0x04 # Irrigation Control
# all these devices are associated with Template 1780
# Standard Irrigation Sprinkler
@templid = 1780
case subcat.hex

when 0x00; log('Found Simplehomenet EZRain1 Sprinkler Controller')
end
when 0x05 # Climate Control
case subcat.hex
when 0x00; log('Found Broan SMSC080 Exhaust Fan')
when 0x01; log('Found Simplehomenet EZTherm')
when 0x02; log('Found Broan SMSC110 Exhaust Fan')
when 0x03
log('Found Venstar RF Thermostat Module')
@templid = 2198 #Set Template
when 0x04; log('Found Simplehomenet EZStat Thermostat')
end
when 0x06 # Pool and Spa Control
case subcat.hex
when 0x00; log('Found Simplehomenet EZPool')
end
when 0x07 # Sensors and Actuators
case subcat.hex
when 0x00
end
when 0x08 # Home Entertainment
case subcat.hex
when 0x00
end
when 0x09 # Energy Management
case subcat.hex
when 0x00
end
when 0x0A # Built-In Appliance Control
case subcat.hex
when 0x00
end
when 0x0B # Plumbing
case subcat.hex
when 0x00
end
when 0x0C # Communication
case subcat.hex
when 0x00
end
when 0x0D # Computer Control
case subcat.hex
when 0x00
end
when 0x0E # Window Coverings
case subcat.hex
when 0x00
end
when 0x0F # Access Control
case subcat.hex
when 0x00
end
when 0x10 # Security, Health, and Safety
when 0x11 # Surveillance
when 0x12 # Automotive
when 0x13 # Pet care
when 0x14 # Toys
when 0x15 # Timekeeping
when 0x16 # Holiday
end
return @templid
end

def processDeviceInfo(param)
### temporary
### 12-24-07 Adding Device Template compatibility..
#have to find MY address
insHb = param['Parameter3'] # From
insMb = param['Parameter4']
insLb = param['Parameter5']

insID = padhex(insHb) + "." + padhex(insMb) + "." + padhex(insLb)
#set the devicecat and device subcat in the childdatabases
# 0-1 Device Category
# 2-3 Device SubCategory
# 4-5 Device Firmware
log('proccessDeviceInfo:Insteon ID' + insID)
$childdatabases[insID][0][0..1] = param['Parameter6']
$childdatabases[insID][0][2..3] = param['Parameter7']
$childdatabases[insID][0][4..5] = param['Parameter8']
savechilddatabases(insID)
log('InsteonID: ' + insID)
#log('Child Config AFTER update:' + $childdatabases[insID][0].to_s)
log($yellow)
@template = getdevicetemplate(param['Parameter6'], param['Parameter7'])
$devicetemplate[insID] = @template
log('Template ID:' + @template.to_s)
### eventually, open a XML configuration script?
### or read saved data from mysql?
### most likely save this information to sql with device.
### eventually, IPKDB will be available to ping.
log('for Insteon ID:' + insID)
log($grey)
end

def recvComplete
# Clears the wait flag, but does not remove a command from the queue
$wAIT = false
log($green + "Receive Completed. Checking command queue" + $grey)
if $cmdqueue.nitems > 0 then
log("Queue:" + $aqua + $cmdqueue.nitems.to_s + $grey + " : executing next command")
SndIns()
else
log($yellow + 'Queue Empty.' + $grey)
if $rerun == true
log('RERUN=TRUE, RESTARTING')
$rerun = false
mainRestart()
else
log('RERUN Not needed. Checking if reported..')
#report Child devices here.
if $reported == false
log('Reporting Child Devices')
@work = ""
$childdatabases.each_key{
|insteonID|
log('Child:' + insteonID)
log('Config:' + $childdatabases[insteonID].inspect)
@template = $devicetemplate[insteonID]
@work += insteonID + "\t\t\t" + @template.to_s + "\t\n"
}
log(@work)
cmd = Command.new(device_.devid_, -1001, 1, 2, 54)
cmd.params_[13] = @work
SendCommand(cmd)

$reported = true
else
log('report not needed')
end
end

end
end
def removecurrentcommand
#get the current child
log('in RemoveCurrentCommand')
log('Current Command:' + $cmdqueue[0].inspect)
#id is in param123
@id = $cmdqueue[0]['Parameter1']
@id += '.' + $cmdqueue[0]['Parameter2']
@id += '.' + $cmdqueue[0]['Parameter3']
log('ID=' + @id)
#now to remove from child and PLM databases
removefromchild(@id)
removefromplm(@id)
cmdComplete
end
def cmdComplete
# Clears the wait flag, and removes the command from the queue.
$wAIT = false
$resetNext = 0
$cmdqueue.delete_at(0)
# now that THAT command is completed, check to see if there is
# another command ready to transmit.
log($green + "Command Completed." + $grey)
end
def checkWait(param)
#Checks for response from current command.
if $cmdqueue[0] != nil
if $wAIT == true
#log('CW:waiting for command to complete')
else
#log('CW:reports clear')
end
else
log('------:)----checkWait: command queue is emtpy')
if $wAIT == true #this should never happen
log('------:(XXX-CheckWait: TRUE')
end
end
end

def plmparse(value)
#THIS ROUTINE REPLACES parsestring()
#this routine will PARSE the incoming stream into valid messages
# value is the complete command
param = {}
#here is a special case, the PLM seems to lock up.
if value == 0x15.chr
log('The PLM stopped responding')
log('Please unplug it, and plug it back in')
log('and do a quick reload router.')

end
while value.length > 2
case value[1]
when 0x62 # Special case, need to look at flags
if (value[5] & 0x10) == 0x10 # check for extended flag
cmdlen = 23
else
cmdlen = 9
end
param['Response'] = 'SndIns'
when 0x50; cmdlen = 11; param['Response'] = 'InsStdMsg'
when 0x51; cmdlen = 25; param['Response'] = 'InsExtMsg'
when 0x68; cmdlen = 4 #Set Insteon ACK Message Byte
when 0x71; cmdlen = 5 #Set Insteon ACK Message Two Bytes
when 0x70; cmdlen = 4 #Set Insteon NACK Message Byte
when 0x63; cmdlen = 5; param['Response'] = 'SndX10'
when 0x52; cmdlen = 4; param['Response'] = 'X10Msg'
when 0x61; cmdlen = 6; param['Response'] = 'SndGrp'
when 0x56; cmdlen = 7; param['Response'] = 'GrpEvntRpt'
when 0x58; cmdlen = 3 #All-Link Cleanup Status Report
when 0x64; cmdlen = 5; param['Response'] = 'StLnk'
when 0x65; cmdlen = 3; param['Response'] = 'CancelLnk'
when 0x53; cmdlen = 10; param['Response'] = 'InsLnkSts'
when 0x69; cmdlen = 3; param['Response'] = 'GetLnk'
when 0x6A; cmdlen = 3; param['Response'] = 'GetNext'
when 0x6C; cmdlen = 3 #Get All-Link Record for Sender
when 0x57; cmdlen = 10; param['Response'] = 'LnkData'
when 0x6F; cmdlen = 12; param['Response'] = 'MngLnk'
when 0x67; cmdlen = 3; param['Response'] = 'RstPLM'
when 0x6B; cmdlen = 4; param['Response'] = 'SetCfg'
when 0x60; cmdlen = 9; param['Response'] = 'GetVersion'
when 0x66; cmdlen = 6 #Set Host Device Category
when 0x72; cmdlen = 3 # RF Sleep
when 0x54; cmdlen = 3; param['Response'] = 'BtnRpt'
when 0x6D; cmdlen = 3; param['Response'] = 'LEDON'
when 0x6E; cmdlen = 3; param['Response'] = 'LEDOFF'
else

log('ERROR IN PLMPARSE- Unknown Command')
debug(value)

return ''
end

#Now we know the length the command should be, see if we have it.
#log('waiting for ' + cmdlen.to_s + ' characters...')
#log('length of current input is ' + value.length.to_s)
if value.length >= cmdlen
#log('GOT whole response')
#Yes, we have the whole command, Pack it in param
for byt in 1..cmdlen
param['Parameter' + byt.to_s] = padhex("%X" %value[byt - 1])
end
#now remove it from the string..
value = value.slice(cmdlen, value.length - cmdlen)
#Send it off for parsing
#log('Sending to EZToDCE:' + param.inspect.to_s)
EZToDCE(param)
else
#log('Still waiting...')
#no, we have NOT received the whole command.

end
end
return value
end

def rawX10(value)

x10MSN = $X10HouseCodes.index[value[0..0]]
x10LSN = $X10UnitCodes.index[value[1..1]]
return x10MSN + x10LSN
end

def X10Flag(value)
return + $X10CommandCodes.index[Value] + '0'
end

def SndIns
# create a new PLM command for SndIns
if $wAIT == false
#log('SndIns:currentcmd=' + $currentcmd.to_s)

if $cmdqueue.nitems > 0
log("SndIns:Queue:" + $aqua + $cmdqueue.nitems.to_s + $grey)
#log('SndIns:' + $cmdqueue.inspect)
param = $cmdqueue[0]
### have to figure out the command byte 2 here
work = '02'.hex.chr + plmcommand(param)
### PLM command compilation
for loop in 2..param.keys.nitems
@dummy = param['Parameter' + (loop - 1).to_s].to_s
work+= @dummy.hex.chr
end
conn_.Reconnect()
debugout(work)
conn_.Send(work)
#sleep 0.1
$wAIT = TRUE
else
log($yellow + 'Queue Empty.' + $grey)
if $rerun == true
log('RERUN=TRUE, RESTARTING')
$rerun = false
mainRestart()
else
log('RERUN Not needed')
if $reported == false
log('Reporting Child Devices')
@work = ""
$childdatabases.each_key{
|insteonID|
log('Child:' + insteonID)
log('Config:' + $childdatabases[insteonID].inspect)
@template = $devicetemplate[insteonID]
@work += insteonID + "\t\t\t" + @template.to_s + "\t\n"
}
log(@work)
cmd = Command.new(device_.devid_, -1001, 1, 2, 54)
cmd.params_[13] = @work
SendCommand(cmd)

$reported = true
else
log('report not needed')
end
end

end
else
log('X-----------SndIns: Waiting for response to:' + $cmdqueue[0]['Command'].to_s)
log('X-----------SndIns: Current Queue Length:' + $cmdqueue.nitems.to_s)
end
end
def plmcommand(param)
### this returns the proper Byte2 for the command.
case param['Command']
when 'GetVersion'; return 0x60.chr
when 'SndIns'; return 0x62.chr
when 'SndGrp'; return 0x61.chr
when 'SndX10'; return 0x63.chr
when 'GetLnk'; return 0x69.chr
when 'GetNext'; return 0x6A.chr
when 'BtnRpt'; return 0x54.chr
when 'GetCfg'; return 0x73.chr
when 'StLnk'; return 0x64.chr
when 'CancelLnk'; return 0x65.chr
when 'MngLnk'; return 0x6F.chr
when 'RstPLM'; return 0x67.chr
when 'SetCfg'; return 0x6B.chr
when 'LEDON'; return 0x6D.chr
when 'LEDOFF'; return 0x6E.chr
## hack
when 'InsStdMsg'
log('ERROR:PLMCommand encountered a COMMAND of INSSTDMSG')
break
return 0x62.chr
end
end

def debug(text)
work = 'DEBUG:'

for c in 1..text.length
work += padhex("%X" %text[c-1]) + ' '
end
log($yellow + work + "Length:" + text.length.to_s + $grey)
end
def debugout(text)
work = 'out:'

for c in 1..text.length
work += padhex("%X" %text[c-1]) + ' '
end
log($green + work + "Length:" + text.length.to_s + $grey)
end
def debugin(text)
work = 'IN:'

for c in 1..text.length
work += padhex("%X" %text[c-1]) + ' '
end
log($red + work + "Length:" + text.length.to_s + $grey)
end

def padhex(hex)
if hex.length==1
hex = "0" + hex
end
return hex
end

def percenttohex(level)
# convert from percent to byte
return "%X" %((level.to_i * 2.55)).to_i
end

def hextopercent(level)
return ((level.hex.to_i / 2.55)).to_i
end

def hextoTempurature(degree) #Thermostat change hex to tempurature
return ((degree.hex.to_i / 2)).to_i
end
def Tempuraturetohex (degree) #Thermostat Cahnge tempurature to hex
return ((degree.to_1 * 2)).hex
end

def log(line)
$log = File.open("/var/log/pluto/" + device_.devid_.to_s + "_Generic_Serial_Device.log", "a")
$log.puts "(***):" + line.to_s
$log.close
end
def log2(line)
#this will send a message out the the orbiters..
#/usr/pluto/bin/MessageSend localhost 0 20 1 809 9 "Text to Display" 70 "alert" 182 "30" 251 "??"
cmd = Command.new(device_.devid_, -1000, 1, 1, 809)
cmd.params_[9] = line #text to display
cmd.params_[70] = 'PLMMessage' #Token
cmd.params_[182] = '10' #Timeout in seconds
cmd.params_[251] = '??'
SendCommand(cmd)
end
def checkChildRecordsinPLM()
log('Entered CheckChildRecordsinPLM')
# log('In CheckChildRecordsinPLM')
# time to verify all children are in the PLM
#
# log('Total PLM Records:' + $plmdatabase.nitems.to_s)
$plmdatabase.each{|record|
log('Record: = '+ getIIDfromRecord(record) + ' Group:' + getGroupfromRecord(record))
log('checking to see if it needs to be added as a child...')
if existsinchild(getIIDfromRecord(record)) == false

log(getIIDfromRecord(record) + ' needs to be added to the child database')
addtochild(getIIDfromRecord(record))
end
}

$childdatabases.each_key {|child|
if existsinplm(child) == false
log(child + ' needs to be added to PLM')
sendAddtoPLM(child)
else
log(child + ' exists in PLM')
end

#now to scan the childs database
for record in 1..($childdatabases[child].nitems - 1)
@test = $childdatabases[child][record]
if existsinplm(getIIDfromRecord(@test)) == false
log(getIIDfromRecord(@test) + ' needs to be added to PLM')
sendAddtoPLM(getIIDfromRecord(@test))
else
log(getIIDfromRecord(@test) + ' exists in PLM')
end
#Also check to see if it needs to be added in the childdatabases
end
}

end
def existsinplm(insteonid)
result = false
$plmdatabase.each{|record|
#log(insteonid + '==' + getIIDfromRecord(record))
if insteonid == getIIDfromRecord(record)
result = true
end
}
return result
end
def existsinchild(insteonid)
log('ExistsinChild:InsteonID:' + insteonid)
result = false
$childdatabases.each_key{|record|
if insteonid == record
result = true
end
}
log('ExistsinChild result:FALSE') if result == false
log('ExistsinChild result:TRUE') if result == true
return result
end
def addtochild(insteonID)
log('addtochild Routne called')
log('Adding ' + insteonID + ' to the child database...')
if insteonID.length == 2 then
log('Child is X10')
$state[insteonID] = 0
else
log('Child is Insteon')
$childdatabases[insteonID] = ['****************']
sendPing(insteonID)
$rerun = true
end
end


def removefromchild(insteonID)
log('Removing ' + insteonID + ' from child database')
$childdatabases.delete(insteonID)
$state.delete(insteonID)
end
def removefromplm(insteonID)
log('Removing from plm')
$plmdatabase.each{|record|
#log(insteonid + '==' + getIIDfromRecord(record))
if insteonID == getIIDfromRecord(record)
debug(record)
log('Found Record, Deleting')
$plmdatabase.delete(record)

#now, we have to remove it from the device.
param = {'Command' =>'MngLnk',
'Parameter1' => '80', #DELETE
'Parameter2' => record[0..1], #control byte
'Parameter3' => record[2..3], #group
'Parameter4' => record[4..5],#HB
'Parameter5' => record[6..7],#MB
'Parameter6' => record[8..9],#LB
'Parameter7' => record[10..11],#data1
'Parameter8' => record[12..13],#data2
'Parameter9' => record[14..15] #data3

}
log(param.inspect)
$cmdqueue << param
end
}
end
def sendAddtoPLM(insteonID)
log('Adding ' + insteonID + ' to the PLM database...')
#This adds a record into the PLM
@insID = insteonID.split('.')
param = {'Command' => 'MngLnk',
'Parameter1' => '40', #control code -- add new record as Controller
'Parameter2' => 'C2', #All Link Record Flags AKA Record Control Byte
'Parameter3' => '01', #All Link Group
'Parameter4' => @insID[0], #HB
'Parameter5' => @insID[1], #MB
'Parameter6' => @insID[2], #LB
'Parameter7' => '01', #Link Data 1 ON-Level
'Parameter8' => '01', #Link Data 2 Ramp Rate
'Parameter9' => 'FF'} #Link Data 3 not used
if $wAIT == true
$cmdqueue.insert(1, param)
else
$cmdqueue.insert(0, param)
end

SndIns()
end

def getIIDfromRecord(recordstring)
#this extracts the insteonID string from the record.
#log('getIIDfromRecord::recordstring:' + recordstring)
@idhb = recordstring[4..5]
@idmb = recordstring[6..7]
@idlb = recordstring[8..9]
@result = @idhb + '.' + @idmb + '.' +@idlb
#log('GetIIDfromRecord: Found ID:' + @result)
return @result
end

def processBroadcastMessage(param)
#search the child databases for responders,
#and fire COMMANDS for each responder. 06Feb08
#and fire events for each responder.XXXXXXXXXXXXX
#Message flag is in parameter9 Group command 0xCx (All-Link Broadcast Message Pg 42.)
#Group is in parameter8
#From InsteonID is parameters 3, 4, 5
group = param['Parameter8']
from = padhex(param['Parameter3']) + '.'
from += padhex(param['Parameter4']) + '.'
from += padhex(param['Parameter5'])
log('Looking for ' + from + ' Group:' + group)
log('Showing Parameter10:' + param['Parameter10'].to_s)
#Ok, now have to search child databases for from AND group AND responder
$childdatabases.each_key{|child|
#log('Searching:' + child)
for rec in 1..($childdatabases[child].nitems - 1)
record = $childdatabases[child][rec]
if getIIDfromRecord(record) == from # First, look for Insteon ID
#log('Found ID')
if getGroupfromRecord(record) == group #next, Group
#log('Found Group')
if isResponderRecord(record) # is a responder?
#log('Found Responder')
#figure out the child devicenum
from = $children[child]
#figure out the command
case param['Parameter10'].hex
when 0x11 #on
reportStatus(from, 100)
when 0x13 #off
reportStatus(from, 0)
when 0x6B # Thermostat Command On/OFF/AUTO
case param['Parameter11'].to_s
when '09' #status to OFF
#need to set current temp
reportStatus(from, 0)
else
#check thermostat for state and update and set current temp
#reportStatus(from, 100)
end

when 0x6C # Thermostat Command Cool Point
tempurature =param['Parameter11'] /2 #temp in hex need to devide by 2 = current cool point
#reportStatus(from,tempurature)
when 0x6D# Thermostat Command Heat Point
tempurature =param['Parameter11'] /2 #temp in hex need to devide by 2 = current heat point
#reportStatus(from,tempurature)

when 0x17 #dim/brighten -ignore
level = 0
when 0x18 # STOP dim/brighten - sendgetstatus
level = 0
sendGetChildStatus(child)
else
level = 0
log('Command is other than ON/OFF/Dim/Brighten')
end
end
end
end
end
}
end

def reportStatus(from, level)
log('From:' + from.to_s) #shows child id
log('current State:' + $state[from].to_s)
log('Wanted State:' + level.to_s)
case $state[from]
when 0
if level >=1
cmd = Command.new(from, from, 1, 1, 192) #on
cmd.params_[120] = "1"
SendCommand(cmd)
cmd = Command.new(from, from, 1, 1, 184)
cmd.params_[76] = level.to_s
cmd.params_[120] = "1"
SendCommand(cmd)
end
when 100
if level >= 1
cmd = Command.new(from, from, 1, 1, 184)
cmd.params_[76] = level.to_s
cmd.params_[120] = "1"
SendCommand(cmd)
else
cmd = Command.new(from, from, 1, 1, 193) # off
cmd.params_[120] = "1"
SendCommand(cmd)
end
else
if level == 100
cmd = Command.new(from, from, 1, 1, 193) #off
cmd.params_[120] = "1"
SendCommand(cmd)
cmd = Command.new(from, from, 1, 1, 192) # on
cmd.params_[120] = "1"
SendCommand(cmd)
end
cmd = Command.new(from, from, 1, 1, 184) #SetLevel
cmd.params_[76] = level.to_s
cmd.params_[120] = "1"
SendCommand(cmd)
end
log('ReportStatus: device:' + from.to_s + ' Status:' + level.to_s)
$state[from] = level
end

def isResponderRecord(recordstring)
work = recordstring[0..1].hex
if (work & 0x40) == 0x40 #check bit 6
result = false #signifies Controller record
else
result = true #signifies Responder record
end
return result
end

def getGroupfromRecord(recordstring)
#this extracts the GROUP from the record.
if recordstring == nil
return '00'
else
return recordstring[2..3]
end
end
def getdeltafromconfig(insteonID)
#This returns the delta from the child.
@work = $childdatabases[insteonID][0] # the settings stored in [0]
if @work == nil
return '00'
else
return @work[6..7]
end
end
def sendGetChildStatus(insteonID)
#log('sendGetChildStatus Called')
if insteonID.length != 2 #X10 device
@insID = insteonID.split('.')
param = {'Command' => 'SndIns',
'Parameter1' => @insID[0],
'Parameter2' => @insID[1],
'Parameter3' => @insID[2],
'Parameter4' => '0F', #flags
'Parameter5' => '19', #Status Request
'Parameter6' => '00'} #not used.
$cmdqueue << param
SndIns()
#Returned response will have cmd1 = DBDelta
#Returned response will have cmd2 = ON-Level
else
log('X10 does not report status')
end
end
def islast(record)
#high water mark
return false if (record[0..1].hex & 0x02) == 0x02
return true
end

def isinuse(record)
return true if (record[0..1].hex & 0x80) == 0x80
return false
end

def iscontroller(record)
return true if (record[0..1].hex & 0x40) == 0x40
return false
end
def group(record)
return record[2..3]
end
def remoteid(record)

@insteonID = record[4..5] + '.'
@insteonID += record[6..7] + '.'
@insteonID += record[8..9]
return @insteonID
end

def findresponderrecord(masterid, slaveid, groupid)
# log(masterid + ':' + slaveid + ':' + groupid)
$childdatabases[slaveid].each{|check|
# log('Record:' + check.to_s)
if iscontroller(check.to_s) == false #responder record
# log('found responder record')
# log('remoteid:' + remoteid(check.to_s))
if remoteid(check.to_s) == masterid # found
# log('Found Controller ID in responder record')
if group(check.to_s) == groupid
# log('Group Matches')
#found group
return true
end
end
end
}
return false
end
def findcontrollerrecord(masterid, slaveid, groupid)
# log(masterid + ':' + slaveid + ':' + groupid)
$childdatabases[masterid].each{|check|
# log('Record:' + check.to_s)
if iscontroller(check.to_s) == true #controller
# log('found controller record')
if remoteid(check.to_s) == slaveid # found
# log('found Responder ID in Controller record')
if group(check.to_s) == groupid
# log('Group Matches')
#found group
return true
end
end
end
}
return false
end

# time to define a structure to save the raw data in hex
# starts at [0]
# Bytes Meaning
# 0-1 Device Category
# 2-3 Device SubCategory
# 4-5 Device Firmware
# 6-7 Database Delta
# 8-9 reserved
# 10-11 reserved
# 12-13 reserved
# 14-15 reserved
###### First database record below (in same format its read from the device)
###### This is the same format as an ALL-Link Record Response from the PLM
###### (0x57) bytes 3..10
# 16-17 record control byte
# 18-19 Group
# 20-21 ID HB
# 22-23 ID MB
# 24-25 ID LB
# 26-27 Link Specific Data1
# 28-29 Link Specific Data2
# 30-31 Link Specific Data3
######
# 32-47 next database record...