{"version":3,"sources":["jsdelivr-header.js","/npm/homebridge-awair-local@1.3.1/index.js"],"names":[],"mappings":"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","file":"/npm/homebridge-awair-local@1.3.1/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/homebridge-awair-local@1.3.1/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","var Service, Characteristic;\nvar request = require(\"request-promise\");\nconst packageJSON = require(\"./package.json\");\n\nmodule.exports = function(homebridge) {\n\tService = homebridge.hap.Service;\n\tCharacteristic = homebridge.hap.Characteristic;\n\t\n\thomebridge.registerAccessory(\"homebridge-awair-local\", \"AwairLocal\", AwairLocal);\n};\n\nfunction AwairLocal(log, config) {\n\tthis.log = log;\n\tthis.logging = config[\"logging\"] || false; // true || false (default: false = OFF)\n\tthis.logging_level = config[\"logging_level\"] || 0; // 0, 1, 2, 3, ... (default: 0 = OFF)\n\tthis.ip = config[\"ip\"]; // can also be mDNS .local address (without http://)\n\tthis.carbonDioxideThreshold = Number(config[\"carbonDioxideThreshold\"]) || 0; // ppm, 0 = OFF\n\tthis.carbonDioxideThresholdOff = Number(config[\"carbonDioxideThresholdOff\"]) || Number(this.carbonDioxideThreshold); // ppm, same as carbonDioxideThreshold by default, should be less than or equal to carbonDioxideThreshold\n\tthis.vocMW = Number(config[\"voc_mixture_mw\"]) || 72.66578273019740; // Molecular Weight (g/mol) of a reference VOC gas or mixture\n\tthis.airQualityMethod = config[\"air_quality_method\"] || \"awair-score\"; // awair-score, awair-aqi, awair-pm25\n\tthis.polling_interval = Number(config[\"polling_interval\"]) || 10; // seconds (default: 10 seconds)\n\tthis.limit = Number(config[\"limit\"]) || 1; // consecutive 10 second samples averaged (default: 1 x 10 = 10 seconds)\n\tthis.url = config[\"url\"] || \"http://\" + this.ip + \"/air-data/latest\";\n\tthis.configUrl = config[\"url\"] || \"http://\" + this.ip + \"/settings/config/data\";\n\tthis.manufacturer = config[\"manufacturer\"] || \"Awair\";\n\tthis.model = config[\"model\"] ||  \"unknown model\"; // awair-mint, awair-omni, awair-element, awair-r2\n\tthis.devType = this.model;\n\tthis.serial = config[\"serial\"] || \"unknown serial\";\n\tthis.version = config[\"version\"] || \"unknown version\";\n}\n\nAwairLocal.prototype = {\n\tgetData: function() {\n\t\tvar options = {\n\t\t\tmethod: \"GET\",\n\t\t\turi: this.url,\n\t\t\tjson: true\n\t\t};\n\t\t\n\t\tif(this.logging || this.logging_level > 0){this.log(\"[\" + this.serial + \"] url: \" + this.url)};\n\t\t\n\t\tvar that = this;\n\t\t\n\t\treturn request(options)\n\t\t\t.then(function(response) {\n\t\t\t\tvar data = response;\n\t\t\t\t\n\t\t\t\tvar score = data.score;\n\t\t\t\t\n\t\t\t\tif (that.airQualityMethod == 'awair-aqi') {\n\t\t\t\t\tthat.airQualityService\n\t\t\t\t\t.setCharacteristic(Characteristic.AirQuality, that.convertAwairAqi(data));\n\t\t\t\t} else if (that.airQualityMethod == 'awair-pm25') {\n\t\t\t\t\tthat.airQualityService\n\t\t\t\t\t.setCharacteristic(Characteristic.AirQuality, that.convertAwairPM(data));\n\t\t\t\t} else {\n\t\t\t\t\tthat.airQualityService\n\t\t\t\t\t.setCharacteristic(Characteristic.AirQuality, that.convertScore(score));\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tthat.airQualityService.isPrimaryService = true;\n\t\t\t\tif (that.devType == \"awair-mint\") {\n\t\t\t\t\tthat.airQualityService.linkedServices = [that.humidityService, that.temperatureService, that.lightLevelService];\n\t\t\t\t} else if (that.devType == \"awair-omni\") {\n\t\t\t\t\tthat.airQualityService.linkedServices = [that.humidityService, that.temperatureService, that.carbonDioxideService, that.lightLevelService];\n\t\t\t\t} else {\n\t\t\t\t\tthat.airQualityService.linkedServices = [that.humidityService, that.temperatureService, that.carbonDioxideService];\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tvar temp = parseFloat(data.temp);\n\t\t\t\tvar atmos = 1;\n\t\t\t\t\n\t\t\t\tif(that.logging || that.logging_level > 1){that.log(\"[\" + that.serial + \"] \" + that.url + \": \" + JSON.stringify(data) + \", score: \" + score)};\n\t\t\t\t\n\t\t\t\tfor (var sensor in data) {\n\t\t\t\t\tswitch (sensor) {\n\t\t\t\t\t\tcase \"dew_point\":\n\t\t\t\t\t\t\t// Dew Point (C)\n\t\t\t\t\t\t\t// TODO: replace with a HomeKit service\n\t\t\t\t\t\t\tif(that.logging || that.logging_level > 2){that.log(\"[\" + that.serial + \"] ignoring \" + JSON.stringify(sensor) + \": \" + parseFloat(data[sensor]))};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"temp\":\n\t\t\t\t\t\t\t// Temperature (C)\n\t\t\t\t\t\t\tthat.temperatureService\n\t\t\t\t\t\t\t\t.setCharacteristic(Characteristic.CurrentTemperature, parseFloat(data[sensor]))\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"humid\":\n\t\t\t\t\t\t\t// Humidity (%)\n\t\t\t\t\t\t\tthat.humidityService\n\t\t\t\t\t\t\t\t.setCharacteristic(Characteristic.CurrentRelativeHumidity, parseFloat(data[sensor]))\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"abs_humid\":\n\t\t\t\t\t\t\t// Absolute Humidity (mg/L)\n\t\t\t\t\t\t\t// TODO: replace with a HomeKit service\n\t\t\t\t\t\t\tif(that.logging || that.logging_level > 2){that.log(\"[\" + that.serial + \"] ignoring \" + JSON.stringify(sensor) + \": \" + parseFloat(data[sensor]))};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"co2\":\n\t\t\t\t\t\t\t// Carbon Dioxide (ppm)\n\t\t\t\t\t\t\tvar co2 = parseFloat(data[sensor]);\n\t\t\t\t\t\t\tvar co2Detected;\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tvar co2Before = that.carbonDioxideService.getCharacteristic(Characteristic.CarbonDioxideDetected).value;\n\t\t\t\t\t\t\tif(that.logging || that.logging_level > 2){that.log(\"[\" + that.serial + \"] CO2Before: \" + co2Before)};\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t// Logic to determine if Carbon Dioxide should trip a change in Detected state\n\t\t\t\t\t\t\tthat.carbonDioxideService\n\t\t\t\t\t\t\t\t.setCharacteristic(Characteristic.CarbonDioxideLevel, parseFloat(data[sensor]))\n\t\t\t\t\t\t\tif ((that.carbonDioxideThreshold > 0) && (co2 >= that.carbonDioxideThreshold)) {\n\t\t\t\t\t\t\t\t// threshold set and CO2 HIGH\n\t\t\t\t\t\t\t\tco2Detected = 1;\n\t\t\t\t\t\t\t\tif(that.logging || that.logging_level > 2){that.log(\"[\" + that.serial + \"] CO2 HIGH: \" + co2 + \" > \" + that.carbonDioxideThreshold)};\n\t\t\t\t\t\t\t} else if ((that.carbonDioxideThreshold > 0) && (co2 < that.carbonDioxideThresholdOff)) {\n\t\t\t\t\t\t\t\t// threshold set and CO2 LOW\n\t\t\t\t\t\t\t\tco2Detected = 0;\n\t\t\t\t\t\t\t\tif(that.logging || that.logging_level > 2){that.log(\"[\" + that.serial + \"] CO2 NORMAL: \" + co2 + \" < \" + that.carbonDioxideThresholdOff)};\n\t\t\t\t\t\t\t} else if ((that.carbonDioxideThreshold > 0) && (co2 < that.carbonDioxideThreshold) && (co2 > that.carbonDioxideThresholdOff)) {\n\t\t\t\t\t\t\t\t// the inbetween...\n\t\t\t\t\t\t\t\tif(that.logging || that.logging_level > 2){that.log(\"[\" + that.serial + \"] CO2 INBETWEEN: \" + that.carbonDioxideThreshold + \" > [[[\" + co2 + \"]]] > \" + that.carbonDioxideThresholdOff)};\n\t\t\t\t\t\t\t\tco2Detected = co2Before;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// threshold NOT set\n\t\t\t\t\t\t\t\tco2Detected = 0;\n\t\t\t\t\t\t\t\tif(that.logging || that.logging_level > 2){that.log(\"[\" + that.serial + \"] CO2: \" + co2)};\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t// Prevent sending a Carbon Dioxide detected update if one has not occured\n\t\t\t\t\t\t\tif ((co2Before == 0) && (co2Detected == 0)) {\n\t\t\t\t\t\t\t\t// CO2 low already, don't send\n\t\t\t\t\t\t\t\tif(that.logging || that.logging_level > 2){that.log(\"Carbon Dioxide already low.\")};\n\t\t\t\t\t\t\t} else if ((co2Before == 0) && (co2Detected == 1)) {\n\t\t\t\t\t\t\t\t// CO2 low to high, send it!\n\t\t\t\t\t\t\t\tthat.carbonDioxideService.setCharacteristic(Characteristic.CarbonDioxideDetected, co2Detected);\n\t\t\t\t\t\t\t\tif(that.logging || that.logging_level > 2){that.log(\"Carbon Dioxide low to high.\")};\n\t\t\t\t\t\t\t} else if ((co2Before == 1) && (co2Detected == 1)) {\n\t\t\t\t\t\t\t\t// CO2 high to not-quite-low-enough-yet, don't send\n\t\t\t\t\t\t\t\tif(that.logging || that.logging_level > 2){that.log(\"Carbon Dioxide already elevated.\")};\n\t\t\t\t\t\t\t} else if ((co2Before == 1) && (co2Detected == 0)) {\n\t\t\t\t\t\t\t\t// CO2 low to high, send it!\n\t\t\t\t\t\t\t\tthat.carbonDioxideService.setCharacteristic(Characteristic.CarbonDioxideDetected, co2Detected);\n\t\t\t\t\t\t\t\tif(that.logging || that.logging_level > 2){that.log(\"Carbon Dioxide high to low.\")};\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// CO2 unknown...\n\t\t\t\t\t\t\t\tif(that.logging || that.logging_level > 2){that.log(\"Carbon Dioxide state unknown.\")};\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"co2_est\":\n\t\t\t\t\t\t\t// Estimated CO2 (ppm)\n\t\t\t\t\t\t\t// TODO: replace with a HomeKit service (specifically for Awair Mint)\n\t\t\t\t\t\t\tif(that.logging || that.logging_level > 2){that.log(\"[\" + that.serial + \"] ignoring \" + JSON.stringify(sensor) + \": \" + parseFloat(data[sensor]))};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"voc\":\n\t\t\t\t\t\t\tvar voc = parseFloat(data[sensor]);\n\t\t\t\t\t\t\tvar tvoc = that.convertChemicals(voc, atmos, temp);\n\t\t\t\t\t\t\tif(that.logging || that.logging_level > 2){that.log(\"[\" + that.serial + \"]: voc (\" + voc + \" ppb) => tvoc (\" + tvoc + \" ug/m^3)\")};\n\t\t\t\t\t\t\t// Chemicals (ug/m^3)\n\t\t\t\t\t\t\tthat.airQualityService\n\t\t\t\t\t\t\t\t.setCharacteristic(Characteristic.VOCDensity, tvoc);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"pm25\":\n\t\t\t\t\t\t\t// PM2.5 (ug/m^3)\n\t\t\t\t\t\t\tthat.airQualityService\n\t\t\t\t\t\t\t\t.setCharacteristic(Characteristic.PM2_5Density, parseFloat(data[sensor]));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"pm10_est\":\n\t\t\t\t\t\t\t// PM10 (ug/m^3) - estimated\n\t\t\t\t\t\t\tthat.airQualityService\n\t\t\t\t\t\t\t\t.setCharacteristic(Characteristic.PM10Density, parseFloat(data[sensor]));\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"lux\":\n\t\t\t\t\t\t\t// Light (lux)\n\t\t\t\t\t\t\tthat.lightLevelService\n\t\t\t\t\t\t\t\t.setCharacteristic(Characteristic.CurrentAmbientLightLevel, parseFloat(data[sensor]));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"spl_a\":\n\t\t\t\t\t\t\t// Sound (dBA)\n\t\t\t\t\t\t\t// TODO: replace with a HomeKit service\n\t\t\t\t\t\t\tif(that.logging || that.logging_level > 2){that.log(\"[\" + that.serial + \"] ignoring \" + JSON.stringify(sensor) + \": \" + parseFloat(data[sensor]))};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tif(that.logging || that.logging_level > 2){that.log(\"[\" + that.serial + \"] ignoring \" + JSON.stringify(sensor) + \": \" + parseFloat(data[sensor]))};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(function(err) {\n\t\t\t\tif(that.logging || that.logging_level > 0){that.log(\"[\" + that.serial + \"] \" + err)};\n\t\t\t\tthat.temperatureService\n\t\t\t\t\t.setCharacteristic(Characteristic.CurrentTemperature, \"--\")\n\t\t\t\tthat.humidityService\n\t\t\t\t\t.setCharacteristic(Characteristic.CurrentRelativeHumidity, \"--\")\n\t\t\t\tif (that.devType != \"awair-mint\") {\n\t\t\t\t\tthat.carbonDioxideService\n\t\t\t\t\t\t.setCharacteristic(Characteristic.CarbonDioxideLevel, \"--\")\n\t\t\t\t\t\t.setCharacteristic(Characteristic.CarbonDioxideDetected, \"--\")\n\t\t\t\t};\n\t\t\t\tif (that.devType == \"awair-omni\" || that.devType == \"awair-mint\") {\n\t\t\t\t\tthat.lightLevelService\n\t\t\t\t\t\t.setCharacteristic(Characteristic.CurrentAmbientLightLevel, \"--\")\n\t\t\t\t};\n\t\t\t\tthat.airQualityService\n\t\t\t\t\t.setCharacteristic(Characteristic.AirQuality, \"--\")\n\t\t\t\t\t.setCharacteristic(Characteristic.VOCDensity, \"--\")\n\t\t\t\t\t.setCharacteristic(Characteristic.PM10Density, \"--\")\n\t\t\t\t\t.setCharacteristic(Characteristic.PM2_5Density, \"--\")\n\t\t\t});\n\t},\n\t\n\tconvertChemicals: function(voc, atmos, temp) {\n\t\tvar that = this;\n\t\tvar mw = parseFloat(that.vocMW);\n\t\tvar voc = parseFloat(voc);\n\t\tvar atmos = parseFloat(atmos);\n\t\tvar temp = parseFloat(temp);\n\t\tvar vocString = \"(\" + voc + \" * \" + mw + \" * \" + atmos + \" * 101.32) / ((273.15 + \" + temp + \") * 8.3144)\";\n\t\tvar tvoc = (voc * mw * atmos * 101.32) / ((273.15 + temp) * 8.3144);\n\t\tif(that.logging || that.logging_level > 2){that.log(\"[\" + that.serial + \"] ppb => ug/m^3 equation: \" + vocString)};\n\t\treturn tvoc;\n\t},\n\t\n\tconvertScore: function(score) {\n\t\tvar that = this;\n\t\tvar score = parseFloat(score);\n\t\tif (score >= 90) {\n\t\t\treturn 1; // EXCELLENT\n\t\t} else if (score >= 80 && score < 90) {\n\t\t\treturn 2; // GOOD\n\t\t} else if (score >= 60 && score < 80) {\n\t\t\treturn 3; // FAIR\n\t\t} else if (score >= 50 && score < 60) {\n\t\t\treturn 4; // INFERIOR\n\t\t} else if (score < 50) {\n\t\t\treturn 5; // POOR\n\t\t} else {\n\t\t\treturn 0; // Error\n\t\t}\n\t},\n\t\n\tconvertAwairAqi: function(data) {\n\t\tvar that = this;\n\t\tvar aqiArray = [];\n\t\tvar data = data;\n\t\tfor (var sensor in data) {\n\t\t\tswitch (sensor) {\n\t\t\t\tcase \"voc\":\n\t\t\t\t\tvar aqiVoc = parseFloat(data[sensor]);\n\t\t\t\t\tif (aqiVoc >= 0 && aqiVoc < 333) {\n\t\t\t\t\t\taqiVoc = 1; // EXCELLENT\n\t\t\t\t\t} else if (aqiVoc >= 333 && aqiVoc < 1000) {\n\t\t\t\t\t\taqiVoc = 2; // GOOD\n\t\t\t\t\t} else if (aqiVoc >= 1000 && aqiVoc < 3333) {\n\t\t\t\t\t\taqiVoc = 3; // FAIR\n\t\t\t\t\t} else if (aqiVoc >= 3333 && aqiVoc < 8332) {\n\t\t\t\t\t\taqiVoc = 4; // INFERIOR\n\t\t\t\t\t} else if (aqiVoc >= 8332) {\n\t\t\t\t\t\taqiVoc = 5; // POOR\n\t\t\t\t\t} else {\n\t\t\t\t\t\taqiVoc = 0; // Error\n\t\t\t\t\t}\n\t\t\t\t\taqiArray.push(aqiVoc);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"pm25\":\n\t\t\t\t\tvar aqiPm25 = parseFloat(data[sensor]);\n\t\t\t\t\tif (aqiPm25 >= 0 && aqiPm25 < 15) {\n\t\t\t\t\t\taqiPm25 = 1; // EXCELLENT\n\t\t\t\t\t} else if (aqiPm25 >= 15 && aqiPm25 < 35) {\n\t\t\t\t\t\taqiPm25 = 2; // GOOD\n\t\t\t\t\t} else if (aqiPm25 >= 35 && aqiPm25 < 55) {\n\t\t\t\t\t\taqiPm25 = 3; // FAIR\n\t\t\t\t\t} else if (aqiPm25 >= 55 && aqiPm25 < 75) {\n\t\t\t\t\t\taqiPm25 = 4; // INFERIOR\n\t\t\t\t\t} else if (aqiPm25 >= 75) {\n\t\t\t\t\t\taqiPm25 = 5; // POOR\n\t\t\t\t\t} else {\n\t\t\t\t\t\taqiPm25 = 0; // Error\n\t\t\t\t\t}\n\t\t\t\t\taqiArray.push(aqiPm25);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tif(that.logging || that.logging_level > 2){that.log(\"[\" + that.serial + \"] ignoring \" + JSON.stringify(sensor) + \": \" + parseFloat(data[sensor]))};\n\t\t\t\t\taqiArray.push(0);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif(that.logging || that.logging_level > 2){that.log(\"[\" + that.serial + \"] array: \" + JSON.stringify(aqiArray))};\n\t\treturn Math.max(...aqiArray);\n\t},\n\t\n\tconvertAwairPM: function(data) {\n\t\tvar that = this;\n\t\tvar aqiArray = [];\n\t\tvar data = data;\n\t\tfor (var sensor in data) {\n\t\t\tswitch (sensor) {\n\t\t\t\tcase \"pm25\":\n\t\t\t\t\tvar aqiPm25 = parseFloat(data[sensor]);\n\t\t\t\t\tif (aqiPm25 >= 0 && aqiPm25 < 15) {\n\t\t\t\t\t\taqiPm25 = 1; // EXCELLENT\n\t\t\t\t\t} else if (aqiPm25 >= 15 && aqiPm25 < 35) {\n\t\t\t\t\t\taqiPm25 = 2; // GOOD\n\t\t\t\t\t} else if (aqiPm25 >= 35 && aqiPm25 < 55) {\n\t\t\t\t\t\taqiPm25 = 3; // FAIR\n\t\t\t\t\t} else if (aqiPm25 >= 55 && aqiPm25 < 75) {\n\t\t\t\t\t\taqiPm25 = 4; // INFERIOR\n\t\t\t\t\t} else if (aqiPm25 >= 75) {\n\t\t\t\t\t\taqiPm25 = 5; // POOR\n\t\t\t\t\t} else {\n\t\t\t\t\t\taqiPm25 = 0; // Error\n\t\t\t\t\t}\n\t\t\t\t\taqiArray.push(aqiPm25);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tif(that.logging || that.logging_level > 2){that.log(\"[\" + that.serial + \"] ignoring \" + JSON.stringify(sensor) + \": \" + parseFloat(data[sensor]))};\n\t\t\t\t\taqiArray.push(0);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif(that.logging || that.logging_level > 2){that.log(\"[\" + that.serial + \"] array: \" + JSON.stringify(aqiArray))};\n\t\treturn Math.max(...aqiArray);\n\t},\n\t\n\tgetServices: function() {\n\t\tvar services = [];\n\t\t\n\t\tvar informationService = new Service.AccessoryInformation();\n\t\tinformationService\n\t\t\t.setCharacteristic(Characteristic.Manufacturer, this.manufacturer)\n\t\t\t.setCharacteristic(Characteristic.Model, this.model)\n\t\t\t.setCharacteristic(Characteristic.SerialNumber, this.serial)\n\t\t\t.setCharacteristic(Characteristic.FirmwareRevision, this.version);\n\t\tthis.informationService = informationService;\n\t\tservices.push(informationService);\n\t\t\n\t\tvar airQualityService = new Service.AirQualitySensor();\n\t\tairQualityService\n\t\t\t.setCharacteristic(Characteristic.AirQuality, \"--\")\n\t\t\t.setCharacteristic(Characteristic.VOCDensity, \"--\")\n\t\t\t.setCharacteristic(Characteristic.PM2_5Density, \"--\")\n\t\t\t.setCharacteristic(Characteristic.PM10Density, \"--\");\n\t\tairQualityService\n\t\t\t.getCharacteristic(Characteristic.VOCDensity)\n\t\t\t.setProps({\n\t\t\t\tminValue: 0,\n\t\t\t\tmaxValue: 100000\n\t\t\t});\n\t\tthis.airQualityService = airQualityService;\n\t\tservices.push(airQualityService);\n\t\t\n\t\tvar temperatureService = new Service.TemperatureSensor();\n\t\ttemperatureService\n\t\t\t.setCharacteristic(Characteristic.CurrentTemperature, \"--\");\n\t\ttemperatureService\n\t\t\t.getCharacteristic(Characteristic.CurrentTemperature)\n\t\t\t.setProps({\n\t\t\t\tminValue: -100,\n\t\t\t\tmaxValue: 100\n\t\t\t});\n\t\tthis.temperatureService = temperatureService;\n\t\tservices.push(temperatureService);\n\t\t\n\t\tvar humidityService = new Service.HumiditySensor();\n\t\thumidityService\n\t\t\t.setCharacteristic(Characteristic.CurrentRelativeHumidity, \"--\");\n\t\tthis.humidityService = humidityService;\n\t\tservices.push(humidityService);\n\t\t\n\t\tif (this.devType != \"awair-mint\") {\n\t\t\tvar carbonDioxideService = new Service.CarbonDioxideSensor();\n\t\t\tcarbonDioxideService\n\t\t\t\t.setCharacteristic(Characteristic.CarbonDioxideLevel, \"--\");\n\t\t\tthis.carbonDioxideService = carbonDioxideService;\n\t\t\tservices.push(carbonDioxideService);\n\t\t}\n\t\t\n\t\tif (this.devType == \"awair-omni\" || this.devType == \"awair-mint\") {\n\t\t\tvar lightLevelService = new Service.LightSensor();\n\t\t\tlightLevelService\n\t\t\t\t.setCharacteristic(Characteristic.CurrentAmbientLightLevel, \"--\");\n\t\t\tlightLevelService\n\t\t\t\t.getCharacteristic(Characteristic.CurrentAmbientLightLevel)\n\t\t\t\t.setProps({\n\t\t\t\t\tminValue: 0,\n\t\t\t\t\tmaxValue: 64000\n\t\t\t\t});\n\t\t\tthis.lightLevelService = lightLevelService;\n\t\t\tservices.push(lightLevelService);\n\t\t}\n\t\t\n\t\tif (this.polling_interval > 0) {\n\t\t\tif(this.logging || this.logging_level > 1){this.log(\"[\" + this.serial + \"] polling_interval set to \" + this.polling_interval)};\n\t\t\tthis.timer = setInterval(\n\t\t\t\tthis.getData.bind(this),\n\t\t\t\tthis.polling_interval * 1000\n\t\t\t);\n\t\t} else {\n\t\t\tif(this.logging || this.logging_level > 0){this.log(\"[\" + this.serial + \"] no polling_interval set, defaulting to \" + this.polling_interval)};\n\t\t\tthis.timer = setInterval(\n\t\t\t\tthis.getData.bind(this),\n\t\t\t\tthis.polling_interval * 1000\n\t\t\t);\n\t\t}\n\t\t\n\t\t// Get tnitial state\n\t\tthis.getData().bind(this);\n\t\t\n\t\treturn services;\n\t}\n};"]}