<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 async def _request(self, method, *args, **kwargs):
 """Send a request to the device and awaits a response. This mainly ensures that requests are sent serially, as the Modbus protocol does not allow simultaneous requests (it'll ignore any request sent while it's processing something). The driver handles this by assuming there is only one client instance. If other clients exist, other logic will have to be added to either prevent or manage race conditions. """

        if not self.open:
            await self._connect()
        while self.waiting:
            await asyncio.sleep(0.1)
        if self.client.protocol is None or not self.client.protocol.connected:
            raise TimeoutError("Not connected to device.")
        try:
            future = getattr(self.client.protocol, method)(*args, **kwargs)
        except AttributeError:
            raise TimeoutError("Not connected to device.")
        self.waiting = True
        try:
            return await asyncio.wait_for(future, timeout=self.timeout)
        except asyncio.TimeoutError as e:
            if self.open:
                # This came from reading through the pymodbus@python3 source
                # Problem was that the driver was not detecting disconnect
                if hasattr(self, 'modbus'):
                    self.client.protocol_lost_connection(self.modbus)
                self.open = False
            raise TimeoutError(e)
        except pymodbus.exceptions.ConnectionException as e:
            raise ConnectionError(e)
        finally:
            self.waiting = False