lib-comfoair
Version:
Library to communicate with Zehnder ComfoAirQ ventilation unit through the ComfoControl gateway
242 lines (241 loc) • 10.3 kB
TypeScript
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 {};