Difference between revisions of "Generic Serial Device"
Line 10: | Line 10: | ||
Select the device, and click "RubyCodes" button to be able to edit code that will be executed. | Select the device, and click "RubyCodes" button to be able to edit code that will be executed. | ||
− | You should be able to see commands that are specified in device template (like ON/OFF/WhateverElse) and a group of ''Internal | + | You should be able to see commands that are specified in device template (like ON/OFF/WhateverElse) and a group of ''Internal Commands'' which are used to perform certain actions ar to add helper functions. |
If the command you are trying to add doesn't show on first page, go to ''Add/Remove commands'' and add more commands for your device. | If the command you are trying to add doesn't show on first page, go to ''Add/Remove commands'' and add more commands for your device. | ||
Line 19: | Line 19: | ||
<$"PWON\r"$> | <$"PWON\r"$> | ||
:which simply will send the string ''"PWON\r"'' to device. | :which simply will send the string ''"PWON\r"'' to device. | ||
+ | |||
+ | You'll have to quickreload 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't update it's cache without full restart of [[DCERouter]]. With this code it creates a ruby source which will be interpretted by embedded ruby. | ||
+ | |||
+ | It will create methods called "cmd_CmdIDx" for each command(x) defined in web interface except ''Private_Method_Listing'' which will be inserted in the body of the class directly without wrapping. | ||
+ | |||
+ | The source usually looks like (''DevID'' is iPK_Device of specific device, ''CmdIDx'' is iPK_Command ) : | ||
+ | |||
+ | require 'Ruby_Generic_Serial_Device' | ||
+ | class Command < Ruby_Generic_Serial_Device::RubyCommandWrapper | ||
+ | end | ||
+ | class Device_DevID < Ruby_Generic_Serial_Device::RubySerialWrapper | ||
+ | def cmd_CmdID1(paramlist) | ||
+ | @returnParamArray.clear | ||
+ | ### WEB CODE for CmdID1 GOES HERE ### | ||
+ | return @returnParamArray | ||
+ | end | ||
+ | def cmd_CmdID2(paramlist) | ||
+ | @returnParamArray.clear | ||
+ | ### WEB CODE for CmdID2 GOES HERE ### | ||
+ | return @returnParamArray | ||
+ | end | ||
+ | ... | ||
+ | def cmd_ReceiveCommandForChild(cmd) | ||
+ | ### Process_Receive Command_For_Child GOES HERE ### | ||
+ | end | ||
+ | ... | ||
+ | ### Private_Method_Listing GOES HERE ### | ||
+ | ... | ||
+ | def initialize() | ||
+ | super | ||
+ | @returnParamArray=Array.new | ||
+ | end | ||
+ | ### Generated Setters/Getters goes here (may be empty, but usually looks like below) ### | ||
+ | def data_set(value) | ||
+ | @returnParamArray[19]=value | ||
+ | end | ||
+ | |||
+ | end | ||
+ | |||
+ | This is short description of ''Internal Commands'' and what they do | ||
+ | * '''Private Method Listing''' - used to insert all kind of helpers | ||
+ | * '''Process IDLE''' - method executed once in a while (may be used to keep connection alive, scan for new devices on serial bus) | ||
+ | * '''Process Incoming Data''' - called when some data is available | ||
+ | * '''Process Receive Command For Child''' - 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 ''cmd'' which is a wrapper for DCEMessage, so you'll have access to deviceId, senderId, commandID and so on. | ||
+ | * '''Process Initialize''' - called when device is starting (to perform handshake with device or some other initialisation required by protocol) | ||
+ | * '''Process Release''' - to close gracefully connection with device | ||
== Implementation notes == | == Implementation notes == | ||
− | + | ||
+ | == Known issues == | ||
+ | |||
+ | == Examples == | ||
+ | For more details check [[GSD_Ruby_Interface]] | ||
+ | |||
0:require 'Ruby_Generic_Serial_Device' | 0:require 'Ruby_Generic_Serial_Device' | ||
1:class Command < Ruby_Generic_Serial_Device::RubyCommandWrapper | 1:class Command < Ruby_Generic_Serial_Device::RubyCommandWrapper | ||
Line 72: | Line 123: | ||
205:#### END SETTERS #################################################################### | 205:#### END SETTERS #################################################################### | ||
206:end | 206:end | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− |
Revision as of 12:59, 22 May 2006
This page was written by Pluto and imported with their permission when LinuxMCE branched off in February, 2007. In general any information should apply to LinuxMCE. However, this page should be edited to reflect changes to LinuxMCE and remove old references to Pluto. |
- Note : The information is not quite complete because I'm not the original author.
Short description
It's a standard DCE device, it only can execute commands and send events (no event handler yet, but Aaron wants it badly).
The main idea is instead of programming a device in C++, compile, link whith 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'll have access to devicedata, device hierarchy, established connection and so on.
The ruby code for each device template is storred somewhere in InfraredGroup_Command table. To edit infrared code, on pluto-admin website go to Wizard> Devices > Generic_Serial_Devices. You have to add a device from a device template in order to see anything in that page.
Select the device, and click "RubyCodes" button to be able to edit code that will be executed. You should be able to see commands that are specified in device template (like ON/OFF/WhateverElse) and a group of Internal Commands which are used to perform certain actions ar to add helper functions.
If the command you are trying to add doesn't show on first page, go to Add/Remove commands and add more commands for your device.
There are 2 forms of ruby code you can write :
- standard ruby code (check [1] and [2] for syntax, referencies and programming guides)
- short form for conn_.Send
<$"PWON\r"$>
- which simply will send the string "PWON\r" to device.
You'll have to quickreload 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't update it's cache without full restart of DCERouter. With this code it creates a ruby source which will be interpretted by embedded ruby.
It will create methods called "cmd_CmdIDx" for each command(x) defined in web interface except Private_Method_Listing which will be inserted in the body of the class directly without wrapping.
The source usually looks like (DevID is iPK_Device of specific device, CmdIDx is iPK_Command ) :
require 'Ruby_Generic_Serial_Device' class Command < Ruby_Generic_Serial_Device::RubyCommandWrapper end class Device_DevID < Ruby_Generic_Serial_Device::RubySerialWrapper def cmd_CmdID1(paramlist) @returnParamArray.clear ### WEB CODE for CmdID1 GOES HERE ### return @returnParamArray end def cmd_CmdID2(paramlist) @returnParamArray.clear ### WEB CODE for CmdID2 GOES HERE ### return @returnParamArray end ... def cmd_ReceiveCommandForChild(cmd) ### Process_Receive Command_For_Child GOES HERE ### end ... ### Private_Method_Listing GOES HERE ### ... def initialize() super @returnParamArray=Array.new end ### Generated Setters/Getters goes here (may be empty, but usually looks like below) ### def data_set(value) @returnParamArray[19]=value end
end
This is short description of Internal Commands and what they do
- Private Method Listing - used to insert all kind of helpers
- Process IDLE - method executed once in a while (may be used to keep connection alive, scan for new devices on serial bus)
- Process Incoming Data - called when some data is available
- Process Receive Command For Child - 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 cmd which is a wrapper for DCEMessage, so you'll have access to deviceId, senderId, commandID and so on.
- Process Initialize - called when device is starting (to perform handshake with device or some other initialisation required by protocol)
- Process Release - to close gracefully connection with device
Implementation notes
Known issues
Examples
For more details check GSD_Ruby_Interface
0:require 'Ruby_Generic_Serial_Device' 1:class Command < Ruby_Generic_Serial_Device::RubyCommandWrapper 2:end 3:class Device_47 < Ruby_Generic_Serial_Device::RubySerialWrapper 4:#### 84 #################################################################### 5:def cmd_84(data, format, disable_aspect_lock, streamid, width, height) 6:@returnParamArray.clear 7:conn_.Reconnect() 8:auth_s=device_.devdata_[114]+":"+device_.devdata_[115] 9:auth_a=Array.new; 10:auth_s.each{|c| auth_a.push(c)} 11: 12:fix_path=device_.devdata_[2]; 13:fix_path='/'+fix_path if(fix_path[0]!='/'[0]); 14: 15:s = "GET "+fix_path+" HTTP/1.0\r\n" 16:s+= "Accept: */*\r\n" 17:s+= "Authorization: Basic "+auth_a.pack("m").chop+"\r\n" 18:s+= "\r\n" 19: 20:conn_.Send(s) 21:recv="" 22:while(true) 23: buff=conn_.Recv(16384, 5000) 24: if(buff.length() == 0) 25: break 26: end 27: recv = recv + buff 28:end 29:if (recv=~ /^HTTP[^\r\n]+200\sOK.+?\r\n\r\n(.+)$/m) 30: fileName="/tmp/ip_camera_img"+device_.devid_.to_s 31: data_set($1) 32: format_set('jpg') 33:end 34:return @returnParamArray 35:end ... 194:#### START SETTERS #################################################################### 195:def initialize() 196:super 197:@returnParamArray=Array.new 198:end 199:def data_set(value) 200:@returnParamArray[19]=value 201:end 202:def format_set(value) 203:@returnParamArray[20]=value 204:end 205:#### END SETTERS #################################################################### 206:end