diff --git a/README.rst b/README.rst index 95c9a90..2180945 100644 --- a/README.rst +++ b/README.rst @@ -60,10 +60,14 @@ use the ``slot`` kwarg if the PLC is not in slot 0. Controllers with on-board e # Read a tag plc.read_tag('DINT1') + # Returns: (1, 'DINT'), a (value, data type) tuple + # Read a list of tags plc.read_tag(['Tag1', 'Tag2', 'Tag3']) # or plc.read_tag('Tag1', 'Tag2', 'Tag3') + # Returns: [('Tag1', 0, 'DINT'), ('Tag2', 1, 'DINT'), ('Tag3, 2, 'DINT')] + # Reading multiple tags includes the tag name with each result # To read all the DINT controller-scoped tags: dint_tags = [tag for tag in plc.tags if plc.tags[tag].get('data_type') == 'DINT'] @@ -93,7 +97,7 @@ use the ``slot`` kwarg if the PLC is not in slot 0. Controllers with on-board e # RETURN: True (if successful, False if not) plc.write_tag([('DINT1', -1, 'DINT'), ('DINT2', 0, 'DINT'), ('DINT3', 1, 'DINT')]) - # RETURN: [('DINT1', -1, 'DINT', 'GOOD'), ('DINT2', 0, 'DINT', 'GOOD'), ('DINT3', 1, 'DINT', 'GOOD')] + # RETURN: [('DINT1', -1, 'DINT', True), ('DINT2', 0, 'DINT', True), ('DINT3', 1, 'DINT', True)] # Writing multiple tags will return the Tag Name, Value written, Data Type, and True/False # Writing Strings diff --git a/pycomm3/__init__.py b/pycomm3/__init__.py index b8d5eda..9ffe847 100644 --- a/pycomm3/__init__.py +++ b/pycomm3/__init__.py @@ -24,7 +24,7 @@ # SOFTWARE. # -__version_info__ = (0, 1, 0) +__version_info__ = (0, 1, 1) __version__ = '.'.join(f'{x}' for x in __version_info__) diff --git a/pycomm3/base.py b/pycomm3/base.py index 2fff593..c020b19 100644 --- a/pycomm3/base.py +++ b/pycomm3/base.py @@ -226,7 +226,8 @@ def register_session(self): reply = self._receive() if self._check_reply(reply): self._session = unpack_dint(reply[4:8]) - self.__log.debug("Session ={0} has been registered.".format(print_bytes_line(reply[4:8]))) + if self._debug: + self.__log.debug("Session ={0} has been registered.".format(print_bytes_line(reply[4:8]))) return self._session self._status = 'Warning ! the session has not been registered.' diff --git a/pycomm3/clx.py b/pycomm3/clx.py index 4093578..934aed6 100644 --- a/pycomm3/clx.py +++ b/pycomm3/clx.py @@ -83,7 +83,7 @@ def __init__(self, ip_address, *args, slot=0, large_packets=True, init_info=True self.use_instance_ids = self.info.get('version_major', 0) >= MIN_VER_INSTANCE_IDS if init_tags: - self._tags = self.get_tag_list() + self.get_tag_list() self.close() def _check_reply(self, reply): @@ -127,7 +127,6 @@ def create_tag_rp(self, tag, multi_requests=False): If any error it returns none """ tags = tag.split('.') - index = [] if tags: base, *attrs = tags @@ -145,16 +144,13 @@ def create_tag_rp(self, tag, multi_requests=False): rp.append(PADDING_BYTE) for attr in attrs: - # Check if is an array tag - if '[' in attr: - # Remove the last square bracket - attr = attr[:len(attr) - 1] - # Isolate the value inside bracket - inside_value = attr[attr.find('[') + 1:] - # Now split the inside value in case part of multidimensional array - index = inside_value.split(',') - # Get only the tag part - attr = attr[:attr.find('[')] + if '[' in attr: # Check if is an array tag + attr = attr[:len(attr) - 1] # Remove the last square bracket + inside_value = attr[attr.find('[') + 1:] # Isolate the value inside bracket + index = inside_value.split(',') # Now split the inside value in case part of multidimensional array + attr = attr[:attr.find('[')] # Get only the tag part + else: + index = [] tag_length = len(attr) # Create the request path @@ -175,8 +171,7 @@ def create_tag_rp(self, tag, multi_requests=False): elif val <= 0xfffffffff: attr_path += [ELEMENT_ID["32-bit"], PADDING_BYTE, pack_dint(val)] else: - # Cannot create a valid request packet - return None + return None # Cannot create a valid request packet rp += attr_path @@ -394,7 +389,7 @@ def _write_tag_multi_write(self, tags): rp = self.create_tag_rp(name, multi_requests=True) request = bytes([TAG_SERVICES_REQUEST["Read Modify Write Tag"]]) + rp request += b''.join(self._make_write_bit_data(bit, value, bool_ary='[' in name)) - if typ == 'BOOL' and name.endswith('['): + if typ == 'BOOL' and name.endswith(']'): name = self._dword_to_boolarray(name, bit) else: name = f'{name}.{bit}' diff --git a/pycomm3/const.py b/pycomm3/const.py index c164e62..6eb47e2 100644 --- a/pycomm3/const.py +++ b/pycomm3/const.py @@ -31,6 +31,7 @@ MULTISERVICE_READ_OVERHEAD = 6 MULTISERVICE_WRITE_OVERHEAD = 3 MIN_VER_INSTANCE_IDS = 21 # using Symbol Instance Addressing not supported below version 21 +MIN_VER_LARGE_CONNECTIONS = 20 # >500 byte connections not supported below logix v20 EXTENDED_SYMBOL = b'\x91' BOOL_ONE = 0xff REQUEST_SERVICE = 0 @@ -119,7 +120,7 @@ CONNECTION_MANAGER_INSTANCE = { 'Open Request': b'\x01', 'Open Format Rejected': b'\x02', - 'Open Resource Rejected': b'\x03', + 'Open Resource Rejected': b'\x03', 'Open Other Rejected': b'\x04', 'Close Request': b'\x05', 'Close Format Request': b'\x06', diff --git a/setup.py b/setup.py index 9b048cf..48dfeb1 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,6 @@ def read(file_name): author='Ian Ottoway', author_email="ian@ottoway.dev", url="https://github.com/ottowayi/pycomm3", - download_url="", description="A PLC communication library for Python", long_description=read('README.rst'), license="MIT",