Example #1
0
def tag_list_equal():
    with LogixDriver('10.61.50.4/10') as plc:
        tag_list = plc.get_tag_list()
        if {tag['tag_name']: tag for tag in tag_list} == plc.tags:
            print('They are the same!')

    with LogixDriver('10.61.50.4/10', init_tags=False) as plc2:
        plc2.get_tag_list()

    if plc.tags == plc2.tags:
        print('Calling get_tag_list() does the same thing.')
    else:
        print('Calling get_tag_list() does NOT do the same.')
Example #2
0
def read():
    try:
        plc_path = request.args.get('plc')
        tag = request.args.get('tag')
        if plc_path in plc_connections.keys():
            plc = plc_connections[plc_path]
        else:
            plc = LogixDriver(plc_path)
            plc_connections[plc_path] = plc
        val = plc.read(tag).value
        return jsonify({'status': 'success', 'val': val})
    except:
        import traceback
        return jsonify({'status': 'error', 'val': traceback.format_exc()})
Example #3
0
def read_plc(ip_address, tag_name):
    try:
        with LogixDriver(ip_address) as plc:
            return plc.read(tag_name)
    except:
        #log error
        return ""
Example #4
0
def read_all_plc(ip_address):
    try:
        with LogixDriver(ip_address) as plc:
            return plc.tags
    except:
        # Log error#
        return ""
Example #5
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'})
Example #6
0
def test_connect_init_tags():
    with LogixDriver(PATH) as plc:
        assert len(plc.tags) > 0
        assert isinstance(plc.tags, dict)
        assert 'Pycomm3_Testing' in plc.info['programs']

        assert plc.tags == {tag['tag_name']: tag for tag in plc.get_tag_list()}
Example #7
0
def info_plc(ip_address):
    try:
        with LogixDriver(ip_address) as plc:
            return plc.info
    except:
        # Log error
        return ""
Example #8
0
def test_connect_init_info():
    with LogixDriver(PATH, init_info=True, init_tags=False) as plc:
        assert plc.info['name'] == plc.name
        assert plc.info['vendor'] == 'Rockwell Automation/Allen-Bradley'
        assert plc.info['keyswitch'] == 'REMOTE RUN'
        assert 'modules' not in plc.info
        assert 'tasks' not in plc.info
        assert 'programs' not in plc.info
Example #9
0
def connectToPlc(ipAddress):
    try:
        myPlc = LogixDriver(ipAddress)
    except:
        log.exception('PLC connection error.')
    else:
        log.info("Connected to PLC.")
        return myPlc
    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
Example #11
0
def write_plc(ip_address, tag_name, tag_value):
    try:

        with LogixDriver(ip_address) as plc:
            result = plc.write(tag_name, tag_value)
            return result

    except:
        # log error
        return ""
Example #12
0
def find_pids():
    with LogixDriver('10.61.50.4/10') as plc:

        # PIDs are structures, the data_type attribute will be a dict with data type definition.
        # For tag types of 'atomic' the data type will a string, we need to skip those first.
        # Then we can just look for tags whose data type name matches 'PID'
        pid_tags = [
            tag for tag, _def in plc.tags.items()
            if _def['data_type_name'] == 'PID'
        ]

        print(pid_tags)
Example #13
0
def discoverPLCs(): # Function to discover any PLC on the network
    ips, slots, progName = [], [], []
    try:
        discovery = CIPDriver.discover() # Return list of all CIP devices on the network
        for device in discovery: # Go through discovery list and append any PLC#'s to a list
            if device['product_type'] == "Programmable Logic Controller":
                ips.append(device['ip_address'])        
        if len(ips) > 0: # Print the discovered PLC's, if there are any
            ips.sort() # Sort the IP address in ascending order
            table = Table(box=box.ROUNDED) # Create table 
            table.add_column('#', justify='center') # Add column
            table.add_column('Device Type', justify='center') # Add column
            table.add_column('IP Address', justify='center') # Add column
            table.add_column('Slot #', justify='center') # Add column
            table.add_column('Program Name', justify='center') # Add column
            for i, ip in enumerate(ips): # Add row for each PLC discovered
                slots.append('Unknown')
                progName.append('Unknown')
                for slot in range(1, 18):
                    try:
                        plc = LogixDriver(f'{plc}/{str(slot)}', init_tags=False)
                        if plc.open():
                            slots[i] = slot
                            progName[i] = plc.get_plc_name()
                            plc.close()
                            break
                    except:
                        continue
                table.add_row(str(i+1), 'Programmable Logic Controller', ip, str(slots[i]), progName[i])
            print(table)
        else:
            print("No PLC's discovered on the network")
    except Exception:
        traceback.print_exc()
Example #14
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 #15
0
def write_pf525_parameter():
    drive_path = '10.10.10.100/bp/1/enet/192.168.1.55'

    with LogixDriver(drive_path, init_tags=False, init_info=False) as drive:
        drive.generic_message(
            service=CommonService.set_attribute_single,
            class_code=b'\x93',
            instance=b'\x29',  # (hex) Parameter 41 = Accel Time
            attribute=b'\x09',
            request_data=Pack.int(500),  # 5s = seconds * 100
            connected=False,
            unconnected_send=True,
            route_path=True,
            name='pf525_param')
Example #16
0
    def poll_plc(self):
        while self.run_poll:
            while self.ui.pushButton_poll.isChecked():
                if int(self.ui.label_countdown.text()) > self.ui.spinBox_poll.value():
                    self.ui.label_countdown.setText(str(self.ui.spinBox_poll.value()))
                if int(self.ui.label_countdown.text()) < 1:
                    self.ui.label_countdown.setText(str(self.ui.spinBox_poll.value()))
                    try:
                        
                        with LogixDriver(self.ui.lineEdit_ip.text()) as plc:
                            curr_datetime = datetime.now()
                            date_stamp = curr_datetime.strftime("%Y-%m-%d %H:%M:%S")
                            
                            
                            row = self.ui.tableWidget.rowCount()
                            if row >= self.ui.spinBox_chart_points.value():
                                self.ui.tableWidget.removeRow(row-1)
                            self.ui.tableWidget.insertRow(0)
                            self.ui.tableWidget.setItem(0, 0, QTableWidgetItem(date_stamp))

                            with open(self.ui.label_log_file.text(), "a", newline="") as outfile:
                                writer = csv.writer(outfile)
                                for i in self.settings["tags"]:
                                    fields = []
                                    fields.append(date_stamp)
                                    val = round(plc.read(i).value, 2)
                                    fields.append(i)
                                    fields.append(val)
                                    writer.writerow(fields)

                                    if i == self.ui.comboBox_chart_tag.currentText():
                                        self.x.append(curr_datetime)
                                        self.y.append(val)
                                        if len(self.x) > self.ui.spinBox_chart_points.value():
                                            self.x.pop(0)
                                        if len(self.y) > self.ui.spinBox_chart_points.value():
                                            self.y.pop(0)
                                        self.refresh_chart()

                                    self.ui.tableWidget.setItem(0, self.settings["tags"].index(i)+1, QTableWidgetItem("%.2f" % val))
                    except Exception as error:
                        self.ui.label_error.setStyleSheet("background-color: rgba(255, 0, 0, 0.5);")
                        self.ui.label_error.setText(str(error))
                        time.sleep(10)
                    else:
                        self.ui.label_error.setStyleSheet("background-color: rgba(35, 199, 35, 1);")
                        self.ui.label_error.setText(" ")
                
                time.sleep(1)
                self.ui.label_countdown.setText(str(int(self.ui.label_countdown.text()) - 1))
Example #17
0
def write_structure():

    with LogixDriver('10.61.50.4/10') as plc:
        recipe_data = [
            True, [10, 11, 4, 20, 6, 20, 6, 30, 5, 0],
            [100, 500, 85, 5, 15, 10.5, 20, 0, 0, 0],
            [
                'Set Water Temperature', 'Heated Water', 'Start Agitator',
                'Hand Add - Flavor Part 1', 'Timed Mix',
                'Hand Add - Flavor Part 2', 'Timed Mix',
                'Transfer to Storage Tank', 'Disable Agitator', ''
            ], ['°F', 'lbs', '%', 'gal', 'min', 'lbs', 'min', '', '', ''],
            'Our Fictional Recipe'
        ]

        plc.write(('Example_Recipe', recipe_data))
Example #18
0
def read_pf525_parameter():
    drive_path = '10.10.10.100/bp/1/enet/192.168.1.55'

    with LogixDriver(drive_path, init_tags=False, init_info=False) as drive:
        param = drive.generic_message(
            service=CommonService.get_attribute_single,
            class_code=b'\x93',
            instance=b'\x29',  # (hex) Parameter 41 = Accel Time
            attribute=b'\x09',
            connected=False,
            unconnected_send=True,
            route_path=True,
            data_format=[
                ('AccelTime', 'INT'),
            ],
            name='pf525_param')
        print(param)
Example #19
0
    def poll_plc(self):
        while True:
            while self.ui.pushButton_poll.isChecked():
                self.find_checked()

                try:
                    fields = []
                    with LogixDriver(self.ui.comboBox_ip.currentText()) as plc:
                        date_stamp = datetime.now().strftime(
                            "%Y-%m-%d %H:%M:%S")
                        fields.append(date_stamp)

                        row = self.ui.tableWidget.rowCount() - 1
                        if row >= 20:
                            self.ui.tableWidget.removeRow(row - 1)
                        self.ui.tableWidget.insertRow(0)
                        self.ui.tableWidget.setItem(
                            0, 0, QTableWidgetItem(date_stamp))

                        with open("test.csv", "a", newline="") as outfile:
                            writer = csv.writer(outfile)
                            for i in self.poll_tags:
                                val = round(
                                    plc.read(self.poll_tags[i] +
                                             ".EuOut").value, 2)
                                fields.append(self.poll_tags[i])
                                fields.append(val)
                                writer.writerow(fields)

                                self.ui.tableWidget.setItem(
                                    0, i, QTableWidgetItem("%.2f" % val))
                        #for i in self.poll_tags:
                        #    fields.append(plc.read(self.poll_tags[i] + ".EuOut").value)

                except Exception as error:
                    self.ui.label_error.setStyleSheet(
                        "background-color: rgba(255, 0, 0, 0.5);")
                    self.ui.label_error.setText(str(error))
                    time.sleep(10)
                else:
                    self.ui.label_error.setStyleSheet(
                        "background-color: rgba(35, 199, 35, 1);")
                    self.ui.label_error.setText(" ")

                time.sleep(self.ui.spinBox_poll.value())
Example #20
0
    def get_plc_tags(self):
        self.tags.clear()
        self.ui.treeWidget
        with LogixDriver(self.ui.comboBox_ip.currentText()) as plc:
            self.tags = plc.get_tag_list()
        for i in self.tags:
            parent = QTreeWidgetItem(self.ui.treeWidget)
            parent.setText(0, "{}".format(i['tag_name']))
            if type(i['data_type']) == str:
                parent.setText(1, i['data_type'])
            parent.setFlags(parent.flags() | Qt.ItemIsUserCheckable)
            parent.setCheckState(0, Qt.Unchecked)
            #for x in range(5):
            #    child = QTreeWidgetItem(parent)
            #    child.setFlags(child.flags() | Qt.ItemIsUserCheckable)
            #    child.setText(0, "Child {}".format(x))
            #    child.setCheckState(0, Qt.Unchecked)

        self.ui.treeWidget.sortByColumn(0)
        self.ui.treeWidget.resizeColumnToContents(0)
Example #21
0
def read_single():
    with LogixDriver('10.61.50.4/10') as plc:
        return plc.read('DINT1')
Example #22
0
def read_udt():
    with LogixDriver('10.61.50.4/10') as plc:
        return plc.read('SimpleUDT1_1')
Example #23
0
def read_strings():
    with LogixDriver('10.61.50.4/10') as plc:
        return plc.read('STRING1', 'STRING_ARY1[2]{2}')
Example #24
0
def read_array_slice():
    with LogixDriver('10.61.50.4/10') as plc:
        return plc.read('DINT_ARY1[50]{5}')
Example #25
0
#!/usr/bin/env python3
"""
Python script to dump tags from AB-Logix PLC to JSON file

Usage:

./fetch-tags.py <IP[PATH]>  > tags.json
"""

import argparse

try:
    import rapidjson as json
except:
    import json

from pycomm3 import LogixDriver

ap = argparse.ArgumentParser()

ap.add_argument("source", metavar="PLC", help="PLC host/ip and path")

a = ap.parse_args()

with LogixDriver(a.source) as plc:
    print(json.dumps(plc.get_tag_list()))
Example #26
0
def write_multiple():
    with LogixDriver('10.61.50.4/10') as plc:
        return plc.write(('REAL2', 25.2),
                         ('STRING3', 'A test for writing to a string.'))
Example #27
0
def write_single():
    with LogixDriver('10.61.50.4/10') as plc:
        return plc.write(('DINT2', 100_000_000))
Example #28
0
def read_timer():
    with LogixDriver('10.61.50.4/10') as plc:
        return plc.read('TIMER1')
Example #29
0
def read_multiple():
    tags = ['DINT1', 'SINT1', 'REAL1']
    with LogixDriver('10.61.50.4/10') as plc:
        return plc.read(*tags)
Example #30
0
import os
from pycomm3 import LogixDriver

ip_cl = os.environ["controllogix"]
try:
    print('\033[46;1mControlLogix 5581E PLC - ' + ip_cl + ':\033[0m')
    with LogixDriver(ip_cl) as plc:
        print(plc.get_tag_list())
except:
    print('\033[41;1mSomething went wrong while connecting to ' + ip_cl +
          '\033[0m')