text: #!/usr/bin/env python3
  # -*- coding: utf-8-unix -*-
  """
  Library to control moRFeus mixer/signal generator.
  
  Usage:
    import morfeus
  
    mrf = morfeus.MoRFeus()
    mrf.mode = morfeus.Mode.GENERATOR
    mrf.freq = 120000000
  
  """
  
  import hid
  import enum
  from struct import pack, unpack
  
  VID = 0x10C4
  PID = 0xEAC9
  
  CMD_GET = 0x72
  CMD_SET = 0x77
  
  # REPORT ID must be prepended to every hid_write to make it cross-platform.
  REPORT_ID = 0x00
  
  class Mode(enum.Enum):
      MIXER = 0
      GENERATOR = 1
  
  class MoRFeus(object):
      """Creates instance to control moRFeus.
  
  Example:
    mrf = MoRFeus()
    mrf = MoRFeus(morfeus.VID, morfeus.PID)
  """
      def __init__(self, vid=VID, pid=PID, index=0):
          try:
              found = hid.enumerate(VID, PID)[index]
              self.dev = hid.device()
              self.dev.open_path(found['path'])
          except IndexError as e:
              raise Exception("No device found") from e
  
      @property
      def freq(self):
          """Get or set Frequency in HZ
  Example:
    mrf.freq = 120000000
    print(mrf.freq)
  """
          dev = self.dev
          msg = pack(">BBB14x", REPORT_ID, CMD_GET, 0x81)
          dev.write(msg)
  
          ret = dev.read(16)
          return int.from_bytes(ret[2:10], byteorder='big', signed=False)
  
      @freq.setter
      def freq(self, freq):
          dev = self.dev
          msg = pack(">BBBQ6x", REPORT_ID, CMD_SET, 0x81, freq)
          dev.write(msg)
          dev.read(16)
  
      @property
      def mode(self):
          """Get or set function mode
  Example:
    mrf.mode = morfeus.Mode.MIXER
    print(mrf.mode)
    mrf.mode = morfeus.Mode.GENERATOR
    print(mrf.mode)
  """
          dev = self.dev
          msg = pack(">BBB14x", REPORT_ID, CMD_GET, 0x82)
          dev.write(msg)
  
          ret = dev.read(16)
          val = int.from_bytes(ret[2:10], byteorder='big', signed=False)
          return Mode(val)
  
      @mode.setter
      def mode(self, mode):
          dev = self.dev
          msg = pack(">BBBQ6x", REPORT_ID, CMD_SET, 0x82, mode.value)
          dev.write(msg)
          dev.read(16)
  
      @property
      def current(self):
          """Get or set current level
  Example:
    mrf.current = 1
    print(mrf.current)
  """
          dev = self.dev
          msg = pack(">BBB14x", REPORT_ID, CMD_GET, 0x83)
          dev.write(msg)
  
          ret = dev.read(16)
          return int.from_bytes(ret[2:10], byteorder='big', signed=False)
  
      @current.setter
      def current(self, level=0):
          dev = self.dev
          msg = pack(">BBBQ6x", REPORT_ID, CMD_SET, 0x83, level)
          dev.write(msg)
          dev.read(16)
  
      @property
      def bias(self):
          """Get or set Bias-T status
  Example:
    mrf.bias = 1
    print(mrf.bias)
  """
          dev = self.dev
          msg = pack(">BBB14x", REPORT_ID, CMD_GET, 0x84)
          dev.write(msg)
  
          ret = dev.read(16)
          return int.from_bytes(ret[2:10], byteorder='big', signed=False)
  
      @bias.setter
      def bias(self, status=0):
          dev = self.dev
          msg = pack(">BBBQ6x", REPORT_ID, CMD_SET, 0x84, status)
          dev.write(msg)
          dev.read(16)
  
  if __name__ == '__main__' and '__file__' in globals():
      from IPython import embed
      mrf = MoRFeus()
      mrf.freq = 123000000
      print(mrf.freq)
      mrf.freq += 1000000
      print(mrf.freq)
      embed()
  