We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
ModbusException 0x07 is missing in pdu.py
In pdu.py is ModbusException NegativeAcknowledge missing. Is it possible to add: NegativeAcknowledge  = 0x07 ?


class ModbusExceptions:  

    IllegalFunction = 0x01
    IllegalAddress = 0x02
    IllegalValue = 0x03
    SlaveFailure = 0x04
    Acknowledge = 0x05
    SlaveBusy = 0x06
    MemoryParityError = 0x08
    GatewayPathUnavailable = 0x0A
    GatewayNoResponse = 0x0B

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pymodbus/pdu.py`
Content:
```
1 """Contains base classes for modbus request/response/error packets."""
2 
3 __all__ = [
4     "ModbusRequest",
5     "ModbusResponse",
6     "ModbusExceptions",
7     "ExceptionResponse",
8     "IllegalFunctionRequest",
9 ]
10 
11 # pylint: disable=missing-type-doc
12 import struct
13 
14 from pymodbus.exceptions import NotImplementedException
15 from pymodbus.logging import Log
16 from pymodbus.utilities import rtuFrameSize
17 
18 
19 # --------------------------------------------------------------------------- #
20 # Base PDUs
21 # --------------------------------------------------------------------------- #
22 class ModbusPDU:
23     """Base class for all Modbus messages.
24 
25     .. attribute:: transaction_id
26 
27        This value is used to uniquely identify a request
28        response pair.  It can be implemented as a simple counter
29 
30     .. attribute:: protocol_id
31 
32        This is a constant set at 0 to indicate Modbus.  It is
33        put here for ease of expansion.
34 
35     .. attribute:: slave_id
36 
37        This is used to route the request to the correct child. In
38        the TCP modbus, it is used for routing (or not used at all. However,
39        for the serial versions, it is used to specify which child to perform
40        the requests against. The value 0x00 represents the broadcast address
41        (also 0xff).
42 
43     .. attribute:: check
44 
45        This is used for LRC/CRC in the serial modbus protocols
46 
47     .. attribute:: skip_encode
48 
49        This is used when the message payload has already been encoded.
50        Generally this will occur when the PayloadBuilder is being used
51        to create a complicated message. By setting this to True, the
52        request will pass the currently encoded message through instead
53        of encoding it again.
54     """
55 
56     def __init__(self, slave=0, **kwargs):
57         """Initialize the base data for a modbus request.
58 
59         :param slave: Modbus slave slave ID
60 
61         """
62         self.transaction_id = kwargs.get("transaction", 0)
63         self.protocol_id = kwargs.get("protocol", 0)
64         self.slave_id = slave
65         self.skip_encode = kwargs.get("skip_encode", False)
66         self.check = 0x0000
67 
68     def encode(self):
69         """Encode the message.
70 
71         :raises: A not implemented exception
72         """
73         raise NotImplementedException()
74 
75     def decode(self, data):
76         """Decode data part of the message.
77 
78         :param data: is a string object
79         :raises NotImplementedException:
80         """
81         raise NotImplementedException()
82 
83     @classmethod
84     def calculateRtuFrameSize(cls, buffer):
85         """Calculate the size of a PDU.
86 
87         :param buffer: A buffer containing the data that have been received.
88         :returns: The number of bytes in the PDU.
89         :raises NotImplementedException:
90         """
91         if hasattr(cls, "_rtu_frame_size"):
92             return cls._rtu_frame_size
93         if hasattr(cls, "_rtu_byte_count_pos"):
94             return rtuFrameSize(buffer, cls._rtu_byte_count_pos)
95         raise NotImplementedException(
96             f"Cannot determine RTU frame size for {cls.__name__}"
97         )
98 
99 
100 class ModbusRequest(ModbusPDU):
101     """Base class for a modbus request PDU."""
102 
103     function_code = -1
104 
105     def __init__(self, slave=0, **kwargs):  # pylint: disable=useless-parent-delegation
106         """Proxy to the lower level initializer.
107 
108         :param slave: Modbus slave slave ID
109         """
110         super().__init__(slave, **kwargs)
111 
112     def doException(self, exception):
113         """Build an error response based on the function.
114 
115         :param exception: The exception to return
116         :raises: An exception response
117         """
118         exc = ExceptionResponse(self.function_code, exception)
119         Log.error("Exception response {}", exc)
120         return exc
121 
122 
123 class ModbusResponse(ModbusPDU):
124     """Base class for a modbus response PDU.
125 
126     .. attribute:: should_respond
127 
128        A flag that indicates if this response returns a result back
129        to the client issuing the request
130 
131     .. attribute:: _rtu_frame_size
132 
133        Indicates the size of the modbus rtu response used for
134        calculating how much to read.
135     """
136 
137     should_respond = True
138     function_code = 0x00
139 
140     def __init__(self, slave=0, **kwargs):
141         """Proxy the lower level initializer.
142 
143         :param slave: Modbus slave slave ID
144 
145         """
146         super().__init__(slave, **kwargs)
147         self.bits = []
148         self.registers = []
149 
150     def isError(self) -> bool:
151         """Check if the error is a success or failure."""
152         return self.function_code > 0x80
153 
154 
155 # --------------------------------------------------------------------------- #
156 # Exception PDUs
157 # --------------------------------------------------------------------------- #
158 class ModbusExceptions:  # pylint: disable=too-few-public-methods
159     """An enumeration of the valid modbus exceptions."""
160 
161     IllegalFunction = 0x01
162     IllegalAddress = 0x02
163     IllegalValue = 0x03
164     SlaveFailure = 0x04
165     Acknowledge = 0x05
166     SlaveBusy = 0x06
167     MemoryParityError = 0x08
168     GatewayPathUnavailable = 0x0A
169     GatewayNoResponse = 0x0B
170 
171     @classmethod
172     def decode(cls, code):
173         """Give an error code, translate it to a string error name.
174 
175         :param code: The code number to translate
176         """
177         values = {
178             v: k
179             for k, v in iter(cls.__dict__.items())
180             if not k.startswith("__") and not callable(v)
181         }
182         return values.get(code, None)
183 
184 
185 class ExceptionResponse(ModbusResponse):
186     """Base class for a modbus exception PDU."""
187 
188     ExceptionOffset = 0x80
189     _rtu_frame_size = 5
190 
191     def __init__(self, function_code, exception_code=None, **kwargs):
192         """Initialize the modbus exception response.
193 
194         :param function_code: The function to build an exception response for
195         :param exception_code: The specific modbus exception to return
196         """
197         super().__init__(**kwargs)
198         self.original_code = function_code
199         self.function_code = function_code | self.ExceptionOffset
200         self.exception_code = exception_code
201 
202     def encode(self):
203         """Encode a modbus exception response.
204 
205         :returns: The encoded exception packet
206         """
207         return struct.pack(">B", self.exception_code)
208 
209     def decode(self, data):
210         """Decode a modbus exception response.
211 
212         :param data: The packet data to decode
213         """
214         self.exception_code = int(data[0])
215 
216     def __str__(self):
217         """Build a representation of an exception response.
218 
219         :returns: The string representation of an exception response
220         """
221         message = ModbusExceptions.decode(self.exception_code)
222         parameters = (self.function_code, self.original_code, message)
223         return (
224             "Exception Response(%d, %d, %s)"  # pylint: disable=consider-using-f-string
225             % parameters
226         )
227 
228 
229 class IllegalFunctionRequest(ModbusRequest):
230     """Define the Modbus slave exception type "Illegal Function".
231 
232     This exception code is returned if the slave::
233 
234         - does not implement the function code **or**
235         - is not in a state that allows it to process the function
236     """
237 
238     ErrorCode = 1
239 
240     def __init__(self, function_code, **kwargs):
241         """Initialize a IllegalFunctionRequest.
242 
243         :param function_code: The function we are erroring on
244         """
245         super().__init__(**kwargs)
246         self.function_code = function_code
247 
248     def decode(self, _data):
249         """Decode so this failure will run correctly."""
250 
251     def execute(self, _context):
252         """Build an illegal function request error response.
253 
254         :returns: The error response packet
255         """
256         return ExceptionResponse(self.function_code, self.ErrorCode)
257
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pymodbus/pdu.py b/pymodbus/pdu.py
--- a/pymodbus/pdu.py
+++ b/pymodbus/pdu.py
@@ -164,6 +164,7 @@
     SlaveFailure = 0x04
     Acknowledge = 0x05
     SlaveBusy = 0x06
+    NegativeAcknowledge = 0x07
     MemoryParityError = 0x08
     GatewayPathUnavailable = 0x0A
     GatewayNoResponse = 0x0B

{"golden_diff": "diff --git a/pymodbus/pdu.py b/pymodbus/pdu.py\n--- a/pymodbus/pdu.py\n+++ b/pymodbus/pdu.py\n@@ -164,6 +164,7 @@\n     SlaveFailure = 0x04\n     Acknowledge = 0x05\n     SlaveBusy = 0x06\n+    NegativeAcknowledge = 0x07\n     MemoryParityError = 0x08\n     GatewayPathUnavailable = 0x0A\n     GatewayNoResponse = 0x0B\n", "issue": "ModbusException 0x07 is missing in pdu.py\nIn pdu.py is ModbusException NegativeAcknowledge missing. Is it possible to add: NegativeAcknowledge  = 0x07 ?\r\n\r\n\r\nclass ModbusExceptions:  \r\n\r\n    IllegalFunction = 0x01\r\n    IllegalAddress = 0x02\r\n    IllegalValue = 0x03\r\n    SlaveFailure = 0x04\r\n    Acknowledge = 0x05\r\n    SlaveBusy = 0x06\r\n    MemoryParityError = 0x08\r\n    GatewayPathUnavailable = 0x0A\r\n    GatewayNoResponse = 0x0B\n", "before_files": [{"content": "\"\"\"Contains base classes for modbus request/response/error packets.\"\"\"\n\n__all__ = [\n    \"ModbusRequest\",\n    \"ModbusResponse\",\n    \"ModbusExceptions\",\n    \"ExceptionResponse\",\n    \"IllegalFunctionRequest\",\n]\n\n# pylint: disable=missing-type-doc\nimport struct\n\nfrom pymodbus.exceptions import NotImplementedException\nfrom pymodbus.logging import Log\nfrom pymodbus.utilities import rtuFrameSize\n\n\n# --------------------------------------------------------------------------- #\n# Base PDUs\n# --------------------------------------------------------------------------- #\nclass ModbusPDU:\n    \"\"\"Base class for all Modbus messages.\n\n    .. attribute:: transaction_id\n\n       This value is used to uniquely identify a request\n       response pair.  It can be implemented as a simple counter\n\n    .. attribute:: protocol_id\n\n       This is a constant set at 0 to indicate Modbus.  It is\n       put here for ease of expansion.\n\n    .. attribute:: slave_id\n\n       This is used to route the request to the correct child. In\n       the TCP modbus, it is used for routing (or not used at all. However,\n       for the serial versions, it is used to specify which child to perform\n       the requests against. The value 0x00 represents the broadcast address\n       (also 0xff).\n\n    .. attribute:: check\n\n       This is used for LRC/CRC in the serial modbus protocols\n\n    .. attribute:: skip_encode\n\n       This is used when the message payload has already been encoded.\n       Generally this will occur when the PayloadBuilder is being used\n       to create a complicated message. By setting this to True, the\n       request will pass the currently encoded message through instead\n       of encoding it again.\n    \"\"\"\n\n    def __init__(self, slave=0, **kwargs):\n        \"\"\"Initialize the base data for a modbus request.\n\n        :param slave: Modbus slave slave ID\n\n        \"\"\"\n        self.transaction_id = kwargs.get(\"transaction\", 0)\n        self.protocol_id = kwargs.get(\"protocol\", 0)\n        self.slave_id = slave\n        self.skip_encode = kwargs.get(\"skip_encode\", False)\n        self.check = 0x0000\n\n    def encode(self):\n        \"\"\"Encode the message.\n\n        :raises: A not implemented exception\n        \"\"\"\n        raise NotImplementedException()\n\n    def decode(self, data):\n        \"\"\"Decode data part of the message.\n\n        :param data: is a string object\n        :raises NotImplementedException:\n        \"\"\"\n        raise NotImplementedException()\n\n    @classmethod\n    def calculateRtuFrameSize(cls, buffer):\n        \"\"\"Calculate the size of a PDU.\n\n        :param buffer: A buffer containing the data that have been received.\n        :returns: The number of bytes in the PDU.\n        :raises NotImplementedException:\n        \"\"\"\n        if hasattr(cls, \"_rtu_frame_size\"):\n            return cls._rtu_frame_size\n        if hasattr(cls, \"_rtu_byte_count_pos\"):\n            return rtuFrameSize(buffer, cls._rtu_byte_count_pos)\n        raise NotImplementedException(\n            f\"Cannot determine RTU frame size for {cls.__name__}\"\n        )\n\n\nclass ModbusRequest(ModbusPDU):\n    \"\"\"Base class for a modbus request PDU.\"\"\"\n\n    function_code = -1\n\n    def __init__(self, slave=0, **kwargs):  # pylint: disable=useless-parent-delegation\n        \"\"\"Proxy to the lower level initializer.\n\n        :param slave: Modbus slave slave ID\n        \"\"\"\n        super().__init__(slave, **kwargs)\n\n    def doException(self, exception):\n        \"\"\"Build an error response based on the function.\n\n        :param exception: The exception to return\n        :raises: An exception response\n        \"\"\"\n        exc = ExceptionResponse(self.function_code, exception)\n        Log.error(\"Exception response {}\", exc)\n        return exc\n\n\nclass ModbusResponse(ModbusPDU):\n    \"\"\"Base class for a modbus response PDU.\n\n    .. attribute:: should_respond\n\n       A flag that indicates if this response returns a result back\n       to the client issuing the request\n\n    .. attribute:: _rtu_frame_size\n\n       Indicates the size of the modbus rtu response used for\n       calculating how much to read.\n    \"\"\"\n\n    should_respond = True\n    function_code = 0x00\n\n    def __init__(self, slave=0, **kwargs):\n        \"\"\"Proxy the lower level initializer.\n\n        :param slave: Modbus slave slave ID\n\n        \"\"\"\n        super().__init__(slave, **kwargs)\n        self.bits = []\n        self.registers = []\n\n    def isError(self) -> bool:\n        \"\"\"Check if the error is a success or failure.\"\"\"\n        return self.function_code > 0x80\n\n\n# --------------------------------------------------------------------------- #\n# Exception PDUs\n# --------------------------------------------------------------------------- #\nclass ModbusExceptions:  # pylint: disable=too-few-public-methods\n    \"\"\"An enumeration of the valid modbus exceptions.\"\"\"\n\n    IllegalFunction = 0x01\n    IllegalAddress = 0x02\n    IllegalValue = 0x03\n    SlaveFailure = 0x04\n    Acknowledge = 0x05\n    SlaveBusy = 0x06\n    MemoryParityError = 0x08\n    GatewayPathUnavailable = 0x0A\n    GatewayNoResponse = 0x0B\n\n    @classmethod\n    def decode(cls, code):\n        \"\"\"Give an error code, translate it to a string error name.\n\n        :param code: The code number to translate\n        \"\"\"\n        values = {\n            v: k\n            for k, v in iter(cls.__dict__.items())\n            if not k.startswith(\"__\") and not callable(v)\n        }\n        return values.get(code, None)\n\n\nclass ExceptionResponse(ModbusResponse):\n    \"\"\"Base class for a modbus exception PDU.\"\"\"\n\n    ExceptionOffset = 0x80\n    _rtu_frame_size = 5\n\n    def __init__(self, function_code, exception_code=None, **kwargs):\n        \"\"\"Initialize the modbus exception response.\n\n        :param function_code: The function to build an exception response for\n        :param exception_code: The specific modbus exception to return\n        \"\"\"\n        super().__init__(**kwargs)\n        self.original_code = function_code\n        self.function_code = function_code | self.ExceptionOffset\n        self.exception_code = exception_code\n\n    def encode(self):\n        \"\"\"Encode a modbus exception response.\n\n        :returns: The encoded exception packet\n        \"\"\"\n        return struct.pack(\">B\", self.exception_code)\n\n    def decode(self, data):\n        \"\"\"Decode a modbus exception response.\n\n        :param data: The packet data to decode\n        \"\"\"\n        self.exception_code = int(data[0])\n\n    def __str__(self):\n        \"\"\"Build a representation of an exception response.\n\n        :returns: The string representation of an exception response\n        \"\"\"\n        message = ModbusExceptions.decode(self.exception_code)\n        parameters = (self.function_code, self.original_code, message)\n        return (\n            \"Exception Response(%d, %d, %s)\"  # pylint: disable=consider-using-f-string\n            % parameters\n        )\n\n\nclass IllegalFunctionRequest(ModbusRequest):\n    \"\"\"Define the Modbus slave exception type \"Illegal Function\".\n\n    This exception code is returned if the slave::\n\n        - does not implement the function code **or**\n        - is not in a state that allows it to process the function\n    \"\"\"\n\n    ErrorCode = 1\n\n    def __init__(self, function_code, **kwargs):\n        \"\"\"Initialize a IllegalFunctionRequest.\n\n        :param function_code: The function we are erroring on\n        \"\"\"\n        super().__init__(**kwargs)\n        self.function_code = function_code\n\n    def decode(self, _data):\n        \"\"\"Decode so this failure will run correctly.\"\"\"\n\n    def execute(self, _context):\n        \"\"\"Build an illegal function request error response.\n\n        :returns: The error response packet\n        \"\"\"\n        return ExceptionResponse(self.function_code, self.ErrorCode)\n", "path": "pymodbus/pdu.py"}], "after_files": [{"content": "\"\"\"Contains base classes for modbus request/response/error packets.\"\"\"\n\n__all__ = [\n    \"ModbusRequest\",\n    \"ModbusResponse\",\n    \"ModbusExceptions\",\n    \"ExceptionResponse\",\n    \"IllegalFunctionRequest\",\n]\n\n# pylint: disable=missing-type-doc\nimport struct\n\nfrom pymodbus.exceptions import NotImplementedException\nfrom pymodbus.logging import Log\nfrom pymodbus.utilities import rtuFrameSize\n\n\n# --------------------------------------------------------------------------- #\n# Base PDUs\n# --------------------------------------------------------------------------- #\nclass ModbusPDU:\n    \"\"\"Base class for all Modbus messages.\n\n    .. attribute:: transaction_id\n\n       This value is used to uniquely identify a request\n       response pair.  It can be implemented as a simple counter\n\n    .. attribute:: protocol_id\n\n       This is a constant set at 0 to indicate Modbus.  It is\n       put here for ease of expansion.\n\n    .. attribute:: slave_id\n\n       This is used to route the request to the correct child. In\n       the TCP modbus, it is used for routing (or not used at all. However,\n       for the serial versions, it is used to specify which child to perform\n       the requests against. The value 0x00 represents the broadcast address\n       (also 0xff).\n\n    .. attribute:: check\n\n       This is used for LRC/CRC in the serial modbus protocols\n\n    .. attribute:: skip_encode\n\n       This is used when the message payload has already been encoded.\n       Generally this will occur when the PayloadBuilder is being used\n       to create a complicated message. By setting this to True, the\n       request will pass the currently encoded message through instead\n       of encoding it again.\n    \"\"\"\n\n    def __init__(self, slave=0, **kwargs):\n        \"\"\"Initialize the base data for a modbus request.\n\n        :param slave: Modbus slave slave ID\n\n        \"\"\"\n        self.transaction_id = kwargs.get(\"transaction\", 0)\n        self.protocol_id = kwargs.get(\"protocol\", 0)\n        self.slave_id = slave\n        self.skip_encode = kwargs.get(\"skip_encode\", False)\n        self.check = 0x0000\n\n    def encode(self):\n        \"\"\"Encode the message.\n\n        :raises: A not implemented exception\n        \"\"\"\n        raise NotImplementedException()\n\n    def decode(self, data):\n        \"\"\"Decode data part of the message.\n\n        :param data: is a string object\n        :raises NotImplementedException:\n        \"\"\"\n        raise NotImplementedException()\n\n    @classmethod\n    def calculateRtuFrameSize(cls, buffer):\n        \"\"\"Calculate the size of a PDU.\n\n        :param buffer: A buffer containing the data that have been received.\n        :returns: The number of bytes in the PDU.\n        :raises NotImplementedException:\n        \"\"\"\n        if hasattr(cls, \"_rtu_frame_size\"):\n            return cls._rtu_frame_size\n        if hasattr(cls, \"_rtu_byte_count_pos\"):\n            return rtuFrameSize(buffer, cls._rtu_byte_count_pos)\n        raise NotImplementedException(\n            f\"Cannot determine RTU frame size for {cls.__name__}\"\n        )\n\n\nclass ModbusRequest(ModbusPDU):\n    \"\"\"Base class for a modbus request PDU.\"\"\"\n\n    function_code = -1\n\n    def __init__(self, slave=0, **kwargs):  # pylint: disable=useless-parent-delegation\n        \"\"\"Proxy to the lower level initializer.\n\n        :param slave: Modbus slave slave ID\n        \"\"\"\n        super().__init__(slave, **kwargs)\n\n    def doException(self, exception):\n        \"\"\"Build an error response based on the function.\n\n        :param exception: The exception to return\n        :raises: An exception response\n        \"\"\"\n        exc = ExceptionResponse(self.function_code, exception)\n        Log.error(\"Exception response {}\", exc)\n        return exc\n\n\nclass ModbusResponse(ModbusPDU):\n    \"\"\"Base class for a modbus response PDU.\n\n    .. attribute:: should_respond\n\n       A flag that indicates if this response returns a result back\n       to the client issuing the request\n\n    .. attribute:: _rtu_frame_size\n\n       Indicates the size of the modbus rtu response used for\n       calculating how much to read.\n    \"\"\"\n\n    should_respond = True\n    function_code = 0x00\n\n    def __init__(self, slave=0, **kwargs):\n        \"\"\"Proxy the lower level initializer.\n\n        :param slave: Modbus slave slave ID\n\n        \"\"\"\n        super().__init__(slave, **kwargs)\n        self.bits = []\n        self.registers = []\n\n    def isError(self) -> bool:\n        \"\"\"Check if the error is a success or failure.\"\"\"\n        return self.function_code > 0x80\n\n\n# --------------------------------------------------------------------------- #\n# Exception PDUs\n# --------------------------------------------------------------------------- #\nclass ModbusExceptions:  # pylint: disable=too-few-public-methods\n    \"\"\"An enumeration of the valid modbus exceptions.\"\"\"\n\n    IllegalFunction = 0x01\n    IllegalAddress = 0x02\n    IllegalValue = 0x03\n    SlaveFailure = 0x04\n    Acknowledge = 0x05\n    SlaveBusy = 0x06\n    NegativeAcknowledge = 0x07\n    MemoryParityError = 0x08\n    GatewayPathUnavailable = 0x0A\n    GatewayNoResponse = 0x0B\n\n    @classmethod\n    def decode(cls, code):\n        \"\"\"Give an error code, translate it to a string error name.\n\n        :param code: The code number to translate\n        \"\"\"\n        values = {\n            v: k\n            for k, v in iter(cls.__dict__.items())\n            if not k.startswith(\"__\") and not callable(v)\n        }\n        return values.get(code, None)\n\n\nclass ExceptionResponse(ModbusResponse):\n    \"\"\"Base class for a modbus exception PDU.\"\"\"\n\n    ExceptionOffset = 0x80\n    _rtu_frame_size = 5\n\n    def __init__(self, function_code, exception_code=None, **kwargs):\n        \"\"\"Initialize the modbus exception response.\n\n        :param function_code: The function to build an exception response for\n        :param exception_code: The specific modbus exception to return\n        \"\"\"\n        super().__init__(**kwargs)\n        self.original_code = function_code\n        self.function_code = function_code | self.ExceptionOffset\n        self.exception_code = exception_code\n\n    def encode(self):\n        \"\"\"Encode a modbus exception response.\n\n        :returns: The encoded exception packet\n        \"\"\"\n        return struct.pack(\">B\", self.exception_code)\n\n    def decode(self, data):\n        \"\"\"Decode a modbus exception response.\n\n        :param data: The packet data to decode\n        \"\"\"\n        self.exception_code = int(data[0])\n\n    def __str__(self):\n        \"\"\"Build a representation of an exception response.\n\n        :returns: The string representation of an exception response\n        \"\"\"\n        message = ModbusExceptions.decode(self.exception_code)\n        parameters = (self.function_code, self.original_code, message)\n        return (\n            \"Exception Response(%d, %d, %s)\"  # pylint: disable=consider-using-f-string\n            % parameters\n        )\n\n\nclass IllegalFunctionRequest(ModbusRequest):\n    \"\"\"Define the Modbus slave exception type \"Illegal Function\".\n\n    This exception code is returned if the slave::\n\n        - does not implement the function code **or**\n        - is not in a state that allows it to process the function\n    \"\"\"\n\n    ErrorCode = 1\n\n    def __init__(self, function_code, **kwargs):\n        \"\"\"Initialize a IllegalFunctionRequest.\n\n        :param function_code: The function we are erroring on\n        \"\"\"\n        super().__init__(**kwargs)\n        self.function_code = function_code\n\n    def decode(self, _data):\n        \"\"\"Decode so this failure will run correctly.\"\"\"\n\n    def execute(self, _context):\n        \"\"\"Build an illegal function request error response.\n\n        :returns: The error response packet\n        \"\"\"\n        return ExceptionResponse(self.function_code, self.ErrorCode)\n", "path": "pymodbus/pdu.py"}]}