<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://wiki.linuxmce.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Newacct</id>
	<title>LinuxMCE - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.linuxmce.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Newacct"/>
	<link rel="alternate" type="text/html" href="http://wiki.linuxmce.org/index.php/Special:Contributions/Newacct"/>
	<updated>2026-10-27T12:07:15Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.44.0</generator>
	<entry>
		<id>http://wiki.linuxmce.org/index.php?title=Onkyo_TXSR805&amp;diff=23905</id>
		<title>Onkyo TXSR805</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxmce.org/index.php?title=Onkyo_TXSR805&amp;diff=23905"/>
		<updated>2010-06-07T22:48:18Z</updated>

		<summary type="html">&lt;p&gt;Newacct: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category: Audio]]&lt;br /&gt;
{{versioninfo}}&lt;br /&gt;
{{stub}}&lt;br /&gt;
[[category: Tutorials]]&lt;br /&gt;
== Using the Onkyo TX-SR805 with RS232 Control ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;THIS CODE IS STILL BEING DEVELOPED&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Future home of the howto for setting up a Onkyo TX-SR805 with RS232 support.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
May widen howto to all Onkyo RS232 Receivers.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This device does currently work with limited functionality.  A writeup for how to add this device to a Linux MCE system will be done soon.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
** If you use this device and have any problems or suggestions to the code here, please switch over to the discussion tab and bring it to my attention **&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Current features supported:&amp;lt;br&amp;gt;&lt;br /&gt;
-On/Off&amp;lt;br&amp;gt;&lt;br /&gt;
-Change inputs&amp;lt;br&amp;gt;&lt;br /&gt;
-Volume control (Up/Down in set increments.  cmd_313 Set Volume still needs work)&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Being worked on:&amp;lt;br&amp;gt;&lt;br /&gt;
-Precise Volume Control (cmd_313)&amp;lt;br&amp;gt;&lt;br /&gt;
-Listening Modes&amp;lt;br&amp;gt;&lt;br /&gt;
-Zone 2/3&amp;lt;br&amp;gt;&lt;br /&gt;
-FM Tuner&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&#039;&#039;&#039;Ruby Code:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Section: 193 Off&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1PWR00\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 192 On&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1PWR01\r&amp;quot;$&amp;gt;&lt;br /&gt;
 sleep(2)&lt;br /&gt;
 &amp;lt;$&amp;quot;!AMT00\r&amp;quot;$&amp;gt;&lt;br /&gt;
 @mute = false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 169 AM&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI25\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 164 Aux&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI03\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 172 Aux 2&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI04\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 162 CD&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI23\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 165 DVD&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI10\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 170 FM&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI24\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 163 Phono&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI22\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 160 Tape / Tape 1&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI20\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 173 Tape 2&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI21\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 166 Tuner&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI26\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 909 XM&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI31\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 373 Private Method Listing&amp;lt;br&amp;gt;&lt;br /&gt;
 # Written by Jason Bennett&lt;br /&gt;
 #&lt;br /&gt;
 # Process 373 - Methods&lt;br /&gt;
 def receiveMsg&lt;br /&gt;
  buff = conn_.Recv(7, 1000) &lt;br /&gt;
  log(&amp;quot;Message Received: #{buff}&amp;quot;)&lt;br /&gt;
  trash = conn_.Recv(1, 100)&lt;br /&gt;
  if buff.length() &amp;lt; 7&lt;br /&gt;
    parsed1 = &amp;quot;ERR&amp;quot;&lt;br /&gt;
    parsed2 = &amp;quot;00&amp;quot;&lt;br /&gt;
  else&lt;br /&gt;
    parsed2 = buff[5..6]&lt;br /&gt;
    parsed1 = buff[2..4]&lt;br /&gt;
    return [parsed1, parsed2]&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
 #-------------------------------------------- Parsing -----------------------------------------------------------------------------------&lt;br /&gt;
 def chkMsg(cat, opt)&lt;br /&gt;
    case cat&lt;br /&gt;
      # Power&lt;br /&gt;
      when &amp;quot;PWR&amp;quot;&lt;br /&gt;
          cmd = Command.new(device_.devid_, -1001, 1, 2, 48)  # 48 = Power State&lt;br /&gt;
          case opt&lt;br /&gt;
            when &amp;quot;01&amp;quot;&lt;br /&gt;
              cmd.params_[10] = &amp;quot;1&amp;quot;   # Command 48, Param 10: 1 = On&lt;br /&gt;
            when &amp;quot;00&amp;quot;&lt;br /&gt;
              cmd.params_[10] = &amp;quot;0&amp;quot;   # Command 48, Param 10: 2 = Off&lt;br /&gt;
          end&lt;br /&gt;
          SendCommand(cmd)&lt;br /&gt;
      # Master Volume Level&lt;br /&gt;
      when &amp;quot;MVL&amp;quot;&lt;br /&gt;
        cmd = Command.new(device_.devid_, -1001, 1, 2, 71)   # 71 = Volume&lt;br /&gt;
        cmd.params_[30] = opt.hex.to_s # Command 71, Param 16 = Volume Level in Decimal&lt;br /&gt;
        log(&amp;quot;volume reported as: #{opt.hex}&amp;quot;)&lt;br /&gt;
        SendCommand(cmd)&lt;br /&gt;
      # Input Selection&lt;br /&gt;
      when &amp;quot;SLI&amp;quot;&lt;br /&gt;
        cmd = Command.new(device_.devid_, -1001, 1, 2, 49)    # 49 = Input Selection&lt;br /&gt;
        case opt&lt;br /&gt;
          when &amp;quot;00&amp;quot;&lt;br /&gt;
            input_param = 316&lt;br /&gt;
          when &amp;quot;01&amp;quot;&lt;br /&gt;
            input_param = 317&lt;br /&gt;
          when &amp;quot;02&amp;quot;&lt;br /&gt;
            input_param = 318&lt;br /&gt;
          when &amp;quot;03&amp;quot;&lt;br /&gt;
            input_param = 164&lt;br /&gt;
          when &amp;quot;04&amp;quot;&lt;br /&gt;
            input_param = 172&lt;br /&gt;
          when &amp;quot;10&amp;quot;&lt;br /&gt;
            input_param = 165&lt;br /&gt;
          when &amp;quot;20&amp;quot;&lt;br /&gt;
            input_param = 160&lt;br /&gt;
          when &amp;quot;22&amp;quot;&lt;br /&gt;
            input_param = 163&lt;br /&gt;
          when &amp;quot;23&amp;quot;&lt;br /&gt;
            input_param = 162&lt;br /&gt;
          when &amp;quot;24&amp;quot;&lt;br /&gt;
            input_param = 170&lt;br /&gt;
          when &amp;quot;25&amp;quot;&lt;br /&gt;
            input_param = 169&lt;br /&gt;
          when &amp;quot;26&amp;quot;&lt;br /&gt;
            input_param = 166&lt;br /&gt;
          when &amp;quot;31&amp;quot;&lt;br /&gt;
            input_param = 909&lt;br /&gt;
        end&lt;br /&gt;
        cmd.params_[41] = input_param.to_s  # Command 49, Param 41 = Input&lt;br /&gt;
        SendCommand(cmd)&lt;br /&gt;
    end&lt;br /&gt;
 end&lt;br /&gt;
 #-------------------------------------------- Logging -----------------------------------------------------------------------------------&lt;br /&gt;
 def log(line)&lt;br /&gt;
  $log = File.open(&amp;quot;/var/log/pluto/#{device_.devid_}_Generic_Serial_Device.log&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
  $log.puts &amp;quot;(***):#{line}&amp;quot;&lt;br /&gt;
  $log.close&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 350 Process Incoming Data&amp;lt;br&amp;gt;&lt;br /&gt;
 # Written by Jason Bennett&lt;br /&gt;
 #&lt;br /&gt;
 # Process 350 - Incoming&lt;br /&gt;
 incMsg = receiveMsg()&lt;br /&gt;
 log(&amp;quot;New Msg: #{incMsg[0]}:#{incMsg[1]}&amp;quot;)&lt;br /&gt;
 chkMsg(incMsg[0], incMsg[1])&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 355 Process Initialize&amp;lt;br&amp;gt;&lt;br /&gt;
 #31-May-06 14:13 init  Onkyo Receiver&lt;br /&gt;
 initok=false&lt;br /&gt;
 for iRetry in 0...4&lt;br /&gt;
    print &amp;quot;Initializing unit\n&amp;quot;&lt;br /&gt;
      conn_.Send(&amp;quot;!1PWRQSTN\r&amp;quot;)&lt;br /&gt;
    buf = conn_.Recv(200, 1000)&lt;br /&gt;
    if !buf.nil? &amp;amp;&amp;amp; buf.include?(&amp;quot;PWR0&amp;quot;)&lt;br /&gt;
        print &amp;quot;Initialized ok\n&amp;quot;&lt;br /&gt;
                initok=true&lt;br /&gt;
                break&lt;br /&gt;
        else&lt;br /&gt;
                print &amp;quot;Didn&#039;t respond to command\n&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
 end&lt;br /&gt;
 if initok==false&lt;br /&gt;
        DisableDevice( device_.devid_, true )&lt;br /&gt;
        print &amp;quot;The device wouldn&#039;t respond. Disabling it.\n&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
 end&lt;br /&gt;
 print &amp;quot;Initialized ok, doing log\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 97 Mute&amp;lt;br&amp;gt;&lt;br /&gt;
 if(@mute)&lt;br /&gt;
  &amp;lt;$&amp;quot;!1AMT00\r&amp;quot;$&amp;gt;&lt;br /&gt;
 else&lt;br /&gt;
  &amp;lt;$&amp;quot;!1AMT01\r&amp;quot;$&amp;gt;&lt;br /&gt;
 end&lt;br /&gt;
 @mute=!@mute&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 313 Set Volume&amp;lt;br&amp;gt;&lt;br /&gt;
 slevel = &amp;quot;%x&amp;quot; % level.to_i&lt;br /&gt;
 &amp;lt;$&amp;quot;!1MVL&amp;quot; + slevel + &amp;quot;\r&amp;quot;$&amp;gt;&lt;br /&gt;
 SetDeviceDataInDB( device_.devid_, 158, level ) # 158 = DEVICEDATA_Volume_Level_CONST&lt;br /&gt;
 print &amp;quot;volume and corresponding device data set\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 90 Vol Down&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1MVLDOWN\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 89 Vol Up&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1MVLUP\r&amp;quot;$&amp;gt;&lt;/div&gt;</summary>
		<author><name>Newacct</name></author>
	</entry>
	<entry>
		<id>http://wiki.linuxmce.org/index.php?title=Insteon_PLM_Ruby_Code_373&amp;diff=23758</id>
		<title>Insteon PLM Ruby Code 373</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxmce.org/index.php?title=Insteon_PLM_Ruby_Code_373&amp;diff=23758"/>
		<updated>2010-05-16T00:27:08Z</updated>

		<summary type="html">&lt;p&gt;Newacct: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Versioninfo}}&lt;br /&gt;
[[category: Insteon]]&lt;br /&gt;
&amp;lt;pre&amp;gt;#### Written by Dan Damron&lt;br /&gt;
#### #373 Private Method Listing ####&lt;br /&gt;
&lt;br /&gt;
def mainStart() ## This is called FIRST, reruns cannot call this.&lt;br /&gt;
  #Register Message Interceptor&lt;br /&gt;
  @interceptor = Command.new(device_.devid_, -1000, 1, 5, 37)&lt;br /&gt;
  @interceptor.params_[2] = device_.devid_.to_s&lt;br /&gt;
  SendCommand(@interceptor)&lt;br /&gt;
  #Get the PLM Database&lt;br /&gt;
  sendGetLink&lt;br /&gt;
  #get Child devices&lt;br /&gt;
  log(&#039;Finding Children..&#039;)&lt;br /&gt;
  device_.childdevices_.each{|c| $children[device_.childdevices_[c.to_s.to_i].devdata_[12].chomp.strip] = c.to_s.to_i}&lt;br /&gt;
  $children.each{|c,v| log(c + &#039; = &#039; + v.to_s)&lt;br /&gt;
  }&lt;br /&gt;
  log(&#039;reading stored Child configuration:&#039;)&lt;br /&gt;
&lt;br /&gt;
  $children.each_key{|c|&lt;br /&gt;
    #Get each Childs configuration&lt;br /&gt;
    $state[c] = 0&lt;br /&gt;
    getdeviceconfig(c) #&lt;br /&gt;
&lt;br /&gt;
    #the above getdeviceconfig packs $configparams array&lt;br /&gt;
    log(&#039;Configuration for &#039; + c + &#039; = &#039; + $configparams.inspect.to_s)&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  log(&#039;********************************************************&#039;)&lt;br /&gt;
  #get childs actual configuation and status&lt;br /&gt;
  $children.each_key{|c| sendGetChildStatus(c)}&lt;br /&gt;
  SndIns()&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
def mainRestart()&lt;br /&gt;
  #We have hashes already set up.&lt;br /&gt;
  $childdatabases.each_key{|@insteonID|&lt;br /&gt;
    $state[@insteonID] = 0&lt;br /&gt;
    sendGetChildStatus(@insteonID)}&lt;br /&gt;
  SndIns()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def setdeviceconfig(insteonid, configurestring)&lt;br /&gt;
  @deviceid = $children[insteonid]&lt;br /&gt;
  @cmdfrom = device_.devid_&lt;br /&gt;
  @cmdto = 4 #general info plugin&lt;br /&gt;
  @priority = 1&lt;br /&gt;
  @type=1 #command&lt;br /&gt;
  @cmdid = 246&lt;br /&gt;
&lt;br /&gt;
  #set up command..&lt;br /&gt;
  @cmd = Command.new(@cmdfrom, @cmdto, @priority, @type, @cmdid)&lt;br /&gt;
  @cmd.params_[2] = @deviceid.to_s&lt;br /&gt;
  @cmd.params_[52] = &#039;59&#039; # Configuration&lt;br /&gt;
  @cmd.params_[5] = configurestring&lt;br /&gt;
  SendCommand(@cmd)&lt;br /&gt;
  #log(&#039;SetDeviceConfig:&#039; + configurestring)&lt;br /&gt;
  #log(&#039;Configuration Saved - will be available on next reload&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def getdeviceconfig(insteonid)&lt;br /&gt;
  @deviceid = $children[insteonid]&lt;br /&gt;
  @configstring = &#039;&#039;&lt;br /&gt;
  begin&lt;br /&gt;
    @configstring = device_.childdevices_[@deviceid].devdata_[59].to_s&lt;br /&gt;
  rescue&lt;br /&gt;
    log(&#039;Device ID = &#039; + @deviceid.to_s)&lt;br /&gt;
    log($red + &#039;Error - Child has no configuration&#039;+ $grey)&lt;br /&gt;
    log(&#039;Setting initial value of &amp;quot;****************&amp;quot;&#039;)&lt;br /&gt;
    setdeviceconfig(insteonid, (&#039;*&#039; * 16))&lt;br /&gt;
    @configstring = &#039;*&#039; * 16&lt;br /&gt;
    sendPing(insteonid)&lt;br /&gt;
  end&lt;br /&gt;
  if @configstring == &#039;&#039;&lt;br /&gt;
    $configparams = [&#039;****************&#039;]&lt;br /&gt;
    log(&#039;CAUGHT BLANK RECORD&#039;)&lt;br /&gt;
    setdeviceconfig(insteonid, (&#039;*&#039; * 16))&lt;br /&gt;
    sendPing(insteonid)&lt;br /&gt;
  else&lt;br /&gt;
    $configparams = @configstring.unpack(&#039;a16&#039; * (@configstring.length / 16))&lt;br /&gt;
    $devicetemplate[insteonid] = getdevicetemplate($configparams[0][0..1], $configparams[0][2..3])&lt;br /&gt;
  end&lt;br /&gt;
  #log($yellow + &#039;getdeviceconfig:&#039; + $configparams.inspect + $grey)&lt;br /&gt;
  #add the configuration parameters to the child database&lt;br /&gt;
  $childdatabases[insteonid] = $configparams&lt;br /&gt;
  #get the device type&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def sendGetLink()&lt;br /&gt;
  #lets just see exactly what is in the PLM database&lt;br /&gt;
  param = {&#039;Command&#039; =&amp;gt; &#039;GetLnk&#039;}&lt;br /&gt;
  $cmdqueue &amp;lt;&amp;lt; param&lt;br /&gt;
  SndIns()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def sendGetNext()&lt;br /&gt;
  param = {&#039;Command&#039; =&amp;gt; &#039;GetNext&#039;}&lt;br /&gt;
  if $wAIT&lt;br /&gt;
    $cmdqueue.insert(1, param)&lt;br /&gt;
  else&lt;br /&gt;
    $cmdqueue.insert(0,param)&lt;br /&gt;
  end&lt;br /&gt;
  SndIns()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def sendRemoteGetLink(insteonID)&lt;br /&gt;
  # Read First ALDB Record&lt;br /&gt;
  # a few variables need to be set up here..&lt;br /&gt;
  $recordof = insteonID # save the insteon ID&lt;br /&gt;
  insID = insteonID.chomp.split(&#039;.&#039;) # get the seperate bytes&lt;br /&gt;
  $remoteDBOffsetMSB = 0x0F # initial offset&lt;br /&gt;
  $remoteDBOffsetLSB = 0xF8 # initial LSB offset&lt;br /&gt;
  param = {&#039;Command&#039; =&amp;gt; &#039;SndIns&#039;,&lt;br /&gt;
    &#039;Parameter1&#039; =&amp;gt; insID[0], #HB&lt;br /&gt;
    &#039;Parameter2&#039; =&amp;gt; insID[1], #MB&lt;br /&gt;
    &#039;Parameter3&#039; =&amp;gt; insID[2], #LB&lt;br /&gt;
    &#039;Parameter4&#039; =&amp;gt; &#039;0F&#039;, #Flags&lt;br /&gt;
    &#039;Parameter5&#039; =&amp;gt; &#039;28&#039;, #Cmd1&lt;br /&gt;
    &#039;Parameter6&#039; =&amp;gt; &amp;quot;%X&amp;quot; %$remoteDBOffsetMSB #Cmd2 Set MSB Offset&lt;br /&gt;
  }&lt;br /&gt;
  $cmdqueue &amp;lt;&amp;lt; param&lt;br /&gt;
  # repeat last param for each byte to read (F8..FF)=first record&lt;br /&gt;
&lt;br /&gt;
  for x in 0..7&lt;br /&gt;
    param = {&#039;Command&#039; =&amp;gt; &#039;SndIns&#039;,&lt;br /&gt;
      &#039;Parameter1&#039; =&amp;gt; insID[0], #HB&lt;br /&gt;
      &#039;Parameter2&#039; =&amp;gt; insID[1], #MB&lt;br /&gt;
      &#039;Parameter3&#039; =&amp;gt; insID[2], #LB&lt;br /&gt;
      &#039;Parameter4&#039; =&amp;gt; &#039;0F&#039;, #Flags&lt;br /&gt;
      &#039;Parameter5&#039; =&amp;gt; &#039;2B&#039;, #Cmd1 Peek&lt;br /&gt;
      &#039;Parameter6&#039; =&amp;gt; &amp;quot;%X&amp;quot; %($remoteDBOffsetLSB + x) #Cmd2&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $cmdqueue &amp;lt;&amp;lt; param&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def sendRemoteGetNext(insteonID)&lt;br /&gt;
  insID = insteonID.chomp.split(&#039;.&#039;) # get the seperate bytes&lt;br /&gt;
  ### Do NOT forget to check to see if we need to decrease the MSB&lt;br /&gt;
&lt;br /&gt;
  if $remoteDBOffsetLSB == 0x00&lt;br /&gt;
    #OffsetMSB needs to be decreased, and LSB needs reset.&lt;br /&gt;
    $remoteDBOffsetMSB = $remoteDBOffsetMSB - 1&lt;br /&gt;
    $remoteDBOffsetLSN = 0xFF # the next line will decrease this by 8&lt;br /&gt;
  end&lt;br /&gt;
  # decrease DBOffsetLSB by 0x08&lt;br /&gt;
  $remoteDBOffsetLSB = $remoteDBOffsetLSB - 0x08&lt;br /&gt;
&lt;br /&gt;
  for x in 0..7&lt;br /&gt;
    param = {&#039;Command&#039; =&amp;gt; &#039;SndIns&#039;,&lt;br /&gt;
      &#039;Parameter1&#039; =&amp;gt; insID[0], #HB&lt;br /&gt;
      &#039;Parameter2&#039; =&amp;gt; insID[1], #MB&lt;br /&gt;
      &#039;Parameter3&#039; =&amp;gt; insID[2], #LB&lt;br /&gt;
      &#039;Parameter4&#039; =&amp;gt; &#039;0F&#039;, #Flags&lt;br /&gt;
      &#039;Parameter5&#039; =&amp;gt; &#039;2B&#039;, #Cmd1 Peek&lt;br /&gt;
      &#039;Parameter6&#039; =&amp;gt; &amp;quot;%X&amp;quot; %($remoteDBOffsetLSB + x) #Cmd2&lt;br /&gt;
    }&lt;br /&gt;
    #log(&#039;sendRemoteGetNet:added to queue:&#039; + param.inspect)&lt;br /&gt;
    if $wAIT&lt;br /&gt;
      $cmdqueue.insert(x + 1, param)&lt;br /&gt;
    else&lt;br /&gt;
      $cmdqueue.insert(x,param)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
### Main command parsing routine is EZToDCE&lt;br /&gt;
def EZToDCE(param)&lt;br /&gt;
  #param contains a hash of EZBridge command structure&lt;br /&gt;
  #log($blue + &#039;Queue:&#039; + $cmdqueue[0].inspect + $grey)&lt;br /&gt;
  #log($blue + &#039;Param:&#039; + param.inspect + $grey)&lt;br /&gt;
  #log($blue + &#039;currentcmd:&#039; + $currentcmd.to_s + $grey)&lt;br /&gt;
  #checkWait(param)&lt;br /&gt;
  case param[&#039;Response&#039;]&lt;br /&gt;
    # Standard RESPONSES (to commands)&lt;br /&gt;
  when &#039;GetRevision&#039; # Special Response&lt;br /&gt;
    log(&#039;-----|---------GetRevision:&#039; + param[&#039;Parameter1&#039;])&lt;br /&gt;
&lt;br /&gt;
  when &#039;GetLatLong&#039; # Special Response&lt;br /&gt;
    log(&#039;-----|---------GetLatLong: Lat=&#039; + param[&#039;Lat&#039;] + &#039;, Long=&#039; + param[&#039;Long&#039;])&lt;br /&gt;
&lt;br /&gt;
  when &#039;SetLatLong&#039;&lt;br /&gt;
    if param[&#039;Parameter1&#039;] == &#039;True&#039; then&lt;br /&gt;
      log(&#039;-----|---------SetLatLong: Ok&#039;)&lt;br /&gt;
    else&lt;br /&gt;
      log(&#039;-----X---------SetLatLong: FAILED!&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  when &#039;SetPasswd&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;SetTimeZone&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;GetClock&#039; # Special Response&lt;br /&gt;
&lt;br /&gt;
  when &#039;SetClock&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;SetNTPServer&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;Upgrade&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;NetCfg&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;Reset&#039;&lt;br /&gt;
    #Reset Response&lt;br /&gt;
&lt;br /&gt;
    cmdComplete&lt;br /&gt;
    SndIns()&lt;br /&gt;
  when &#039;LstTimers&#039; # Special Response&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  when &#039;ClrTimers&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;AddTimer&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;GetTimer&#039; # Special Response&lt;br /&gt;
&lt;br /&gt;
  when &#039;SetTimer&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;DelTimer&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;GetVersion&#039; # Special Response&lt;br /&gt;
&lt;br /&gt;
  when &#039;SndGrp&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;SndIns&#039; # response from SndIns&lt;br /&gt;
    ### BUG FOUND ### When the EZBridge receives a command from an EXTERNAL source&lt;br /&gt;
    ### ie not from this device, cmdqueue will be nil, and the code below&lt;br /&gt;
    ### fails. Have to check against that.&lt;br /&gt;
    if not $cmdqueue.empty?&lt;br /&gt;
      #First, check the response to make sure the command made it ok.&lt;br /&gt;
      if param[&#039;Parameter9&#039;].to_i == 6 #Ack received&lt;br /&gt;
        #log(&#039;Sending to ProcessACK&#039;)&lt;br /&gt;
        processACK(param)&lt;br /&gt;
      else # NACK received - command failed.&lt;br /&gt;
        log(&#039;Command NACKED&#039;)&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      #Response received for another device.&lt;br /&gt;
      log(&#039;Response detected for a command that was not sent by me&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  when &#039;SndX10&#039;&lt;br /&gt;
    log(&#039;Response detected for SndX10&#039;)&lt;br /&gt;
    if param[&#039;Parameter5&#039;].to_i == 6 #ack&lt;br /&gt;
      log(&#039;X10 Command Successfull&#039;)&lt;br /&gt;
&lt;br /&gt;
      cmdComplete&lt;br /&gt;
      SndIns()&lt;br /&gt;
    else&lt;br /&gt;
      log(&#039;X10 Command FAILED&#039;)&lt;br /&gt;
      cmdComplete&lt;br /&gt;
      SndIns()&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
  when &#039;StLnk&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;CancelLnk&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;SetDev&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;RstPLM&#039;&lt;br /&gt;
    #Reset Response&lt;br /&gt;
    $timeout = 1&lt;br /&gt;
    cmdComplete&lt;br /&gt;
    SndIns()&lt;br /&gt;
&lt;br /&gt;
  when &#039;GetLnk&#039;&lt;br /&gt;
    if param[&#039;Parameter3&#039;].to_i == 6 #ack&lt;br /&gt;
      log(&#039;GetLnk ACKED&#039;)&lt;br /&gt;
      #if we get this, we should get a AllLink Record Response next&lt;br /&gt;
    else&lt;br /&gt;
      log(&#039;GetLnk NACKED&#039;)&lt;br /&gt;
      # The PLM is BLANK&lt;br /&gt;
      #have to add records to the PLM here.&lt;br /&gt;
      cmdComplete&lt;br /&gt;
      ### FINISHED WITH GetLnk&lt;br /&gt;
      checkChildRecordsinPLM()&lt;br /&gt;
      SndIns()&lt;br /&gt;
    end&lt;br /&gt;
  when &#039;GetNext&#039;&lt;br /&gt;
    if param[&#039;Parameter3&#039;].to_i == 6 #ack&lt;br /&gt;
      log(&#039;sendGetNext ACKED&#039;)&lt;br /&gt;
      #if we get this, we should get a AllLink Record Response next&lt;br /&gt;
    else&lt;br /&gt;
      log(&#039;sendGetNext NACKED&#039;)&lt;br /&gt;
      #we get this when there are no more records&lt;br /&gt;
      cmdComplete&lt;br /&gt;
      #FINISHED with GetNext&lt;br /&gt;
      # if we are here, we are in config mode&lt;br /&gt;
      # so, next is to check to make sure the&lt;br /&gt;
      # childrens insteon ID is in the PLM&lt;br /&gt;
      checkChildRecordsinPLM()&lt;br /&gt;
      # now, to make sure that all the records in the PLM are sensed as children&lt;br /&gt;
      &lt;br /&gt;
      SndIns()&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
  when &#039;SetCfg&#039; # response from Setcfg command&lt;br /&gt;
    if param[&#039;Parameter4&#039;].to_i == 6 #ack&lt;br /&gt;
      log(&#039;SetCfg Completed&#039;)&lt;br /&gt;
      cmdComplete&lt;br /&gt;
      SndIns()&lt;br /&gt;
    else&lt;br /&gt;
      log(&#039;SetCfg NACKED&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  when &#039;GetLnkData&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;LEDON&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;LEDOFF&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;MngLnk&#039;&lt;br /&gt;
    if param[&#039;Parameter12&#039;].to_i == 6&lt;br /&gt;
      log(&#039;MngLnk =&amp;gt; ACK&#039;)&lt;br /&gt;
    else&lt;br /&gt;
      log(&#039;MngLnk =&amp;gt; NACK&#039;)&lt;br /&gt;
    end&lt;br /&gt;
    cmdComplete&lt;br /&gt;
    SndIns()&lt;br /&gt;
&lt;br /&gt;
  when &#039;GetCfg&#039; # Special Response&lt;br /&gt;
&lt;br /&gt;
  when &#039;LstMacros&#039; # Special Response&lt;br /&gt;
&lt;br /&gt;
  when &#039;ClrMacros&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;AddMacro&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;GetMacro&#039; # Special Response&lt;br /&gt;
&lt;br /&gt;
  when &#039;SetMacro&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;DelMacro&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;LstDevices&#039; # Special Response&lt;br /&gt;
&lt;br /&gt;
  when &#039;ClrDevices&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;AddDevice&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;GetDevice&#039; # Special Response&lt;br /&gt;
&lt;br /&gt;
  when &#039;SetDevice&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;DelDevice&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;LstZones&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;ClrZones&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;AddZone&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;GetZone&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;SetZone&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;DelZone&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;AddDevZone&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;DelDevZone&#039;&lt;br /&gt;
&lt;br /&gt;
    # Response Messages&lt;br /&gt;
  when &#039;InsExtMsg&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;InsStdMsg&#039;&lt;br /&gt;
    case $currentcmd # if this msg is part of a response, the Insteon Cmd1 will be saved here.&lt;br /&gt;
    when 0x0&lt;br /&gt;
      #log(&#039;REROUTING to processExternalCommand(param)&#039;)&lt;br /&gt;
      processExternalCommand(param)&lt;br /&gt;
    when 0x1 #Assign to Group&lt;br /&gt;
      ### This is a broadcast message sent&lt;br /&gt;
      # from a PING command&lt;br /&gt;
      # or from a StartLink...&lt;br /&gt;
      log(&#039;Caught Assign to Group Message from Device&#039;)&lt;br /&gt;
      ### BUG HERE&lt;br /&gt;
      #have to check flags to see if this is a broadcast message&lt;br /&gt;
      log(&#039;Checking if this is a broadcast message&#039;)&lt;br /&gt;
      log(&#039;Flags:&#039; + param[&#039;Parameter9&#039;])&lt;br /&gt;
      if (param[&#039;Parameter9&#039;].hex &amp;amp; 0x80) == 0x80&lt;br /&gt;
        log(&#039;Message IS BROADCAST&#039;)&lt;br /&gt;
        #recvComplete&lt;br /&gt;
        processDeviceInfo(param)&lt;br /&gt;
&lt;br /&gt;
        # check to see if current cmd is for this broadcast..&lt;br /&gt;
        log(&#039;Current Command:&#039; + $cmdqueue[0][&#039;Parameter5&#039;])&lt;br /&gt;
        if $cmdqueue[0][&#039;Parameter5&#039;] == &#039;10&#039;&lt;br /&gt;
          #log(&#039;Clearing PING Command&#039;)&lt;br /&gt;
          $currentcmd = 0&lt;br /&gt;
          cmdComplete&lt;br /&gt;
          SndIns()&lt;br /&gt;
        else&lt;br /&gt;
          log(&#039;CURRENT CMD IS NOT PING - NOT CLEARING&#039;)&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
      else&lt;br /&gt;
        log(&#039;Message is NOT Broadcast&#039;)&lt;br /&gt;
      end&lt;br /&gt;
    when 0x2 #Delete from Group&lt;br /&gt;
    when 0x10 # PING&lt;br /&gt;
      #this is where I catch the InsStdMsg for ping.&lt;br /&gt;
      log(&#039;Caught PING Message from Device&#039;)&lt;br /&gt;
      $currentcmd = 1&lt;br /&gt;
&lt;br /&gt;
    when 0x11 # ON&lt;br /&gt;
      log(&#039;Caught Insteon ON from INTERNAL source&#039;)&lt;br /&gt;
      insHb = param[&#039;Parameter3&#039;] # From&lt;br /&gt;
      insMb = param[&#039;Parameter4&#039;]&lt;br /&gt;
      insLb = param[&#039;Parameter5&#039;]&lt;br /&gt;
&lt;br /&gt;
      insID = insHb + &amp;quot;.&amp;quot; + insMb + &amp;quot;.&amp;quot; + insLb&lt;br /&gt;
      myDevFrom = $children[insID]&lt;br /&gt;
      log(&#039;Current DIM level:&#039; + param[&#039;Parameter11&#039;])&lt;br /&gt;
&lt;br /&gt;
      reportStatus(myDevFrom, hextopercent(param[&#039;Parameter11&#039;]))&lt;br /&gt;
&lt;br /&gt;
      $currentcmd = 0&lt;br /&gt;
      cmdComplete&lt;br /&gt;
&lt;br /&gt;
      SndIns()&lt;br /&gt;
    when 0x13 # OFF&lt;br /&gt;
      insHb = param[&#039;Parameter3&#039;] # From&lt;br /&gt;
      insMb = param[&#039;Parameter4&#039;]&lt;br /&gt;
      insLb = param[&#039;Parameter5&#039;]&lt;br /&gt;
      insID = insHb + &amp;quot;.&amp;quot; + insMb + &amp;quot;.&amp;quot; + insLb&lt;br /&gt;
      myDevFrom = $children[insID]&lt;br /&gt;
      reportStatus(myDevFrom, 0)&lt;br /&gt;
&lt;br /&gt;
      $currentcmd = 0&lt;br /&gt;
      cmdComplete&lt;br /&gt;
      #log(&#039;EVENT and state SENT!!!.48:[10]=0&#039;)&lt;br /&gt;
      SndIns()&lt;br /&gt;
    when 0x19 # Status Report&lt;br /&gt;
      # now to clear the currentcmd and remove command from the queue&lt;br /&gt;
      $currentcmd = 0&lt;br /&gt;
      cmdComplete&lt;br /&gt;
&lt;br /&gt;
      log(&#039;Processing 0x19 Status Report&#039;)&lt;br /&gt;
      #This is where I get the database delta (in cmd1)&lt;br /&gt;
      insHb = param[&#039;Parameter3&#039;] # From&lt;br /&gt;
      insMb = param[&#039;Parameter4&#039;]&lt;br /&gt;
      insLb = param[&#039;Parameter5&#039;]&lt;br /&gt;
      insID = insHb + &amp;quot;.&amp;quot; + insMb + &amp;quot;.&amp;quot; + insLb&lt;br /&gt;
      #First, to compare the DB Delta with current config.&lt;br /&gt;
      #Database Delta...&lt;br /&gt;
      delta = param[&#039;Parameter10&#039;].to_s&lt;br /&gt;
      log($blue + &#039;Database Delta=&#039; + delta + $grey)&lt;br /&gt;
      log($blue + &#039;Configuration is:&#039; + getdeltafromconfig(insID) + $grey)&lt;br /&gt;
      if delta == getdeltafromconfig(insID)&lt;br /&gt;
        if $children[insID] != nil&lt;br /&gt;
          myDevFrom = $children[insID]&lt;br /&gt;
          myDevTo = -1000 #DCE Router&lt;br /&gt;
          myPriority = 1&lt;br /&gt;
          myType = 2 #Event&lt;br /&gt;
&lt;br /&gt;
          #Send an EVENT to report STATE ONLY if database has not changed&lt;br /&gt;
          # AND child exists in pluto&lt;br /&gt;
          reportStatus(myDevFrom, hextopercent(param[&#039;Parameter11&#039;]))&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        log(&#039;Databse CHANGED -getting remote database&#039;)&lt;br /&gt;
        #here, I have to WIPE the databse&lt;br /&gt;
        # to prepare it for new data&lt;br /&gt;
        ### here is where the DAMN CONFIG was reset!!!&lt;br /&gt;
        oldconfigstring = $childdatabases[insID][0]&lt;br /&gt;
        $childdatabases[insID] = [oldconfigstring]&lt;br /&gt;
        log(&#039;Setting Database Config&#039;)&lt;br /&gt;
        $childdatabases[insID][0][6..7] = delta&lt;br /&gt;
        savechilddatabases(insID)&lt;br /&gt;
        sendRemoteGetLink(insID)&lt;br /&gt;
      end&lt;br /&gt;
      # finally, to check execute next command...&lt;br /&gt;
      SndIns()&lt;br /&gt;
    when 0x28 # Set Address MSB&lt;br /&gt;
      log(&#039;Received SET Address MSB from remote device&#039;)&lt;br /&gt;
      $currentcmd = 0&lt;br /&gt;
      $remoteLinkRecord = &#039;&#039;&lt;br /&gt;
      cmdComplete&lt;br /&gt;
      SndIns()&lt;br /&gt;
    when 0x2B # peek&lt;br /&gt;
      ### BUG HERE... have to verify response is a PEEK command&lt;br /&gt;
      #response command is stored in parameter10&lt;br /&gt;
      if param[&#039;Parameter10&#039;].hex == 0x2B # this is the peek command&lt;br /&gt;
        cmdComplete&lt;br /&gt;
        log(&#039;Received PEEK from remote Device! DATA=&#039; + param[&#039;Parameter11&#039;])&lt;br /&gt;
        checkPeekData(param)&lt;br /&gt;
        $currentcmd = 0&lt;br /&gt;
        SndIns()&lt;br /&gt;
      else&lt;br /&gt;
        log(&#039;Waiting for remote PEEK response, but got :&#039; + param[&#039;Parameter10&#039;])&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
  when &#039;X10Msg&#039;&lt;br /&gt;
    log($purple + &#039;X10 Message Received&#039; + $grey)&lt;br /&gt;
    if param[&#039;Parameter4&#039;].hex == 0x00&lt;br /&gt;
      log(&#039;This byte is a House/Unit Code&#039;)&lt;br /&gt;
      hn = param[&#039;Parameter3&#039;][0].chr&lt;br /&gt;
      ln = param[&#039;Parameter3&#039;][1].chr&lt;br /&gt;
      $x10byte1 = $X10HouseCodes[hn]&lt;br /&gt;
      $x10byte1 += $X10UnitCodes[ln]&lt;br /&gt;
      log(&#039;Translated X10 House/Unit Code:&#039; + $x10byte1)&lt;br /&gt;
    else&lt;br /&gt;
      log(&#039;This byte is a House/Command Code&#039;)&lt;br /&gt;
      hn = param[&#039;Parameter3&#039;][0].chr&lt;br /&gt;
      ln = param[&#039;Parameter3&#039;][1].chr&lt;br /&gt;
      $x10byte2 = $X10HouseCodes[hn]&lt;br /&gt;
      $x10byte2 += $X10CommandCodes[ln]&lt;br /&gt;
      log(&#039;Translated X10 Command Code:&#039; + $x10byte2)&lt;br /&gt;
      log(&#039;X10 Command ready to send:&#039; + $x10byte1 + &#039; &#039; + $x10byte2)&lt;br /&gt;
      case $X10CommandCodes[ln]&lt;br /&gt;
      when &#039;On&#039;&lt;br /&gt;
        #Send ON to lmnce&lt;br /&gt;
        if $children[$x10byte1] == nil&lt;br /&gt;
          log(&#039;I do not control this X10 device&#039;)&lt;br /&gt;
        else&lt;br /&gt;
          cmd = Command.new($children[$x10byte1].to_i, -1000, 1, 1, 192)&lt;br /&gt;
          cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
          SendCommand(cmd)&lt;br /&gt;
        end&lt;br /&gt;
      when &#039;Off&#039;&lt;br /&gt;
        #Send OFF to lmnce&lt;br /&gt;
        if $children[$x10byte1] == nil&lt;br /&gt;
          log(&#039;I do not control this X10 device&#039;)&lt;br /&gt;
        else&lt;br /&gt;
          cmd = Command.new($children[$x10byte1].to_i, -1000, 1, 1, 193)&lt;br /&gt;
          cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
          SendCommand(cmd)&lt;br /&gt;
        end&lt;br /&gt;
      when &#039;Bright&#039;&lt;br /&gt;
        if $children[$x10byte1] == nil&lt;br /&gt;
          log(&#039;I do not control this X10 device&#039;)&lt;br /&gt;
        else&lt;br /&gt;
          #send a command to set the state + 1&lt;br /&gt;
          @curstate = ($state[$x10byte1] / 100) * 32 #get equal 32 steps&lt;br /&gt;
          $state[$x10byte1] = ((@curstate + 1) / 32) * 100&lt;br /&gt;
          cmd = Command.new($children[$x10byte1].to_i, -1000, 1, 1, 184)&lt;br /&gt;
          cmd.params_[76] = $state[$x10byte1].to_s&lt;br /&gt;
          cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
          SendCommand(cmd)&lt;br /&gt;
          #$state[$x10byte1] = ($state[$x10byte1] / 100) * 32&lt;br /&gt;
        end&lt;br /&gt;
      when &#039;Dim&#039;&lt;br /&gt;
        @curstate = ($state[$x10byte1] / 100) * 32 #get equal 32 steps&lt;br /&gt;
        $state[$x10byte1] = ((@curstate - 1) / 32) * 100&lt;br /&gt;
        cmd = Command.new($children[$x10byte1].to_i, -1000, 1, 1, 184)&lt;br /&gt;
        cmd.params_[76] = $state[$x10byte1].to_s&lt;br /&gt;
        cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
        SendCommand(cmd)&lt;br /&gt;
      when &#039;All Lights Off&#039;&lt;br /&gt;
        log(&#039;ALL Lights OFF Command not implemented&#039;)&lt;br /&gt;
      when &#039;All Lights On&#039;&lt;br /&gt;
        log(&#039;All Lights ON Command not implemented&#039;)&lt;br /&gt;
      when &#039;Status Request&#039;&lt;br /&gt;
        log(&#039;Status Request Command not implemented&#039;)&lt;br /&gt;
      when &#039;Hail Ack&#039;&lt;br /&gt;
        log(&#039;Hail Ack Command not implemented&#039;)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
  when &#039;InsLnkSts&#039;&lt;br /&gt;
    log(&#039;InsLnkSts Received&#039;)&lt;br /&gt;
&lt;br /&gt;
  when &#039;BtnRpt&#039;&lt;br /&gt;
    log(&#039;Button Report Received&#039;)&lt;br /&gt;
  when &#039;UsrRst&#039;&lt;br /&gt;
    log(&#039;User Reset Response Received&#039;)&lt;br /&gt;
  when &#039;GrpEvntRpt&#039;&lt;br /&gt;
    log(&#039;Group Event Report Received&#039;)&lt;br /&gt;
&lt;br /&gt;
  when &#039;LnkData&#039;&lt;br /&gt;
    processLnkData(param)&lt;br /&gt;
    # Other messages&lt;br /&gt;
  when &#039;PLMTimeout&#039;&lt;br /&gt;
    log(&#039;PLM Timeout detected.. resetting EZBridge&#039;)&lt;br /&gt;
    resetcmd = {&#039;Command&#039; =&amp;gt; &#039;Reset&#039;}&lt;br /&gt;
    if $wAIT == true&lt;br /&gt;
      $cmdqueue.insert(1, resetcmd)&lt;br /&gt;
    else&lt;br /&gt;
      $cmdqueue.insert(0,resetcmd)&lt;br /&gt;
    end&lt;br /&gt;
    sleep 15&lt;br /&gt;
    $wAIT = false&lt;br /&gt;
    SndIns()&lt;br /&gt;
  when &#039;PLMEchoError&#039; # Have not seen this since a1.23&lt;br /&gt;
    # error sending command to PLM, reset command and try again&lt;br /&gt;
    log(&#039;-----XXXXXXX&#039; + param[&#039;Response&#039;])&lt;br /&gt;
    resetcmd = {&#039;Command&#039; =&amp;gt; &#039;Reset&#039;}&lt;br /&gt;
    if $wAIT == true&lt;br /&gt;
      $cmdqueue.insert(1, resetcmd)&lt;br /&gt;
    else&lt;br /&gt;
      $cmdqueue.insert(0,resetcmd)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    sleep 15&lt;br /&gt;
    $wAIT = false&lt;br /&gt;
    SndIns()&lt;br /&gt;
  when &#039;LongAck&#039;&lt;br /&gt;
    log(&#039;-----XXXXXXX&#039; + param[&#039;Response&#039;])&lt;br /&gt;
    # Error - seems to show up after PLMEchoError&lt;br /&gt;
    resetcmd = {&#039;Command&#039; =&amp;gt; &#039;Reset&#039;}&lt;br /&gt;
    if $wAIT == true&lt;br /&gt;
      $cmdqueue.insert(1, resetcmd)&lt;br /&gt;
    else&lt;br /&gt;
      $cmdqueue.insert(0,resetcmd)&lt;br /&gt;
    end&lt;br /&gt;
    sleep 15&lt;br /&gt;
    $wAIT = false&lt;br /&gt;
    SndIns()&lt;br /&gt;
  else&lt;br /&gt;
    log(&#039;-----XXXXXXX UNKNOWN Response Received&#039;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
### Support routine for EZToDCE&lt;br /&gt;
def processLnkData(param)&lt;br /&gt;
  #Caught a LnkData Response&lt;br /&gt;
  log(&#039;LnkData Message Received&#039;)&lt;br /&gt;
  log(param.inspect)&lt;br /&gt;
  if param[&#039;Parameter6&#039;] == &#039;00&#039; and param[&#039;Parameter7&#039;] == &#039;00&#039;&lt;br /&gt;
    log(&#039;FOUND X10 DEVICE!!!&#039;)&lt;br /&gt;
    insteonID = padhex(param[&#039;Parameter5&#039;])&lt;br /&gt;
  else&lt;br /&gt;
    insteonID = padhex(param[&#039;Parameter5&#039;]) + &#039;.&#039; + padhex(param[&#039;Parameter6&#039;]) + &#039;.&#039; + padhex(param[&#039;Parameter7&#039;])&lt;br /&gt;
  end&lt;br /&gt;
  group = param[&#039;Parameter4&#039;]&lt;br /&gt;
  recflags = param[&#039;Parameter3&#039;]&lt;br /&gt;
  lnkdata1 = param[&#039;Parameter8&#039;]&lt;br /&gt;
  lnkdata2 = param[&#039;Parameter9&#039;]&lt;br /&gt;
  lnkdata3 = param[&#039;Parameter10&#039;]&lt;br /&gt;
  #pack string to store for PLM Database&lt;br /&gt;
  @currentrecord = recflags + group&lt;br /&gt;
  @currentrecord += param[&#039;Parameter5&#039;] + param[&#039;Parameter6&#039;] + param[&#039;Parameter7&#039;]&lt;br /&gt;
  @currentrecord += lnkdata1 + lnkdata2 + lnkdata3&lt;br /&gt;
&lt;br /&gt;
  #Add to plmdatabase&lt;br /&gt;
  $plmdatabase &amp;lt;&amp;lt; @currentrecord&lt;br /&gt;
  log(&#039;record Flags:&#039; + recflags)&lt;br /&gt;
  #log(&#039;PLM database=&#039; +$plmdatabase.inspect)&lt;br /&gt;
  if (recflags[0] &amp;amp; 0x80) == 0x80 # Record is in use if true&lt;br /&gt;
  end&lt;br /&gt;
  if (recflags[0] &amp;amp; 0x40) == 0x40 # Controller if true&lt;br /&gt;
    log(&#039;Controller&#039;)&lt;br /&gt;
  else&lt;br /&gt;
    log(&#039;Responder&#039;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  log(&#039;Insteon ID:&#039; + insteonID + &#039;, Group:&#039; + group)&lt;br /&gt;
&lt;br /&gt;
  cmdComplete&lt;br /&gt;
  sendGetNext()&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
### Support Routine for EZToDCE&lt;br /&gt;
def processExternalCommand(param)&lt;br /&gt;
  #there is no current command&lt;br /&gt;
  # THIS IS COMING FROM AN OUTSIDE SOURCE&lt;br /&gt;
  #EG: Manually turning Light Switch On/Off&lt;br /&gt;
  # process this command.&lt;br /&gt;
  # Note, this is a standard message&lt;br /&gt;
  ### have to check here if child is mine!&lt;br /&gt;
&lt;br /&gt;
  # This is where I have to check for a broadcast command..&lt;br /&gt;
  #if so, search the child databases for responders,&lt;br /&gt;
  #and fire events for each responder.&lt;br /&gt;
  #Message flag is in parameter9 Group command 0xCx (All-Link Broadcast Message Pg 42.)&lt;br /&gt;
  #Group is in parameter8&lt;br /&gt;
  #From InsteonID is parameters 3, 4, 5&lt;br /&gt;
  if (param[&#039;Parameter9&#039;].hex &amp;amp; 0xC0) == 0xC0 # Message is Broadcast&lt;br /&gt;
    log(&#039;Rerouting to processBroadcastMessage&#039;)&lt;br /&gt;
    processBroadcastMessage(param)&lt;br /&gt;
  else&lt;br /&gt;
    log(&#039;Process External Command:&#039;)&lt;br /&gt;
    log(&#039;Param:&#039; + param.inspect)&lt;br /&gt;
&lt;br /&gt;
    # there is no ack here. Simply Send COMMANDS back to DCE&lt;br /&gt;
    # and Complete the recv..&lt;br /&gt;
    case param[&#039;Parameter10&#039;].hex #this is the command&lt;br /&gt;
    when 0x01 #Assign to Group&lt;br /&gt;
      log(&#039;Caught EXTERNAL Assign to Group&#039;)&lt;br /&gt;
      processDeviceInfo(param)&lt;br /&gt;
      recvComplete&lt;br /&gt;
    when 0x02 #Delete from Group&lt;br /&gt;
      log(&#039;Caught EXTERNAL Delete from Group&#039;)&lt;br /&gt;
      recvComplete&lt;br /&gt;
    when 0x10 # PING&lt;br /&gt;
      log(&#039;Caught EXTERNAL Insteon PING result&#039;)&lt;br /&gt;
      recvComplete&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    when 0x11 #ON&lt;br /&gt;
      log(&#039;Caught EXTERNAL Insteon ON command result&#039;)&lt;br /&gt;
      #on level is in cmd2&lt;br /&gt;
      insHb = param[&#039;Parameter3&#039;] # From&lt;br /&gt;
      insMb = param[&#039;Parameter4&#039;]&lt;br /&gt;
      insLb = param[&#039;Parameter5&#039;]&lt;br /&gt;
      insID = insHb + &amp;quot;.&amp;quot; + insMb + &amp;quot;.&amp;quot; + insLb&lt;br /&gt;
      log(&#039;From:&#039; +insID)&lt;br /&gt;
      log(&#039;Device:&#039; + $children[insID].to_s)&lt;br /&gt;
      myDevFrom = $children[insID]&lt;br /&gt;
      # check to see if I own child&lt;br /&gt;
      if myDevFrom == nil&lt;br /&gt;
        log(&#039;I do not control this device.&#039;)&lt;br /&gt;
      else&lt;br /&gt;
        reportStatus(myDevFrom, hextopercent(param[&#039;Parameter11&#039;]))&lt;br /&gt;
        $currentcmd = 0&lt;br /&gt;
      end&lt;br /&gt;
      recvComplete&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    when 0x13 #OFF&lt;br /&gt;
      log(&#039;Caught EXTERNAL Insteon OFF result&#039;)&lt;br /&gt;
      #on level is in cmd2&lt;br /&gt;
      insHb = param[&#039;Parameter3&#039;] # From&lt;br /&gt;
      insMb = param[&#039;Parameter4&#039;]&lt;br /&gt;
      insLb = param[&#039;Parameter5&#039;]&lt;br /&gt;
      insID = insHb + &amp;quot;.&amp;quot; + insMb + &amp;quot;.&amp;quot; + insLb&lt;br /&gt;
      myDevFrom = $children[insID]&lt;br /&gt;
      if myDevFrom == nil&lt;br /&gt;
        log(&#039;I do not control this device.&#039;)&lt;br /&gt;
      else&lt;br /&gt;
&lt;br /&gt;
        reportStatus(myDevFrom, 0)&lt;br /&gt;
&lt;br /&gt;
        $currentcmd = 0&lt;br /&gt;
        #log(&#039;EVENT and state SENT!!!.48:[10]=0&#039;)&lt;br /&gt;
      end&lt;br /&gt;
      recvComplete&lt;br /&gt;
    when 0x15; log(&#039;Caught EXTERNAL Insteon Brighten Result&#039;)&lt;br /&gt;
    when 0x16; log(&#039;Caught EXTERNAL Insteon DIM Result&#039;)&lt;br /&gt;
    when 0x24; log(&#039;Caught EXTERNAL Insteon DO EE READ&#039;)&lt;br /&gt;
    when 0x28; log(&#039;Caught EXTERNAL Insteon SET ADDRESS MSB&#039;)&lt;br /&gt;
    when 0x29; log(&#039;Caught EXTERNAL Insteon POKE&#039;)&lt;br /&gt;
    when 0x2A; log(&#039;Caught EXTERNAL Insteon POKE EXTENDED&#039;)&lt;br /&gt;
    when 0x2B; log(&#039;Caught EXTERNAL Insteon PEEK&#039;)&lt;br /&gt;
    when 0x2C; log(&#039;Caught EXTERNAL Insteon PEEK INTERNAL&#039;)&lt;br /&gt;
    when 0x2D; log(&#039;Caught EXTERNAL Insteon POKE INTERNAL&#039;)&lt;br /&gt;
    else&lt;br /&gt;
      log(&#039;Unknown EXTERNAL Insteon Command.&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
### Support Routine for EZToDCE&lt;br /&gt;
def processACK(param)&lt;br /&gt;
  #log(&#039;In ProcessACK: Param7:&#039; + param[&#039;Parameter7&#039;])&lt;br /&gt;
  #log(&#039;CurrentCmd=&#039; + $currentcmd.to_s)&lt;br /&gt;
  case param[&#039;Parameter7&#039;].hex #Received an ack to THIS command&lt;br /&gt;
  when 0x1 #Assign to Group&lt;br /&gt;
    log(&#039;Got Assign to Group ACK&#039;)&lt;br /&gt;
    $currentcmd = 0x01&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
    #processDeviceInfo(param)&lt;br /&gt;
    #cmdComplete&lt;br /&gt;
  when 0x2 #Delete from Group&lt;br /&gt;
  when 0x10 # PING&lt;br /&gt;
    log(&#039;Got PING ACK&#039;)&lt;br /&gt;
    #cmdComplete&lt;br /&gt;
    $currentcmd = 0x1&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
  when 0x11 #ON&lt;br /&gt;
    $currentcmd = 0x11&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
  when 0x13 #OFF&lt;br /&gt;
    $currentcmd = 0x13&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
  when 0x15 #Bright&lt;br /&gt;
    $currentcmd = 0x15&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
  when 0x16 #DIM&lt;br /&gt;
    $currentcmd = 0x16&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
  when 0x17 #Start Manual Change&lt;br /&gt;
  when 0x18 #Stop Manual Change&lt;br /&gt;
  when 0x19 #Status Request&lt;br /&gt;
    # Status Request Acked - get ready for InsStdMsg&lt;br /&gt;
    $currentcmd = 0x19&lt;br /&gt;
    # change cmd to reflect InsStdMsg&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
  when 0x24&lt;br /&gt;
    log(&#039;Caught ACK for Insteon DO EE READ&#039;)&lt;br /&gt;
    $currentcmd = 0x24&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
  when 0x28&lt;br /&gt;
    log(&#039;Caught ACK for Insteon SET ADDRESS MSB&#039;)&lt;br /&gt;
    $currentcmd = 0x28&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
&lt;br /&gt;
  when 0x29&lt;br /&gt;
    log(&#039;Caught ACK for Insteon POKE&#039;)&lt;br /&gt;
    $currentcmd = 0x29&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
&lt;br /&gt;
  when 0x2A&lt;br /&gt;
    log(&#039;Caught ACK for Insteon POKE EXTENDED&#039;)&lt;br /&gt;
    $currentcmd = 0x2A&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
&lt;br /&gt;
  when 0x2B&lt;br /&gt;
    #log(&#039;Caught ACK for Insteon PEEK&#039;)&lt;br /&gt;
    $currentcmd = 0x2B&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
&lt;br /&gt;
  when 0x2C&lt;br /&gt;
    log(&#039;Caught ACK for Insteon PEEK INTERNAL&#039;)&lt;br /&gt;
    $currentcmd = 0x2C&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
&lt;br /&gt;
  when 0x2D&lt;br /&gt;
    log(&#039;Caught ACK for Insteon POKE INTERNAL&#039;)&lt;br /&gt;
    $currentcmd = 0x2D&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
&lt;br /&gt;
  else&lt;br /&gt;
    log(&#039;Unknown Insteon Cmd1&#039;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def checkPeekData(param)&lt;br /&gt;
&lt;br /&gt;
  $remoteLinkRecord += param[&#039;Parameter11&#039;].hex.chr&lt;br /&gt;
  log(&#039;CURRENT REMOTE RECORD IS:&#039;)&lt;br /&gt;
  debug($remoteLinkRecord)&lt;br /&gt;
  if $remoteLinkRecord.length == 8&lt;br /&gt;
    log(&#039;REMOTE RECORD COMPLETE!&#039;)&lt;br /&gt;
    processRemoteRecord(param)&lt;br /&gt;
    $remoteLinkRecord = &#039;&#039;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def processRemoteRecord(param)&lt;br /&gt;
  #have to find MY address&lt;br /&gt;
  insHb = param[&#039;Parameter3&#039;] # From&lt;br /&gt;
  insMb = param[&#039;Parameter4&#039;]&lt;br /&gt;
  insLb = param[&#039;Parameter5&#039;]&lt;br /&gt;
  insID = padhex(insHb) + &amp;quot;.&amp;quot; + padhex(insMb) + &amp;quot;.&amp;quot; + padhex(insLb)&lt;br /&gt;
&lt;br /&gt;
  log(&#039;Processing remote Record below:&#039;)&lt;br /&gt;
&lt;br /&gt;
  @flags = &amp;quot;\nFrom Device:&amp;quot; + insID + &amp;quot;\nFlags:\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  if ($remoteLinkRecord[0] &amp;amp; 0x02) == 0x02 # High water mark&lt;br /&gt;
    @flags += &amp;quot;Not the last record\n&amp;quot;&lt;br /&gt;
  else&lt;br /&gt;
    @flags += &amp;quot;This IS the last record\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  if ($remoteLinkRecord[0] &amp;amp; 0x80) == 0x80 # Record is in use&lt;br /&gt;
    @flags += &amp;quot;Record In Use\n&amp;quot;&lt;br /&gt;
    if ($remoteLinkRecord[0] &amp;amp; 0x40) == 0x40 # Controller/Responder&lt;br /&gt;
      @flags += &amp;quot;I am a Controller of &amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      @flags += &amp;quot;I am a Responder of &amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    @insteonID = &amp;quot;%02X&amp;quot; %$remoteLinkRecord[2] + &#039;.&#039;&lt;br /&gt;
    @insteonID += &amp;quot;%02X&amp;quot; %$remoteLinkRecord[3] + &#039;.&#039;&lt;br /&gt;
    @insteonID += &amp;quot;%02X&amp;quot; %$remoteLinkRecord[4]&lt;br /&gt;
&lt;br /&gt;
    @group = &amp;quot;%X&amp;quot; %$remoteLinkRecord[1]&lt;br /&gt;
    @flags += @insteonID + &amp;quot; Group:&amp;quot; + @group&lt;br /&gt;
    @work = &amp;quot;%02X&amp;quot; %$remoteLinkRecord[0] #Control byte&lt;br /&gt;
    @work += &amp;quot;%02X&amp;quot; %$remoteLinkRecord[1] # Group&lt;br /&gt;
    @work += &amp;quot;%02X&amp;quot; %$remoteLinkRecord[2] # ID HB&lt;br /&gt;
    @work += &amp;quot;%02X&amp;quot; %$remoteLinkRecord[3] # ID MB&lt;br /&gt;
    @work += &amp;quot;%02X&amp;quot; %$remoteLinkRecord[4] # ID LB&lt;br /&gt;
    @work += &amp;quot;%02X&amp;quot; %$remoteLinkRecord[5] # Data1&lt;br /&gt;
    @work += &amp;quot;%02X&amp;quot; %$remoteLinkRecord[6] # Data2&lt;br /&gt;
    @work += &amp;quot;%02X&amp;quot; %$remoteLinkRecord[7] # Data3&lt;br /&gt;
    log(&#039;adding to:&#039; + insID)&lt;br /&gt;
    log(&#039;Value:&#039; + @work)&lt;br /&gt;
    $childdatabases[insID] &amp;lt;&amp;lt; @work #add it to the database&lt;br /&gt;
    # log(&#039;Current Database:&#039; + $childdatabases.inspect)&lt;br /&gt;
    #now to save the database to configuration.&lt;br /&gt;
    savechilddatabases(insID)&lt;br /&gt;
    # Now to check to see if the child exists as a record&lt;br /&gt;
    if $childdatabases[@insteonID] == nil&lt;br /&gt;
      log(&#039;InsteonID is NEW, adding Child database entry&#039;)&lt;br /&gt;
      $childdatabases[@insteonID] = [&#039;****************&#039;]&lt;br /&gt;
      $rerun = true&lt;br /&gt;
      sendAddtoPLM(@insteonID)&lt;br /&gt;
      sendPing(@insteonID)&lt;br /&gt;
    else&lt;br /&gt;
      log(&#039;InsteonID:&#039; + @insteonID.to_s + &#039;seems to exist in child databases&#039;)&lt;br /&gt;
      log(&#039;CDB:&#039; + $childdatabases.inspect)&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    @flags += &amp;quot;Record NOT in use\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  log($aqua + @flags + $grey)&lt;br /&gt;
  log2(@flags)&lt;br /&gt;
  if ($remoteLinkRecord[0] &amp;amp; 0x02) == 0x02&lt;br /&gt;
    sendRemoteGetNext(insID)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def savechilddatabases(insteonID)&lt;br /&gt;
  #This takes the $childdatabase hash+array and encodes it to&lt;br /&gt;
  # save it as a string.&lt;br /&gt;
  @work = &#039;&#039;&lt;br /&gt;
  #log($yellow + &#039;SaveChildDatabases::nitems:&#039; + $childdatabases[insteonID].nitems.to_s)&lt;br /&gt;
  #log($childdatabases[insteonID].inspect + $grey)&lt;br /&gt;
  $childdatabases[insteonID].each{|record|&lt;br /&gt;
    @work += record&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  #now to save the string...&lt;br /&gt;
  setdeviceconfig(insteonID, @work)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
def sendPing(insteonID)&lt;br /&gt;
  insID = insteonID.split(&#039;.&#039;)&lt;br /&gt;
  param = {&#039;Command&#039; =&amp;gt; &#039;SndIns&#039;,&lt;br /&gt;
    &#039;Parameter1&#039; =&amp;gt; insID[0],&lt;br /&gt;
    &#039;Parameter2&#039; =&amp;gt; insID[1],&lt;br /&gt;
    &#039;Parameter3&#039; =&amp;gt; insID[2],&lt;br /&gt;
    &#039;Parameter4&#039; =&amp;gt; &#039;0F&#039;,&lt;br /&gt;
    &#039;Parameter5&#039; =&amp;gt; &#039;10&#039;, #ID Request&lt;br /&gt;
    &#039;Parameter6&#039; =&amp;gt; &#039;00&#039;}&lt;br /&gt;
  $cmdqueue &amp;lt;&amp;lt; param&lt;br /&gt;
  log(&#039;PING Sent!&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def getdevicetemplate(cat, subcat)&lt;br /&gt;
&lt;br /&gt;
  log(&#039;Entered getdevicetemplate, Cat=&#039; + cat.to_s + &#039;, subcat = &#039; + subcat.to_s)&lt;br /&gt;
  @templid = 0&lt;br /&gt;
  case cat.hex&lt;br /&gt;
  when 0x0 # Generalized Controllers&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x04; log(&#039;Found ControLinc [2430]&#039;)&lt;br /&gt;
    when 0x05; log(&#039;Found RemoteLinc [2440]&#039;)&lt;br /&gt;
    when 0x06; log(&#039;Found Icon Tabletop Controller [2830]&#039;)&lt;br /&gt;
    when 0x09; log(&#039;Found SignaLinc RF Signal Enhancer [2442]&#039;)&lt;br /&gt;
    when 0x0A; log(&#039;Found Balboa Instruments Poolux LCD Controller&#039;)&lt;br /&gt;
    when 0x0B; log(&#039;Found Access Point [2443]&#039;)&lt;br /&gt;
    when 0x0C; log(&#039;Found IES Color Touchscreen&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  when 0x01 # Dimmable Lighting Control&lt;br /&gt;
    # all these devices are associated with Template 38&lt;br /&gt;
    # Light Switch (dimmable)&lt;br /&gt;
    @templid = 38&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00; log(&#039;Found LampLinc V2 [2456D3]&#039;)&lt;br /&gt;
    when 0x01; log(&#039;Found SwitchLinc V2 Dimmer 600W [2476D]&#039;)&lt;br /&gt;
    when 0x02; log(&#039;Found In-LineLinc Dimmer [2475D]&#039;)&lt;br /&gt;
    when 0x03; log(&#039;Found Icon Switch Dimmer [2876D]&#039;)&lt;br /&gt;
    when 0x04; log(&#039;Found SwitchLinc V2 Dimmer 1000W [2476DH]&#039;)&lt;br /&gt;
    when 0x06; log(&#039;Found LampLinc 2-pin [2456D2]&#039;)&lt;br /&gt;
    when 0x07; log(&#039;Found Icon LampLinc V2 2-pin [2456D2]&#039;)&lt;br /&gt;
    when 0x09; log(&#039;Found KeypadLinc Dimmer [2486D]&#039;)&lt;br /&gt;
    when 0x0A; log(&#039;Found Icon In-Wall Controller [2886D]&#039;)&lt;br /&gt;
    when 0x0D; log(&#039;Found SocketLinc [2454D]&#039;)&lt;br /&gt;
    when 0x13; log(&#039;Found Icon SwitchLinc Dimmer for Lixar/Bell Canada [2676D-B]&#039;)&lt;br /&gt;
    when 0x17; log(&#039;Found ToggleLinc Dimmer [2466D]&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  when 0x02 # Switched Lighting Control&lt;br /&gt;
    # all these devices are associated with Template 37&lt;br /&gt;
    # Light Switch (ON/OFF)&lt;br /&gt;
    @templid = 37&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
&lt;br /&gt;
    when 0x09; log(&#039;Found ApplianceLinc [2456S3]&#039;)&lt;br /&gt;
    when 0x0A; log(&#039;Found SwitchLinc Relay [2476S]&#039;)&lt;br /&gt;
    when 0x0B; log(&#039;Found Icon On Off Switch [2876S]&#039;)&lt;br /&gt;
    when 0x0C; log(&#039;Found Icon Appliance Adapter [2856S3]&#039;)&lt;br /&gt;
    when 0x0D; log(&#039;Found ToggleLinc Relay [2466S]&#039;)&lt;br /&gt;
    when 0x0E; log(&#039;Found Switchlinc Relay Countdown Timer [2476ST]&#039;)&lt;br /&gt;
    when 0x10; log(&#039;Found In-LineLinc Relay [2475D]&#039;)&lt;br /&gt;
    when 0x13; log(&#039;Found Icon SwitchLinc Relay for Lixar/Bell Canada [2676R-B]&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  when 0x03 # Network Bridges&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x01; log(&#039;Found PowerLinc Serial [2414S]&#039;)&lt;br /&gt;
    when 0x02; log(&#039;Found PowerLinc USB [2414U]&#039;)&lt;br /&gt;
    when 0x03; log(&#039;Found Icon PowerLinc Serial [2814S]&#039;)&lt;br /&gt;
    when 0x04; log(&#039;Found Icon PowerLinc USB [2814U]&#039;)&lt;br /&gt;
    when 0x05; log(&#039;Found Smartlabs Power Line Modem Serial [2412S]&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  when 0x04 # Irrigation Control&lt;br /&gt;
    # all these devices are associated with Template 1780&lt;br /&gt;
    # Standard Irrigation Sprinkler&lt;br /&gt;
    @templid = 1780&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
&lt;br /&gt;
    when 0x00; log(&#039;Found Simplehomenet EZRain1 Sprinkler Controller&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  when 0x05 # Climate Control&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00; log(&#039;Found Broan SMSC080 Exhaust Fan&#039;)&lt;br /&gt;
    when 0x01; log(&#039;Found Simplehomenet EZTherm&#039;)&lt;br /&gt;
    when 0x02; log(&#039;Found Broan SMSC110 Exhaust Fan&#039;)&lt;br /&gt;
    when 0x03; log(&#039;Found Venstar RF Thermostat Module&#039;)&lt;br /&gt;
    when 0x04; log(&#039;Found Simplehomenet EZStat Thermostat&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  when 0x06 # Pool and Spa Control&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00; log(&#039;Found Simplehomenet EZPool&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  when 0x07 # Sensors and Actuators&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00&lt;br /&gt;
    end&lt;br /&gt;
  when 0x08 # Home Entertainment&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00&lt;br /&gt;
    end&lt;br /&gt;
  when 0x09 # Energy Management&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00&lt;br /&gt;
    end&lt;br /&gt;
  when 0x0A # Built-In Appliance Control&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00&lt;br /&gt;
    end&lt;br /&gt;
  when 0x0B # Plumbing&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00&lt;br /&gt;
    end&lt;br /&gt;
  when 0x0C # Communication&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00&lt;br /&gt;
    end&lt;br /&gt;
  when 0x0D # Computer Control&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00&lt;br /&gt;
    end&lt;br /&gt;
  when 0x0E # Window Coverings&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00&lt;br /&gt;
    end&lt;br /&gt;
  when 0x0F # Access Control&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00&lt;br /&gt;
    end&lt;br /&gt;
  when 0x10 # Security, Health, and Safety&lt;br /&gt;
  when 0x11 # Surveillance&lt;br /&gt;
  when 0x12 # Automotive&lt;br /&gt;
  when 0x13 # Pet care&lt;br /&gt;
  when 0x14 # Toys&lt;br /&gt;
  when 0x15 # Timekeeping&lt;br /&gt;
  when 0x16 # Holiday&lt;br /&gt;
  end&lt;br /&gt;
  return @templid&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def processDeviceInfo(param)&lt;br /&gt;
  ### temporary&lt;br /&gt;
  ### 12-24-07 Adding Device Template compatibility..&lt;br /&gt;
  #have to find MY address&lt;br /&gt;
  insHb = param[&#039;Parameter3&#039;] # From&lt;br /&gt;
  insMb = param[&#039;Parameter4&#039;]&lt;br /&gt;
  insLb = param[&#039;Parameter5&#039;]&lt;br /&gt;
&lt;br /&gt;
  insID = padhex(insHb) + &amp;quot;.&amp;quot; + padhex(insMb) + &amp;quot;.&amp;quot; + padhex(insLb)&lt;br /&gt;
  #set the devicecat and device subcat in the childdatabases&lt;br /&gt;
  # 0-1 Device Category&lt;br /&gt;
  # 2-3 Device SubCategory&lt;br /&gt;
  # 4-5 Device Firmware&lt;br /&gt;
  log(&#039;proccessDeviceInfo:Insteon ID&#039; + insID)&lt;br /&gt;
  $childdatabases[insID][0][0..1] = param[&#039;Parameter6&#039;]&lt;br /&gt;
  $childdatabases[insID][0][2..3] = param[&#039;Parameter7&#039;]&lt;br /&gt;
  $childdatabases[insID][0][4..5] = param[&#039;Parameter8&#039;]&lt;br /&gt;
  savechilddatabases(insID)&lt;br /&gt;
  log(&#039;InsteonID: &#039; + insID)&lt;br /&gt;
  #log(&#039;Child Config AFTER update:&#039; + $childdatabases[insID][0].to_s)&lt;br /&gt;
  log($yellow)&lt;br /&gt;
  @template = getdevicetemplate(param[&#039;Parameter6&#039;], param[&#039;Parameter7&#039;])&lt;br /&gt;
  $devicetemplate[insID] = @template&lt;br /&gt;
  log(&#039;Template ID:&#039; + @template.to_s)&lt;br /&gt;
  ### eventually, open a XML configuration script?&lt;br /&gt;
  ### or read saved data from mysql?&lt;br /&gt;
  ### most likely save this information to sql with device.&lt;br /&gt;
  ### eventually, IPKDB will be available to ping.&lt;br /&gt;
  log(&#039;for Insteon ID:&#039; + insID)&lt;br /&gt;
  log($grey)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def recvComplete&lt;br /&gt;
  # Clears the wait flag, but does not remove a command from the queue&lt;br /&gt;
  $wAIT = false&lt;br /&gt;
  log($green + &amp;quot;Receive Completed. Checking command queue&amp;quot; + $grey)&lt;br /&gt;
  if $cmdqueue.nitems &amp;gt; 0 then&lt;br /&gt;
    log(&amp;quot;Queue:&amp;quot; + $aqua + $cmdqueue.nitems.to_s + $grey + &amp;quot; : executing next command&amp;quot;)&lt;br /&gt;
    SndIns()&lt;br /&gt;
  else&lt;br /&gt;
    log($yellow + &#039;Queue Empty.&#039; + $grey)&lt;br /&gt;
    if $rerun&lt;br /&gt;
      log(&#039;RERUN=TRUE, RESTARTING&#039;)&lt;br /&gt;
      $rerun = false&lt;br /&gt;
      mainRestart()&lt;br /&gt;
    else&lt;br /&gt;
      log(&#039;RERUN Not needed. Checking if reported..&#039;)&lt;br /&gt;
      #report Child devices here.&lt;br /&gt;
      if not $reported&lt;br /&gt;
        log(&#039;Reporting Child Devices&#039;)&lt;br /&gt;
        @work = &amp;quot;&amp;quot;&lt;br /&gt;
        $childdatabases.each{&lt;br /&gt;
          |insteonID,value|&lt;br /&gt;
          log(&#039;Child:&#039; + insteonID)&lt;br /&gt;
          log(&#039;Config:&#039; + value.inspect)&lt;br /&gt;
          @template = $devicetemplate[insteonID]&lt;br /&gt;
          @work += insteonID + &amp;quot;\t\t\t&amp;quot; + @template.to_s + &amp;quot;\t\n&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
        log(@work)&lt;br /&gt;
        cmd = Command.new(device_.devid_, -1001, 1, 2, 54)&lt;br /&gt;
        cmd.params_[13] = @work&lt;br /&gt;
        SendCommand(cmd)&lt;br /&gt;
&lt;br /&gt;
        $reported = true&lt;br /&gt;
      else&lt;br /&gt;
        log(&#039;report not needed&#039;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
def removecurrentcommand&lt;br /&gt;
  #get the current child&lt;br /&gt;
  log(&#039;in RemoveCurrentCommand&#039;)&lt;br /&gt;
  log(&#039;Current Command:&#039; + $cmdqueue[0].inspect)&lt;br /&gt;
  #id is in param123&lt;br /&gt;
  @id = $cmdqueue[0][&#039;Parameter1&#039;]&lt;br /&gt;
  @id += &#039;.&#039; + $cmdqueue[0][&#039;Parameter2&#039;]&lt;br /&gt;
  @id += &#039;.&#039; + $cmdqueue[0][&#039;Parameter3&#039;]&lt;br /&gt;
  log(&#039;ID=&#039; + @id)&lt;br /&gt;
  #now to remove from child and PLM databases&lt;br /&gt;
  removefromchild(@id)&lt;br /&gt;
  removefromplm(@id)&lt;br /&gt;
  cmdComplete&lt;br /&gt;
end&lt;br /&gt;
def cmdComplete&lt;br /&gt;
  # Clears the wait flag, and removes the command from the queue.&lt;br /&gt;
  $wAIT = false&lt;br /&gt;
  $resetNext = 0&lt;br /&gt;
  $cmdqueue.delete_at(0)&lt;br /&gt;
  # now that THAT command is completed, check to see if there is&lt;br /&gt;
  # another command ready to transmit.&lt;br /&gt;
  log($green + &amp;quot;Command Completed.&amp;quot; + $grey)&lt;br /&gt;
end&lt;br /&gt;
def checkWait(param)&lt;br /&gt;
  #Checks for response from current command.&lt;br /&gt;
  if $cmdqueue[0] != nil&lt;br /&gt;
    if $wAIT == true&lt;br /&gt;
      #log(&#039;CW:waiting for command to complete&#039;)&lt;br /&gt;
    else&lt;br /&gt;
      #log(&#039;CW:reports clear&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    log(&#039;------:)----checkWait: command queue is emtpy&#039;)&lt;br /&gt;
    if $wAIT == true #this should never happen&lt;br /&gt;
      log(&#039;------:(XXX-CheckWait: TRUE&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def plmparse(value)&lt;br /&gt;
  #THIS ROUTINE REPLACES parsestring()&lt;br /&gt;
  #this routine will PARSE the incoming stream into valid messages&lt;br /&gt;
  # value is the complete command&lt;br /&gt;
  param = {}&lt;br /&gt;
  #here is a special case, the PLM seems to lock up.&lt;br /&gt;
  if value == 0x15.chr&lt;br /&gt;
    log(&#039;The PLM stopped responding&#039;)&lt;br /&gt;
    log(&#039;Please unplug it, and plug it back in&#039;)&lt;br /&gt;
    log(&#039;and do a quick reload router.&#039;)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
  while value.length &amp;gt; 2&lt;br /&gt;
    case value[1]&lt;br /&gt;
    when 0x62 # Special case, need to look at flags&lt;br /&gt;
      if (value[5] &amp;amp; 0x10) == 0x10 # check for extended flag&lt;br /&gt;
        cmdlen = 23&lt;br /&gt;
      else&lt;br /&gt;
        cmdlen = 9&lt;br /&gt;
      end&lt;br /&gt;
      param[&#039;Response&#039;] = &#039;SndIns&#039;&lt;br /&gt;
    when 0x50; cmdlen = 11; param[&#039;Response&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
    when 0x51; cmdlen = 25; param[&#039;Response&#039;] = &#039;InsExtMsg&#039;&lt;br /&gt;
    when 0x68; cmdlen = 4 #Set Insteon ACK Message Byte&lt;br /&gt;
    when 0x71; cmdlen = 5 #Set Insteon ACK Message Two Bytes&lt;br /&gt;
    when 0x70; cmdlen = 4 #Set Insteon NACK Message Byte&lt;br /&gt;
    when 0x63; cmdlen = 5; param[&#039;Response&#039;] = &#039;SndX10&#039;&lt;br /&gt;
    when 0x52; cmdlen = 4; param[&#039;Response&#039;] = &#039;X10Msg&#039;&lt;br /&gt;
    when 0x61; cmdlen = 6; param[&#039;Response&#039;] = &#039;SndGrp&#039;&lt;br /&gt;
    when 0x56; cmdlen = 7; param[&#039;Response&#039;] = &#039;GrpEvntRpt&#039;&lt;br /&gt;
    when 0x58; cmdlen = 3 #All-Link Cleanup Status Report&lt;br /&gt;
    when 0x64; cmdlen = 5; param[&#039;Response&#039;] = &#039;StLnk&#039;&lt;br /&gt;
    when 0x65; cmdlen = 3; param[&#039;Response&#039;] = &#039;CancelLnk&#039;&lt;br /&gt;
    when 0x53; cmdlen = 10; param[&#039;Response&#039;] = &#039;InsLnkSts&#039;&lt;br /&gt;
    when 0x69; cmdlen = 3; param[&#039;Response&#039;] = &#039;GetLnk&#039;&lt;br /&gt;
    when 0x6A; cmdlen = 3; param[&#039;Response&#039;] = &#039;GetNext&#039;&lt;br /&gt;
    when 0x6C; cmdlen = 3 #Get All-Link Record for Sender&lt;br /&gt;
    when 0x57; cmdlen = 10; param[&#039;Response&#039;] = &#039;LnkData&#039;&lt;br /&gt;
    when 0x6F; cmdlen = 12; param[&#039;Response&#039;] = &#039;MngLnk&#039;&lt;br /&gt;
    when 0x67; cmdlen = 3; param[&#039;Response&#039;] = &#039;RstPLM&#039;&lt;br /&gt;
    when 0x6B; cmdlen = 4; param[&#039;Response&#039;] = &#039;SetCfg&#039;&lt;br /&gt;
    when 0x60; cmdlen = 9; param[&#039;Response&#039;] = &#039;GetVersion&#039;&lt;br /&gt;
    when 0x66; cmdlen = 6 #Set Host Device Category&lt;br /&gt;
    when 0x72; cmdlen = 3 # RF Sleep&lt;br /&gt;
    when 0x54; cmdlen = 3; param[&#039;Response&#039;] = &#039;BtnRpt&#039;&lt;br /&gt;
    when 0x6D; cmdlen = 3; param[&#039;Response&#039;] = &#039;LEDON&#039;&lt;br /&gt;
    when 0x6E; cmdlen = 3; param[&#039;Response&#039;] = &#039;LEDOFF&#039;&lt;br /&gt;
    else&lt;br /&gt;
&lt;br /&gt;
      log(&#039;ERROR IN PLMPARSE- Unknown Command&#039;)&lt;br /&gt;
      debug(value)&lt;br /&gt;
&lt;br /&gt;
      return &#039;&#039;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    #Now we know the length the command should be, see if we have it.&lt;br /&gt;
    #log(&#039;waiting for &#039; + cmdlen.to_s + &#039; characters...&#039;)&lt;br /&gt;
    #log(&#039;length of current input is &#039; + value.length.to_s)&lt;br /&gt;
    if value.length &amp;gt;= cmdlen&lt;br /&gt;
      #log(&#039;GOT whole response&#039;)&lt;br /&gt;
      #Yes, we have the whole command, Pack it in param&lt;br /&gt;
      for byt in 1..cmdlen&lt;br /&gt;
        param[&#039;Parameter&#039; + byt.to_s] = &amp;quot;%02X&amp;quot; %value[byt - 1]&lt;br /&gt;
      end&lt;br /&gt;
      #now remove it from the string..&lt;br /&gt;
      value = value.slice(cmdlen, value.length - cmdlen)&lt;br /&gt;
      #Send it off for parsing&lt;br /&gt;
      #log(&#039;Sending to EZToDCE:&#039; + param.inspect.to_s)&lt;br /&gt;
      EZToDCE(param)&lt;br /&gt;
    else&lt;br /&gt;
      #log(&#039;Still waiting...&#039;)&lt;br /&gt;
      #no, we have NOT received the whole command.&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  return value&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def rawX10(value)&lt;br /&gt;
&lt;br /&gt;
  x10MSN = $X10HouseCodes.index[value[0..0]]&lt;br /&gt;
  x10LSN = $X10UnitCodes.index[value[1..1]]&lt;br /&gt;
  return x10MSN + x10LSN&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def X10Flag(value)&lt;br /&gt;
  return + $X10CommandCodes.index[Value] + &#039;0&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def SndIns&lt;br /&gt;
  # create a new PLM command for SndIns&lt;br /&gt;
  if not $wAIT&lt;br /&gt;
    #log(&#039;SndIns:currentcmd=&#039; + $currentcmd.to_s)&lt;br /&gt;
&lt;br /&gt;
    if $cmdqueue.nitems &amp;gt; 0&lt;br /&gt;
      log(&amp;quot;SndIns:Queue:&amp;quot; + $aqua + $cmdqueue.nitems.to_s + $grey)&lt;br /&gt;
      #log(&#039;SndIns:&#039; + $cmdqueue.inspect)&lt;br /&gt;
      param = $cmdqueue[0]&lt;br /&gt;
      ### have to figure out the command byte 2 here&lt;br /&gt;
      work = &#039;02&#039;.hex.chr + plmcommand(param)&lt;br /&gt;
      ### PLM command compilation&lt;br /&gt;
      for loop in 2..param.keys.nitems&lt;br /&gt;
        @dummy = param[&#039;Parameter&#039; + (loop - 1).to_s].to_s&lt;br /&gt;
        work+= @dummy.hex.chr&lt;br /&gt;
      end&lt;br /&gt;
      conn_.Reconnect()&lt;br /&gt;
      debugout(work)&lt;br /&gt;
      conn_.Send(work)&lt;br /&gt;
      #sleep 0.1&lt;br /&gt;
      $wAIT = TRUE&lt;br /&gt;
    else&lt;br /&gt;
      log($yellow + &#039;Queue Empty.&#039; + $grey)&lt;br /&gt;
      if $rerun&lt;br /&gt;
        log(&#039;RERUN=TRUE, RESTARTING&#039;)&lt;br /&gt;
        $rerun = false&lt;br /&gt;
        mainRestart()&lt;br /&gt;
      else&lt;br /&gt;
        log(&#039;RERUN Not needed&#039;)&lt;br /&gt;
        if not $reported&lt;br /&gt;
          log(&#039;Reporting Child Devices&#039;)&lt;br /&gt;
          @work = &amp;quot;&amp;quot;&lt;br /&gt;
          $childdatabases.each{&lt;br /&gt;
            |insteonID,value|&lt;br /&gt;
            log(&#039;Child:&#039; + insteonID)&lt;br /&gt;
            log(&#039;Config:&#039; + value.inspect)&lt;br /&gt;
            @template = $devicetemplate[insteonID]&lt;br /&gt;
            @work += insteonID + &amp;quot;\t\t\t&amp;quot; + @template.to_s + &amp;quot;\t\n&amp;quot;&lt;br /&gt;
          }&lt;br /&gt;
          log(@work)&lt;br /&gt;
          cmd = Command.new(device_.devid_, -1001, 1, 2, 54)&lt;br /&gt;
          cmd.params_[13] = @work&lt;br /&gt;
          SendCommand(cmd)&lt;br /&gt;
&lt;br /&gt;
          $reported = true&lt;br /&gt;
        else&lt;br /&gt;
          log(&#039;report not needed&#039;)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    log(&#039;X-----------SndIns: Waiting for response to:&#039; + $cmdqueue[0][&#039;Command&#039;].to_s)&lt;br /&gt;
    log(&#039;X-----------SndIns: Current Queue Length:&#039; + $cmdqueue.nitems.to_s)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
def plmcommand(param)&lt;br /&gt;
  ### this returns the proper Byte2 for the command.&lt;br /&gt;
  case param[&#039;Command&#039;]&lt;br /&gt;
  when &#039;GetVersion&#039;; return 0x60.chr&lt;br /&gt;
  when &#039;SndIns&#039;; return 0x62.chr&lt;br /&gt;
  when &#039;SndGrp&#039;; return 0x61.chr&lt;br /&gt;
  when &#039;SndX10&#039;; return 0x63.chr&lt;br /&gt;
  when &#039;GetLnk&#039;; return 0x69.chr&lt;br /&gt;
  when &#039;GetNext&#039;; return 0x6A.chr&lt;br /&gt;
  when &#039;BtnRpt&#039;; return 0x54.chr&lt;br /&gt;
  when &#039;GetCfg&#039;; return 0x73.chr&lt;br /&gt;
  when &#039;StLnk&#039;; return 0x64.chr&lt;br /&gt;
  when &#039;CancelLnk&#039;; return 0x65.chr&lt;br /&gt;
  when &#039;MngLnk&#039;; return 0x6F.chr&lt;br /&gt;
  when &#039;RstPLM&#039;; return 0x67.chr&lt;br /&gt;
  when &#039;SetCfg&#039;; return 0x6B.chr&lt;br /&gt;
  when &#039;LEDON&#039;; return 0x6D.chr&lt;br /&gt;
  when &#039;LEDOFF&#039;; return 0x6E.chr&lt;br /&gt;
    ## hack&lt;br /&gt;
  when &#039;InsStdMsg&#039;&lt;br /&gt;
    log(&#039;ERROR:PLMCommand encountered a COMMAND of INSSTDMSG&#039;)&lt;br /&gt;
    break&lt;br /&gt;
    return 0x62.chr&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def debug(text)&lt;br /&gt;
  work = &#039;DEBUG:&#039;&lt;br /&gt;
&lt;br /&gt;
  for c in 1..text.length&lt;br /&gt;
    work += &amp;quot;%02X&amp;quot; %text[c-1] + &#039; &#039;&lt;br /&gt;
  end&lt;br /&gt;
  log($yellow + work + &amp;quot;Length:&amp;quot; + text.length.to_s + $grey)&lt;br /&gt;
end&lt;br /&gt;
def debugout(text)&lt;br /&gt;
  work = &#039;out:&#039;&lt;br /&gt;
&lt;br /&gt;
  for c in 1..text.length&lt;br /&gt;
    work += &amp;quot;%02X&amp;quot; %text[c-1] + &#039; &#039;&lt;br /&gt;
  end&lt;br /&gt;
  log($green + work + &amp;quot;Length:&amp;quot; + text.length.to_s + $grey)&lt;br /&gt;
end&lt;br /&gt;
def debugin(text)&lt;br /&gt;
  work = &#039;IN:&#039;&lt;br /&gt;
&lt;br /&gt;
  for c in 1..text.length&lt;br /&gt;
    work += &amp;quot;%02X&amp;quot; %text[c-1] + &#039; &#039;&lt;br /&gt;
  end&lt;br /&gt;
  log($red + work + &amp;quot;Length:&amp;quot; + text.length.to_s + $grey)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def padhex(hex)&lt;br /&gt;
  if hex.length==1&lt;br /&gt;
    hex = &amp;quot;0&amp;quot; + hex&lt;br /&gt;
  end&lt;br /&gt;
  return hex&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def percenttohex(level)&lt;br /&gt;
  # convert from percent to byte&lt;br /&gt;
  return &amp;quot;%X&amp;quot; %(level.to_i * 2.55).to_i&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def hextopercent(level)&lt;br /&gt;
  return (level.hex.to_i / 2.55).to_i&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def log(line)&lt;br /&gt;
  $log = File.open(&amp;quot;/var/log/pluto/&amp;quot; + device_.devid_.to_s + &amp;quot;_Generic_Serial_Device.log&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
  $log.puts &amp;quot;(***):&amp;quot; + line.to_s&lt;br /&gt;
  $log.close&lt;br /&gt;
end&lt;br /&gt;
def log2(line)&lt;br /&gt;
  #this will send a message out the the orbiters..&lt;br /&gt;
  #/usr/pluto/bin/MessageSend localhost 0 20 1 809 9 &amp;quot;Text to Display&amp;quot; 70 &amp;quot;alert&amp;quot; 182 &amp;quot;30&amp;quot; 251 &amp;quot;??&amp;quot;&lt;br /&gt;
  cmd = Command.new(device_.devid_, -1000, 1, 1, 809)&lt;br /&gt;
  cmd.params_[9] = line #text to display&lt;br /&gt;
  cmd.params_[70] = &#039;PLMMessage&#039; #Token&lt;br /&gt;
  cmd.params_[182] = &#039;10&#039; #Timeout in seconds&lt;br /&gt;
  cmd.params_[251] = &#039;??&#039;&lt;br /&gt;
  SendCommand(cmd)&lt;br /&gt;
end&lt;br /&gt;
def checkChildRecordsinPLM()&lt;br /&gt;
  log(&#039;Entered CheckChildRecordsinPLM&#039;)&lt;br /&gt;
  # log(&#039;In CheckChildRecordsinPLM&#039;)&lt;br /&gt;
  # time to verify all children are in the PLM&lt;br /&gt;
  #&lt;br /&gt;
  # log(&#039;Total PLM Records:&#039; + $plmdatabase.nitems.to_s)&lt;br /&gt;
  $plmdatabase.each{|record|&lt;br /&gt;
    log(&#039;Record: = &#039;+ getIIDfromRecord(record) + &#039; Group:&#039; + getGroupfromRecord(record))&lt;br /&gt;
    log(&#039;checking to see if it needs to be added as a child...&#039;)&lt;br /&gt;
    if not existsinchild(getIIDfromRecord(record))&lt;br /&gt;
        &lt;br /&gt;
      log(getIIDfromRecord(record) + &#039; needs to be added to the child database&#039;)&lt;br /&gt;
      addtochild(getIIDfromRecord(record))&lt;br /&gt;
    end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  $childdatabases.each {|child,value|&lt;br /&gt;
    if not existsinplm(child)&lt;br /&gt;
      log(child + &#039; needs to be added to PLM&#039;)&lt;br /&gt;
      sendAddtoPLM(child)&lt;br /&gt;
    else&lt;br /&gt;
      log(child + &#039; exists in PLM&#039;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    #now to scan the childs database&lt;br /&gt;
    for record in 1..(value.nitems - 1)&lt;br /&gt;
      @test = value[record]&lt;br /&gt;
      if not existsinplm(getIIDfromRecord(@test))&lt;br /&gt;
        log(getIIDfromRecord(@test) + &#039; needs to be added to PLM&#039;)&lt;br /&gt;
        sendAddtoPLM(getIIDfromRecord(@test))&lt;br /&gt;
      else&lt;br /&gt;
        log(getIIDfromRecord(@test) + &#039; exists in PLM&#039;)&lt;br /&gt;
      end&lt;br /&gt;
      #Also check to see if it needs to be added in the childdatabases&lt;br /&gt;
    end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
def existsinplm(insteonid)&lt;br /&gt;
  result = false&lt;br /&gt;
  $plmdatabase.each{|record|&lt;br /&gt;
    #log(insteonid + &#039;==&#039; + getIIDfromRecord(record))&lt;br /&gt;
    if insteonid == getIIDfromRecord(record)&lt;br /&gt;
      result = true&lt;br /&gt;
    end&lt;br /&gt;
  }&lt;br /&gt;
  return result&lt;br /&gt;
end&lt;br /&gt;
def existsinchild(insteonid)&lt;br /&gt;
  log(&#039;ExistsinChild:InsteonID:&#039; + insteonid)&lt;br /&gt;
  result = $childdatabases.keys.include?(insteonid)&lt;br /&gt;
  log(&#039;ExistsinChild result:FALSE&#039;) if not result&lt;br /&gt;
  log(&#039;ExistsinChild result:TRUE&#039;) if result&lt;br /&gt;
  return result&lt;br /&gt;
end&lt;br /&gt;
def addtochild(insteonID)&lt;br /&gt;
  log(&#039;addtochild Routne called&#039;)&lt;br /&gt;
  log(&#039;Adding &#039; + insteonID + &#039; to the child database...&#039;)&lt;br /&gt;
  if insteonID.length == 2 then&lt;br /&gt;
    log(&#039;Child is X10&#039;)&lt;br /&gt;
    $state[insteonID] = 0&lt;br /&gt;
  else&lt;br /&gt;
    log(&#039;Child is Insteon&#039;)&lt;br /&gt;
    $childdatabases[insteonID] = [&#039;****************&#039;]&lt;br /&gt;
    sendPing(insteonID)&lt;br /&gt;
    $rerun = true&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
def removefromchild(insteonID)&lt;br /&gt;
  log(&#039;Removing &#039; + insteonID + &#039; from child database&#039;)&lt;br /&gt;
  $childdatabases.delete(insteonID)&lt;br /&gt;
  $state.delete(insteonID)&lt;br /&gt;
end&lt;br /&gt;
def removefromplm(insteonID)&lt;br /&gt;
  log(&#039;Removing from plm&#039;)&lt;br /&gt;
  $plmdatabase.each{|record|&lt;br /&gt;
    #log(insteonid + &#039;==&#039; + getIIDfromRecord(record))&lt;br /&gt;
    if insteonID == getIIDfromRecord(record)&lt;br /&gt;
      debug(record)&lt;br /&gt;
      log(&#039;Found Record, Deleting&#039;)&lt;br /&gt;
      $plmdatabase.delete(record)&lt;br /&gt;
      &lt;br /&gt;
      #now, we have to remove it from the device.&lt;br /&gt;
      param = {&#039;Command&#039; =&amp;gt;&#039;MngLnk&#039;,&lt;br /&gt;
        &#039;Parameter1&#039; =&amp;gt; &#039;80&#039;, #DELETE&lt;br /&gt;
        &#039;Parameter2&#039; =&amp;gt; record[0..1], #control byte&lt;br /&gt;
        &#039;Parameter3&#039; =&amp;gt; record[2..3], #group&lt;br /&gt;
        &#039;Parameter4&#039; =&amp;gt; record[4..5],#HB&lt;br /&gt;
        &#039;Parameter5&#039; =&amp;gt; record[6..7],#MB&lt;br /&gt;
        &#039;Parameter6&#039; =&amp;gt; record[8..9],#LB&lt;br /&gt;
        &#039;Parameter7&#039; =&amp;gt; record[10..11],#data1&lt;br /&gt;
        &#039;Parameter8&#039; =&amp;gt; record[12..13],#data2&lt;br /&gt;
        &#039;Parameter9&#039; =&amp;gt; record[14..15] #data3&lt;br /&gt;
        &lt;br /&gt;
      }&lt;br /&gt;
      log(param.inspect)&lt;br /&gt;
      $cmdqueue &amp;lt;&amp;lt; param&lt;br /&gt;
    end&lt;br /&gt;
  }&lt;br /&gt;
end&lt;br /&gt;
def sendAddtoPLM(insteonID)&lt;br /&gt;
  log(&#039;Adding &#039; + insteonID + &#039; to the PLM database...&#039;)&lt;br /&gt;
  #This adds a record into the PLM&lt;br /&gt;
  @insID = insteonID.split(&#039;.&#039;)&lt;br /&gt;
  param = {&#039;Command&#039; =&amp;gt; &#039;MngLnk&#039;,&lt;br /&gt;
    &#039;Parameter1&#039; =&amp;gt; &#039;40&#039;, #control code -- add new record as Controller&lt;br /&gt;
    &#039;Parameter2&#039; =&amp;gt; &#039;C2&#039;, #All Link Record Flags AKA Record Control Byte&lt;br /&gt;
    &#039;Parameter3&#039; =&amp;gt; &#039;01&#039;, #All Link Group&lt;br /&gt;
    &#039;Parameter4&#039; =&amp;gt; @insID[0], #HB&lt;br /&gt;
    &#039;Parameter5&#039; =&amp;gt; @insID[1], #MB&lt;br /&gt;
    &#039;Parameter6&#039; =&amp;gt; @insID[2], #LB&lt;br /&gt;
    &#039;Parameter7&#039; =&amp;gt; &#039;01&#039;, #Link Data 1 ON-Level&lt;br /&gt;
    &#039;Parameter8&#039; =&amp;gt; &#039;01&#039;, #Link Data 2 Ramp Rate&lt;br /&gt;
    &#039;Parameter9&#039; =&amp;gt; &#039;FF&#039;} #Link Data 3 not used&lt;br /&gt;
  if $wAIT&lt;br /&gt;
    $cmdqueue.insert(1, param)&lt;br /&gt;
  else&lt;br /&gt;
    $cmdqueue.insert(0, param)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  SndIns()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def getIIDfromRecord(recordstring)&lt;br /&gt;
  #this extracts the insteonID string from the record.&lt;br /&gt;
  #log(&#039;getIIDfromRecord::recordstring:&#039; + recordstring)&lt;br /&gt;
  @idhb = recordstring[4..5]&lt;br /&gt;
  @idmb = recordstring[6..7]&lt;br /&gt;
  @idlb = recordstring[8..9]&lt;br /&gt;
  @result = @idhb + &#039;.&#039; + @idmb + &#039;.&#039; +@idlb&lt;br /&gt;
  #log(&#039;GetIIDfromRecord: Found ID:&#039; + @result)&lt;br /&gt;
  return @result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def processBroadcastMessage(param)&lt;br /&gt;
  #search the child databases for responders,&lt;br /&gt;
  #and fire COMMANDS for each responder. 06Feb08&lt;br /&gt;
  #and fire events for each responder.XXXXXXXXXXXXX&lt;br /&gt;
  #Message flag is in parameter9 Group command 0xCx (All-Link Broadcast Message Pg 42.)&lt;br /&gt;
  #Group is in parameter8&lt;br /&gt;
  #From InsteonID is parameters 3, 4, 5&lt;br /&gt;
  group = param[&#039;Parameter8&#039;]&lt;br /&gt;
  from = padhex(param[&#039;Parameter3&#039;]) + &#039;.&#039;&lt;br /&gt;
  from += padhex(param[&#039;Parameter4&#039;]) + &#039;.&#039;&lt;br /&gt;
  from += padhex(param[&#039;Parameter5&#039;])&lt;br /&gt;
  log(&#039;Looking for &#039; + from + &#039; Group:&#039; + group)&lt;br /&gt;
  #Ok, now have to search child databases for from AND group AND responder&lt;br /&gt;
  $childdatabases.each{|child,value|&lt;br /&gt;
    #log(&#039;Searching:&#039; + child)&lt;br /&gt;
    for rec in 1..(value.nitems - 1)&lt;br /&gt;
      record = value[rec]&lt;br /&gt;
      if getIIDfromRecord(record) == from # First, look for Insteon ID&lt;br /&gt;
        #log(&#039;Found ID&#039;)&lt;br /&gt;
        if getGroupfromRecord(record) == group #next, Group&lt;br /&gt;
          #log(&#039;Found Group&#039;)&lt;br /&gt;
          if isResponderRecord(record) # is a responder?&lt;br /&gt;
            #log(&#039;Found Responder&#039;)&lt;br /&gt;
            #figure out the child devicenum&lt;br /&gt;
            from = $children[child]&lt;br /&gt;
            #figure out the command&lt;br /&gt;
            case param[&#039;Parameter10&#039;].hex&lt;br /&gt;
            when 0x11 #on&lt;br /&gt;
              reportStatus(from, 100)&lt;br /&gt;
            when 0x13 #off&lt;br /&gt;
              reportStatus(from, 0)&lt;br /&gt;
            when 0x17 #dim/brighten -ignore&lt;br /&gt;
              level = 0&lt;br /&gt;
            when 0x18 # STOP dim/brighten - sendgetstatus&lt;br /&gt;
              level = 0&lt;br /&gt;
              sendGetChildStatus(child)&lt;br /&gt;
            else&lt;br /&gt;
              level = 0&lt;br /&gt;
              log(&#039;Command is other than ON/OFF/Dim/Brighten&#039;)&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  }&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def reportStatus(from, level)&lt;br /&gt;
  log(&#039;From:&#039; + from.to_s)&lt;br /&gt;
  log(&#039;current State:&#039; + $state[from].to_s)&lt;br /&gt;
  log(&#039;Wanted State:&#039; + level.to_s)&lt;br /&gt;
  case $state[from]&lt;br /&gt;
  when 0&lt;br /&gt;
    if level &amp;gt;=1&lt;br /&gt;
      cmd = Command.new(from, from, 1, 1, 192) #on&lt;br /&gt;
      cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
      SendCommand(cmd)&lt;br /&gt;
      cmd = Command.new(from, from, 1, 1, 184)&lt;br /&gt;
      cmd.params_[76] = level.to_s&lt;br /&gt;
      cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
      SendCommand(cmd)&lt;br /&gt;
    end&lt;br /&gt;
  when 100&lt;br /&gt;
    if level &amp;gt;= 1&lt;br /&gt;
      cmd = Command.new(from, from, 1, 1, 184)&lt;br /&gt;
      cmd.params_[76] = level.to_s&lt;br /&gt;
      cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
      SendCommand(cmd)&lt;br /&gt;
    else&lt;br /&gt;
      cmd = Command.new(from, from, 1, 1, 193) # off&lt;br /&gt;
      cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
      SendCommand(cmd)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if level == 100&lt;br /&gt;
      cmd = Command.new(from, from, 1, 1, 193) #off&lt;br /&gt;
      cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
      SendCommand(cmd)&lt;br /&gt;
      cmd = Command.new(from, from, 1, 1, 192) # on&lt;br /&gt;
      cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
      SendCommand(cmd)&lt;br /&gt;
    end&lt;br /&gt;
    cmd = Command.new(from, from, 1, 1, 184) #SetLevel&lt;br /&gt;
    cmd.params_[76] = level.to_s&lt;br /&gt;
    cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
    SendCommand(cmd)&lt;br /&gt;
  end&lt;br /&gt;
  log(&#039;ReportStatus: device:&#039; + from.to_s + &#039; Status:&#039; + level.to_s)&lt;br /&gt;
  $state[from] = level&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def isResponderRecord(recordstring)&lt;br /&gt;
  work = recordstring[0..1].hex&lt;br /&gt;
  if (work &amp;amp; 0x40) == 0x40 #check bit 6&lt;br /&gt;
    result = false #signifies Controller record&lt;br /&gt;
  else&lt;br /&gt;
    result = true #signifies Responder record&lt;br /&gt;
  end&lt;br /&gt;
  return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def getGroupfromRecord(recordstring)&lt;br /&gt;
  #this extracts the GROUP from the record.&lt;br /&gt;
  if recordstring == nil&lt;br /&gt;
    return &#039;00&#039;&lt;br /&gt;
  else&lt;br /&gt;
    return recordstring[2..3]&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
def getdeltafromconfig(insteonID)&lt;br /&gt;
  #This returns the delta from the child.&lt;br /&gt;
  @work = $childdatabases[insteonID][0] # the settings stored in [0]&lt;br /&gt;
  if @work == nil&lt;br /&gt;
    return &#039;00&#039;&lt;br /&gt;
  else&lt;br /&gt;
    return @work[6..7]&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
def sendGetChildStatus(insteonID)&lt;br /&gt;
  #log(&#039;sendGetChildStatus Called&#039;)&lt;br /&gt;
  if insteonID.length != 2 #X10 device&lt;br /&gt;
    @insID = insteonID.split(&#039;.&#039;)&lt;br /&gt;
    param = {&#039;Command&#039; =&amp;gt; &#039;SndIns&#039;,&lt;br /&gt;
      &#039;Parameter1&#039; =&amp;gt; @insID[0],&lt;br /&gt;
      &#039;Parameter2&#039; =&amp;gt; @insID[1],&lt;br /&gt;
      &#039;Parameter3&#039; =&amp;gt; @insID[2],&lt;br /&gt;
      &#039;Parameter4&#039; =&amp;gt; &#039;0F&#039;, #flags&lt;br /&gt;
      &#039;Parameter5&#039; =&amp;gt; &#039;19&#039;, #Status Request&lt;br /&gt;
      &#039;Parameter6&#039; =&amp;gt; &#039;00&#039;} #not used.&lt;br /&gt;
    $cmdqueue &amp;lt;&amp;lt; param&lt;br /&gt;
    SndIns()&lt;br /&gt;
    #Returned response will have cmd1 = DBDelta&lt;br /&gt;
    #Returned response will have cmd2 = ON-Level&lt;br /&gt;
  else&lt;br /&gt;
    log(&#039;X10 does not report status&#039;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# time to define a structure to save the raw data in hex&lt;br /&gt;
# starts at [0]&lt;br /&gt;
# Bytes Meaning&lt;br /&gt;
# 0-1 Device Category&lt;br /&gt;
# 2-3 Device SubCategory&lt;br /&gt;
# 4-5 Device Firmware&lt;br /&gt;
# 6-7 Database Delta&lt;br /&gt;
# 8-9 reserved&lt;br /&gt;
# 10-11 reserved&lt;br /&gt;
# 12-13 reserved&lt;br /&gt;
# 14-15 reserved&lt;br /&gt;
###### First database record below (in same format its read from the device)&lt;br /&gt;
###### This is the same format as an ALL-Link Record Response from the PLM&lt;br /&gt;
###### (0x57) bytes 3..10&lt;br /&gt;
# 16-17 record control byte&lt;br /&gt;
# 18-19 Group&lt;br /&gt;
# 20-21 ID HB&lt;br /&gt;
# 22-23 ID MB&lt;br /&gt;
# 24-25 ID LB&lt;br /&gt;
# 26-27 Link Specific Data1&lt;br /&gt;
# 28-29 Link Specific Data2&lt;br /&gt;
# 30-31 Link Specific Data3&lt;br /&gt;
######&lt;br /&gt;
# 32-47 next database record...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Newacct</name></author>
	</entry>
	<entry>
		<id>http://wiki.linuxmce.org/index.php?title=LG_42LB5D&amp;diff=22224</id>
		<title>LG 42LB5D</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxmce.org/index.php?title=LG_42LB5D&amp;diff=22224"/>
		<updated>2010-02-02T09:56:45Z</updated>

		<summary type="html">&lt;p&gt;Newacct: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Video]]&lt;br /&gt;
[[Category: Displays]]&lt;br /&gt;
&lt;br /&gt;
 {| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
==Features==&lt;br /&gt;
===Basics===&lt;br /&gt;
* 42&amp;quot; (diagonal) [[16:9|widescreen]] [[LCD]] television&lt;br /&gt;
* Good build quality on the whole, though some edges on the plastic casing were left &amp;quot;sharp&amp;quot; (I&#039;m OCD about fit and finish)&lt;br /&gt;
* Not that heavy for its size (one person can lift it, in or out of packing carton)&lt;br /&gt;
Special features and nice touches:&lt;br /&gt;
* [[RS232 port]] at the back to allow external control (by LinuxMCE for example)&lt;br /&gt;
* Power LED is red on standby, and switches to green when set is on (thank goodness, blue-LED fever is abating! :-)&lt;br /&gt;
* Brightness can be instantly adjusted via two remote buttons -- the only thing better would be a photosensor that adjusts things automatically for ambient light (but that&#039;s what hacking is all about ;-)&lt;br /&gt;
===Picture fidelity===&lt;br /&gt;
* Crisp picture when provided with full quality source (e.g. true HD)&lt;br /&gt;
* Crisp picture with some ghosting when using the RGB-PC input with a standard (though longer than average) VGA video cable -- I will try to add a photo of the effect; the lowest-tech connections ([[S-Video]], RF, and the like) for PC video are NOT recommended!&lt;br /&gt;
* A touch blurry with low-end sources ([[S-Video]], RF) like older game systems, but still a fairly good overall picture; I have yet to test other signal methods with my game systems (requires special cables I don&#039;t yet have).&lt;br /&gt;
===Usability===&lt;br /&gt;
* The [[OSD]] UI and remote are excellent.  Both the menus and the buttons are laid out sensibly, and the system incorporates a great idea for settings that are cyclic (most are): the first time you press a button (e.g. [[aspect ratio]]), it brings up an [[OSD]] reminder of the current setting; subsequent presses will cycle through the available options.  It&#039;s simple, and effective at preventing accidental setting changes by a single inadvertent button press on the remote.&lt;br /&gt;
Resolutions:&lt;br /&gt;
* 1024x768&lt;br /&gt;
* 1280x768&lt;br /&gt;
* 1360x768&lt;br /&gt;
 &lt;br /&gt;
== Adding new template ==&lt;br /&gt;
Here is a description of adding a Template for LG LCD TV with serial connections for control.  According to the manual the following models should work:&lt;br /&gt;
LCD TV MODELS 37LB5D / 42LB5D / 47LB5D 52LB5D/ 32LB4D / 37LB4D / 42LB4D&lt;br /&gt;
I have the 42LB5D, so I know that this one works. &lt;br /&gt;
&lt;br /&gt;
=== Specify device data and parameters ===&lt;br /&gt;
&lt;br /&gt;
On the LinuxMCE admin website go to: Advanced &amp;gt; Configuration &amp;gt; Device Templates&lt;br /&gt;
&lt;br /&gt;
Select: Manufacturer &#039;LG&#039;, Device Category &#039;TVs/Plasmas/LCD&#039;s/Projectors&#039; and press &#039;Add device template&#039;&lt;br /&gt;
&lt;br /&gt;
 Description : XXLB4/5D&lt;br /&gt;
 Implements DCE : yes&lt;br /&gt;
 Command line : Generic_Serial_Device&lt;br /&gt;
 Device Category  AV TVs/Plasmas/Projection... #77&lt;br /&gt;
 Manufacturer LG&lt;br /&gt;
&lt;br /&gt;
Also have added following parameters (You need to add them one by one under the header &#039;Device data&#039;):&lt;br /&gt;
&lt;br /&gt;
 Device data&lt;br /&gt;
 Current Data 	                                    Comments 	                    Default Value&lt;br /&gt;
 #37 COM Port on PC(string) 	              The serial port 						&lt;br /&gt;
 #76 COM Port ParityBit/Stop(string) 	      Parity/Stop bits (factory defaults) 	N81 		&lt;br /&gt;
 #78 COM Port BaudRate(string)                Baud rate (factory default) 	        B9600 		&lt;br /&gt;
 #157 Discrete Volume(bool) 	              Indicates if the volume on...             1 &lt;br /&gt;
&lt;br /&gt;
Settings are factory defaults and shouldn&#039;t be changed (9600 baud rate, 8 bits, 1 stop bit).  Make sure that the check box for Allowed to Modify is checked, so that you can change to the appropriate COM port later.&lt;br /&gt;
&lt;br /&gt;
=== &#039;Edit Ruby code&#039; (on template page)  ===&lt;br /&gt;
&lt;br /&gt;
==== &#039;Add/remove commands&#039; ====&lt;br /&gt;
First, I clicked on &#039;Add/remove commands&#039; and clicked on commands that are supported by device...&lt;br /&gt;
&lt;br /&gt;
* Ruby Internal Commands&lt;br /&gt;
* Standard TV&lt;br /&gt;
&lt;br /&gt;
==== &#039;Add Ruby snippets to commands&#039;==== &lt;br /&gt;
Edited corresponding Ruby snippets for each command. Basically those are just simple strings that get send on rs232 to take proper action on device according to received command from LinuxMCE... Use the extended editor for the multiline entries (otherwise ruby won&#039;t understand it and gives lot&#039;s of errors)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#193 Off&lt;br /&gt;
	log(&#039;Sending OFF Command&#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;ka 01 00\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#192 On&lt;br /&gt;
	log(&#039;Sending ON Command&#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;ka 01 01\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
Inputs&lt;br /&gt;
#419 Antenna&lt;br /&gt;
		&lt;br /&gt;
#316 AV 1&lt;br /&gt;
	log(&#039;Switching Input to AV1&#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;kb 01 02\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#317 AV 2&lt;br /&gt;
	log(&#039;Switching Input to AV2&#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;kb 01 03\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#712 Component 1&lt;br /&gt;
	log(&#039;Switching Input to Component 1&#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;kb 01 04\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#713 Component 2&lt;br /&gt;
	log(&#039;Switching Input to Component 2&#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;kb 01 05\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#426 External 3&lt;br /&gt;
	log(&#039;Switching Input to HDMI 3&#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;kb 01 09\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#361 HDMI&lt;br /&gt;
	log(&#039;Switching Input to HDMI 1&#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;kb 01 07\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#767 HDMI 2&lt;br /&gt;
	log(&#039;Switching Input to HDMI 2&#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;kb 01 08\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#376 Input 3&lt;br /&gt;
	log(&#039;Switching Input to HDMI 3&#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;kb 01 09\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#154 RGB&lt;br /&gt;
	log(&#039;Switching Input to RGB/PC&#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;kb 01 06\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#166 Tuner&lt;br /&gt;
	log(&#039;Switching Input to Analog Tuner&#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;kb 01 01\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#873 Tuner - Digital&lt;br /&gt;
	log(&#039;Switching Input to Digital Tuner&#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;kb 01 00\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
Aspect Ratios&lt;br /&gt;
#879 16:9&lt;br /&gt;
	log(&#039;Switching Aspect Ratio to 16:9&#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;kc 01 02\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#877 4:3&lt;br /&gt;
	log(&#039;Switching Aspect Ratio to 4:3&#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;kc 01 01\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
Disk Handle&lt;br /&gt;
#48 Eject Disk&lt;br /&gt;
		&lt;br /&gt;
DSP Modes&lt;br /&gt;
#116 DSP Mode&lt;br /&gt;
	log(&#039;Switching DSP Modes: Toggled Only&#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 52\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
General&lt;br /&gt;
#190 Enter/Go&lt;br /&gt;
	log(&#039;Sending Enter/Go Command&#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 44\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
Internal&lt;br /&gt;
#373 Private Method Listing&lt;br /&gt;
	def log(line)&lt;br /&gt;
          $log = File.open(&amp;quot;/var/log/pluto/&amp;quot; + device_.devid_.to_s + &amp;quot;_Generic_Serial_Device.log&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
          $log.puts &amp;quot;(***):&amp;quot; + line.to_s&lt;br /&gt;
          $log.close&lt;br /&gt;
        end 	&lt;br /&gt;
#351 Process IDLE&lt;br /&gt;
		&lt;br /&gt;
#350 Process Incoming Data&lt;br /&gt;
	buff = &#039;&#039;&lt;br /&gt;
        loop do&lt;br /&gt;
          buff=conn_.Recv(30,200)&lt;br /&gt;
          if buff.empty?&lt;br /&gt;
            log(&#039;Nothing Received&#039;)&lt;br /&gt;
            break&lt;br /&gt;
          end&lt;br /&gt;
          log(&#039;Received: &#039; + Regexp.escape(buff.to_s))&lt;br /&gt;
          if buff.include?(&amp;quot;OK&amp;quot;)&lt;br /&gt;
            log(Regexp.escape(buff.to_s) + &#039;: Command Processed Successfully&#039;)&lt;br /&gt;
          elsif buff.include?(&amp;quot;NG&amp;quot;)&lt;br /&gt;
            log(Regexp.escape(buff.to_s) +&#039;: Command Processed Unsuccessfully&#039;)&lt;br /&gt;
          end&lt;br /&gt;
        end 	&lt;br /&gt;
#355 Process Initialize&lt;br /&gt;
	for iRetry in 0...4&lt;br /&gt;
          print &amp;quot;Initializing unit\n&amp;quot;&lt;br /&gt;
          conn_.Send(&amp;quot;ke 01 01\r&amp;quot;) # Send UnMute Command&lt;br /&gt;
          buf = conn_.Recv(30,200) # Expected Return # ke 01 01\r\ne 00 OK01x\r\n&lt;br /&gt;
          if !buf.nil? &amp;amp;&amp;amp; buf.include?(&amp;quot;OK&amp;quot;)&lt;br /&gt;
            print &amp;quot;Initialized ok\n&amp;quot;&lt;br /&gt;
            print &amp;quot;Setting volume to 30%\n&amp;quot;&lt;br /&gt;
            cmd_313(15)&lt;br /&gt;
            SetDeviceDataInDB( device_.devid_, 158, &amp;quot;15&amp;quot; )&lt;br /&gt;
            # 158 = DEVICEDATA_Volume_Level_CONST&lt;br /&gt;
            return&lt;br /&gt;
          end&lt;br /&gt;
          print &amp;quot;Failed to initialize. Wait 1 secs and try again\n&amp;quot;&lt;br /&gt;
          sleep(1)&lt;br /&gt;
        end&lt;br /&gt;
#DisableDevice( device_.devid_, true )&lt;br /&gt;
#print &amp;quot;The device would not respond. Disabling it.\n&amp;quot; 	&lt;br /&gt;
#384 Process Receive Command For Child&lt;br /&gt;
		&lt;br /&gt;
#356 Process Release&lt;br /&gt;
		&lt;br /&gt;
Misc&lt;br /&gt;
#548 Menu&lt;br /&gt;
	log(&#039;Sending Menu Command&#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 43\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#676 Video Mute&lt;br /&gt;
	log(&#039;Sending Video Mute Command&#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;kd 01 00\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
Numbers&lt;br /&gt;
#364 -/--/---&lt;br /&gt;
		&lt;br /&gt;
#204 0&lt;br /&gt;
	log(&#039;Sending 0 &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 10\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#205 1&lt;br /&gt;
	log(&#039;Sending 1 &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 11\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#206 2&lt;br /&gt;
	log(&#039;Sending 2 &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 12\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#207 3&lt;br /&gt;
	log(&#039;Sending 3 &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 13\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#208 4&lt;br /&gt;
	log(&#039;Sending 4 &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 14\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#209 5&lt;br /&gt;
	log(&#039;Sending 5 &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 15\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#210 6&lt;br /&gt;
	log(&#039;Sending 6 &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 16\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#211 7&lt;br /&gt;
	log(&#039;Sending 7 &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 17\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#212 8&lt;br /&gt;
	log(&#039;Sending 8 &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 18\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#213 9&lt;br /&gt;
	log(&#039;Sending 9 &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 19\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#363 Back / Clear Entry&lt;br /&gt;
	log(&#039;Sending Back/Clear Command &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 1A\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
On-Screen Menu Navig&lt;br /&gt;
#240 Back / Prior Menu&lt;br /&gt;
	log(&#039;Sending Exit Command &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 5B\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#225 Display&lt;br /&gt;
		&lt;br /&gt;
#368 Help&lt;br /&gt;
		&lt;br /&gt;
#86 Menu (Show Menu)&lt;br /&gt;
	log(&#039;Sending Menu Command &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 43\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#201 Move Down&lt;br /&gt;
	log(&#039;Sending Move Down Command &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 41\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#202 Move Left&lt;br /&gt;
	log(&#039;Sending Move Left Command &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 07\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#203 Move Right&lt;br /&gt;
	log(&#039;Sending Move RighCommand &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 06\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#200 Move Up&lt;br /&gt;
	log(&#039;Sending Move Up Command &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 40\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
Simple Control&lt;br /&gt;
#92 Pause&lt;br /&gt;
	log(&#039;Sending Pause Command &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 BA\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#139 Play&lt;br /&gt;
	log(&#039;Sending Play Command &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 B0\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#102 Record&lt;br /&gt;
	#log(&#039;Sending Record Command &#039;) &lt;br /&gt;
        #&amp;lt;$&amp;quot;mc 01 BD\r&amp;quot;$&amp;gt; &lt;br /&gt;
#64 Skip Back - Channel/Track Lower&lt;br /&gt;
	log(&#039;Sending Channel Down Command &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 01\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#63 Skip Fwd - Channel/Track Greater&lt;br /&gt;
	log(&#039;Sending Channel Up Command &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 00\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#95 Stop&lt;br /&gt;
	log(&#039;Sending Stop Command &#039;) &lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 B1\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
Sound &amp;amp; Volume&lt;br /&gt;
#97 Mute&lt;br /&gt;
	if @mute&lt;br /&gt;
          &amp;lt;$&amp;quot;ke 01 00\r&amp;quot;$&amp;gt;&lt;br /&gt;
        else&lt;br /&gt;
          &amp;lt;$&amp;quot;ke 01 01\r&amp;quot;$&amp;gt;&lt;br /&gt;
        end&lt;br /&gt;
        @mute=!@mute 	&lt;br /&gt;
#313 Set Volume&lt;br /&gt;
	@volume=level.to_i()&lt;br /&gt;
        ilevel = @volume.to_i&lt;br /&gt;
        log( &#039;setting volume to &#039;+ ilevel.to_s)&lt;br /&gt;
        log(&#039;Sending the Following Command: kf 01 &#039;+ilevel.to_s(16)+&#039;\r&#039;)&lt;br /&gt;
        &amp;lt;$&amp;quot;kf 01 &amp;quot;+ilevel.to_s(16)+&amp;quot;\r&amp;quot;$&amp;gt;&lt;br /&gt;
        SetDeviceDataInDB( device_.devid_, 158, ilevel .to_s)&lt;br /&gt;
        # 158 = DEVICEDATA_Volume_Level_CONST # &amp;quot;volume and corresponding device data set\n&amp;quot; 	&lt;br /&gt;
#90 Vol Down&lt;br /&gt;
	log(&#039;lowering volume from &#039; + @volume.to_s)&lt;br /&gt;
        cmd_313(@volume-1) 	&lt;br /&gt;
#89 Vol Up&lt;br /&gt;
	log(&#039;Increasing volume from &#039; + @volume.to_s)&lt;br /&gt;
        cmd_313(@volume+1) 	&lt;br /&gt;
Speed Ctrl&lt;br /&gt;
#125 Scan Back/Rewind&lt;br /&gt;
	log(&#039;Sending Rewind Command &#039;)&lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 8F\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#93 Scan Fwd/Fast Fwd&lt;br /&gt;
	log(&#039;Sending Fast Fwd Command &#039;)&lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 8E\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
#98 Slow Scan Back&lt;br /&gt;
		&lt;br /&gt;
#99 Slow Scan Forward&lt;br /&gt;
		&lt;br /&gt;
TV&lt;br /&gt;
#136 Previous Channel&lt;br /&gt;
	log(&#039;Sending Previous Channel Command &#039;)&lt;br /&gt;
        &amp;lt;$&amp;quot;mc 01 B2\r&amp;quot;$&amp;gt; 	&lt;br /&gt;
	&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Adding device ==&lt;br /&gt;
&lt;br /&gt;
This is a simple process that you can now add via the [[LinuxMCE Admin Website]] at &#039;&#039;&#039;Wizard &amp;gt; [[AV Devices|A/V Equipment]]&#039;&#039;&#039;&lt;br /&gt;
=== Add device based on created template ===&lt;br /&gt;
Just search for the device template that you created and select it from the list&lt;br /&gt;
=== Specify COM port for it ===&lt;br /&gt;
Just tell LinuxMCE which com port to use.&lt;br /&gt;
=== Assing it to new room ===&lt;br /&gt;
Tell LinuxMCE which room to assign this device&lt;br /&gt;
=== Specifiy Audio pipe connections to inputs on receiver ===&lt;br /&gt;
Tell LinuxMCE how you have thing attached to the LG TV and how the LG TV is attached to the computer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;I have it attached via RGB port and I have my cable box attached to AV1 and my HDTV connected to Tuner-Digital input.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Making Plug&amp;amp;Play==&lt;br /&gt;
This is not needed to use the TV, but I post as an option.&lt;br /&gt;
Location: /usr/pluto/pnp&lt;br /&gt;
&lt;br /&gt;
    vi /usr/pluto/pnp/20_LGLCD.sh&lt;br /&gt;
add the following and then make the file executable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; #!/bin/bash&lt;br /&gt;
#Play and Play script for LG TV&#039;s Models Numbers:LGXXLB4/5D&lt;br /&gt;
#Set ID needs to be set to 01&lt;br /&gt;
#Serial feedback is very slow so it requires several seconds to get feedback&lt;br /&gt;
#Device Template Number:1905 on my local Machine.&lt;br /&gt;
#Serail Command for Power On ka 01 01 &lt;br /&gt;
#Serial Command for Power OFF ka 01 00&lt;br /&gt;
#Returns two different strings depending on whether or not the TV is On or Off, so we will try to turn it ON then resend the ON command as it returns proper string (ka 01 01\r\na 00 OK01x\r\n)&lt;br /&gt;
echo &amp;quot;LG TV Detection script queue $2&amp;quot;&lt;br /&gt;
/usr/pluto/bin/TestSerialPort -p $3 -P N81 -b 9600 -t &amp;quot;ka 01 01\r&amp;quot;&lt;br /&gt;
sleep 5s&lt;br /&gt;
/usr/pluto/bin/TestSerialPort -p $3 -P N81 -b 9600 -t &amp;quot;ka 01 01\r&amp;quot; -i 5 -s &amp;quot;OK01x\r&amp;quot;&lt;br /&gt;
if [[ &amp;quot;$?&amp;quot; -ne 0 ]]; then&lt;br /&gt;
echo &amp;quot;It&#039;s not a LG TV&amp;quot;&lt;br /&gt;
/usr/pluto/bin/MessageSend dcerouter -r 0 $1 1 806 224 $2 13 &amp;quot;$4&amp;quot; 44 0&lt;br /&gt;
else&lt;br /&gt;
echo &amp;quot;It is a LG TV&amp;quot;&lt;br /&gt;
/usr/pluto/bin/MessageSend dcerouter -r 0 $1 1 806 224 $2 13 &amp;quot;$4&amp;quot; 44 1905&lt;br /&gt;
fi&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the plugin will run the script with 4 parameters: the device id of the plugin, the unique id for this event (the PK_PnpQueue), a path where the device is located (ip address for ethernet devices, serial port for rs232 devices, etc.), and the name of the pnp detection script.&lt;br /&gt;
&lt;br /&gt;
The detection script should attempt to determine what device template is on the path using any appropriate means. If it finds a match, it should fire a message using the paramters it received, such as this:&lt;br /&gt;
&lt;br /&gt;
/usr/pluto/bin/MessageSend dcerouter -r 0 $1 806 224 $2 13 &amp;quot;$4&amp;quot; 44 1905(this is the template id for the devicetemplate you created above)&lt;/div&gt;</summary>
		<author><name>Newacct</name></author>
	</entry>
	<entry>
		<id>http://wiki.linuxmce.org/index.php?title=Onkyo_TXSR805&amp;diff=22223</id>
		<title>Onkyo TXSR805</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxmce.org/index.php?title=Onkyo_TXSR805&amp;diff=22223"/>
		<updated>2010-02-02T09:54:39Z</updated>

		<summary type="html">&lt;p&gt;Newacct: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category: Audio]]&lt;br /&gt;
{{stub}}&lt;br /&gt;
[[category: Tutorials]]&lt;br /&gt;
== Using the Onkyo TX-SR805 with RS232 Control ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;THIS CODE IS STILL BEING DEVELOPED&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Future home of the howto for setting up a Onkyo TX-SR805 with RS232 support.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
May widen howto to all Onkyo RS232 Receivers.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This device does currently work with limited functionality.  A writeup for how to add this device to a Linux MCE system will be done soon.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
** If you use this device and have any problems or suggestions to the code here, please switch over to the discussion tab and bring it to my attention **&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Current features supported:&amp;lt;br&amp;gt;&lt;br /&gt;
-On/Off&amp;lt;br&amp;gt;&lt;br /&gt;
-Change inputs&amp;lt;br&amp;gt;&lt;br /&gt;
-Volume control (Up/Down in set increments.  cmd_313 Set Volume still needs work)&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Being worked on:&amp;lt;br&amp;gt;&lt;br /&gt;
-Precise Volume Control (cmd_313)&amp;lt;br&amp;gt;&lt;br /&gt;
-Listening Modes&amp;lt;br&amp;gt;&lt;br /&gt;
-Zone 2/3&amp;lt;br&amp;gt;&lt;br /&gt;
-FM Tuner&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&#039;&#039;&#039;Ruby Code:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Section: 193 Off&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1PWR00\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 192 On&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1PWR01\r&amp;quot;$&amp;gt;&lt;br /&gt;
 sleep(2)&lt;br /&gt;
 &amp;lt;$&amp;quot;!AMT00\r&amp;quot;$&amp;gt;&lt;br /&gt;
 @mute = false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 169 AM&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI25\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 164 Aux&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI03\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 172 Aux 2&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI04\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 162 CD&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI23\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 165 DVD&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI10\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 170 FM&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI24\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 163 Phono&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI22\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 160 Tape / Tape 1&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI20\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 173 Tape 2&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI21\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 166 Tuner&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI26\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 909 XM&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1SLI31\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 373 Private Method Listing&amp;lt;br&amp;gt;&lt;br /&gt;
 # Written by Jason Bennett&lt;br /&gt;
 #&lt;br /&gt;
 # Process 373 - Methods&lt;br /&gt;
 def receiveMsg&lt;br /&gt;
  buff = conn_.Recv(7, 1000) &lt;br /&gt;
  log(&amp;quot;Message Received: #{buff}&amp;quot;)&lt;br /&gt;
  trash = conn_.Recv(1, 100)&lt;br /&gt;
  if buff.length() &amp;lt; 7&lt;br /&gt;
    parsed1 = &amp;quot;ERR&amp;quot;&lt;br /&gt;
    parsed2 = &amp;quot;00&amp;quot;&lt;br /&gt;
  else&lt;br /&gt;
    parsed2 = buff[5].chr + buff[6].chr&lt;br /&gt;
    parsed1 = buff[2].chr + buff[3].chr + buff[4].chr&lt;br /&gt;
    return [parsed1, parsed2]&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
 #-------------------------------------------- Parsing -----------------------------------------------------------------------------------&lt;br /&gt;
 def chkMsg(cat, opt)&lt;br /&gt;
    case cat&lt;br /&gt;
      # Power&lt;br /&gt;
      when &amp;quot;PWR&amp;quot;&lt;br /&gt;
          cmd = Command.new(device_.devid_, -1001, 1, 2, 48)  # 48 = Power State&lt;br /&gt;
          case opt&lt;br /&gt;
            when &amp;quot;01&amp;quot;&lt;br /&gt;
              cmd.params_[10] = &amp;quot;1&amp;quot;   # Command 48, Param 10: 1 = On&lt;br /&gt;
            when &amp;quot;00&amp;quot;&lt;br /&gt;
              cmd.params_[10] = &amp;quot;0&amp;quot;   # Command 48, Param 10: 2 = Off&lt;br /&gt;
          end&lt;br /&gt;
          SendCommand(cmd)&lt;br /&gt;
      # Master Volume Level&lt;br /&gt;
      when &amp;quot;MVL&amp;quot;&lt;br /&gt;
        cmd = Command.new(device_.devid_, -1001, 1, 2, 71)   # 71 = Volume&lt;br /&gt;
        cmd.params_[30] = opt.hex.to_s # Command 71, Param 16 = Volume Level in Decimal&lt;br /&gt;
        log(&amp;quot;volume reported as: #{opt.hex.to_s}&amp;quot;)&lt;br /&gt;
        SendCommand(cmd)&lt;br /&gt;
      # Input Selection&lt;br /&gt;
      when &amp;quot;SLI&amp;quot;&lt;br /&gt;
        cmd = Command.new(device_.devid_, -1001, 1, 2, 49)    # 49 = Input Selection&lt;br /&gt;
        case opt&lt;br /&gt;
          when &amp;quot;00&amp;quot;&lt;br /&gt;
            input_param = 316&lt;br /&gt;
          when &amp;quot;01&amp;quot;&lt;br /&gt;
            input_param = 317&lt;br /&gt;
          when &amp;quot;02&amp;quot;&lt;br /&gt;
            input_param = 318&lt;br /&gt;
          when &amp;quot;03&amp;quot;&lt;br /&gt;
            input_param = 164&lt;br /&gt;
          when &amp;quot;04&amp;quot;&lt;br /&gt;
            input_param = 172&lt;br /&gt;
          when &amp;quot;10&amp;quot;&lt;br /&gt;
            input_param = 165&lt;br /&gt;
          when &amp;quot;20&amp;quot;&lt;br /&gt;
            input_param = 160&lt;br /&gt;
          when &amp;quot;22&amp;quot;&lt;br /&gt;
            input_param = 163&lt;br /&gt;
          when &amp;quot;23&amp;quot;&lt;br /&gt;
            input_param = 162&lt;br /&gt;
          when &amp;quot;24&amp;quot;&lt;br /&gt;
            input_param = 170&lt;br /&gt;
          when &amp;quot;25&amp;quot;&lt;br /&gt;
            input_param = 169&lt;br /&gt;
          when &amp;quot;26&amp;quot;&lt;br /&gt;
            input_param = 166&lt;br /&gt;
          when &amp;quot;31&amp;quot;&lt;br /&gt;
            input_param = 909&lt;br /&gt;
        end&lt;br /&gt;
        cmd.params_[41] = input_param.to_s()  # Command 49, Param 41 = Input&lt;br /&gt;
        SendCommand(cmd)&lt;br /&gt;
    end&lt;br /&gt;
 end&lt;br /&gt;
 #-------------------------------------------- Logging -----------------------------------------------------------------------------------&lt;br /&gt;
 def log(line)&lt;br /&gt;
  $log = File.open(&amp;quot;/var/log/pluto/&amp;quot; + device_.devid_.to_s + &amp;quot;_Generic_Serial_Device.log&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
  $log.puts &amp;quot;(***):&amp;quot; + line.to_s&lt;br /&gt;
  $log.close&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 350 Process Incoming Data&amp;lt;br&amp;gt;&lt;br /&gt;
 # Written by Jason Bennett&lt;br /&gt;
 #&lt;br /&gt;
 # Process 350 - Incoming&lt;br /&gt;
 incMsg = receiveMsg()&lt;br /&gt;
 log(&amp;quot;New Msg: #{incMsg[0]}:#{incMsg[1]}&amp;quot;)&lt;br /&gt;
 chkMsg(incMsg[0], incMsg[1])&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 355 Process Initialize&amp;lt;br&amp;gt;&lt;br /&gt;
 #31-May-06 14:13 init  Onkyo Receiver&lt;br /&gt;
 initok=false&lt;br /&gt;
 for iRetry in 0...4&lt;br /&gt;
    print &amp;quot;Initializing unit\n&amp;quot;&lt;br /&gt;
      conn_.Send(&amp;quot;!1PWRQSTN\r&amp;quot;)&lt;br /&gt;
    buf = conn_.Recv(200, 1000)&lt;br /&gt;
    if !buf.nil? &amp;amp;&amp;amp; buf.include?(&amp;quot;PWR0&amp;quot;)&lt;br /&gt;
        print &amp;quot;Initialized ok\n&amp;quot;&lt;br /&gt;
                initok=true&lt;br /&gt;
                break&lt;br /&gt;
        else&lt;br /&gt;
                print &amp;quot;Didn&#039;t respond to command\n&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
 end&lt;br /&gt;
 if initok==false&lt;br /&gt;
        DisableDevice( device_.devid_, true )&lt;br /&gt;
        print &amp;quot;The device wouldn&#039;t respond. Disabling it.\n&amp;quot;&lt;br /&gt;
        return&lt;br /&gt;
 end&lt;br /&gt;
 print &amp;quot;Initialized ok, doing log\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 97 Mute&amp;lt;br&amp;gt;&lt;br /&gt;
 if(@mute)&lt;br /&gt;
  &amp;lt;$&amp;quot;!1AMT00\r&amp;quot;$&amp;gt;&lt;br /&gt;
 else&lt;br /&gt;
  &amp;lt;$&amp;quot;!1AMT01\r&amp;quot;$&amp;gt;&lt;br /&gt;
 end&lt;br /&gt;
 @mute=!@mute&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 313 Set Volume&amp;lt;br&amp;gt;&lt;br /&gt;
 slevel = sprintf( &amp;quot;%x&amp;quot;, level.to_i)&lt;br /&gt;
 &amp;lt;$&amp;quot;!1MVL&amp;quot; + slevel + &amp;quot;\r&amp;quot;$&amp;gt;&lt;br /&gt;
 SetDeviceDataInDB( device_.devid_, 158, level ) # 158 = DEVICEDATA_Volume_Level_CONST&lt;br /&gt;
 print &amp;quot;volume and corresponding device data set\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 90 Vol Down&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1MVLDOWN\r&amp;quot;$&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Section: 89 Vol Up&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;$&amp;quot;!1MVLUP\r&amp;quot;$&amp;gt;&lt;/div&gt;</summary>
		<author><name>Newacct</name></author>
	</entry>
	<entry>
		<id>http://wiki.linuxmce.org/index.php?title=Insteon_PLM_Ruby_Code_355&amp;diff=22184</id>
		<title>Insteon PLM Ruby Code 355</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxmce.org/index.php?title=Insteon_PLM_Ruby_Code_355&amp;diff=22184"/>
		<updated>2010-01-27T09:16:39Z</updated>

		<summary type="html">&lt;p&gt;Newacct: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category: Insteon]]&lt;br /&gt;
&amp;lt;pre&amp;gt;#### Written by Dan Damron&lt;br /&gt;
#### #355 Process Initialize ####&lt;br /&gt;
$red = 0x1b.chr + &#039;[31m&#039;&lt;br /&gt;
$green = 0x1b.chr + &#039;[32m&#039;&lt;br /&gt;
$yellow = 0x1b.chr + &#039;[33m&#039;&lt;br /&gt;
$blue = 0x1b.chr + &#039;[34m&#039;&lt;br /&gt;
$purple = 0x1b.chr + &#039;[35m&#039;&lt;br /&gt;
$aqua = 0x1b.chr + &#039;[36m&#039;&lt;br /&gt;
$grey = 0x1b.chr + &#039;[37m&#039;&lt;br /&gt;
$redBack = 0x1b.chr + &#039;[41m&#039;&lt;br /&gt;
$greenBack = 0x1b.chr + &#039;[42m&#039;&lt;br /&gt;
$yellowBack = 0x1b.chr + &#039;[43m&#039;&lt;br /&gt;
$blueBack = 0x1b.chr + &#039;[44m&#039;&lt;br /&gt;
$purpleBack = 0x1b.chr + &#039;[45m&#039;&lt;br /&gt;
$aquaBack = 0x1b.chr + &#039;[46m&#039;&lt;br /&gt;
$greyBack = 0x1b.chr + &#039;[47m&#039;&lt;br /&gt;
$blackBack = 0x1b.chr + &#039;[48m&#039;&lt;br /&gt;
$remoteLinkRecord = &#039;&#039;&lt;br /&gt;
#$remoteRecordReady = 0&lt;br /&gt;
$configstring = &#039;&#039;&lt;br /&gt;
$configparams = []&lt;br /&gt;
$childdatabases = {}&lt;br /&gt;
$newdevices = {}&lt;br /&gt;
$state = {}&lt;br /&gt;
$devicetemplate = {}&lt;br /&gt;
$plmdatabase = []&lt;br /&gt;
$plmlastrecord = true&lt;br /&gt;
$log = &#039;&#039;&lt;br /&gt;
$cmdTo = &#039;&#039;&lt;br /&gt;
$cmdFrom = &#039;&#039;&lt;br /&gt;
$cmdPriority = &#039;&#039;&lt;br /&gt;
$cmdType = &#039;&#039;&lt;br /&gt;
$cmdID = &#039;&#039;&lt;br /&gt;
$cmdParams = {}&lt;br /&gt;
$children = {}&lt;br /&gt;
$recvbuff = &#039;&#039;&lt;br /&gt;
$wAIT = false&lt;br /&gt;
$currentCmd = {}&lt;br /&gt;
$flagsBroadcastMessage = 128&lt;br /&gt;
$flagsDirectMessage = 0&lt;br /&gt;
$flagsAckDirectMessage = 32&lt;br /&gt;
$flagsNackDirectMessage = 160&lt;br /&gt;
$flagsGroupBroadcaseMessage = 192&lt;br /&gt;
$flagsGroupCleanupDirectMessage = 64&lt;br /&gt;
$flagsGroupAckDirectMessage =96&lt;br /&gt;
$flagsGroupNackDirectMessage = 224&lt;br /&gt;
$cmdqueue = []&lt;br /&gt;
$currentcmd = 0 # to save state of command when receiving more data.&lt;br /&gt;
$resetNext = 0 # used in Process IDLE to trap stalled responses.&lt;br /&gt;
$savedstate = nil&lt;br /&gt;
$dcequeue = []&lt;br /&gt;
$rerun = false&lt;br /&gt;
$reported = false&lt;br /&gt;
$X10HouseCodes = {&lt;br /&gt;
  &#039;6&#039;, &#039;A&#039;,&lt;br /&gt;
  &#039;E&#039;, &#039;B&#039;, &lt;br /&gt;
  &#039;2&#039;, &#039;C&#039;, &lt;br /&gt;
  &#039;A&#039;, &#039;D&#039;, &lt;br /&gt;
  &#039;1&#039;, &#039;E&#039;, &lt;br /&gt;
  &#039;9&#039;, &#039;F&#039;, &lt;br /&gt;
  &#039;5&#039;, &#039;G&#039;, &lt;br /&gt;
  &#039;D&#039;, &#039;H&#039;, &lt;br /&gt;
  &#039;7&#039;, &#039;I&#039;, &lt;br /&gt;
  &#039;F&#039;, &#039;J&#039;, &lt;br /&gt;
  &#039;3&#039;, &#039;K&#039;, &lt;br /&gt;
  &#039;B&#039;, &#039;L&#039;, &lt;br /&gt;
  &#039;0&#039;, &#039;M&#039;, &lt;br /&gt;
  &#039;8&#039;, &#039;N&#039;, &lt;br /&gt;
  &#039;4&#039;, &#039;O&#039;, &lt;br /&gt;
  &#039;C&#039;, &#039;P&#039;}&lt;br /&gt;
$X10UnitCodes = {&lt;br /&gt;
  &#039;6&#039;, &#039;1&#039;, &lt;br /&gt;
  &#039;E&#039;, &#039;2&#039;, &lt;br /&gt;
  &#039;2&#039;, &#039;3&#039;, &lt;br /&gt;
  &#039;A&#039;, &#039;4&#039;, &lt;br /&gt;
  &#039;1&#039;, &#039;5&#039;, &lt;br /&gt;
  &#039;9&#039;, &#039;6&#039;, &lt;br /&gt;
  &#039;5&#039;, &#039;7&#039;, &lt;br /&gt;
  &#039;D&#039;, &#039;8&#039;, &lt;br /&gt;
  &#039;7&#039;, &#039;9&#039;, &lt;br /&gt;
  &#039;F&#039;, &#039;10&#039;, &lt;br /&gt;
  &#039;3&#039;, &#039;11&#039;, &lt;br /&gt;
  &#039;B&#039;, &#039;12&#039;, &lt;br /&gt;
  &#039;0&#039;, &#039;13&#039;, &lt;br /&gt;
  &#039;8&#039;, &#039;14&#039;, &lt;br /&gt;
  &#039;4&#039;, &#039;15&#039;, &lt;br /&gt;
  &#039;C&#039;, &#039;16&#039;}&lt;br /&gt;
$X10CommandCodes = {&lt;br /&gt;
  &#039;6&#039;, &#039;All Lights Off&#039;, &lt;br /&gt;
  &#039;E&#039;, &#039;Status = off&#039;,&lt;br /&gt;
  &#039;2&#039;, &#039;On&#039;, &lt;br /&gt;
  &#039;A&#039;, &#039;Pre-Set Dim&#039;,&lt;br /&gt;
  &#039;1&#039;, &#039;All Lights On&#039;, &lt;br /&gt;
  &#039;9&#039;, &#039;Hail Ack&#039;,&lt;br /&gt;
  &#039;5&#039;, &#039;Bright&#039;, &lt;br /&gt;
  &#039;D&#039;, &#039;Status=on&#039;,&lt;br /&gt;
  &#039;7&#039;, &#039;Extended Code&#039;,&lt;br /&gt;
  &#039;F&#039;, &#039;Status Request&#039;,&lt;br /&gt;
  &#039;3&#039;, &#039;Off&#039;, &lt;br /&gt;
  &#039;B&#039;, &#039;Pre-set Dim&#039;, &lt;br /&gt;
  &#039;0&#039;, &#039;All Units Off&#039;, &lt;br /&gt;
  &#039;8&#039;, &#039;Hail Request&#039;, &lt;br /&gt;
  &#039;4&#039;, &#039;Dim&#039;, &lt;br /&gt;
  &#039;C&#039;, &#039;Extended Data(analog)&#039;}&lt;br /&gt;
$responseString = &#039;&amp;lt;&#039; + &#039;/&#039; + &#039;Response&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
############################## TEST Code below #################################&lt;br /&gt;
# testing Reading a devices Database&lt;br /&gt;
#	Common Insteon Device Memory Locations:&lt;br /&gt;
#	0x0001 EESize - MSB of size of EEPROM chip in device&lt;br /&gt;
#	0x0002 EEVersion - Firmware Revision number&lt;br /&gt;
#	0x0020 EEOnLevel - Preset On-Level for lighting control&lt;br /&gt;
#	0x0021 EERampRate - Ramp Rate for Lighting Control&lt;br /&gt;
#	0x0030 EEX10BaseHouse - Base X10 House Code for device&lt;br /&gt;
#	0x0031 EEX10BaseUnit - Base X10 Unit Code for device&lt;br /&gt;
#	&lt;br /&gt;
#	ALDB/L&lt;br /&gt;
#	Starts at the top of external serial eeprom and grows downward.&lt;br /&gt;
#	most limited-memory INSTEON devices, top of memory is 0x0FFF&lt;br /&gt;
#	Each Record is 8 bytes long, so the first record starts at&lt;br /&gt;
#	0x0FF8, the second record starts at 0x0FF0&lt;br /&gt;
#&lt;br /&gt;
#	ALDB/L Record Format:&lt;br /&gt;
#	Record Control:	1 byte&lt;br /&gt;
#	Group:		1 Byte&lt;br /&gt;
#	ID:		3 Bytes HB MB LB&lt;br /&gt;
#	Data1:		1 Byte Link-specific data (eg. On-Level)&lt;br /&gt;
#	Data2:		1 Byte Link specific data (eg. Ramp Rates)&lt;br /&gt;
#	Data3:		1 Byte Link specific data (normally unused)&lt;br /&gt;
#&lt;br /&gt;
#	Record Control Byte Bitmap:&lt;br /&gt;
#	7: 1=Record in use, 0=Record is available&lt;br /&gt;
#	6: 1=Controller of ID, 0=Responder of ID&lt;br /&gt;
#	5: Product Dependant&lt;br /&gt;
#	4: Product Dependant&lt;br /&gt;
#	3: Product Dependant&lt;br /&gt;
#	2: Product Dependant&lt;br /&gt;
#	1: 1=Record has been used before, 0=High water mark (last record)&lt;br /&gt;
#	0: Reserved&lt;br /&gt;
#PLM cat 03 subcat 05&lt;br /&gt;
# param = {&#039;Command&#039; =&amp;gt; &#039;StLnk&#039;,&lt;br /&gt;
#&#039;Parameter1&#039; =&amp;gt; &#039;01&#039;, #Link code 0x01=controller&lt;br /&gt;
#&#039;Parameter2&#039; =&amp;gt; &#039;8F&#039; #All Link Group&lt;br /&gt;
#}&lt;br /&gt;
#$cmdqueue &amp;lt;&amp;lt; param&lt;br /&gt;
# param = {&#039;Command&#039; =&amp;gt; &#039;CancelLnk&#039;}&lt;br /&gt;
#$cmdqueue &amp;lt;&amp;lt; param&lt;br /&gt;
#SndIns()&lt;br /&gt;
#&lt;br /&gt;
#Lets try the Assign to ALL-Link Group ### SUCCESS!!!&lt;br /&gt;
#param = {&#039;Command&#039; =&amp;gt; &#039;SndIns&#039;,&lt;br /&gt;
#&#039;Parameter1&#039; =&amp;gt; &#039;0A&#039;, #HB&lt;br /&gt;
#&#039;Parameter2&#039; =&amp;gt; &#039;8F&#039;, #MB&lt;br /&gt;
#&#039;Parameter3&#039; =&amp;gt; &#039;5A&#039;, #LB&lt;br /&gt;
#&#039;Parameter4&#039; =&amp;gt; &#039;0F&#039;, #Flags&lt;br /&gt;
#&#039;Parameter5&#039; =&amp;gt; &#039;01&#039;, #Cmd1&lt;br /&gt;
#&#039;Parameter6&#039; =&amp;gt; &#039;8F&#039; #Cmd2&lt;br /&gt;
#}&lt;br /&gt;
#&lt;br /&gt;
#&lt;br /&gt;
#param = {&#039;Command&#039; =&amp;gt; &#039;MngLnk&#039;,&lt;br /&gt;
#&#039;Parameter1&#039; =&amp;gt; &#039;00&#039;, # Control Code &lt;br /&gt;
#&#039;Parameter2&#039; =&amp;gt; &#039;C2&#039;, #All Link Record Flags AKA Record Control Byte&lt;br /&gt;
#&#039;Parameter3&#039; =&amp;gt; &#039;01&#039;, #All Link Group&lt;br /&gt;
#&#039;Parameter4&#039; =&amp;gt; &#039;0A&#039;, #HB&lt;br /&gt;
#&#039;Parameter5&#039; =&amp;gt; &#039;97&#039;, #MB&lt;br /&gt;
#&#039;Parameter6&#039; =&amp;gt; &#039;0B&#039;, #LB&lt;br /&gt;
#&#039;Parameter7&#039; =&amp;gt; &#039;01&#039;, #Link Data 1 ON-Level&lt;br /&gt;
#&#039;Parameter8&#039; =&amp;gt; &#039;01&#039;, #Link Data 2 Ramp Rate&lt;br /&gt;
#&#039;Parameter9&#039; =&amp;gt; &#039;00&#039;} #Link Data 3 not used&lt;br /&gt;
#$cmdqueue &amp;lt;&amp;lt; param&lt;br /&gt;
#&lt;br /&gt;
#&lt;br /&gt;
## Test Device: LampLinc ID:0A.97.0B&lt;br /&gt;
# Assign Test device to Group&lt;br /&gt;
#param = {&#039;Command&#039; =&amp;gt; &#039;SndIns&#039;,&lt;br /&gt;
#&#039;Parameter1&#039; =&amp;gt; &#039;0A&#039;, #HB&lt;br /&gt;
#&#039;Parameter2&#039; =&amp;gt; &#039;97&#039;, #MB&lt;br /&gt;
#&#039;Parameter3&#039; =&amp;gt; &#039;0B&#039;, #LB&lt;br /&gt;
#&#039;Parameter4&#039; =&amp;gt; &#039;0F&#039;, #Flags&lt;br /&gt;
#&#039;Parameter5&#039; =&amp;gt; &#039;01&#039;, #Cmd1&lt;br /&gt;
#&#039;Parameter6&#039; =&amp;gt; &#039;01&#039; #Cmd2&lt;br /&gt;
#}&lt;br /&gt;
#$cmdqueue &amp;lt;&amp;lt; param&lt;br /&gt;
#&lt;br /&gt;
#&lt;br /&gt;
############################## Real Code below #################################&lt;br /&gt;
log(&#039;MY DEVICE:&#039; + device_.devid_.to_s)&lt;br /&gt;
&lt;br /&gt;
#################################################&lt;br /&gt;
#What I need to do and the order I need to do it.&lt;br /&gt;
#done	read PLM database&lt;br /&gt;
#done	get child devices&lt;br /&gt;
#done	read child devices configuration&lt;br /&gt;
#done1	all child devices in the PLM database?&lt;br /&gt;
#done	if not, add their ID to the PLM database (new group numbers?)&lt;br /&gt;
#	get the status of each (child) device&lt;br /&gt;
#	compare the Database delta with the value stored in the configuration&lt;br /&gt;
#		Different?&lt;br /&gt;
#			read the child database &lt;br /&gt;
#			update configuration&lt;br /&gt;
#			check devices links to see if any are new&lt;br /&gt;
#			new link found, what to do?? send a message?&lt;br /&gt;
#				create new child device?&lt;br /&gt;
#				PING the new device and back to 1&lt;br /&gt;
###&lt;br /&gt;
# easiest way?.. create hash for PLM records&lt;br /&gt;
# 		create hash for child devices is needed &lt;br /&gt;
#		(not needed if DBDelta is same)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#reset the PLM&lt;br /&gt;
$timeout = 3&lt;br /&gt;
#param = {&#039;Command&#039; =&amp;gt; &#039;RstPLM&#039;}&lt;br /&gt;
#$cmdqueue &amp;lt;&amp;lt; param&lt;br /&gt;
#SndIns()&lt;br /&gt;
&lt;br /&gt;
#put IM in monitor mode..&lt;br /&gt;
param = {&#039;Command&#039; =&amp;gt; &#039;SetCfg&#039;, &#039;Parameter1&#039; =&amp;gt; &#039;40&#039;}&lt;br /&gt;
$cmdqueue &amp;lt;&amp;lt; param&lt;br /&gt;
SndIns()&lt;br /&gt;
mainStart()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
##children found... get the status of each child...&lt;br /&gt;
#$children.each_key{|c|&lt;br /&gt;
#	if c.length &amp;gt; 2 #filter out X10 for now&lt;br /&gt;
#	  	#pack insteon message here, and send it out!&lt;br /&gt;
#		# receive message in parsemessage and relay commands back in it.&lt;br /&gt;
#		insteonID = c.chomp.split(&#039;.&#039;)&lt;br /&gt;
#		param = {&#039;Command&#039; =&amp;gt; &#039;SndIns&#039;, &lt;br /&gt;
#		&#039;Parameter1&#039; =&amp;gt; insteonID[0], &lt;br /&gt;
#		&#039;Parameter2&#039; =&amp;gt; insteonID[1],&lt;br /&gt;
#		&#039;Parameter3&#039; =&amp;gt; insteonID[2],&lt;br /&gt;
#		&#039;Parameter4&#039; =&amp;gt; &#039;0F&#039;, #flags&lt;br /&gt;
#		&#039;Parameter5&#039; =&amp;gt; &#039;19&#039;, #Status Request&lt;br /&gt;
#		&#039;Parameter6&#039; =&amp;gt; &#039;00&#039;} #not used.&lt;br /&gt;
#		$cmdqueue &amp;lt;&amp;lt; param&lt;br /&gt;
## below gets the device Cat/SubCat/Firmware&lt;br /&gt;
#		param = {&#039;Command&#039; =&amp;gt; &#039;SndIns&#039;, &lt;br /&gt;
#		&#039;Parameter1&#039; =&amp;gt; insteonID[0], &lt;br /&gt;
#		&#039;Parameter2&#039; =&amp;gt; insteonID[1],&lt;br /&gt;
#		&#039;Parameter3&#039; =&amp;gt; insteonID[2],&lt;br /&gt;
#		&#039;Parameter4&#039; =&amp;gt; &#039;0F&#039;, #flags&lt;br /&gt;
#		&#039;Parameter5&#039; =&amp;gt; &#039;10&#039;, #PING&lt;br /&gt;
#		&#039;Parameter6&#039; =&amp;gt; &#039;00&#039;} #not used.&lt;br /&gt;
#		$cmdqueue &amp;lt;&amp;lt; param&lt;br /&gt;
#&lt;br /&gt;
#	end&lt;br /&gt;
#	}&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Newacct</name></author>
	</entry>
	<entry>
		<id>http://wiki.linuxmce.org/index.php?title=Insteon_PLM_Ruby_Code_373&amp;diff=22183</id>
		<title>Insteon PLM Ruby Code 373</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxmce.org/index.php?title=Insteon_PLM_Ruby_Code_373&amp;diff=22183"/>
		<updated>2010-01-27T09:03:48Z</updated>

		<summary type="html">&lt;p&gt;Newacct: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[category: Insteon]]&lt;br /&gt;
&amp;lt;pre&amp;gt;#### Written by Dan Damron&lt;br /&gt;
#### #373 Private Method Listing ####&lt;br /&gt;
&lt;br /&gt;
def mainStart() ## This is called FIRST, reruns cannot call this.&lt;br /&gt;
  #Register Message Interceptor&lt;br /&gt;
  @interceptor = Command.new(device_.devid_, -1000, 1, 5, 37)&lt;br /&gt;
  @interceptor.params_[2] = device_.devid_.to_s&lt;br /&gt;
  SendCommand(@interceptor)&lt;br /&gt;
  #Get the PLM Database&lt;br /&gt;
  sendGetLink&lt;br /&gt;
  #get Child devices&lt;br /&gt;
  log(&#039;Finding Children..&#039;)&lt;br /&gt;
  device_.childdevices_.each{|c| $children[device_.childdevices_[c.to_s.to_i].devdata_[12].chomp.lstrip.rstrip] = c.to_s.to_i}&lt;br /&gt;
  $children.each{|c,v| log(c + &#039; = &#039; + v.to_s)&lt;br /&gt;
  }&lt;br /&gt;
  log(&#039;reading stored Child configuration:&#039;)&lt;br /&gt;
&lt;br /&gt;
  $children.each_key{|c|&lt;br /&gt;
    #Get each Childs configuration&lt;br /&gt;
    $state[c] = 0&lt;br /&gt;
    getdeviceconfig(c) #&lt;br /&gt;
&lt;br /&gt;
    #the above getdeviceconfig packs $configparams array&lt;br /&gt;
    log(&#039;Configuration for &#039; + c + &#039; = &#039; + $configparams.inspect.to_s)&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  log(&#039;********************************************************&#039;)&lt;br /&gt;
  #get childs actual configuation and status&lt;br /&gt;
  $children.each_key{|c| sendGetChildStatus(c)}&lt;br /&gt;
  SndIns()&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
def mainRestart()&lt;br /&gt;
  #We have hashes already set up.&lt;br /&gt;
  $childdatabases.each_key{|@insteonID|&lt;br /&gt;
    $state[@insteonID] = 0&lt;br /&gt;
    sendGetChildStatus(@insteonID)}&lt;br /&gt;
  SndIns()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def setdeviceconfig(insteonid, configurestring)&lt;br /&gt;
  @deviceid = $children[insteonid]&lt;br /&gt;
  @cmdfrom = device_.devid_&lt;br /&gt;
  @cmdto = 4 #general info plugin&lt;br /&gt;
  @priority = 1&lt;br /&gt;
  @type=1 #command&lt;br /&gt;
  @cmdid = 246&lt;br /&gt;
&lt;br /&gt;
  #set up command..&lt;br /&gt;
  @cmd = Command.new(@cmdfrom, @cmdto, @priority, @type, @cmdid)&lt;br /&gt;
  @cmd.params_[2] = @deviceid.to_s&lt;br /&gt;
  @cmd.params_[52] = &#039;59&#039; # Configuration&lt;br /&gt;
  @cmd.params_[5] = configurestring&lt;br /&gt;
  SendCommand(@cmd)&lt;br /&gt;
  #log(&#039;SetDeviceConfig:&#039; + configurestring)&lt;br /&gt;
  #log(&#039;Configuration Saved - will be available on next reload&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def getdeviceconfig(insteonid)&lt;br /&gt;
  @deviceid = $children[insteonid]&lt;br /&gt;
  @configstring = &#039;&#039;&lt;br /&gt;
  begin&lt;br /&gt;
    @configstring = device_.childdevices_[@deviceid].devdata_[59].to_s&lt;br /&gt;
  rescue&lt;br /&gt;
    log(&#039;Device ID = &#039; + @deviceid.to_s)&lt;br /&gt;
    log($red + &#039;Error - Child has no configuration&#039;+ $grey)&lt;br /&gt;
    log(&#039;Setting initial value of &amp;quot;****************&amp;quot;&#039;)&lt;br /&gt;
    setdeviceconfig(insteonid, (&#039;*&#039; * 16))&lt;br /&gt;
    @configstring = &#039;*&#039; * 16&lt;br /&gt;
    sendPing(insteonid)&lt;br /&gt;
  end&lt;br /&gt;
  if @configstring == &#039;&#039;&lt;br /&gt;
    $configparams = [&#039;****************&#039;]&lt;br /&gt;
    log(&#039;CAUGHT BLANK RECORD&#039;)&lt;br /&gt;
    setdeviceconfig(insteonid, (&#039;*&#039; * 16))&lt;br /&gt;
    sendPing(insteonid)&lt;br /&gt;
  else&lt;br /&gt;
    $configparams = @configstring.unpack(&#039;a16&#039; * (@configstring.length / 16))&lt;br /&gt;
    $devicetemplate[insteonid] = getdevicetemplate($configparams[0][0..1], $configparams[0][2..3])&lt;br /&gt;
  end&lt;br /&gt;
  #log($yellow + &#039;getdeviceconfig:&#039; + $configparams.inspect + $grey)&lt;br /&gt;
  #add the configuration parameters to the child database&lt;br /&gt;
  $childdatabases[insteonid] = $configparams&lt;br /&gt;
  #get the device type&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def sendGetLink()&lt;br /&gt;
  #lets just see exactly what is in the PLM database&lt;br /&gt;
  param = {&#039;Command&#039; =&amp;gt; &#039;GetLnk&#039;}&lt;br /&gt;
  $cmdqueue &amp;lt;&amp;lt; param&lt;br /&gt;
  SndIns()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def sendGetNext()&lt;br /&gt;
  param = {&#039;Command&#039; =&amp;gt; &#039;GetNext&#039;}&lt;br /&gt;
  if $wAIT&lt;br /&gt;
    $cmdqueue.insert(1, param)&lt;br /&gt;
  else&lt;br /&gt;
    $cmdqueue.insert(0,param)&lt;br /&gt;
  end&lt;br /&gt;
  SndIns()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def sendRemoteGetLink(insteonID)&lt;br /&gt;
  # Read First ALDB Record&lt;br /&gt;
  # a few variables need to be set up here..&lt;br /&gt;
  $recordof = insteonID # save the insteon ID&lt;br /&gt;
  insID = insteonID.chomp.split(&#039;.&#039;) # get the seperate bytes&lt;br /&gt;
  $remoteDBOffsetMSB = 0x0F # initial offset&lt;br /&gt;
  $remoteDBOffsetLSB = 0xF8 # initial LSB offset&lt;br /&gt;
  param = {&#039;Command&#039; =&amp;gt; &#039;SndIns&#039;,&lt;br /&gt;
    &#039;Parameter1&#039; =&amp;gt; insID[0], #HB&lt;br /&gt;
    &#039;Parameter2&#039; =&amp;gt; insID[1], #MB&lt;br /&gt;
    &#039;Parameter3&#039; =&amp;gt; insID[2], #LB&lt;br /&gt;
    &#039;Parameter4&#039; =&amp;gt; &#039;0F&#039;, #Flags&lt;br /&gt;
    &#039;Parameter5&#039; =&amp;gt; &#039;28&#039;, #Cmd1&lt;br /&gt;
    &#039;Parameter6&#039; =&amp;gt; &amp;quot;%X&amp;quot; %$remoteDBOffsetMSB #Cmd2 Set MSB Offset&lt;br /&gt;
  }&lt;br /&gt;
  $cmdqueue &amp;lt;&amp;lt; param&lt;br /&gt;
  # repeat last param for each byte to read (F8..FF)=first record&lt;br /&gt;
&lt;br /&gt;
  for x in 0..7&lt;br /&gt;
    param = {&#039;Command&#039; =&amp;gt; &#039;SndIns&#039;,&lt;br /&gt;
      &#039;Parameter1&#039; =&amp;gt; insID[0], #HB&lt;br /&gt;
      &#039;Parameter2&#039; =&amp;gt; insID[1], #MB&lt;br /&gt;
      &#039;Parameter3&#039; =&amp;gt; insID[2], #LB&lt;br /&gt;
      &#039;Parameter4&#039; =&amp;gt; &#039;0F&#039;, #Flags&lt;br /&gt;
      &#039;Parameter5&#039; =&amp;gt; &#039;2B&#039;, #Cmd1 Peek&lt;br /&gt;
      &#039;Parameter6&#039; =&amp;gt; &amp;quot;%X&amp;quot; %($remoteDBOffsetLSB + x) #Cmd2&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $cmdqueue &amp;lt;&amp;lt; param&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def sendRemoteGetNext(insteonID)&lt;br /&gt;
  insID = insteonID.chomp.split(&#039;.&#039;) # get the seperate bytes&lt;br /&gt;
  ### Do NOT forget to check to see if we need to decrease the MSB&lt;br /&gt;
&lt;br /&gt;
  if $remoteDBOffsetLSB == 0x00&lt;br /&gt;
    #OffsetMSB needs to be decreased, and LSB needs reset.&lt;br /&gt;
    $remoteDBOffsetMSB = $remoteDBOffsetMSB - 1&lt;br /&gt;
    $remoteDBOffsetLSN = 0xFF # the next line will decrease this by 8&lt;br /&gt;
  end&lt;br /&gt;
  # decrease DBOffsetLSB by 0x08&lt;br /&gt;
  $remoteDBOffsetLSB = $remoteDBOffsetLSB - 0x08&lt;br /&gt;
&lt;br /&gt;
  for x in 0..7&lt;br /&gt;
    param = {&#039;Command&#039; =&amp;gt; &#039;SndIns&#039;,&lt;br /&gt;
      &#039;Parameter1&#039; =&amp;gt; insID[0], #HB&lt;br /&gt;
      &#039;Parameter2&#039; =&amp;gt; insID[1], #MB&lt;br /&gt;
      &#039;Parameter3&#039; =&amp;gt; insID[2], #LB&lt;br /&gt;
      &#039;Parameter4&#039; =&amp;gt; &#039;0F&#039;, #Flags&lt;br /&gt;
      &#039;Parameter5&#039; =&amp;gt; &#039;2B&#039;, #Cmd1 Peek&lt;br /&gt;
      &#039;Parameter6&#039; =&amp;gt; &amp;quot;%X&amp;quot; %($remoteDBOffsetLSB + x) #Cmd2&lt;br /&gt;
    }&lt;br /&gt;
    #log(&#039;sendRemoteGetNet:added to queue:&#039; + param.inspect)&lt;br /&gt;
    if $wAIT&lt;br /&gt;
      $cmdqueue.insert(x + 1, param)&lt;br /&gt;
    else&lt;br /&gt;
      $cmdqueue.insert(x,param)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
### Main command parsing routine is EZToDCE&lt;br /&gt;
def EZToDCE(param)&lt;br /&gt;
  #param contains a hash of EZBridge command structure&lt;br /&gt;
  #log($blue + &#039;Queue:&#039; + $cmdqueue[0].inspect + $grey)&lt;br /&gt;
  #log($blue + &#039;Param:&#039; + param.inspect + $grey)&lt;br /&gt;
  #log($blue + &#039;currentcmd:&#039; + $currentcmd.to_s + $grey)&lt;br /&gt;
  #checkWait(param)&lt;br /&gt;
  case param[&#039;Response&#039;]&lt;br /&gt;
    # Standard RESPONSES (to commands)&lt;br /&gt;
  when &#039;GetRevision&#039; # Special Response&lt;br /&gt;
    log(&#039;-----|---------GetRevision:&#039; + param[&#039;Parameter1&#039;])&lt;br /&gt;
&lt;br /&gt;
  when &#039;GetLatLong&#039; # Special Response&lt;br /&gt;
    log(&#039;-----|---------GetLatLong: Lat=&#039; + param[&#039;Lat&#039;] + &#039;, Long=&#039; + param[&#039;Long&#039;])&lt;br /&gt;
&lt;br /&gt;
  when &#039;SetLatLong&#039;&lt;br /&gt;
    if param[&#039;Parameter1&#039;] == &#039;True&#039; then&lt;br /&gt;
      log(&#039;-----|---------SetLatLong: Ok&#039;)&lt;br /&gt;
    else&lt;br /&gt;
      log(&#039;-----X---------SetLatLong: FAILED!&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  when &#039;SetPasswd&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;SetTimeZone&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;GetClock&#039; # Special Response&lt;br /&gt;
&lt;br /&gt;
  when &#039;SetClock&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;SetNTPServer&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;Upgrade&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;NetCfg&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;Reset&#039;&lt;br /&gt;
    #Reset Response&lt;br /&gt;
&lt;br /&gt;
    cmdComplete&lt;br /&gt;
    SndIns()&lt;br /&gt;
  when &#039;LstTimers&#039; # Special Response&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  when &#039;ClrTimers&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;AddTimer&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;GetTimer&#039; # Special Response&lt;br /&gt;
&lt;br /&gt;
  when &#039;SetTimer&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;DelTimer&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;GetVersion&#039; # Special Response&lt;br /&gt;
&lt;br /&gt;
  when &#039;SndGrp&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;SndIns&#039; # response from SndIns&lt;br /&gt;
    ### BUG FOUND ### When the EZBridge receives a command from an EXTERNAL source&lt;br /&gt;
    ### ie not from this device, cmdqueue will be nil, and the code below&lt;br /&gt;
    ### fails. Have to check against that.&lt;br /&gt;
    if not $cmdqueue.empty?&lt;br /&gt;
      #First, check the response to make sure the command made it ok.&lt;br /&gt;
      if param[&#039;Parameter9&#039;].to_i == 6 #Ack received&lt;br /&gt;
        #log(&#039;Sending to ProcessACK&#039;)&lt;br /&gt;
        processACK(param)&lt;br /&gt;
      else # NACK received - command failed.&lt;br /&gt;
        log(&#039;Command NACKED&#039;)&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      #Response received for another device.&lt;br /&gt;
      log(&#039;Response detected for a command that was not sent by me&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  when &#039;SndX10&#039;&lt;br /&gt;
    log(&#039;Response detected for SndX10&#039;)&lt;br /&gt;
    if param[&#039;Parameter5&#039;].to_i == 6 #ack&lt;br /&gt;
      log(&#039;X10 Command Successfull&#039;)&lt;br /&gt;
&lt;br /&gt;
      cmdComplete&lt;br /&gt;
      SndIns()&lt;br /&gt;
    else&lt;br /&gt;
      log(&#039;X10 Command FAILED&#039;)&lt;br /&gt;
      cmdComplete&lt;br /&gt;
      SndIns()&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
  when &#039;StLnk&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;CancelLnk&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;SetDev&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;RstPLM&#039;&lt;br /&gt;
    #Reset Response&lt;br /&gt;
    $timeout = 1&lt;br /&gt;
    cmdComplete&lt;br /&gt;
    SndIns()&lt;br /&gt;
&lt;br /&gt;
  when &#039;GetLnk&#039;&lt;br /&gt;
    if param[&#039;Parameter3&#039;].to_i == 6 #ack&lt;br /&gt;
      log(&#039;GetLnk ACKED&#039;)&lt;br /&gt;
      #if we get this, we should get a AllLink Record Response next&lt;br /&gt;
    else&lt;br /&gt;
      log(&#039;GetLnk NACKED&#039;)&lt;br /&gt;
      # The PLM is BLANK&lt;br /&gt;
      #have to add records to the PLM here.&lt;br /&gt;
      cmdComplete&lt;br /&gt;
      ### FINISHED WITH GetLnk&lt;br /&gt;
      checkChildRecordsinPLM()&lt;br /&gt;
      SndIns()&lt;br /&gt;
    end&lt;br /&gt;
  when &#039;GetNext&#039;&lt;br /&gt;
    if param[&#039;Parameter3&#039;].to_i == 6 #ack&lt;br /&gt;
      log(&#039;sendGetNext ACKED&#039;)&lt;br /&gt;
      #if we get this, we should get a AllLink Record Response next&lt;br /&gt;
    else&lt;br /&gt;
      log(&#039;sendGetNext NACKED&#039;)&lt;br /&gt;
      #we get this when there are no more records&lt;br /&gt;
      cmdComplete&lt;br /&gt;
      #FINISHED with GetNext&lt;br /&gt;
      # if we are here, we are in config mode&lt;br /&gt;
      # so, next is to check to make sure the&lt;br /&gt;
      # childrens insteon ID is in the PLM&lt;br /&gt;
      checkChildRecordsinPLM()&lt;br /&gt;
      # now, to make sure that all the records in the PLM are sensed as children&lt;br /&gt;
      &lt;br /&gt;
      SndIns()&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
  when &#039;SetCfg&#039; # response from Setcfg command&lt;br /&gt;
    if param[&#039;Parameter4&#039;].to_i == 6 #ack&lt;br /&gt;
      log(&#039;SetCfg Completed&#039;)&lt;br /&gt;
      cmdComplete&lt;br /&gt;
      SndIns()&lt;br /&gt;
    else&lt;br /&gt;
      log(&#039;SetCfg NACKED&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  when &#039;GetLnkData&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;LEDON&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;LEDOFF&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;MngLnk&#039;&lt;br /&gt;
    if param[&#039;Parameter12&#039;].to_i == 6&lt;br /&gt;
      log(&#039;MngLnk =&amp;gt; ACK&#039;)&lt;br /&gt;
    else&lt;br /&gt;
      log(&#039;MngLnk =&amp;gt; NACK&#039;)&lt;br /&gt;
    end&lt;br /&gt;
    cmdComplete&lt;br /&gt;
    SndIns()&lt;br /&gt;
&lt;br /&gt;
  when &#039;GetCfg&#039; # Special Response&lt;br /&gt;
&lt;br /&gt;
  when &#039;LstMacros&#039; # Special Response&lt;br /&gt;
&lt;br /&gt;
  when &#039;ClrMacros&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;AddMacro&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;GetMacro&#039; # Special Response&lt;br /&gt;
&lt;br /&gt;
  when &#039;SetMacro&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;DelMacro&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;LstDevices&#039; # Special Response&lt;br /&gt;
&lt;br /&gt;
  when &#039;ClrDevices&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;AddDevice&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;GetDevice&#039; # Special Response&lt;br /&gt;
&lt;br /&gt;
  when &#039;SetDevice&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;DelDevice&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;LstZones&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;ClrZones&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;AddZone&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;GetZone&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;SetZone&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;DelZone&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;AddDevZone&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;DelDevZone&#039;&lt;br /&gt;
&lt;br /&gt;
    # Response Messages&lt;br /&gt;
  when &#039;InsExtMsg&#039;&lt;br /&gt;
&lt;br /&gt;
  when &#039;InsStdMsg&#039;&lt;br /&gt;
    case $currentcmd # if this msg is part of a response, the Insteon Cmd1 will be saved here.&lt;br /&gt;
    when 0x0&lt;br /&gt;
      #log(&#039;REROUTING to processExternalCommand(param)&#039;)&lt;br /&gt;
      processExternalCommand(param)&lt;br /&gt;
    when 0x1 #Assign to Group&lt;br /&gt;
      ### This is a broadcast message sent&lt;br /&gt;
      # from a PING command&lt;br /&gt;
      # or from a StartLink...&lt;br /&gt;
      log(&#039;Caught Assign to Group Message from Device&#039;)&lt;br /&gt;
      ### BUG HERE&lt;br /&gt;
      #have to check flags to see if this is a broadcast message&lt;br /&gt;
      log(&#039;Checking if this is a broadcast message&#039;)&lt;br /&gt;
      log(&#039;Flags:&#039; + param[&#039;Parameter9&#039;])&lt;br /&gt;
      if (param[&#039;Parameter9&#039;].hex &amp;amp; 0x80) == 0x80&lt;br /&gt;
        log(&#039;Message IS BROADCAST&#039;)&lt;br /&gt;
        #recvComplete&lt;br /&gt;
        processDeviceInfo(param)&lt;br /&gt;
&lt;br /&gt;
        # check to see if current cmd is for this broadcast..&lt;br /&gt;
        log(&#039;Current Command:&#039; + $cmdqueue[0][&#039;Parameter5&#039;])&lt;br /&gt;
        if $cmdqueue[0][&#039;Parameter5&#039;] == &#039;10&#039;&lt;br /&gt;
          #log(&#039;Clearing PING Command&#039;)&lt;br /&gt;
          $currentcmd = 0&lt;br /&gt;
          cmdComplete&lt;br /&gt;
          SndIns()&lt;br /&gt;
        else&lt;br /&gt;
          log(&#039;CURRENT CMD IS NOT PING - NOT CLEARING&#039;)&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
      else&lt;br /&gt;
        log(&#039;Message is NOT Broadcast&#039;)&lt;br /&gt;
      end&lt;br /&gt;
    when 0x2 #Delete from Group&lt;br /&gt;
    when 0x10 # PING&lt;br /&gt;
      #this is where I catch the InsStdMsg for ping.&lt;br /&gt;
      log(&#039;Caught PING Message from Device&#039;)&lt;br /&gt;
      $currentcmd = 1&lt;br /&gt;
&lt;br /&gt;
    when 0x11 # ON&lt;br /&gt;
      log(&#039;Caught Insteon ON from INTERNAL source&#039;)&lt;br /&gt;
      insHb = param[&#039;Parameter3&#039;] # From&lt;br /&gt;
      insMb = param[&#039;Parameter4&#039;]&lt;br /&gt;
      insLb = param[&#039;Parameter5&#039;]&lt;br /&gt;
&lt;br /&gt;
      insID = insHb + &amp;quot;.&amp;quot; + insMb + &amp;quot;.&amp;quot; + insLb&lt;br /&gt;
      myDevFrom = $children[insID]&lt;br /&gt;
      log(&#039;Current DIM level:&#039; + param[&#039;Parameter11&#039;])&lt;br /&gt;
&lt;br /&gt;
      reportStatus(myDevFrom, hextopercent(param[&#039;Parameter11&#039;]))&lt;br /&gt;
&lt;br /&gt;
      $currentcmd = 0&lt;br /&gt;
      cmdComplete&lt;br /&gt;
&lt;br /&gt;
      SndIns()&lt;br /&gt;
    when 0x13 # OFF&lt;br /&gt;
      insHb = param[&#039;Parameter3&#039;] # From&lt;br /&gt;
      insMb = param[&#039;Parameter4&#039;]&lt;br /&gt;
      insLb = param[&#039;Parameter5&#039;]&lt;br /&gt;
      insID = insHb + &amp;quot;.&amp;quot; + insMb + &amp;quot;.&amp;quot; + insLb&lt;br /&gt;
      myDevFrom = $children[insID]&lt;br /&gt;
      reportStatus(myDevFrom, 0)&lt;br /&gt;
&lt;br /&gt;
      $currentcmd = 0&lt;br /&gt;
      cmdComplete&lt;br /&gt;
      #log(&#039;EVENT and state SENT!!!.48:[10]=0&#039;)&lt;br /&gt;
      SndIns()&lt;br /&gt;
    when 0x19 # Status Report&lt;br /&gt;
      # now to clear the currentcmd and remove command from the queue&lt;br /&gt;
      $currentcmd = 0&lt;br /&gt;
      cmdComplete&lt;br /&gt;
&lt;br /&gt;
      log(&#039;Processing 0x19 Status Report&#039;)&lt;br /&gt;
      #This is where I get the database delta (in cmd1)&lt;br /&gt;
      insHb = param[&#039;Parameter3&#039;] # From&lt;br /&gt;
      insMb = param[&#039;Parameter4&#039;]&lt;br /&gt;
      insLb = param[&#039;Parameter5&#039;]&lt;br /&gt;
      insID = insHb + &amp;quot;.&amp;quot; + insMb + &amp;quot;.&amp;quot; + insLb&lt;br /&gt;
      #First, to compare the DB Delta with current config.&lt;br /&gt;
      #Database Delta...&lt;br /&gt;
      delta = param[&#039;Parameter10&#039;].to_s&lt;br /&gt;
      log($blue + &#039;Database Delta=&#039; + delta + $grey)&lt;br /&gt;
      log($blue + &#039;Configuration is:&#039; + getdeltafromconfig(insID) + $grey)&lt;br /&gt;
      if delta == getdeltafromconfig(insID)&lt;br /&gt;
        if $children[insID] != nil&lt;br /&gt;
          myDevFrom = $children[insID]&lt;br /&gt;
          myDevTo = -1000 #DCE Router&lt;br /&gt;
          myPriority = 1&lt;br /&gt;
          myType = 2 #Event&lt;br /&gt;
&lt;br /&gt;
          #Send an EVENT to report STATE ONLY if database has not changed&lt;br /&gt;
          # AND child exists in pluto&lt;br /&gt;
          reportStatus(myDevFrom, hextopercent(param[&#039;Parameter11&#039;]))&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        log(&#039;Databse CHANGED -getting remote database&#039;)&lt;br /&gt;
        #here, I have to WIPE the databse&lt;br /&gt;
        # to prepare it for new data&lt;br /&gt;
        ### here is where the DAMN CONFIG was reset!!!&lt;br /&gt;
        oldconfigstring = $childdatabases[insID][0]&lt;br /&gt;
        $childdatabases[insID] = [oldconfigstring]&lt;br /&gt;
        log(&#039;Setting Database Config&#039;)&lt;br /&gt;
        $childdatabases[insID][0][6..7] = delta&lt;br /&gt;
        savechilddatabases(insID)&lt;br /&gt;
        sendRemoteGetLink(insID)&lt;br /&gt;
      end&lt;br /&gt;
      # finally, to check execute next command...&lt;br /&gt;
      SndIns()&lt;br /&gt;
    when 0x28 # Set Address MSB&lt;br /&gt;
      log(&#039;Received SET Address MSB from remote device&#039;)&lt;br /&gt;
      $currentcmd = 0&lt;br /&gt;
      $remoteLinkRecord = &#039;&#039;&lt;br /&gt;
      cmdComplete&lt;br /&gt;
      SndIns()&lt;br /&gt;
    when 0x2B # peek&lt;br /&gt;
      ### BUG HERE... have to verify response is a PEEK command&lt;br /&gt;
      #response command is stored in parameter10&lt;br /&gt;
      if param[&#039;Parameter10&#039;].hex == 0x2B # this is the peek command&lt;br /&gt;
        cmdComplete&lt;br /&gt;
        log(&#039;Received PEEK from remote Device! DATA=&#039; + param[&#039;Parameter11&#039;])&lt;br /&gt;
        checkPeekData(param)&lt;br /&gt;
        $currentcmd = 0&lt;br /&gt;
        SndIns()&lt;br /&gt;
      else&lt;br /&gt;
        log(&#039;Waiting for remote PEEK response, but got :&#039; + param[&#039;Parameter10&#039;])&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
  when &#039;X10Msg&#039;&lt;br /&gt;
    log($purple + &#039;X10 Message Received&#039; + $grey)&lt;br /&gt;
    if param[&#039;Parameter4&#039;].hex == 0x00&lt;br /&gt;
      log(&#039;This byte is a House/Unit Code&#039;)&lt;br /&gt;
      hn = param[&#039;Parameter3&#039;][0].chr&lt;br /&gt;
      ln = param[&#039;Parameter3&#039;][1].chr&lt;br /&gt;
      $x10byte1 = $X10HouseCodes[hn]&lt;br /&gt;
      $x10byte1 += $X10UnitCodes[ln]&lt;br /&gt;
      log(&#039;Translated X10 House/Unit Code:&#039; + $x10byte1)&lt;br /&gt;
    else&lt;br /&gt;
      log(&#039;This byte is a House/Command Code&#039;)&lt;br /&gt;
      hn = param[&#039;Parameter3&#039;][0].chr&lt;br /&gt;
      ln = param[&#039;Parameter3&#039;][1].chr&lt;br /&gt;
      $x10byte2 = $X10HouseCodes[hn]&lt;br /&gt;
      $x10byte2 += $X10CommandCodes[ln]&lt;br /&gt;
      log(&#039;Translated X10 Command Code:&#039; + $x10byte2)&lt;br /&gt;
      log(&#039;X10 Command ready to send:&#039; + $x10byte1 + &#039; &#039; + $x10byte2)&lt;br /&gt;
      case $X10CommandCodes[ln]&lt;br /&gt;
      when &#039;On&#039;&lt;br /&gt;
        #Send ON to lmnce&lt;br /&gt;
        if $children[$x10byte1] == nil&lt;br /&gt;
          log(&#039;I do not control this X10 device&#039;)&lt;br /&gt;
        else&lt;br /&gt;
          cmd = Command.new($children[$x10byte1].to_i, -1000, 1, 1, 192)&lt;br /&gt;
          cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
          SendCommand(cmd)&lt;br /&gt;
        end&lt;br /&gt;
      when &#039;Off&#039;&lt;br /&gt;
        #Send OFF to lmnce&lt;br /&gt;
        if $children[$x10byte1] == nil&lt;br /&gt;
          log(&#039;I do not control this X10 device&#039;)&lt;br /&gt;
        else&lt;br /&gt;
          cmd = Command.new($children[$x10byte1].to_i, -1000, 1, 1, 193)&lt;br /&gt;
          cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
          SendCommand(cmd)&lt;br /&gt;
        end&lt;br /&gt;
      when &#039;Bright&#039;&lt;br /&gt;
        if $children[$x10byte1] == nil&lt;br /&gt;
          log(&#039;I do not control this X10 device&#039;)&lt;br /&gt;
        else&lt;br /&gt;
          #send a command to set the state + 1&lt;br /&gt;
          @curstate = ($state[$x10byte1] / 100) * 32 #get equal 32 steps&lt;br /&gt;
          $state[$x10byte1] = ((@curstate + 1) / 32) * 100&lt;br /&gt;
          cmd = Command.new($children[$x10byte1].to_i, -1000, 1, 1, 184)&lt;br /&gt;
          cmd.params_[76] = $state[$x10byte1].to_s&lt;br /&gt;
          cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
          SendCommand(cmd)&lt;br /&gt;
          #$state[$x10byte1] = ($state[$x10byte1] / 100) * 32&lt;br /&gt;
        end&lt;br /&gt;
      when &#039;Dim&#039;&lt;br /&gt;
        @curstate = ($state[$x10byte1] / 100) * 32 #get equal 32 steps&lt;br /&gt;
        $state[$x10byte1] = ((@curstate - 1) / 32) * 100&lt;br /&gt;
        cmd = Command.new($children[$x10byte1].to_i, -1000, 1, 1, 184)&lt;br /&gt;
        cmd.params_[76] = $state[$x10byte1].to_s&lt;br /&gt;
        cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
        SendCommand(cmd)&lt;br /&gt;
      when &#039;All Lights Off&#039;&lt;br /&gt;
        log(&#039;ALL Lights OFF Command not implemented&#039;)&lt;br /&gt;
      when &#039;All Lights On&#039;&lt;br /&gt;
        log(&#039;All Lights ON Command not implemented&#039;)&lt;br /&gt;
      when &#039;Status Request&#039;&lt;br /&gt;
        log(&#039;Status Request Command not implemented&#039;)&lt;br /&gt;
      when &#039;Hail Ack&#039;&lt;br /&gt;
        log(&#039;Hail Ack Command not implemented&#039;)&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
  when &#039;InsLnkSts&#039;&lt;br /&gt;
    log(&#039;InsLnkSts Received&#039;)&lt;br /&gt;
&lt;br /&gt;
  when &#039;BtnRpt&#039;&lt;br /&gt;
    log(&#039;Button Report Received&#039;)&lt;br /&gt;
  when &#039;UsrRst&#039;&lt;br /&gt;
    log(&#039;User Reset Response Received&#039;)&lt;br /&gt;
  when &#039;GrpEvntRpt&#039;&lt;br /&gt;
    log(&#039;Group Event Report Received&#039;)&lt;br /&gt;
&lt;br /&gt;
  when &#039;LnkData&#039;&lt;br /&gt;
    processLnkData(param)&lt;br /&gt;
    # Other messages&lt;br /&gt;
  when &#039;PLMTimeout&#039;&lt;br /&gt;
    log(&#039;PLM Timeout detected.. resetting EZBridge&#039;)&lt;br /&gt;
    resetcmd = {&#039;Command&#039; =&amp;gt; &#039;Reset&#039;}&lt;br /&gt;
    if $wAIT == true&lt;br /&gt;
      $cmdqueue.insert(1, resetcmd)&lt;br /&gt;
    else&lt;br /&gt;
      $cmdqueue.insert(0,resetcmd)&lt;br /&gt;
    end&lt;br /&gt;
    sleep 15&lt;br /&gt;
    $wAIT = false&lt;br /&gt;
    SndIns()&lt;br /&gt;
  when &#039;PLMEchoError&#039; # Have not seen this since a1.23&lt;br /&gt;
    # error sending command to PLM, reset command and try again&lt;br /&gt;
    log(&#039;-----XXXXXXX&#039; + param[&#039;Response&#039;])&lt;br /&gt;
    resetcmd = {&#039;Command&#039; =&amp;gt; &#039;Reset&#039;}&lt;br /&gt;
    if $wAIT == true&lt;br /&gt;
      $cmdqueue.insert(1, resetcmd)&lt;br /&gt;
    else&lt;br /&gt;
      $cmdqueue.insert(0,resetcmd)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    sleep 15&lt;br /&gt;
    $wAIT = false&lt;br /&gt;
    SndIns()&lt;br /&gt;
  when &#039;LongAck&#039;&lt;br /&gt;
    log(&#039;-----XXXXXXX&#039; + param[&#039;Response&#039;])&lt;br /&gt;
    # Error - seems to show up after PLMEchoError&lt;br /&gt;
    resetcmd = {&#039;Command&#039; =&amp;gt; &#039;Reset&#039;}&lt;br /&gt;
    if $wAIT == true&lt;br /&gt;
      $cmdqueue.insert(1, resetcmd)&lt;br /&gt;
    else&lt;br /&gt;
      $cmdqueue.insert(0,resetcmd)&lt;br /&gt;
    end&lt;br /&gt;
    sleep 15&lt;br /&gt;
    $wAIT = false&lt;br /&gt;
    SndIns()&lt;br /&gt;
  else&lt;br /&gt;
    log(&#039;-----XXXXXXX UNKNOWN Response Received&#039;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
### Support routine for EZToDCE&lt;br /&gt;
def processLnkData(param)&lt;br /&gt;
  #Caught a LnkData Response&lt;br /&gt;
  log(&#039;LnkData Message Received&#039;)&lt;br /&gt;
  log(param.inspect)&lt;br /&gt;
  if param[&#039;Parameter6&#039;] == &#039;00&#039; and param[&#039;Parameter7&#039;] == &#039;00&#039;&lt;br /&gt;
    log(&#039;FOUND X10 DEVICE!!!&#039;)&lt;br /&gt;
    insteonID = padhex(param[&#039;Parameter5&#039;])&lt;br /&gt;
  else&lt;br /&gt;
    insteonID = padhex(param[&#039;Parameter5&#039;]) + &#039;.&#039; + padhex(param[&#039;Parameter6&#039;]) + &#039;.&#039; + padhex(param[&#039;Parameter7&#039;])&lt;br /&gt;
  end&lt;br /&gt;
  group = param[&#039;Parameter4&#039;]&lt;br /&gt;
  recflags = param[&#039;Parameter3&#039;]&lt;br /&gt;
  lnkdata1 = param[&#039;Parameter8&#039;]&lt;br /&gt;
  lnkdata2 = param[&#039;Parameter9&#039;]&lt;br /&gt;
  lnkdata3 = param[&#039;Parameter10&#039;]&lt;br /&gt;
  #pack string to store for PLM Database&lt;br /&gt;
  @currentrecord = recflags + group&lt;br /&gt;
  @currentrecord += param[&#039;Parameter5&#039;] + param[&#039;Parameter6&#039;] + param[&#039;Parameter7&#039;]&lt;br /&gt;
  @currentrecord += lnkdata1 + lnkdata2 + lnkdata3&lt;br /&gt;
&lt;br /&gt;
  #Add to plmdatabase&lt;br /&gt;
  $plmdatabase &amp;lt;&amp;lt; @currentrecord&lt;br /&gt;
  log(&#039;record Flags:&#039; + recflags)&lt;br /&gt;
  #log(&#039;PLM database=&#039; +$plmdatabase.inspect)&lt;br /&gt;
  if (recflags[0] &amp;amp; 0x80) == 0x80 # Record is in use if true&lt;br /&gt;
  end&lt;br /&gt;
  if (recflags[0] &amp;amp; 0x40) == 0x40 # Controller if true&lt;br /&gt;
    log(&#039;Controller&#039;)&lt;br /&gt;
  else&lt;br /&gt;
    log(&#039;Responder&#039;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  log(&#039;Insteon ID:&#039; + insteonID + &#039;, Group:&#039; + group)&lt;br /&gt;
&lt;br /&gt;
  cmdComplete&lt;br /&gt;
  sendGetNext()&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
### Support Routine for EZToDCE&lt;br /&gt;
def processExternalCommand(param)&lt;br /&gt;
  #there is no current command&lt;br /&gt;
  # THIS IS COMING FROM AN OUTSIDE SOURCE&lt;br /&gt;
  #EG: Manually turning Light Switch On/Off&lt;br /&gt;
  # process this command.&lt;br /&gt;
  # Note, this is a standard message&lt;br /&gt;
  ### have to check here if child is mine!&lt;br /&gt;
&lt;br /&gt;
  # This is where I have to check for a broadcast command..&lt;br /&gt;
  #if so, search the child databases for responders,&lt;br /&gt;
  #and fire events for each responder.&lt;br /&gt;
  #Message flag is in parameter9 Group command 0xCx (All-Link Broadcast Message Pg 42.)&lt;br /&gt;
  #Group is in parameter8&lt;br /&gt;
  #From InsteonID is parameters 3, 4, 5&lt;br /&gt;
  if (param[&#039;Parameter9&#039;].hex &amp;amp; 0xC0) == 0xC0 # Message is Broadcast&lt;br /&gt;
    log(&#039;Rerouting to processBroadcastMessage&#039;)&lt;br /&gt;
    processBroadcastMessage(param)&lt;br /&gt;
  else&lt;br /&gt;
    log(&#039;Process External Command:&#039;)&lt;br /&gt;
    log(&#039;Param:&#039; + param.inspect)&lt;br /&gt;
&lt;br /&gt;
    # there is no ack here. Simply Send COMMANDS back to DCE&lt;br /&gt;
    # and Complete the recv..&lt;br /&gt;
    case param[&#039;Parameter10&#039;].hex #this is the command&lt;br /&gt;
    when 0x01 #Assign to Group&lt;br /&gt;
      log(&#039;Caught EXTERNAL Assign to Group&#039;)&lt;br /&gt;
      processDeviceInfo(param)&lt;br /&gt;
      recvComplete&lt;br /&gt;
    when 0x02 #Delete from Group&lt;br /&gt;
      log(&#039;Caught EXTERNAL Delete from Group&#039;)&lt;br /&gt;
      recvComplete&lt;br /&gt;
    when 0x10 # PING&lt;br /&gt;
      log(&#039;Caught EXTERNAL Insteon PING result&#039;)&lt;br /&gt;
      recvComplete&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    when 0x11 #ON&lt;br /&gt;
      log(&#039;Caught EXTERNAL Insteon ON command result&#039;)&lt;br /&gt;
      #on level is in cmd2&lt;br /&gt;
      insHb = param[&#039;Parameter3&#039;] # From&lt;br /&gt;
      insMb = param[&#039;Parameter4&#039;]&lt;br /&gt;
      insLb = param[&#039;Parameter5&#039;]&lt;br /&gt;
      insID = insHb + &amp;quot;.&amp;quot; + insMb + &amp;quot;.&amp;quot; + insLb&lt;br /&gt;
      log(&#039;From:&#039; +insID)&lt;br /&gt;
      log(&#039;Device:&#039; + $children[insID].to_s)&lt;br /&gt;
      myDevFrom = $children[insID]&lt;br /&gt;
      # check to see if I own child&lt;br /&gt;
      if myDevFrom == nil&lt;br /&gt;
        log(&#039;I do not control this device.&#039;)&lt;br /&gt;
      else&lt;br /&gt;
        reportStatus(myDevFrom, hextopercent(param[&#039;Parameter11&#039;]))&lt;br /&gt;
        $currentcmd = 0&lt;br /&gt;
      end&lt;br /&gt;
      recvComplete&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    when 0x13 #OFF&lt;br /&gt;
      log(&#039;Caught EXTERNAL Insteon OFF result&#039;)&lt;br /&gt;
      #on level is in cmd2&lt;br /&gt;
      insHb = param[&#039;Parameter3&#039;] # From&lt;br /&gt;
      insMb = param[&#039;Parameter4&#039;]&lt;br /&gt;
      insLb = param[&#039;Parameter5&#039;]&lt;br /&gt;
      insID = insHb + &amp;quot;.&amp;quot; + insMb + &amp;quot;.&amp;quot; + insLb&lt;br /&gt;
      myDevFrom = $children[insID]&lt;br /&gt;
      if myDevFrom == nil&lt;br /&gt;
        log(&#039;I do not control this device.&#039;)&lt;br /&gt;
      else&lt;br /&gt;
&lt;br /&gt;
        reportStatus(myDevFrom, 0)&lt;br /&gt;
&lt;br /&gt;
        $currentcmd = 0&lt;br /&gt;
        #log(&#039;EVENT and state SENT!!!.48:[10]=0&#039;)&lt;br /&gt;
      end&lt;br /&gt;
      recvComplete&lt;br /&gt;
    when 0x15; log(&#039;Caught EXTERNAL Insteon Brighten Result&#039;)&lt;br /&gt;
    when 0x16; log(&#039;Caught EXTERNAL Insteon DIM Result&#039;)&lt;br /&gt;
    when 0x24; log(&#039;Caught EXTERNAL Insteon DO EE READ&#039;)&lt;br /&gt;
    when 0x28; log(&#039;Caught EXTERNAL Insteon SET ADDRESS MSB&#039;)&lt;br /&gt;
    when 0x29; log(&#039;Caught EXTERNAL Insteon POKE&#039;)&lt;br /&gt;
    when 0x2A; log(&#039;Caught EXTERNAL Insteon POKE EXTENDED&#039;)&lt;br /&gt;
    when 0x2B; log(&#039;Caught EXTERNAL Insteon PEEK&#039;)&lt;br /&gt;
    when 0x2C; log(&#039;Caught EXTERNAL Insteon PEEK INTERNAL&#039;)&lt;br /&gt;
    when 0x2D; log(&#039;Caught EXTERNAL Insteon POKE INTERNAL&#039;)&lt;br /&gt;
    else&lt;br /&gt;
      log(&#039;Unknown EXTERNAL Insteon Command.&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
### Support Routine for EZToDCE&lt;br /&gt;
def processACK(param)&lt;br /&gt;
  #log(&#039;In ProcessACK: Param7:&#039; + param[&#039;Parameter7&#039;])&lt;br /&gt;
  #log(&#039;CurrentCmd=&#039; + $currentcmd.to_s)&lt;br /&gt;
  case param[&#039;Parameter7&#039;].hex #Received an ack to THIS command&lt;br /&gt;
  when 0x1 #Assign to Group&lt;br /&gt;
    log(&#039;Got Assign to Group ACK&#039;)&lt;br /&gt;
    $currentcmd = 0x01&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
    #processDeviceInfo(param)&lt;br /&gt;
    #cmdComplete&lt;br /&gt;
  when 0x2 #Delete from Group&lt;br /&gt;
  when 0x10 # PING&lt;br /&gt;
    log(&#039;Got PING ACK&#039;)&lt;br /&gt;
    #cmdComplete&lt;br /&gt;
    $currentcmd = 0x1&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
  when 0x11 #ON&lt;br /&gt;
    $currentcmd = 0x11&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
  when 0x13 #OFF&lt;br /&gt;
    $currentcmd = 0x13&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
  when 0x15 #Bright&lt;br /&gt;
    $currentcmd = 0x15&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
  when 0x16 #DIM&lt;br /&gt;
    $currentcmd = 0x16&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
  when 0x17 #Start Manual Change&lt;br /&gt;
  when 0x18 #Stop Manual Change&lt;br /&gt;
  when 0x19 #Status Request&lt;br /&gt;
    # Status Request Acked - get ready for InsStdMsg&lt;br /&gt;
    $currentcmd = 0x19&lt;br /&gt;
    # change cmd to reflect InsStdMsg&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
  when 0x24&lt;br /&gt;
    log(&#039;Caught ACK for Insteon DO EE READ&#039;)&lt;br /&gt;
    $currentcmd = 0x24&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
  when 0x28&lt;br /&gt;
    log(&#039;Caught ACK for Insteon SET ADDRESS MSB&#039;)&lt;br /&gt;
    $currentcmd = 0x28&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
&lt;br /&gt;
  when 0x29&lt;br /&gt;
    log(&#039;Caught ACK for Insteon POKE&#039;)&lt;br /&gt;
    $currentcmd = 0x29&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
&lt;br /&gt;
  when 0x2A&lt;br /&gt;
    log(&#039;Caught ACK for Insteon POKE EXTENDED&#039;)&lt;br /&gt;
    $currentcmd = 0x2A&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
&lt;br /&gt;
  when 0x2B&lt;br /&gt;
    #log(&#039;Caught ACK for Insteon PEEK&#039;)&lt;br /&gt;
    $currentcmd = 0x2B&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
&lt;br /&gt;
  when 0x2C&lt;br /&gt;
    log(&#039;Caught ACK for Insteon PEEK INTERNAL&#039;)&lt;br /&gt;
    $currentcmd = 0x2C&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
&lt;br /&gt;
  when 0x2D&lt;br /&gt;
    log(&#039;Caught ACK for Insteon POKE INTERNAL&#039;)&lt;br /&gt;
    $currentcmd = 0x2D&lt;br /&gt;
    $cmdqueue[0][&#039;Command&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
&lt;br /&gt;
  else&lt;br /&gt;
    log(&#039;Unknown Insteon Cmd1&#039;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def checkPeekData(param)&lt;br /&gt;
&lt;br /&gt;
  $remoteLinkRecord += param[&#039;Parameter11&#039;].hex.chr&lt;br /&gt;
  log(&#039;CURRENT REMOTE RECORD IS:&#039;)&lt;br /&gt;
  debug($remoteLinkRecord)&lt;br /&gt;
  if $remoteLinkRecord.length == 8&lt;br /&gt;
    log(&#039;REMOTE RECORD COMPLETE!&#039;)&lt;br /&gt;
    processRemoteRecord(param)&lt;br /&gt;
    $remoteLinkRecord = &#039;&#039;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def processRemoteRecord(param)&lt;br /&gt;
  #have to find MY address&lt;br /&gt;
  insHb = param[&#039;Parameter3&#039;] # From&lt;br /&gt;
  insMb = param[&#039;Parameter4&#039;]&lt;br /&gt;
  insLb = param[&#039;Parameter5&#039;]&lt;br /&gt;
  insID = padhex(insHb) + &amp;quot;.&amp;quot; + padhex(insMb) + &amp;quot;.&amp;quot; + padhex(insLb)&lt;br /&gt;
&lt;br /&gt;
  log(&#039;Processing remote Record below:&#039;)&lt;br /&gt;
&lt;br /&gt;
  @flags = &amp;quot;\nFrom Device:&amp;quot; + insID + &amp;quot;\nFlags:\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  if ($remoteLinkRecord[0] &amp;amp; 0x02) == 0x02 # High water mark&lt;br /&gt;
    @flags += &amp;quot;Not the last record\n&amp;quot;&lt;br /&gt;
  else&lt;br /&gt;
    @flags += &amp;quot;This IS the last record\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  if ($remoteLinkRecord[0] &amp;amp; 0x80) == 0x80 # Record is in use&lt;br /&gt;
    @flags += &amp;quot;Record In Use\n&amp;quot;&lt;br /&gt;
    if ($remoteLinkRecord[0] &amp;amp; 0x40) == 0x40 # Controller/Responder&lt;br /&gt;
      @flags += &amp;quot;I am a Controller of &amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      @flags += &amp;quot;I am a Responder of &amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    @insteonID = &amp;quot;%02X&amp;quot; %$remoteLinkRecord[2] + &#039;.&#039;&lt;br /&gt;
    @insteonID += &amp;quot;%02X&amp;quot; %$remoteLinkRecord[3] + &#039;.&#039;&lt;br /&gt;
    @insteonID += &amp;quot;%02X&amp;quot; %$remoteLinkRecord[4]&lt;br /&gt;
&lt;br /&gt;
    @group = &amp;quot;%X&amp;quot; %$remoteLinkRecord[1]&lt;br /&gt;
    @flags += @insteonID + &amp;quot; Group:&amp;quot; + @group&lt;br /&gt;
    @work = &amp;quot;%02X&amp;quot; %$remoteLinkRecord[0] #Control byte&lt;br /&gt;
    @work += &amp;quot;%02X&amp;quot; %$remoteLinkRecord[1] # Group&lt;br /&gt;
    @work += &amp;quot;%02X&amp;quot; %$remoteLinkRecord[2] # ID HB&lt;br /&gt;
    @work += &amp;quot;%02X&amp;quot; %$remoteLinkRecord[3] # ID MB&lt;br /&gt;
    @work += &amp;quot;%02X&amp;quot; %$remoteLinkRecord[4] # ID LB&lt;br /&gt;
    @work += &amp;quot;%02X&amp;quot; %$remoteLinkRecord[5] # Data1&lt;br /&gt;
    @work += &amp;quot;%02X&amp;quot; %$remoteLinkRecord[6] # Data2&lt;br /&gt;
    @work += &amp;quot;%02X&amp;quot; %$remoteLinkRecord[7] # Data3&lt;br /&gt;
    log(&#039;adding to:&#039; + insID)&lt;br /&gt;
    log(&#039;Value:&#039; + @work)&lt;br /&gt;
    $childdatabases[insID] &amp;lt;&amp;lt; @work #add it to the database&lt;br /&gt;
    # log(&#039;Current Database:&#039; + $childdatabases.inspect)&lt;br /&gt;
    #now to save the database to configuration.&lt;br /&gt;
    savechilddatabases(insID)&lt;br /&gt;
    # Now to check to see if the child exists as a record&lt;br /&gt;
    if $childdatabases[@insteonID] == nil&lt;br /&gt;
      log(&#039;InsteonID is NEW, adding Child database entry&#039;)&lt;br /&gt;
      $childdatabases[@insteonID] = [&#039;****************&#039;]&lt;br /&gt;
      $rerun = true&lt;br /&gt;
      sendAddtoPLM(@insteonID)&lt;br /&gt;
      sendPing(@insteonID)&lt;br /&gt;
    else&lt;br /&gt;
      log(&#039;InsteonID:&#039; + @insteonID.to_s + &#039;seems to exist in child databases&#039;)&lt;br /&gt;
      log(&#039;CDB:&#039; + $childdatabases.inspect)&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    @flags += &amp;quot;Record NOT in use\n&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  log($aqua + @flags + $grey)&lt;br /&gt;
  log2(@flags)&lt;br /&gt;
  if ($remoteLinkRecord[0] &amp;amp; 0x02) == 0x02&lt;br /&gt;
    sendRemoteGetNext(insID)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def savechilddatabases(insteonID)&lt;br /&gt;
  #This takes the $childdatabase hash+array and encodes it to&lt;br /&gt;
  # save it as a string.&lt;br /&gt;
  @work = &#039;&#039;&lt;br /&gt;
  #log($yellow + &#039;SaveChildDatabases::nitems:&#039; + $childdatabases[insteonID].nitems.to_s)&lt;br /&gt;
  #log($childdatabases[insteonID].inspect + $grey)&lt;br /&gt;
  $childdatabases[insteonID].each{|record|&lt;br /&gt;
    @work += record&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  #now to save the string...&lt;br /&gt;
  setdeviceconfig(insteonID, @work)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
def sendPing(insteonID)&lt;br /&gt;
  insID = insteonID.split(&#039;.&#039;)&lt;br /&gt;
  param = {&#039;Command&#039; =&amp;gt; &#039;SndIns&#039;,&lt;br /&gt;
    &#039;Parameter1&#039; =&amp;gt; insID[0],&lt;br /&gt;
    &#039;Parameter2&#039; =&amp;gt; insID[1],&lt;br /&gt;
    &#039;Parameter3&#039; =&amp;gt; insID[2],&lt;br /&gt;
    &#039;Parameter4&#039; =&amp;gt; &#039;0F&#039;,&lt;br /&gt;
    &#039;Parameter5&#039; =&amp;gt; &#039;10&#039;, #ID Request&lt;br /&gt;
    &#039;Parameter6&#039; =&amp;gt; &#039;00&#039;}&lt;br /&gt;
  $cmdqueue &amp;lt;&amp;lt; param&lt;br /&gt;
  log(&#039;PING Sent!&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def getdevicetemplate(cat, subcat)&lt;br /&gt;
&lt;br /&gt;
  log(&#039;Entered getdevicetemplate, Cat=&#039; + cat.to_s + &#039;, subcat = &#039; + subcat.to_s)&lt;br /&gt;
  @templid = 0&lt;br /&gt;
  case cat.hex&lt;br /&gt;
  when 0x0 # Generalized Controllers&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x04; log(&#039;Found ControLinc [2430]&#039;)&lt;br /&gt;
    when 0x05; log(&#039;Found RemoteLinc [2440]&#039;)&lt;br /&gt;
    when 0x06; log(&#039;Found Icon Tabletop Controller [2830]&#039;)&lt;br /&gt;
    when 0x09; log(&#039;Found SignaLinc RF Signal Enhancer [2442]&#039;)&lt;br /&gt;
    when 0x0A; log(&#039;Found Balboa Instruments Poolux LCD Controller&#039;)&lt;br /&gt;
    when 0x0B; log(&#039;Found Access Point [2443]&#039;)&lt;br /&gt;
    when 0x0C; log(&#039;Found IES Color Touchscreen&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  when 0x01 # Dimmable Lighting Control&lt;br /&gt;
    # all these devices are associated with Template 38&lt;br /&gt;
    # Light Switch (dimmable)&lt;br /&gt;
    @templid = 38&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00; log(&#039;Found LampLinc V2 [2456D3]&#039;)&lt;br /&gt;
    when 0x01; log(&#039;Found SwitchLinc V2 Dimmer 600W [2476D]&#039;)&lt;br /&gt;
    when 0x02; log(&#039;Found In-LineLinc Dimmer [2475D]&#039;)&lt;br /&gt;
    when 0x03; log(&#039;Found Icon Switch Dimmer [2876D]&#039;)&lt;br /&gt;
    when 0x04; log(&#039;Found SwitchLinc V2 Dimmer 1000W [2476DH]&#039;)&lt;br /&gt;
    when 0x06; log(&#039;Found LampLinc 2-pin [2456D2]&#039;)&lt;br /&gt;
    when 0x07; log(&#039;Found Icon LampLinc V2 2-pin [2456D2]&#039;)&lt;br /&gt;
    when 0x09; log(&#039;Found KeypadLinc Dimmer [2486D]&#039;)&lt;br /&gt;
    when 0x0A; log(&#039;Found Icon In-Wall Controller [2886D]&#039;)&lt;br /&gt;
    when 0x0D; log(&#039;Found SocketLinc [2454D]&#039;)&lt;br /&gt;
    when 0x13; log(&#039;Found Icon SwitchLinc Dimmer for Lixar/Bell Canada [2676D-B]&#039;)&lt;br /&gt;
    when 0x17; log(&#039;Found ToggleLinc Dimmer [2466D]&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  when 0x02 # Switched Lighting Control&lt;br /&gt;
    # all these devices are associated with Template 37&lt;br /&gt;
    # Light Switch (ON/OFF)&lt;br /&gt;
    @templid = 37&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
&lt;br /&gt;
    when 0x09; log(&#039;Found ApplianceLinc [2456S3]&#039;)&lt;br /&gt;
    when 0x0A; log(&#039;Found SwitchLinc Relay [2476S]&#039;)&lt;br /&gt;
    when 0x0B; log(&#039;Found Icon On Off Switch [2876S]&#039;)&lt;br /&gt;
    when 0x0C; log(&#039;Found Icon Appliance Adapter [2856S3]&#039;)&lt;br /&gt;
    when 0x0D; log(&#039;Found ToggleLinc Relay [2466S]&#039;)&lt;br /&gt;
    when 0x0E; log(&#039;Found Switchlinc Relay Countdown Timer [2476ST]&#039;)&lt;br /&gt;
    when 0x10; log(&#039;Found In-LineLinc Relay [2475D]&#039;)&lt;br /&gt;
    when 0x13; log(&#039;Found Icon SwitchLinc Relay for Lixar/Bell Canada [2676R-B]&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  when 0x03 # Network Bridges&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x01; log(&#039;Found PowerLinc Serial [2414S]&#039;)&lt;br /&gt;
    when 0x02; log(&#039;Found PowerLinc USB [2414U]&#039;)&lt;br /&gt;
    when 0x03; log(&#039;Found Icon PowerLinc Serial [2814S]&#039;)&lt;br /&gt;
    when 0x04; log(&#039;Found Icon PowerLinc USB [2814U]&#039;)&lt;br /&gt;
    when 0x05; log(&#039;Found Smartlabs Power Line Modem Serial [2412S]&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  when 0x04 # Irrigation Control&lt;br /&gt;
    # all these devices are associated with Template 1780&lt;br /&gt;
    # Standard Irrigation Sprinkler&lt;br /&gt;
    @templid = 1780&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
&lt;br /&gt;
    when 0x00; log(&#039;Found Simplehomenet EZRain1 Sprinkler Controller&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  when 0x05 # Climate Control&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00; log(&#039;Found Broan SMSC080 Exhaust Fan&#039;)&lt;br /&gt;
    when 0x01; log(&#039;Found Simplehomenet EZTherm&#039;)&lt;br /&gt;
    when 0x02; log(&#039;Found Broan SMSC110 Exhaust Fan&#039;)&lt;br /&gt;
    when 0x03; log(&#039;Found Venstar RF Thermostat Module&#039;)&lt;br /&gt;
    when 0x04; log(&#039;Found Simplehomenet EZStat Thermostat&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  when 0x06 # Pool and Spa Control&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00; log(&#039;Found Simplehomenet EZPool&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  when 0x07 # Sensors and Actuators&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00&lt;br /&gt;
    end&lt;br /&gt;
  when 0x08 # Home Entertainment&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00&lt;br /&gt;
    end&lt;br /&gt;
  when 0x09 # Energy Management&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00&lt;br /&gt;
    end&lt;br /&gt;
  when 0x0A # Built-In Appliance Control&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00&lt;br /&gt;
    end&lt;br /&gt;
  when 0x0B # Plumbing&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00&lt;br /&gt;
    end&lt;br /&gt;
  when 0x0C # Communication&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00&lt;br /&gt;
    end&lt;br /&gt;
  when 0x0D # Computer Control&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00&lt;br /&gt;
    end&lt;br /&gt;
  when 0x0E # Window Coverings&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00&lt;br /&gt;
    end&lt;br /&gt;
  when 0x0F # Access Control&lt;br /&gt;
    case subcat.hex&lt;br /&gt;
    when 0x00&lt;br /&gt;
    end&lt;br /&gt;
  when 0x10 # Security, Health, and Safety&lt;br /&gt;
  when 0x11 # Surveillance&lt;br /&gt;
  when 0x12 # Automotive&lt;br /&gt;
  when 0x13 # Pet care&lt;br /&gt;
  when 0x14 # Toys&lt;br /&gt;
  when 0x15 # Timekeeping&lt;br /&gt;
  when 0x16 # Holiday&lt;br /&gt;
  end&lt;br /&gt;
  return @templid&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def processDeviceInfo(param)&lt;br /&gt;
  ### temporary&lt;br /&gt;
  ### 12-24-07 Adding Device Template compatibility..&lt;br /&gt;
  #have to find MY address&lt;br /&gt;
  insHb = param[&#039;Parameter3&#039;] # From&lt;br /&gt;
  insMb = param[&#039;Parameter4&#039;]&lt;br /&gt;
  insLb = param[&#039;Parameter5&#039;]&lt;br /&gt;
&lt;br /&gt;
  insID = padhex(insHb) + &amp;quot;.&amp;quot; + padhex(insMb) + &amp;quot;.&amp;quot; + padhex(insLb)&lt;br /&gt;
  #set the devicecat and device subcat in the childdatabases&lt;br /&gt;
  # 0-1 Device Category&lt;br /&gt;
  # 2-3 Device SubCategory&lt;br /&gt;
  # 4-5 Device Firmware&lt;br /&gt;
  log(&#039;proccessDeviceInfo:Insteon ID&#039; + insID)&lt;br /&gt;
  $childdatabases[insID][0][0..1] = param[&#039;Parameter6&#039;]&lt;br /&gt;
  $childdatabases[insID][0][2..3] = param[&#039;Parameter7&#039;]&lt;br /&gt;
  $childdatabases[insID][0][4..5] = param[&#039;Parameter8&#039;]&lt;br /&gt;
  savechilddatabases(insID)&lt;br /&gt;
  log(&#039;InsteonID: &#039; + insID)&lt;br /&gt;
  #log(&#039;Child Config AFTER update:&#039; + $childdatabases[insID][0].to_s)&lt;br /&gt;
  log($yellow)&lt;br /&gt;
  @template = getdevicetemplate(param[&#039;Parameter6&#039;], param[&#039;Parameter7&#039;])&lt;br /&gt;
  $devicetemplate[insID] = @template&lt;br /&gt;
  log(&#039;Template ID:&#039; + @template.to_s)&lt;br /&gt;
  ### eventually, open a XML configuration script?&lt;br /&gt;
  ### or read saved data from mysql?&lt;br /&gt;
  ### most likely save this information to sql with device.&lt;br /&gt;
  ### eventually, IPKDB will be available to ping.&lt;br /&gt;
  log(&#039;for Insteon ID:&#039; + insID)&lt;br /&gt;
  log($grey)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def recvComplete&lt;br /&gt;
  # Clears the wait flag, but does not remove a command from the queue&lt;br /&gt;
  $wAIT = false&lt;br /&gt;
  log($green + &amp;quot;Receive Completed. Checking command queue&amp;quot; + $grey)&lt;br /&gt;
  if $cmdqueue.nitems &amp;gt; 0 then&lt;br /&gt;
    log(&amp;quot;Queue:&amp;quot; + $aqua + $cmdqueue.nitems.to_s + $grey + &amp;quot; : executing next command&amp;quot;)&lt;br /&gt;
    SndIns()&lt;br /&gt;
  else&lt;br /&gt;
    log($yellow + &#039;Queue Empty.&#039; + $grey)&lt;br /&gt;
    if $rerun&lt;br /&gt;
      log(&#039;RERUN=TRUE, RESTARTING&#039;)&lt;br /&gt;
      $rerun = false&lt;br /&gt;
      mainRestart()&lt;br /&gt;
    else&lt;br /&gt;
      log(&#039;RERUN Not needed. Checking if reported..&#039;)&lt;br /&gt;
      #report Child devices here.&lt;br /&gt;
      if not $reported&lt;br /&gt;
        log(&#039;Reporting Child Devices&#039;)&lt;br /&gt;
        @work = &amp;quot;&amp;quot;&lt;br /&gt;
        $childdatabases.each{&lt;br /&gt;
          |insteonID,value|&lt;br /&gt;
          log(&#039;Child:&#039; + insteonID)&lt;br /&gt;
          log(&#039;Config:&#039; + value.inspect)&lt;br /&gt;
          @template = $devicetemplate[insteonID]&lt;br /&gt;
          @work += insteonID + &amp;quot;\t\t\t&amp;quot; + @template.to_s + &amp;quot;\t\n&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
        log(@work)&lt;br /&gt;
        cmd = Command.new(device_.devid_, -1001, 1, 2, 54)&lt;br /&gt;
        cmd.params_[13] = @work&lt;br /&gt;
        SendCommand(cmd)&lt;br /&gt;
&lt;br /&gt;
        $reported = true&lt;br /&gt;
      else&lt;br /&gt;
        log(&#039;report not needed&#039;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
def removecurrentcommand&lt;br /&gt;
  #get the current child&lt;br /&gt;
  log(&#039;in RemoveCurrentCommand&#039;)&lt;br /&gt;
  log(&#039;Current Command:&#039; + $cmdqueue[0].inspect)&lt;br /&gt;
  #id is in param123&lt;br /&gt;
  @id = $cmdqueue[0][&#039;Parameter1&#039;]&lt;br /&gt;
  @id += &#039;.&#039; + $cmdqueue[0][&#039;Parameter2&#039;]&lt;br /&gt;
  @id += &#039;.&#039; + $cmdqueue[0][&#039;Parameter3&#039;]&lt;br /&gt;
  log(&#039;ID=&#039; + @id)&lt;br /&gt;
  #now to remove from child and PLM databases&lt;br /&gt;
  removefromchild(@id)&lt;br /&gt;
  removefromplm(@id)&lt;br /&gt;
  cmdComplete&lt;br /&gt;
end&lt;br /&gt;
def cmdComplete&lt;br /&gt;
  # Clears the wait flag, and removes the command from the queue.&lt;br /&gt;
  $wAIT = false&lt;br /&gt;
  $resetNext = 0&lt;br /&gt;
  $cmdqueue.delete_at(0)&lt;br /&gt;
  # now that THAT command is completed, check to see if there is&lt;br /&gt;
  # another command ready to transmit.&lt;br /&gt;
  log($green + &amp;quot;Command Completed.&amp;quot; + $grey)&lt;br /&gt;
end&lt;br /&gt;
def checkWait(param)&lt;br /&gt;
  #Checks for response from current command.&lt;br /&gt;
  if $cmdqueue[0] != nil&lt;br /&gt;
    if $wAIT == true&lt;br /&gt;
      #log(&#039;CW:waiting for command to complete&#039;)&lt;br /&gt;
    else&lt;br /&gt;
      #log(&#039;CW:reports clear&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    log(&#039;------:)----checkWait: command queue is emtpy&#039;)&lt;br /&gt;
    if $wAIT == true #this should never happen&lt;br /&gt;
      log(&#039;------:(XXX-CheckWait: TRUE&#039;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def plmparse(value)&lt;br /&gt;
  #THIS ROUTINE REPLACES parsestring()&lt;br /&gt;
  #this routine will PARSE the incoming stream into valid messages&lt;br /&gt;
  # value is the complete command&lt;br /&gt;
  param = {}&lt;br /&gt;
  #here is a special case, the PLM seems to lock up.&lt;br /&gt;
  if value == 0x15.chr&lt;br /&gt;
    log(&#039;The PLM stopped responding&#039;)&lt;br /&gt;
    log(&#039;Please unplug it, and plug it back in&#039;)&lt;br /&gt;
    log(&#039;and do a quick reload router.&#039;)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
  while value.length &amp;gt; 2&lt;br /&gt;
    case value[1]&lt;br /&gt;
    when 0x62 # Special case, need to look at flags&lt;br /&gt;
      if (value[5] &amp;amp; 0x10) == 0x10 # check for extended flag&lt;br /&gt;
        cmdlen = 23&lt;br /&gt;
      else&lt;br /&gt;
        cmdlen = 9&lt;br /&gt;
      end&lt;br /&gt;
      param[&#039;Response&#039;] = &#039;SndIns&#039;&lt;br /&gt;
    when 0x50; cmdlen = 11; param[&#039;Response&#039;] = &#039;InsStdMsg&#039;&lt;br /&gt;
    when 0x51; cmdlen = 25; param[&#039;Response&#039;] = &#039;InsExtMsg&#039;&lt;br /&gt;
    when 0x68; cmdlen = 4 #Set Insteon ACK Message Byte&lt;br /&gt;
    when 0x71; cmdlen = 5 #Set Insteon ACK Message Two Bytes&lt;br /&gt;
    when 0x70; cmdlen = 4 #Set Insteon NACK Message Byte&lt;br /&gt;
    when 0x63; cmdlen = 5; param[&#039;Response&#039;] = &#039;SndX10&#039;&lt;br /&gt;
    when 0x52; cmdlen = 4; param[&#039;Response&#039;] = &#039;X10Msg&#039;&lt;br /&gt;
    when 0x61; cmdlen = 6; param[&#039;Response&#039;] = &#039;SndGrp&#039;&lt;br /&gt;
    when 0x56; cmdlen = 7; param[&#039;Response&#039;] = &#039;GrpEvntRpt&#039;&lt;br /&gt;
    when 0x58; cmdlen = 3 #All-Link Cleanup Status Report&lt;br /&gt;
    when 0x64; cmdlen = 5; param[&#039;Response&#039;] = &#039;StLnk&#039;&lt;br /&gt;
    when 0x65; cmdlen = 3; param[&#039;Response&#039;] = &#039;CancelLnk&#039;&lt;br /&gt;
    when 0x53; cmdlen = 10; param[&#039;Response&#039;] = &#039;InsLnkSts&#039;&lt;br /&gt;
    when 0x69; cmdlen = 3; param[&#039;Response&#039;] = &#039;GetLnk&#039;&lt;br /&gt;
    when 0x6A; cmdlen = 3; param[&#039;Response&#039;] = &#039;GetNext&#039;&lt;br /&gt;
    when 0x6C; cmdlen = 3 #Get All-Link Record for Sender&lt;br /&gt;
    when 0x57; cmdlen = 10; param[&#039;Response&#039;] = &#039;LnkData&#039;&lt;br /&gt;
    when 0x6F; cmdlen = 12; param[&#039;Response&#039;] = &#039;MngLnk&#039;&lt;br /&gt;
    when 0x67; cmdlen = 3; param[&#039;Response&#039;] = &#039;RstPLM&#039;&lt;br /&gt;
    when 0x6B; cmdlen = 4; param[&#039;Response&#039;] = &#039;SetCfg&#039;&lt;br /&gt;
    when 0x60; cmdlen = 9; param[&#039;Response&#039;] = &#039;GetVersion&#039;&lt;br /&gt;
    when 0x66; cmdlen = 6 #Set Host Device Category&lt;br /&gt;
    when 0x72; cmdlen = 3 # RF Sleep&lt;br /&gt;
    when 0x54; cmdlen = 3; param[&#039;Response&#039;] = &#039;BtnRpt&#039;&lt;br /&gt;
    when 0x6D; cmdlen = 3; param[&#039;Response&#039;] = &#039;LEDON&#039;&lt;br /&gt;
    when 0x6E; cmdlen = 3; param[&#039;Response&#039;] = &#039;LEDOFF&#039;&lt;br /&gt;
    else&lt;br /&gt;
&lt;br /&gt;
      log(&#039;ERROR IN PLMPARSE- Unknown Command&#039;)&lt;br /&gt;
      debug(value)&lt;br /&gt;
&lt;br /&gt;
      return &#039;&#039;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    #Now we know the length the command should be, see if we have it.&lt;br /&gt;
    #log(&#039;waiting for &#039; + cmdlen.to_s + &#039; characters...&#039;)&lt;br /&gt;
    #log(&#039;length of current input is &#039; + value.length.to_s)&lt;br /&gt;
    if value.length &amp;gt;= cmdlen&lt;br /&gt;
      #log(&#039;GOT whole response&#039;)&lt;br /&gt;
      #Yes, we have the whole command, Pack it in param&lt;br /&gt;
      for byt in 1..cmdlen&lt;br /&gt;
        param[&#039;Parameter&#039; + byt.to_s] = &amp;quot;%02X&amp;quot; %value[byt - 1]&lt;br /&gt;
      end&lt;br /&gt;
      #now remove it from the string..&lt;br /&gt;
      value = value.slice(cmdlen, value.length - cmdlen)&lt;br /&gt;
      #Send it off for parsing&lt;br /&gt;
      #log(&#039;Sending to EZToDCE:&#039; + param.inspect.to_s)&lt;br /&gt;
      EZToDCE(param)&lt;br /&gt;
    else&lt;br /&gt;
      #log(&#039;Still waiting...&#039;)&lt;br /&gt;
      #no, we have NOT received the whole command.&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  return value&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def rawX10(value)&lt;br /&gt;
&lt;br /&gt;
  x10MSN = $X10HouseCodes.index[value[0..0]]&lt;br /&gt;
  x10LSN = $X10UnitCodes.index[value[1..1]]&lt;br /&gt;
  return x10MSN + x10LSN&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def X10Flag(value)&lt;br /&gt;
  return + $X10CommandCodes.index[Value] + &#039;0&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def SndIns&lt;br /&gt;
  # create a new PLM command for SndIns&lt;br /&gt;
  if not $wAIT&lt;br /&gt;
    #log(&#039;SndIns:currentcmd=&#039; + $currentcmd.to_s)&lt;br /&gt;
&lt;br /&gt;
    if $cmdqueue.nitems &amp;gt; 0&lt;br /&gt;
      log(&amp;quot;SndIns:Queue:&amp;quot; + $aqua + $cmdqueue.nitems.to_s + $grey)&lt;br /&gt;
      #log(&#039;SndIns:&#039; + $cmdqueue.inspect)&lt;br /&gt;
      param = $cmdqueue[0]&lt;br /&gt;
      ### have to figure out the command byte 2 here&lt;br /&gt;
      work = &#039;02&#039;.hex.chr + plmcommand(param)&lt;br /&gt;
      ### PLM command compilation&lt;br /&gt;
      for loop in 2..param.keys.nitems&lt;br /&gt;
        @dummy = param[&#039;Parameter&#039; + (loop - 1).to_s].to_s&lt;br /&gt;
        work+= @dummy.hex.chr&lt;br /&gt;
      end&lt;br /&gt;
      conn_.Reconnect()&lt;br /&gt;
      debugout(work)&lt;br /&gt;
      conn_.Send(work)&lt;br /&gt;
      #sleep 0.1&lt;br /&gt;
      $wAIT = TRUE&lt;br /&gt;
    else&lt;br /&gt;
      log($yellow + &#039;Queue Empty.&#039; + $grey)&lt;br /&gt;
      if $rerun&lt;br /&gt;
        log(&#039;RERUN=TRUE, RESTARTING&#039;)&lt;br /&gt;
        $rerun = false&lt;br /&gt;
        mainRestart()&lt;br /&gt;
      else&lt;br /&gt;
        log(&#039;RERUN Not needed&#039;)&lt;br /&gt;
        if not $reported&lt;br /&gt;
          log(&#039;Reporting Child Devices&#039;)&lt;br /&gt;
          @work = &amp;quot;&amp;quot;&lt;br /&gt;
          $childdatabases.each{&lt;br /&gt;
            |insteonID,value|&lt;br /&gt;
            log(&#039;Child:&#039; + insteonID)&lt;br /&gt;
            log(&#039;Config:&#039; + value.inspect)&lt;br /&gt;
            @template = $devicetemplate[insteonID]&lt;br /&gt;
            @work += insteonID + &amp;quot;\t\t\t&amp;quot; + @template.to_s + &amp;quot;\t\n&amp;quot;&lt;br /&gt;
          }&lt;br /&gt;
          log(@work)&lt;br /&gt;
          cmd = Command.new(device_.devid_, -1001, 1, 2, 54)&lt;br /&gt;
          cmd.params_[13] = @work&lt;br /&gt;
          SendCommand(cmd)&lt;br /&gt;
&lt;br /&gt;
          $reported = true&lt;br /&gt;
        else&lt;br /&gt;
          log(&#039;report not needed&#039;)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    log(&#039;X-----------SndIns: Waiting for response to:&#039; + $cmdqueue[0][&#039;Command&#039;].to_s)&lt;br /&gt;
    log(&#039;X-----------SndIns: Current Queue Length:&#039; + $cmdqueue.nitems.to_s)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
def plmcommand(param)&lt;br /&gt;
  ### this returns the proper Byte2 for the command.&lt;br /&gt;
  case param[&#039;Command&#039;]&lt;br /&gt;
  when &#039;GetVersion&#039;; return 0x60.chr&lt;br /&gt;
  when &#039;SndIns&#039;; return 0x62.chr&lt;br /&gt;
  when &#039;SndGrp&#039;; return 0x61.chr&lt;br /&gt;
  when &#039;SndX10&#039;; return 0x63.chr&lt;br /&gt;
  when &#039;GetLnk&#039;; return 0x69.chr&lt;br /&gt;
  when &#039;GetNext&#039;; return 0x6A.chr&lt;br /&gt;
  when &#039;BtnRpt&#039;; return 0x54.chr&lt;br /&gt;
  when &#039;GetCfg&#039;; return 0x73.chr&lt;br /&gt;
  when &#039;StLnk&#039;; return 0x64.chr&lt;br /&gt;
  when &#039;CancelLnk&#039;; return 0x65.chr&lt;br /&gt;
  when &#039;MngLnk&#039;; return 0x6F.chr&lt;br /&gt;
  when &#039;RstPLM&#039;; return 0x67.chr&lt;br /&gt;
  when &#039;SetCfg&#039;; return 0x6B.chr&lt;br /&gt;
  when &#039;LEDON&#039;; return 0x6D.chr&lt;br /&gt;
  when &#039;LEDOFF&#039;; return 0x6E.chr&lt;br /&gt;
    ## hack&lt;br /&gt;
  when &#039;InsStdMsg&#039;&lt;br /&gt;
    log(&#039;ERROR:PLMCommand encountered a COMMAND of INSSTDMSG&#039;)&lt;br /&gt;
    break&lt;br /&gt;
    return 0x62.chr&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def debug(text)&lt;br /&gt;
  work = &#039;DEBUG:&#039;&lt;br /&gt;
&lt;br /&gt;
  for c in 1..text.length&lt;br /&gt;
    work += &amp;quot;%02X&amp;quot; %text[c-1] + &#039; &#039;&lt;br /&gt;
  end&lt;br /&gt;
  log($yellow + work + &amp;quot;Length:&amp;quot; + text.length.to_s + $grey)&lt;br /&gt;
end&lt;br /&gt;
def debugout(text)&lt;br /&gt;
  work = &#039;out:&#039;&lt;br /&gt;
&lt;br /&gt;
  for c in 1..text.length&lt;br /&gt;
    work += &amp;quot;%02X&amp;quot; %text[c-1] + &#039; &#039;&lt;br /&gt;
  end&lt;br /&gt;
  log($green + work + &amp;quot;Length:&amp;quot; + text.length.to_s + $grey)&lt;br /&gt;
end&lt;br /&gt;
def debugin(text)&lt;br /&gt;
  work = &#039;IN:&#039;&lt;br /&gt;
&lt;br /&gt;
  for c in 1..text.length&lt;br /&gt;
    work += &amp;quot;%02X&amp;quot; %text[c-1] + &#039; &#039;&lt;br /&gt;
  end&lt;br /&gt;
  log($red + work + &amp;quot;Length:&amp;quot; + text.length.to_s + $grey)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def padhex(hex)&lt;br /&gt;
  if hex.length==1&lt;br /&gt;
    hex = &amp;quot;0&amp;quot; + hex&lt;br /&gt;
  end&lt;br /&gt;
  return hex&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def percenttohex(level)&lt;br /&gt;
  # convert from percent to byte&lt;br /&gt;
  return &amp;quot;%X&amp;quot; %(level.to_i * 2.55).to_i&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def hextopercent(level)&lt;br /&gt;
  return (level.hex.to_i / 2.55).to_i&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def log(line)&lt;br /&gt;
  $log = File.open(&amp;quot;/var/log/pluto/&amp;quot; + device_.devid_.to_s + &amp;quot;_Generic_Serial_Device.log&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
  $log.puts &amp;quot;(***):&amp;quot; + line.to_s&lt;br /&gt;
  $log.close&lt;br /&gt;
end&lt;br /&gt;
def log2(line)&lt;br /&gt;
  #this will send a message out the the orbiters..&lt;br /&gt;
  #/usr/pluto/bin/MessageSend localhost 0 20 1 809 9 &amp;quot;Text to Display&amp;quot; 70 &amp;quot;alert&amp;quot; 182 &amp;quot;30&amp;quot; 251 &amp;quot;??&amp;quot;&lt;br /&gt;
  cmd = Command.new(device_.devid_, -1000, 1, 1, 809)&lt;br /&gt;
  cmd.params_[9] = line #text to display&lt;br /&gt;
  cmd.params_[70] = &#039;PLMMessage&#039; #Token&lt;br /&gt;
  cmd.params_[182] = &#039;10&#039; #Timeout in seconds&lt;br /&gt;
  cmd.params_[251] = &#039;??&#039;&lt;br /&gt;
  SendCommand(cmd)&lt;br /&gt;
end&lt;br /&gt;
def checkChildRecordsinPLM()&lt;br /&gt;
  log(&#039;Entered CheckChildRecordsinPLM&#039;)&lt;br /&gt;
  # log(&#039;In CheckChildRecordsinPLM&#039;)&lt;br /&gt;
  # time to verify all children are in the PLM&lt;br /&gt;
  #&lt;br /&gt;
  # log(&#039;Total PLM Records:&#039; + $plmdatabase.nitems.to_s)&lt;br /&gt;
  $plmdatabase.each{|record|&lt;br /&gt;
    log(&#039;Record: = &#039;+ getIIDfromRecord(record) + &#039; Group:&#039; + getGroupfromRecord(record))&lt;br /&gt;
    log(&#039;checking to see if it needs to be added as a child...&#039;)&lt;br /&gt;
    if not existsinchild(getIIDfromRecord(record))&lt;br /&gt;
        &lt;br /&gt;
      log(getIIDfromRecord(record) + &#039; needs to be added to the child database&#039;)&lt;br /&gt;
      addtochild(getIIDfromRecord(record))&lt;br /&gt;
    end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  $childdatabases.each {|child,value|&lt;br /&gt;
    if not existsinplm(child)&lt;br /&gt;
      log(child + &#039; needs to be added to PLM&#039;)&lt;br /&gt;
      sendAddtoPLM(child)&lt;br /&gt;
    else&lt;br /&gt;
      log(child + &#039; exists in PLM&#039;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    #now to scan the childs database&lt;br /&gt;
    for record in 1..(value.nitems - 1)&lt;br /&gt;
      @test = value[record]&lt;br /&gt;
      if not existsinplm(getIIDfromRecord(@test))&lt;br /&gt;
        log(getIIDfromRecord(@test) + &#039; needs to be added to PLM&#039;)&lt;br /&gt;
        sendAddtoPLM(getIIDfromRecord(@test))&lt;br /&gt;
      else&lt;br /&gt;
        log(getIIDfromRecord(@test) + &#039; exists in PLM&#039;)&lt;br /&gt;
      end&lt;br /&gt;
      #Also check to see if it needs to be added in the childdatabases&lt;br /&gt;
    end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
def existsinplm(insteonid)&lt;br /&gt;
  result = false&lt;br /&gt;
  $plmdatabase.each{|record|&lt;br /&gt;
    #log(insteonid + &#039;==&#039; + getIIDfromRecord(record))&lt;br /&gt;
    if insteonid == getIIDfromRecord(record)&lt;br /&gt;
      result = true&lt;br /&gt;
    end&lt;br /&gt;
  }&lt;br /&gt;
  return result&lt;br /&gt;
end&lt;br /&gt;
def existsinchild(insteonid)&lt;br /&gt;
  log(&#039;ExistsinChild:InsteonID:&#039; + insteonid)&lt;br /&gt;
  result = $childdatabases.keys.include?(insteonid)&lt;br /&gt;
  log(&#039;ExistsinChild result:FALSE&#039;) if not result&lt;br /&gt;
  log(&#039;ExistsinChild result:TRUE&#039;) if result&lt;br /&gt;
  return result&lt;br /&gt;
end&lt;br /&gt;
def addtochild(insteonID)&lt;br /&gt;
  log(&#039;addtochild Routne called&#039;)&lt;br /&gt;
  log(&#039;Adding &#039; + insteonID + &#039; to the child database...&#039;)&lt;br /&gt;
  if insteonID.length == 2 then&lt;br /&gt;
    log(&#039;Child is X10&#039;)&lt;br /&gt;
    $state[insteonID] = 0&lt;br /&gt;
  else&lt;br /&gt;
    log(&#039;Child is Insteon&#039;)&lt;br /&gt;
    $childdatabases[insteonID] = [&#039;****************&#039;]&lt;br /&gt;
    sendPing(insteonID)&lt;br /&gt;
    $rerun = true&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
def removefromchild(insteonID)&lt;br /&gt;
  log(&#039;Removing &#039; + insteonID + &#039; from child database&#039;)&lt;br /&gt;
  $childdatabases.delete(insteonID)&lt;br /&gt;
  $state.delete(insteonID)&lt;br /&gt;
end&lt;br /&gt;
def removefromplm(insteonID)&lt;br /&gt;
  log(&#039;Removing from plm&#039;)&lt;br /&gt;
  $plmdatabase.each{|record|&lt;br /&gt;
    #log(insteonid + &#039;==&#039; + getIIDfromRecord(record))&lt;br /&gt;
    if insteonID == getIIDfromRecord(record)&lt;br /&gt;
      debug(record)&lt;br /&gt;
      log(&#039;Found Record, Deleting&#039;)&lt;br /&gt;
      $plmdatabase.delete(record)&lt;br /&gt;
      &lt;br /&gt;
      #now, we have to remove it from the device.&lt;br /&gt;
      param = {&#039;Command&#039; =&amp;gt;&#039;MngLnk&#039;,&lt;br /&gt;
        &#039;Parameter1&#039; =&amp;gt; &#039;80&#039;, #DELETE&lt;br /&gt;
        &#039;Parameter2&#039; =&amp;gt; record[0..1], #control byte&lt;br /&gt;
        &#039;Parameter3&#039; =&amp;gt; record[2..3], #group&lt;br /&gt;
        &#039;Parameter4&#039; =&amp;gt; record[4..5],#HB&lt;br /&gt;
        &#039;Parameter5&#039; =&amp;gt; record[6..7],#MB&lt;br /&gt;
        &#039;Parameter6&#039; =&amp;gt; record[8..9],#LB&lt;br /&gt;
        &#039;Parameter7&#039; =&amp;gt; record[10..11],#data1&lt;br /&gt;
        &#039;Parameter8&#039; =&amp;gt; record[12..13],#data2&lt;br /&gt;
        &#039;Parameter9&#039; =&amp;gt; record[14..15] #data3&lt;br /&gt;
        &lt;br /&gt;
      }&lt;br /&gt;
      log(param.inspect)&lt;br /&gt;
      $cmdqueue &amp;lt;&amp;lt; param&lt;br /&gt;
    end&lt;br /&gt;
  }&lt;br /&gt;
end&lt;br /&gt;
def sendAddtoPLM(insteonID)&lt;br /&gt;
  log(&#039;Adding &#039; + insteonID + &#039; to the PLM database...&#039;)&lt;br /&gt;
  #This adds a record into the PLM&lt;br /&gt;
  @insID = insteonID.split(&#039;.&#039;)&lt;br /&gt;
  param = {&#039;Command&#039; =&amp;gt; &#039;MngLnk&#039;,&lt;br /&gt;
    &#039;Parameter1&#039; =&amp;gt; &#039;40&#039;, #control code -- add new record as Controller&lt;br /&gt;
    &#039;Parameter2&#039; =&amp;gt; &#039;C2&#039;, #All Link Record Flags AKA Record Control Byte&lt;br /&gt;
    &#039;Parameter3&#039; =&amp;gt; &#039;01&#039;, #All Link Group&lt;br /&gt;
    &#039;Parameter4&#039; =&amp;gt; @insID[0], #HB&lt;br /&gt;
    &#039;Parameter5&#039; =&amp;gt; @insID[1], #MB&lt;br /&gt;
    &#039;Parameter6&#039; =&amp;gt; @insID[2], #LB&lt;br /&gt;
    &#039;Parameter7&#039; =&amp;gt; &#039;01&#039;, #Link Data 1 ON-Level&lt;br /&gt;
    &#039;Parameter8&#039; =&amp;gt; &#039;01&#039;, #Link Data 2 Ramp Rate&lt;br /&gt;
    &#039;Parameter9&#039; =&amp;gt; &#039;FF&#039;} #Link Data 3 not used&lt;br /&gt;
  if $wAIT&lt;br /&gt;
    $cmdqueue.insert(1, param)&lt;br /&gt;
  else&lt;br /&gt;
    $cmdqueue.insert(0, param)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  SndIns()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def getIIDfromRecord(recordstring)&lt;br /&gt;
  #this extracts the insteonID string from the record.&lt;br /&gt;
  #log(&#039;getIIDfromRecord::recordstring:&#039; + recordstring)&lt;br /&gt;
  @idhb = recordstring[4..5]&lt;br /&gt;
  @idmb = recordstring[6..7]&lt;br /&gt;
  @idlb = recordstring[8..9]&lt;br /&gt;
  @result = @idhb + &#039;.&#039; + @idmb + &#039;.&#039; +@idlb&lt;br /&gt;
  #log(&#039;GetIIDfromRecord: Found ID:&#039; + @result)&lt;br /&gt;
  return @result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def processBroadcastMessage(param)&lt;br /&gt;
  #search the child databases for responders,&lt;br /&gt;
  #and fire COMMANDS for each responder. 06Feb08&lt;br /&gt;
  #and fire events for each responder.XXXXXXXXXXXXX&lt;br /&gt;
  #Message flag is in parameter9 Group command 0xCx (All-Link Broadcast Message Pg 42.)&lt;br /&gt;
  #Group is in parameter8&lt;br /&gt;
  #From InsteonID is parameters 3, 4, 5&lt;br /&gt;
  group = param[&#039;Parameter8&#039;]&lt;br /&gt;
  from = padhex(param[&#039;Parameter3&#039;]) + &#039;.&#039;&lt;br /&gt;
  from += padhex(param[&#039;Parameter4&#039;]) + &#039;.&#039;&lt;br /&gt;
  from += padhex(param[&#039;Parameter5&#039;])&lt;br /&gt;
  log(&#039;Looking for &#039; + from + &#039; Group:&#039; + group)&lt;br /&gt;
  #Ok, now have to search child databases for from AND group AND responder&lt;br /&gt;
  $childdatabases.each{|child,value|&lt;br /&gt;
    #log(&#039;Searching:&#039; + child)&lt;br /&gt;
    for rec in 1..(value.nitems - 1)&lt;br /&gt;
      record = value[rec]&lt;br /&gt;
      if getIIDfromRecord(record) == from # First, look for Insteon ID&lt;br /&gt;
        #log(&#039;Found ID&#039;)&lt;br /&gt;
        if getGroupfromRecord(record) == group #next, Group&lt;br /&gt;
          #log(&#039;Found Group&#039;)&lt;br /&gt;
          if isResponderRecord(record) # is a responder?&lt;br /&gt;
            #log(&#039;Found Responder&#039;)&lt;br /&gt;
            #figure out the child devicenum&lt;br /&gt;
            from = $children[child]&lt;br /&gt;
            #figure out the command&lt;br /&gt;
            case param[&#039;Parameter10&#039;].hex&lt;br /&gt;
            when 0x11 #on&lt;br /&gt;
              reportStatus(from, 100)&lt;br /&gt;
            when 0x13 #off&lt;br /&gt;
              reportStatus(from, 0)&lt;br /&gt;
            when 0x17 #dim/brighten -ignore&lt;br /&gt;
              level = 0&lt;br /&gt;
            when 0x18 # STOP dim/brighten - sendgetstatus&lt;br /&gt;
              level = 0&lt;br /&gt;
              sendGetChildStatus(child)&lt;br /&gt;
            else&lt;br /&gt;
              level = 0&lt;br /&gt;
              log(&#039;Command is other than ON/OFF/Dim/Brighten&#039;)&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  }&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def reportStatus(from, level)&lt;br /&gt;
  log(&#039;From:&#039; + from.to_s)&lt;br /&gt;
  log(&#039;current State:&#039; + $state[from].to_s)&lt;br /&gt;
  log(&#039;Wanted State:&#039; + level.to_s)&lt;br /&gt;
  case $state[from]&lt;br /&gt;
  when 0&lt;br /&gt;
    if level &amp;gt;=1&lt;br /&gt;
      cmd = Command.new(from, from, 1, 1, 192) #on&lt;br /&gt;
      cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
      SendCommand(cmd)&lt;br /&gt;
      cmd = Command.new(from, from, 1, 1, 184)&lt;br /&gt;
      cmd.params_[76] = level.to_s&lt;br /&gt;
      cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
      SendCommand(cmd)&lt;br /&gt;
    end&lt;br /&gt;
  when 100&lt;br /&gt;
    if level &amp;gt;= 1&lt;br /&gt;
      cmd = Command.new(from, from, 1, 1, 184)&lt;br /&gt;
      cmd.params_[76] = level.to_s&lt;br /&gt;
      cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
      SendCommand(cmd)&lt;br /&gt;
    else&lt;br /&gt;
      cmd = Command.new(from, from, 1, 1, 193) # off&lt;br /&gt;
      cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
      SendCommand(cmd)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if level == 100&lt;br /&gt;
      cmd = Command.new(from, from, 1, 1, 193) #off&lt;br /&gt;
      cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
      SendCommand(cmd)&lt;br /&gt;
      cmd = Command.new(from, from, 1, 1, 192) # on&lt;br /&gt;
      cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
      SendCommand(cmd)&lt;br /&gt;
    end&lt;br /&gt;
    cmd = Command.new(from, from, 1, 1, 184) #SetLevel&lt;br /&gt;
    cmd.params_[76] = level.to_s&lt;br /&gt;
    cmd.params_[120] = &amp;quot;1&amp;quot;&lt;br /&gt;
    SendCommand(cmd)&lt;br /&gt;
  end&lt;br /&gt;
  log(&#039;ReportStatus: device:&#039; + from.to_s + &#039; Status:&#039; + level.to_s)&lt;br /&gt;
  $state[from] = level&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def isResponderRecord(recordstring)&lt;br /&gt;
  work = recordstring[0..1].hex&lt;br /&gt;
  if (work &amp;amp; 0x40) == 0x40 #check bit 6&lt;br /&gt;
    result = false #signifies Controller record&lt;br /&gt;
  else&lt;br /&gt;
    result = true #signifies Responder record&lt;br /&gt;
  end&lt;br /&gt;
  return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def getGroupfromRecord(recordstring)&lt;br /&gt;
  #this extracts the GROUP from the record.&lt;br /&gt;
  if recordstring == nil&lt;br /&gt;
    return &#039;00&#039;&lt;br /&gt;
  else&lt;br /&gt;
    return recordstring[2..3]&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
def getdeltafromconfig(insteonID)&lt;br /&gt;
  #This returns the delta from the child.&lt;br /&gt;
  @work = $childdatabases[insteonID][0] # the settings stored in [0]&lt;br /&gt;
  if @work == nil&lt;br /&gt;
    return &#039;00&#039;&lt;br /&gt;
  else&lt;br /&gt;
    return @work[6..7]&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
def sendGetChildStatus(insteonID)&lt;br /&gt;
  #log(&#039;sendGetChildStatus Called&#039;)&lt;br /&gt;
  if insteonID.length != 2 #X10 device&lt;br /&gt;
    @insID = insteonID.split(&#039;.&#039;)&lt;br /&gt;
    param = {&#039;Command&#039; =&amp;gt; &#039;SndIns&#039;,&lt;br /&gt;
      &#039;Parameter1&#039; =&amp;gt; @insID[0],&lt;br /&gt;
      &#039;Parameter2&#039; =&amp;gt; @insID[1],&lt;br /&gt;
      &#039;Parameter3&#039; =&amp;gt; @insID[2],&lt;br /&gt;
      &#039;Parameter4&#039; =&amp;gt; &#039;0F&#039;, #flags&lt;br /&gt;
      &#039;Parameter5&#039; =&amp;gt; &#039;19&#039;, #Status Request&lt;br /&gt;
      &#039;Parameter6&#039; =&amp;gt; &#039;00&#039;} #not used.&lt;br /&gt;
    $cmdqueue &amp;lt;&amp;lt; param&lt;br /&gt;
    SndIns()&lt;br /&gt;
    #Returned response will have cmd1 = DBDelta&lt;br /&gt;
    #Returned response will have cmd2 = ON-Level&lt;br /&gt;
  else&lt;br /&gt;
    log(&#039;X10 does not report status&#039;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# time to define a structure to save the raw data in hex&lt;br /&gt;
# starts at [0]&lt;br /&gt;
# Bytes Meaning&lt;br /&gt;
# 0-1 Device Category&lt;br /&gt;
# 2-3 Device SubCategory&lt;br /&gt;
# 4-5 Device Firmware&lt;br /&gt;
# 6-7 Database Delta&lt;br /&gt;
# 8-9 reserved&lt;br /&gt;
# 10-11 reserved&lt;br /&gt;
# 12-13 reserved&lt;br /&gt;
# 14-15 reserved&lt;br /&gt;
###### First database record below (in same format its read from the device)&lt;br /&gt;
###### This is the same format as an ALL-Link Record Response from the PLM&lt;br /&gt;
###### (0x57) bytes 3..10&lt;br /&gt;
# 16-17 record control byte&lt;br /&gt;
# 18-19 Group&lt;br /&gt;
# 20-21 ID HB&lt;br /&gt;
# 22-23 ID MB&lt;br /&gt;
# 24-25 ID LB&lt;br /&gt;
# 26-27 Link Specific Data1&lt;br /&gt;
# 28-29 Link Specific Data2&lt;br /&gt;
# 30-31 Link Specific Data3&lt;br /&gt;
######&lt;br /&gt;
# 32-47 next database record...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Newacct</name></author>
	</entry>
	<entry>
		<id>http://wiki.linuxmce.org/index.php?title=D-Link_DCS-5300G&amp;diff=22182</id>
		<title>D-Link DCS-5300G</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxmce.org/index.php?title=D-Link_DCS-5300G&amp;diff=22182"/>
		<updated>2010-01-27T08:47:39Z</updated>

		<summary type="html">&lt;p&gt;Newacct: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: Cameras]]&lt;br /&gt;
[[Category: IP Cameras]]&lt;br /&gt;
&lt;br /&gt;
[[Image:D-link-dcs-5300g.jpg|right]]&lt;br /&gt;
[[Image:DCS-70.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
= Status =&lt;br /&gt;
The D-Link DCS-5300G device template can be derived from the Panasonic IP Camera. A initial version can be found in the testing sqlCVS repository. It is fully plug and play and supports pan and tilt.&lt;br /&gt;
&lt;br /&gt;
= Features =&lt;br /&gt;
* Browser based&lt;br /&gt;
* PAN Range +/- 135°, TILT Range +90°/ -45°&lt;br /&gt;
* 802.11g WLAN (2 antennas with RP-SMA connector)&lt;br /&gt;
* 10/100mbit LAN&lt;br /&gt;
* 2x I/O Port, 1x Sensor Input, 1x Relay Output&lt;br /&gt;
* 1x mic input, 1x A/V Connector&lt;br /&gt;
* 30fps max&lt;br /&gt;
* active motion detector&lt;br /&gt;
* MPEG4 compression&lt;br /&gt;
* UPnP, DynDNS&lt;br /&gt;
* Real-Time Live Video &amp;amp; Audio Streaming&lt;br /&gt;
* compatible with DCS-70 outdoor mount&lt;br /&gt;
&lt;br /&gt;
= Ruby Code =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RCODE:&lt;br /&gt;
   0:require &#039;Ruby_Generic_Serial_Device&#039;&lt;br /&gt;
   1:class Command &amp;lt; Ruby_Generic_Serial_Device::RubyCommandWrapper&lt;br /&gt;
   2:end&lt;br /&gt;
   3:class Device_95 &amp;lt; Ruby_Generic_Serial_Device::RubySerialIOWrapper&lt;br /&gt;
   4:#### 84 ####################################################################&lt;br /&gt;
   5:def cmd_84(data, format, disable_aspect_lock, streamid, width, height, cmd=nil)&lt;br /&gt;
   6:@returnParamArray.clear&lt;br /&gt;
   7:conn_.Reconnect()&lt;br /&gt;
   8:auth_s=device_.devdata_[114]+&amp;quot;:&amp;quot;+device_.devdata_[115]&lt;br /&gt;
   9:auth_a=Array.new;&lt;br /&gt;
  10:auth_s.each{|c| auth_a.push(c)}&lt;br /&gt;
  11:&lt;br /&gt;
  12:fix_path=device_.devdata_[2]&lt;br /&gt;
  13:fix_path=&#039;/&#039;+fix_path if fix_path[0]!=&#039;/&#039;[0]&lt;br /&gt;
  14:&lt;br /&gt;
  15:s = &amp;quot;GET &amp;quot;+fix_path+&amp;quot; HTTP/1.0\r\n&amp;quot;&lt;br /&gt;
  16:s+= &amp;quot;Accept: */*\r\n&amp;quot;&lt;br /&gt;
  17:s+= &amp;quot;Authorization: Basic &amp;quot;+auth_a.pack(&amp;quot;m&amp;quot;).chop+&amp;quot;\r\n&amp;quot;&lt;br /&gt;
  18:s+= &amp;quot;\r\n&amp;quot;&lt;br /&gt;
  19:&lt;br /&gt;
  20:conn_.Send(s)&lt;br /&gt;
  21:recv=&amp;quot;&amp;quot;&lt;br /&gt;
  22:loop do&lt;br /&gt;
  23:  buff=conn_.Recv(16384, 5000)&lt;br /&gt;
  24:  if buff.empty?&lt;br /&gt;
  25:    break&lt;br /&gt;
  26:  end&lt;br /&gt;
  27:  recv += buff&lt;br /&gt;
  28:end&lt;br /&gt;
  29:if recv=~ /^HTTP[^\r\n]+200\sOK.+?\r\n\r\n(.+)$/m&lt;br /&gt;
  30:  fileName=&amp;quot;/tmp/ip_camera_img&amp;quot;+device_.devid_.to_s&lt;br /&gt;
  31:  imageFile=File.new(fileName+&amp;quot;.jpg&amp;quot;,&#039;w&#039;)&lt;br /&gt;
  32:  imageFile.print $1&lt;br /&gt;
  33:  imageFile.close()&lt;br /&gt;
  34:  system(&amp;quot;/usr/bin/convert &amp;quot;+fileName+&amp;quot;.jpg &amp;quot;+fileName+&amp;quot;.png&amp;quot;);&lt;br /&gt;
  35:  size=File.stat(fileName+&amp;quot;.png&amp;quot;).size &lt;br /&gt;
  36:  imageFile=File.new(fileName+&amp;quot;.png&amp;quot;,&#039;r&#039;)&lt;br /&gt;
  37:  img = imageFile.read(size);&lt;br /&gt;
  38:  imageFile.close()&lt;br /&gt;
  39:  data_set(img)&lt;br /&gt;
  40:  format_set(&#039;png&#039;)&lt;br /&gt;
  41:end&lt;br /&gt;
  42:return @returnParamArray&lt;br /&gt;
  43:end&lt;br /&gt;
  44:#### 200 ####################################################################&lt;br /&gt;
  45:def cmd_200(cmd=nil)&lt;br /&gt;
  46:@returnParamArray.clear&lt;br /&gt;
  47:conn_.Reconnect()&lt;br /&gt;
  48:auth_s=device_.devdata_[114]+&amp;quot;:&amp;quot;+device_.devdata_[115]&lt;br /&gt;
  49:auth_a=Array.new;&lt;br /&gt;
  50:auth_s.each{|c| auth_a.push(c)}&lt;br /&gt;
  51:s = &amp;quot;GET /cgi-bin/camctrl.cgi?move=up HTTP/1.0\r\n&amp;quot;&lt;br /&gt;
  52:s+= &amp;quot;Accept: */*\r\n&amp;quot;&lt;br /&gt;
  53:s+= &amp;quot;Authorization: Basic &amp;quot;+auth_a.pack(&amp;quot;m&amp;quot;).chop+&amp;quot;\r\n&amp;quot;&lt;br /&gt;
  54:s+= &amp;quot;\r\n&amp;quot;&lt;br /&gt;
  55:&lt;br /&gt;
  56:conn_.Send(s)&lt;br /&gt;
  57:recv=&amp;quot;&amp;quot;&lt;br /&gt;
  58:loop do&lt;br /&gt;
  59:buff=conn_.Recv(256, 5000)&lt;br /&gt;
  60:if buff.empty?&lt;br /&gt;
  61:break&lt;br /&gt;
  62:end&lt;br /&gt;
  63:recv += buff&lt;br /&gt;
  64:end&lt;br /&gt;
  65:return @returnParamArray&lt;br /&gt;
  66:end&lt;br /&gt;
  67:#### 201 ####################################################################&lt;br /&gt;
  68:def cmd_201(cmd=nil)&lt;br /&gt;
  69:@returnParamArray.clear&lt;br /&gt;
  70:conn_.Reconnect()&lt;br /&gt;
  71:auth_s=device_.devdata_[114]+&amp;quot;:&amp;quot;+device_.devdata_[115]&lt;br /&gt;
  72:auth_a=Array.new;&lt;br /&gt;
  73:auth_s.each{|c| auth_a.push(c)}&lt;br /&gt;
  74:s = &amp;quot;GET /cgi-bin/camctrl.cgi?move=down HTTP/1.0\r\n&amp;quot;&lt;br /&gt;
  75:s+= &amp;quot;Accept: */*\r\n&amp;quot;&lt;br /&gt;
  76:s+= &amp;quot;Authorization: Basic &amp;quot;+auth_a.pack(&amp;quot;m&amp;quot;).chop+&amp;quot;\r\n&amp;quot;&lt;br /&gt;
  77:s+= &amp;quot;\r\n&amp;quot;&lt;br /&gt;
  78:&lt;br /&gt;
  79:conn_.Send(s)&lt;br /&gt;
  80:recv=&amp;quot;&amp;quot;&lt;br /&gt;
  81:loop do&lt;br /&gt;
  82:buff=conn_.Recv(256, 5000)&lt;br /&gt;
  83:if buff.empty?&lt;br /&gt;
  84:break&lt;br /&gt;
  85:end&lt;br /&gt;
  86:recv += buff&lt;br /&gt;
  87:end&lt;br /&gt;
  88:return @returnParamArray&lt;br /&gt;
  89:end&lt;br /&gt;
  90:#### 202 ####################################################################&lt;br /&gt;
  91:def cmd_202(cmd=nil)&lt;br /&gt;
  92:@returnParamArray.clear&lt;br /&gt;
  93:conn_.Reconnect()&lt;br /&gt;
  94:auth_s=device_.devdata_[114]+&amp;quot;:&amp;quot;+device_.devdata_[115]&lt;br /&gt;
  95:auth_a=Array.new;&lt;br /&gt;
  96:auth_s.each{|c| auth_a.push(c)}&lt;br /&gt;
  97:s = &amp;quot;GET /cgi-bin/camctrl.cgi?move=left HTTP/1.0\r\n&amp;quot;&lt;br /&gt;
  98:s+= &amp;quot;Accept: */*\r\n&amp;quot;&lt;br /&gt;
  99:s+= &amp;quot;Authorization: Basic &amp;quot;+auth_a.pack(&amp;quot;m&amp;quot;).chop+&amp;quot;\r\n&amp;quot;&lt;br /&gt;
 100:s+= &amp;quot;\r\n&amp;quot;&lt;br /&gt;
 101:&lt;br /&gt;
 102:conn_.Send(s)&lt;br /&gt;
 103:recv=&amp;quot;&amp;quot;&lt;br /&gt;
 104:loop do&lt;br /&gt;
 105:buff=conn_.Recv(256, 5000)&lt;br /&gt;
 106:if buff.empty?&lt;br /&gt;
 107:break&lt;br /&gt;
 108:end&lt;br /&gt;
 109:recv += buff&lt;br /&gt;
 110:end&lt;br /&gt;
 111:return @returnParamArray&lt;br /&gt;
 112:end&lt;br /&gt;
 113:#### 203 ####################################################################&lt;br /&gt;
 114:def cmd_203(cmd=nil)&lt;br /&gt;
 115:@returnParamArray.clear&lt;br /&gt;
 116:conn_.Reconnect()&lt;br /&gt;
 117:auth_s=device_.devdata_[114]+&amp;quot;:&amp;quot;+device_.devdata_[115]&lt;br /&gt;
 118:auth_a=Array.new;&lt;br /&gt;
 119:auth_s.each{|c| auth_a.push(c)}&lt;br /&gt;
 120:s = &amp;quot;GET /cgi-bin/camctrl.cgi?move=right HTTP/1.0\r\n&amp;quot;&lt;br /&gt;
 121:s+= &amp;quot;Accept: */*\r\n&amp;quot;&lt;br /&gt;
 122:s+= &amp;quot;Authorization: Basic &amp;quot;+auth_a.pack(&amp;quot;m&amp;quot;).chop+&amp;quot;\r\n&amp;quot;&lt;br /&gt;
 123:s+= &amp;quot;\r\n&amp;quot;&lt;br /&gt;
 124:&lt;br /&gt;
 125:conn_.Send(s)&lt;br /&gt;
 126:recv=&amp;quot;&amp;quot;&lt;br /&gt;
 127:loop do&lt;br /&gt;
 128:  buff=conn_.Recv(256, 5000)&lt;br /&gt;
 129:  if buff.empty?&lt;br /&gt;
 130:    break&lt;br /&gt;
 131:  end&lt;br /&gt;
 132:  recv += buff&lt;br /&gt;
 133:end&lt;br /&gt;
 134:return @returnParamArray&lt;br /&gt;
 135:end&lt;br /&gt;
 136:#### START SETTERS ####################################################################&lt;br /&gt;
 137:def initialize()&lt;br /&gt;
 138:super&lt;br /&gt;
 139:@returnParamArray=Array.new&lt;br /&gt;
 140:end&lt;br /&gt;
 141:def data_set(value)&lt;br /&gt;
 142:@returnParamArray[19]=value&lt;br /&gt;
 143:end&lt;br /&gt;
 144:def format_set(value)&lt;br /&gt;
 145:@returnParamArray[20]=value&lt;br /&gt;
 146:end&lt;br /&gt;
 147:####  END  SETTERS ####################################################################&lt;br /&gt;
 148:end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Newacct</name></author>
	</entry>
	<entry>
		<id>http://wiki.linuxmce.org/index.php?title=Generic_Serial_Device&amp;diff=22181</id>
		<title>Generic Serial Device</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxmce.org/index.php?title=Generic_Serial_Device&amp;diff=22181"/>
		<updated>2010-01-27T08:44:25Z</updated>

		<summary type="html">&lt;p&gt;Newacct: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;br /&gt;
  | __TOC__&lt;br /&gt;
  |}&lt;br /&gt;
[[Category: Programmer&#039;s Guide]]&lt;br /&gt;
[[Category: Serial]]&lt;br /&gt;
[[Category: GSD]]&lt;br /&gt;
&lt;br /&gt;
Generic_Serial_Device (also known as &#039;&#039;&#039;GSD&#039;&#039;&#039;) is a LinuxMCE device that allows end-user to do simple programming for RS232, serial USB (See [[Serial Hack]] for details on getting USB to serial adapters identified properly in the admin panel!) or network connected devices.&lt;br /&gt;
:Note : The information is not quite complete because I&#039;m not the original author.&lt;br /&gt;
&lt;br /&gt;
== Short description ==&lt;br /&gt;
It&#039;s a standard DCE device, it only can execute commands and send events .&lt;br /&gt;
The main idea is instead of programming a device in C++, compile, link with proper libraries you can edit (in a webpage) few lines of code in ruby which will be executed when device receives that command. It exports several objects into ruby so you&#039;ll have access to devicedata, device hierarchy, established connection and so on.&lt;br /&gt;
&lt;br /&gt;
The ruby code for each device template is stored somewhere in &#039;&#039;InfraredGroup_Command&#039;&#039; table. To edit the code go to Wizard&amp;gt; Devices &amp;gt; Generic_Serial_Devices on [[LinuxMCE-admin]] website. You have to add a device from a device template in order to see anything in that page.&lt;br /&gt;
&lt;br /&gt;
Select the device, and click &amp;quot;RubyCodes&amp;quot; button to be able to edit code that will be executed. &lt;br /&gt;
You should be able to see commands that are specified in device template (like ON/OFF/WhateverElse) and a group of &#039;&#039;Internal Commands&#039;&#039; which are used to perform certain actions are to add helper functions.&lt;br /&gt;
&lt;br /&gt;
If the command you are trying to add doesn&#039;t show on first page, go to &#039;&#039;Add/Remove commands&#039;&#039; and add more commands for your device.&lt;br /&gt;
&lt;br /&gt;
=== Ruby source code ===&lt;br /&gt;
&lt;br /&gt;
There are 2 forms of ruby code you can write :&lt;br /&gt;
* standard ruby code (check [http://www.ruby-lang.org/en/] and [http://poignantguide.net/ruby/] for syntax, references and programming guides)&lt;br /&gt;
* short form for &#039;&#039;&#039;conn_.Send&#039;&#039;&#039;&lt;br /&gt;
 &amp;lt;$&amp;quot;PWON\r&amp;quot;$&amp;gt;&lt;br /&gt;
:which simply will send the string &#039;&#039;&amp;quot;PWON\r&amp;quot;&#039;&#039; to device.&lt;br /&gt;
&lt;br /&gt;
You&#039;ll have to quick reload router to get new code. Restarting GSD only will keep old code because the code is supplied by [[Infrared_Plugin]] which caches pluto_main and won&#039;t update it&#039;s cache without full restart of [[DCERouter]]. With this code it creates a ruby source which will be interpreted by embedded ruby.&lt;br /&gt;
&lt;br /&gt;
It will create methods called &amp;quot;cmd_CmdIDx&amp;quot; for each command(x) defined in web interface except &#039;&#039;Private_Method_Listing&#039;&#039; which will be inserted in the body of the class directly without wrapping.&lt;br /&gt;
&lt;br /&gt;
The source usually looks like (&#039;&#039;DevID&#039;&#039; is iPK_Device of specific device, &#039;&#039;CmdIDx&#039;&#039; is iPK_Command ) :&lt;br /&gt;
&lt;br /&gt;
 require &#039;Ruby_Generic_Serial_Device&#039;&lt;br /&gt;
 class Command &amp;lt; Ruby_Generic_Serial_Device::RubyCommandWrapper&lt;br /&gt;
 end&lt;br /&gt;
 class Device_DevID &amp;lt; Ruby_Generic_Serial_Device::RubySerialWrapper&lt;br /&gt;
 def cmd_CmdID1(paramlist)&lt;br /&gt;
     @returnParamArray.clear&lt;br /&gt;
     ### WEB CODE for CmdID1 GOES HERE ###&lt;br /&gt;
     return @returnParamArray&lt;br /&gt;
 end&lt;br /&gt;
 def cmd_CmdID2(paramlist)&lt;br /&gt;
     @returnParamArray.clear&lt;br /&gt;
     ### WEB CODE for CmdID2 GOES HERE ###&lt;br /&gt;
     return @returnParamArray&lt;br /&gt;
 end&lt;br /&gt;
 ...&lt;br /&gt;
 def cmd_ReceiveCommandForChild(cmd)&lt;br /&gt;
     ### Process_Receive Command_For_Child GOES HERE ###&lt;br /&gt;
 end&lt;br /&gt;
 ...&lt;br /&gt;
 ### Private_Method_Listing GOES HERE ###&lt;br /&gt;
 ...&lt;br /&gt;
 def initialize()&lt;br /&gt;
     super&lt;br /&gt;
     @returnParamArray=Array.new&lt;br /&gt;
 end&lt;br /&gt;
 ### Generated Setters/Getters goes here (may be empty, but usually looks like below) ###&lt;br /&gt;
 def data_set(value)&lt;br /&gt;
     @returnParamArray[19]=value&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
There might be more then one class definition in that source. This may happen when child device is itself a GSD device.&lt;br /&gt;
&lt;br /&gt;
=== Command details ===&lt;br /&gt;
When the command from DCE arrives it is routed to specific device and &#039;&#039;cmd_XXX&#039;&#039; is run. The commands are run one by one, meaning that you cannot run 2 commands simultaneously. This limitation is implied by embedded ruby interpretor which fails if run from multiple threads.&lt;br /&gt;
DCE commands may have return parameters (well known GetVideoFrame), as ruby can return only 1 parameter the &#039;&#039;@returnParamArray&#039;&#039; was added. You can see that in each method we insert &#039;&#039;&#039;@returnParamArray.clear&#039;&#039;&#039; then the real code and then &#039;&#039;&#039;return @returnParamArray&#039;&#039;&#039;. Also some setters are generated (like the one from above) for code readability.&lt;br /&gt;
&lt;br /&gt;
Beside usual DCE command you&#039;ll see some &#039;&#039;Internal Commands&#039;&#039;. Here goes a small list and what they do:&lt;br /&gt;
* &#039;&#039;&#039;Private Method Listing&#039;&#039;&#039; - used to insert all kind of helpers&lt;br /&gt;
* &#039;&#039;&#039;Process IDLE&#039;&#039;&#039; - method executed once in a while (may be used to keep connection alive, scan for new devices on serial bus)&lt;br /&gt;
* &#039;&#039;&#039;Process Incoming Data&#039;&#039;&#039; - called when some data is available &lt;br /&gt;
* &#039;&#039;&#039;Process Receive Command For Child&#039;&#039;&#039; - called if the device has children and those are pretty dummy (like Lights under CM11), so practically the parent will do the job. As a parameter you have &#039;&#039;cmd&#039;&#039; which is a wrapper for DCEMessage, so you&#039;ll have access to deviceId, senderId, commandID and so on.&lt;br /&gt;
* &#039;&#039;&#039;Process Initialize&#039;&#039;&#039; - called when device is starting (to perform handshake with device or some other initialisation required by protocol)&lt;br /&gt;
* &#039;&#039;&#039;Process Release&#039;&#039;&#039; - to close gracefully connection with device (say &amp;quot;good bye&amp;quot; or something)&lt;br /&gt;
&lt;br /&gt;
== Implementation notes ==&lt;br /&gt;
There are several classes that actually need to be touched. Most of the other classes are just for wrapping DCE objects (like Device, Message, Connection and so on) and exporting them into ruby.&lt;br /&gt;
&lt;br /&gt;
Most important classes :&lt;br /&gt;
* &#039;&#039;&#039;RubyDCEDeviceNode&#039;&#039;&#039; is actually the Device, responsable with initialisation and partially a message handler.&lt;br /&gt;
* &#039;&#039;&#039;RubyDCEEmbededClass&#039;&#039;&#039; is bridge between DeviceNode and ruby, it has &#039;&#039;CallCmdHandler&#039;&#039; which does the real call to ruby and sends back result.&lt;br /&gt;
* &#039;&#039;&#039;RubyIOManager&#039;&#039;&#039; is the one responsible for instantiating RubyDCEDeviceNodes, code retrieval, command handler and serializing ruby calls.&lt;br /&gt;
* &#039;&#039;&#039;RubyDCECodeSupplier&#039;&#039;&#039; gives you the ruby code&lt;br /&gt;
* &#039;&#039;&#039;RubyCommandWrapper&#039;&#039;&#039; a wrapper for Message&lt;br /&gt;
* &#039;&#039;&#039;GSDMessageProcessing&#039;&#039;&#039; is [[Message_Translation|message translator]] which will try to run command if it&#039;s implemented without translation.&lt;br /&gt;
* &#039;&#039;&#039;RubySerialIOConnectionWrapper&#039;&#039;&#039; helps to wrap Serial and TCP/IP based connection under same interface, see down the hierarchy the connection you need.&lt;br /&gt;
&lt;br /&gt;
There are also some files needed for building a library for ruby with SWIG, let them alone, it should work.&lt;br /&gt;
&lt;br /&gt;
The compilation will give you &#039;&#039;&#039;Generic_Serial_Device&#039;&#039;&#039; and &#039;&#039;&#039;Ruby_Generic_Serial_Device.so&#039;&#039;&#039;, first file is the binary itself, second file is the bridge library and it will be included by ruby (the request for it is in the first line of the generated source)&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&lt;br /&gt;
* Only &#039;&#039;&#039;ONE&#039;&#039;&#039; command can be executed at a time. This is a limitation of embedded ruby, which should be run from one thread only.&lt;br /&gt;
* If command expected an answer, it would wait about 20 seconds for the ruby command to complete, and if the command haven&#039;t completed yet, it would send an empty response.&lt;br /&gt;
* Most of the data are pretty cryptic (like &#039;&#039;device_.devdata_[114]&#039;&#039;), you have to look that that number represents (device data id, command id, command parameter id, event id, event parameter id, some other id)&lt;br /&gt;
&lt;br /&gt;
== Short example ==&lt;br /&gt;
For more details about exported classes and available methods check [[GSD_Ruby_Interface]]&lt;br /&gt;
&lt;br /&gt;
Here is a short example from &#039;&#039;Panasonic IP Camera&#039;&#039;:&lt;br /&gt;
   0:require &#039;Ruby_Generic_Serial_Device&#039;&lt;br /&gt;
   1:class Command &amp;lt; Ruby_Generic_Serial_Device::RubyCommandWrapper&lt;br /&gt;
   2:end&lt;br /&gt;
   3:class Device_47 &amp;lt; Ruby_Generic_Serial_Device::RubySerialWrapper&lt;br /&gt;
   4:#### 84 ####################################################################&lt;br /&gt;
   5:def cmd_84(data, format, disable_aspect_lock, streamid, width, height)&lt;br /&gt;
   6:@returnParamArray.clear&lt;br /&gt;
   7:conn_.Reconnect()&lt;br /&gt;
   8:auth_s=device_.devdata_[114]+&amp;quot;:&amp;quot;+device_.devdata_[115]&lt;br /&gt;
   9:auth_a=Array.new;&lt;br /&gt;
  10:auth_s.each{|c| auth_a.push(c)}&lt;br /&gt;
  11:&lt;br /&gt;
  12:fix_path=device_.devdata_[2];&lt;br /&gt;
  13:fix_path=&#039;/&#039;+fix_path if fix_path[0]!=&#039;/&#039;[0];&lt;br /&gt;
  14:&lt;br /&gt;
  15:s = &amp;quot;GET &amp;quot;+fix_path+&amp;quot; HTTP/1.0\r\n&amp;quot;&lt;br /&gt;
  16:s+= &amp;quot;Accept: */*\r\n&amp;quot;&lt;br /&gt;
  17:s+= &amp;quot;Authorization: Basic &amp;quot;+auth_a.pack(&amp;quot;m&amp;quot;).chop+&amp;quot;\r\n&amp;quot;&lt;br /&gt;
  18:s+= &amp;quot;\r\n&amp;quot;&lt;br /&gt;
  19:&lt;br /&gt;
  20:conn_.Send(s)&lt;br /&gt;
  21:recv=&amp;quot;&amp;quot;&lt;br /&gt;
  22:loop {&lt;br /&gt;
  23:  buff=conn_.Recv(16384, 5000)&lt;br /&gt;
  24:  if buff.empty?&lt;br /&gt;
  25:    break&lt;br /&gt;
  26:  end&lt;br /&gt;
  27:  recv += buff&lt;br /&gt;
  28:}&lt;br /&gt;
  29:if recv=~ /^HTTP[^\r\n]+200\sOK.+?\r\n\r\n(.+)$/m&lt;br /&gt;
  30:  data_set($1)&lt;br /&gt;
  31:  format_set(&#039;jpg&#039;)&lt;br /&gt;
  32:end&lt;br /&gt;
  33:return @returnParamArray&lt;br /&gt;
  34:end&lt;br /&gt;
 ...&lt;br /&gt;
 194:#### START SETTERS ####################################################################&lt;br /&gt;
 195:def initialize()&lt;br /&gt;
 196:super&lt;br /&gt;
 197:@returnParamArray=Array.new&lt;br /&gt;
 198:end&lt;br /&gt;
 199:def data_set(value)&lt;br /&gt;
 200:@returnParamArray[19]=value&lt;br /&gt;
 201:end&lt;br /&gt;
 202:def format_set(value)&lt;br /&gt;
 203:@returnParamArray[20]=value&lt;br /&gt;
 204:end&lt;br /&gt;
 205:####  END  SETTERS ####################################################################&lt;br /&gt;
 206:end&lt;br /&gt;
You can see how command 84 (GetVideoFrame) is implemented:&lt;br /&gt;
* it has 6 parameters &#039;&#039;cmd_84(data, format, disable_aspect_lock, streamid, width, height)&#039;&#039;, parameters &#039;&#039;data&#039;&#039; and &#039;&#039;format&#039;&#039; are also output parameters&lt;br /&gt;
* to set output parameters methods like &#039;&#039;data_set&#039;&#039; and &#039;&#039;format_set&#039;&#039; are automatically generated&lt;br /&gt;
* &#039;&#039;device_.devdata_[114]&#039;&#039;, &#039;&#039;device_.devdata_[115]&#039;&#039; are the username and password to login into camera &lt;br /&gt;
* then it creates HTTP header with basic authorization&lt;br /&gt;
* &#039;&#039;device_.devdata_[2]&#039;&#039; is the path to the snapshot (it is configurable because it can change between models)&lt;br /&gt;
* it sends the request and waits for the answer&lt;br /&gt;
* reads the answer, regexp parse it and gets JPEG content&lt;br /&gt;
* sets output parameters&lt;br /&gt;
* returns @returnParamArray (the return statement is added automatically)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Example - Adding Clipsal Interface ==&lt;br /&gt;
&lt;br /&gt;
We can control lights, curtains and climate controls using Clipsal Interface that connects through Serial Port.&lt;br /&gt;
&lt;br /&gt;
[[Here is a detailed example of how to add Clipsal Interface using Generic Serial Device.|Adding Clipsal Interface using Generic Serial Device]]&lt;br /&gt;
&lt;br /&gt;
== Useful Pages ==&lt;br /&gt;
* [[Serial Hack]] - A quick and dirty hack to fix the USB to Serial adapter problem! (Device not showing the correct block device on the admin panel)&lt;br /&gt;
* [[How to add your own GSD device]]&lt;/div&gt;</summary>
		<author><name>Newacct</name></author>
	</entry>
</feed>