{"version":3,"sources":["jsdelivr-header.js","/npm/homebridge-airgradient@2.3.3/dist/index.js"],"names":[],"mappings":"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","file":"/npm/homebridge-airgradient@2.3.3/dist/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/homebridge-airgradient@2.3.3/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","\"use strict\";\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n    return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nconst axios_1 = __importDefault(require(\"axios\"));\nlet hap;\nclass AirGradientPlatform {\n    constructor(log, config, api) {\n        // Keep a stable map of cached and newly-created accessories by UUID\n        this.accessories = new Map();\n        // Persist sensor configs to act on them after didFinishLaunching\n        this.sensorConfigs = [];\n        this.log = log;\n        this.api = api;\n        hap = api.hap;\n        if (Array.isArray(config === null || config === void 0 ? void 0 : config.sensors)) {\n            for (const sensorConfig of config.sensors) {\n                if (sensorConfig === null || sensorConfig === void 0 ? void 0 : sensorConfig.serialno) {\n                    this.sensorConfigs.push(sensorConfig);\n                    this.log.info('Queued sensor for init with serial number:', sensorConfig.serialno);\n                }\n            }\n        }\n        // Only manipulate accessories after Homebridge has finished launching, so cache restore happens first.\n        this.api.on('didFinishLaunching', () => {\n            this.log.info('Did finish launching');\n            for (const sensorConfig of this.sensorConfigs) {\n                const uuid = hap.uuid.generate(sensorConfig.serialno);\n                const cached = this.accessories.get(uuid);\n                if (cached) {\n                    this.log.info('Restoring existing accessory from cache:', cached.displayName);\n                    if (!cached.context.serial) {\n                        cached.context.serial = sensorConfig.serialno;\n                    }\n                    new AirGradientSensor(this, cached, sensorConfig);\n                }\n                else {\n                    this.log.info('Adding new accessory for serial number:', sensorConfig.serialno);\n                    const accessory = new this.api.platformAccessory(`AirGradient Sensor ${sensorConfig.serialno}`, uuid);\n                    accessory.context.serial = sensorConfig.serialno;\n                    new AirGradientSensor(this, accessory, sensorConfig);\n                    this.api.registerPlatformAccessories('homebridge-airgradient', 'AirGradientPlatform', [accessory]);\n                    this.accessories.set(uuid, accessory);\n                }\n            }\n        });\n    }\n    configureAccessory(accessory) {\n        this.accessories.set(accessory.UUID, accessory);\n    }\n}\nfunction isAirGradientData(x) {\n    if (x === null || typeof x !== 'object') {\n        return false;\n    }\n    const o = x;\n    // Minimal required fields you actually rely on elsewhere\n    return (typeof o.pm02 === 'number' &&\n        typeof o.pm10 === 'number' &&\n        typeof o.rco2 === 'number' &&\n        typeof o.atmp === 'number' &&\n        typeof o.rhum === 'number');\n}\nclass AirGradientSensor {\n    constructor(platform, accessory, sensorConfig) {\n        var _a, _b;\n        this.data = null;\n        this.platform = platform;\n        this.accessory = accessory;\n        this.log = platform.log;\n        this.serialno = sensorConfig.serialno;\n        this.pollingInterval = (sensorConfig.pollingInterval && sensorConfig.pollingInterval > 0)\n            ? sensorConfig.pollingInterval\n            : 60000; // Default to 1 minute, must be higher than 0\n        this.useCompensatedValues = (_a = sensorConfig.useCompensatedValues) !== null && _a !== void 0 ? _a : false;\n        this.co2AlertThreshold = (sensorConfig.co2AlertThreshold && sensorConfig.co2AlertThreshold > 0)\n            ? sensorConfig.co2AlertThreshold\n            : 800;\n        // Construct the local API URL using the serialno\n        this.apiUrl = `http://airgradient_${this.serialno}.local/measures/current`;\n        this.accessory.getService(hap.Service.AccessoryInformation)\n            .setCharacteristic(hap.Characteristic.Manufacturer, 'AirGradient')\n            .setCharacteristic(hap.Characteristic.SerialNumber, this.serialno);\n        this.service = this.accessory.getService(hap.Service.AirQualitySensor) ||\n            this.accessory.addService(hap.Service.AirQualitySensor);\n        this.serviceTemp = this.accessory.getService(hap.Service.TemperatureSensor) ||\n            this.accessory.addService(hap.Service.TemperatureSensor);\n        this.serviceCO2 = this.accessory.getService(hap.Service.CarbonDioxideSensor) ||\n            this.accessory.addService(hap.Service.CarbonDioxideSensor);\n        this.serviceHumid = this.accessory.getService(hap.Service.HumiditySensor) ||\n            this.accessory.addService(hap.Service.HumiditySensor);\n        // Ensure all optional characteristics exist (getCharacteristic ensures creation for optionals)\n        this.service.getCharacteristic(hap.Characteristic.AirQuality);\n        this.service.getCharacteristic(hap.Characteristic.PM2_5Density);\n        this.service.getCharacteristic(hap.Characteristic.PM10Density);\n        if (!this.service.testCharacteristic(hap.Characteristic.VOCDensity)) {\n            this.service.addCharacteristic(hap.Characteristic.VOCDensity);\n        }\n        if (!this.service.testCharacteristic(hap.Characteristic.NitrogenDioxideDensity)) {\n            this.service.addCharacteristic(hap.Characteristic.NitrogenDioxideDensity);\n        }\n        this.serviceCO2.getCharacteristic(hap.Characteristic.CarbonDioxideDetected);\n        this.serviceCO2.getCharacteristic(hap.Characteristic.CarbonDioxideLevel);\n        // Initialize safe placeholder values so the Home hub never sees \"missing\" nodes\n        this.service.updateCharacteristic(hap.Characteristic.AirQuality, (_b = hap.Characteristic.AirQuality.UNKNOWN) !== null && _b !== void 0 ? _b : hap.Characteristic.AirQuality.FAIR);\n        this.service.updateCharacteristic(hap.Characteristic.PM2_5Density, 0);\n        this.service.updateCharacteristic(hap.Characteristic.PM10Density, 0);\n        this.service.updateCharacteristic(hap.Characteristic.VOCDensity, 0);\n        this.service.updateCharacteristic(hap.Characteristic.NitrogenDioxideDensity, 0);\n        this.serviceCO2.updateCharacteristic(hap.Characteristic.CarbonDioxideDetected, hap.Characteristic.CarbonDioxideDetected.CO2_LEVELS_NORMAL);\n        this.serviceCO2.updateCharacteristic(hap.Characteristic.CarbonDioxideLevel, 0);\n        this.serviceTemp.getCharacteristic(hap.Characteristic.CurrentTemperature);\n        this.serviceTemp.updateCharacteristic(hap.Characteristic.CurrentTemperature, 0);\n        this.serviceHumid.getCharacteristic(hap.Characteristic.CurrentRelativeHumidity);\n        this.serviceHumid.updateCharacteristic(hap.Characteristic.CurrentRelativeHumidity, 0);\n        this.updateData();\n    }\n    async fetchData() {\n        var _a;\n        try {\n            // Strongly type the expected payload\n            const response = await axios_1.default.get(this.apiUrl, {\n                timeout: 30000, // optional: avoid hanging forever\n                headers: { 'Accept': 'application/json' },\n                // validateStatus: (s) => s >= 200 && s < 400, // optional: treat 3xx as ok if your devices redirect\n            });\n            const payload = response.data;\n            // Runtime validation: ensures critical numeric fields exist\n            if (!isAirGradientData(payload)) {\n                this.log.error('AirGradient API returned unexpected data format:', payload);\n                return; // keep previous this.data (so we don’t overwrite with bad data)\n            }\n            // All good—commit and log\n            this.data = payload;\n            this.log.info('Data fetched successfully:', this.data);\n            // Optional extra debug\n            this.log.debug('API response:', this.data);\n        }\n        catch (err) {\n            // Make axios/network errors readable without losing detail\n            const e = err;\n            if (axios_1.default.isAxiosError(e)) {\n                this.log.error(`Axios error fetching AirGradient data: ${e.message}` +\n                    (e.response ? ` (status ${e.response.status})` : '') +\n                    (e.code ? ` [code ${e.code}]` : ''));\n                if ((_a = e.response) === null || _a === void 0 ? void 0 : _a.data) {\n                    this.log.debug('Error response body:', e.response.data);\n                }\n            }\n            else if (e instanceof Error) {\n                this.log.error('Error fetching data from AirGradient API:', e.message);\n                this.log.debug(e.stack || 'no stack');\n            }\n            else {\n                this.log.error('Unknown error fetching data from AirGradient API:', e);\n            }\n            throw err; // keep existing control flow in updateData()\n        }\n    }\n    async updateData() {\n        try {\n            await this.fetchData();\n            if (this.data) {\n                this.updateCharacteristics();\n            }\n        }\n        catch (error) {\n            this.log.error('Error updating data:', error);\n        }\n        finally {\n            // Schedule the next update\n            setTimeout(() => this.updateData(), this.pollingInterval);\n        }\n    }\n    updateCharacteristics() {\n        if (this.data) {\n            // Use compensated values if enabled and available, otherwise fallback to the default values\n            const pm2_5 = this.useCompensatedValues && this.data.pm02Compensated !== undefined\n                ? this.data.pm02Compensated\n                : this.data.pm02;\n            const temp = this.useCompensatedValues && this.data.atmpCompensated !== undefined\n                ? this.data.atmpCompensated\n                : this.data.atmp;\n            const humidity = this.useCompensatedValues && this.data.rhumCompensated !== undefined\n                ? this.data.rhumCompensated\n                : this.data.rhum;\n            // Other values remain the same\n            const pm10 = this.data.pm10;\n            const tvoc = this.data.tvocIndex;\n            const nox = this.data.noxIndex;\n            const co2 = this.data.rco2;\n            if (typeof pm2_5 === 'number' && isFinite(pm2_5)) {\n                this.service.updateCharacteristic(hap.Characteristic.PM2_5Density, pm2_5);\n            }\n            else {\n                this.log.warn('Invalid PM2.5 value:', pm2_5);\n            }\n            if (typeof pm10 === 'number' && isFinite(pm10)) {\n                this.service.updateCharacteristic(hap.Characteristic.PM10Density, pm10);\n            }\n            else {\n                this.log.warn('Invalid PM10 value:', pm10);\n            }\n            if (typeof tvoc === 'number' && isFinite(tvoc)) {\n                this.service.updateCharacteristic(hap.Characteristic.VOCDensity, tvoc);\n            }\n            else {\n                this.log.warn('Invalid TVOC value:', tvoc);\n            }\n            if (typeof nox === 'number' && isFinite(nox)) {\n                this.service.updateCharacteristic(hap.Characteristic.NitrogenDioxideDensity, nox);\n            }\n            else {\n                this.log.warn('Invalid NOx value:', nox);\n            }\n            if (typeof temp === 'number' && isFinite(temp)) {\n                this.serviceTemp.updateCharacteristic(hap.Characteristic.CurrentTemperature, temp);\n            }\n            else {\n                this.log.warn('Invalid Temperature value:', temp);\n            }\n            if (typeof co2 === 'number' && isFinite(co2)) {\n                this.serviceCO2.updateCharacteristic(hap.Characteristic.CarbonDioxideDetected, this.calculateCO2Detected(co2));\n                this.serviceCO2.updateCharacteristic(hap.Characteristic.CarbonDioxideLevel, co2);\n            }\n            else {\n                this.log.warn('Invalid CO2 value:', co2);\n            }\n            if (typeof humidity === 'number' && isFinite(humidity)) {\n                this.serviceHumid.updateCharacteristic(hap.Characteristic.CurrentRelativeHumidity, humidity);\n            }\n            else {\n                this.log.warn('Invalid Humidity value:', humidity);\n            }\n            this.service.updateCharacteristic(hap.Characteristic.AirQuality, this.calculateAirQuality(pm2_5));\n            this.log.info(`Updated characteristics - PM2.5: ${pm2_5}, PM10: ${pm10}, TVOC: ${tvoc}, ` +\n                `NOx: ${nox}, TEMP: ${temp}, CO2: ${co2}, Humidity: ${humidity}`);\n        }\n    }\n    calculateAirQuality(pm2_5) {\n        if (pm2_5 <= 12) {\n            return hap.Characteristic.AirQuality.EXCELLENT;\n        }\n        else if (pm2_5 <= 35.4) {\n            return hap.Characteristic.AirQuality.GOOD;\n        }\n        else if (pm2_5 <= 55.4) {\n            return hap.Characteristic.AirQuality.FAIR;\n        }\n        else if (pm2_5 <= 150.4) {\n            return hap.Characteristic.AirQuality.INFERIOR;\n        }\n        else {\n            return hap.Characteristic.AirQuality.POOR;\n        }\n    }\n    calculateCO2Detected(co2) {\n        return co2 > this.co2AlertThreshold\n            ? hap.Characteristic.CarbonDioxideDetected.CO2_LEVELS_ABNORMAL\n            : hap.Characteristic.CarbonDioxideDetected.CO2_LEVELS_NORMAL;\n    }\n    handleAirQualityGet(callback) {\n        if (this.data) {\n            callback(null, this.calculateAirQuality(this.data.pm02));\n        }\n        else {\n            callback(new Error('No data available'));\n        }\n    }\n    handlePM2_5DensityGet(callback) {\n        if (this.data) {\n            callback(null, this.data.pm02);\n        }\n        else {\n            callback(new Error('No data available'));\n        }\n    }\n    handlePM10DensityGet(callback) {\n        if (this.data) {\n            callback(null, this.data.pm10);\n        }\n        else {\n            callback(new Error('No data available'));\n        }\n    }\n    handleVOCDensityGet(callback) {\n        if (this.data) {\n            callback(null, this.data.tvocIndex);\n        }\n        else {\n            callback(new Error('No data available'));\n        }\n    }\n    handleNitrogenDioxideDensityGet(callback) {\n        if (this.data) {\n            callback(null, this.data.noxIndex);\n        }\n        else {\n            callback(new Error('No data available'));\n        }\n    }\n    handleCurrentTemperatureGet(callback) {\n        if (this.data) {\n            callback(null, this.data.atmp);\n        }\n        else {\n            callback(new Error('No data available'));\n        }\n    }\n    handleCarbonDioxideDetectedGet(callback) {\n        if (this.data) {\n            callback(null, this.calculateCO2Detected(this.data.rco2));\n        }\n        else {\n            callback(new Error('No data available'));\n        }\n    }\n    handleCarbonDioxideLevelGet(callback) {\n        if (this.data) {\n            callback(null, this.data.rco2);\n        }\n        else {\n            callback(new Error('No data available'));\n        }\n    }\n    handleCurrentRelativeHumidityGet(callback) {\n        if (this.data) {\n            callback(null, this.data.rhum);\n        }\n        else {\n            callback(new Error('No data available'));\n        }\n    }\n}\nmodule.exports = (homebridge) => {\n    hap = homebridge.hap;\n    homebridge.registerPlatform('homebridge-airgradient', 'AirGradientPlatform', AirGradientPlatform);\n};\n"]}