ddamron
Alumni
wants to work for LinuxMCE

Posts: 962
|
 |
« 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')
|