/** * Smart Home Device Interfaces * Generic types for smart home features (lights, climate, sensors, etc.) * Protocol-agnostic - can be implemented by Home Assistant, Hue, MQTT, etc. */ import type { TFeatureState, IFeatureInfo } from './feature.interfaces.js'; // ============================================================================ // Light Feature Types // ============================================================================ export type TLightProtocol = 'home-assistant' | 'hue' | 'mqtt' | 'zigbee'; export interface ILightCapabilities { supportsBrightness: boolean; supportsColorTemp: boolean; supportsRgb: boolean; supportsHs: boolean; // Hue/Saturation supportsXy: boolean; // CIE xy color supportsEffects: boolean; supportsTransition: boolean; effects?: string[]; minMireds?: number; maxMireds?: number; minColorTempKelvin?: number; maxColorTempKelvin?: number; } export interface ILightState { isOn: boolean; brightness?: number; // 0-255 colorTemp?: number; // Kelvin colorTempMireds?: number; // Mireds (1000000/Kelvin) rgbColor?: [number, number, number]; hsColor?: [number, number]; // [hue 0-360, saturation 0-100] xyColor?: [number, number]; // CIE xy effect?: string; } export interface ILightFeatureInfo extends IFeatureInfo { type: 'light'; protocol: TLightProtocol; capabilities: ILightCapabilities; currentState: ILightState; } // ============================================================================ // Climate/Thermostat Feature Types // ============================================================================ export type TClimateProtocol = 'home-assistant' | 'nest' | 'ecobee' | 'mqtt'; export type THvacMode = | 'off' | 'heat' | 'cool' | 'heat_cool' // Auto dual setpoint | 'auto' | 'dry' | 'fan_only'; export type THvacAction = | 'off' | 'heating' | 'cooling' | 'drying' | 'idle' | 'fan'; export interface IClimateCapabilities { hvacModes: THvacMode[]; presetModes?: string[]; // 'away', 'eco', 'boost', 'sleep' fanModes?: string[]; // 'auto', 'low', 'medium', 'high' swingModes?: string[]; // 'off', 'vertical', 'horizontal', 'both' supportsTargetTemp: boolean; supportsTargetTempRange: boolean; // For heat_cool mode supportsHumidity: boolean; supportsAuxHeat: boolean; minTemp: number; maxTemp: number; tempStep: number; // Temperature increment (e.g., 0.5, 1) minHumidity?: number; maxHumidity?: number; } export interface IClimateState { currentTemp?: number; targetTemp?: number; targetTempHigh?: number; // For heat_cool mode targetTempLow?: number; // For heat_cool mode hvacMode: THvacMode; hvacAction?: THvacAction; presetMode?: string; fanMode?: string; swingMode?: string; humidity?: number; targetHumidity?: number; auxHeat?: boolean; } export interface IClimateFeatureInfo extends IFeatureInfo { type: 'climate'; protocol: TClimateProtocol; capabilities: IClimateCapabilities; currentState: IClimateState; } // ============================================================================ // Sensor Feature Types // ============================================================================ export type TSensorProtocol = 'home-assistant' | 'mqtt' | 'snmp'; export type TSensorDeviceClass = | 'temperature' | 'humidity' | 'pressure' | 'illuminance' | 'battery' | 'power' | 'energy' | 'voltage' | 'current' | 'frequency' | 'gas' | 'co2' | 'pm25' | 'pm10' | 'signal_strength' | 'timestamp' | 'duration' | 'distance' | 'speed' | 'weight' | 'monetary' | 'data_size' | 'data_rate' | 'water' | 'irradiance' | 'precipitation' | 'precipitation_intensity' | 'wind_speed'; export type TSensorStateClass = | 'measurement' // Instantaneous reading | 'total' // Cumulative total | 'total_increasing'; // Monotonically increasing total export interface ISensorCapabilities { deviceClass?: TSensorDeviceClass; stateClass?: TSensorStateClass; unit?: string; nativeUnit?: string; precision?: number; // Decimal places } export interface ISensorState { value: string | number | boolean; numericValue?: number; unit?: string; lastUpdated: Date; } export interface ISensorFeatureInfo extends IFeatureInfo { type: 'sensor'; protocol: TSensorProtocol; capabilities: ISensorCapabilities; currentState: ISensorState; } // ============================================================================ // Camera Feature Types // ============================================================================ export type TCameraProtocol = 'home-assistant' | 'onvif' | 'rtsp'; export interface ICameraCapabilities { supportsStream: boolean; supportsPtz: boolean; // Pan-tilt-zoom supportsSnapshot: boolean; supportsMotionDetection: boolean; frontendStreamType?: 'hls' | 'web_rtc'; streamUrl?: string; } export interface ICameraState { isRecording: boolean; isStreaming: boolean; motionDetected: boolean; } export interface ICameraFeatureInfo extends IFeatureInfo { type: 'camera'; protocol: TCameraProtocol; capabilities: ICameraCapabilities; currentState: ICameraState; } // ============================================================================ // Cover/Blind Feature Types // ============================================================================ export type TCoverProtocol = 'home-assistant' | 'mqtt' | 'somfy'; export type TCoverDeviceClass = | 'awning' | 'blind' | 'curtain' | 'damper' | 'door' | 'garage' | 'gate' | 'shade' | 'shutter' | 'window'; export type TCoverState = 'open' | 'opening' | 'closed' | 'closing' | 'stopped' | 'unknown'; export interface ICoverCapabilities { deviceClass?: TCoverDeviceClass; supportsOpen: boolean; supportsClose: boolean; supportsStop: boolean; supportsPosition: boolean; // set_cover_position supportsTilt: boolean; // set_cover_tilt_position } export interface ICoverStateInfo { state: TCoverState; position?: number; // 0-100, 0 = closed, 100 = fully open tiltPosition?: number; // 0-100 } export interface ICoverFeatureInfo extends IFeatureInfo { type: 'cover'; protocol: TCoverProtocol; capabilities: ICoverCapabilities; currentState: ICoverStateInfo; } // ============================================================================ // Switch Feature Types // ============================================================================ export type TSwitchProtocol = 'home-assistant' | 'mqtt' | 'tasmota' | 'tuya'; export type TSwitchDeviceClass = 'outlet' | 'switch'; export interface ISwitchCapabilities { deviceClass?: TSwitchDeviceClass; } export interface ISwitchState { isOn: boolean; } export interface ISwitchFeatureInfo extends IFeatureInfo { type: 'switch'; protocol: TSwitchProtocol; capabilities: ISwitchCapabilities; currentState: ISwitchState; } // ============================================================================ // Lock Feature Types // ============================================================================ export type TLockProtocol = 'home-assistant' | 'mqtt' | 'august' | 'yale'; export type TLockState = | 'locked' | 'unlocked' | 'locking' | 'unlocking' | 'jammed' | 'unknown'; export interface ILockCapabilities { supportsOpen: boolean; // Physical open (some locks can open the door) } export interface ILockStateInfo { state: TLockState; isLocked: boolean; } export interface ILockFeatureInfo extends IFeatureInfo { type: 'lock'; protocol: TLockProtocol; capabilities: ILockCapabilities; currentState: ILockStateInfo; } // ============================================================================ // Fan Feature Types // ============================================================================ export type TFanProtocol = 'home-assistant' | 'mqtt' | 'bond'; export type TFanDirection = 'forward' | 'reverse'; export interface IFanCapabilities { supportsSpeed: boolean; supportsOscillate: boolean; supportsDirection: boolean; supportsPresetModes: boolean; presetModes?: string[]; speedCount?: number; // Number of discrete speed levels } export interface IFanState { isOn: boolean; percentage?: number; // 0-100 speed presetMode?: string; oscillating?: boolean; direction?: TFanDirection; } export interface IFanFeatureInfo extends IFeatureInfo { type: 'fan'; protocol: TFanProtocol; capabilities: IFanCapabilities; currentState: IFanState; } // ============================================================================ // Protocol Client Interfaces (for dependency injection) // ============================================================================ /** * Light protocol client interface * Implemented by HomeAssistantProtocol, HueProtocol, etc. */ export interface ILightProtocolClient { turnOn(entityId: string, options?: { brightness?: number; colorTemp?: number; rgb?: [number, number, number]; transition?: number }): Promise; turnOff(entityId: string, options?: { transition?: number }): Promise; toggle(entityId: string): Promise; setBrightness(entityId: string, brightness: number, transition?: number): Promise; setColorTemp(entityId: string, kelvin: number, transition?: number): Promise; setRgbColor(entityId: string, r: number, g: number, b: number, transition?: number): Promise; setEffect(entityId: string, effect: string): Promise; getState(entityId: string): Promise; } /** * Climate protocol client interface */ export interface IClimateProtocolClient { setHvacMode(entityId: string, mode: THvacMode): Promise; setTargetTemp(entityId: string, temp: number): Promise; setTargetTempRange(entityId: string, low: number, high: number): Promise; setPresetMode(entityId: string, preset: string): Promise; setFanMode(entityId: string, mode: string): Promise; setSwingMode(entityId: string, mode: string): Promise; setAuxHeat(entityId: string, enabled: boolean): Promise; getState(entityId: string): Promise; } /** * Sensor protocol client interface (read-only) */ export interface ISensorProtocolClient { getState(entityId: string): Promise; } /** * Camera protocol client interface */ export interface ICameraProtocolClient { getSnapshot(entityId: string): Promise; getSnapshotUrl(entityId: string): Promise; getStreamUrl(entityId: string): Promise; getState(entityId: string): Promise; } /** * Cover protocol client interface */ export interface ICoverProtocolClient { open(entityId: string): Promise; close(entityId: string): Promise; stop(entityId: string): Promise; setPosition(entityId: string, position: number): Promise; setTiltPosition(entityId: string, position: number): Promise; getState(entityId: string): Promise; } /** * Switch protocol client interface */ export interface ISwitchProtocolClient { turnOn(entityId: string): Promise; turnOff(entityId: string): Promise; toggle(entityId: string): Promise; getState(entityId: string): Promise; } /** * Lock protocol client interface */ export interface ILockProtocolClient { lock(entityId: string): Promise; unlock(entityId: string): Promise; open(entityId: string): Promise; // Physical open if supported getState(entityId: string): Promise; } /** * Fan protocol client interface */ export interface IFanProtocolClient { turnOn(entityId: string, percentage?: number): Promise; turnOff(entityId: string): Promise; toggle(entityId: string): Promise; setPercentage(entityId: string, percentage: number): Promise; setPresetMode(entityId: string, mode: string): Promise; setOscillating(entityId: string, oscillating: boolean): Promise; setDirection(entityId: string, direction: TFanDirection): Promise; getState(entityId: string): Promise; }