import { Observable } from 'rxjs';
import { MonitoringConfig } from './monitoring-config';
import { MotionMasterPubSubClient } from './motion-master-pub-sub-client';
import { MotionMasterPubSubSocket } from './motion-master-pub-sub-socket';
import { MotionMasterReqResClient } from './motion-master-req-res-client';
import { MotionMasterReqResSocket } from './motion-master-req-res-socket';
import { DeviceParameterIds, DeviceRef, MotionMasterConnectionConfig, ParameterValueType, PositionProfileConfig, TorqueProfileConfig, VelocityProfileConfig } from './types';
import { DeviceParameter } from './device-parameter';
import { Cia402State } from './cia402';
import { DataMonitoring } from './data-monitoring';
import { HomingProcedureConfig, HomingProcedureStatus } from './homing';
/**
 * Creates an instance of the {@link MotionMasterClient} using the specified hostname or connection configuration object.
 * Both the hostname and configuration properties are optional. Default values for each option can be found in {@link MotionMasterConnectionConfig}.
 * After the instance is created, the function opens the WebSocket connections, allowing the returned client object to send requests immediately.
 */
export declare function createMotionMasterClient(config?: Partial<MotionMasterConnectionConfig>): MotionMasterClient;
export declare function createMotionMasterClient(hostname?: string, pingSystemInterval?: number, systemAliveTimeout?: number): MotionMasterClient;
export declare class MotionMasterClient {
    readonly reqResSocket: MotionMasterReqResSocket;
    readonly pubSubSocket: MotionMasterPubSubSocket;
    readonly request: MotionMasterReqResClient;
    readonly monitor: MotionMasterPubSubClient;
    private systemEventSubscription?;
    constructor(reqResSocket: MotionMasterReqResSocket, pubSubSocket: MotionMasterPubSubSocket);
    /**
     * Emits true when both req/res and pub/sub sockets are opened.
     * Emits false if any socket closes.
     * This is a hot observable and always replays the latest opened state on subscription.
     */
    readonly socketsOpened$: Observable<boolean>;
    /**
     * Emits `true` **only when the client transitions into the ready state**,
     * meaning both sockets have become opened.
     *
     * `distinctUntilChanged()` guarantees that repeated `true` values are suppressed.
     * However, new subscribers will still immediately receive the last replayed `true`
     * if the client is already ready.
     */
    readonly ready$: Observable<boolean>;
    /**
     * Emits a single time when the client becomes ready for the first time.
     *
     * - Emits immediately if both sockets are already open.
     * - Completes after emitting once.
     * - If the client never becomes ready, this observable never emits.
     */
    readonly onceReady$: Observable<boolean>;
    /**
     * Returns an Observable that emits once when both req/res and pub/sub sockets are opened, then completes.
     *
     * - Emits immediately if both sockets are already open.
     * - Completes after emitting once.
     * - Errors with a TimeoutError if the specified timeout is reached before both sockets are open.
     *
     * @param requestTimeout The maximum time (in milliseconds) to wait for both sockets to open. Default is 5000 ms.
     * @returns Observable<void> that emits once when ready and then completes.
     */
    onceReady(requestTimeout?: number): Observable<void>;
    /**
     * Waits until both req/res and pub/sub sockets are opened.
     *
     * - Resolves immediately if both sockets are already open.
     * - Otherwise, waits up to `requestTimeout` milliseconds for both sockets to open.
     * - Throws a TimeoutError if the timeout is reached before both sockets are open.
     * - Returns a Promise that resolves when the client is ready.
     *
     * @param requestTimeout Maximum time in milliseconds to wait for both sockets to open. Default is 5000 ms.
     * @returns Promise<void> that resolves when both sockets are open or rejects on timeout.
     */
    whenReady(requestTimeout?: number): Promise<void>;
    /**
     * Creates and returns and instance of {@link DataMonitoring} class.
     */
    createDataMonitoring(ids: DeviceParameterIds, monitoringInterval: number, config?: MonitoringConfig): DataMonitoring;
    /**
     * Start monitoring.
     *
     * Note that the returned observable will never complete on its own.
     *
     * If you unsubscribe from it, the teardown code will send a request to the master to stop the monitoring.
     * That means you will end up with an observable that is not complete, but it won't emit any values.
     * This is fine when you want to use the monitoring observable directly in the template with async pipe,
     * which will unsubscribe automatically and stop the monitoring when you leave the component.
     *
     * If you need to complete the observable so that, for example, the toArray() operator works as expected, then use the {@link DataMonitoring} class,
     * which has a stop method. It can optionally buffer data for exporting as CSV or performing statistics on it.
     *
     * @param ids Device parameter IDs to monitor.
     * @param monitoringInterval At what interval should the master application send values.
     * @param config Configure the topic, buffer size, distinct.
     * @param requestTimeout How long will the client wait for the master to confirm that monitoring has started.
     * @returns An observable of an array of parameter values.
     */
    startMonitoring(ids: DeviceParameterIds, monitoringInterval: number, config?: MonitoringConfig, requestTimeout?: number): Observable<ParameterValueType[]>;
    /**
     * TODO: return device parameters instead of just parameters
     * get parameters from ESI uprfront, and then when parameters are received
     * from motion master just concatenate (spread operator) props from ESI and props from parameter
     * assign device parameter id like 0x1018:00.12345
     * when assembling device parameter, get parameter from device in ESI based on product code, see ESI service
     * this should probably done for other get parameters functions, get ESI file from device or prepared, get data from it
     */
    startMonitoringDeviceParameters(ids: DeviceParameterIds, monitoringInterval: number, config?: MonitoringConfig, requestTimeout?: number): Observable<DeviceParameter[]>;
    startMonitoringValue<T extends ParameterValueType = number>(id: string | [DeviceRef, number, number], monitoringInterval: number, config?: MonitoringConfig, requestTimeout?: number): Observable<T>;
    trackControlword(deviceRef: DeviceRef, monitoringInterval?: number): Observable<number>;
    trackStatusword(deviceRef: DeviceRef, monitoringInterval?: number): Observable<number>;
    trackOperationEnabled(deviceRef: DeviceRef, monitoringInterval?: number): Observable<boolean>;
    trackHomingProcedureStatus(deviceRef: DeviceRef, monitoringInterval?: number): Observable<HomingProcedureStatus>;
    trackTargetReached(deviceRef: DeviceRef, monitoringInterval?: number): Observable<boolean>;
    waitUntilTargetReached(deviceRef: DeviceRef, monitoringInterval?: number, requestTimeout?: number): Observable<true>;
    whenTargetReached(deviceRef: DeviceRef, monitoringInterval?: number, requestTimeout?: number): Promise<true>;
    waitUntilCia402StateReached(deviceRef: DeviceRef, state: Cia402State, monitoringInterval?: number, requestTimeout?: number): Observable<void>;
    whenCia402StateReached(deviceRef: DeviceRef, state: Cia402State, monitoringInterval?: number, requestTimeout?: number): Promise<void>;
    waitUntilParameterValueEquals(id: string | [DeviceRef, number, number], value: number, window?: number, monitoringInterval?: number, requestTimeout?: number): Observable<true>;
    whenParameterValueEquals(id: string | [DeviceRef, number, number], value: number, window?: number, monitoringInterval?: number, requestTimeout?: number): Promise<true>;
    /**
     * Executes a torque profile on the specified device.
     *
     * Downloads target torque and slope first, then sets Torque Profile Mode and transitions to
     * Operation Enabled. The brake is released automatically by the drive in PT mode. What happens
     * next depends on the combination of skipQuickStop and targetReachTimeout:
     *
     * - skipQuickStop: false (default) + targetReachTimeout set:
     *   Waits for the target reached bit (0x6041) within the given timeout, waits for holdingDuration
     *   if set, then issues a quick stop. The state waited for after the quick stop depends on the
     *   quick stop option code (0x605A): Quick Stop Active if the code is 6, Switch On Disabled otherwise.
     *   Throws if the target is not reached in time.
     *
     * - skipQuickStop: false (default) + no positive targetReachTimeout:
     *   Throws immediately — the function cannot determine when to issue the quick stop.
     *
     * - skipQuickStop: true + targetReachTimeout set:
     *   Waits for the target reached bit within the given timeout but does not issue a quick stop.
     *   The device remains in the Operation Enabled state.
     *
     * - skipQuickStop: true + no targetReachTimeout:
     *   Returns immediately after enabling the drive. The device remains in the Operation Enabled state.
     *
     * When skipQuickStop is true and an error is thrown (e.g. target not reached in time), the drive
     * remains in Operation Enabled. The caller is responsible for issuing a quick stop or transitioning
     * the drive to a safe state.
     *
     * @param deviceRef - Reference to the target device.
     * @param config - Torque profile configuration.
     * @throws Error if skipQuickStop is false and targetReachTimeout is not a positive number.
     * @throws Error if the target is not reached within targetReachTimeout.
     */
    runTorqueProfile(deviceRef: DeviceRef, config: TorqueProfileConfig): Promise<void>;
    /**
     * Executes a velocity profile on the specified device.
     *
     * Downloads target velocity, acceleration and deceleration first, then sets Profile Velocity Mode
     * and transitions to Operation Enabled. The brake is released automatically by the drive in PV mode.
     * What happens next depends on the combination of skipQuickStop and targetReachTimeout:
     *
     * - skipQuickStop: false (default) + targetReachTimeout set:
     *   Waits for the target reached bit (0x6041) within the given timeout, waits for holdingDuration
     *   if set, then issues a quick stop. The state waited for after the quick stop depends on the
     *   quick stop option code (0x605A): Quick Stop Active if the code is 6, Switch On Disabled otherwise.
     *   Throws if the target is not reached in time.
     *
     * - skipQuickStop: false (default) + no positive targetReachTimeout:
     *   Throws immediately — the function cannot determine when to issue the quick stop.
     *
     * - skipQuickStop: true + targetReachTimeout set:
     *   Waits for the target reached bit within the given timeout but does not issue a quick stop.
     *   The device remains in the Operation Enabled state.
     *
     * - skipQuickStop: true + no targetReachTimeout:
     *   Returns immediately after enabling the drive. The device remains in the Operation Enabled state.
     *
     * When skipQuickStop is true and an error is thrown (e.g. target not reached in time), the drive
     * remains in Operation Enabled. The caller is responsible for issuing a quick stop or transitioning
     * the drive to a safe state.
     *
     * @param deviceRef - Reference to the target device.
     * @param config - Velocity profile configuration.
     * @throws Error if skipQuickStop is false and targetReachTimeout is not a positive number.
     * @throws Error if the target is not reached within targetReachTimeout.
     */
    runVelocityProfile(deviceRef: DeviceRef, config: VelocityProfileConfig): Promise<void>;
    /**
     * Executes a position profile on the specified device.
     *
     * Downloads target position, velocity, acceleration and deceleration first, then sets Profile
     * Position Mode, transitions to Operation Enabled and applies the set point. The brake is released
     * automatically by the drive in PP mode. What happens next depends on the combination of
     * skipQuickStop and targetReachTimeout:
     *
     * - skipQuickStop: false (default) + targetReachTimeout set:
     *   Waits for the target reached bit (0x6041) within the given timeout, waits for holdingDuration
     *   if set, then issues a quick stop. The state waited for after the quick stop depends on the
     *   quick stop option code (0x605A): Quick Stop Active if the code is 6, Switch On Disabled otherwise.
     *   Throws if the target is not reached in time.
     *
     * - skipQuickStop: false (default) + no positive targetReachTimeout:
     *   Throws immediately — the function cannot determine when to issue the quick stop.
     *
     * - skipQuickStop: true + targetReachTimeout set:
     *   Waits for the target reached bit within the given timeout but does not issue a quick stop.
     *   The device remains in the Operation Enabled state.
     *
     * - skipQuickStop: true + no targetReachTimeout:
     *   Returns immediately after applying the set point. The device remains in the Operation Enabled state.
     *
     * When skipQuickStop is true and an error is thrown (e.g. target not reached in time), the drive
     * remains in Operation Enabled. The caller is responsible for issuing a quick stop or transitioning
     * the drive to a safe state.
     *
     * @param deviceRef - Reference to the target device.
     * @param config - Position profile configuration.
     * @throws Error if skipQuickStop is false and targetReachTimeout is not a positive number.
     * @throws Error if the target is not reached within targetReachTimeout.
     */
    runPositionProfile(deviceRef: DeviceRef, config: PositionProfileConfig): Promise<void>;
    /**
     * Executes the homing procedure to locate the home position value (0x2005:01).
     *
     * You can optionally provide a configuration object that specifies acceleration, method, and speeds;
     * if not provided, the parameter values already set on the device will be used.
     *
     * The function will first emit a "running" status, followed by either "succeeded" or "failed".
     * After completion, the device will remain in the Operation Enabled state.
     *
     * No CiA402 state transitions will occur for the "Homing on current position" methods (35 and 37).
     * Additionally, the halt bit will remain unchanged for these methods, in contrast to other methods where the halt bit is cleared.
     *
     * @param deviceRef - Reference to the device being homed.
     * @param config - Optional configuration for the homing procedure.
     * @param monitoringInterval - Interval for monitoring the homing procedure status in microseconds (default: 50,000 μs).
     * @param requestTimeout - Timeout for the homing request in milliseconds (default: 300,000 ms).
     * @returns An Observable that emits the status of the homing procedure.
     */
    runHomingProcedure(deviceRef: DeviceRef, config?: HomingProcedureConfig, monitoringInterval?: number, requestTimeout?: number): Observable<HomingProcedureStatus>;
    subscribeToSystemEvent(): void;
    stopMonitoring(messageId: string): void;
    stopMonitoringAll(): void;
    closeSockets(): void;
    reopenSockets(): void;
}
