def rpc_v2(self, cmd, arg_format, result_format, *args, **kw):
        """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
        """
        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)
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