Example #1
0
class LogixDriverCOMServer:
    _reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER
    _public_methods_ = ['open', 'close', 'read_tag', 'write', ] #'get_plc_info', 'get_plc_name', 'get_tag_list']
    _readonlu_attrs_ = []
    _public_attrs_ = []
    # _readonly_attrs_ = ['tags', 'info', 'name']
    # _public_attrs_ = ['path', 'large_packets', 'init_tags', 'init_program_tags' ] + _readonly_attrs_

    _reg_clsid_ = CLSID
    _reg_desc_ = 'Pycomm3 - Python Ethernet/IP ControlLogix Library COM Server'
    _reg_progid_ = 'Pycomm3.COMServer'

    def __init__(self):
        self.plc: LogixDriver = None

    def open(self, path, init_tags=True, init_program_tags=False, init_info=True):
        self.plc = LogixDriver(path, init_tags=init_tags, init_program_tags=init_program_tags, init_info=init_info)
        self.plc.open()

    def close(self):
        self.plc.close()

    def read(self, tag):
        result = self.plc.read(tag)
        return result.value if result else None

    def write(self, *tag_values):
        return self.plc.write(*tag_values)
Example #2
0
def array_read():
    plc_path = request.args.get('plc')
    data = json.loads(request.data)
    if plc_path in plc_connections.keys():
        plc = plc_connections[plc_path]
    else:
        plc = LogixDriver(plc_path)
        plc_connections[plc_path] = plc
    tag = request.args.get('tag')
    tag_type = plc.tags[tag.split('[')[0]]['data_type_name']
    value = types[tag_type](request.args.get('value'))
    error = plc.write((tag, value)).error
    if error is not None:
        import traceback
        raise Exception(traceback.format_exc())
    return jsonify({'status': 'success'})
class allenbradley_logix(driver):
    '''
    This driver supports services specific to ControlLogix, CompactLogix, and Micro800 PLCs.
    The driver is based on the library pycomm3: https://github.com/ottowayi/pycomm3.

    Parameters:
    ip  : String    : ip address of the PLC
    '''

    def __init__(self, name: str, pipe: Optional[Pipe] = None):
        """
        :param name: (optional) Name for the driver
        :param pipe: (optional) Pipe used to communicate with the driver thread. See gateway.py
        """
        # Inherit
        driver.__init__(self, name, pipe)
        
        self.ip = '192.168.0.1'


    def connect(self) -> bool:
        """ Connect driver.
        
        : returns: True if connection stablished False if not
        """
        # Create connection
        try:
            self._connection = LogixDriver(self.ip)
            self._connection.open()
        except Exception as e:
            self.sendDebugInfo(f"Connection with {self.ip} cannot be stablished.")
            return False

        # Check connection status.
        if self._connection.connected:
            return True
        else:
            self.sendDebugInfo(f"Driver not connected.") 
            return False


    def disconnect(self):
        """ Disconnect driver.
        """
        if self._connection:
            self._connection.close()


    def addVariables(self, variables: dict):
        """ Add variables to the driver. Correctly added variables will be added to internal dictionary 'variables'.
        Any error adding a variable should be communicated to the server using sendDebugInfo() method.
        : param variables: Variables to add in a dict following the setup format. (See documentation) 
        """
        for var_id in list(variables.keys()):
            var_data = dict(variables[var_id])
            try:
                var_data['value'] = None
                self.variables[var_id] = var_data 
            except Exception as e:
                self.sendDebugInfo(f'SETUP: {e} \"{var_id}\"')
                

    def readVariables(self, variables: list) -> list:
        """ Read given variable values. In case that the read is not possible or generates an error BAD quality should be returned.
        : param variables: List of variable ids to be read. 
        : returns: list of tupples including (var_id, var_value, VariableQuality)
        """
        res = []
        try:
            values = self._connection.read(*variables)
            if not isinstance(values, list):
                values = [values]
            for (tag, value, _, error) in values:
                if error:
                    res.append((tag, None, VariableQuality.BAD))
                else:
                    res.append((tag, value, VariableQuality.GOOD))
        except Exception as e:
            self.sendDebugInfo(f'exception reading variable values: {e}')
        return res


    def writeVariables(self, variables: list) -> list:
        """ Write given variable values. In case that the write is not possible or generates an error BAD quality should be returned.
        : param variables: List of tupples with variable ids and the values to be written (var_id, var_value). 
        : returns: list of tupples including (var_id, var_value, VariableQuality)
        """
        res = []

        try:
            values = self._connection.write(*variables)
            if not isinstance(values, list):
                values = [values]
            for (tag, value, _, error) in values:
                if error:
                    res.append((tag, value, VariableQuality.BAD))
                else:
                    res.append((tag, value, VariableQuality.GOOD))
        except Exception as e:
            self.sendDebugInfo(f'exception writing variable values: {e}')

        return res