### Install pymcprotocol Source: https://pymcprotocol.netlify.app/ Install the pymcprotocol library using pip. This is the first step to using the library. ```bash pip install pymcprotocol ``` -------------------------------- ### POST /remote_run Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Starts the PLC remotely with specified clear mode settings. ```APIDOC ## POST /remote_run ### Description Runs the PLC remotely. ### Parameters #### Request Body - **clear_mode** (int) - Required - 0: no clear, 1: clear except latch, 2: clear all - **force_exec** (bool) - Optional - Force execution if operated by another device ``` -------------------------------- ### Batch Read/Write Operations Source: https://pymcprotocol.netlify.app/ Perform batch read and write operations for word and bit units. Specify the starting device and the number of units to read or write. ```python #read from D100 to D110 wordunits_values = pymc3e.batchread_wordunits(headdevice="D100", readsize=10) #read from X10 to X20 bitunits_values = pymc3e.batchread_bitunits(headdevice="X10", readsize=10) #write from D10 to D15 pymc3e.batchwrite_wordunits(headdevice="D10", values=[0, 10, 20, 30, 40]) #write from Y10 to Y15 pymc3e.batchwrite_bitunits(headdevice="Y10", values=[0, 1, 0, 1, 0]) ``` -------------------------------- ### Batch Write Word Units Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Writes a list of values to the PLC starting at the specified head device in word units. ```APIDOC ## batchwrite_wordunits ### Description Writes a batch of word unit values to the PLC starting at the specified head device. ### Parameters - **headdevice** (str) - Required - Write head device (e.g., "D1000") - **values** (list[int]) - Required - List of values to write. ``` -------------------------------- ### Batch Write Bit Units Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Writes a list of bit values (0 or 1) to the PLC starting at the specified head device. ```APIDOC ## batchwrite_bitunits ### Description Writes a batch of bit unit values to the PLC starting at the specified head device. ### Parameters - **headdevice** (str) - Required - Write head device (e.g., "X10") - **values** (list[int]) - Required - List of values to write (0 for OFF, 1 for ON). ``` -------------------------------- ### GET /read_cputype Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Retrieves the CPU type and CPU code from the connected PLC. ```APIDOC ## GET /read_cputype ### Description Reads the CPU type and CPU code from the PLC. ### Method GET ### Endpoint /read_cputype ### Response #### Success Response (200) - **cpu_type** (str) - The model name of the CPU. - **cpu_code** (str) - The 4-character hexadecimal CPU code. ``` -------------------------------- ### POST /connect Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Establishes a TCP/IP connection to the target PLC. ```APIDOC ## POST /connect ### Description Connects to a PLC using the specified IP address and port number. ### Method POST ### Endpoint /connect ### Parameters #### Request Body - **ip** (str) - Required - IP address (IPv4) of the PLC. - **port** (int) - Required - Port number of the PLC. - **timeout** (float) - Optional - Timeout in seconds for the communication. ``` -------------------------------- ### Type3E Connection and Configuration Source: https://pymcprotocol.netlify.app/pymcprotocol Methods for initializing the Type3E client, establishing a connection to the PLC, and configuring communication parameters. ```APIDOC ## Type3E Connection ### Description Initializes the Type3E client and manages the socket connection to the PLC. ### Methods - **__init__(plctype='Q')**: Constructor for the Type3E class. - **connect(ip, port, timeout)**: Establishes a connection to the PLC. - **close()**: Closes the active connection. - **setaccessopt(...)**: Configures communication settings like commtype, network, pc, and timer. ### Parameters #### connect - **ip** (str) - Required - IP address (IPV4) of the PLC. - **port** (int) - Required - Port number. - **timeout** (float) - Optional - Timeout in seconds. #### setaccessopt - **commtype** (str) - Optional - "binary" or "ascii". - **network** (int) - Optional - Network number (0-255). - **pc** (int) - Optional - Station number (0-255). - **timer_sec** (int) - Optional - Timeout in seconds. ``` -------------------------------- ### Connect to PLC with pymcprotocol Source: https://pymcprotocol.netlify.app/ Initialize and connect to a PLC using the Type3E or Type4E protocol. Specify the PLC type (e.g., 'L', 'iQ-L', 'iQ-R') if not using the default Q series. Configure communication type to 'ascii' if needed. ```python import pymcprotocol #If you use Q series PLC pymc3e = pymcprotocol.Type3E() #if you use L series PLC, pymc3e = pymcprotocol.Type3E(plctype="L") #if you use QnA series PLC, pymc3e = pymcprotocol.Type3E(plctype="L") #if you use iQ-L series PLC, pymc3e = pymcprotocol.Type3E(plctype="iQ-L") #if you use iQ-R series PLC, pymc3e = pymcprotocol.Type3E(plctype="iQ-R") #If you use 4E type pymc4e = pymcprotocol.Type4E() #If you use ascii byte communication. (default is "binary") pymc3e.setaccessopt(commtype="ascii") pymc3e.connect("192.168.1.2", 1025) ``` -------------------------------- ### Send and Receive MC Data Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e This snippet demonstrates sending and receiving data using the MC protocol. It includes making command data, encoding values, constructing the send data, sending it, receiving the response, and checking the answer. PLC must be stopped when using this command. ```python command = 0x1005 subcommand = 0x0000 request_data = bytes() request_data += self._make_commanddata(command, subcommand) request_data += self._encode_value(0x0001, mode="short") #fixed value send_data = self._make_senddata(request_data) #send mc data self._send(send_data) #reciev mc data recv_data = self._recv() self._check_cmdanswer(recv_data) return None ``` -------------------------------- ### Set Access Options Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Configures network, station, and timeout parameters for MC protocol access. Validates input ranges and updates socket timeouts if connected. ```python def setaccessopt(self, commtype=None, network=None, pc=None, dest_moduleio=None, dest_modulesta=None, timer_sec=None): """Set mc protocol access option. Args: commtype(str): communication type. "binary" or "ascii". (Default: "binary") network(int): network No. of an access target. (0<= network <= 255) pc(int): network module station No. of an access target. (0<= pc <= 255) dest_moduleio(int): When accessing a multidrop connection station via network, specify the start input/output number of a multidrop connection source module. the CPU module of the multiple CPU system and redundant system. dest_modulesta(int): accessing a multidrop connection station via network, specify the station No. of aaccess target module timer_sec(int): Time out to return Timeout Error from PLC. MC protocol time is per 250msec, but for ease, setaccessopt requires per sec. Socket time out is set timer_sec + 1 sec. """ if commtype: self._set_commtype(commtype) if network: try: network.to_bytes(1, "little") self.network = network except: raise ValueError("network must be 0 <= network <= 255") if pc: try: pc.to_bytes(1, "little") self.pc = pc except: raise ValueError("pc must be 0 <= pc <= 255") if dest_moduleio: try: dest_moduleio.to_bytes(2, "little") self.dest_moduleio = dest_moduleio except: raise ValueError("dest_moduleio must be 0 <= dest_moduleio <= 65535") if dest_modulesta: try: dest_modulesta.to_bytes(1, "little") self.dest_modulesta = dest_modulesta except: raise ValueError("dest_modulesta must be 0 <= dest_modulesta <= 255") if timer_sec: try: timer_250msec = 4 * timer_sec timer_250msec.to_bytes(2, "little") self.timer = timer_250msec self.soc_timeout = timer_sec + 1 if self._is_connected: self._sock.settimeout(self.soc_timeout) except: raise ValueError("timer_sec must be 0 <= timer_sec <= 16383, / sec") return None ``` -------------------------------- ### Make MC Protocol Device Data Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Prepares device data bytes, including device type code and number, based on the PLC type and communication mode (binary or ASCII). Raises a ValueError for invalid device formats. ```python def _make_devicedata(self, device): """make mc protocol device data. (device code and device number) Args: device(str): device. (ex: "D1000", "Y1") Returns: device_data(bytes): device data """ device_data = bytes() devicetype = re.search(r"\D+", device) if devicetype is None: raise ValueError("Invalid device ") else: devicetype = devicetype.group(0) if self.commtype == const.COMMTYPE_BINARY: devicecode, devicebase = const.DeviceConstants.get_binary_devicecode(self.plctype, devicetype) devicenum = int(get_device_number(device), devicebase) if self.plctype is const.iQR_SERIES: device_data += devicenum.to_bytes(4, "little") device_data += devicecode.to_bytes(2, "little") else: device_data += devicenum.to_bytes(3, "little") device_data += devicecode.to_bytes(1, "little") else: devicecode, devicebase = const.DeviceConstants.get_ascii_devicecode(self.plctype, devicetype) devicenum = str(int(get_device_number(device), devicebase)) if self.plctype is const.iQR_SERIES: device_data += devicecode.encode() device_data += devicenum.rjust(8, "0").upper().encode() else: device_data += devicecode.encode() device_data += devicenum.rjust(6, "0").upper().encode() return device_data ``` -------------------------------- ### Making Command Data Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Constructs the command data bytes, which include the command code and subcommand code. ```APIDOC ## _make_commanddata ### Description Constructs the command and subcommand data as a byte string. ### Method Internal helper method ### Parameters - **command** (int) - Required - The command code. - **subcommand** (int) - Required - The subcommand code. ### Returns - **command_data** (bytes) - The combined command and subcommand data. ``` -------------------------------- ### Initialize Type3E communication Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Constructor for the Type3E class, which sets the PLC type for the connection. ```python def __init__(self, plctype ="Q"): """Constructor """ self._set_plctype(plctype) ``` -------------------------------- ### Define MCProtocolError and UnsupportedComandError Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/mcprotocolerror Custom exception classes for handling device-specific and command-unsupported errors in MC protocol communication. ```python """This file is collection of mcprotocol error. """ [docs]class MCProtocolError(Exception): """devicecode error. Device is not exsist. Attributes: plctype(str): PLC type. "Q", "L" or "iQ" devicename(str): devicename. (ex: "Q", "P", both of them does not support mcprotocol.) """ [docs] def __init__(self, errorcode): self.errorcode = "0x" + format(errorcode, "x").rjust(4, "0").upper() def __str__(self): return "mc protocol error: error code {}".format(self.errorcode) [docs]class UnsupportedComandError(Exception): """This command is not supported by the module you connected. """ [docs] def __init__(self): pass def __str__(self): return "This command is not supported by the module you connected." \ "If you connect with CPU module, please use E71 module." [docs]def check_mcprotocol_error(status): """Check mc protocol command error. If errot exist(status != 0), raise Error. """ if status == 0: return None elif status == 0xC059: raise UnsupportedComandError else: raise MCProtocolError(status) ``` -------------------------------- ### Manage PLC connection Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Methods to establish and terminate a TCP/IP connection to the PLC. ```python def connect(self, ip, port): """Connect to PLC Args: ip (str): ip address(IPV4) to connect PLC port (int): port number of connect PLC timeout (float): timeout second in communication """ self._ip = ip self._port = port self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._sock.settimeout(self.soc_timeout) self._sock.connect((ip, port)) self._is_connected = True def close(self): """Close connection """ self._sock.close() self._is_connected = False ``` -------------------------------- ### Make MC Protocol Command Data Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Constructs command data bytes by encoding the command and subcommand codes as shorts. ```python def _make_commanddata(self, command, subcommand): """make mc protocol command and subcommand data Args: command(int): command code subcommand(int): subcommand code Returns: command_data(bytes):command data """ command_data = bytes() command_data += self._encode_value(command, "short") command_data += self._encode_value(subcommand, "short") return command_data ``` -------------------------------- ### Initialize PLC Connection Source: https://pymcprotocol.netlify.app/_sources/index.rst.txt Initialize a connection object for MC Protocol Type 3E or Type 4E. Specify the PLC type for Type 3E connections. The default communication type is binary; set to 'ascii' if needed. ```python import pymcprotocol #If you use Q series PLC pymc3e = pymcprotocol.Type3E() #if you use L series PLC, pymc3e = pymcprotocol.Type3E(plctype="L") #if you use QnA series PLC, pymc3e = pymcprotocol.Type3E(plctype="L") #if you use iQ-L series PLC, pymc3e = pymcprotocol.Type3E(plctype="iQ-L") #if you use iQ-R series PLC, pymc3e = pymcprotocol.Type3E(plctype="iQ-R") #If you use 4E type pymc4e = pymcprotocol.Type4E() #If you use ascii byte communication. (default is "binary") pymc3e.setaccessopt(commtype="ascii") pymc3e.connect("192.168.1.2", 1025) ``` -------------------------------- ### Set Access Options Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Configures various parameters for MC protocol access, including communication type, network details, and timeouts. ```APIDOC ## POST /api/access/options ### Description Sets the access options for the MC protocol. ### Method POST ### Endpoint /api/access/options ### Parameters #### Request Body - **commtype** (str) - Optional - Communication type. "binary" or "ascii". (Default: "binary") - **network** (int) - Optional - Network No. of an access target. (0 <= network <= 255) - **pc** (int) - Optional - Network module station No. of an access target. (0 <= pc <= 255) - **dest_moduleio** (int) - Optional - Start input/output number of a multidrop connection source module. - **dest_modulesta** (int) - Optional - Station No. of an access target module in a multidrop connection. - **timer_sec** (int) - Optional - Timeout in seconds for PLC responses. (0 <= timer_sec <= 16383) ### Request Example { "commtype": "ascii", "network": 1, "pc": 10, "dest_moduleio": 0, "dest_modulesta": 0, "timer_sec": 5 } ### Response #### Success Response (200) - **status** (str) - Indicates success or failure of the operation. #### Response Example { "status": "success" } ``` -------------------------------- ### MCProtocolError Exception Source: https://pymcprotocol.netlify.app/pymcprotocol Custom exception for MCProtocol errors, indicating issues like non-existent devices. ```APIDOC ## MCProtocolError Exception ### Description Custom exception for MCProtocol errors, such as device non-existence. ### Attributes * `plctype` (str): The PLC type (e.g., 'Q', 'L', 'iQ'). * `devicename` (str): The device name (e.g., 'Q', 'P'). ### Parameters * `errorcode` - Required - The error code associated with the exception. ``` -------------------------------- ### Configure PLC and Communication Settings Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Internal methods to validate and set the PLC series type and communication mode (binary or ASCII). These methods update internal state and word size requirements. ```python def _set_plctype(self, plctype): """Check PLC type. If plctype is vaild, set self.commtype. Args: plctype(str): PLC type. "Q", "L", "QnA", "iQ-L", "iQ-R", """ if plctype == "Q": self.plctype = const.Q_SERIES elif plctype == "L": self.plctype = const.L_SERIES elif plctype == "QnA": self.plctype = const.QnA_SERIES elif plctype == "iQ-L": self.plctype = const.iQL_SERIES elif plctype == "iQ-R": self.plctype = const.iQR_SERIES else: raise PLCTypeError() def _set_commtype(self, commtype): """Check communication type. If commtype is vaild, set self.commtype. Args: commtype(str): communication type. "binary" or "ascii". (Default: "binary") """ if commtype == "binary": self.commtype = const.COMMTYPE_BINARY self._wordsize = 2 elif commtype == "ascii": self.commtype = const.COMMTYPE_ASCII self._wordsize = 4 else: raise CommTypeError() ``` -------------------------------- ### Type4E Class Initialization Source: https://pymcprotocol.netlify.app/pymcprotocol Initializes the Type4E communication class for MC Protocol version 4E. ```APIDOC ## Type4E Class ### Description Initializes the mcprotocol 4E communication class. Type 4e is similar to Type 3E, with differences primarily in the subheader. ### Attributes * `subheader` (int): The subheader value for MC protocol. * `subheaderserial` (int): The subheader serial for MC protocol to identify the client. ### Parameters * `plctype` (str) - Optional - The PLC type, defaults to 'Q'. ``` -------------------------------- ### Define custom exceptions Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Custom exception classes for handling communication and PLC type configuration errors. ```python class CommTypeError(Exception): """Communication type error. Communication type must be "binary" or "ascii" """ def __init__(self): pass def __str__(self): return "communication type must be \"binary\" or \"ascii\"" class PLCTypeError(Exception): """PLC type error. PLC type must be"Q", "L", "QnA", "iQ-L", "iQ-R" """ def __init__(self): pass def __str__(self): return "plctype must be \"Q\", \"L\", \"QnA\" \"iQ-L\" or \"iQ-R\"" ``` -------------------------------- ### POST /echo_test Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Sends a string of alphanumeric data to the PLC and expects the same data to be returned, verifying the integrity of the connection. ```APIDOC ## POST /echo_test ### Description Performs an echo test by sending alphanumeric data to the PLC. The PLC must return the exact same data to confirm successful communication. ### Method POST ### Endpoint /echo_test ### Parameters #### Request Body - **echo_data** (str) - Required - The alphanumeric string to send to the PLC. Must be between 1 and 960 characters. ### Response #### Success Response (200) - **answer_len** (int) - The length of the data returned by the PLC. - **answer_data** (str) - The data returned by the PLC. ``` -------------------------------- ### UnsupportedCommandError Exception Source: https://pymcprotocol.netlify.app/pymcprotocol Custom exception raised when a command is not supported by the connected module. ```APIDOC ## UnsupportedCommandError Exception ### Description Custom exception raised when a command is not supported by the connected module. ``` -------------------------------- ### Batch Write Bit Units Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Performs a batch write operation in bit units. Requires a head device and a list of values, where each value must be 0 or 1. Raises a ValueError for invalid input values. ```python def batchwrite_bitunits(self, headdevice, values): """batch read in bit units. Args: headdevice(str): Write head device. (ex: "X10") values(list[int]): Write values. each value must be 0 or 1. 0 is OFF, 1 is ON. """ write_size = len(values) #check values for value in values: if not (value == 0 or value == 1): raise ValueError("Each value must be 0 or 1. 0 is OFF, 1 is ON.") command = 0x1401 if self.plctype == const.iQR_SERIES: ``` -------------------------------- ### Error Handling and Module Structure Source: https://pymcprotocol.netlify.app/genindex Overview of the error handling classes and module structure provided by the pymcprotocol library. ```APIDOC ## pymcprotocol.mcprotocolerror ### Description Provides error handling mechanisms for the MC Protocol implementation. ### Classes - **MCProtocolError**: Base error class for MC Protocol operations. - **__init__()**: Initializes the error instance. - **devicename**: Attribute representing the device name associated with the error. - **plctype**: Attribute representing the PLC type associated with the error. - **UnsupportedComandError**: Error raised when an unsupported command is encountered. - **__init__()**: Initializes the error instance. ### Functions - **check_mcprotocol_error()**: Utility function to validate and check for MC Protocol errors. ``` -------------------------------- ### Exception Classes Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/mcprotocolerror Custom exception classes used for handling specific MC Protocol errors. ```APIDOC ## MCProtocolError ### Description Exception raised when a device code error occurs or the device does not exist. ### Attributes - **plctype** (str) - PLC type ("Q", "L", or "iQ"). - **devicename** (str) - The name of the device. ## UnsupportedComandError ### Description Exception raised when the connected module does not support the requested command. It is recommended to use an E71 module if connecting with a CPU module. ``` -------------------------------- ### Perform Random Read Operation Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Reads values from specified word and dword devices randomly. Requires a list of device strings for both word and dword types. ```python def randomread(self, word_devices, dword_devices): """read word units and dword units randomly. Moniter condition does not support. Args: word_devices(list[str]): Read device word units. (ex: ["D1000", "D1010"]) dword_devices(list[str]): Read device dword units. (ex: ["D1000", "D1012"]) Returns: word_values(list[int]): word units value list dword_values(list[int]): dword units value list """ command = 0x0403 if self.plctype == const.iQR_SERIES: subcommand = 0x0002 else: subcommand = 0x0000 word_size = len(word_devices) dword_size = len(dword_devices) request_data = bytes() request_data += self._make_commanddata(command, subcommand) request_data += self._encode_value(word_size, mode="byte") request_data += self._encode_value(dword_size, mode="byte") for word_device in word_devices: request_data += self._make_devicedata(word_device) for dword_device in dword_devices: request_data += self._make_devicedata(dword_device) send_data = self._make_senddata(request_data) #send mc data self._send(send_data) #reciev mc data recv_data = self._recv() self._check_cmdanswer(recv_data) data_index = self._get_answerdata_index() word_values= [] dword_values= [] for word_device in word_devices: wordvalue = self._decode_value(recv_data[data_index:data_index+self._wordsize], mode="short", isSigned=True) word_values.append(wordvalue) data_index += self._wordsize for dword_device in dword_devices: dwordvalue = self._decode_value(recv_data[data_index:data_index+self._wordsize*2], mode="long", isSigned=True) dword_values.append(dwordvalue) data_index += self._wordsize*2 return word_values, dword_values ``` -------------------------------- ### Batch Write Word Units Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Performs a batch write operation in word units. Takes a head device and a list of integer values to write. Encodes values as signed integers. ```python def batchwrite_wordunits(self, headdevice, values): """batch write in word units. Args: headdevice(str): Write head device. (ex: "D1000") values(list[int]): Write values. """ write_size = len(values) command = 0x1401 if self.plctype == const.iQR_SERIES: subcommand = 0x0002 else: subcommand = 0x0000 request_data = bytes() request_data += self._make_commanddata(command, subcommand) request_data += self._make_devicedata(headdevice) request_data += self._encode_value(write_size) for value in values: request_data += self._encode_value(value, isSigned=True) send_data = self._make_senddata(request_data) #send mc data self._send(send_data) #reciev mc data recv_data = self._recv() self._check_cmdanswer(recv_data) return None ``` -------------------------------- ### Batch Read Bit Units Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Reads a specified number of device points in bit units from the PLC. ```APIDOC ## batchread_bitunits ### Description Reads a batch of data from the PLC starting at the specified head device in bit units. ### Parameters - **headdevice** (str) - Required - Read head device (e.g., "X1") - **size** (int) - Required - Number of read device points ### Response - **bitunits_values** (list[int]) - A list of bit unit values (0 or 1). ``` -------------------------------- ### Perform Random Write Operation Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Writes values to specified word and dword devices randomly. Raises a ValueError if the length of devices and values lists do not match. ```python def randomwrite(self, word_devices, word_values, dword_devices, dword_values): """write word units and dword units randomly. Args: word_devices(list[str]): Write word devices. (ex: ["D1000", "D1020"]) word_values(list[int]): Values for each word devices. (ex: [100, 200]) dword_devices(list[str]): Write dword devices. (ex: ["D1000", "D1020"]) dword_values(list[int]): Values for each dword devices. (ex: [100, 200]) """ if len(word_devices) != len(word_values): raise ValueError("word_devices and word_values must be same length") if len(dword_devices) != len(dword_values): raise ValueError("dword_devices and dword_values must be same length") word_size = len(word_devices) dword_size = len(dword_devices) command = 0x1402 if self.plctype == const.iQR_SERIES: subcommand = 0x0002 else: subcommand = 0x0000 request_data = bytes() request_data += self._make_commanddata(command, subcommand) request_data += self._encode_value(word_size, mode="byte") request_data += self._encode_value(dword_size, mode="byte") for word_device, word_value in zip(word_devices, word_values): request_data += self._make_devicedata(word_device) ``` -------------------------------- ### PLC Remote Execution Commands Source: https://pymcprotocol.netlify.app/_sources/index.rst.txt Execute remote commands such as run, stop, latch clear, pause, and reset. These commands are available when connected via Ethernet modules (e.g., E71). Reading the CPU type is also supported. ```python #remote run, clear all device pymc3e.remote_run(clear_mode=2, force_exec=True) #remote stop pymc3e.remote_stop() #remote latch clear. (have to PLC be stopped) pymc3e.remote_latchclear() #remote pause pymc3e.remote_pause(force_exec=False) #remote reset pymc3e.remote_reset() #read PLC type cpu_type, cpu_code = pymc3e.read_cputype() ``` -------------------------------- ### Internal Helper Functions Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Internal functions for managing PLC type, communication type, and data indexing. ```APIDOC ## Internal Functions ### `_set_plctype(plctype)` #### Description Checks and sets the PLC type. #### Parameters - **plctype** (str) - PLC type. Accepted values: "Q", "L", "QnA", "iQ-L", "iQ-R". ### `_set_commtype(commtype)` #### Description Checks and sets the communication type. #### Parameters - **commtype** (str) - Communication type. Accepted values: "binary" or "ascii". (Default: "binary") ### `_get_answerdata_index()` #### Description Gets the index for answer data based on the communication type. #### Returns - **index** (int) - The index for answer data. ### `_get_answerstatus_index()` #### Description Gets the index for answer status based on the communication type. #### Returns - **index** (int) - The index for answer status. ### `_make_senddata(requestdata)` #### Description Constructs the data to be sent according to the MC protocol and communication type. #### Parameters - **requestdata** (bytes) - The raw request data to be encoded. #### Returns - **mc_data** (bytes) - The formatted MC protocol data ready for sending. ``` -------------------------------- ### Read CPU Type Source: https://pymcprotocol.netlify.app/pymcprotocol Reads and returns the CPU type code of the PLC. ```APIDOC ## read_cputype ### Description Reads the CPU type of the PLC. ### Returns * `CPU type` (str): The CPU code, a 4-length number. ``` -------------------------------- ### POST /close Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Closes the active socket connection to the PLC. ```APIDOC ## POST /close ### Description Closes the current socket connection and updates the connection status. ### Method POST ### Endpoint /close ``` -------------------------------- ### Batch Read Word Units Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Reads a specified number of device points in word units from the PLC. ```APIDOC ## batchread_wordunits ### Description Reads a batch of data from the PLC starting at the specified head device in word units. ### Parameters - **headdevice** (str) - Required - Read head device (e.g., "D1000") - **readsize** (int) - Required - Number of read device points ### Response - **wordunits_values** (list[int]) - A list of word unit values read from the device. ``` -------------------------------- ### Write Bit Units Randomly Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Writes values to specified bit devices. Requires that the length of bit_devices matches the length of values, and each value must be 0 or 1. ```python def randomwrite_bitunits(self, bit_devices, values): """write bit units randomly. Args: bit_devices(list[str]): Write bit devices. (ex: ["X10", "X20"]) values(list[int]): Write values. each value must be 0 or 1. 0 is OFF, 1 is ON. """ if len(bit_devices) != len(values): raise ValueError("bit_devices and values must be same length") write_size = len(values) #check values for value in values: if not (value == 0 or value == 1): raise ValueError("Each value must be 0 or 1. 0 is OFF, 1 is ON.") command = 0x1402 if self.plctype == const.iQR_SERIES: subcommand = 0x0003 else: subcommand = 0x0001 request_data = bytes() request_data += self._make_commanddata(command, subcommand) request_data += self._encode_value(write_size, mode="byte") for bit_device, value in zip(bit_devices, values): request_data += self._make_devicedata(bit_device) #byte value for iQ-R requires 2 byte data if self.plctype == const.iQR_SERIES: request_data += self._encode_value(value, mode="short", isSigned=True) else: request_data += self._encode_value(value, mode="byte", isSigned=True) send_data = self._make_senddata(request_data) #send mc data self._send(send_data) #reciev mc data recv_data = self._recv() self._check_cmdanswer(recv_data) return None ``` -------------------------------- ### Read CPU Type and Code Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Reads the CPU type and code from the PLC. Handles both binary and non-binary communication types for data parsing. ```python command = 0x0101 subcommand = 0x0000 request_data = bytes() request_data += self._make_commanddata(command, subcommand) send_data = self._make_senddata(request_data) #send mc data self._send(send_data) #reciev mc data recv_data = self._recv() self._check_cmdanswer(recv_data) data_index = self._get_answerdata_index() cpu_name_length = 16 if self.commtype == const.COMMTYPE_BINARY: cpu_type = recv_data[data_index:data_index+cpu_name_length].decode() cpu_type = cpu_type.replace("\x20", "") cpu_code = int.from_bytes(recv_data[data_index+cpu_name_length:], "little") cpu_code = format(cpu_code, "x").rjust(4, "0") else: cpu_type = recv_data[data_index:data_index+cpu_name_length].decode() cpu_type = cpu_type.replace("\x20", "") cpu_code = recv_data[data_index+cpu_name_length:].decode() return cpu_type, cpu_code ``` -------------------------------- ### POST /randomwrite_bitunits Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Writes values to specified bit units randomly on the PLC. ```APIDOC ## POST /randomwrite_bitunits ### Description Writes values to a list of bit devices. Each value must be 0 (OFF) or 1 (ON). ### Parameters #### Request Body - **bit_devices** (list[str]) - Required - List of bit devices (e.g., ["X10", "X20"]) - **values** (list[int]) - Required - List of values (0 or 1) ``` -------------------------------- ### Making Device Data Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Generates the device data bytes, which include the device type code and device number, formatted according to the PLC type and communication type. ```APIDOC ## _make_devicedata ### Description Constructs the device data bytes, including device type code and device number, formatted based on PLC and communication types. ### Method Internal helper method ### Parameters - **device** (str) - Required - The device identifier (e.g., "D1000", "Y1"). ### Returns - **device_data** (bytes) - The formatted device data. ### Raises - **ValueError** - If the device string is invalid. ``` -------------------------------- ### Type4E._make_senddata Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type4e Constructs the full MC protocol data packet for transmission based on the provided request data. ```APIDOC ## _make_senddata ### Description Constructs the binary or ASCII encoded MC protocol data packet, including subheaders, network information, and the request payload. ### Parameters #### Request Body - **requestdata** (bytes) - Required - The raw MC protocol request data to be encapsulated. ### Response - **mc_data** (bytes) - The fully constructed MC protocol packet ready for transmission. ``` -------------------------------- ### Construct Send Data Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Formats request data into MC protocol bytes based on the configured communication type. ```python def _make_senddata(self, requestdata): """Makes send mc protorocl data. Args: requestdata(bytes): mc protocol request data. data must be converted according to self.commtype Returns: mc_data(bytes): send mc protorocl data """ mc_data = bytes() # subheader is big endian if self.commtype == const.COMMTYPE_BINARY: mc_data += self.subheader.to_bytes(2, "big") else: mc_data += format(self.subheader, "x").ljust(4, "0").upper().encode() mc_data += self._encode_value(self.network, "byte") mc_data += self._encode_value(self.pc, "byte") ``` -------------------------------- ### Random Write (Word and DWord Units) Source: https://pymcprotocol.netlify.app/pymcprotocol Writes values to word and dword devices randomly. ```APIDOC ## randomwrite ### Description Writes word units and dword units randomly. ### Parameters * `word_devices` (list[str]) - Required - List of word devices to write to. (ex: ["D1000", "D1020"]) * `word_values` (list[int]) - Required - Values for each word device. (ex: [100, 200]) * `dword_devices` (list[str]) - Required - List of dword devices to write to. (ex: ["D1000", "D1020"]) * `dword_values` (list[int]) - Required - Values for each dword device. (ex: [100, 200]) ### Returns * `word_values` (list[int]): A list of word unit values. * `dword_values` (list[int]): A list of dword unit values. ``` -------------------------------- ### Random Write (Bit Units) Source: https://pymcprotocol.netlify.app/pymcprotocol Writes values to bit devices randomly. ```APIDOC ## randomwrite_bitunits ### Description Writes bit units randomly. ### Parameters * `bit_devices` (list[str]) - Required - List of bit devices to write to. (ex: ["X10", "X20"]) * `values` (list[int]) - Required - Values for each bit device. Each value must be 0 (OFF) or 1 (ON). ``` -------------------------------- ### POST /remote_unlock Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Unlocks the PLC using a password. ```APIDOC ## POST /remote_unlock ### Description Unlocks the PLC by providing a password. ### Method POST ### Endpoint /remote_unlock ### Parameters #### Request Body - **password** (str) - Required - The remote password. - **request_input** (bool) - Optional - If true, prompts the user for password input. ``` -------------------------------- ### POST /remote_pause Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Pauses the PLC remotely. ```APIDOC ## POST /remote_pause ### Description Pauses the PLC remotely. ### Parameters #### Request Body - **force_exec** (bool) - Optional - Force execution if operated by another device ``` -------------------------------- ### POST /remote_lock Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Locks the PLC using a password. ```APIDOC ## POST /remote_lock ### Description Locks the PLC by providing a password. ### Method POST ### Endpoint /remote_lock ### Parameters #### Request Body - **password** (str) - Required - The remote password. - **request_input** (bool) - Optional - If true, prompts the user for password input. ``` -------------------------------- ### Retrieve Data Indices Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Helper methods to determine the byte index for answer data and status based on the current communication mode. ```python def _get_answerdata_index(self): """Get answer data index from return data byte. """ if self.commtype == const.COMMTYPE_BINARY: return 11 else: return 22 def _get_answerstatus_index(self): """Get command status index from return data byte. """ if self.commtype == const.COMMTYPE_BINARY: return 9 else: return 18 ``` -------------------------------- ### Random Write Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Writes word units and dword units randomly to the device. ```APIDOC ## Random Write ### Description Writes word units and dword units randomly. ### Method POST (assumed, based on internal _send/_recv calls) ### Endpoint `/api/device/randomwrite` (assumed) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **word_devices** (list[str]) - Required - Write word devices. (ex: ["D1000", "D1020"]) - **word_values** (list[int]) - Required - Values for each word device. (ex: [100, 200]) - **dword_devices** (list[str]) - Required - Write dword devices. (ex: ["D1000", "D1020"]) - **dword_values** (list[int]) - Required - Values for each dword device. (ex: [100, 200]) ### Request Example ```json { "word_devices": ["D1000", "D1020"], "word_values": [100, 200], "dword_devices": ["D1000", "D1020"], "dword_values": [300, 400] } ``` ### Response #### Success Response (200) No specific response fields mentioned, typically indicates success. #### Response Example ```json { "status": "success" } ``` ``` -------------------------------- ### Random Read/Write Operations Source: https://pymcprotocol.netlify.app/ Perform random read and write operations for word, dword, and bit units. Specify individual devices and their corresponding values for writing. ```python #read "D1000", "D2000" and dword "D3000". word_values, dword_values = pymc3e.randomread(word_devices=["D1000", "D2000"], dword_devices=["D3000"]) #write 1000 to "D1000", 2000 to "D2000" and 655362 todword "D3000" pymc3e.randomwrite(word_devices=["D1000", "D1002"], word_values=[1000, 2000], dword_devices=["D1004"], dword_values=[655362]) #write 1(ON) to "X0", 0(OFF) to "X10" pymc3e.randomwrite_bitunits(bit_devices=["X0", "X10"], values=[1, 0]) ``` -------------------------------- ### POST /remote_reset Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Resets the PLC remotely. The PLC must be in a stopped state before executing this command. ```APIDOC ## POST /remote_reset ### Description Resets the PLC remotely. Note that the PLC must be stopped prior to calling this method. ### Method POST ### Endpoint /remote_reset ``` -------------------------------- ### Random Read Source: https://pymcprotocol.netlify.app/_modules/pymcprotocol/type3e Reads word and dword units randomly from the device. Monitor condition is not supported. ```APIDOC ## Random Read ### Description Reads word units and dword units randomly. Monitor condition does not support. ### Method POST (assumed, based on internal _send/_recv calls) ### Endpoint `/api/device/randomread` (assumed) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None (data is constructed internally) ### Request Example ```json { "word_devices": ["D1000", "D1010"], "dword_devices": ["D1000", "D1012"] } ``` ### Response #### Success Response (200) - **word_values** (list[int]) - List of word unit values. - **dword_values** (list[int]) - List of dword unit values. #### Response Example ```json { "word_values": [100, 200], "dword_values": [300, 400] } ``` ```