<commit_before>"""Module containing the connection wrapper for the PLM interface."""
import asyncio
import logging
import serial
import serial.aio

from .plm import PLM

__all__ = ('Connection')

# pylint: disable=invalid-name,no-member
try:
    ensure_future = asyncio.ensure_future
except AttributeError:
    ensure_future = asyncio.async


class Connection:
    """Handler to maintain the Powerline device connection."""

    def __init__(self):
        """Instantiate the Connection object."""
        self.log = logging.getLogger(__name__)

    @classmethod
    @asyncio.coroutine
    def create(cls, device='/dev/ttyUSB0',
               auto_reconnect=True, loop=None, protocol_class=PLM, userdefined=()):
        """Initiate a connection to a specific device.

        Here is where we supply the device and callback callables we
        expect for this PLM class object.

        :param device:
            Unix device where the PLM is attached
        :param auto_reconnect:
            Should the Connection try to automatically reconnect if needed?
        :param loop:
            asyncio.loop for async operation

        :type device:
            str
        :type auto_reconnect:
            boolean
        :type loop:
            asyncio.loop
        :type update_callback:
            callable
        """
        conn = cls()

        conn.device = device
        conn._loop = loop or asyncio.get_event_loop()
        conn._retry_interval = 1
        conn._closed = False
        conn._closing = False
        conn._halted = False
        conn._auto_reconnect = auto_reconnect

        def connection_lost():
            """Function callback for Protocol when connection is lost."""
            if conn._auto_reconnect and not conn._closing:
                ensure_future(conn._reconnect(), loop=conn._loop)

        conn.protocol = protocol_class(
            connection_lost_callback=connection_lost, 
            loop=conn._loop, 
            userdefineddevices=userdefined)

        yield from conn._reconnect()

        return conn

    @property
    def transport(self):
        """Return pointer to the transport object.

        Use this property to obtain passthrough access to the underlying
        Protocol properties and methods.
        """
        return self.protocol.transport

    def _get_retry_interval(self):
        return self._retry_interval

    def _reset_retry_interval(self):
        self._retry_interval = 1

    def _increase_retry_interval(self):
        self._retry_interval = min(300, 1.5 * self._retry_interval)

    @asyncio.coroutine
    def _reconnect(self):
        while True:
            try:
                if self._halted:
                    yield from asyncio.sleep(2, loop=self._loop)
                else:
                    self.log.info('Connecting to PLM on %s', self.device)
                    yield from serial.aio.create_serial_connection(
                        self._loop, lambda: self.protocol,
                        self.device, baudrate=19200, timeout=1)
                    self._reset_retry_interval()
                    return

            except OSError:
                self._increase_retry_interval()
                interval = self._get_retry_interval()
                self.log.warning('Connecting failed, retry in %i seconds: %s',
                                 interval, self.device)
                yield from asyncio.sleep(interval, loop=self._loop)

    def close(self):
        """Close the PLM device connection and don't try to reconnect."""
        self.log.warning('Closing connection to PLM')
        self._closing = True
        if self.protocol.transport:
            self.protocol.transport.close()

    def halt(self):
        """Close the PLM device connection and wait for a resume() request."""
        self.log.warning('Halting connection to PLM')
        self._halted = True<commit_msg>Removing timeout setting in create_serial_connection since serial.aio overrides it anyway. Moving to PLM.<commit_after>"""Module containing the connection wrapper for the PLM interface."""
import asyncio
import logging
import serial
import serial.aio

from .plm import PLM

__all__ = ('Connection')

# pylint: disable=invalid-name,no-member
try:
    ensure_future = asyncio.ensure_future
except AttributeError:
    ensure_future = asyncio.async


class Connection:
    """Handler to maintain the Powerline device connection."""

    def __init__(self):
        """Instantiate the Connection object."""
        self.log = logging.getLogger(__name__)

    @classmethod
    @asyncio.coroutine
    def create(cls, device='/dev/ttyUSB0',
               auto_reconnect=True, loop=None, protocol_class=PLM, userdefined=()):
        """Initiate a connection to a specific device.

        Here is where we supply the device and callback callables we
        expect for this PLM class object.

        :param device:
            Unix device where the PLM is attached
        :param auto_reconnect:
            Should the Connection try to automatically reconnect if needed?
        :param loop:
            asyncio.loop for async operation

        :type device:
            str
        :type auto_reconnect:
            boolean
        :type loop:
            asyncio.loop
        :type update_callback:
            callable
        """
        conn = cls()

        conn.device = device
        conn._loop = loop or asyncio.get_event_loop()
        conn._retry_interval = 1
        conn._closed = False
        conn._closing = False
        conn._halted = False
        conn._auto_reconnect = auto_reconnect

        def connection_lost():
            """Function callback for Protocol when connection is lost."""
            if conn._auto_reconnect and not conn._closing:
                ensure_future(conn._reconnect(), loop=conn._loop)

        conn.protocol = protocol_class(
            connection_lost_callback=connection_lost, 
            loop=conn._loop, 
            userdefineddevices=userdefined)

        yield from conn._reconnect()

        return conn

    @property
    def transport(self):
        """Return pointer to the transport object.

        Use this property to obtain passthrough access to the underlying
        Protocol properties and methods.
        """
        return self.protocol.transport

    def _get_retry_interval(self):
        return self._retry_interval

    def _reset_retry_interval(self):
        self._retry_interval = 1

    def _increase_retry_interval(self):
        self._retry_interval = min(300, 1.5 * self._retry_interval)

    @asyncio.coroutine
    def _reconnect(self):
        while True:
            try:
                if self._halted:
                    yield from asyncio.sleep(2, loop=self._loop)
                else:
                    self.log.info('Connecting to PLM on %s', self.device)
                    yield from serial.aio.create_serial_connection(
                        self._loop, lambda: self.protocol,
                        self.device, baudrate=19200)
                    self._reset_retry_interval()
                    return

            except OSError:
                self._increase_retry_interval()
                interval = self._get_retry_interval()
                self.log.warning('Connecting failed, retry in %i seconds: %s',
                                 interval, self.device)
                yield from asyncio.sleep(interval, loop=self._loop)

    def close(self):
        """Close the PLM device connection and don't try to reconnect."""
        self.log.warning('Closing connection to PLM')
        self._closing = True
        if self.protocol.transport:
            self.protocol.transport.close()

    def halt(self):
        """Close the PLM device connection and wait for a resume() request."""
        self.log.warning('Halting connection to PLM')
        self._halted = True
{'fraction_non_alphanumeric': 0.07702068265448547, 'fraction_numerical': 0.0036797360741022715, 'mean_word_length': 2.0257197696737044, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3361051', 'n_tokens_mistral': 2067, 'n_tokens_neox': 1983, 'n_words': 594}