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')