text: # Copyright (c) 2018 Kevin Weiss, for HAW Hamburg  <kevin.weiss@haw-hamburg.de>
  #
  # This file is subject to the terms and conditions of the MIT License. See the
  # file LICENSE in the top level directory for more details.
  # SPDX-License-Identifier:    MIT
  """Abstract Base Device for RIOT PAL
  This module is the abstract device that interfaces to a driver.  It handles the
  selection and initialzation of the driver.
  
  Example:
      class ApplicationDevice(BaseDevice):
          def show_example(self):
              self._write('Send Example')
              print(self._read())
  
      example_use_case = ApplicationDevice('serial', port='my/port/name')
      example_use_case.show_example()
  """
  import logging
  try:
      from .serial_driver import SerialDriver
  except ImportError:
      from serial_driver import SerialDriver
  try:
      from .riot_driver import RiotDriver
  except ImportError:
      from riot_driver import RiotDriver
  
  
  class BaseDevice:
      """Instance for devices to connect and utilize drivers.
  
      Args:
          driver_type(str): Selects the driver that is used on the devices.
              'serial' uses the standard serial port, all following arguments
              get passed through.
              'riot' uses the riot make term system.
          *args: Variable length argument list.
          **kwargs: Arbitrary keyword arguments.
      """
  
      def __init__(self, *args, **kwargs):
          self._driver = self._driver_from_config(*args, **kwargs)
  
      def close(self):
          """Closes the device connection."""
          self._driver.close()
  
      def _readline(self):
          """Reads data from the driver.
  
          Returns:
              str: string of data if success, driver defined error if failed.
          """
          return self._driver.readline()
  
      def _write(self, data):
          """Writes data to the driver.
  
          Args:
              data(str): Variable length argument list.
          """
          return self._driver.write(data)
  
      @staticmethod
      def _driver_from_config(*args, **kwargs):
          """Returns driver instance given configuration"""
          driver_type = kwargs.pop('driver_type', 'serial')
  
          if driver_type == 'serial':
              return SerialDriver(*args, **kwargs)
          elif driver_type == 'riot':
              return RiotDriver(*args, **kwargs)
          elif driver_type == 'driver':
              return kwargs['driver']
          raise NotImplementedError()
  
      @classmethod
      def copy_driver(cls, device):
          """Copies the driver instance so many devices can use one driver."""
          # pylint: disable=W0212
          logging.debug("Cloning Driver: %r", device._driver)
          return cls(driver_type='driver', driver=device._driver)
  