hap-nodejs
Version:
HAP-NodeJS is a Node.js implementation of HomeKit Accessory Server.
440 lines • 14.4 kB
TypeScript
import { EventEmitter } from "events";
import { AudioBitrate, AudioSamplerate } from "../camera";
import { HDSProtocolSpecificErrorReason, DataStreamConnection, DataStreamProtocolHandler, EventHandler, RequestHandler } from "../datastream";
import type { AudioStreamManagement, DataStreamTransportManagement, Siri, TargetControl, TargetControlManagement } from "../definitions";
import { ControllerIdentifier, ControllerServiceMap, SerializableController, StateChangeDelegate } from "./Controller";
/**
* @group Apple TV Remote
*/
export declare const enum ButtonType {
UNDEFINED = 0,
MENU = 1,
PLAY_PAUSE = 2,
TV_HOME = 3,
SELECT = 4,
ARROW_UP = 5,
ARROW_RIGHT = 6,
ARROW_DOWN = 7,
ARROW_LEFT = 8,
VOLUME_UP = 9,
VOLUME_DOWN = 10,
SIRI = 11,
POWER = 12,
GENERIC = 13
}
/**
* @group Apple TV Remote
*/
export declare const enum TargetCategory {
UNDEFINED = 0,
APPLE_TV = 24
}
/**
* @group Apple TV Remote
*/
export declare const enum ButtonState {
UP = 0,
DOWN = 1
}
/**
* @group Apple TV Remote
*/
export type SupportedConfiguration = {
maximumTargets: number;
ticksPerSecond: number;
supportedButtonConfiguration: SupportedButtonConfiguration[];
hardwareImplemented: boolean;
};
/**
* @group Apple TV Remote
*/
export type SupportedButtonConfiguration = {
buttonID: number;
buttonType: ButtonType;
};
/**
* @group Apple TV Remote
*/
export type TargetConfiguration = {
targetIdentifier: number;
targetName?: string;
targetCategory?: TargetCategory;
buttonConfiguration: Record<number, ButtonConfiguration>;
};
/**
* @group Apple TV Remote
*/
export type ButtonConfiguration = {
buttonID: number;
buttonType: ButtonType;
buttonName?: string;
};
/**
* @group Camera
*/
export declare const enum AudioCodecTypes {
PCMU = 0,
PCMA = 1,
AAC_ELD = 2,
OPUS = 3,
MSBC = 4,// mSBC is a bluetooth codec (lol)
AMR = 5,
AMR_WB = 6
}
type SupportedAudioStreamConfiguration = {
audioCodecConfiguration: AudioCodecConfiguration;
};
/**
* @group Apple TV Remote
*/
export type AudioCodecConfiguration = {
codecType: AudioCodecTypes;
parameters: AudioCodecParameters;
};
/**
* @group Apple TV Remote
*/
export type AudioCodecParameters = {
channels: number;
bitrate: AudioBitrate;
samplerate: AudioSamplerate;
rtpTime?: RTPTime;
};
/**
* @group Apple TV Remote
*/
export type RTPTime = 20 | 30 | 40 | 60;
declare const enum SiriAudioSessionState {
STARTING = 0,// we are currently waiting for a response for the start request
SENDING = 1,// we are sending data
CLOSING = 2,// we are currently waiting for the acknowledgment event
CLOSED = 3
}
/**
* @group Apple TV Remote
*/
export type AudioFrame = {
data: Buffer;
rms: number;
};
/**
* @group Apple TV Remote
*/
export type FrameHandler = (frame: AudioFrame) => void;
/**
* @group Apple TV Remote
*/
export type ErrorHandler = (error: HDSProtocolSpecificErrorReason) => void;
/**
* @group Apple TV Remote
*/
export interface SiriAudioStreamProducer {
startAudioProduction(selectedAudioConfiguration: AudioCodecConfiguration): void;
stopAudioProduction(): void;
}
/**
* @group Apple TV Remote
*/
export interface SiriAudioStreamProducerConstructor {
/**
* Creates a new instance of a SiriAudioStreamProducer
*
* @param frameHandler - called for every opus frame recorded
* @param errorHandler - should be called with an appropriate reason when the producing process errored
* @param options - optional parameter for passing any configuration related options
*/
new (frameHandler: FrameHandler, errorHandler: ErrorHandler, options?: any): SiriAudioStreamProducer;
}
/**
* @group Apple TV Remote
*/
export declare const enum TargetUpdates {
NAME = 0,
CATEGORY = 1,
UPDATED_BUTTONS = 2,
REMOVED_BUTTONS = 3
}
/**
* @group Apple TV Remote
*/
export declare const enum RemoteControllerEvents {
/**
* This event is emitted when the active state of the remote has changed.
* active = true indicates that there is currently an Apple TV listening of button presses and audio streams.
*/
ACTIVE_CHANGE = "active-change",
/**
* This event is emitted when the currently selected target has changed.
* Possible reasons for a changed active identifier: manual change via api call, first target configuration
* gets added, active target gets removed, accessory gets unpaired, reset request was sent.
* An activeIdentifier of 0 indicates that no target is selected.
*/
ACTIVE_IDENTIFIER_CHANGE = "active-identifier-change",
/**
* This event is emitted when a new target configuration is received. As we currently do not persistently store
* configured targets, this will be called at every startup for every Apple TV configured in the home.
*/
TARGET_ADDED = "target-add",
/**
* This event is emitted when an existing target was updated.
* The 'updates' array indicates what exactly was changed for the target.
*/
TARGET_UPDATED = "target-update",
/**
* This event is emitted when an existing configuration for a target was removed.
*/
TARGET_REMOVED = "target-remove",
/**
* This event is emitted when a reset of the target configuration is requested.
* With this event every configuration made should be reset. This event is also called
* when the accessory gets unpaired.
*/
TARGETS_RESET = "targets-reset"
}
/**
* @group Apple TV Remote
*/
export declare interface RemoteController {
on(event: "active-change", listener: (active: boolean) => void): this;
on(event: "active-identifier-change", listener: (activeIdentifier: number) => void): this;
on(event: "target-add", listener: (targetConfiguration: TargetConfiguration) => void): this;
on(event: "target-update", listener: (targetConfiguration: TargetConfiguration, updates: TargetUpdates[]) => void): this;
on(event: "target-remove", listener: (targetIdentifier: number) => void): this;
on(event: "targets-reset", listener: () => void): this;
emit(event: "active-change", active: boolean): boolean;
emit(event: "active-identifier-change", activeIdentifier: number): boolean;
emit(event: "target-add", targetConfiguration: TargetConfiguration): boolean;
emit(event: "target-update", targetConfiguration: TargetConfiguration, updates: TargetUpdates[]): boolean;
emit(event: "target-remove", targetIdentifier: number): boolean;
emit(event: "targets-reset"): boolean;
}
/**
* @group Apple TV Remote
*/
export interface RemoteControllerServiceMap extends ControllerServiceMap {
targetControlManagement: TargetControlManagement;
targetControl: TargetControl;
siri?: Siri;
audioStreamManagement?: AudioStreamManagement;
dataStreamTransportManagement?: DataStreamTransportManagement;
}
/**
* @group Apple TV Remote
*/
export interface SerializedControllerState {
activeIdentifier: number;
targetConfigurations: Record<number, TargetConfiguration>;
}
/**
* Handles everything needed to implement a fully working HomeKit remote controller.
*
* @group Apple TV Remote
*/
export declare class RemoteController extends EventEmitter implements SerializableController<RemoteControllerServiceMap, SerializedControllerState>, DataStreamProtocolHandler {
private stateChangeDelegate?;
private readonly audioSupported;
private readonly audioProducerConstructor?;
private readonly audioProducerOptions?;
private targetControlManagementService?;
private targetControlService?;
private siriService?;
private audioStreamManagementService?;
private dataStreamManagement?;
private buttons;
private readonly supportedConfiguration;
targetConfigurations: Map<number, TargetConfiguration>;
private targetConfigurationsString;
private lastButtonEvent;
activeIdentifier: number;
private activeConnection?;
private activeConnectionDisconnectListener?;
private readonly supportedAudioConfiguration;
private selectedAudioConfiguration;
private selectedAudioConfigurationString;
private dataStreamConnections;
private activeAudioSession?;
private nextAudioSession?;
/**
* @private
*/
eventHandler?: Record<string, EventHandler>;
/**
* @private
*/
requestHandler?: Record<string, RequestHandler>;
/**
* Creates a new RemoteController.
* If siri voice input is supported the constructor to an SiriAudioStreamProducer needs to be supplied.
* Otherwise, a remote without voice support will be created.
*
* For every audio session a new SiriAudioStreamProducer will be constructed.
*
* @param audioProducerConstructor - constructor for a SiriAudioStreamProducer
* @param producerOptions - if supplied this argument will be supplied as third argument of the SiriAudioStreamProducer
* constructor. This should be used to supply configurations to the stream producer.
*/
constructor(audioProducerConstructor?: SiriAudioStreamProducerConstructor, producerOptions?: any);
/**
* @private
*/
controllerId(): ControllerIdentifier;
/**
* Set a new target as active target. A value of 0 indicates that no target is selected currently.
*
* @param activeIdentifier - target identifier
*/
setActiveIdentifier(activeIdentifier: number): void;
/**
* @returns if the current target is active, meaning the active device is listening for button events or audio sessions
*/
isActive(): boolean;
/**
* Checks if the supplied targetIdentifier is configured.
*
* @param targetIdentifier - The target identifier.
*/
isConfigured(targetIdentifier: number): boolean;
/**
* Returns the targetIdentifier for a give device name
*
* @param name - The name of the device.
* @returns The targetIdentifier of the device or undefined if not existent.
*/
getTargetIdentifierByName(name: string): number | undefined;
/**
* Sends a button event to press the supplied button.
*
* @param button - button to be pressed
*/
pushButton(button: ButtonType): void;
/**
* Sends a button event that the supplied button was released.
*
* @param button - button which was released
*/
releaseButton(button: ButtonType): void;
/**
* Presses a supplied button for a given time.
*
* @param button - button to be pressed and released
* @param time - time in milliseconds (defaults to 200ms)
*/
pushAndReleaseButton(button: ButtonType, time?: number): void;
protected constructSupportedConfiguration(): SupportedConfiguration;
protected constructSupportedAudioConfiguration(): SupportedAudioStreamConfiguration;
private handleTargetControlWrite;
private handleAddTarget;
private handleUpdateTarget;
private handleRemoveTarget;
private handleResetTargets;
private handleListTargets;
private handleActiveWrite;
private setInactive;
private handleActiveSessionDisconnected;
private sendButtonEvent;
private parseTargetConfigurationTLV;
private updatedTargetConfiguration;
private buildTargetControlSupportedConfigurationTLV;
private handleTargetControlWhoAmI;
private handleSiriAudioStart;
private handleSiriAudioStop;
private handleDataSendAckEvent;
private handleDataSendCloseEvent;
private handleSiriAudioSessionClosed;
private handleDataStreamConnectionClosed;
private handleSelectedAudioConfigurationWrite;
private static buildSupportedAudioConfigurationTLV;
private static buildSelectedAudioConfigurationTLV;
private static buildCodecConfigurationTLV;
/**
* @private
*/
constructServices(): RemoteControllerServiceMap;
/**
* @private
*/
initWithServices(serviceMap: RemoteControllerServiceMap): void | RemoteControllerServiceMap;
/**
* @private
*/
configureServices(): void;
/**
* @private
*/
handleControllerRemoved(): void;
/**
* @private
*/
handleFactoryReset(): void;
/**
* @private
*/
serialize(): SerializedControllerState | undefined;
/**
* @private
*/
deserialize(serialized: SerializedControllerState): void;
/**
* @private
*/
setupStateChangeDelegate(delegate?: StateChangeDelegate): void;
}
/**
* @group Apple TV Remote
*/
export declare const enum SiriAudioSessionEvents {
CLOSE = "close"
}
/**
* @group Apple TV Remote
*/
export declare interface SiriAudioSession {
on(event: "close", listener: () => void): this;
emit(event: "close"): boolean;
}
/**
* Represents an ongoing audio transmission
* @group Apple TV Remote
*/
export declare class SiriAudioSession extends EventEmitter {
readonly connection: DataStreamConnection;
private readonly selectedAudioConfiguration;
private readonly producer;
private producerRunning;
private producerTimer?;
/**
* @private file private API
*/
state: SiriAudioSessionState;
streamId?: number;
endOfStream: boolean;
private audioFrameQueue;
private readonly maxQueueSize;
private sequenceNumber;
private readonly closeListener;
constructor(connection: DataStreamConnection, selectedAudioConfiguration: AudioCodecConfiguration, producerConstructor: SiriAudioStreamProducerConstructor, producerOptions?: any);
/**
* Called when siri button is pressed
*/
start(): void;
/**
* @returns if the audio session is closing
*/
isClosing(): boolean;
/**
* Called when siri button is released (or active identifier is changed to another device)
*/
stop(): void;
private startAudioProducer;
private stopAudioProducer;
private handleSiriAudioFrame;
private handleProducerError;
handleDataSendAckEvent(endOfStream: boolean): void;
handleDataSendCloseEvent(reason: HDSProtocolSpecificErrorReason): void;
private sendDataSendCloseEvent;
private handleDataStreamConnectionClosed;
private closed;
private popSome;
}
export {};
//# sourceMappingURL=RemoteController.d.ts.map