{"version":3,"sources":["jsdelivr-header.js","/npm/govee-lan-control@3.0.2/src/index.ts","/npm/govee-lan-control@3.0.2/src/commands/setColors.ts","/npm/govee-lan-control@3.0.2/src/commands/setOnOff.ts","/npm/govee-lan-control@3.0.2/src/commands/createSocket.ts"],"names":[],"mappings":"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","file":"/npm/govee-lan-control@3.0.2/dist/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/govee-lan-control@3.0.2/dist/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","import { RemoteInfo, Socket, createSocket } from 'dgram';\r\nimport { fade, setBrightness, setColor, updateValues } from './commands/setColors';\r\nimport { setOff, setOn } from './commands/setOnOff';\r\nimport getSocket from './commands/createSocket';\r\nimport { EventEmitter } from 'events';\r\nimport * as ct from 'color-temperature';\r\n\r\nexport interface DeviceState\r\n{\r\n    isOn: number,\r\n    brightness: number,\r\n    color: { \"r\": number, \"g\": number, \"b\": number; },\r\n    colorKelvin: number,\r\n    hasReceivedUpdates: boolean;\r\n}\r\n\r\nexport class Device extends EventEmitter\r\n{\r\n    constructor(data: Record<string, any>, GoveeInstance: Govee, socket: Socket)\r\n    {\r\n        super();\r\n        deviceList.set(data.ip, this);\r\n\r\n        this.model = data.sku;\r\n        this.deviceID = data.device;\r\n        this.ip = data.ip;\r\n        this.versions = {\r\n            BLEhardware: data.bleVersionHard,\r\n            BLEsoftware: data.bleVersionSoft,\r\n            WiFiHardware: data.wifiVersionHard,\r\n            WiFiSoftware: data.wifiVersionSoft\r\n        };\r\n\r\n        this.state = {\r\n            isOn: 0,\r\n            brightness: 0,\r\n            color: { \"r\": 0, \"g\": 0, \"b\": 0 },\r\n            colorKelvin: 0,\r\n            hasReceivedUpdates: false\r\n        };\r\n\r\n        this.socket = socket;\r\n        this.updateTimer = setInterval(() =>\r\n        {\r\n            this.updateValues();\r\n        }, 6000);\r\n\r\n        // When the status gets changes, emit it on the main class aswell\r\n        this.on(\"updatedStatus\", (data, stateChanged) =>\r\n        {\r\n            GoveeInstance.emit(\"updatedStatus\", this, data, stateChanged);\r\n        });\r\n\r\n        this.goveeInstance = GoveeInstance;\r\n    }\r\n    readonly ip: string;\r\n    readonly deviceID: string;\r\n    readonly model: string;\r\n    readonly socket: Socket;\r\n    readonly goveeInstance: Govee;\r\n    readonly versions: {\r\n        BLEhardware: string;\r\n        BLEsoftware: string;\r\n        WiFiHardware: string;\r\n        WiFiSoftware: string;\r\n    };\r\n    public state: DeviceState;\r\n    readonly actions = new actions(this);\r\n    readonly updateValues = async () => await updateValues(this);\r\n    private updateTimer: NodeJS.Timer;\r\n    public destroy = () =>\r\n    {\r\n        this.emit(\"destroyed\");\r\n        clearTimeout(this.updateTimer);\r\n    };\r\n}\r\n\r\nclass actions\r\n{\r\n    constructor(device: Device)\r\n    {\r\n        this.device = device;\r\n    }\r\n    private device: Device;\r\n    setColor = (color: colorOptions): Promise<void> => setColor.call(this.device, color);\r\n\r\n    /**\r\n     * @description\r\n     * Pass a 0-100 value to set the brightness of the device.\r\n     */\r\n    setBrightness = (brightness: string | number): Promise<void> => setBrightness.call(this.device, brightness);\r\n\r\n    /**\r\n     * @description\r\n     * #### Fade the color and brightness of your device.\r\n     * **Warning**: This works by sending many many commands (At least every 10ms).\r\n     * \r\n     * Before the code gets run for sending values, the state of the device gets updated.\r\n     * ***\r\n     * Usage:\r\n     * ```js\r\n     * fadeColor({\r\n            time: 2000, // In milliseconds\r\n            color: {\r\n                hex: \"#282c34\" // Other options possible\r\n            },\r\n            brightness: 20 // 0-100\r\n        });\r\n     * ```\r\n     */\r\n    fadeColor = (options: fadeOptions): Promise<void> =>\r\n    {\r\n        this.cancelFade();\r\n\r\n        return fade.call(this.device, eventEmitter, options);\r\n    };\r\n\r\n    /**\r\n     * @description Cancels the current fade action\r\n     * \r\n     * @param rejectPromises Reject active fade promise\r\n     */\r\n    cancelFade = (rejectPromises: boolean = false) => this.device.emit(\"fadeCancel\", rejectPromises);\r\n\r\n    /**\r\n     * @description\r\n     * Turn off a device.\r\n     */\r\n    setOff = (): Promise<void> => setOff.call(this.device);\r\n\r\n    /**\r\n     * @description\r\n     * Turn on a device.\r\n     */\r\n    setOn = (): Promise<void> => setOn.call(this.device);\r\n}\r\n\r\nclass GoveeConfig\r\n{\r\n    /**\r\n     * Automatically start searching for devices when the UDP socket is made.\r\n     * @default true\r\n     */\r\n    startDiscover?: boolean = true;\r\n    /**\r\n     * The interval (in ms) at which new devices will be scanned for.\r\n     * @default 60000 (1 minute)\r\n     */\r\n    discoverInterval?: number = 60000;\r\n}\r\n\r\n//  TODO: I have no idea why i have to define the variables outside the class. But when they're inside the class, they're always undefined outside of the constructor.\r\n//? Edit: I do see it now (anonymous functions), but i haven't changed it yet.\r\nvar deviceList = new Map<string, Device>();\r\nvar eventEmitter: EventEmitter;\r\nvar udpSocket: Socket;\r\n\r\nclass Govee extends EventEmitter\r\n{\r\n    private config?: GoveeConfig;\r\n    private isReady = false;\r\n    constructor(config?: GoveeConfig)\r\n    {\r\n        super();\r\n        eventEmitter = this;\r\n        this.config = config;\r\n\r\n        this.getSocket().then(() =>\r\n        {\r\n            this.emit(\"ready\");\r\n            this.isReady = true;\r\n        });\r\n\r\n        var discoverInterval = 60_000;\r\n\r\n        if (config && config.discoverInterval)\r\n        {\r\n            discoverInterval = config.discoverInterval;\r\n        }\r\n\r\n        this.once(\"ready\", () =>\r\n        {\r\n            this.discoverInterval = setInterval(() =>\r\n            {\r\n                this.discover();\r\n            }, discoverInterval);\r\n        });\r\n    }\r\n\r\n    private discoverInterval: NodeJS.Timer;\r\n\r\n    private getSocket = (): Promise<void> =>\r\n    {\r\n        return new Promise<void>((resolve, reject) =>\r\n        {\r\n            getSocket().then(async (socket) =>\r\n            {\r\n                if (!socket)\r\n                {\r\n                    console.error(\"UDP Socket was not estabilished whilst trying to discover new devices.\\n\\nIs the server able to access UDP port 4001 and 4002 on address 239.255.255.250?\");\r\n                    var whileSocket = undefined;\r\n                    while (whileSocket == undefined)\r\n                    {\r\n                        whileSocket = await getSocket();\r\n                        if (whileSocket == undefined)\r\n                        {\r\n                            console.error(\"UDP Socket was not estabilished whilst trying to discover new devices.\\n\\nIs the server able to access UDP port 4001 and 4002 on address 239.255.255.250?\");\r\n                        }\r\n                    }\r\n                    udpSocket = whileSocket;\r\n                } else\r\n                {\r\n                    udpSocket = socket;\r\n                }\r\n\r\n                udpSocket.on(\"message\", this.receiveMessage);\r\n\r\n                //? Now that we have a socket, we can scan (again)\r\n                //TODO: Creating the socket and scanning can probably combined into 1, but i don't want to risk it, seeing as i have 1 govee device\r\n                if (!this.config || this.config.startDiscover)\r\n                {\r\n                    this.discover();\r\n                }\r\n                if (!this.isReady)\r\n                {\r\n                    this.emit(\"ready\");\r\n                    this.isReady = true;\r\n                }\r\n                resolve();\r\n            });\r\n        });\r\n    };\r\n\r\n\r\n    /**\r\n     * @description\r\n     * Use this function to re-send the command to scan for devices.\r\n     * \r\n     * Note that you typically don't have to run this command yourself. \r\n     */\r\n    public discover = () =>\r\n    {\r\n        if (!udpSocket)\r\n        {\r\n            console.error(\"UDP Socket was not estabilished whilst trying to discover new devices.\\n\\nIs the server able to access UDP port 4001 and 4002 on address 239.255.255.250?\");\r\n            return;\r\n        }\r\n        let message = JSON.stringify(\r\n            {\r\n                \"msg\": {\r\n                    \"cmd\": \"scan\",\r\n                    \"data\": {\r\n                        \"account_topic\": \"reserve\",\r\n                    }\r\n                }\r\n            }\r\n        );\r\n        udpSocket.send(message, 0, message.length, 4001, \"239.255.255.250\");\r\n        deviceList.forEach((dev) =>\r\n        {\r\n            udpSocket.send(message, 0, message.length, 4003, dev.ip);\r\n            this.discoverTimes[dev.ip] ||= 0;\r\n            this.discoverTimes[dev.ip]++;\r\n\r\n            if (this.discoverTimes[dev.ip] >= 5)\r\n            {\r\n                eventEmitter.emit(\"deviceRemoved\", dev);\r\n                dev.destroy();\r\n                deviceList.delete(dev.ip);\r\n            }\r\n        });\r\n    };\r\n\r\n    private discoverTimes: Map<string, number> = new Map();\r\n\r\n    private receiveMessage = async (msg: Buffer, rinfo: RemoteInfo) =>\r\n    {\r\n        var msgRes: messageResponse = JSON.parse(msg.toString());\r\n        if (!udpSocket)\r\n        {\r\n            return;\r\n        }\r\n        var data = msgRes.msg.data;\r\n        switch (msgRes.msg.cmd)\r\n        {\r\n            case \"scan\":\r\n                var oldList = Array.from(deviceList.values());\r\n                if (!deviceList.has(data.ip))\r\n                {\r\n                    var device = new Device(data, this, udpSocket);\r\n                    device.updateValues();\r\n                }\r\n                this.discoverTimes[data.ip] = 0;\r\n                oldList.forEach((device) =>\r\n                {\r\n                    if (!deviceList.has(device.ip))\r\n                    {\r\n                        eventEmitter.emit(\"deviceRemoved\", device);\r\n                        device.destroy();\r\n                        deviceList.delete(device.ip);\r\n                    }\r\n                });\r\n                break;\r\n\r\n            case \"devStatus\":\r\n                var device = deviceList.get(rinfo.address);\r\n\r\n                var oldState = JSON.parse(JSON.stringify(device.state));\r\n                device.state.brightness = data.brightness;\r\n                device.state.isOn = data.onOff;\r\n                device.state.color = data.color;\r\n\r\n                if (!data.color.colorTemInKelvin)\r\n                {\r\n                    device.state.colorKelvin = ct.rgb2colorTemperature({ red: data.color.r, green: data.color.g, blue: data.color.b });\r\n                } else\r\n                {\r\n                    device.state.colorKelvin = data.color.colorTemInKelvin;\r\n                }\r\n\r\n                var stateChanged: stateChangedOptions = [];\r\n                var colorChanged = oldState.color.r !== data.color.r || oldState.color.g !== data.color.g || oldState.color.b !== data.color.b;\r\n                var brightnessChanged = oldState.brightness !== data.brightness;\r\n                var onOffChanged = oldState.isOn !== data.onOff;\r\n\r\n                //* This may seem like a weird way of doing things, but i want to first get the full state of the device, then i can say it has been added\r\n                if (!device.state.hasReceivedUpdates)\r\n                {\r\n                    device.state.hasReceivedUpdates = true;\r\n                    eventEmitter.emit(\"deviceAdded\", device);\r\n                }\r\n\r\n                if (brightnessChanged)\r\n                {\r\n                    stateChanged.push(\"brightness\");\r\n                }\r\n                if (colorChanged)\r\n                {\r\n                    stateChanged.push(\"color\");\r\n                }\r\n                if (onOffChanged)\r\n                {\r\n                    stateChanged.push(\"onOff\");\r\n                }\r\n                device.emit(\"updatedStatus\", device.state, stateChanged as stateChangedOptions);\r\n                // eventEmitter.emit(\"updatedStatus\", device, device.state, stateChanged);\r\n                break;\r\n\r\n            default:\r\n                break;\r\n        }\r\n    };\r\n\r\n\r\n    /**\r\n     * A map of devices where the devices' IP is the key, and the Device object is the value.\r\n     */\r\n    public get devicesMap (): Map<string, Device>\r\n    {\r\n        return deviceList;\r\n    }\r\n    /**\r\n     * An array of all devices.\r\n     */\r\n    public get devicesArray (): Device[]\r\n    {\r\n        return Array.from(deviceList.values());\r\n    }\r\n\r\n    /**\r\n     * Retrieve the values of all devices.\r\n     */\r\n    public async updateAllDevices ()\r\n    {\r\n        const updatePromises = this.devicesArray.map((device) => device.updateValues);\r\n        await Promise.all(updatePromises);\r\n        return;\r\n    }\r\n\r\n    public destroy ()\r\n    {\r\n        eventEmitter.removeAllListeners();\r\n        deviceList = new Map<string, Device>();\r\n        eventEmitter = undefined;\r\n        udpSocket.close();\r\n        udpSocket = undefined;\r\n        clearInterval(this.discoverInterval);\r\n        //? Loop over all devices and clear their timeouts\r\n        deviceList.forEach((device) =>\r\n        {\r\n            device.destroy();\r\n        });\r\n    }\r\n}\r\n\r\nexport default Govee;\r\n\r\ninterface messageResponse\r\n{\r\n    msg: {\r\n        cmd: \"devStatus\" | \"scan\",\r\n        data: Record<string, any>;\r\n    };\r\n}\r\n\r\nexport interface DataResponseStatus\r\n{\r\n    onOff: 0 | 1;\r\n    brightness: number;\r\n    color: {\r\n        r: number;\r\n        g: number;\r\n        b: number;\r\n    };\r\n    colorTemInKelvin: number;\r\n}\r\n\r\nexport type stateChangedOptions = (\"onOff\" | \"brightness\" | \"color\" | undefined)[];\r\n\r\nexport interface fadeOptions\r\n{\r\n    time: number;\r\n    color?: colorOptions;\r\n    brightness?: number;\r\n}\r\n\r\ninterface colorOptionsHex\r\n{\r\n    hex: string;\r\n    rgb?: never;\r\n    hsl?: never;\r\n    kelvin?: never;\r\n}\r\ninterface colorOptionsRGB\r\n{\r\n    hex?: never;\r\n    rgb: [number, number, number];\r\n    hsl?: never;\r\n    kelvin?: never;\r\n}\r\ninterface colorOptionsHSL\r\n{\r\n    hex?: never;\r\n    rgb?: never;\r\n    hsl: [number, number, number];\r\n    kelvin?: never;\r\n}\r\ninterface colorOptionsKelvin\r\n{\r\n    hex?: never;\r\n    rgb?: never;\r\n    hsl?: never;\r\n    kelvin: string | number;\r\n}\r\nexport type colorOptions = colorOptionsHex | colorOptionsRGB | colorOptionsHSL | colorOptionsKelvin;\r\n\r\n\r\ntype DeviceEventTypes =\r\n    {\r\n        updatedStatus: (data: DeviceState, stateChanged: stateChangedOptions) => void;\r\n        fadeCancel: (rejectPromises: boolean) => void;\r\n        destroyed: () => void;\r\n    };\r\n\r\nexport declare interface Device\r\n{\r\n    addListener<E extends keyof DeviceEventTypes> (event: E, listener: DeviceEventTypes[E]): this;\r\n    on<E extends keyof DeviceEventTypes> (event: E, listener: DeviceEventTypes[E]): this;\r\n    once<E extends keyof DeviceEventTypes> (event: E, listener: DeviceEventTypes[E]): this;\r\n    prependListener<E extends keyof DeviceEventTypes> (event: E, listener: DeviceEventTypes[E]): this;\r\n    prependOnceListener<E extends keyof DeviceEventTypes> (event: E, listener: DeviceEventTypes[E]): this;\r\n\r\n    off<E extends keyof DeviceEventTypes> (event: E, listener: DeviceEventTypes[E]): this;\r\n    removeAllListeners<E extends keyof DeviceEventTypes> (event?: E): this;\r\n    removeListener<E extends keyof DeviceEventTypes> (event: E, listener: DeviceEventTypes[E]): this;\r\n\r\n    emit<E extends keyof DeviceEventTypes> (event: E, ...args: Parameters<DeviceEventTypes[E]>): boolean;\r\n    // The sloppy `eventNames()` return type is to mitigate type incompatibilities - see #5\r\n    eventNames (): (keyof DeviceEventTypes | string | symbol)[];\r\n    rawListeners<E extends keyof DeviceEventTypes> (event: E): DeviceEventTypes[E][];\r\n    listeners<E extends keyof DeviceEventTypes> (event: E): DeviceEventTypes[E][];\r\n    listenerCount<E extends keyof DeviceEventTypes> (event: E): number;\r\n\r\n    getMaxListeners (): number;\r\n    setMaxListeners (maxListeners: number): this;\r\n}\r\n\r\ntype GoveeEventTypes = {\r\n    ready: () => void;\r\n    deviceAdded: (device: Device) => void;\r\n    deviceRemoved: (device: Device) => void;\r\n    updatedStatus: (device: Device, data: DeviceState, stateChanged: stateChangedOptions) => void;\r\n};\r\n\r\ninterface Govee\r\n{\r\n    addListener<E extends keyof GoveeEventTypes> (event: E, listener: GoveeEventTypes[E]): this;\r\n    on<E extends keyof GoveeEventTypes> (event: E, listener: GoveeEventTypes[E]): this;\r\n    once<E extends keyof GoveeEventTypes> (event: E, listener: GoveeEventTypes[E]): this;\r\n    prependListener<E extends keyof GoveeEventTypes> (event: E, listener: GoveeEventTypes[E]): this;\r\n    prependOnceListener<E extends keyof GoveeEventTypes> (event: E, listener: GoveeEventTypes[E]): this;\r\n\r\n    off<E extends keyof GoveeEventTypes> (event: E, listener: GoveeEventTypes[E]): this;\r\n    removeAllListeners<E extends keyof GoveeEventTypes> (event?: E): this;\r\n    removeListener<E extends keyof GoveeEventTypes> (event: E, listener: GoveeEventTypes[E]): this;\r\n\r\n    emit<E extends keyof GoveeEventTypes> (event: E, ...args: Parameters<GoveeEventTypes[E]>): boolean;\r\n    // The sloppy `eventNames()` return type is to mitigate type incompatibilities - see #5\r\n    eventNames (): (keyof GoveeEventTypes | string | symbol)[];\r\n    rawListeners<E extends keyof GoveeEventTypes> (event: E): GoveeEventTypes[E][];\r\n    listeners<E extends keyof GoveeEventTypes> (event: E): GoveeEventTypes[E][];\r\n    listenerCount<E extends keyof GoveeEventTypes> (event: E): number;\r\n\r\n    getMaxListeners (): number;\r\n    setMaxListeners (maxListeners: number): this;\r\n}","import Govee, { colorOptions, DataResponseStatus, Device, fadeOptions, stateChangedOptions } from \"..\";\r\nimport { hex, hsl, rgb } from \"color-convert\";\r\nimport * as ct from 'color-temperature';\r\n\r\n/**\r\n * \r\n * @param x Starting number\r\n * @param y Ending number\r\n * @param a percent (0-1)\r\n */\r\nconst lerp = (x: number, y: number, a: number) => x * (1 - a) + y * a;\r\n/**\r\n * \r\n * @param a Starting number\r\n * @param b Ending number\r\n * @param amount percent (0-1)\r\n */\r\nfunction lerpColor (a: string, b: string, amount: number)\r\n{\r\n\r\n    var ah = parseInt(a.replace(/#/g, ''), 16),\r\n        ar = ah >> 16, ag = ah >> 8 & 0xff, ab = ah & 0xff,\r\n        bh = parseInt(b.replace(/#/g, ''), 16),\r\n        br = bh >> 16, bg = bh >> 8 & 0xff, bb = bh & 0xff,\r\n        rr = ar + amount * (br - ar),\r\n        rg = ag + amount * (bg - ag),\r\n        rb = ab + amount * (bb - ab);\r\n\r\n    return '#' + ((1 << 24) + (rr << 16) + (rg << 8) + rb | 0).toString(16).slice(1);\r\n}\r\n\r\n/**\r\n * Returns a bezier interpolated value, using the given ranges\r\n * @param {number} value  Value to be interpolated\r\n * @param {number} s1 Source range start\r\n * @param {number} s2  Source range end\r\n * @param {number} t1  Target range start\r\n * @param {number} t2  Target range end\r\n * @param {number} [slope]  Weight of the curve (0.5 = linear, 0.1 = weighted near target start, 0.9 = weighted near target end)\r\n * @returns {number} Interpolated value\r\n */\r\nvar interpolate = function (value: number, s1: number, s2: number, t1: any, t2: any, slope: number)\r\n{\r\n    //Default to linear interpolation\r\n    slope = slope || 0.5;\r\n\r\n    //If the value is out of the source range, floor to min/max target values\r\n    if (value < Math.min(s1, s2))\r\n    {\r\n        return Math.min(s1, s2) === s1 ? t1 : t2;\r\n    }\r\n\r\n    if (value > Math.max(s1, s2))\r\n    {\r\n        return Math.max(s1, s2) === s1 ? t1 : t2;\r\n    }\r\n\r\n    //Reverse the value, to make it correspond to the target range (this is a side-effect of the bezier calculation)\r\n    value = s2 - value;\r\n\r\n    var C1 = { x: s1, y: t1 }; //Start of bezier curve\r\n    var C3 = { x: s2, y: t2 }; //End of bezier curve\r\n    var C2 = {              //Control point\r\n        x: C3.x,\r\n        y: C1.y + Math.abs(slope) * (C3.y - C1.y)\r\n    };\r\n\r\n    //Find out how far the value is on the curve\r\n    var percent = value / (C3.x - C1.x);\r\n\r\n    return C1.y * b1(percent) + C2.y * b2(percent) + C3.y * b3(percent);\r\n\r\n    function b1 (t: number) { return t * t; }\r\n    function b2 (t: number) { return 2 * t * (1 - t); }\r\n    function b3 (t: number) { return (1 - t) * (1 - t); }\r\n};\r\n\r\n/**\r\n * @description\r\n * Set the color of a light.\r\n */\r\nexport function setColor (this: Device, options: colorOptions): Promise<void>\r\n{\r\n    var device = this;\r\n    return new Promise((resolve, reject) =>\r\n    {\r\n        var rgb = { r: 0, g: 0, b: 0 };\r\n        var message: string;\r\n\r\n        if (options.kelvin)\r\n        {\r\n            var kelvin = parseFloat(options.kelvin.toString().replace(/[^0-9]/g, \"\"));\r\n\r\n            message = JSON.stringify(\r\n                {\r\n                    msg: {\r\n                        cmd: \"colorwc\",\r\n                        data: {\r\n                            colorTemInKelvin: kelvin\r\n                        }\r\n                    }\r\n                }\r\n            );\r\n        } else\r\n        {\r\n            if (options.hex !== undefined)\r\n            {\r\n                var newColor = hex.rgb(options.hex);\r\n                rgb = {\r\n                    r: newColor[0],\r\n                    g: newColor[1],\r\n                    b: newColor[2]\r\n                };\r\n            } else if (options.hsl !== undefined)\r\n            {\r\n                var newColor = hsl.rgb(options.hsl);\r\n                rgb = {\r\n                    r: newColor[0],\r\n                    g: newColor[1],\r\n                    b: newColor[2]\r\n                };\r\n            } else if (options.rgb !== undefined)\r\n            {\r\n                rgb = {\r\n                    r: options.rgb[0],\r\n                    g: options.rgb[1],\r\n                    b: options.rgb[2]\r\n                };\r\n            }\r\n\r\n            message = JSON.stringify(\r\n                {\r\n                    msg: {\r\n                        cmd: \"colorwc\",\r\n                        data: {\r\n                            color: rgb\r\n                        }\r\n                    }\r\n                }\r\n            );\r\n        }\r\n\r\n        //! Commands have to be send twice te be caught by devstatus... annoying\r\n        // device.socket?.send(message, 0, message.length, 4001, device.ip, () =>\r\n        // {\r\n            device.socket?.send(message, 0, message.length, 4003, device.ip, async () =>\r\n            {\r\n                if (rgb)\r\n                {\r\n                    device.state.color = rgb;\r\n                    device.state.colorKelvin = ct.rgb2colorTemperature({ red: rgb.r, green: rgb.g, blue: rgb.b });\r\n                } else if (kelvin)\r\n                {\r\n                    var rgbColor = ct.colorTemperature2rgb(kelvin);\r\n                    device.state.color = { r: rgbColor.red, g: rgbColor.green, b: rgbColor.blue };\r\n                    device.state.colorKelvin = kelvin;\r\n                }\r\n                device.emit(\"updatedStatus\", device.state, [\"color\"])\r\n                resolve();\r\n                // await sleep(100)\r\n                // updateValues(device, false)\r\n            });\r\n        // });\r\n    });\r\n}\r\n\r\nexport function setBrightness (this: Device, brightness: number | string): Promise<void>\r\n{\r\n    return new Promise((resolve, reject) =>\r\n    {\r\n        var bright = Math.round(parseFloat(brightness.toString()) * 100) / 100;\r\n        let message = JSON.stringify(\r\n            {\r\n                \"msg\": {\r\n                    \"cmd\": \"brightness\",\r\n                    \"data\": {\r\n                        \"value\": bright,\r\n                    }\r\n                }\r\n            }\r\n        );\r\n        //! Commands have to be send twice te be caught by devstatus... annoying\r\n        // this.socket?.send(message, 0, message.length, 4001, this.ip, ()=>{\r\n            this.socket?.send(message, 0, message.length, 4003, this.ip, async () =>\r\n            {\r\n                this.state.brightness = bright;\r\n                resolve();\r\n                await sleep(100)\r\n                this.emit(\"updatedStatus\", this.state, [\"brightness\"])\r\n                // updateValues(this, false)\r\n            });\r\n        // });\r\n    });\r\n}\r\n\r\nexport function fade (this: Device, eventEmitter: Govee, options: fadeOptions): Promise<void>\r\n{\r\n    return new Promise(async (resolve, reject) =>\r\n    {\r\n        var device = this;\r\n        //? Get current value\r\n        await updateValues(device);\r\n        await sleep(100);\r\n\r\n        var curHex = rgb.hex(device.state.color.r, device.state.color.g, device.state.color.b);\r\n        var curKelvin = ct.rgb2colorTemperature({ red: device.state.color.r, green: device.state.color.g, blue: device.state.color.b });\r\n        var curBrightness = device.state.isOn == 1 ? device.state.brightness : 1;\r\n        var targetKelvin: number;\r\n        var targetBright = options.brightness;\r\n\r\n        if (options.color?.kelvin)\r\n        {\r\n            targetKelvin = parseFloat(options.color.kelvin.toString().replace(/[^0-9]/g, \"\"));\r\n        }\r\n\r\n        var changeColor = options.color?.hex !== undefined || options.color?.hsl !== undefined || options.color?.rgb !== undefined;\r\n\r\n        var startTime = Date.now();\r\n\r\n        var newColor = \"\";\r\n        if (options.color?.hsl !== undefined)\r\n            newColor = hsl.hex(options.color.hsl);\r\n        else if (options.color?.rgb !== undefined)\r\n            newColor = rgb.hex(options.color.rgb);\r\n        else if (options.color?.hex !== undefined)\r\n            newColor = options.color.hex.replace(/#/g, '');\r\n\r\n        async function stepBrightness (percent: number)\r\n        {\r\n            var newBright = lerp(curBrightness, targetBright, Math.max(Math.min(percent, 1), 0));\r\n            device.actions.setBrightness(newBright);\r\n        }\r\n\r\n        async function stepColor (percent: number, newColor: string)\r\n        {\r\n            var lerpedColor = lerpColor(curHex, newColor, Math.max(Math.min(percent, 1), 0));\r\n\r\n            device.actions.setColor({ hex: \"#\" + lerpedColor });\r\n        }\r\n\r\n        async function stepKelvin (percent: number, targetKelvin: number)\r\n        {\r\n            var lerpedKelvin = lerp(curKelvin, targetKelvin, Math.max(Math.min(percent, 1), 0));\r\n            var kelvinRGB = ct.colorTemperature2rgb(lerpedKelvin);\r\n\r\n            device.actions.setColor({ rgb: [kelvinRGB.red, kelvinRGB.green, kelvinRGB.blue] });\r\n        }\r\n\r\n        // Start loop\r\n        var running = true;\r\n        \r\n        var fadeEndTimeout = setTimeout(async () =>\r\n        {\r\n            running = false;\r\n            this.removeListener(\"fadeCancel\", fadeCancelHandler)\r\n            if (changeColor)\r\n            {\r\n                setColor.call(device, {\r\n                    hex: newColor\r\n                });\r\n            } else if (targetKelvin)\r\n            {\r\n                var kelvinRGB = ct.colorTemperature2rgb(targetKelvin);\r\n                await device.actions.setColor({ rgb: [kelvinRGB.red, kelvinRGB.green, kelvinRGB.blue] });\r\n            }\r\n            if (options.brightness !== undefined)\r\n            {\r\n                device.actions.setBrightness(targetBright);\r\n            }\r\n\r\n            await sleep(50);\r\n            await device.updateValues();\r\n            var updatedValues: stateChangedOptions = []\r\n            if (curBrightness !== targetBright) {\r\n                updatedValues.push(\"brightness\")\r\n            }\r\n            if (changeColor) {\r\n                updatedValues.push(\"color\")\r\n            }\r\n            device.emit(\"updatedStatus\", device.state, updatedValues)\r\n            resolve();\r\n        }, options.time - 100);\r\n\r\n        // Respond to fade cancel\r\n        function fadeCancelHandler(rejectPromise) {\r\n            running = false\r\n            clearTimeout(fadeEndTimeout);\r\n\r\n            if (rejectPromise) {\r\n                reject(\"Fade got cancelled\")\r\n            }else{\r\n                resolve();\r\n            }\r\n        }\r\n        this.once(\"fadeCancel\", fadeCancelHandler)\r\n\r\n        while (running == true)\r\n        {\r\n            var startLoopTime = Date.now();\r\n            var percent = interpolate((Date.now() - startTime) / (options.time - 100), 0, 1, 0, 1, 0.5);\r\n            // Color step\r\n            if (changeColor)\r\n            {\r\n                stepColor(percent, newColor);\r\n            }\r\n\r\n            // Kelvin step\r\n            if (options.color && options.color.kelvin !== undefined)\r\n            {\r\n                stepKelvin(percent, targetKelvin);\r\n            }\r\n\r\n            // Brightness step\r\n            if (options.brightness !== undefined)\r\n            {\r\n                stepBrightness(percent);\r\n            }\r\n            await sleep(30 - (Date.now() - startLoopTime));\r\n        }\r\n    });\r\n}\r\n\r\nfunction sleep (ms: number): Promise<void>\r\n{\r\n    return new Promise((resolve, reject) =>\r\n    {\r\n        setTimeout(() =>\r\n        {\r\n            resolve();\r\n        }, ms);\r\n    });\r\n}\r\n\r\nexport function updateValues (device?: Device, updateAll?: boolean)\r\n{\r\n    return new Promise<void>((resolve, reject) =>\r\n    {\r\n        let message = JSON.stringify(\r\n            {\r\n                \"msg\": {\r\n                    \"cmd\": \"devStatus\",\r\n                    \"data\": {}\r\n                }\r\n            }\r\n        );\r\n        if (!updateAll)\r\n        {\r\n            device.socket.send(message, 0, message.length, 4003, device.ip);\r\n            resolve();\r\n        } else\r\n        {\r\n            device.socket.send(message, 0, message.length, 4001, \"239.255.255.250\");\r\n            resolve();\r\n        }\r\n    });\r\n}","import { Device } from \"..\";\r\n\r\nexport function setOff (this: Device): Promise<void>\r\n{\r\n    var device = this;\r\n    return new Promise((resolve, reject) =>\r\n    {\r\n        let message = JSON.stringify(\r\n            {\r\n                msg: {\r\n                    cmd: \"turn\",\r\n                    data: {\r\n                        value: 0\r\n                    }\r\n                }\r\n            }\r\n        );\r\n        device.socket?.send(message, 0, message.length, 4003, device.ip, async () =>\r\n        {\r\n            device.state.isOn = 0;\r\n            device.emit(\"updatedStatus\", device.state, [\"onOff\"])\r\n            resolve();\r\n        });\r\n    });\r\n}\r\n\r\n/**\r\n * @description\r\n * Turn on a light.\r\n */\r\nexport function setOn (this: Device): Promise<void>\r\n{\r\n    var device = this;\r\n    return new Promise((resolve, reject) =>\r\n    {\r\n        let message = JSON.stringify(\r\n            {\r\n                msg: {\r\n                    cmd: \"turn\",\r\n                    data: {\r\n                        value: 1\r\n                    }\r\n                }\r\n            }\r\n        );\r\n        device.socket?.send(message, 0, message.length, 4003, device.ip, () =>\r\n        {\r\n            device.state.isOn = 1;\r\n            device.emit(\"updatedStatus\", device.state, [\"onOff\"])\r\n            resolve();\r\n        });\r\n    });\r\n}","import { createSocket, Socket } from 'node:dgram';\r\nimport { networkInterfaces } from 'os';\r\nconst address = '239.255.255.250';\r\nconst port = 4002;\r\n\r\n\r\n//? Loop over all network interfaces (that apply) to find one with Govee devices.\r\nexport default (): Promise<Socket> =>\r\n{\r\n    return new Promise((resolve, reject) =>\r\n    {\r\n        const nets = networkInterfaces();\r\n        var sockets: Socket[] = []\r\n        var isResolved = false\r\n\r\n        //* Modified from https://stackoverflow.com/a/8440736/11186759\r\n        for (const name of Object.keys(nets))\r\n        {\r\n            nets[name]?.forEach((net) =>\r\n            {\r\n                const familyV4Value = typeof net.family === 'string' ? 'IPv4' : 4;\r\n                if (net.family === familyV4Value && !net.internal)\r\n                {\r\n                    let socket = createSocket({\r\n                        type: 'udp4',\r\n                        reuseAddr: true // for testing multiple instances on localhost\r\n                    });\r\n                    sockets.push(socket)\r\n\r\n                    socket.once('message', (msg, remote) =>\r\n                    {\r\n                        resolve(socket);\r\n                        isResolved = true\r\n                    });\r\n\r\n\r\n                    socket.bind(port, net.address);\r\n\r\n                    socket.on(\"listening\", function ()\r\n                    {\r\n                        socket.setBroadcast(true);\r\n                        socket.setMulticastTTL(128);\r\n                        socket.addMembership(address);\r\n                        let message = JSON.stringify(\r\n                            {\r\n                                \"msg\": {\r\n                                    \"cmd\": \"scan\",\r\n                                    \"data\": {\r\n                                        \"account_topic\": \"reserve\",\r\n                                    }\r\n                                }\r\n                            }\r\n                        );\r\n                        socket.send(message, 0, message.length, 4001, address);\r\n                    });\r\n                }\r\n            });\r\n        }\r\n\r\n        setTimeout(() => {\r\n            if (isResolved == false) {\r\n                sockets.forEach((socket)=>{\r\n                    socket.close()\r\n                })\r\n                resolve(undefined)\r\n            }\r\n        }, 5000);\r\n    });\r\n};"]}