Advertisement
Guest User

Untitled

a guest
Dec 10th, 2010
3,888
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.51 KB | None | 0 0
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. #libnodave.py
  4.  
  5. """
  6.    ein Wrapper für die c- Bibliothek libnodave
  7.    
  8.    TODO:
  9.            Methode um Merkerbyte als Dict. abzurufen
  10.  
  11. """
  12. import ctypes
  13. import os
  14.  
  15.     # copied constants from nodave.h
  16. #Protocol types to be used with newInterface:
  17. daveProtoMPI  = 0    # MPI for S7 300/400
  18. daveProtoMPI2 = 1    # MPI for S7 300/400, "Andrew's version" without STX
  19. daveProtoMPI3 = 2    # MPI for S7 300/400, Step 7 Version, not yet implemented
  20. daveProtoMPI4 = 3    # MPI for S7 300/400, "Andrew's version" with STX
  21.  
  22. daveProtoPPI  = 10    # PPI for S7 200
  23. daveProtoAS511 = 20    # S5 programming port protocol
  24. daveProtoS7online = 50    # use s7onlinx.dll for transport
  25. daveProtoISOTCP = 122    # ISO over TCP */
  26. daveProtoISOTCP243 = 123 # ISO over TCP with CP243 */
  27. daveProtoISOTCPR = 124   # ISO over TCP with Routing */
  28.  
  29. daveProtoMPI_IBH = 223   # MPI with IBH NetLink MPI to ethernet gateway */
  30. daveProtoPPI_IBH = 224   # PPI with IBH NetLink PPI to ethernet gateway */
  31.  
  32. daveProtoNLpro = 230     # MPI with NetLink Pro MPI to ethernet gateway */
  33.  
  34. daveProtoUserTransport = 255    # Libnodave will pass the PDUs of S7 Communication to user */
  35.                                       # defined call back functions. */
  36.                    
  37. #ProfiBus speed constants:
  38. daveSpeed9k = 0
  39. daveSpeed19k = 1
  40. daveSpeed187k = 2
  41. daveSpeed500k = 3
  42. daveSpeed1500k = 4
  43. daveSpeed45k = 5
  44. daveSpeed93k = 6
  45.  
  46. #    S7 specific constants:
  47. daveBlockType_OB = '8'
  48. daveBlockType_DB = 'A'
  49. daveBlockType_SDB = 'B'
  50. daveBlockType_FC = 'C'
  51. daveBlockType_SFC = 'D'
  52. daveBlockType_FB = 'E'
  53. daveBlockType_SFB = 'F'
  54.  
  55. daveS5BlockType_DB = 0x01
  56. daveS5BlockType_SB = 0x02
  57. daveS5BlockType_PB = 0x04
  58. daveS5BlockType_FX = 0x05
  59. daveS5BlockType_FB = 0x08
  60. daveS5BlockType_DX = 0x0C
  61. daveS5BlockType_OB = 0x10
  62.  
  63.  
  64. #Use these constants for parameter "area" in daveReadBytes and daveWriteBytes  
  65. daveSysInfo = 0x3      # System info of 200 family
  66. daveSysFlags = 0x5    # System flags of 200 family
  67. daveAnaIn = 0x6       # analog inputs of 200 family
  68. daveAnaOut = 0x7      # analog outputs of 200 family
  69.  
  70. daveP = 0x80           # direct peripheral access
  71. daveInputs = 0x81    
  72. daveOutputs = 0x82    
  73. daveFlags = 0x83
  74. daveDB = 0x84          # data blocks
  75. daveDI = 0x85          # instance data blocks
  76. daveLocal = 0x86       # not tested
  77. daveV = 0x87           # don't know what it is
  78. daveCounter = 28       # S7 counters
  79. daveTimer = 29         # S7 timers
  80. daveCounter200 = 30    # IEC counters (200 family)
  81. daveTimer200 = 31      # IEC timers (200 family)
  82. daveSysDataS5 = 0x86   # system data area ?
  83. daveRawMemoryS5 = 0    # just the raw memory
  84.  
  85.  
  86.     #locate the acutal location so we will later find the
  87.     #libnodave-libs
  88. APPDIR = os.path.dirname(os.path.abspath(__file__))
  89.  
  90. if os.name == 'nt':
  91.     DLL_LOC = os.path.join(APPDIR, 'libnodave', 'win', 'libnodave.dll')
  92. elif os.name == 'posix':
  93.     DLL_LOC = os.path.join(APPDIR, 'libnodave', 'libnodave.so')
  94. else:
  95.     print 'only win and linux supportet yet'
  96.  
  97.  
  98. def int_to_bitarr(integer):
  99.     """
  100.        aus einem übergebenen Integer ein 8-stelliges Array erstellen in dem die einzelnen
  101.        Enthaltenen Bits aufzufinden sind
  102.        im bitarr sind die Positionen im array gleich den Werten im Merkerbyte auf der SPS
  103.        m0.0 ist 1. Bit im Merkerbyte (arr[0]
  104.    """
  105.     string = bin(integer)[2:]
  106.     arr = list()
  107.    
  108.     for bit in xrange(8 - len(string)):
  109.         arr.append(0)  
  110.    
  111.     for bit in string:
  112.         arr.append(int(bit))    
  113.    
  114.     arr.reverse()
  115.     return arr
  116.  
  117. def bitarr_to_int(bitarr):
  118.     """
  119.        eine liste die ein Byte repräsentiert in den passenden
  120.        integer-Wert umrechnen
  121.    """
  122.     str_bitarr = list()
  123.     bitarr.reverse()
  124.     for elem in bitarr:
  125.         str_bitarr.append(str(elem))
  126.     print str_bitarr
  127.     string = ''.join(str_bitarr)
  128.     return int(string,2)
  129.  
  130.  
  131.     #class to represent a c-struct
  132. class _daveOSserialType(ctypes.Structure):
  133.     _fields_ = [("rfd", ctypes.c_int),
  134.                 ("wfd", ctypes.c_int)]
  135.    
  136.  
  137. class libnodave(object):
  138.     def __init__(self):
  139.            
  140.         self. fds = _daveOSserialType()
  141.         self.init_dll()
  142.        
  143.         self.buffer = ctypes.create_string_buffer('buffer')
  144.         self.buffer_p = ctypes.pointer(self.buffer)
  145.        
  146.     def init_dll(self):
  147.         """
  148.            initiate the os depending dll-File
  149.            set argtypes and resttypes for used functions
  150.        """
  151.         if os.name == 'nt':
  152.             self.dave = ctypes.windll.LoadLibrary(DLL_LOC)
  153.         else:
  154.             self.dave =  ctypes.cdll.LoadLibrary(DLL_LOC)
  155.    
  156.         self.dave.setPort.restype =  ctypes.c_int
  157.         self.dave.setPort.argtypes = [ctypes.c_char_p,
  158.                                       ctypes.c_char_p,
  159.                                       ctypes.c_char]
  160.        
  161.         self.dave.daveNewInterface.resttype = ctypes.c_void_p
  162.         self.dave.daveNewInterface.argtypes = [_daveOSserialType,
  163.                                                ctypes.c_char_p,
  164.                                                ctypes.c_int,
  165.                                                ctypes.c_int,
  166.                                                ctypes.c_int]
  167.        
  168.         self.dave.daveInitAdapter.resttype = ctypes.c_void_p
  169.         self.dave.daveInitAdapter.argtypes = [ctypes.c_void_p]
  170.        
  171.         self.dave.daveNewConnection.resttype = ctypes.c_void_p
  172.         self.dave.daveNewConnection.argtypes = [ctypes.c_void_p,
  173.                                                 ctypes.c_int,
  174.                                                 ctypes.c_int,
  175.                                                 ctypes.c_int]
  176.        
  177.         self.dave.daveConnectPLC.resttype = ctypes.c_int
  178.         self.dave.daveConnectPLC.argtypes = [ctypes.c_void_p]
  179.        
  180.         self.dave.daveSetTimeout.resttype = ctypes.c_void_p
  181.         self.dave.daveSetTimeout.argtypes = [ctypes.c_void_p,
  182.                                              ctypes.c_int]
  183.        
  184.         self.dave.daveGetU8.resttype = ctypes.c_int
  185.         self.dave.daveGetU8.argtypes = [ctypes.c_void_p]
  186.        
  187.         self.dave.daveDisconnectPLC.resttype = ctypes.c_int
  188.         self.dave.daveDisconnectPLC.argtypes = [ctypes.c_void_p]
  189.        
  190.         self.dave.daveFree.resttype = None
  191.         self.dave.daveFree.argtypes = [ctypes.c_void_p]
  192.        
  193.         self.dave.daveDisconnectAdapter.resttype = ctypes.c_int
  194.         self.dave.daveDisconnectAdapter.argtypes = [ctypes.c_void_p]
  195.        
  196.         self.dave.daveReadBytes.resttype = ctypes.c_int
  197.         self.dave.daveReadBytes.argtypes = [ctypes.c_void_p,
  198.                                             ctypes.c_int,
  199.                                             ctypes.c_int,
  200.                                             ctypes.c_int,
  201.                                             ctypes.c_int,
  202.                                             ctypes.c_void_p]
  203.        
  204.         self.dave.daveGetCounterValue.resttype = ctypes.c_int
  205.         self.dave.daveGetCounterValue.argtypes = [ctypes.c_void_p,
  206.                                                   ctypes.c_int,
  207.                                                   ctypes.c_int,
  208.                                                   ctypes.c_int,
  209.                                                   ctypes.c_int,
  210.                                                   ctypes.c_void_p]
  211.        
  212.         self.dave.daveWriteBytes.resttype = ctypes.c_int
  213.         self.dave.daveWriteBytes.argtypes = [ctypes.c_void_p,
  214.                                              ctypes.c_int,
  215.                                              ctypes.c_int,
  216.                                              ctypes.c_int,
  217.                                              ctypes.c_int,
  218.                                              ctypes.c_void_p]
  219.        
  220.        
  221.     def set_port(self, port, baud='9600', parity = 'E'):
  222.         """
  223.            set a serial connection port
  224.        """
  225.         self.fds.rfd = self.dave.setPort(port, baud, parity)
  226.         self.fds.wfd = self.fds.rfd
  227.        
  228.     def new_interface(self, name, localMPI, protocol, speed):
  229.         """
  230.            EXPORTSPEC daveInterface * DECL2 daveNewInterface(_daveOSserialType nfd,
  231.                            char * nname, int localMPI, int protocol, int speed);
  232.        """
  233.         self.di = self.dave.daveNewInterface(self.fds, name, localMPI, protocol, speed)
  234.    
  235.     def set_timeout(self, time):
  236.         """
  237.            set a new timeout
  238.            EXPORTSPEC void DECL2 daveSetTimeout(daveInterface * di, int tmo);
  239.        """
  240.         self.dave.daveSetTimeout(self.di, time)
  241.    
  242.     def init_adapter(self):
  243.         """
  244.            initiate the configurated adapter
  245.            EXPORTSPEC int DECL2 _daveInitAdapterNLpro(daveInterface * di);
  246.        """
  247.         self.dave.daveInitAdapter(self.di)
  248.        
  249.     def connect_plc(self, mpi, rack, slot):
  250.         """
  251.            connect to the plc
  252.            daveConnection * DECL2 daveNewConnection(daveInterface * di, int MPI,int rack, int slot);
  253.        """
  254.         self.dc = self.dave.daveNewConnection(self.di, mpi, rack, slot)
  255.         res = self.dave.daveConnectPLC(self.dc)
  256.  
  257.     def disconnect(self):
  258.         """
  259.            disconnect connection to PLC and Adapter
  260.        """
  261.         self.dave.daveDisconnectPLC(self.dc)
  262.         self.dave.daveFree(self.dc)
  263.         self.dave.daveDisconnectAdapter(self.di)
  264.         self.dave.daveFree(self.di)
  265.         return True
  266.        
  267.     def read_bytes(self, area, db, start, len):
  268.         """
  269.            int daveReadBytes(daveConnection * dc, int area, int DB, int start, int len, void * buffer);
  270.            set the pointer to specified memory in the plc
  271.            returns True if pointer is set
  272.        """
  273.         res = self.dave.daveReadBytes(self.dc, area, db, start, len, self.buffer)
  274.         if res == 0:
  275.             return True
  276.         return False
  277.    
  278.     def get_counter_value(self, counter_number):
  279.         """
  280.            read a counter from the plc
  281.        """
  282.         self.read_bytes(daveCounter, 0, 0, 1)  
  283.         counters = list()
  284.         for val in xrange(16):
  285.             counters.append(self.dave.daveGetCounterValue(self.dc))
  286.         return counters[counter_number]
  287.    
  288.     def get_counters(self):
  289.         """
  290.            Liste mit allen Zählern der S5 auslesen und zurückgeben
  291.            TODO: wird das wirklich gebraucht?
  292.        """
  293.         if self.read_bytes(daveCounter, 0, 0, 1):  
  294.             counters = list()
  295.             for val in xrange(16):
  296.                 counters.append(self.dave.daveGetCounterValue(self.dc))
  297.             return counters
  298.         return False
  299.    
  300.     def get_marker_byte(self, marker):
  301.         """
  302.            einen merkerbyte auslesen
  303.            rückgabewert ist ein Integer. Sollen die einzelnen Bits untersucht werden
  304.            muss der rückgabewert nach binär konvertiert werden -> bin(result)
  305.        """
  306.         if self.read_bytes(daveFlags, 0, marker, 1):
  307.             return self.dave.daveGetU8(self.dc)
  308.         return -1
  309.    
  310.     def get_marker(self, marker, byte):
  311.         """
  312.            einen bestimmten Merker aus einem Merkerbyte auslesen
  313.        """
  314.         m_byte = self.get_marker_byte(marker)
  315.         if m_byte >= 0:
  316.             byte_arr = int_to_bitarr(m_byte)
  317.             return byte_arr[byte]
  318.         return False
  319.    
  320.     def get_marker_byte_list(self, marker):
  321.         """
  322.            ein Merkerbyte als liste zurückgeben
  323.            get a list with a bits representing all marker from read byte
  324.        """  
  325.         if self.read_bytes(daveFlags, 0, marker, 1):
  326.             return int_to_bitarr(self.dave.daveGetU8(self.dc))
  327.         return False
  328.    
  329.     def get_marker_byte_dict(self, marker):
  330.         """
  331.            ein Merkerbyte als Dict zurückgeben
  332.        """
  333.         _l = self.get_marker_byte_list(marker)
  334.         print 'libnodave - merkerbyte:', _l
  335.         d = dict()
  336.         for val in xrange(8):
  337.             d[val]=_l[val]
  338.         return d
  339.        
  340.     def write_marker_byte(self, marker, value):
  341.         """
  342.            EXPORTSPEC int DECL2 daveWriteBytes(daveConnection * dc, int area, int DB, int start,
  343.                                                int len, void * buffer);
  344.            ein Merkerbyte in die SPS schreiben
  345.            TODO: anpassen und testen
  346.        """
  347.         buffer = ctypes.c_byte(int(value))
  348.         buffer_p =  ctypes.pointer(buffer)
  349.         self.dave.daveWriteBytes(self.dc, daveFlags, 0, marker, 1, buffer_p)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement