All Downloads are FREE. Search and download functionalities are using the official Maven repository.

zaber.motion.ascii.Connection Maven / Gradle / Ivy

Go to download

A library that aims to provide easy-to-use API for communication with Zaber devices using Zaber ASCII Protocol.

There is a newer version: 6.7.0
Show newest version
// ===== THIS FILE IS GENERATED FROM A TEMPLATE ===== //
// ============== DO NOT EDIT DIRECTLY ============== //

package zaber.motion.ascii;

import zaber.motion.protobufs.Main;
import zaber.motion.ArrayUtility;
import zaber.motion.gateway.Call;
import zaber.motion.gateway.Events;
import zaber.motion.exceptions.ExceptionConverter;
import zaber.motion.exceptions.MotionLibException;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import io.reactivex.Observable;
import io.reactivex.subjects.ReplaySubject;
import io.reactivex.subjects.Subject;

/**
 * Class representing access to particular connection (serial port, TCP connection).
 */
public class Connection implements AutoCloseable {
    private Observable unknownResponse;

    /**
     * Event invoked when a response from a device cannot be matched to any known request.
     */
    public Observable getUnknownResponse() {
        return this.unknownResponse;
    }

    private Observable alert;

    /**
     * Event invoked when an alert is received from a device.
     */
    public Observable getAlert() {
        return this.alert;
    }

    private Subject disconnected = ReplaySubject.create();

    /**
     * Event invoked when connection is interrupted or closed.
     */
    public Observable getDisconnected() {
        return this.disconnected;
    }

    /**
     * Default baud rate for serial connections.
     */
    public static final int DEFAULT_BAUD_RATE = 115200;


    private int interfaceId;

    /**
     * @return The interface ID identifies this Connection instance with the underlying library.
     */
    public int getInterfaceId() {
        return this.interfaceId;
    }


    /**
     * @return The default timeout, in milliseconds, for a device to respond to a request.
     * Setting the timeout to a too low value may cause request timeout exceptions.
     */
    public int getDefaultRequestTimeout() {
        return this.retrieveTimeout();
    }

    /**
     * The default timeout, in milliseconds, for a device to respond to a request.
     * Setting the timeout to a too low value may cause request timeout exceptions.
     */
    public void setDefaultRequestTimeout(int value) {
        this.changeTimeout(value);
    }


    /**
     * @return Controls whether outgoing messages contain checksum.
     */
    public boolean getChecksumEnabled() {
        return this.retrieveChecksumEnabled();
    }

    /**
     * Controls whether outgoing messages contain checksum.
     */
    public void setChecksumEnabled(boolean value) {
        this.changeChecksumEnabled(value);
    }

    public Connection(
        int interfaceId) {
        this.interfaceId = interfaceId;
        this.subscribe();
    }

    /**
     * Opens a serial port, if Zaber Launcher controls the port, the port will be opened through Zaber Launcher.
     * Zaber Launcher allows sharing of the port between multiple applications.
     * Use openSerialPortDirectly if sharing is not desirable.
     * @param portName Name of the port to open.
     * @param baudRate Optional baud rate (defaults to 115200).
     * @return A CompletableFuture that can be completed to get the result:
     * An object representing the port.
     */
    public static CompletableFuture openSerialPortAsync(
        String portName, int baudRate) {
        Main.OpenInterfaceRequest.Builder builder = Main.OpenInterfaceRequest.newBuilder();
        builder = builder.setInterfaceType(Main.InterfaceType.SERIAL_PORT);

        builder = builder.setPortName(portName);
        builder = builder.setBaudRate(baudRate);
        CompletableFuture response = Call.callAsync(
            "interface/open",
            builder.build(),
            Main.OpenInterfaceResponse.parser());
        return response
            .thenApply(r -> new Connection(r.getInterfaceId()));
    }

    /**
     * Opens a serial port, if Zaber Launcher controls the port, the port will be opened through Zaber Launcher.
     * Zaber Launcher allows sharing of the port between multiple applications.
     * Use openSerialPortDirectly if sharing is not desirable.
     * @param portName Name of the port to open.
     * @return A CompletableFuture that can be completed to get the result:
     * An object representing the port.
     */
    public static CompletableFuture openSerialPortAsync(
        String portName) {
        return openSerialPortAsync(portName, DEFAULT_BAUD_RATE);
    }

    /**
     * Opens a serial port, if Zaber Launcher controls the port, the port will be opened through Zaber Launcher.
     * Zaber Launcher allows sharing of the port between multiple applications.
     * Use openSerialPortDirectly if sharing is not desirable.
     * @param portName Name of the port to open.
     * @param baudRate Optional baud rate (defaults to 115200).
     * @return An object representing the port.
     */
    public static Connection openSerialPort(
        String portName, int baudRate) {
        try {
            return openSerialPortAsync(portName, baudRate).get();
        } catch (ExecutionException e) {
            if (e.getCause() instanceof MotionLibException) {
                throw (MotionLibException) e.getCause();
            } else {
                throw new MotionLibException(e.getCause());
            }
        } catch (InterruptedException e) {
            throw new MotionLibException(e);
        }
    }

    /**
     * Opens a serial port, if Zaber Launcher controls the port, the port will be opened through Zaber Launcher.
     * Zaber Launcher allows sharing of the port between multiple applications.
     * Use openSerialPortDirectly if sharing is not desirable.
     * @param portName Name of the port to open.
     * @return An object representing the port.
     */
    public static Connection openSerialPort(
        String portName) {
        return openSerialPort(portName, DEFAULT_BAUD_RATE);
    }

    /**
     * Opens a serial port, bypassing Zaber Launcher.
     * If the port is already opened by Zaber Launcher, this will fail.
     * @param portName Name of the port to open.
     * @param baudRate Optional baud rate (defaults to 115200).
     * @return A CompletableFuture that can be completed to get the result:
     * An object representing the port.
     */
    public static CompletableFuture openSerialPortDirectlyAsync(
        String portName, int baudRate) {
        Main.OpenInterfaceRequest.Builder builder = Main.OpenInterfaceRequest.newBuilder();
        builder = builder.setInterfaceType(Main.InterfaceType.SERIAL_PORT);
        builder = builder.setRejectRoutedConnection(true);

        builder = builder.setPortName(portName);
        builder = builder.setBaudRate(baudRate);
        CompletableFuture response = Call.callAsync(
            "interface/open",
            builder.build(),
            Main.OpenInterfaceResponse.parser());
        return response
            .thenApply(r -> new Connection(r.getInterfaceId()));
    }

    /**
     * Opens a serial port, bypassing Zaber Launcher.
     * If the port is already opened by Zaber Launcher, this will fail.
     * @param portName Name of the port to open.
     * @return A CompletableFuture that can be completed to get the result:
     * An object representing the port.
     */
    public static CompletableFuture openSerialPortDirectlyAsync(
        String portName) {
        return openSerialPortDirectlyAsync(portName, DEFAULT_BAUD_RATE);
    }

    /**
     * Opens a serial port, bypassing Zaber Launcher.
     * If the port is already opened by Zaber Launcher, this will fail.
     * @param portName Name of the port to open.
     * @param baudRate Optional baud rate (defaults to 115200).
     * @return An object representing the port.
     */
    public static Connection openSerialPortDirectly(
        String portName, int baudRate) {
        try {
            return openSerialPortDirectlyAsync(portName, baudRate).get();
        } catch (ExecutionException e) {
            if (e.getCause() instanceof MotionLibException) {
                throw (MotionLibException) e.getCause();
            } else {
                throw new MotionLibException(e.getCause());
            }
        } catch (InterruptedException e) {
            throw new MotionLibException(e);
        }
    }

    /**
     * Opens a serial port, bypassing Zaber Launcher.
     * If the port is already opened by Zaber Launcher, this will fail.
     * @param portName Name of the port to open.
     * @return An object representing the port.
     */
    public static Connection openSerialPortDirectly(
        String portName) {
        return openSerialPortDirectly(portName, DEFAULT_BAUD_RATE);
    }

    /**
     * Opens a TCP connection.
     * @param hostName Hostname or IP address.
     * @param port Port number.
     * @return A CompletableFuture that can be completed to get the result:
     * An object representing the connection.
     */
    public static CompletableFuture openTcpAsync(
        String hostName, int port) {
        Main.OpenInterfaceRequest.Builder builder = Main.OpenInterfaceRequest.newBuilder();
        builder = builder.setInterfaceType(Main.InterfaceType.TCP);

        builder = builder.setHostName(hostName);
        builder = builder.setPort(port);
        CompletableFuture response = Call.callAsync(
            "interface/open",
            builder.build(),
            Main.OpenInterfaceResponse.parser());
        return response
            .thenApply(r -> new Connection(r.getInterfaceId()));
    }

    /**
     * Opens a TCP connection.
     * @param hostName Hostname or IP address.
     * @param port Port number.
     * @return An object representing the connection.
     */
    public static Connection openTcp(
        String hostName, int port) {
        try {
            return openTcpAsync(hostName, port).get();
        } catch (ExecutionException e) {
            if (e.getCause() instanceof MotionLibException) {
                throw (MotionLibException) e.getCause();
            } else {
                throw new MotionLibException(e.getCause());
            }
        } catch (InterruptedException e) {
            throw new MotionLibException(e);
        }
    }

    /**
     * Opens a connection using a custom transport.
     * @param transport The custom connection transport.
     * @return A CompletableFuture that can be completed to get the result:
     * An object representing the connection.
     */
    public static CompletableFuture openCustomAsync(
        Transport transport) {
        Main.OpenInterfaceRequest.Builder builder = Main.OpenInterfaceRequest.newBuilder();
        builder = builder.setInterfaceType(Main.InterfaceType.CUSTOM);

        builder = builder.setTransport(transport.getTransportId());
        CompletableFuture response = Call.callAsync(
            "interface/open",
            builder.build(),
            Main.OpenInterfaceResponse.parser());
        return response
            .thenApply(r -> new Connection(r.getInterfaceId()));
    }

    /**
     * Opens a connection using a custom transport.
     * @param transport The custom connection transport.
     * @return An object representing the connection.
     */
    public static Connection openCustom(
        Transport transport) {
        try {
            return openCustomAsync(transport).get();
        } catch (ExecutionException e) {
            if (e.getCause() instanceof MotionLibException) {
                throw (MotionLibException) e.getCause();
            } else {
                throw new MotionLibException(e.getCause());
            }
        } catch (InterruptedException e) {
            throw new MotionLibException(e);
        }
    }

    /**
     * Opens a unauthenticated connection to a cloud connected device chain.
     * Use this method to connect to Virtual Device Demo instance.
     * @param cloudId The cloud ID to connect to.
     * @param connectionName The name of the connection to open.
     * Can be left empty to default to the only connection present.
     * Otherwise, use serial port name for serial port connection or hostname:port for TCP connection.
     * @param api The URL of the API to receive connection info from.
     * @return A CompletableFuture that can be completed to get the result:
     * An object representing the connection.
     */
    public static CompletableFuture openIotUnauthenticatedAsync(
        String cloudId, String connectionName, String api) {
        Main.OpenInterfaceRequest.Builder builder = Main.OpenInterfaceRequest.newBuilder();
        builder = builder.setInterfaceType(Main.InterfaceType.IOT);
        builder = builder.setRealm("unauthenticated");
        builder = builder.setToken("unauthenticated");

        builder = builder.setCloudId(cloudId);
        builder = builder.setConnectionName(connectionName);
        builder = builder.setApi(api);
        CompletableFuture response = Call.callAsync(
            "interface/open",
            builder.build(),
            Main.OpenInterfaceResponse.parser());
        return response
            .thenApply(r -> new Connection(r.getInterfaceId()));
    }

    /**
     * Opens a unauthenticated connection to a cloud connected device chain.
     * Use this method to connect to Virtual Device Demo instance.
     * @param cloudId The cloud ID to connect to.
     * @param connectionName The name of the connection to open.
     * Can be left empty to default to the only connection present.
     * Otherwise, use serial port name for serial port connection or hostname:port for TCP connection.
     * @return A CompletableFuture that can be completed to get the result:
     * An object representing the connection.
     */
    public static CompletableFuture openIotUnauthenticatedAsync(
        String cloudId, String connectionName) {
        return openIotUnauthenticatedAsync(cloudId, connectionName, "https://api.zaber.io");
    }

    /**
     * Opens a unauthenticated connection to a cloud connected device chain.
     * Use this method to connect to Virtual Device Demo instance.
     * @param cloudId The cloud ID to connect to.
     * @return A CompletableFuture that can be completed to get the result:
     * An object representing the connection.
     */
    public static CompletableFuture openIotUnauthenticatedAsync(
        String cloudId) {
        return openIotUnauthenticatedAsync(cloudId, "", "https://api.zaber.io");
    }

    /**
     * Opens a unauthenticated connection to a cloud connected device chain.
     * Use this method to connect to Virtual Device Demo instance.
     * @param cloudId The cloud ID to connect to.
     * @param connectionName The name of the connection to open.
     * Can be left empty to default to the only connection present.
     * Otherwise, use serial port name for serial port connection or hostname:port for TCP connection.
     * @param api The URL of the API to receive connection info from.
     * @return An object representing the connection.
     */
    public static Connection openIotUnauthenticated(
        String cloudId, String connectionName, String api) {
        try {
            return openIotUnauthenticatedAsync(cloudId, connectionName, api).get();
        } catch (ExecutionException e) {
            if (e.getCause() instanceof MotionLibException) {
                throw (MotionLibException) e.getCause();
            } else {
                throw new MotionLibException(e.getCause());
            }
        } catch (InterruptedException e) {
            throw new MotionLibException(e);
        }
    }

    /**
     * Opens a unauthenticated connection to a cloud connected device chain.
     * Use this method to connect to Virtual Device Demo instance.
     * @param cloudId The cloud ID to connect to.
     * @param connectionName The name of the connection to open.
     * Can be left empty to default to the only connection present.
     * Otherwise, use serial port name for serial port connection or hostname:port for TCP connection.
     * @return An object representing the connection.
     */
    public static Connection openIotUnauthenticated(
        String cloudId, String connectionName) {
        return openIotUnauthenticated(cloudId, connectionName, "https://api.zaber.io");
    }

    /**
     * Opens a unauthenticated connection to a cloud connected device chain.
     * Use this method to connect to Virtual Device Demo instance.
     * @param cloudId The cloud ID to connect to.
     * @return An object representing the connection.
     */
    public static Connection openIotUnauthenticated(
        String cloudId) {
        return openIotUnauthenticated(cloudId, "", "https://api.zaber.io");
    }

    /**
     * Opens a secured connection to a cloud connected device chain.
     * Use this method to connect to devices on your account.
     * @param cloudId The cloud ID to connect to.
     * @param token The token to authenticate with.
     * @param connectionName The name of the connection to open.
     * Can be left empty to default to the only connection present.
     * Otherwise, use serial port name for serial port connection or hostname:port for TCP connection.
     * @param realm The realm to connect to.
     * @param api The URL of the API to receive connection info from.
     * @return A CompletableFuture that can be completed to get the result:
     * An object representing the connection.
     */
    public static CompletableFuture openIotAuthenticatedAsync(
        String cloudId, String token, String connectionName, String realm, String api) {
        Main.OpenInterfaceRequest.Builder builder = Main.OpenInterfaceRequest.newBuilder();
        builder = builder.setInterfaceType(Main.InterfaceType.IOT);

        builder = builder.setCloudId(cloudId);
        builder = builder.setToken(token);
        builder = builder.setConnectionName(connectionName);
        builder = builder.setRealm(realm);
        builder = builder.setApi(api);
        CompletableFuture response = Call.callAsync(
            "interface/open",
            builder.build(),
            Main.OpenInterfaceResponse.parser());
        return response
            .thenApply(r -> new Connection(r.getInterfaceId()));
    }

    /**
     * Opens a secured connection to a cloud connected device chain.
     * Use this method to connect to devices on your account.
     * @param cloudId The cloud ID to connect to.
     * @param token The token to authenticate with.
     * @param connectionName The name of the connection to open.
     * Can be left empty to default to the only connection present.
     * Otherwise, use serial port name for serial port connection or hostname:port for TCP connection.
     * @param realm The realm to connect to.
     * @return A CompletableFuture that can be completed to get the result:
     * An object representing the connection.
     */
    public static CompletableFuture openIotAuthenticatedAsync(
        String cloudId, String token, String connectionName, String realm) {
        return openIotAuthenticatedAsync(cloudId, token, connectionName, realm, "https://api.zaber.io");
    }

    /**
     * Opens a secured connection to a cloud connected device chain.
     * Use this method to connect to devices on your account.
     * @param cloudId The cloud ID to connect to.
     * @param token The token to authenticate with.
     * @param connectionName The name of the connection to open.
     * Can be left empty to default to the only connection present.
     * Otherwise, use serial port name for serial port connection or hostname:port for TCP connection.
     * @return A CompletableFuture that can be completed to get the result:
     * An object representing the connection.
     */
    public static CompletableFuture openIotAuthenticatedAsync(
        String cloudId, String token, String connectionName) {
        return openIotAuthenticatedAsync(cloudId, token, connectionName, "", "https://api.zaber.io");
    }

    /**
     * Opens a secured connection to a cloud connected device chain.
     * Use this method to connect to devices on your account.
     * @param cloudId The cloud ID to connect to.
     * @param token The token to authenticate with.
     * @return A CompletableFuture that can be completed to get the result:
     * An object representing the connection.
     */
    public static CompletableFuture openIotAuthenticatedAsync(
        String cloudId, String token) {
        return openIotAuthenticatedAsync(cloudId, token, "", "", "https://api.zaber.io");
    }

    /**
     * Opens a secured connection to a cloud connected device chain.
     * Use this method to connect to devices on your account.
     * @param cloudId The cloud ID to connect to.
     * @param token The token to authenticate with.
     * @param connectionName The name of the connection to open.
     * Can be left empty to default to the only connection present.
     * Otherwise, use serial port name for serial port connection or hostname:port for TCP connection.
     * @param realm The realm to connect to.
     * @param api The URL of the API to receive connection info from.
     * @return An object representing the connection.
     */
    public static Connection openIotAuthenticated(
        String cloudId, String token, String connectionName, String realm, String api) {
        try {
            return openIotAuthenticatedAsync(cloudId, token, connectionName, realm, api).get();
        } catch (ExecutionException e) {
            if (e.getCause() instanceof MotionLibException) {
                throw (MotionLibException) e.getCause();
            } else {
                throw new MotionLibException(e.getCause());
            }
        } catch (InterruptedException e) {
            throw new MotionLibException(e);
        }
    }

    /**
     * Opens a secured connection to a cloud connected device chain.
     * Use this method to connect to devices on your account.
     * @param cloudId The cloud ID to connect to.
     * @param token The token to authenticate with.
     * @param connectionName The name of the connection to open.
     * Can be left empty to default to the only connection present.
     * Otherwise, use serial port name for serial port connection or hostname:port for TCP connection.
     * @param realm The realm to connect to.
     * @return An object representing the connection.
     */
    public static Connection openIotAuthenticated(
        String cloudId, String token, String connectionName, String realm) {
        return openIotAuthenticated(cloudId, token, connectionName, realm, "https://api.zaber.io");
    }

    /**
     * Opens a secured connection to a cloud connected device chain.
     * Use this method to connect to devices on your account.
     * @param cloudId The cloud ID to connect to.
     * @param token The token to authenticate with.
     * @param connectionName The name of the connection to open.
     * Can be left empty to default to the only connection present.
     * Otherwise, use serial port name for serial port connection or hostname:port for TCP connection.
     * @return An object representing the connection.
     */
    public static Connection openIotAuthenticated(
        String cloudId, String token, String connectionName) {
        return openIotAuthenticated(cloudId, token, connectionName, "", "https://api.zaber.io");
    }

    /**
     * Opens a secured connection to a cloud connected device chain.
     * Use this method to connect to devices on your account.
     * @param cloudId The cloud ID to connect to.
     * @param token The token to authenticate with.
     * @return An object representing the connection.
     */
    public static Connection openIotAuthenticated(
        String cloudId, String token) {
        return openIotAuthenticated(cloudId, token, "", "", "https://api.zaber.io");
    }

    /**
     * Opens a connection to Zaber Launcher in your Local Area Network.
     * The connection is not secured.
     * @param hostName Hostname or IP address.
     * @param port Port number.
     * @param connectionName The name of the connection to open.
     * Can be left empty to default to the only connection present.
     * Otherwise, use serial port name for serial port connection or hostname:port for TCP connection.
     * @return A CompletableFuture that can be completed to get the result:
     * An object representing the connection.
     */
    public static CompletableFuture openNetworkShareAsync(
        String hostName, int port, String connectionName) {
        Main.OpenInterfaceRequest.Builder builder = Main.OpenInterfaceRequest.newBuilder();
        builder = builder.setInterfaceType(Main.InterfaceType.NETWORK_SHARE);

        builder = builder.setHostName(hostName);
        builder = builder.setPort(port);
        builder = builder.setConnectionName(connectionName);
        CompletableFuture response = Call.callAsync(
            "interface/open",
            builder.build(),
            Main.OpenInterfaceResponse.parser());
        return response
            .thenApply(r -> new Connection(r.getInterfaceId()));
    }

    /**
     * Opens a connection to Zaber Launcher in your Local Area Network.
     * The connection is not secured.
     * @param hostName Hostname or IP address.
     * @param port Port number.
     * @return A CompletableFuture that can be completed to get the result:
     * An object representing the connection.
     */
    public static CompletableFuture openNetworkShareAsync(
        String hostName, int port) {
        return openNetworkShareAsync(hostName, port, "");
    }

    /**
     * Opens a connection to Zaber Launcher in your Local Area Network.
     * The connection is not secured.
     * @param hostName Hostname or IP address.
     * @param port Port number.
     * @param connectionName The name of the connection to open.
     * Can be left empty to default to the only connection present.
     * Otherwise, use serial port name for serial port connection or hostname:port for TCP connection.
     * @return An object representing the connection.
     */
    public static Connection openNetworkShare(
        String hostName, int port, String connectionName) {
        try {
            return openNetworkShareAsync(hostName, port, connectionName).get();
        } catch (ExecutionException e) {
            if (e.getCause() instanceof MotionLibException) {
                throw (MotionLibException) e.getCause();
            } else {
                throw new MotionLibException(e.getCause());
            }
        } catch (InterruptedException e) {
            throw new MotionLibException(e);
        }
    }

    /**
     * Opens a connection to Zaber Launcher in your Local Area Network.
     * The connection is not secured.
     * @param hostName Hostname or IP address.
     * @param port Port number.
     * @return An object representing the connection.
     */
    public static Connection openNetworkShare(
        String hostName, int port) {
        return openNetworkShare(hostName, port, "");
    }

    /**
     * Sends a generic ASCII command to this connection.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @param device Optional device address to send the command to.
     * @param axis Optional axis number to send the command to.
     * @param checkErrors Controls whether to throw an exception when the device rejects the command.
     * @param timeout The timeout, in milliseconds, for a device to respond to the command.
     * Overrides the connection default request timeout.
     * @return A CompletableFuture that can be completed to get the result:
     * A response to the command.
     */
    public CompletableFuture genericCommandAsync(
        String command, int device, int axis, boolean checkErrors, int timeout) {
        Main.GenericCommandRequest.Builder builder = Main.GenericCommandRequest.newBuilder();
        builder = builder.setInterfaceId(getInterfaceId());

        builder = builder.setCommand(command);
        builder = builder.setDevice(device);
        builder = builder.setAxis(axis);
        builder = builder.setCheckErrors(checkErrors);
        builder = builder.setTimeout(timeout);
        CompletableFuture response = Call.callAsync(
            "interface/generic_command",
            builder.build(),
            Main.GenericCommandResponse.parser());
        return response
            .thenApply(r -> Response.fromProtobuf(r));
    }

    /**
     * Sends a generic ASCII command to this connection.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @param device Optional device address to send the command to.
     * @param axis Optional axis number to send the command to.
     * @param checkErrors Controls whether to throw an exception when the device rejects the command.
     * @return A CompletableFuture that can be completed to get the result:
     * A response to the command.
     */
    public CompletableFuture genericCommandAsync(
        String command, int device, int axis, boolean checkErrors) {
        return genericCommandAsync(command, device, axis, checkErrors, 0);
    }

    /**
     * Sends a generic ASCII command to this connection.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @param device Optional device address to send the command to.
     * @param axis Optional axis number to send the command to.
     * @return A CompletableFuture that can be completed to get the result:
     * A response to the command.
     */
    public CompletableFuture genericCommandAsync(
        String command, int device, int axis) {
        return genericCommandAsync(command, device, axis, true, 0);
    }

    /**
     * Sends a generic ASCII command to this connection.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @param device Optional device address to send the command to.
     * @return A CompletableFuture that can be completed to get the result:
     * A response to the command.
     */
    public CompletableFuture genericCommandAsync(
        String command, int device) {
        return genericCommandAsync(command, device, 0, true, 0);
    }

    /**
     * Sends a generic ASCII command to this connection.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @return A CompletableFuture that can be completed to get the result:
     * A response to the command.
     */
    public CompletableFuture genericCommandAsync(
        String command) {
        return genericCommandAsync(command, 0, 0, true, 0);
    }

    /**
     * Sends a generic ASCII command to this connection.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @param device Optional device address to send the command to.
     * @param axis Optional axis number to send the command to.
     * @param checkErrors Controls whether to throw an exception when the device rejects the command.
     * @param timeout The timeout, in milliseconds, for a device to respond to the command.
     * Overrides the connection default request timeout.
     * @return A response to the command.
     */
    public Response genericCommand(
        String command, int device, int axis, boolean checkErrors, int timeout) {
        try {
            return genericCommandAsync(command, device, axis, checkErrors, timeout).get();
        } catch (ExecutionException e) {
            if (e.getCause() instanceof MotionLibException) {
                throw (MotionLibException) e.getCause();
            } else {
                throw new MotionLibException(e.getCause());
            }
        } catch (InterruptedException e) {
            throw new MotionLibException(e);
        }
    }

    /**
     * Sends a generic ASCII command to this connection.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @param device Optional device address to send the command to.
     * @param axis Optional axis number to send the command to.
     * @param checkErrors Controls whether to throw an exception when the device rejects the command.
     * @return A response to the command.
     */
    public Response genericCommand(
        String command, int device, int axis, boolean checkErrors) {
        return genericCommand(command, device, axis, checkErrors, 0);
    }

    /**
     * Sends a generic ASCII command to this connection.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @param device Optional device address to send the command to.
     * @param axis Optional axis number to send the command to.
     * @return A response to the command.
     */
    public Response genericCommand(
        String command, int device, int axis) {
        return genericCommand(command, device, axis, true, 0);
    }

    /**
     * Sends a generic ASCII command to this connection.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @param device Optional device address to send the command to.
     * @return A response to the command.
     */
    public Response genericCommand(
        String command, int device) {
        return genericCommand(command, device, 0, true, 0);
    }

    /**
     * Sends a generic ASCII command to this connection.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @return A response to the command.
     */
    public Response genericCommand(
        String command) {
        return genericCommand(command, 0, 0, true, 0);
    }

    /**
     * Sends a generic ASCII command to this connection without expecting a response and without adding a message ID.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @param device Optional device address to send the command to.
     * @param axis Optional axis number to send the command to.
     * @return A CompletableFuture that can be completed to know when the work is complete.
     */
    public CompletableFuture genericCommandNoResponseAsync(
        String command, int device, int axis) {
        Main.GenericCommandRequest.Builder builder = Main.GenericCommandRequest.newBuilder();
        builder = builder.setInterfaceId(getInterfaceId());

        builder = builder.setCommand(command);
        builder = builder.setDevice(device);
        builder = builder.setAxis(axis);
        return Call.callAsync("interface/generic_command_no_response", builder.build(), null)
            .thenApply(r -> (Void) null);
    }

    /**
     * Sends a generic ASCII command to this connection without expecting a response and without adding a message ID.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @param device Optional device address to send the command to.
     * @return A CompletableFuture that can be completed to know when the work is complete.
     */
    public CompletableFuture genericCommandNoResponseAsync(
        String command, int device) {
        return genericCommandNoResponseAsync(command, device, 0);
    }

    /**
     * Sends a generic ASCII command to this connection without expecting a response and without adding a message ID.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @return A CompletableFuture that can be completed to know when the work is complete.
     */
    public CompletableFuture genericCommandNoResponseAsync(
        String command) {
        return genericCommandNoResponseAsync(command, 0, 0);
    }

    /**
     * Sends a generic ASCII command to this connection without expecting a response and without adding a message ID.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @param device Optional device address to send the command to.
     * @param axis Optional axis number to send the command to.
     */
    public void genericCommandNoResponse(
        String command, int device, int axis) {
        try {
            genericCommandNoResponseAsync(command, device, axis).get();
        } catch (ExecutionException e) {
            if (e.getCause() instanceof MotionLibException) {
                throw (MotionLibException) e.getCause();
            } else {
                throw new MotionLibException(e.getCause());
            }
        } catch (InterruptedException e) {
            throw new MotionLibException(e);
        }
    }

    /**
     * Sends a generic ASCII command to this connection without expecting a response and without adding a message ID.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @param device Optional device address to send the command to.
     */
    public void genericCommandNoResponse(
        String command, int device) {
        genericCommandNoResponse(command, device, 0);
    }

    /**
     * Sends a generic ASCII command to this connection without expecting a response and without adding a message ID.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     */
    public void genericCommandNoResponse(
        String command) {
        genericCommandNoResponse(command, 0, 0);
    }

    /**
     * Sends a generic ASCII command to this connection and expect multiple responses,
     * either from one device or from many devices.
     * Responses are returned in order of arrival.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @param device Optional device address to send the command to.
     * @param axis Optional axis number to send the command to.
     * @param checkErrors Controls whether to throw an exception when a device rejects the command.
     * @param timeout The timeout, in milliseconds, for a device to respond to the command.
     * Overrides the connection default request timeout.
     * @return A CompletableFuture that can be completed to get the result:
     * All responses to the command.
     */
    public CompletableFuture genericCommandMultiResponseAsync(
        String command, int device, int axis, boolean checkErrors, int timeout) {
        Main.GenericCommandRequest.Builder builder = Main.GenericCommandRequest.newBuilder();
        builder = builder.setInterfaceId(getInterfaceId());

        builder = builder.setCommand(command);
        builder = builder.setDevice(device);
        builder = builder.setAxis(axis);
        builder = builder.setCheckErrors(checkErrors);
        builder = builder.setTimeout(timeout);
        CompletableFuture response = Call.callAsync(
            "interface/generic_command_multi_response",
            builder.build(),
            Main.GenericCommandResponseCollection.parser());
        return response
            .thenApply(r -> r.getResponsesList().stream()
            .map(resp -> Response.fromProtobuf(resp)).toArray(Response[]::new));
    }

    /**
     * Sends a generic ASCII command to this connection and expect multiple responses,
     * either from one device or from many devices.
     * Responses are returned in order of arrival.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @param device Optional device address to send the command to.
     * @param axis Optional axis number to send the command to.
     * @param checkErrors Controls whether to throw an exception when a device rejects the command.
     * @return A CompletableFuture that can be completed to get the result:
     * All responses to the command.
     */
    public CompletableFuture genericCommandMultiResponseAsync(
        String command, int device, int axis, boolean checkErrors) {
        return genericCommandMultiResponseAsync(command, device, axis, checkErrors, 0);
    }

    /**
     * Sends a generic ASCII command to this connection and expect multiple responses,
     * either from one device or from many devices.
     * Responses are returned in order of arrival.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @param device Optional device address to send the command to.
     * @param axis Optional axis number to send the command to.
     * @return A CompletableFuture that can be completed to get the result:
     * All responses to the command.
     */
    public CompletableFuture genericCommandMultiResponseAsync(
        String command, int device, int axis) {
        return genericCommandMultiResponseAsync(command, device, axis, true, 0);
    }

    /**
     * Sends a generic ASCII command to this connection and expect multiple responses,
     * either from one device or from many devices.
     * Responses are returned in order of arrival.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @param device Optional device address to send the command to.
     * @return A CompletableFuture that can be completed to get the result:
     * All responses to the command.
     */
    public CompletableFuture genericCommandMultiResponseAsync(
        String command, int device) {
        return genericCommandMultiResponseAsync(command, device, 0, true, 0);
    }

    /**
     * Sends a generic ASCII command to this connection and expect multiple responses,
     * either from one device or from many devices.
     * Responses are returned in order of arrival.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @return A CompletableFuture that can be completed to get the result:
     * All responses to the command.
     */
    public CompletableFuture genericCommandMultiResponseAsync(
        String command) {
        return genericCommandMultiResponseAsync(command, 0, 0, true, 0);
    }

    /**
     * Sends a generic ASCII command to this connection and expect multiple responses,
     * either from one device or from many devices.
     * Responses are returned in order of arrival.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @param device Optional device address to send the command to.
     * @param axis Optional axis number to send the command to.
     * @param checkErrors Controls whether to throw an exception when a device rejects the command.
     * @param timeout The timeout, in milliseconds, for a device to respond to the command.
     * Overrides the connection default request timeout.
     * @return All responses to the command.
     */
    public Response[] genericCommandMultiResponse(
        String command, int device, int axis, boolean checkErrors, int timeout) {
        try {
            return genericCommandMultiResponseAsync(command, device, axis, checkErrors, timeout).get();
        } catch (ExecutionException e) {
            if (e.getCause() instanceof MotionLibException) {
                throw (MotionLibException) e.getCause();
            } else {
                throw new MotionLibException(e.getCause());
            }
        } catch (InterruptedException e) {
            throw new MotionLibException(e);
        }
    }

    /**
     * Sends a generic ASCII command to this connection and expect multiple responses,
     * either from one device or from many devices.
     * Responses are returned in order of arrival.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @param device Optional device address to send the command to.
     * @param axis Optional axis number to send the command to.
     * @param checkErrors Controls whether to throw an exception when a device rejects the command.
     * @return All responses to the command.
     */
    public Response[] genericCommandMultiResponse(
        String command, int device, int axis, boolean checkErrors) {
        return genericCommandMultiResponse(command, device, axis, checkErrors, 0);
    }

    /**
     * Sends a generic ASCII command to this connection and expect multiple responses,
     * either from one device or from many devices.
     * Responses are returned in order of arrival.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @param device Optional device address to send the command to.
     * @param axis Optional axis number to send the command to.
     * @return All responses to the command.
     */
    public Response[] genericCommandMultiResponse(
        String command, int device, int axis) {
        return genericCommandMultiResponse(command, device, axis, true, 0);
    }

    /**
     * Sends a generic ASCII command to this connection and expect multiple responses,
     * either from one device or from many devices.
     * Responses are returned in order of arrival.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @param device Optional device address to send the command to.
     * @return All responses to the command.
     */
    public Response[] genericCommandMultiResponse(
        String command, int device) {
        return genericCommandMultiResponse(command, device, 0, true, 0);
    }

    /**
     * Sends a generic ASCII command to this connection and expect multiple responses,
     * either from one device or from many devices.
     * Responses are returned in order of arrival.
     * For more information refer to the [ASCII Protocol Manual](https://www.zaber.com/protocol-manual#topic_commands).
     * @param command Command and its parameters.
     * @return All responses to the command.
     */
    public Response[] genericCommandMultiResponse(
        String command) {
        return genericCommandMultiResponse(command, 0, 0, true, 0);
    }

    /**
     * Resets ASCII protocol message IDs. Only for testing purposes.
     */
    public void resetIds() {
        Main.EmptyInterfaceRequest.Builder builder = Main.EmptyInterfaceRequest.newBuilder();
        builder = builder.setInterfaceId(getInterfaceId());

        Call.callSync("interface/reset_ids", builder.build(), null);
    }


    /**
     * Close the connection.
     * @return A CompletableFuture that can be completed to know when the work is complete.
     */
    public CompletableFuture closeAsync() {
        Main.CloseInterfaceRequest.Builder builder = Main.CloseInterfaceRequest.newBuilder();
        builder = builder.setInterfaceId(getInterfaceId());

        return Call.callAsync("interface/close", builder.build(), null)
            .thenApply(r -> (Void) null);
    }

    /**
     * Close the connection.
     */
    public void close() {
        try {
            closeAsync().get();
        } catch (ExecutionException e) {
            if (e.getCause() instanceof MotionLibException) {
                throw (MotionLibException) e.getCause();
            } else {
                throw new MotionLibException(e.getCause());
            }
        } catch (InterruptedException e) {
            throw new MotionLibException(e);
        }
    }

    /**
     * Gets a Device class instance which allows you to control a particular device on this connection.
     * Devices are numbered from 1.
     * @param deviceAddress Address of device intended to control. Address is configured for each device.
     * @return Device instance.
     */
    public Device getDevice(
        int deviceAddress) {
        if (deviceAddress <= 0) {
            throw new IllegalArgumentException("Invalid value; physical devices are numbered from 1.");
        }
        return new Device(this, deviceAddress);
    }


    /**
     * Renumbers devices present on this connection. After renumbering, devices need to be identified again.
     * @param firstAddress This is the address that the device closest to the computer is given.
     * Remaining devices are numbered consecutively.
     * @return A CompletableFuture that can be completed to get the result:
     * Total number of devices that responded to the renumber.
     */
    public CompletableFuture renumberDevicesAsync(
        int firstAddress) {
        if (firstAddress <= 0) {
            throw new IllegalArgumentException("Invalid value; device addresses are numbered from 1.");
        }
        Main.DeviceRenumberRequest.Builder builder = Main.DeviceRenumberRequest.newBuilder();
        builder = builder.setInterfaceId(getInterfaceId());

        builder = builder.setFirstAddress(firstAddress);
        CompletableFuture response = Call.callAsync(
            "device/renumber",
            builder.build(),
            Main.DeviceRenumberResponse.parser());
        return response
            .thenApply(r -> r.getNumberDevices());
    }

    /**
     * Renumbers devices present on this connection. After renumbering, devices need to be identified again.
     * @return A CompletableFuture that can be completed to get the result:
     * Total number of devices that responded to the renumber.
     */
    public CompletableFuture renumberDevicesAsync() {
        return renumberDevicesAsync(1);
    }

    /**
     * Renumbers devices present on this connection. After renumbering, devices need to be identified again.
     * @param firstAddress This is the address that the device closest to the computer is given.
     * Remaining devices are numbered consecutively.
     * @return Total number of devices that responded to the renumber.
     */
    public int renumberDevices(
        int firstAddress) {
        try {
            return renumberDevicesAsync(firstAddress).get();
        } catch (ExecutionException e) {
            if (e.getCause() instanceof MotionLibException) {
                throw (MotionLibException) e.getCause();
            } else {
                throw new MotionLibException(e.getCause());
            }
        } catch (InterruptedException e) {
            throw new MotionLibException(e);
        }
    }

    /**
     * Renumbers devices present on this connection. After renumbering, devices need to be identified again.
     * @return Total number of devices that responded to the renumber.
     */
    public int renumberDevices() {
        return renumberDevices(1);
    }

    /**
     * Attempts to detect any devices present on this connection.
     * @param identifyDevices Determines whether device identification should be performed as well.
     * @return A CompletableFuture that can be completed to get the result:
     * Array of detected devices.
     */
    public CompletableFuture detectDevicesAsync(
        boolean identifyDevices) {
        Main.DeviceDetectRequest.Builder builder = Main.DeviceDetectRequest.newBuilder();
        builder = builder.setInterfaceId(getInterfaceId());

        builder = builder.setIdentifyDevices(identifyDevices);
        CompletableFuture response = Call.callAsync(
            "device/detect",
            builder.build(),
            Main.DeviceDetectResponse.parser());
        return response
            .thenApply(r -> r.getDevicesList().stream()
            .map(deviceAddress -> this.getDevice(deviceAddress)).toArray(Device[]::new));
    }

    /**
     * Attempts to detect any devices present on this connection.
     * @return A CompletableFuture that can be completed to get the result:
     * Array of detected devices.
     */
    public CompletableFuture detectDevicesAsync() {
        return detectDevicesAsync(true);
    }

    /**
     * Attempts to detect any devices present on this connection.
     * @param identifyDevices Determines whether device identification should be performed as well.
     * @return Array of detected devices.
     */
    public Device[] detectDevices(
        boolean identifyDevices) {
        try {
            return detectDevicesAsync(identifyDevices).get();
        } catch (ExecutionException e) {
            if (e.getCause() instanceof MotionLibException) {
                throw (MotionLibException) e.getCause();
            } else {
                throw new MotionLibException(e.getCause());
            }
        } catch (InterruptedException e) {
            throw new MotionLibException(e);
        }
    }

    /**
     * Attempts to detect any devices present on this connection.
     * @return Array of detected devices.
     */
    public Device[] detectDevices() {
        return detectDevices(true);
    }

    /**
     * Stops all of the devices on this connection.
     * @param waitUntilIdle Determines whether the function should return immediately
     * or wait until the devices are stopped.
     * @return A CompletableFuture that can be completed to get the result:
     * The addresses of the devices that were stopped by this command.
     */
    public CompletableFuture stopAllAsync(
        boolean waitUntilIdle) {
        Main.DeviceOnAllRequest.Builder builder = Main.DeviceOnAllRequest.newBuilder();
        builder = builder.setInterfaceId(getInterfaceId());

        builder = builder.setWaitUntilIdle(waitUntilIdle);
        CompletableFuture response = Call.callAsync(
            "device/stop_all",
            builder.build(),
            Main.DeviceOnAllResponse.parser());
        return response
            .thenApply(r -> ArrayUtility.toPrimitiveArray(r.getDeviceAddressesList().stream().toArray(Integer[]::new)));
    }

    /**
     * Stops all of the devices on this connection.
     * @return A CompletableFuture that can be completed to get the result:
     * The addresses of the devices that were stopped by this command.
     */
    public CompletableFuture stopAllAsync() {
        return stopAllAsync(true);
    }

    /**
     * Stops all of the devices on this connection.
     * @param waitUntilIdle Determines whether the function should return immediately
     * or wait until the devices are stopped.
     * @return The addresses of the devices that were stopped by this command.
     */
    public int[] stopAll(
        boolean waitUntilIdle) {
        try {
            return stopAllAsync(waitUntilIdle).get();
        } catch (ExecutionException e) {
            if (e.getCause() instanceof MotionLibException) {
                throw (MotionLibException) e.getCause();
            } else {
                throw new MotionLibException(e.getCause());
            }
        } catch (InterruptedException e) {
            throw new MotionLibException(e);
        }
    }

    /**
     * Stops all of the devices on this connection.
     * @return The addresses of the devices that were stopped by this command.
     */
    public int[] stopAll() {
        return stopAll(true);
    }

    /**
     * Homes all of the devices on this connection.
     * @param waitUntilIdle Determines whether the function should return immediately
     * or wait until the devices are homed.
     * @return A CompletableFuture that can be completed to get the result:
     * The addresses of the devices that were homed by this command.
     */
    public CompletableFuture homeAllAsync(
        boolean waitUntilIdle) {
        Main.DeviceOnAllRequest.Builder builder = Main.DeviceOnAllRequest.newBuilder();
        builder = builder.setInterfaceId(getInterfaceId());

        builder = builder.setWaitUntilIdle(waitUntilIdle);
        CompletableFuture response = Call.callAsync(
            "device/home_all",
            builder.build(),
            Main.DeviceOnAllResponse.parser());
        return response
            .thenApply(r -> ArrayUtility.toPrimitiveArray(r.getDeviceAddressesList().stream().toArray(Integer[]::new)));
    }

    /**
     * Homes all of the devices on this connection.
     * @return A CompletableFuture that can be completed to get the result:
     * The addresses of the devices that were homed by this command.
     */
    public CompletableFuture homeAllAsync() {
        return homeAllAsync(true);
    }

    /**
     * Homes all of the devices on this connection.
     * @param waitUntilIdle Determines whether the function should return immediately
     * or wait until the devices are homed.
     * @return The addresses of the devices that were homed by this command.
     */
    public int[] homeAll(
        boolean waitUntilIdle) {
        try {
            return homeAllAsync(waitUntilIdle).get();
        } catch (ExecutionException e) {
            if (e.getCause() instanceof MotionLibException) {
                throw (MotionLibException) e.getCause();
            } else {
                throw new MotionLibException(e.getCause());
            }
        } catch (InterruptedException e) {
            throw new MotionLibException(e);
        }
    }

    /**
     * Homes all of the devices on this connection.
     * @return The addresses of the devices that were homed by this command.
     */
    public int[] homeAll() {
        return homeAll(true);
    }

    /**
     * Returns a string that represents the connection.
     * @return A string that represents the connection.
     */
    public String toString() {
        Main.ToStringRequest.Builder builder = Main.ToStringRequest.newBuilder();
        builder = builder.setInterfaceId(getInterfaceId());

        Main.ToStringResponse response = Call.callSync(
            "interface/to_string",
            builder.build(),
            Main.ToStringResponse.parser());
        return response.getToStr();
    }


    /**
     * Returns default request timeout.
     * @return Default request timeout.
     */
    private int retrieveTimeout() {
        Main.EmptyInterfaceRequest.Builder builder = Main.EmptyInterfaceRequest.newBuilder();
        builder = builder.setInterfaceId(getInterfaceId());

        Main.GetInterfaceTimeoutResponse response = Call.callSync(
            "interface/get_timeout",
            builder.build(),
            Main.GetInterfaceTimeoutResponse.parser());
        return response.getValue();
    }


    /**
     * Sets default request timeout.
     * @param timeout Default request timeout.
     */
    private void changeTimeout(
        int timeout) {
        Main.SetInterfaceTimeoutRequest.Builder builder = Main.SetInterfaceTimeoutRequest.newBuilder();
        builder = builder.setInterfaceId(getInterfaceId());

        builder = builder.setTimeout(timeout);
        Call.callSync("interface/set_timeout", builder.build(), null);
    }


    /**
     * Returns checksum enabled.
     * @return Checksum enabled.
     */
    private boolean retrieveChecksumEnabled() {
        Main.EmptyInterfaceRequest.Builder builder = Main.EmptyInterfaceRequest.newBuilder();
        builder = builder.setInterfaceId(getInterfaceId());

        Main.GetInterfaceChecksumEnabledResponse response = Call.callSync(
            "interface/get_checksum_enabled",
            builder.build(),
            Main.GetInterfaceChecksumEnabledResponse.parser());
        return response.getValue();
    }


    /**
     * Sets checksum enabled.
     * @param isEnabled Checksum enabled.
     */
    private void changeChecksumEnabled(
        boolean isEnabled) {
        Main.SetInterfaceChecksumEnabledRequest.Builder builder = Main.SetInterfaceChecksumEnabledRequest.newBuilder();
        builder = builder.setInterfaceId(getInterfaceId());

        builder = builder.setIsEnabled(isEnabled);
        Call.callSync("interface/set_checksum_enabled", builder.build(), null);
    }


    private void subscribe() {
        this.unknownResponse = Events.getEventObservable()
            .takeUntil(this.disconnected)
            .filter(event -> event.getEventName().equals("interface/unknown_response"))
            .map(event -> (Main.UnknownResponseEvent) event.getEventData())
            .filter(event -> (event.getInterfaceId() == this.interfaceId))
            .map(event -> UnknownResponseEvent.fromProtobuf(event));

        this.alert = Events.getEventObservable()
            .takeUntil(this.disconnected)
            .filter(event -> event.getEventName().equals("interface/alert"))
            .map(event -> (Main.AlertEvent) event.getEventData())
            .filter(event -> (event.getInterfaceId() == this.interfaceId))
            .map(event -> AlertEvent.fromProtobuf(event));

        Events.getEventObservable()
            .filter(event -> event.getEventName().equals("interface/disconnected"))
            .map(event -> (Main.DisconnectedEvent) event.getEventData())
            .filter(event -> (event.getInterfaceId() == this.interfaceId))
            .take(1)
            .map(event -> ExceptionConverter.convert(event.getErrorType(), event.getErrorMessage()))
            .subscribe(this.disconnected);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy