LinuxMCE Forums
General => Developers => Topic started by: ddamron 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
-
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')
-
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.
-
Essentially, you don't really care what the house mode is...
You simply report Tripped or NOT..
-
As this is really old code, I'm locking this topic...
If you need further assistance, start your own topic.
Regards,
Dan