YoungJules

Real World Interface

Mar 18th, 2011
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.19 KB | None | 0 0
  1. from dcps import *
  2. from comedi import *
  3. import logging
  4. import urllib
  5. import socket
  6. import os
  7. import time
  8. import platform
  9.  
  10. """rwi (real-world interface) device wrapper. For this to work, comedi and the python comedi bindings must be installed"""
  11.  
  12. class device( bt.device ):
  13.  
  14.     SWITCHES=["Hall", "Study", "Porch", "Lounge", "Terrace", "Trap", "NA", "NA", "NA", "Bathroom", "Kitchen", "Laundry", "Shower", "NA", "Showerroom", "Apex"]
  15.  
  16.     """The rwi device wrapper itself - provides various commands for switches on and off manipulations."""
  17.  
  18.     def __init__( self, universe, ip, boards ):
  19.         """Initialise the rwi device wrapper"""
  20.         self.ip = ip
  21.         self.boards = boards
  22.         self.switches_index = list()
  23.         for switch in self.SWITCHES:
  24.             self.switches_index.append(switch.upper())
  25.         bt.device.__init__( self, universe, ip )
  26.  
  27.     def id( self ):
  28.         """Return an id"""
  29.         return ( 'rwi', 'rwi at %s' % self.ip )
  30.  
  31.     def keygen( self, key ):
  32.         """Generate a unique key for this instance of the rwi device"""
  33.         return 'rwi_%s_%s' % ( self.ip, key )
  34.        
  35.  
  36.     def get_info( self, client, boardnum ):
  37.         """Get some information about the given board"""
  38.         result=self.validate_arg(boardnum)
  39.         if result=="OK":
  40.             client.write(self.boards[int(boardnum)].get_info())
  41.             return bt.SUCCESS
  42.         else:
  43.             client.write(result)
  44.             return bt.FAILURE
  45.        
  46.     def get_board_name( self, client, boardnum ):
  47.         """Get the name of the given board"""
  48.         result=self.validate_arg(boardnum)
  49.         if result=="OK":
  50.             client.write(self.boards[int(boardnum)].get_board_name())
  51.             return bt.SUCCESS
  52.         else:
  53.             client.write(result)
  54.             return bt.FAILURE
  55.  
  56.  
  57.     def get_driver_name( self, client, boardnum ):
  58.         """Get the name of the driver for the given board"""
  59.         result=self.validate_arg(boardnum)
  60.         if result=="OK":
  61.             client.write(self.boards[int(boardnum)].get_driver_name())
  62.             return bt.SUCCESS
  63.         else:
  64.             client.write(result)
  65.             return bt.FAILURE
  66.        
  67.     def channel (self, key ):
  68.         """Tries to make sense of a channel param, first looks to see if it's a number, then looks up in the list of switches"""
  69.         try:
  70.             # channel number entered?
  71.             key_ind=int(key)
  72.         except:
  73.             # not a number, so look up channel number in the lights array
  74.             key_ind=self.switches_index.index(key.upper())
  75.         return key_ind
  76.  
  77.     def off( self, client, arg ):
  78.         """Turn off the given switch(es)"""
  79.         args = arg.rsplit(",")
  80.         for arg in args:
  81.             arg = self.channel(arg)
  82.             if arg < 0:
  83.                 return bt.FAILURE
  84.             board, channel = self.get_board_channel(arg)
  85.             self.boards[board].off(channel)
  86.         return bt.SUCCESS
  87.  
  88.     def on( self, client, arg ):
  89.         """Turn on the given switch(es)"""
  90.         args = arg.rsplit(",")
  91.         for arg in args:
  92.             arg = self.channel(arg)
  93.             if arg < 0:
  94.                 return bt.FAILURE
  95.             board, channel = self.get_board_channel(arg)
  96.             self.boards[board].on(channel)
  97.         return bt.SUCCESS
  98.  
  99.     def get_board_channel( self, switch ):
  100.         """Given an absolute switch number, works out which board the switch is on and which switch it is on that board
  101.         If we have a switch number of 14, with 8 switches on the first board and 8 on the second
  102.         we'll return 1 for the board (it's on the 2nd board) and 6 for the switch on that board"""
  103.         if switch < 0:
  104.             return -1, -1
  105.         # go through the boards
  106.         totchans = 0
  107.         for idx in range(len(self.boards)):
  108.             dout = self.boards[idx].find_dout_dev()
  109.             numchans = self.boards[idx].get_num_chans(dout)
  110.             if switch < totchans + numchans:
  111.                 return idx, switch - totchans
  112.             totchans = totchans + numchans
  113.         return -1, -1
  114.  
  115.     def get_switches( self, client ):
  116.         """Return a list of all the defined switches"""
  117.         for idx in range(len(self.SWITCHES)):
  118.         # for switch in self.SWITCHES:
  119.             #client.write(switch)
  120.             client.write('%d, %s' % (idx, self.SWITCHES[idx]))
  121.         return bt.SUCCESS
  122.  
  123.     def find_din_device( self, client, boardnum ):
  124.         """Find the DIN subdevice on the given board"""
  125.         result=self.validate_arg(boardnum)
  126.         if result=="OK":
  127.             client.write(str(self.boards[int(boardnum)].find_din_dev()))
  128.             return bt.SUCCESS
  129.  
  130.         else:
  131.             client.write(result)
  132.             return bt.FAILURE
  133.        
  134.     def find_dout_device( self, client, boardnum ):
  135.         """Find the DOUT subdevice on the given board"""
  136.         result=self.validate_arg(boardnum)
  137.         if result=="OK":
  138.             client.write(str(self.boards[int(boardnum)].find_dout_dev()))
  139.             return bt.SUCCESS
  140.  
  141.         else:
  142.             client.write(result)
  143.             return bt.FAILURE
  144.  
  145.     def get_num_subdevices( self, client, boardnum ):
  146.         """Get the number of subdevices on the given board"""
  147.         result=self.validate_arg(boardnum)
  148.         if result=="OK":
  149.             client.write(str(self.boards[int(boardnum)].get_num_subdevices()))
  150.             return bt.SUCCESS
  151.  
  152.         else:
  153.             client.write(result)
  154.             return bt.FAILURE
  155.  
  156.     def get_num_channels( self, client, boardnum, subdevice ):
  157.         """Get the number of channels on the given subdevice of the given board"""
  158.         result=self.validate_arg(boardnum)
  159.         if result=="OK":
  160.             client.write(str(self.boards[int(boardnum)].get_num_chans(subdevice)))
  161.             return bt.SUCCESS
  162.  
  163.         else:
  164.             client.write(result)
  165.             return bt.FAILURE
  166.  
  167.     def get_dout_state( self, client ):
  168.         """Get the binary state of the DOUT device on the given board(s) as a String"""
  169.         all_states=""
  170.         for idx in range (len(self.boards)):
  171.             dout = self.boards[idx].find_dout_dev()
  172.             all_states = all_states + str(self.boards[idx].get_state(dout))
  173.         client.write(all_states)
  174.         return bt.SUCCESS
  175.  
  176.     def get_din_state( self, client ):
  177.         """Get the binary state of the DIN device on the given board(s) as a String"""
  178.         all_states=""
  179.         for idx in range (len(self.boards)):
  180.             din = self.boards[idx].find_din_dev()
  181.             all_states = all_states + str(self.boards[idx].get_state(din))
  182.         client.write(all_states)
  183.         return bt.SUCCESS
  184.  
  185.     def get_location( self, client, boardnum ):
  186.         """Get the location of the given board (/dev/comedi%)"""
  187.         if self.validate_arg(boardnum)=="OK":
  188.             client.write(self.boards[int(boardnum)].get_location())
  189.         return bt.SUCCESS
  190.  
  191.     def toggle( self, client, boardnum, arg ):
  192.         """On the given board, toggle the given light(s)"""
  193.         result=self.validate_arg(boardnum)
  194.         if result=="OK":
  195.             args = arg.rsplit(",")
  196.             for arg in args:
  197.                 self.boards[int(boardnum)].flip(arg)
  198.             return bt.SUCCESS
  199.  
  200.         else:
  201.             client.write(result)
  202.             return bt.FAILURE
  203.  
  204.     def validate_arg( self, arg ):
  205.         """Try to ensure that the given boardnum corresponds to an actual board"""
  206.         try:
  207.             idx=int(arg)
  208.         except:
  209.             return "Invalid argument, must be number"
  210.         if idx < 0 or idx + 1 > len(self.boards):
  211.             return "Invalid argument, have %d boards" % (len(self.boards))
  212.         return "OK"
  213.        
  214.     def map( self, client ):
  215.         """Device ui map"""
  216.         client.write( 'type, switchmap' )
  217.         client.write( 'item_count, %d' % len(self.SWITCHES) )
  218.         self.get_switches(client)
  219.         return bt.SUCCESS
  220.  
  221. class board():
  222.     DOUT=4
  223.     DIN=3
  224.  
  225.     def __init__( self, dev, location  ):
  226.         """Initialise the board wrapper"""
  227.         logging.debug("Into __init__() on the board class")
  228.         self.dev = dev
  229.         self.subdevices = {}
  230.         self.location = location
  231.  
  232.     def get_info( self ):
  233.         """Get some info"""
  234.         info_txt = "Board: %s\n" % (self.get_board_name())
  235.         info_txt = info_txt + "Driver: %s\n" % (self.get_driver_name())
  236.         info_txt = info_txt + "Located at: %s\n" % (self.get_location())
  237.         numsubdev=self.get_num_subdevices()
  238.         info_txt = info_txt + "Number of sub-devices: %s\n" % (numsubdev)
  239.         for subdevind in range(0, numsubdev):
  240.             subdevtyp=comedi_get_subdevice_type(self.dev, subdevind)
  241.             numchan=comedi_get_n_channels(self.dev, subdevind)
  242.             state=""           
  243.             if (subdevtyp==3 or subdevtyp==4):
  244.                 for chan in range(0, numchan):                 
  245.                     res, value = comedi_dio_read(self.dev, subdevind, chan)
  246.                     if (res==1):
  247.                         state=state + str(value)
  248.                     else:
  249.                         state=state + "*"
  250.                 state="and has state: " + state
  251.             info_txt = info_txt + "Sub device %d has sub device type %d and %d channels %s\n" % (subdevind, subdevtyp, numchan, state)
  252.         return info_txt
  253.  
  254.     def get_board_name( self ):
  255.         return comedi_get_board_name(self.dev)
  256.  
  257.     def get_driver_name( self ):
  258.         return comedi_get_driver_name(self.dev)
  259.  
  260.     def off( self,  channel):
  261.         return comedi_dio_write( self.dev, 3, channel, 0)
  262.  
  263.     def on( self,  channel):
  264.         return comedi_dio_write( self.dev, 3, channel, 1)
  265.  
  266.     def find_din_dev( self ):
  267.         """(internal) Find the DIN subdevice"""
  268.         return comedi_find_subdevice_by_type(self.dev, self.DIN, 0)
  269.        
  270.     def find_dout_dev( self ):
  271.         """(internal) Find the DOUT subdevice"""
  272.         return comedi_find_subdevice_by_type(self.dev, self.DOUT, 0)
  273.  
  274.     def get_num_subdevices( self ):
  275.         """(internal) Get the number of subdevices"""
  276.         return comedi_get_n_subdevices(self.dev)
  277.  
  278.     def get_num_chans( self, arg ):
  279.         """(internal) Get the number of channels on the given subdevice"""
  280.         return comedi_get_n_channels(self.dev, int(arg))
  281.  
  282.     def get_state( self, arg ):
  283.         """(internal) Get the binary state of the given subdevice as a String"""
  284.         numchan=self.get_num_chans(arg)
  285.         logging.debug("numchan: %d" % (numchan))
  286.         state = ""
  287.         for chan in range(0, numchan):
  288.             res, value = comedi_dio_read(self.dev, int(arg), chan)
  289.             logging.debug("res: %d and value: %d" % (res, value))
  290.             if (res==1):
  291.                 state=state + str(value)
  292.             else:
  293.                 state=state + "*"
  294.         return state
  295.  
  296.     def get_location(self):
  297.         return self.location
  298.  
  299.     def flip(self, subdev, chan):
  300.         """(internal) Flips the given channel on the given subdevice"""
  301.         res, value = comedi_dio_read(self.dev, subdev, chan)
  302.         if (res==1):
  303.             if (value==1):
  304.                 res = comedi_dio_write(self.dev, subdev, chan, 0)
  305.             else:
  306.                 res = comedi_dio_write(self.dev, subdev, chan, 1)
  307.  
  308. def instantiate( universe, ip ):
  309.     """Attempt to instantiate a device wrapper for the specified ip addreess."""
  310.  
  311.     logging.debug( "rwi instantiate: started" )
  312.     try:
  313.         if ip == '127.0.0.1':
  314.             logging.debug( "rwi instantiate: is localhost" )
  315.             if platform.system( ) != 'Windows':
  316.                 logging.debug( "rwi instantiate: is NOT Windoze!" )
  317.                 # Sanity check to see if comedi is installed
  318.                 check_comedi = os.system( 'which comedi_test >/dev/null 2>&1' )
  319.                 logging.debug( "rwi instantiate: check_comedi is: %s" % (check_comedi) )
  320.                 if check_comedi == 0:
  321.                     try:
  322.                         logging.debug( "rwi instantiate: check_comedi is 0 so continuing..." )
  323.                         boards = find_boards()
  324.                         logging.debug( "rwi instantiate: find_boards done" )
  325.                         logging.debug( "rwi instantiate: find_boards done, found %d" % (len(boards)) )
  326.                         #logging.debug( "rwi instantiate: number subdevices: %d" % (get_num_subdevices(dev)) )
  327.                         device( universe, ip, boards )
  328.                         logging.debug( "rwi instantiate: device done" )
  329.                         logging.debug( "rwi instantiate returning TRUE!!!" )
  330.                         return True
  331.                     except Exception, e:
  332.                         logging.error( "Got exception in instantiate of rwi device: " + e )
  333.             else:
  334.                 logging.debug( "No comedi on Windoze yet..." )
  335.            
  336.  
  337.     except Exception, e:
  338.         logging.error( 'rwi failure on %s: %s' % ( ip, e ) )
  339.  
  340.     return False
  341.  
  342. def find_boards():
  343.     logging.debug("Into find_boards")
  344.     boards = list()
  345.     for dev_idx in range(16):
  346.         location = "/dev/comedi" + str(dev_idx)
  347.         dev=comedi_open(location)
  348.         if comedi_get_n_subdevices(dev) != -1:
  349.             logging.debug("Creating board from device found at %s" % (location))
  350.             boards.append(board(dev, location))
  351.     return boards
Advertisement
Add Comment
Please, Sign In to add comment