code: def rpc_v2(self, cmd, arg_format, result_format, *args, **kw):
          
          if args:
              packed_args = pack_rpc_payload(arg_format, list(args))
          elif arg_format == "":
              packed_args = b''
          else:
              raise RPCInvalidArgumentsError("Arg format expects arguments to be present", arg_format=arg_format, args=args)
  
          passed_kw = dict()
          if 'timeout' in kw:
              passed_kw['timeout'] = kw['timeout']
  
          try:
              should_retry = False
              payload = self.stream.send_rpc(self.addr, cmd, packed_args, **passed_kw)
          except BusyRPCResponse:
              if "retries" not in kw:
                  kw['retries'] = 10
  
              # Sleep 100 ms and try again unless we've exhausted our retry attempts
              if kw["retries"] == 0:
                  raise BusyRPCResponse("Could not complete RPC %d:%04X after 10 attempts due to busy tile" %
                                        (self.addr, cmd))
  
              should_retry = True
  
          # If the tile was busy, automatically retry up to 10 times
          if should_retry:
              kw['retries'] -= 1
              sleep(0.1)
              return self.rpc_v2(cmd, arg_format, result_format, *args, **kw)
  
          return unpack_rpc_payload(result_format, payload)
docs: Send an RPC call to this module, interpret the return value
          according to the result_type kw argument.  Unless raise keyword
          is passed with value False, raise an RPCException if the command
          is not successful.
  
          v2 enforces the use of arg_format and result_format
          v2 combines the feature+cmd chunks in to a single 2-byte chunk