import type FakeGatoHistory from 'fakegato-history'; import type { API, Characteristic, DynamicPlatformPlugin, Logging, PlatformAccessory, PlatformConfig } from 'homebridge'; import type PQueue from 'p-queue'; import type { LocalStorage } from 'node-persist'; export interface SceneConfig { sceneCode?: string; bleCode?: string; showAs?: 'default' | 'switch'; } /** * A scene, DIY effect or snapshot the user picked in the config UI. Unlike the legacy * fixed slots there is no cap on how many of these a device can have, and each carries * the icon Govee ships for it so the picker can render without re-fetching. */ export interface SceneSelection { /** Name shown in HomeKit. */ name: string; /** Comma-separated base64 command frames. */ sceneCode: string; /** Optional BLE override; defaults to `sceneCode`. */ bleCode?: string; /** Govee scene id, kept so the UI can re-highlight the selection. */ sceneId?: number; /** Which of a scene's effect variants was chosen. */ variantId?: number; iconUrl?: string; iconUrlDark?: string; kind?: 'scene' | 'diy'; showAs?: 'default' | 'switch'; } /** Live music-mode control, exposed as HomeKit characteristics rather than a fixed code. */ export interface MusicModeConfig { enabled?: boolean; effect?: 'energic' | 'rolling' | 'spectrum' | 'rhythm'; sensitivity?: number; autoColour?: boolean; /** Rhythm only: the softer variant. */ soft?: boolean; /** Which generation of the Govee music protocol this model speaks. */ protocol?: 'modern' | 'legacy'; } export interface LightDeviceConfig { label?: string; deviceId: string; ignoreDevice?: boolean; showAs?: 'default' | 'switch'; customAddress?: string; customIPAddress?: string; adaptiveLightingShift?: number; awsBrightnessNoScale?: boolean; awsColourMode?: 'default' | 'rgb' | 'redgreenblue'; brightnessStep?: number; /** * Scenes picked from the Govee scene library. Replaces the fixed `scene`/`diyMode`/… * slots below, which are still honoured for existing configs. */ scenes?: SceneSelection[]; musicModeLive?: MusicModeConfig; scene?: SceneConfig; sceneTwo?: SceneConfig; sceneThree?: SceneConfig; sceneFour?: SceneConfig; musicMode?: SceneConfig; musicModeTwo?: SceneConfig; videoMode?: SceneConfig; videoModeTwo?: SceneConfig; diyMode?: SceneConfig; diyModeTwo?: SceneConfig; diyModeThree?: SceneConfig; diyModeFour?: SceneConfig; segmented?: SceneConfig; segmentedTwo?: SceneConfig; segmentedThree?: SceneConfig; segmentedFour?: SceneConfig; } export interface SwitchDeviceConfig { label?: string; deviceId: string; ignoreDevice?: boolean; showAs?: 'default' | 'switch' | 'purifier' | 'heater' | 'cooler' | 'tap' | 'valve' | 'audio' | 'box' | 'stick'; temperatureSource?: string; } export interface LeakDeviceConfig { label?: string; deviceId: string; ignoreDevice?: boolean; lowBattThreshold?: number; } export interface ThermoDeviceConfig { label?: string; deviceId: string; ignoreDevice?: boolean; lowBattThreshold?: number; showExtraSwitch?: boolean; } export interface FanDeviceConfig { label?: string; deviceId: string; ignoreDevice?: boolean; hideLight?: boolean; } export interface HeaterDeviceConfig { label?: string; deviceId: string; ignoreDevice?: boolean; tempReporting?: boolean; } export interface BasicDeviceConfig { label?: string; deviceId: string; ignoreDevice?: boolean; } export interface KettleDeviceConfig { label?: string; deviceId: string; ignoreDevice?: boolean; hideModeGreenTea?: boolean; hideModeOolongTea?: boolean; hideModeCoffee?: boolean; hideModeBlackTea?: boolean; showCustomMode1?: boolean; showCustomMode2?: boolean; } export interface GoveePluginConfig extends PlatformConfig { name: string; username?: string; password?: string; code?: string; ignoreMatter?: boolean; disableDeviceLogging?: boolean; httpRefreshTime?: number; awsDisable?: boolean; bleDisable?: boolean; bleRefreshTime?: number; lanDisable?: boolean; lanRefreshTime?: number; lanScanInterval?: number; bleControlInterval?: number; colourSafeMode?: boolean; lightDevices?: LightDeviceConfig[]; switchDevices?: SwitchDeviceConfig[]; leakDevices?: LeakDeviceConfig[]; thermoDevices?: ThermoDeviceConfig[]; fanDevices?: FanDeviceConfig[]; heaterDevices?: HeaterDeviceConfig[]; humidifierDevices?: BasicDeviceConfig[]; dehumidifierDevices?: BasicDeviceConfig[]; purifierDevices?: BasicDeviceConfig[]; diffuserDevices?: BasicDeviceConfig[]; kettleDevices?: KettleDeviceConfig[]; iceMakerDevices?: BasicDeviceConfig[]; } export type DeviceConfigEntry = LightDeviceConfig | SwitchDeviceConfig | LeakDeviceConfig | ThermoDeviceConfig | FanDeviceConfig | HeaterDeviceConfig | BasicDeviceConfig | KettleDeviceConfig; export type SensorDeviceConfig = LeakDeviceConfig | ThermoDeviceConfig; export interface GoveeDevice { device: string; deviceName: string; model: string; sku?: string; ip?: string; isLanDevice?: boolean; isLanOnly?: boolean; httpInfo?: GoveeHTTPDeviceInfo; supportCmds?: string[]; properties?: Record; } export interface GoveeHTTPDeviceInfo { device: string; sku: string; deviceName: string; versionSoft?: string; versionHard?: string; /** * Govee's product-family id. Returned by the device list and required as a query * parameter by the scene, DIY and capability endpoints. */ goodsType?: number; pactType?: number; pactCode?: number; deviceExt?: { extResources?: string; deviceSettings?: string; lastDeviceData?: string; }; } export interface LANDevice { device: string; ip: string; sku?: string; isPendingDiscovery?: boolean; isManual?: boolean; initialised?: boolean; } export interface GoveeAccessoryContext { gvDeviceId: string; gvModel: string; /** Govee product-family id, needed by the scene/DIY/capability endpoints. */ goodsType?: number; hasAwsControl: boolean; useAwsControl: boolean; hasBleControl: boolean; useBleControl: boolean; hasLanControl: boolean; useLanControl: boolean; firmware: string | false; hardware: string | false; image: string | false; awsTopic?: string; awsBrightnessNoScale?: boolean; awsColourMode?: string; bleAddress?: string; bleName?: string; supportedCmds?: string[]; supportedCmdsOpts?: { colorTem?: { range?: { min?: number; max?: number; }; }; [key: string]: unknown; }; temperatureSource?: string; minTemp?: number; maxTemp?: number; offTemp?: number; minHumi?: number; maxHumi?: number; offHumi?: number; sensorAttached?: boolean; lanIPAddress?: string; ipAddress?: string; cacheTarget?: number; cacheType?: 'heater' | 'cooler'; adaptiveLighting?: boolean; valveType?: number; cacheDisplayCode?: string; } export type GoveePlatformAccessory = PlatformAccessory; export type CommandType = 'state' | 'stateDual' | 'stateOutlet' | 'stateHumi' | 'statePuri' | 'stateHeat' | 'multiSync' | 'ptReal' | 'brightness' | 'color' | 'colorTem' | 'colorwc' | 'scene' | 'mode' | 'speed' | 'swing' | 'nightLight' | 'displayLight' | 'lock'; export interface DeviceUpdateParams { cmd: CommandType | string; value: unknown; data?: unknown; } export interface AWSParams { cmd: string; data: Record; } export interface BLEParams { cmd: number | string; /** * A `ptReal` command carries base64 frames — a single string, or an ordered list * when the payload spans several frames (scenes, DIY effects). */ data: number | string | number[] | string[]; } export interface LANParams { cmd: string; data: Record; } export interface CommandData { awsParams?: AWSParams; bleParams?: BLEParams; lanParams?: LANParams; } export type DeviceCommand = DeviceUpdateParams; export type ExternalUpdateParams = DeviceStateUpdate; export interface AWSMessage { cmd?: string; data?: Record | string; msg?: string | AWSMessage; op?: { command?: string[]; }; state?: Record; } export interface LANMessage { msg: { cmd: string; data: Record; }; } export interface BLESensorReading { uuid: string; address: string; model: string; battery: number; humidity: number; tempInC: number; tempInF: number; rssi: number; } export interface DecodedSensorValues { battery: number; humidity: number; tempInC: number; tempInF: number; } export interface DeviceStateUpdate { source?: 'AWS' | 'BLE' | 'LAN' | 'HTTP'; online?: boolean; onOff?: number | boolean; brightness?: number; color?: { r: number; g: number; b: number; }; rgb?: { r: number; g: number; b: number; }; colorTemInKelvin?: number; kelvin?: number; temperature?: number; temperatureF?: number; setTemperature?: number; humidity?: number; battery?: number; leakDetected?: boolean; mode?: number; speed?: number; nightLight?: boolean; displayLight?: boolean; lockState?: boolean; filterLife?: number; airQuality?: number; pm25?: number; state?: 'on' | 'off'; commands?: string[]; [key: string]: unknown; } export interface CustomCharacteristicUUIDs { colourMode: string; musicMode: string; musicModeTwo: string; scene: string; sceneTwo: string; sceneThree: string; sceneFour: string; diyMode: string; diyModeTwo: string; diyModeThree: string; diyModeFour: string; segmented: string; segmentedTwo: string; segmentedThree: string; segmentedFour: string; videoMode: string; videoModeTwo: string; nightLight: string; displayLight: string; } export interface EveCharacteristicUUIDs { currentConsumption: string; voltage: string; electricCurrent: string; lastActivation: string; } export interface DeviceController { externalUpdate(params: DeviceStateUpdate): void | Promise; destroy?(): void; } export interface GoveePlatform extends DynamicPlatformPlugin { readonly api: API; readonly log: GoveeLogging; readonly config: GoveePluginConfig; readonly cusChar: CustomCharacteristics; readonly eveChar: EveCharacteristics; readonly eveService: ReturnType; readonly deviceConf: Record>; readonly ignoredDevices: string[]; readonly isBeta: boolean; httpClient: HTTPClient | false; lanClient: LANClient | false; awsClient: AWSClient | false; bleClient: BLEClient | false; queue: PQueue; storageClientData: boolean; storageData?: LocalStorage; sendDeviceUpdate(accessory: GoveePlatformAccessory, params: DeviceUpdateParams): Promise; receiveDeviceUpdate(accessory: GoveePlatformAccessory, params: DeviceStateUpdate): void; } export interface GoveeLogging extends Logging { debug: (msg: string, ...args: unknown[]) => void; debugWarn: (msg: string, ...args: unknown[]) => void; } export interface HTTPClient { login(): Promise; logout(): Promise; getDevices(isSync?: boolean): Promise; getLeakDeviceWarning(deviceId: string, deviceSku: string): Promise; } export interface HTTPLoginResult { accountId: string; client: string; endpoint: string; iot: string; iotPass: string; token: string; tokenTTR?: string; topic: string; } export interface AWSClient { connected: boolean; connect(): Promise; requestUpdate(accessory: GoveePlatformAccessory): Promise; updateDevice(accessory: GoveePlatformAccessory, params: AWSParams): Promise; } export interface LANClient { lanDevices: LANDevice[]; getDevices(): Promise; updateDevice(accessory: GoveePlatformAccessory, params: LANParams): Promise; sendDeviceStateRequest(device: LANDevice): Promise; startDevicesPolling(): void; startStatusPolling(): void; close(): void; } export interface BLEClient { isScanning: boolean; isConnecting: boolean; updateDevice(accessory: GoveePlatformAccessory, params: BLEParams): Promise; startDiscovery(callback: (reading: BLESensorReading) => void): Promise; stopDiscovery(): Promise; shutdown(): void; } export interface CustomCharacteristics { uuids: CustomCharacteristicUUIDs; ColourMode: typeof Characteristic; MusicMode: typeof Characteristic; MusicModeTwo: typeof Characteristic; Scene: typeof Characteristic; SceneTwo: typeof Characteristic; SceneThree: typeof Characteristic; SceneFour: typeof Characteristic; DiyMode: typeof Characteristic; DiyModeTwo: typeof Characteristic; DiyModeThree: typeof Characteristic; DiyModeFour: typeof Characteristic; Segmented: typeof Characteristic; SegmentedTwo: typeof Characteristic; SegmentedThree: typeof Characteristic; SegmentedFour: typeof Characteristic; VideoMode: typeof Characteristic; VideoModeTwo: typeof Characteristic; NightLight: typeof Characteristic; DisplayLight: typeof Characteristic; } export interface EveCharacteristics { uuids: EveCharacteristicUUIDs; CurrentConsumption: typeof Characteristic; Voltage: typeof Characteristic; ElectricCurrent: typeof Characteristic; LastActivation: typeof Characteristic; } export interface EveHistoryService { addEntry: (entry: Record) => void; getInitialTime: () => number; } export interface GoveePlatformAccessoryWithControl extends GoveePlatformAccessory { control?: DeviceController; eveService?: EveHistoryService; log: (msg: string, ...args: unknown[]) => void; logWarn: (msg: string, ...args: unknown[]) => void; logDebug: (msg: string, ...args: unknown[]) => void; logDebugWarn: (msg: string, ...args: unknown[]) => void; } export interface IotCertificate { cert: string; key: string; } export type { API, Characteristic, CharacteristicValue, Logging, PlatformAccessory, PlatformConfig, Service, } from 'homebridge';