360 lines
9.7 KiB
TypeScript
360 lines
9.7 KiB
TypeScript
/**
|
|
* Feature Type Definitions
|
|
* Features are composable capabilities that can be attached to devices
|
|
*/
|
|
|
|
import type { IRetryOptions } from './index.js';
|
|
|
|
// ============================================================================
|
|
// Feature Types
|
|
// ============================================================================
|
|
|
|
/**
|
|
* All supported feature types
|
|
*/
|
|
export type TFeatureType =
|
|
// Document handling
|
|
| 'scan' // Can scan documents (eSCL, SANE)
|
|
| 'print' // Can print documents (IPP, JetDirect)
|
|
| 'fax' // Can send/receive fax
|
|
| 'copy' // Can copy (scan + print combined)
|
|
// Media playback
|
|
| 'playback' // Can play media (audio/video)
|
|
| 'volume' // Has volume control
|
|
// Infrastructure
|
|
| 'power' // Has power status (UPS, smart plug)
|
|
| 'snmp' // SNMP queryable
|
|
// DLNA
|
|
| 'dlna-render' // DLNA renderer
|
|
| 'dlna-serve' // DLNA server (content provider)
|
|
// Smart home (protocol-agnostic: home-assistant, hue, mqtt, etc.)
|
|
| 'light' // Brightness, color, effects
|
|
| 'climate' // Temperature, HVAC modes
|
|
| 'sensor' // Read-only state values
|
|
| 'camera' // Snapshots, streams
|
|
| 'cover' // Blinds, garage doors
|
|
| 'switch' // Binary on/off
|
|
| 'lock' // Lock/unlock
|
|
| 'fan' // Speed, oscillation
|
|
;
|
|
|
|
/**
|
|
* Feature connection state
|
|
*/
|
|
export type TFeatureState = 'disconnected' | 'connecting' | 'connected' | 'error';
|
|
|
|
// ============================================================================
|
|
// Base Feature Interface
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Base interface for all features
|
|
*/
|
|
export interface IFeature {
|
|
/** Feature type identifier */
|
|
readonly type: TFeatureType;
|
|
/** Protocol used by this feature */
|
|
readonly protocol: string;
|
|
/** Current feature state */
|
|
readonly state: TFeatureState;
|
|
/** Port used by this feature (may differ from device port) */
|
|
readonly port: number;
|
|
/** Connect to the feature endpoint */
|
|
connect(): Promise<void>;
|
|
/** Disconnect from the feature endpoint */
|
|
disconnect(): Promise<void>;
|
|
}
|
|
|
|
/**
|
|
* Feature info for serialization
|
|
*/
|
|
export interface IFeatureInfo {
|
|
type: TFeatureType;
|
|
protocol: string;
|
|
port: number;
|
|
state: TFeatureState;
|
|
}
|
|
|
|
// ============================================================================
|
|
// Scan Feature
|
|
// ============================================================================
|
|
|
|
export type TScanProtocol = 'escl' | 'sane' | 'wia';
|
|
export type TScanFormat = 'png' | 'jpeg' | 'pdf' | 'tiff';
|
|
export type TColorMode = 'color' | 'grayscale' | 'blackwhite';
|
|
export type TScanSource = 'flatbed' | 'adf' | 'adf-duplex';
|
|
|
|
export interface IScanCapabilities {
|
|
resolutions: number[];
|
|
formats: TScanFormat[];
|
|
colorModes: TColorMode[];
|
|
sources: TScanSource[];
|
|
maxWidth: number; // mm
|
|
maxHeight: number; // mm
|
|
minWidth: number; // mm
|
|
minHeight: number; // mm
|
|
}
|
|
|
|
export interface IScanArea {
|
|
x: number; // X offset in mm
|
|
y: number; // Y offset in mm
|
|
width: number; // Width in mm
|
|
height: number; // Height in mm
|
|
}
|
|
|
|
export interface IScanOptions {
|
|
resolution?: number;
|
|
format?: TScanFormat;
|
|
colorMode?: TColorMode;
|
|
source?: TScanSource;
|
|
area?: IScanArea;
|
|
intent?: 'document' | 'photo' | 'preview';
|
|
quality?: number; // 1-100 for JPEG
|
|
}
|
|
|
|
export interface IScanResult {
|
|
data: Buffer;
|
|
format: TScanFormat;
|
|
width: number;
|
|
height: number;
|
|
resolution: number;
|
|
colorMode: TColorMode;
|
|
mimeType: string;
|
|
}
|
|
|
|
export interface IScanFeatureInfo extends IFeatureInfo {
|
|
type: 'scan';
|
|
protocol: TScanProtocol;
|
|
supportedFormats: TScanFormat[];
|
|
supportedResolutions: number[];
|
|
supportedColorModes: TColorMode[];
|
|
supportedSources: TScanSource[];
|
|
hasAdf: boolean;
|
|
hasDuplex: boolean;
|
|
}
|
|
|
|
// ============================================================================
|
|
// Print Feature
|
|
// ============================================================================
|
|
|
|
export type TPrintProtocol = 'ipp' | 'jetdirect' | 'lpd';
|
|
export type TPrintSides = 'one-sided' | 'two-sided-long-edge' | 'two-sided-short-edge';
|
|
export type TPrintQuality = 'draft' | 'normal' | 'high';
|
|
export type TPrintColorMode = 'color' | 'monochrome';
|
|
|
|
export interface IPrintCapabilities {
|
|
colorSupported: boolean;
|
|
duplexSupported: boolean;
|
|
mediaSizes: string[];
|
|
mediaTypes: string[];
|
|
resolutions: number[];
|
|
maxCopies: number;
|
|
sidesSupported: TPrintSides[];
|
|
qualitySupported: TPrintQuality[];
|
|
}
|
|
|
|
export interface IPrintOptions {
|
|
copies?: number;
|
|
mediaSize?: string;
|
|
mediaType?: string;
|
|
sides?: TPrintSides;
|
|
quality?: TPrintQuality;
|
|
colorMode?: TPrintColorMode;
|
|
jobName?: string;
|
|
}
|
|
|
|
export interface IPrintJob {
|
|
id: number;
|
|
name: string;
|
|
state: 'pending' | 'processing' | 'completed' | 'canceled' | 'aborted';
|
|
stateReason?: string;
|
|
createdAt: Date;
|
|
completedAt?: Date;
|
|
pagesPrinted?: number;
|
|
pagesTotal?: number;
|
|
}
|
|
|
|
export interface IPrintFeatureInfo extends IFeatureInfo {
|
|
type: 'print';
|
|
protocol: TPrintProtocol;
|
|
supportsColor: boolean;
|
|
supportsDuplex: boolean;
|
|
supportedMediaSizes: string[];
|
|
}
|
|
|
|
// ============================================================================
|
|
// Playback Feature
|
|
// ============================================================================
|
|
|
|
export type TPlaybackProtocol = 'sonos' | 'airplay' | 'chromecast' | 'dlna';
|
|
export type TPlaybackState = 'playing' | 'paused' | 'stopped' | 'buffering' | 'unknown';
|
|
|
|
export interface ITrackInfo {
|
|
title?: string;
|
|
artist?: string;
|
|
album?: string;
|
|
albumArtUri?: string;
|
|
duration?: number; // seconds
|
|
uri?: string;
|
|
}
|
|
|
|
export interface IPlaybackStatus {
|
|
state: TPlaybackState;
|
|
position: number; // seconds
|
|
duration: number; // seconds
|
|
track?: ITrackInfo;
|
|
}
|
|
|
|
export interface IPlaybackFeatureInfo extends IFeatureInfo {
|
|
type: 'playback';
|
|
protocol: TPlaybackProtocol;
|
|
supportsQueue: boolean;
|
|
supportsSeek: boolean;
|
|
}
|
|
|
|
// ============================================================================
|
|
// Volume Feature
|
|
// ============================================================================
|
|
|
|
export interface IVolumeFeatureInfo extends IFeatureInfo {
|
|
type: 'volume';
|
|
minVolume: number;
|
|
maxVolume: number;
|
|
volumeStep: number;
|
|
supportsMute: boolean;
|
|
}
|
|
|
|
// ============================================================================
|
|
// Power Feature (UPS, Smart Plugs)
|
|
// ============================================================================
|
|
|
|
export type TPowerProtocol = 'nut' | 'snmp' | 'smart-plug';
|
|
export type TPowerStatus = 'online' | 'onbattery' | 'lowbattery' | 'charging' | 'discharging' | 'bypass' | 'offline' | 'error' | 'unknown';
|
|
|
|
export interface IBatteryInfo {
|
|
charge: number; // 0-100%
|
|
runtime: number; // seconds remaining
|
|
voltage?: number; // volts
|
|
temperature?: number; // celsius
|
|
health?: 'good' | 'weak' | 'replace';
|
|
}
|
|
|
|
export interface IPowerInfo {
|
|
inputVoltage?: number;
|
|
outputVoltage?: number;
|
|
inputFrequency?: number;
|
|
outputFrequency?: number;
|
|
load?: number; // 0-100%
|
|
power?: number; // watts
|
|
}
|
|
|
|
export interface IPowerFeatureInfo extends IFeatureInfo {
|
|
type: 'power';
|
|
protocol: TPowerProtocol;
|
|
hasBattery: boolean;
|
|
supportsShutdown: boolean;
|
|
supportsTest: boolean;
|
|
}
|
|
|
|
// ============================================================================
|
|
// SNMP Feature
|
|
// ============================================================================
|
|
|
|
export type TSnmpVersion = 'v1' | 'v2c' | 'v3';
|
|
|
|
export interface ISnmpVarbind {
|
|
oid: string;
|
|
type: number;
|
|
value: unknown;
|
|
}
|
|
|
|
export interface ISnmpFeatureInfo extends IFeatureInfo {
|
|
type: 'snmp';
|
|
version: TSnmpVersion;
|
|
community?: string; // for v1/v2c
|
|
sysDescr?: string;
|
|
sysName?: string;
|
|
sysLocation?: string;
|
|
}
|
|
|
|
// ============================================================================
|
|
// DLNA Render Feature
|
|
// ============================================================================
|
|
|
|
export interface IDlnaTransportInfo {
|
|
state: 'STOPPED' | 'PLAYING' | 'PAUSED' | 'TRANSITIONING' | 'NO_MEDIA_PRESENT';
|
|
status: string;
|
|
speed: string;
|
|
}
|
|
|
|
export interface IDlnaPositionInfo {
|
|
track: number;
|
|
trackDuration: string;
|
|
trackMetaData?: string;
|
|
trackUri?: string;
|
|
relTime: string;
|
|
absTime: string;
|
|
}
|
|
|
|
export interface IDlnaRenderFeatureInfo extends IFeatureInfo {
|
|
type: 'dlna-render';
|
|
udn: string;
|
|
friendlyName: string;
|
|
supportsVolume: boolean;
|
|
supportedProtocols: string[];
|
|
}
|
|
|
|
// ============================================================================
|
|
// DLNA Server Feature
|
|
// ============================================================================
|
|
|
|
export interface IDlnaContentItem {
|
|
id: string;
|
|
parentId: string;
|
|
title: string;
|
|
class: string;
|
|
restricted: boolean;
|
|
uri?: string;
|
|
albumArtUri?: string;
|
|
duration?: string;
|
|
size?: number;
|
|
isContainer: boolean;
|
|
childCount?: number;
|
|
}
|
|
|
|
export interface IDlnaBrowseResult {
|
|
items: IDlnaContentItem[];
|
|
numberReturned: number;
|
|
totalMatches: number;
|
|
updateId: number;
|
|
}
|
|
|
|
export interface IDlnaServeFeatureInfo extends IFeatureInfo {
|
|
type: 'dlna-serve';
|
|
udn: string;
|
|
friendlyName: string;
|
|
contentCount?: number;
|
|
}
|
|
|
|
// ============================================================================
|
|
// Discovery Types
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Feature discovered during network scan or mDNS/SSDP
|
|
*/
|
|
export interface IDiscoveredFeature {
|
|
type: TFeatureType;
|
|
protocol: string;
|
|
port: number;
|
|
metadata: Record<string, unknown>;
|
|
}
|
|
|
|
/**
|
|
* Options for creating a feature instance
|
|
*/
|
|
export interface IFeatureOptions {
|
|
retryOptions?: IRetryOptions;
|
|
metadata?: Record<string, unknown>;
|
|
}
|