def execute_monitor(self, timeout=0): """モニタ登録したデバイスのデータを読み取る :param int timeout: タイムアウト、250msec単位 :return: デバイスに入っていたデータ(ワードアクセス分のリスト, ダブルワードアクセス分のリスト) :rtype: (List[int], List[bytes]) """ cmd = const.SLMPCommand.Device_ExecuteMonitor sub_cmd = 0x00 if ( self.__monitor_device_num[0] == 0 and self.__monitor_device_num[1] == 0 ): raise RuntimeError("モニタデバイス未登録") seq = self.__cmd_format(timeout, cmd, sub_cmd, b"") try: data = self.__recv_loop(seq, timeout) except TimeoutError as e: raise TimeoutError() from e buf = data[5] if isinstance(buf, str): # ASCII bytes_buf = util.str2bytes_buf(buf) bytes_buf.reverse() word_data = list() dword_data = list() for _ in range(self.__monitor_device_num[0]): d1 = bytes_buf.pop() d2 = bytes_buf.pop() word_data.append(bytes([d2, d1])) for _ in range(self.__monitor_device_num[1]): d1 = bytes_buf.pop() d2 = bytes_buf.pop() d3 = bytes_buf.pop() d4 = bytes_buf.pop() dword_data.append(bytes([d4, d3, d2, d1])) else: split_pos = self.__monitor_device_num[0] * 2 dword_data, word_data = util.extracts_word_dword_data( buf, split_pos ) return word_data, dword_data
def read_random_devices(self, word_list, dword_list, timeout=0): """指定した連続していないデバイスのデータを読む :param word_list: ワードアクセスするデバイスのリスト :type word_list: List[(const.DeviceCode, int)] :param dword_list: ダブルワードアクセスするデバイスのリスト :type dword_list: List[(const.DeviceCode, int)] :param int timeout: タイムアウト、250msec単位 :return: デバイスに入っていたデータ(ワードアクセス分のリスト, ダブルワードアクセス分のリスト) :rtype: (List[int], List[bytes]) """ cmd = const.SLMPCommand.Device_ReadRandom sub_cmd = 0x0000 buf = self.__format_device_list(word_list, dword_list) seq = self.__cmd_format(timeout, cmd, sub_cmd, buf) try: data = self.__recv_loop(seq, timeout) except TimeoutError as e: raise TimeoutError(word_list, dword_list) from e buf = data[5] if isinstance(buf, str): # ASCII bytes_buf = util.str2bytes_buf(buf) bytes_buf.reverse() word_data = list() dword_data = list() for _ in range(len(word_list)): d1 = bytes_buf.pop() d2 = bytes_buf.pop() word_data.append(bytes([d2, d1])) for _ in range(len(dword_list)): d1 = bytes_buf.pop() d2 = bytes_buf.pop() d3 = bytes_buf.pop() d4 = bytes_buf.pop() dword_data.append(bytes([d4, d3, d2, d1])) else: split_pos = len(word_list) * 2 dword_data, word_data = util.extracts_word_dword_data( buf, split_pos ) return word_data, dword_data
def read_block(self, word_list, bit_list, timeout=0): """ブロックで読み出す :param word_list: ワード単位でアクセスするデバイスブロックのリスト (デバイスコード, アドレス, 点数) :type word_list: List[(const.DeviceCode, int, int)] :param bit_list: ビット単位でアクセスするデバイスブロックのリスト (デバイスコード, アドレス, 点数) :type bit_list: List[(const.DeviceCode, int, int)] :param int timeout: タイムアウト、250msec単位 :return: デバイスに入っていたデータ(ワードアクセス分のリスト, ビットアクセス分のリスト) :rtype: (List[List[int]], List[List[bool]) """ cmd = const.SLMPCommand.Device_ReadBlock sub_smd = 0x00 if self.__protocol[0]: # Binary buf = struct.pack("<BB", len(word_list), len(bit_list)) for dc, addr, num in word_list + bit_list: buf += struct.pack("<I", addr)[:-1] buf += struct.pack("<BH", dc.value, num) else: # ASCII buf = b"%02X%02X" % (len(word_list), len(bit_list)) for dc, addr, num in word_list + bit_list: buf += dc.name.encode("ascii") if len(dc.name) == 1: buf += b"*" if dc in const.D_ADDR_16: buf += b"%06X%04X" % (addr, num) else: buf += b"%06d%04X" % (addr, num) seq = self.__cmd_format(timeout, cmd, sub_smd, buf) try: data = self.__recv_loop(seq, timeout) except TimeoutError as e: raise TimeoutError() from e buf = data[5] if isinstance(buf, str): # ASCII bytes_buf = util.str2bytes_buf(buf) a_flag = True else: bytes_buf = bytearray(buf[:]) a_flag = False bytes_buf.reverse() word_data = list() bit_data = list() for dc1, addr1, num1 in word_list: tmp_buf = list() for _ in range(num1): d1 = bytes_buf.pop() d2 = bytes_buf.pop() if a_flag: d2, d1 = d1, d2 tmp_buf.append(bytes([d1, d2])) word_data.append(tmp_buf) for dc1, addr1, num1 in bit_list: tmp_buf = list() for _ in range(num1): d1 = bytes_buf.pop() d2 = bytes_buf.pop() if a_flag: d2, d1 = d1, d2 tmp_buf.extend(util.unpack_bits([d1, d2])) bit_data.append(tmp_buf) return word_data, bit_data