Author Topic: Insteon Integrated! EZBridge now, PLM soon  (Read 4688 times)

ddamron

  • Alumni
  • wants to work for LinuxMCE
  • *
  • Posts: 962
    • View Profile
    • My LinuxMCE User Page
Insteon Integrated! EZBridge now, PLM soon
« on: November 30, 2007, 07:28:47 pm »
I'm getting a weird error each time I load my GSD/Ruby Insteon Driver...

The error is:
359:01   11/30/07 11:01:22.718      Failed loading code: Error loading code:
error: undefined method `log' for Device_103:Class, line: 27
line 27 is ok, and so is the method (located in private method listing)

This started when power failed during a reboot...

I've tried deleting the device, and recreating it,
deleting all code in the template, and recreating it,
deleting all commands out of the template, and recreating them...

Looks to me like a corrupt sql table of some sort (error loading code)
any ideas on how to fix it?

Thanks,

Dan
« Last Edit: December 01, 2007, 09:32:14 am by ddamron »
The only intuitive interface is the nipple.  After that it's all learned.
My other computer is your windows box.
I'm out of my mind.  Back in 5 minutes.
Q:  What's Red and smells like blue paint?

A:  Red Paint.

ddamron

  • Alumni
  • wants to work for LinuxMCE
  • *
  • Posts: 962
    • View Profile
    • My LinuxMCE User Page
Insteon Integrated! EZBridge now, PLM soon
« Reply #1 on: December 01, 2007, 09:28:07 am »
Ok, I'll take the lack of responses as noone knows...  I'm reinstalling linuxmce from the DVD now...

FYI, I have successfully implemented Insteon via an EZ Bridge.  Code still a bit buggy (I'm learning ruby as I go, and it's changed considerably from what I posted earlier)

I figured out the messaging back to linuxmce.. sort of...

Now that I'm getting more familiar with Ruby, I want to re-write my routines to implement a message queue. (Ruby isn't threaded, and crashes if attempted).  I need two queues, 1 for commands from MCE to Insteon, and another for back.

I've written my code to be as object oriented as possible so most of it I can reuse.  Basic commands are implemented, along with framework for implementing groups, etc.  I'd like to also implememt a 'spider' to detect insteon devices not currently installed. 

PeteK, Thank you for all your help..  As I do not have a PLC, I cannot develop for that, however, I have both a PLM and an EZ-Bridge, so I'll be integrating the PLM in ruby next.  Basically their the same thing, the EZ-Bridge connects the PLM to ethernet, and uses XML rather than bytes, but almost everything in is pretty much the same.

Code you say??  hehe, thought you'd never ask...

I am posting my current code, I tried to put a 'busy' flag in, and broke it... hence why I'll implement queues.  Here it is...

Comments are welcome and encouraged!

If you use this, please let me know, It's free, but a lot of sweat went into this so far... I'd like gratification SOMEONE is using it other than me. :)


#### Written by Dan Damron
#### #373 Private Method Listing ####
#
#   Commands send back to DCE
#   184 - SetLevel value 0-100 (% on) or +-1 for steps
#   193 - Turn Light OFF   
#   192 - Turn Light ON
#
#
#
#
require "rexml/document"
include REXML

def log(line)
   $log = File.open("/var/log/pluto/insteon1.log", "a")
   $log.puts line.to_s
   $log.close
end
def parseMessage(param)

   #get parameter name
   instruction = param.keys[1]
#   log('instruction=:' + instruction + ':')
   case instruction
   when 'Parameter2' # Standard Command
      #get parameter value
      insvalue = param[instruction]
      case insvalue
      when '0X50' # InsStdMsg
         log('Standard Insteon Message')
         log('From ' + $cmdTo.to_s + ', To ' + $cmdFrom.to_s + ', Pri ' + $cmdPriority.to_s + ', Type ' + $cmdType.to_s + ', ID ' + $cmdID.to_s)
         sndCommand = Command.new($cmdTo, $cmdFrom, $cmdPriority, $cmdType, $cmdID)
         sndCommand.params_ = $cmdParams
         insHb = "%X" %param['Parameter3'].hex
         insMb = "%X" %param['Parameter4'].hex
         insLb = "%X" %param['Parameter5'].hex
         insID = insHb + "." + insMb + "." + insLb
         insFlags = "%X" %param['Parameter9'].hex
         insCmd1 = "%X" %param['Parameter10'].hex
         insCmd2 = "%X" %param['Parameter11'].hex
         log('From:' + insID + ', cmd1:' + insCmd1 + ', cmd2:' + insCmd2)
         case insCmd1
            when '1' # Assign to Group(inscmd2)
            when '2' # Delete from Group(inscmd2)
            when '10' # ping
            when '11' # ON Level(inscmd2)
#               sndCommand.params_[184] = hextopercent(insCmd2).to_s
#               sndCommand.params_[76] = hextopercent(insCmd2).to_s
               if insCmd2 = 'FF' then
#                  sndCommand.params_[192] = ''
#                  sndCommand.params_[97] = ''
#                  sndCommand.params_[98] = ''
               end
               SendCommand(sndCommand)
            when '13' # off (cmd2=none or Group#)
#               sndCommand.params_[76] = '0'
#               sndCommand.params_[97] = ''
#               sndCommand.params_[98] = ''
#               sndCommand.params_[184] = '0'
#               sndCommand.params_[193] = ''
               SendCommand(sndCommand)
            when '15' # Bright (cmd2=# of steps)
#               sndCommand.params_[184] = '+' + indCmd2.hex.to_s
               SendCommand(sndCommand)
            when '16' # Dim (cmd2=# of steps)
#               sndCommand.params_[184] = '-' + indCmd2.hex.to_s
               SendCommand(sndCommand)
            when '17' # Start Manual Change (cmd2, 1=Up, 0=Down)
            when '18' # Stop Manual Change
            when '19' # Status Request (see docs)
            when '24' # Do Read EEPROM
            when '28' # Set MSB for peek/poke
         end
 
         when '0X51' # InsExtMsg
            log('Extended Insteon Message')
         when '0X52' # X10Msg
            log('X10 Message')
         when '0X53' # InsLnkSts
            log('Insteon Link Status Report')
         when '0X54' # BtnRpt
            log('Insteon Button Report')
         when '0X55' # UsrRst
            log('User Reset')
         when '0X56' # GrpEventRpt
            log('Group Member Failure')
         when '0X57' # LnkData
            log('PLM Link Database Record')
            linkFlags = "%X" %param['Parameter3'].hex
            group = "%X" %param['Parameter4'].hex
            insHb = "%X" %(param['Parameter5'].hex)
            insMb = "%X" %(param['Parameter6'].hex)
            insLb = "%X" %(param['Parameter7'].hex)
            insID = insHb + "." + insMb + "." + insLb
            lnkData = "%X" %param['Parameter8'].hex
            lnkData += ".%X" %param['Parameter9'].hex
            lnkData += ".%x" %param['Parameter10'].hex
            log(insID + ", G:" + group + ", F:" + linkFlags + ", D:" + lnkData)
            $links[insID] = linkFlags + group + lnkData
         when '0X60' # GetVersion
            log('PLM Version Information')
         when '0X73' # GetCfg
      end
   end
$busy = false
log('\busy - send command to DCE')
      
end


# create a new XML command for SndIns

def SndIns(command, param)
   log('Command = ' + command)
   doc = Document.new
   doc << XMLDecl.new
   el = doc.add_element 'command'
   el.text = command
   param.keys.each {|k|
      el1 = el.add_element k
      el1.text = param[k]}
   
#   log('SndIns:CmdSent:' + doc.to_s)
   conn_.Send(doc.to_s)
   $cmd=command   
   log('Command Sent:' + $cmd)
$busy = false
log('/busy - Sent Insteon Command')

end

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

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



************************************************************************************
### PROCESS-IDLE ***
if $getConfig == 'PLM' then
   log 'Getting Links...'
   command = 'GetNext'
   param = {}
   SndIns(command, param)
end
if $getConfig == 'LstDevices' then
   command = 'LstDevices'
   param = {}
   SndIns(command, param)
end


************************************************************************************
#### Written by Dan Damron
#### #350 Process Incoming Data ####

#log('Entered Process Incoming Data')
#log('ReceiveData:$resposeString=' + $responseString)
recv = ""
#while ($busy == false)
   while(recv <=> $responseString)
#   log('recv <=> $responseString = ' + (recv <=> $responseString).to_s)
      buff=conn_.RecvDelimited($responseString, 10)
         
         if(buff.length() == 0)
            break
         end
      recv += buff
      log("RecvLoop:" + (recv <=> $responseString).to_s)
   end
end
#log('Busy Process incoming data')
$busy = true
log("*** INCOMING from INSTEON:\n")
#log('$cmd=:' + $cmd + ':')
#log(recv)

# recv now contains XML

param = {} # hash to save data
elname = ""
eltext = ""

#parse XML into hash
doc = Document.new recv
command = doc.root.get_text.value.to_s
if doc.root.has_elements? then
   #has elements
   el = doc.root.elements[1]
   while el != nil
      elname = el.name.to_s
      eltext = doc.root.elements[elname].text.to_s
#      log(elname + '=' + eltext)
      param[elname] = eltext
      el = doc.root.elements[elname].next_element
   end

end
if $cmd == "" then
   # not waiting for a command ack.
   log('Command received')
   parseMessage(param)
else
#   log($cmd <=> command)
   log(':' + $cmd + ': <=> :' + command + ': = ' + ($cmd <=> command).to_s)
   if ($cmd <=> command)> -1  then

      #command response received
      #check for ack
#      log(param[param.keys.last].to_s)
      if param[param.keys.last].to_s == '0X6' then
         log('Command Successfull')
      else
         log('Command NOT successfull')
      end

      $cmd = ""

   else
      #waiting for ack, but received another command
      log('waiting for ' + $cmd + ' but got ' + command + 'instead')
      #parseMessage(param)
   end
#log('/busy - process incoming data')
#$busy = false
#end
************************************************************************************
#### Written by Dan Damron
#### #355 Process Initialize ####

$log = File.new("/var/log/pluto/insteon1.log", "w")
$bFlush = true
$waitTime = 4000
$links = {}
$cmdTo = ''
$cmdFrom = ''
$cmdPriority = ''
$cmdType = ''
$cmdID = ''
$cmdParams = {}
$busy = false
$x10HouseCodes = {'6', 'A', 'E', 'B', '2', 'C', 'A', 'D', '1', 'E', '9', 'F', '5', 'G', 'D', 'H', '7', 'I', 'F', 'J', '3', 'K', 'B', 'L', '0', 'M', '8', 'N', '4', 'O', 'C', 'P'}
$X10UnitCodes = {'6', '1', 'E', '2', '2', '3', 'A', '4', '1', '5', '9', '6', '5', '7', 'D', '8', '7', '9', 'F', '10', '3', '11', 'B', '12', '0', '13', '8', '14', '4', '15', 'C', '16'}
$X10CommandCodes = {'6', 'All Lights Off',
'E', 'Status = off',
'2', 'On',
'A', 'Pre-Set Dim',
'1', 'All Lights On',
'9', 'Hail Ack',
'5', 'Bright',
'D', 'Status=on',
'7', 'Extended Code',
'F', 'Status Request',
'3', 'Off',
'B', 'Pre-set Dim',
'0', 'All Units Off',
'8', 'Hail Request',
'4', 'Dim',
'C', 'Extended Data(analog)'}



#$getConfig = 'PLM'
#$getConfig = 'LstDevices'
$getConfig = ''
$responseString = '<' + '/' + 'Response' + '>'

log('Getting Links...')
#command = 'GetLnk'
#param = {}
#SndIns(command, param)

************************************************************************************
#### Written by Dan Damron
#### #384 Process Receive Command for Child ####
#if $busy==true then
#   break
#end
#$busy = true
#log('busy=true - Recv cmd for Child')
#log('We got cmd: ' + cmd.id_.to_s)
insteonID = device_.childdevices_[cmd.devidto_].devdata_[12].chomp.split('.')
$cmdID = cmd.id_
$cmdTo = cmd.devidto_
childType = device_.childdevices_[cmd.devidto_].devtemplid_
$cmdFrom = cmd.devidfrom_
$cmdPriority = cmd.priority_
$cmdType = cmd.type_
$cmdParams = cmd.params_
log('cmdID:' + $cmdID.to_s + ', cmdFrom:' + $cmdFrom.to_s + ', cmdTo:' + $cmdTo.to_s + ', cmdType:' + $cmdType.to_s + ', Priority:' + $cmdPriority.to_s)
$cmdParams.keys.each {|p| log('Param_[' + p.to_s + ']=' + $cmdParams[p])}

case cmd.id_
when 192
   command = 'SndIns'
   param = {'Parameter1' => insteonID[0],
   'Parameter2' => insteonID[1],
   'Parameter3' => insteonID[2],
   'Parameter4' => '0F',
   'Parameter5' => '11',
   'Parameter6' => 'FF'}
   SndIns(command, param)

when 193
   command = 'SndIns'
   param = {'Parameter1' => insteonID[0],
   'Parameter2' => insteonID[1],
   'Parameter3' => insteonID[2],
   'Parameter4' => '0F',
   'Parameter5' => '13',
   'Parameter6' => '00'}
   SndIns(command, param)

when 184
   # convert from percent to hex
   dim_level = percenttohex(cmd.params_[76]).to_i
   command = 'SndIns'
   param = {'Parameter1' => insteonID[0],
   'Parameter2' => insteonID[1],
   'Parameter3' => insteonID[2],
   'Parameter4' => '0F',
   'Parameter5' => '11',
   'Parameter6' => dim_level}
   SndIns(command, param)

end
#$busy = false
#log('finished recv cmd for child - busy set to false')


« Last Edit: December 01, 2007, 09:32:39 am by ddamron »
The only intuitive interface is the nipple.  After that it's all learned.
My other computer is your windows box.
I'm out of my mind.  Back in 5 minutes.
Q:  What's Red and smells like blue paint?

A:  Red Paint.

nite_man

  • NEEDS to work for LinuxMCE
  • ***
  • Posts: 1019
  • Want to work with LinuxMCE
    • View Profile
    • Smart Home Blog
Re: Insteon Integrated! EZBridge now, PLM soon
« Reply #2 on: December 28, 2007, 10:07:41 am »
Hi Ddamron,

Great work! I also work with GSD interface to one proprietary controller. During that development I faced with necessity to know a current house mode in the method #350 Process Incoming Data to avoid running some security scenarios, for example, if some sensor is tripped but house mode is 'Unarmed'. Do you know how to do it or you don't implement that yet in your INSTEON interface?

Thanks in advance.
Michael Stepanov,
My setup: http://wiki.linuxmce.org/index.php/User:Nite_man#New_setup
Russian LinuxMCE community: http://linuxmce.ru

ddamron

  • Alumni
  • wants to work for LinuxMCE
  • *
  • Posts: 962
    • View Profile
    • My LinuxMCE User Page
Re: Insteon Integrated! EZBridge now, PLM soon
« Reply #3 on: December 28, 2007, 11:18:37 am »
Essentially, you don't really care what the house mode is...
You simply report Tripped or NOT..
The only intuitive interface is the nipple.  After that it's all learned.
My other computer is your windows box.
I'm out of my mind.  Back in 5 minutes.
Q:  What's Red and smells like blue paint?

A:  Red Paint.

ddamron

  • Alumni
  • wants to work for LinuxMCE
  • *
  • Posts: 962
    • View Profile
    • My LinuxMCE User Page
Re: Insteon Integrated! EZBridge now, PLM soon
« Reply #4 on: December 28, 2007, 11:48:36 am »
As this is really old code, I'm locking this topic...
If you need further assistance, start your own topic.

Regards,

Dan
The only intuitive interface is the nipple.  After that it's all learned.
My other computer is your windows box.
I'm out of my mind.  Back in 5 minutes.
Q:  What's Red and smells like blue paint?

A:  Red Paint.