Virtual AQI Device

I took some liberties here, but I added pulls for specifics. I also set it to pull every 30 minutes.

Thank you Byrin for the original source.

/*
	OpenWeatherMap-Air Quality - Detailed
    Modified from Byrin's original
*/
static String version()	{  return '0.0.2'  }
import groovy.transform.Field


metadata {
    definition (name: "OpenWeatherMap-Air Quality", namespace: "AC7SSM", author: "SJ") {
	capability "AirQuality"
    attribute "CO", "float"
    attribute "NO", "float"
    attribute "NO2", "float"
    attribute "O3", "float"
    attribute "SO2", "float"
    attribute "PM2.5", "float"
    attribute "PM10", "float"
    attribute "NH3", "float"

    command 'pollData'
	} 
    preferences {
        input 'apiKey', 'text', required: true, title: 'Type OpenWeatherMap.org API Key Here', defaultValue: null
        input name: "logEnable", type: "bool", title: "Enable debug logging", defaultValue: true
        input name: "txtEnable", type: "bool", title: "Enable descriptionText logging", defaultValue: true
    }
}

void pollAQI() {
	if( apiKey == null ) {
		return
	}
	Map ParamsAQI
	ParamsAQI = [ 
        uri: 'https://api.openweathermap.org/data/2.5/air_pollution?lat=' + (String)location.latitude + '&lon=' + (String)location.longitude + '&appid=' + (String)apiKey, 
        timeout: 20 ]
    if (logEnable) log.debug "ParamsAQI:${ParamsAQI}"
	asynchttpGet('pollAQIHandler', ParamsAQI)
}

void pollAQIHandler(resp, data) {
	if(resp.getStatus() == 200 || resp.getStatus() == 207) {
		Map aqi = parseJson(resp.data)
		if(aqi.toString()==sNULL) {
			pauseExecution(30000) //5 minute pause
			pollAQI()
			return
		}
		def name = 'airQualityIndex'
		def value = aqi.list[0].main.aqi
		def descriptionText = "${device.displayName} ${name} is ${value}"
		if (txtEnable) log.info "${descriptionText}"
		sendEvent(name: name,value: value,descriptionText: descriptionText,unit: unit)
        // Here begins my modification (SJ)
        name = 'CO'
		value = aqi.list[0].components.co
		descriptionText = "${device.displayName} ${name} is ${value}"
		if (txtEnable) log.info "${descriptionText}"
		sendEvent(name: name,value: value,descriptionText: descriptionText,unit: unit)
       
        name = 'NO'
		value = aqi.list[0].components.no
		descriptionText = "${device.displayName} ${name} is ${value}"
		if (txtEnable) log.info "${descriptionText}"
		sendEvent(name: name,value: value,descriptionText: descriptionText,unit: unit)
        
        name = 'NO2'
		value = aqi.list[0].components.no2
		descriptionText = "${device.displayName} ${name} is ${value}"
		if (txtEnable) log.info "${descriptionText}"
		sendEvent(name: name,value: value,descriptionText: descriptionText,unit: unit)
        
        name = 'O3'
		value = aqi.list[0].components.o3
		descriptionText = "${device.displayName} ${name} is ${value}"
		if (txtEnable) log.info "${descriptionText}"
		sendEvent(name: name,value: value,descriptionText: descriptionText,unit: unit)
        
        name = 'SO2'
		value = aqi.list[0].components.so2
		descriptionText = "${device.displayName} ${name} is ${value}"
		if (txtEnable) log.info "${descriptionText}"
		sendEvent(name: name,value: value,descriptionText: descriptionText,unit: unit)
        
        name = 'PM2.5'
		value = aqi.list[0].components.pm2_5
		descriptionText = "${device.displayName} ${name} is ${value}"
		if (txtEnable) log.info "${descriptionText}"
		sendEvent(name: name,value: value,descriptionText: descriptionText,unit: unit)
        
        name = 'PM10'
		value = aqi.list[0].components.pm10
		descriptionText = "${device.displayName} ${name} is ${value}"
		if (txtEnable) log.info "${descriptionText}"
		sendEvent(name: name,value: value,descriptionText: descriptionText,unit: unit)
        
        name = 'NH3'
		value = aqi.list[0].components.nh3
		descriptionText = "${device.displayName} ${name} is ${value}"
		if (txtEnable) log.info "${descriptionText}"
		sendEvent(name: name,value: value,descriptionText: descriptionText,unit: unit)

	}
}

void refresh() {
}

void installed() {
    schedule("0 0/30 * 1/1 * ? *", pollAQI) //every half hour
}

void uninstalled() {
    unschedule()
}

void pollData() {
	pollAQI()
}

I did not work out an actual AQI number yet. It's a bit complicated to do this evening. But it was fun to give a whirl at coding for once in a long while.