import { DiscoveryOperation } from './discoveryOperation';
import { Logger, LogLevel } from './util/logging/index';
import { Opcode } from './protocol/comfoConnect';
import { OpcodeMessageType, requestMessages } from './opcodes';
import { ComfoControlMessage } from './comfoControlMessage';
import { DeviceProperty, PropertyNativeType } from './deviceProperties';
import { NodeProperty } from './rmiProperties';
export interface ComfoControlLogger {
    log(message: string, ...args: unknown[]): void;
}
interface LoggingOptions {
    /**
     * Logger instance to use for logging messages.
     */
    logger?: ComfoControlLogger;
    /**
     * Log level to use for logging messages.
     */
    logLevel?: LogLevel;
}
export interface DiscoverOptions extends LoggingOptions {
    broadcastAddresses?: string | string[];
    port?: number;
    timeout?: number;
    limit?: number;
    abortSignal?: AbortSignal;
}
export interface ComfoControlClientOptions extends LoggingOptions {
    /**
     * IP address of the device
     */
    address: string;
    /**
     * Port of the device, defaults to 56747 if not set
     */
    port?: number;
    /**
     * UUID of the device encodes as HEX string
     */
    uuid: string;
    /**
     * The name of the device that is connecting to the device.
     * If not specified, the hostname of the device will be used.
     */
    deviceName?: string;
    /**
     * 12 byte client ID that is unique to this device.
     */
    clientUuid?: string;
    /**
     * 4 character PIN code to authenticate with the device. Defaults to 0 when not specified.
     */
    pin?: number;
    /**
     * Timeout in milliseconds to wait for a response or confirmation from the device. Defaults to 15000ms.
     * If the device does not respond within this time, the request will be considered failed and the {@link send} method will reject the promise.
     */
    requestTimeout?: number;
}
export declare enum FanMode {
    Away = 0,
    Low = 1,
    Medium = 2,
    High = 3
}
export declare enum TemperatureProfile {
    Normal = 0,
    Cool = 1,
    Warm = 2
}
export declare enum OperationMode {
    Manual = 1,
    Auto = 0
}
export interface DevicePropertyListner<P extends DeviceProperty = DeviceProperty> {
    (update: {
        readonly propertyName: string;
        readonly value: PropertyNativeType<P>;
        readonly raw: Buffer;
    } & DeviceProperty): unknown;
}
type OpcodeResponse<T extends Opcode> = T extends keyof typeof requestMessages ? (typeof requestMessages)[T] extends Opcode.NO_OPERATION ? void : ComfoControlMessage<(typeof requestMessages)[T]> : void;
/**
 * Represents a client that manages a connection with a ComfoControl Gateway Device.
 *
 * Provides methods to discover devices, start and maintain sessions,
 * register property listeners, and interact with the device.
 *
 * @example
 * ```typescript
 * const client = new ComfoControlClient({
 *   address: '192.168.1.100',
 *   uuid: '1234567890abcdef1234567890abcdef',
 *   pin: 1234,
 * });
 *
 * await client.startSession();
 * console.log('Session started:', client.sessionActive);
 * ```
 * @remarks
 * - Make sure to handle errors for production use.
 * - Register property listeners to receive real-time updates.
 *
 * @public
 */
export declare class ComfoControlClient {
    private readonly options;
    private readonly logger;
    private transport;
    private pendingReplies;
    private sessionState;
    private nodes;
    private deviceName;
    private deviceProperties;
    /**
     * Defines handlers for specific opcodes that are received from the server without a preceding request.
     */
    private handlers;
    get sessionActive(): boolean;
    /**
     * Create a new device instance with the specified details.
     * Use the static discover method to find devices on the network if you do not have the details.
     */
    constructor(options: ComfoControlClientOptions, logger?: Logger);
    /**
     * Discover devices on the network using a {@link DiscoveryOperation}. The discovery process will run for the specified timeout or until the limit of devices is reached.
     * If no timeout is specified, the default timeout is 30 seconds. If no limit is specified, all discovered devices will be returned.
     * The operation can be aborted using an AbortSignal, see {@link https://nodejs.org/api/globals.html#class-abortsignal} for details on how to use the AbortSignal.
     * @param options - The options for the discovery process.
     * @returns A {@link DiscoveryOperation} instance that can be used to listen for discovered devices.
     */
    static discover(options?: DiscoverOptions): DiscoveryOperation;
    /**
     * Starts a session with the ComfoControl device. Normally you should not need to call this method directly,
     * as it is called automatically when sending a request that requires an active session.
     *
     * Registers the device/app and starts a session if not already active.
     * Re-registers all properties that were registered before the session was closed.
     *
     * - When you get a `Failed to start session: NOT_ALLOWED` error the client UUID is not accepted by the server,
     * to fix this use the default UUID by not setting the `clientUuid` option.
     * - When you get a `Failed to register: NOT_ALLOWED` the device PIN code is incorrect.
     *
     * @returns {Promise<void>} A promise that resolves when the session is successfully started.
     * @throws Will throw an error if the session is already active or in the process of starting, or if the registration or session start fails.
     */
    startSession(): Promise<void>;
    /**
     * Call this method to stop the session with the ComfoControl Gateway.
     */
    stopSession(): Promise<void>;
    /**
     * Sends a request to the ComfoControl device and waits for a response.
     * Ensures the transport is connected and the session is active before sending the request.
     *
     * @template T - The type of the request opcode.
     * @template R - The type of the response message.
     * @template TRequest - The type of the request data.
     * @param {T} opcode - The opcode of the request.
     * @param {TRequest} [data] - The data to send with the request.
     * @returns {Promise<ComfoControlMessage<R>>} A promise that resolves to the response message.
     * @throws Will throw an error if the transport is already connecting, the session is not active, or the response opcode is unexpected.
     */
    send<T extends keyof typeof requestMessages>(opcode: T, data?: OpcodeMessageType<T>): Promise<OpcodeResponse<T>>;
    private ensureConnected;
    private processMessage;
    private onNodeNotification;
    private onPropertyUpdateNotification;
    private onNotification;
    private onSessionClosed;
    /**
     * Retrieves the current server time from the ComfoControl device.
     * Sends a CN_TIME_REQUEST opcode to the device and processes the response to get the current time.
     * The time is returned as a Date object.
     *
     * @returns {Promise<Date>} A promise that resolves to the current server time as a Date object.
     * @throws Will throw an error if the request fails or the response is invalid.
     */
    getServerTime(): Promise<Date>;
    /**
     * Registers a listener for updates to a specific device property.
     * Sends a CN_RPDO_REQUEST opcode to request updates for the specified property.
     * The listener will be called whenever the property value is updated.
     *
     * @param {T} property - The property to listen for updates on.
     * @param {DevicePropertyListner} listener - The listener function to call when the property is updated.
     * @returns {Promise<void>} A promise that resolves when the property listener is successfully registered.
     * @throws Will throw an error if the request to register the property updates fails.
     */
    registerPropertyListener<T extends DeviceProperty>(property: T, listener: DevicePropertyListner<T>): Promise<void>;
    private requestPropertyUpdates;
    private getDevicePropertyInfo;
    private static wrapLogger;
    /**
     * Reads an RMI property from the device. Predefined readable properties are available in the {@link VentilationUnitProperties} class.
     *
     * @example
     * ```typescript
     * const serial = await client.readProperty(VentilationUnitProperties.NODE.SERIAL_NUMBER);
     * console.log(`Serial number: ${serial}`);
     * ```
     *
     * @param prop The property to read.
     * @returns A promise that resolves to the value of the property.
     */
    readProperty<T extends NodeProperty>(prop: T): Promise<PropertyNativeType<T>>;
    readPropertyRawValue(prop: NodeProperty): Promise<Buffer>;
    /**
     * Writes a property to the device. Predefined writable properties are available in the {@link VentilationUnitProperties} class.
     *
     * This methods executes a write operation on the device and waits for a comfirmation from the gateway that the operation was successful.
     * If the operation fails, an error will be thrown. See {@link ErrorCodes} for a list of possible error codes that can be thrown.
     *
     * @param prop The property to write.
     * @param value The value to write to the property.
     */
    writeProperty<T extends NodeProperty>(prop: T, value: PropertyNativeType<T>): Promise<void>;
    /**
     * Sets the fan mode of the ventilation unit.
     * @param mode The fan mode to set.
     */
    setFanMode(mode: FanMode): Promise<void>;
    /**
     * Enables or disables bypass of the heat exchanger for the ventilation unit when true or
     * resets the bypass to automatic mode when false.
     * @param bypassEnabled True to enable bypass, false to set to automatic mode.
     */
    enableBypass(bypassEnabled: boolean): Promise<void>;
    /**
     * Set the temperature profile for the ventilation unit.
     * @param profile The temperature profile to set.
     */
    setTempratureProfile(profile: TemperatureProfile): Promise<void>;
    /**
     * Sets the operating mode of the ventilation unit.
     * @param mode The operating mode to set.
     */
    setOperatingMode(mode: OperationMode): Promise<void>;
    executeRmiCommand(...bytes: number[]): Promise<void>;
}
export {};
