{"version":3,"sources":["jsdelivr-header.js","/npm/iobroker.procon-ip@1.7.0/src/main.ts"],"names":[],"mappings":"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","file":"/npm/iobroker.procon-ip@1.7.0/build/main.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/iobroker.procon-ip@1.7.0/build/main.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 { Adapter, AdapterOptions } from '@iobroker/adapter-core';\nimport {\n    IServiceConfig,\n    IGetStateServiceConfig,\n    GetStateDataSysInfo,\n    GetStateDataObject,\n    CommandService,\n    GetStateService,\n    UsrcfgCgiService,\n    RelayDataInterpreter,\n    GetStateCategory,\n    GetStateData,\n    SetStateService,\n} from 'procon-ip';\n\n// Augment the adapter.config object with the actual types\ndeclare global {\n    // eslint-disable-next-line @typescript-eslint/no-namespace\n    namespace ioBroker {\n        interface AdapterConfig {\n            controllerUrl: string;\n            basicAuth: boolean;\n            username: string;\n            password: string;\n            updateInterval: number;\n            requestTimeout: number;\n            errorTolerance: number;\n        }\n    }\n}\n\nclass ProconIp extends Adapter {\n    private _relayDataInterpreter!: RelayDataInterpreter;\n    private _getStateService!: GetStateService;\n    private _setStateService!: SetStateService;\n    private _usrcfgCgiService!: UsrcfgCgiService;\n    private _commandService!: CommandService;\n    private _forceUpdate: number[];\n    private _stateData: GetStateData;\n    private _bootstrapped = false;\n    private _objectStateFields = ['value', 'category', 'label', 'unit', 'displayValue', 'active'];\n    private _timeout: NodeJS.Timeout | null = null;\n\n    public constructor(options: Partial<AdapterOptions> = {}) {\n        super({\n            ...options,\n            name: 'procon-ip',\n        });\n        this.on('ready', this.onReady.bind(this));\n        this.on('unload', this.onUnload.bind(this));\n        this.on('stateChange', this.onStateChange.bind(this));\n        this._forceUpdate = new Array<number>();\n        this._stateData = new GetStateData();\n    }\n\n    /**\n     * Is called when databases are connected and adapter received configuration.\n     */\n    private async onReady(): Promise<void> {\n        let connectionApproved = false;\n        await this.setState('info.connection', false, true);\n\n        if (this.config.controllerUrl.length < 1 || !ProconIp.isValidURL(this.config.controllerUrl)) {\n            this.log.warn(`Invalid controller URL ('${this.config.controllerUrl}') supplied.`);\n            return;\n        }\n\n        const serviceConfig = Object.defineProperties(Object.create(this.config), {\n            baseUrl: {\n                value: this.config.controllerUrl,\n                writable: true,\n            },\n            timeout: {\n                value: this.config.requestTimeout,\n                writable: true,\n            },\n        }) as IServiceConfig;\n        this._relayDataInterpreter = new RelayDataInterpreter(this.log);\n        this._getStateService = new GetStateService(serviceConfig as IGetStateServiceConfig, this.log);\n        this._setStateService = new SetStateService(serviceConfig, this.log);\n        this._usrcfgCgiService = new UsrcfgCgiService(\n            serviceConfig,\n            this.log,\n            this._getStateService,\n            this._relayDataInterpreter,\n        );\n        this._commandService = new CommandService(serviceConfig, this.log);\n\n        this.log.debug(`GetStateService url: ${this._getStateService.url}`);\n        this.log.debug(`UsrcfgCgiService url: ${this._usrcfgCgiService.url}`);\n\n        await this._getStateService.update().then(async data => {\n            this._stateData = data;\n\n            // Set objects once on startup\n            if (!this._bootstrapped) {\n                this.log.debug(`Initially setting adapter objects`);\n                await this.setSysInfoObjectsNotExists(data.sysInfo);\n                await this.setStateDataObjectsNotExists(data.objects);\n            }\n        });\n\n        this._timeout = setTimeout(() => {\n            // Start the actual service\n            this._getStateService.start(\n                (data: GetStateData) => {\n                    this.log.silly(`Start processing new GetState.csv`);\n                    connectionApproved = true;\n\n                    // Set sys info states\n                    data.sysInfo.toArrayOfObjects().forEach(info => {\n                        // Only update when value has changed\n                        if (!this._bootstrapped || info.value !== this._stateData.sysInfo[info.key]) {\n                            this.log.debug(`Updating sys info state ${info.key}: ${info.value}`);\n                            this.setStateAsync(\n                                `${this.name}.${this.instance}.info.system.${info.key}`,\n                                info.value.toString(),\n                                true,\n                            ).catch(e => {\n                                this.log.error(`Failed setting state for '${info.key}': ${e}`);\n                            });\n                        }\n                    });\n\n                    this.updateAdvancedSysInfoStates(data.sysInfo);\n\n                    // Set actual sensor and actor/relay object states\n                    data.objects.forEach(obj => {\n                        this.log.silly(\n                            `Comparing previous and current value (${obj.displayValue}) for '${obj.label}' (${obj.category})`,\n                        );\n                        this.log.silly(\n                            `this._stateData.getDataObject(obj.id).value: ${\n                                this._stateData.getDataObject(obj.id).value\n                            }`,\n                        );\n                        this.log.silly(`obj.value: ${obj.value}`);\n\n                        // Only update when value has changed or update is forced (on state change)\n                        const forceObjStateUpdate = this._forceUpdate.indexOf(obj.id);\n                        if (\n                            !this._bootstrapped ||\n                            forceObjStateUpdate >= 0 ||\n                            (this._stateData.getDataObject(obj.id) &&\n                                this._stateData.getDataObject(obj.id).value != obj.value)\n                        ) {\n                            if (this._stateData.getDataObject(obj.id).label != obj.label) {\n                                this.log.debug(`Updating label for '${obj.label}' (${obj.category})`);\n                                this.updateObjectCommonName(obj).catch((e: unknown) => {\n                                    if (e instanceof Error) {\n                                        this.log.error(`Failed fixing label for '${obj.label}': ${e.message}`);\n                                    } else {\n                                        this.log.error(`Failed fixing label for '${obj.label}': ${String(e)}`);\n                                    }\n                                });\n                            }\n                            this.log.debug(`Updating value for '${obj.label}' (${obj.category})`);\n                            this.setDataState(obj);\n                            if (this._forceUpdate[forceObjStateUpdate]) {\n                                this._forceUpdate.splice(forceObjStateUpdate, 1);\n                            }\n                        }\n                    });\n\n                    this.log.silly(`Updating data object for next comparison`);\n                    this._stateData = data;\n                    this._bootstrapped = true;\n                    this.setState('info.connection', true, true).catch(() => {});\n                },\n                (e: unknown) => {\n                    this.setState('info.connection', false, true).catch(() => {});\n                    if (!connectionApproved) {\n                        if (e instanceof Error) {\n                            this.log.error(`Could not connect to the controller: ${e.message}`);\n                        } else {\n                            this.log.error(`Could not connect to the controller: ${String(e)}`);\n                        }\n                        this._getStateService?.stop();\n                    }\n                },\n            );\n        }, 300);\n\n        this.subscribeStates(`${this.name}.${this.instance}.relays.*`);\n        this.subscribeStates(`${this.name}.${this.instance}.externalRelays.*`);\n    }\n\n    // Is called when adapter shuts down - callback has to be called under any circumstances!\n    private onUnload(callback: () => void): void {\n        try {\n            // Stop the service loop (this also handles the info.connection state)\n            this._getStateService?.stop();\n            this.setState('info.connection', false, true).catch(() => {});\n        } catch (e: unknown) {\n            this.log.error(`Failed to stop GetState service: ${String(e)}`);\n        } finally {\n            if (this._timeout) {\n                clearTimeout(this._timeout);\n            }\n            callback();\n        }\n    }\n\n    // Is called if a subscribed state changes\n    private onStateChange(id: string, state: ioBroker.State | null | undefined): void {\n        if (!state) {\n            // The state was deleted\n            this.log.info(`state ${id} deleted`);\n            return;\n        }\n        if (state.ack) {\n            // The state is already acknowledged -> no need to change anything\n            return;\n        }\n\n        if (id.endsWith('.auto')) {\n            this.relayToggleAuto(id, state).catch(e => {\n                this.log.error(`Error on relay toggle (${id}): ${e}`);\n            });\n        } else if (id.endsWith('.onOff')) {\n            this.relayToggleOnOff(id, state).catch(e => {\n                this.log.error(`Error on relay toggle (${id}): ${e}`);\n            });\n        } else if (id.endsWith('.dosageTimer')) {\n            this.setDosageTimer(id, state).catch(e => {\n                this.log.error(`Error on manual dosage (${id}): ${e}`);\n            });\n        } else if (id.endsWith('.timer')) {\n            this.setRelayTimer(id, state).catch(e => {\n                this.log.error(`Error on relay timer (${id}): ${e}`);\n            });\n        }\n    }\n\n    private async relayToggleAuto(objectId: string, state: ioBroker.State): Promise<number> {\n        const onOffState = await this.getStateAsync(objectId.replace(/\\.auto$/, '.onOff'));\n        if (!onOffState) {\n            throw new Error(`Cannot get onOff state to toggle '${objectId}'`);\n        }\n\n        const obj = await this.getObjectAsync(objectId);\n        if (!obj) {\n            throw new Error(`Cannot handle state change for non-existent object '${objectId}'`);\n        }\n\n        const getStateDataObject: GetStateDataObject = this._stateData.getDataObject(Number(obj.native.id));\n        this._forceUpdate.push(getStateDataObject.id);\n        try {\n            if (state.val) {\n                this.log.info(`Switching ${obj.native.label}: auto`);\n                return this._usrcfgCgiService.setAuto(getStateDataObject);\n            } else if (onOffState.val) {\n                this.log.info(`Switching ${obj.native.label}: on`);\n                return this._usrcfgCgiService.setOn(getStateDataObject);\n            }\n            this.log.info(`Switching ${obj.native.label}: off`);\n            return this._usrcfgCgiService.setOff(getStateDataObject);\n        } catch (e: unknown) {\n            if (e instanceof Error) {\n                this.log.error(`Error on switching operation: ${e.message}`);\n            } else {\n                this.log.error(`Error on switching operation: ${String(e)}`);\n            }\n\n            return -1;\n        }\n    }\n\n    private async relayToggleOnOff(objectId: string, state: ioBroker.State): Promise<void> {\n        const obj = await this.getObjectAsync(objectId);\n        if (!obj) {\n            throw new Error(`Cannot handle state change for non-existent object '${objectId}'`);\n        }\n\n        const getStateDataObject: GetStateDataObject = this._stateData.getDataObject(Number(obj.native.id));\n        this._forceUpdate.push(getStateDataObject.id);\n        try {\n            if (state.val) {\n                this.log.info(`Switching ${obj.native.label}: on`);\n                await this._usrcfgCgiService.setOn(getStateDataObject);\n            } else {\n                this.log.info(`Switching ${obj.native.label}: off`);\n                await this._usrcfgCgiService.setOff(getStateDataObject);\n            }\n        } catch (e: unknown) {\n            if (e instanceof Error) {\n                this.log.error(`Error on switching operation: ${e.message}`);\n            } else {\n                this.log.error(`Error on switching operation: ${String(e)}`);\n            }\n        }\n    }\n\n    private async setDosageTimer(objectId: string, state: ioBroker.State): Promise<void> {\n        const obj = await this.getObjectAsync(objectId);\n        if (!obj) {\n            throw new Error(`Cannot handle state change for non-existent object '${objectId}'`);\n        }\n\n        const getStateDataObject: GetStateDataObject = this._stateData.getDataObject(Number(obj.native.id));\n        const relayId =\n            getStateDataObject.categoryId +\n            (getStateDataObject.category === String(GetStateCategory.EXTERNAL_RELAYS) ? 8 : 0);\n        this._forceUpdate.push(getStateDataObject.id);\n        try {\n            const stateValNumber = state.val as number;\n            if (relayId === this._stateData.getChlorineDosageControlId()) {\n                await this._commandService.setChlorineDosage(stateValNumber);\n            } else if (relayId === this._stateData.getPhMinusDosageControlId()) {\n                await this._commandService.setPhMinusDosage(stateValNumber);\n            } else if (relayId === this._stateData.getPhPlusDosageControlId()) {\n                await this._commandService.setPhPlusDosage(stateValNumber);\n            }\n            this.log.info(`Setting dosage timer ${obj.native.label} for ${state.val} seconds`);\n        } catch (e: unknown) {\n            if (e instanceof Error) {\n                this.log.error(`Error setting dosage timer: ${e.message}`);\n            } else {\n                this.log.error(`Error setting dosage timer: ${String(e)}`);\n            }\n        }\n    }\n\n    private async setRelayTimer(objectId: string, state: ioBroker.State): Promise<void> {\n        const obj = await this.getObjectAsync(objectId);\n        if (!obj) {\n            throw new Error(`Cannot handle state change for non-existent object '${objectId}'`);\n        }\n\n        const getStateDataObject: GetStateDataObject = this._stateData.getDataObject(Number(obj.native.id));\n        const relayId =\n            getStateDataObject.categoryId +\n            (getStateDataObject.category === String(GetStateCategory.EXTERNAL_RELAYS) ? 9 : 1);\n        this._forceUpdate.push(getStateDataObject.id);\n        try {\n            const stateValNumber = state.val as number;\n            await this._setStateService.setTimer(relayId, stateValNumber);\n            this.log.info(`Setting timer for ${obj.native.label} to ${state.val} seconds`);\n        } catch (e: unknown) {\n            if (e instanceof Error) {\n                this.log.error(`Error setting relay timer: ${e.message}`);\n            } else {\n                this.log.error(`Error setting relay timer: ${String(e)}`);\n            }\n        }\n    }\n\n    private updateAdvancedSysInfoStates(sysInfo: GetStateDataSysInfo): void {\n        if (!this._bootstrapped || sysInfo.dosageControl !== this._stateData.sysInfo.dosageControl) {\n            this.log.debug('Updating advanced sys info states');\n            this.setStateAsync(\n                `${this.name}.${this.instance}.info.system.phPlusDosageEnabled`,\n                sysInfo.isPhPlusDosageEnabled(),\n                true,\n            ).catch(e => {\n                this.log.error(\n                    `Failed setting state for '${this.name}.${this.instance}.info.system.phPlusDosageEnabled': ${e}`,\n                );\n            });\n            this.setStateAsync(\n                `${this.name}.${this.instance}.info.system.phMinusDosageEnabled`,\n                sysInfo.isPhMinusDosageEnabled(),\n                true,\n            ).catch(e => {\n                this.log.error(\n                    `Failed setting state for '${this.name}.${this.instance}.info.system.phMinusDosageEnabled': ${e}`,\n                );\n            });\n            this.setStateAsync(\n                `${this.name}.${this.instance}.info.system.chlorineDosageEnabled`,\n                sysInfo.isChlorineDosageEnabled(),\n                true,\n            ).catch(e => {\n                this.log.error(\n                    `Failed setting state for '${this.name}.${this.instance}.info.system.chlorineDosageEnabled': ${e}`,\n                );\n            });\n            this.setStateAsync(\n                `${this.name}.${this.instance}.info.system.electrolysis`,\n                sysInfo.isElectrolysis(),\n                true,\n            ).catch(e => {\n                this.log.error(`Failed setting state for '${this.name}.${this.instance}.info.electrolysis': ${e}`);\n            });\n        }\n    }\n\n    private async setSysInfoObjectsNotExists(data: GetStateDataSysInfo): Promise<void> {\n        await this.setObjectNotExists(`${this.name}.${this.instance}.info.system`, {\n            type: 'channel',\n            common: {\n                name: 'SysInfo',\n            },\n            native: {},\n        });\n        for (const sysInfo of data.toArrayOfObjects()) {\n            await this.setObjectNotExists(`${this.name}.${this.instance}.info.system.${sysInfo.key}`, {\n                type: 'state',\n                common: {\n                    name: sysInfo.key,\n                    type: 'string',\n                    role: 'state',\n                    read: true,\n                    write: false,\n                },\n                native: {},\n            });\n        }\n\n        await this.setObjectNotExists(`${this.name}.${this.instance}.info.system.phPlusDosageEnabled`, {\n            type: 'state',\n            common: {\n                name: 'pH+ enabled',\n                type: 'boolean',\n                role: 'state',\n                read: true,\n                write: false,\n            },\n            native: {},\n        });\n\n        await this.setObjectNotExists(`${this.name}.${this.instance}.info.system.phMinusDosageEnabled`, {\n            type: 'state',\n            common: {\n                name: 'pH- enabled',\n                type: 'boolean',\n                role: 'state',\n                read: true,\n                write: false,\n            },\n            native: {},\n        });\n\n        await this.setObjectNotExists(`${this.name}.${this.instance}.info.system.chlorineDosageEnabled`, {\n            type: 'state',\n            common: {\n                name: 'CL enabled',\n                type: 'boolean',\n                role: 'state',\n                read: true,\n                write: false,\n            },\n            native: {},\n        });\n\n        await this.setObjectNotExists(`${this.name}.${this.instance}.info.system.electrolysis`, {\n            type: 'state',\n            common: {\n                name: 'Electrolysis',\n                type: 'boolean',\n                role: 'state',\n                read: true,\n                write: false,\n            },\n            native: {},\n        });\n    }\n\n    private async setStateDataObjectsNotExists(objects: GetStateDataObject[]): Promise<void> {\n        let lastObjCategory = '';\n        for (const obj of objects) {\n            if (lastObjCategory !== obj.category) {\n                await this.setObjectNotExists(`${this.name}.${this.instance}.${obj.category}`, {\n                    type: 'channel',\n                    common: {\n                        name: obj.category,\n                    },\n                    native: {},\n                });\n                lastObjCategory = obj.category;\n            }\n            this.setDataObjectNotExists(obj).catch(e => {\n                this.log.error(`Failed setting objects for '${obj.label}': ${e}`);\n            });\n        }\n    }\n\n    private async setDataObjectNotExists(obj: GetStateDataObject): Promise<void> {\n        await this.setObjectNotExists(`${this.name}.${this.instance}.${obj.category}.${obj.categoryId}`, {\n            type: 'channel',\n            common: {\n                name: obj.label,\n            },\n            native: {},\n        });\n        for (const field of Object.keys(obj)) {\n            const common = {\n                name: obj.label,\n                type: typeof obj[field],\n                role: 'value',\n                read: true,\n                write: false,\n            } as ioBroker.StateCommon;\n\n            switch (field) {\n                case 'value':\n                    if (obj.category == String(GetStateCategory.TEMPERATURES)) {\n                        common.role = 'value.temperature';\n                        common.unit = `°${obj.unit}`;\n                        if (obj.active) {\n                            common.smartName = {\n                                de: obj.label,\n                                en: obj.label,\n                                smartType: 'THERMOSTAT',\n                            };\n                        }\n                    }\n                    break;\n                case 'category':\n                case 'label':\n                case 'unit':\n                case 'displayValue':\n                    common.role = 'text';\n                    break;\n                case 'active':\n                    common.role = 'indicator';\n                    break;\n                default:\n                    continue;\n            }\n\n            try {\n                await this.setObjectNotExists(\n                    `${this.name}.${this.instance}.${obj.category}.${obj.categoryId}.${field}`,\n                    {\n                        type: 'state',\n                        common: common,\n                        native: obj,\n                    },\n                );\n            } catch (e: unknown) {\n                if (e instanceof Error) {\n                    this.log.error(`Failed setting object '${obj.label}': ${e.message}`);\n                } else {\n                    this.log.error(`Failed setting object '${obj.label}': ${String(e)}`);\n                }\n            }\n        }\n\n        if (\n            (obj.category as GetStateCategory) === GetStateCategory.RELAYS ||\n            ((obj.category as GetStateCategory) === GetStateCategory.EXTERNAL_RELAYS &&\n                this._stateData.sysInfo.isExtRelaysEnabled())\n        ) {\n            await this.setRelayDataObject(obj);\n        }\n    }\n\n    private async setRelayDataObject(obj: GetStateDataObject): Promise<void> {\n        const isLight = new RegExp('light|bulb|licht|leucht', 'i').test(obj.label);\n        const relayId = (obj.category === String(GetStateCategory.EXTERNAL_RELAYS) ? 8 : 0) + obj.categoryId;\n        const isDosageRelay = this._getStateService.data.isDosageControl(relayId);\n        const commonAuto = {\n            name: obj.label,\n            type: 'boolean',\n            role: 'switch.mode.auto',\n            read: true,\n            write: true,\n            smartName: obj.active\n                ? {\n                      de: `${obj.label} auto`,\n                      en: `${obj.label} auto`,\n                      smartType: isLight ? 'LIGHT' : 'SWITCH',\n                  }\n                : {},\n        } as ioBroker.StateCommon;\n        const commonOnOff = {\n            name: obj.label,\n            type: 'boolean',\n            role: isLight ? 'switch.light' : 'switch',\n            read: true,\n            write: !isDosageRelay,\n            smartName:\n                obj.active && !isDosageRelay\n                    ? {\n                          de: obj.label,\n                          en: obj.label,\n                          smartType: isLight ? 'LIGHT' : 'SWITCH',\n                      }\n                    : {},\n        } as ioBroker.StateCommon;\n\n        await this.setObjectNotExists(`${this.name}.${this.instance}.${obj.category}.${obj.categoryId}.auto`, {\n            type: 'state',\n            common: commonAuto,\n            native: obj,\n        });\n        await this.setObjectNotExists(`${this.name}.${this.instance}.${obj.category}.${obj.categoryId}.onOff`, {\n            type: 'state',\n            common: commonOnOff,\n            native: obj,\n        });\n\n        if (isDosageRelay) {\n            const commonDosageTimerState = {\n                name: obj.label,\n                type: 'number',\n                role: 'value.interval',\n                read: false,\n                write: true,\n            } as ioBroker.StateCommon;\n\n            await this.setObjectNotExists(\n                `${this.name}.${this.instance}.${obj.category}.${obj.categoryId}.dosageTimer`,\n                {\n                    type: 'state',\n                    common: commonDosageTimerState,\n                    native: obj,\n                },\n            );\n        } else {\n            const commonGenericRelayTimerState = {\n                name: obj.label,\n                type: 'number',\n                role: 'value.interval',\n                read: false,\n                write: true,\n            } as ioBroker.StateCommon;\n\n            await this.setObjectNotExists(`${this.name}.${this.instance}.${obj.category}.${obj.categoryId}.timer`, {\n                type: 'state',\n                common: commonGenericRelayTimerState,\n                native: obj,\n            });\n        }\n    }\n\n    private setDataState(obj: GetStateDataObject): void {\n        for (const field of Object.keys(obj).filter(field => this._objectStateFields.indexOf(field) > -1)) {\n            this.setState(\n                `${this.name}.${this.instance}.${obj.category}.${obj.categoryId}.${field}`,\n                obj[field] as ioBroker.StateValue,\n                true,\n            ).catch(e => {\n                this.log.error(`Failed setting state for '${obj.label}': ${e}`);\n            });\n        }\n\n        if (\n            (obj.category as GetStateCategory) === GetStateCategory.RELAYS ||\n            ((obj.category as GetStateCategory) === GetStateCategory.EXTERNAL_RELAYS &&\n                this._stateData.sysInfo.isExtRelaysEnabled())\n        ) {\n            this.setRelayDataState(obj);\n        }\n    }\n\n    private setRelayDataState(obj: GetStateDataObject): void {\n        this.setState(\n            `${this.name}.${this.instance}.${obj.category}.${obj.categoryId}.auto`,\n            this._relayDataInterpreter.isAuto(obj),\n            true,\n        ).catch(e => {\n            this.log.error(`Failed setting auto/manual switch state for '${obj.label}': ${e}`);\n        });\n        this.setState(\n            `${this.name}.${this.instance}.${obj.category}.${obj.categoryId}.onOff`,\n            this._relayDataInterpreter.isOn(obj),\n            true,\n        ).catch(e => {\n            this.log.error(`Failed setting onOff switch state for '${obj.label}': ${e}`);\n        });\n    }\n\n    private async updateObjectCommonName(obj: GetStateDataObject): Promise<void> {\n        const objId = `${this.name}.${this.instance}.${obj.category}.${obj.categoryId}`;\n        const ioObj = await this.getObjectAsync(objId);\n        if (ioObj) {\n            ioObj.common.name = obj.label;\n            await this.setObject(objId, ioObj);\n        }\n        const objStates = await this.getStatesOfAsync(objId);\n        if (objStates) {\n            for (const state of objStates) {\n                state.common.name = obj.label;\n                await this.setObject(state._id, state);\n            }\n        }\n    }\n\n    private static isValidURL(url: string): boolean {\n        try {\n            new URL(url);\n            return true;\n        } catch {\n            return false;\n        }\n    }\n}\n\nif (require.main !== module) {\n    // Export the constructor in compact mode\n    module.exports = (options: Partial<AdapterOptions> | undefined) => new ProconIp(options);\n} else {\n    // otherwise start the instance directly\n    (() => new ProconIp())();\n}\n"]}