Difference between revisions of "How to add your own GSD device"

From LinuxMCE
Jump to: navigation, search
m
Line 1: Line 1:
 
[[Category: Programmer's Guide]]
 
[[Category: Programmer's Guide]]
 
[[Category: Serial]]
 
[[Category: Serial]]
[[Category: LinuxMCE_Devices]]
+
[[Category: Tutorials]]
 
[[Category: GSD]]
 
[[Category: GSD]]
  

Revision as of 02:13, 11 August 2009


How to add your own GSD device

Create a new GSD device

The steps to add GSD device are following:

1. Be sure that you have installed GSD package -

dpkg -l 'pluto-generic-serial-device'

(it should be there).

3. Created a device template for your system and specify that it should use GSD. Add it under category lighting interfaces if you want to control lighting devices only. To control all kind of devices (security, climate etc) it's better to use Interface::Specialize. Also, you should specify a communication type - RS232, Ethernet etc.

4. After you save a new template a new interface will be added automatically. You can see it under Wizard --> Devices --> Interfaces. Also, there is a GSD page - Wizard --> Devices --> Generic Serial Devices. On that page you'll able to add/modify Ruby commands. To do that you should specify a group and tick box 'internal Ruby Command'. After you quick reload router you should see GSD process in console: # ps -elf|grep Generic_Serial_Device

5 S root     10085     1  0  76   0 -   683 -      Jul17 ?        00:00:00 SCREEN -d -m -S LinCon_8000-30 /usr/pluto/bin/Spawn_Device.sh 30 localhost Generic_Serial_Device
5 S root     10086 10085  0  75   0 -   646 wait   Jul17 pts/8    00:00:00 /bin/bash /usr/pluto/bin/Spawn_Device.sh 30 localhost Generic_Serial_Device
0 S root     31800 10086  0  79   0 - 123146 295621 Jul17 pts/8   00:00:00 ./Generic_Serial_Device -d 30 -r localhost -l /var/log/pluto/30_Generic_Serial_Device.log

Have a look into GSD log: /var/log/pluto/<GSD LinuxMCE ID>_Generic_Serial_Device.log. You can find here all Ruby errors, connection status and other useful information.


Add Ruby code

There are 6 base functions which you need:

  • Private Method Listing - you may place here all common functionality and use it from the others functions.
  • Process IDLE - method executed each one - two seconds, maybe useful to check a connection between your device and LinuxMCE.
  • Process Incoming Data - called when some data come from your device:
    recv = conn_.Recv(100,500);

    recv contains now the data received from the physical device (some switch is OFF). You can parse it to update a status of that switch in LinuxMCE:

    cmd = Command.new(plutoID, -1001, 1, 2, 48)
    cmd.params_[10] = 0
    SendCommand(cmd)
  • Process Receive Command For Child - called when the child device (in your case it's a dimmer of switch) gets some command: ON, OFF or SET LEVEL. Actually, those commands are routed to the parent device (your GSD interface) and it send the commands in desired format to the physical device:
    cmdId           = cmd.id_                                   # Command ID: ON, OFF, SET LEVEL
    cmdTo           = cmd.devidto_                              # Device ID in LinuxMCE
    devPort         = device_.childdevices_[cmdTo].devdata_[12] # 12 contains a port/channel
    childType       = device_.childdevices_[cmdTo].devtemplid_  # Template ID to know type of device: switch or dimmer
    
    case cmdId
          when 192 #192 is ON                     
               command = '<your ON command format>'           
          when 193 #193 is OFF                        
               command = '<your OFF command format>' 
          when 184 #184 is Level of dimmer
               command = '<your SET LEVEL command format>'                   
    end
    
    conn_.Send(command)
    
    In my case the command includes following parameters: LinuxMCE ID - to update the status in LinuxMCE, Port Number - to know where send actual command, command type - ON, OFF, SET LEVEL, level value for SET LEVEL. Plus, I generate an unique ID for each command to check its status. It might be good idea to push unsuccessful commands into array in the GSD device to run them one again.
  • NOTE: From trial and error, I have come to the assumption that ON/OFF and SETLEVEL, internally, have seperate values. Be careful as you can have a device that is OFF with a setlevel of 100%. This results in a pretty UGLY message when to attempt the following: Use cmd[184]=100 to turn a device ON. (but don't actually send a cmd[192].. when you attempt to turn the device OFF, you'll get an ugly message in the GSD device saying that the 'CMD[193] won't be processed because it is useless'. (I'm paraphrasing.. you get the idea...) What makes this worse, is when you use an orbiter to turn a device on, it will send you a cmd[184], not a cmd[192]. You will need to watch for this and send a cmd[192] as needed.
  • NOTE FOR ABOVE: I have found a way to force the command through. a bit of history first: The reason we get the infamous 'won't be processed because it is useless' is because DCE has to deal with NON Discrete codes. for instance: a device that has a power toggle. IF we turn it on, it turns on. Now, if we turn it ON again, DCE thinks it's on and because it's a toggle, it won't send the command. That is why we get this message. I dug pretty deep to find this next piece: params[120]=1 this parameter, when set inside a command, will FORCE DCERouter to send the command regardless of what it thinks the state is. Hope this helps other GSD programmers. DDamron
  • Process Initialize - called when GSD device is starting. It's good point to initialize common variables and start logging for example:
    time      = Time.now
    $logFile  = File.new("/var/log/pluto/ICPDAS-" + time.strftime("%Y%m%d%H%M") + ".log", "w")
    $bFlush   = true          # flash output buffer
    $waitTime = 4000          # wait time in comunication
    

    I use that log approach just for test purpose. When you go live it's better do not use time stamp. To append your GSD device log to the one file after restart of router use that command:

    $logFile  = File.new("/var/log/pluto/ICPDAS.log", "a")
    
    Also, I use that method to get actual status real child devices and update their statuses in the LinuxMCE. Because some switch can be OFF manually during GSD device was down.
  • Process Release - called when GSD device is closing. I don't use at all.
  • Note that you should quick reload router each time when you modify your Ruby code! Because LinuxMCE caches it.

    Viewing the logs

    The best way to test the new GSD device is to edit the file /etc/pluto.conf and comment out the LogLevels filter, so the logging is verbose. You can do this by typing:

    vim /etc/pluto.conf

    Then move to the start of the line that starts with LogLevels, press 'i' for Insert mode in vim, type a # character, then press [ESC]:wq The # at the start of a line means it's commented out, or ignored.

    now do a reload router. You can do this from the console with: /usr/pluto/bin/MessageSend dcerouter 0 -1000 7 1

    Then go to the log directory:

    cd /var/log/pluto

    ls

    ls will list the contents of the directory: There will be a log file that starts with the device number of the gsd device. To follow it type:

    tail -f [filename]

    rather than typing in the full filename, you can just type the first letters (ie the device number) and press tab, which does an auto complete.

    Now send commands to the device. You can do this through the web site or the console. For example, assuming your GSD device has the device id 57, you can send it an ON command (ON is command #192), you could type: /usr/pluto/bin/MessageSend dcerouter 0 57 1 192

    The log will show a bunch of data. The lines that start with 40 and 41 are the serial data that is being sent to/from the device. To filter the tail so it only shows the serial data, type:

    tail -f [filename] | grep '^40\|^41'

    See also