text: import asyncio
  import functools
  import logging
  import time
  
  from pycec.commands import CecCommand, KeyPressCommand, KeyReleaseCommand, \
      PollCommand
  from pycec.const import CMD_STANDBY, KEY_POWER
  from pycec.network import AbstractCecAdapter, HDMINetwork
  
  DEFAULT_PORT = 9526
  MAX_CONNECTION_ATTEMPTS = 5
  CONNECTION_ATTEMPT_DELAY = 3
  _LOGGER = logging.getLogger(__name__)
  
  
  # pragma: no cover
  class TcpAdapter(AbstractCecAdapter):
      def __init__(self, host, port=DEFAULT_PORT, name=None,
                   activate_source=None):
          super().__init__()
          self._polling = dict()
          self._command_callback = None
          self._tcp_loop = asyncio.new_event_loop()
          self._host = host
          self._port = port
          self._transport = None
          self._osd_name = name
          self._activate_source = activate_source
  
      def _after_init(self, callback, f):
          if self._transport:
              _LOGGER.debug("New client: %s", self._transport)
              self._initialized = True
              self._tcp_loop.run_in_executor(None, self._tcp_loop.run_forever)
          if callback:
              callback()
  
      def _init(self):
          for i in range(0, MAX_CONNECTION_ATTEMPTS):
              try:
                  self._transport, protocol = self._tcp_loop.run_until_complete(
                      self._tcp_loop.create_connection(lambda: TcpProtocol(self),
                                                       host=self._host,
                                                       port=self._port))
                  _LOGGER.debug("Connection started.")
                  break
              except (ConnectionRefusedError, RuntimeError) as e:
                  _LOGGER.warning(
                      "Unable to connect due to %s. Trying again in %d seconds, "
                      "%d attempts remaining.",
                      e, CONNECTION_ATTEMPT_DELAY, MAX_CONNECTION_ATTEMPTS - i)
                  time.sleep(CONNECTION_ATTEMPT_DELAY)
          else:
              _LOGGER.error("Unable to connect! Giving up.")
              self.shutdown()
  
      def init(self, callback: callable = None):
          _LOGGER.debug("Starting connection...")
          task = self._loop.run_in_executor(None, self._init)
          task.add_done_callback(functools.partial(self._after_init, callback))
          return task
  
      def shutdown(self):
          self._initialized = False
          if self._transport and not self._transport.is_closing():
              self._transport.close()
          self._transport = None
  
      def _poll_device(self, device):
          req = self._loop.time()
          poll_bucket = self._polling.get(device, set())
          poll_bucket.add(req)
          self._polling.update({device: poll_bucket})
          self.transmit(PollCommand(device))
          while True:
              if req not in self._polling.get(device, set()):
                  _LOGGER.debug("Found device %d.", device)
                  return True
              if self._loop.time() > (req + 5):
                  return False
              time.sleep(.1)
  
      def poll_device(self, device):
          return self._loop.run_in_executor(None, self._poll_device, device)
  
      def get_logical_address(self):
          return 0xf
  
      def standby_devices(self):
          self.transmit(CecCommand(CMD_STANDBY))
  
      def transmit(self, command: CecCommand):
          self._transport.write(("%s\r\n" % command.raw).encode())
  
      def set_command_callback(self, callback):
          self._command_callback = callback
  
      def power_on_devices(self):
          self.transmit(KeyPressCommand(KEY_POWER))
          self.transmit(KeyReleaseCommand())
  
      def set_transport(self, transport):
          self._transport = transport
  
  
  class TcpProtocol(asyncio.Protocol):
      buffer = ''
  
      def __init__(self, adapter: TcpAdapter):
          self._adapter = adapter
          self.transport = None
  
      def connection_made(self, transport):
          self.transport = transport
          self._adapter.set_transport = transport
  
      def data_received(self, data: bytes):
          self.buffer += bytes.decode(data)
          for line in self.buffer.splitlines(keepends=True):
              if line.count('\n') or line.count('\r'):
                  line = line.rstrip()
                  _LOGGER.debug("Received %s from %s", line,
                                self.transport.get_extra_info('peername'))
                  if len(line) == 2:
                      cmd = CecCommand(line)
                      if cmd.src in self._adapter._polling:
                          del self._adapter._polling[cmd.src]
                  else:
                      self._adapter._command_callback("<< " + line)
                  self.buffer = ''
              else:
                  self.buffer = line
  
      def eof_received(self):
          self._adapter.shutdown()
  
      def connection_lost(self, exc):
          _LOGGER.warning("Connection lost. Trying to reconnect...")
          self._adapter.shutdown()
          self._adapter._tcp_loop.stop()
          self._adapter.init()
  
  
  def main():
      """For testing purpose"""
      tcp_adapter = TcpAdapter("192.168.1.5", name="HASS", activate_source=False)
      hdmi_network = HDMINetwork(tcp_adapter)
      hdmi_network.start()
      while True:
          for d in hdmi_network.devices:
              _LOGGER.info("Device: %s", d)
  
          time.sleep(7)
  
  
  if __name__ == '__main__':
      # Configure logging
      _LOGGER.setLevel(logging.DEBUG)
      ch = logging.StreamHandler()
      ch.setLevel(logging.DEBUG)
      try:
          from colorlog import ColoredFormatter
  
          formatter = ColoredFormatter(
              "%(log_color)s%(levelname)-8s %(message)s",
              datefmt=None,
              reset=True,
              log_colors={
                  'DEBUG': 'cyan',
                  'INFO': 'green',
                  'WARNING': 'yellow',
                  'ERROR': 'red',
                  'CRITICAL': 'red',
              }
          )
      except ImportError:
          formatter = logging.Formatter(
              '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
  
      ch.setFormatter(formatter)
      _LOGGER.addHandler(ch)
  
      main()
  