{"id":3023,"date":"2026-04-24T13:31:12","date_gmt":"2026-04-24T11:31:12","guid":{"rendered":"https:\/\/bio-me.bio\/?page_id=3023"},"modified":"2026-04-24T13:31:59","modified_gmt":"2026-04-24T11:31:59","slug":"air-quality-index-calculator","status":"publish","type":"page","link":"https:\/\/bio-me.bio\/?page_id=3023","title":{"rendered":"Air Quality Index Calculator"},"content":{"rendered":"\n<div class=\"eco-tool wp-block-group\" id=\"eco-tool-air-quality-91f2d\">\n  <div class=\"eco-tool__header\">\n    <h2 class=\"eco-tool__title\">Air Quality Index Calculator<\/h2>\n    <p class=\"eco-tool__lead\">\n      Estimate air quality category based on PM2.5 concentration using a simplified AQI model.\n    <\/p>\n  <\/div>\n\n  <form class=\"eco-tool__form\" id=\"eco-air-form-91f2d\" novalidate>\n    <div class=\"eco-tool__grid3\">\n      <div class=\"eco-tool__field\">\n        <label class=\"eco-tool__label\" for=\"eco-air-pm25-91f2d\">PM2.5 level<br>(\u00b5g\/m\u00b3)<\/label>\n        <input class=\"eco-tool__input\" id=\"eco-air-pm25-91f2d\" type=\"number\" min=\"0\" step=\"0.1\" value=\"25\" inputmode=\"decimal\" \/>\n        <div class=\"eco-tool__hint\">Fine particulate matter in micrograms per cubic meter.<\/div>\n      <\/div>\n\n      <div class=\"eco-tool__field\">\n        <label class=\"eco-tool__label\" for=\"eco-air-hours-91f2d\">Exposure time<br>(hours\/day)<\/label>\n        <input class=\"eco-tool__input\" id=\"eco-air-hours-91f2d\" type=\"number\" min=\"0\" max=\"24\" step=\"0.5\" value=\"8\" inputmode=\"decimal\" \/>\n        <div class=\"eco-tool__hint\">Time spent outdoors or in affected air each day.<\/div>\n      <\/div>\n\n      <div class=\"eco-tool__field\">\n        <label class=\"eco-tool__label\" for=\"eco-air-group-91f2d\">Sensitive<br>group<\/label>\n        <select class=\"eco-tool__input\" id=\"eco-air-group-91f2d\">\n          <option value=\"no\">No<\/option>\n          <option value=\"yes\">Yes<\/option>\n        <\/select>\n        <div class=\"eco-tool__hint\">Choose yes for asthma, children, elderly, or heart\/lung issues.<\/div>\n      <\/div>\n    <\/div>\n\n    <div class=\"eco-tool__actions\">\n      <button type=\"button\" class=\"wp-element-button eco-tool__btn\" id=\"eco-air-calc-91f2d\">Calculate<\/button>\n      <button type=\"button\" class=\"wp-element-button eco-tool__btn eco-tool__btn--ghost\" id=\"eco-air-reset-91f2d\">Reset<\/button>\n      <div class=\"eco-tool__error\" id=\"eco-air-error-91f2d\" aria-live=\"polite\"><\/div>\n    <\/div>\n  <\/form>\n\n  <div class=\"eco-tool__result\" id=\"eco-air-result-91f2d\" hidden>\n    <h3 class=\"eco-tool__subtitle\">Result<\/h3>\n\n    <div class=\"eco-tool__cards\">\n      <div class=\"eco-tool__card\">\n        <div class=\"eco-tool__metric-label\">Estimated AQI<\/div>\n        <div class=\"eco-tool__metric-value\" id=\"eco-air-aqi-91f2d\">\u2014<\/div>\n        <div class=\"eco-tool__metric-sub\" id=\"eco-air-category-91f2d\"><\/div>\n      <\/div>\n\n      <div class=\"eco-tool__card\">\n        <div class=\"eco-tool__metric-label\">Exposure note<\/div>\n        <div class=\"eco-tool__metric-value\" id=\"eco-air-risk-91f2d\">\u2014<\/div>\n        <div class=\"eco-tool__metric-sub\" id=\"eco-air-risk-sub-91f2d\"><\/div>\n      <\/div>\n    <\/div>\n\n    <div class=\"eco-tool__card eco-tool__card--wide\">\n      <div class=\"eco-tool__metric-label\">AQI scale position<\/div>\n      <div class=\"eco-tool__bars\" id=\"eco-air-bars-91f2d\"><\/div>\n      <div class=\"eco-tool__metric-sub eco-tool__muted\" id=\"eco-air-tip-91f2d\"><\/div>\n    <\/div>\n\n    <p class=\"eco-tool__note\">\n      Approximate estimate only. This calculator uses a simplified PM2.5-based AQI model and is not a medical or regulatory tool.\n    <\/p>\n  <\/div>\n\n  <details class=\"eco-tool__details\">\n    <summary class=\"eco-tool__summary\">How we calculate<\/summary>\n    <div class=\"eco-tool__details-body\">\n      <p class=\"eco-tool__text\">\n        We estimate AQI from PM2.5 using standard breakpoint ranges, then adjust the practical guidance based on exposure time and whether you belong to a sensitive group.\n      <\/p>\n      <ul class=\"eco-tool__list\" id=\"eco-air-factors-91f2d\"><\/ul>\n    <\/div>\n  <\/details>\n<\/div>\n\n<style>\n.eco-tool{border:1px solid rgba(0,0,0,.12);border-radius:12px;padding:16px}\n.eco-tool__header{margin-bottom:12px}\n.eco-tool__title{margin:0 0 8px}\n.eco-tool__lead{margin:0;opacity:.9}\n.eco-tool__form{margin-top:12px}\n.eco-tool__grid3{display:grid;grid-template-columns:1fr;gap:16px}\n@media (min-width:860px){.eco-tool__grid3{grid-template-columns:1fr 1fr 1fr}}\n.eco-tool__field{display:flex;flex-direction:column;gap:6px}\n.eco-tool__label{font-weight:600}\n.eco-tool__input{width:100%;height:44px;padding:0 12px;border:1px solid rgba(0,0,0,.20);border-radius:10px;background:#fff;box-sizing:border-box;font:inherit}\n.eco-tool select.eco-tool__input{appearance:none;-webkit-appearance:none;line-height:44px;padding-right:40px;background-image:linear-gradient(45deg,transparent 50%,rgba(0,0,0,.60) 50%),linear-gradient(135deg,rgba(0,0,0,.60) 50%,transparent 50%);background-position:calc(100% - 18px) 50%,calc(100% - 12px) 50%;background-size:6px 6px;background-repeat:no-repeat}\n.eco-tool__hint{font-size:.92em;opacity:.78;min-height:38px}\n.eco-tool__actions{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin-top:16px}\n.eco-tool__btn{padding:10px 22px}\n.eco-tool__btn--ghost{background:transparent!important;border:1px solid rgba(0,0,0,.20)!important}\n.eco-tool__btn--ghost:hover,.eco-tool__btn--ghost:focus{background:rgba(0,0,0,.06)!important;border-color:rgba(0,0,0,.35)!important}\n.eco-tool__error{min-height:1.2em;font-weight:600;flex:1 1 240px}\n.eco-tool__result{margin-top:16px}\n.eco-tool__subtitle{margin:0 0 10px}\n.eco-tool__cards{display:grid;gap:10px;grid-template-columns:1fr}\n@media (min-width:860px){.eco-tool__cards{grid-template-columns:1fr 1fr}}\n.eco-tool__card{border:1px solid rgba(0,0,0,.12);border-radius:12px;padding:12px}\n.eco-tool__card--wide{margin-top:10px}\n.eco-tool__metric-label{opacity:.85;font-weight:600}\n.eco-tool__metric-value{font-size:1.6em;font-weight:800;margin-top:6px;line-height:1.1}\n.eco-tool__metric-sub{opacity:.85;margin-top:6px}\n.eco-tool__bars{display:grid;gap:10px;margin-top:12px}\n.eco-tool__barrow{display:grid;grid-template-columns:120px 1fr 90px;gap:10px;align-items:center}\n@media (max-width:480px){.eco-tool__barrow{grid-template-columns:90px 1fr 70px}}\n.eco-tool__barlabel{font-weight:600;opacity:.9}\n.eco-tool__bartrack{border:1px solid rgba(0,0,0,.12);border-radius:999px;height:12px;overflow:hidden;background:rgba(0,0,0,.03)}\n.eco-tool__barfill{height:100%;width:0%;background:rgba(0,0,0,.25)}\n.eco-tool__barval{text-align:right;opacity:.85;white-space:nowrap}\n.eco-tool__note{margin:10px 0 0;opacity:.9}\n.eco-tool__muted{opacity:.8}\n.eco-tool__details{margin-top:14px}\n.eco-tool__summary{cursor:pointer;font-weight:700}\n.eco-tool__details-body{margin-top:10px}\n.eco-tool__text{margin:0 0 10px}\n.eco-tool__list{margin:0;padding-left:18px}\n<\/style>\n\n<script>\n(function(){\n  const S = \"91f2d\";\n  const el = (id) => document.getElementById(id + \"-\" + S);\n\n  const pmEl = el(\"eco-air-pm25\");\n  const hoursEl = el(\"eco-air-hours\");\n  const groupEl = el(\"eco-air-group\");\n\n  const calcBtn = el(\"eco-air-calc\");\n  const resetBtn = el(\"eco-air-reset\");\n  const errorEl = el(\"eco-air-error\");\n  const resultEl = el(\"eco-air-result\");\n\n  const aqiEl = el(\"eco-air-aqi\");\n  const categoryEl = el(\"eco-air-category\");\n  const riskEl = el(\"eco-air-risk\");\n  const riskSubEl = el(\"eco-air-risk-sub\");\n  const barsEl = el(\"eco-air-bars\");\n  const tipEl = el(\"eco-air-tip\");\n  const factorsEl = el(\"eco-air-factors\");\n\n  const BREAKPOINTS = [\n    { cLow: 0.0, cHigh: 12.0, aqiLow: 0, aqiHigh: 50, label: \"Good\" },\n    { cLow: 12.1, cHigh: 35.4, aqiLow: 51, aqiHigh: 100, label: \"Moderate\" },\n    { cLow: 35.5, cHigh: 55.4, aqiLow: 101, aqiHigh: 150, label: \"Unhealthy for Sensitive Groups\" },\n    { cLow: 55.5, cHigh: 150.4, aqiLow: 151, aqiHigh: 200, label: \"Unhealthy\" },\n    { cLow: 150.5, cHigh: 250.4, aqiLow: 201, aqiHigh: 300, label: \"Very Unhealthy\" },\n    { cLow: 250.5, cHigh: 500.4, aqiLow: 301, aqiHigh: 500, label: \"Hazardous\" }\n  ];\n\n  function setError(msg){ errorEl.textContent = msg || \"\"; }\n  function fmt(x){ return Math.round(x).toLocaleString(); }\n\n  function fillFactors(){\n    factorsEl.innerHTML = [\n      `<li><strong>Good:<\/strong> PM2.5 = 0.0\u201312.0 \u00b5g\/m\u00b3<\/li>`,\n      `<li><strong>Moderate:<\/strong> PM2.5 = 12.1\u201335.4 \u00b5g\/m\u00b3<\/li>`,\n      `<li><strong>Unhealthy for Sensitive Groups:<\/strong> PM2.5 = 35.5\u201355.4 \u00b5g\/m\u00b3<\/li>`,\n      `<li><strong>Unhealthy:<\/strong> PM2.5 = 55.5\u2013150.4 \u00b5g\/m\u00b3<\/li>`,\n      `<li><strong>Very Unhealthy \/ Hazardous:<\/strong> PM2.5 above 150.4 \u00b5g\/m\u00b3<\/li>`\n    ].join(\"\");\n  }\n\n  function computeAQI(pm){\n    const bp = BREAKPOINTS.find(b => pm >= b.cLow && pm <= b.cHigh) || BREAKPOINTS[BREAKPOINTS.length - 1];\n    const aqi = ((bp.aqiHigh - bp.aqiLow) \/ (bp.cHigh - bp.cLow)) * (pm - bp.cLow) + bp.aqiLow;\n    return { aqi: Math.round(aqi), label: bp.label };\n  }\n\n  function barRow(label, pct, value){\n    const p = Math.max(0, Math.min(100, pct));\n    return `\n      <div class=\"eco-tool__barrow\">\n        <div class=\"eco-tool__barlabel\">${label}<\/div>\n        <div class=\"eco-tool__bartrack\"><div class=\"eco-tool__barfill\" style=\"width:${p}%;\"><\/div><\/div>\n        <div class=\"eco-tool__barval\">${value}<\/div>\n      <\/div>\n    `;\n  }\n\n  function calculate(){\n    setError(\"\");\n\n    const pm = Number(pmEl.value);\n    const hours = Number(hoursEl.value);\n    const sensitive = groupEl.value === \"yes\";\n\n    if (!Number.isFinite(pm) || pm < 0 || !Number.isFinite(hours) || hours < 0 || hours > 24){\n      setError(\"Please enter valid values in all fields.\");\n      resultEl.hidden = true;\n      return;\n    }\n\n    const data = computeAQI(pm);\n    const exposureScore = (hours \/ 24) * 100;\n    let riskLabel = \"Low\";\n    let note = \"Air quality is relatively acceptable for most people.\";\n\n    if (data.aqi > 150 || (data.aqi > 100 && sensitive) || (data.aqi > 50 && sensitive && hours >= 8)) {\n      riskLabel = \"High\";\n      note = sensitive\n        ? \"Sensitive groups should reduce outdoor exposure and consider extra caution.\"\n        : \"Long outdoor exposure may be a concern at this level.\";\n    } else if (data.aqi > 50 || hours >= 8) {\n      riskLabel = \"Moderate\";\n      note = \"Some people may want to reduce prolonged outdoor activity.\";\n    }\n\n    aqiEl.textContent = `${fmt(data.aqi)}`;\n    categoryEl.textContent = data.label;\n\n    riskEl.textContent = riskLabel;\n    riskSubEl.textContent = note;\n\n    barsEl.innerHTML = [\n      barRow(\"AQI value\", Math.min(data.aqi \/ 500 * 100, 100), `${fmt(data.aqi)}`),\n      barRow(\"Daily exposure\", exposureScore, `${hours} h\/day`),\n      barRow(\"PM2.5 level\", Math.min(pm \/ 250 * 100, 100), `${pm.toFixed(1)} \u00b5g\/m\u00b3`)\n    ].join(\"\");\n\n    tipEl.textContent =\n      data.aqi <= 50 ? \"Tip: Air is generally acceptable at this level.\"\n      : data.aqi <= 100 ? \"Tip: Sensitive people may want to limit longer outdoor exposure.\"\n      : data.aqi <= 150 ? \"Tip: Consider reducing strenuous outdoor activity, especially for sensitive groups.\"\n      : \"Tip: Poor air quality \u2014 reducing outdoor exposure is usually a good idea.\";\n\n    resultEl.hidden = false;\n  }\n\n  function reset(){\n    setError(\"\");\n    pmEl.value = \"25\";\n    hoursEl.value = \"8\";\n    groupEl.value = \"no\";\n    resultEl.hidden = true;\n  }\n\n  fillFactors();\n  calcBtn.addEventListener(\"click\", calculate);\n  resetBtn.addEventListener(\"click\", reset);\n})();\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>Air Quality Index Calculator Estimate air quality category based on PM2.5 concentration using a simplified AQI model. PM2.5 level(\u00b5g\/m\u00b3) Fine particulate matter in micrograms per cubic meter. Exposure time(hours\/day) Time&hellip;<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":2666,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_sitemap_exclude":false,"_sitemap_priority":"","_sitemap_frequency":"","footnotes":""},"_links":{"self":[{"href":"https:\/\/bio-me.bio\/index.php?rest_route=\/wp\/v2\/pages\/3023"}],"collection":[{"href":"https:\/\/bio-me.bio\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/bio-me.bio\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/bio-me.bio\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/bio-me.bio\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3023"}],"version-history":[{"count":1,"href":"https:\/\/bio-me.bio\/index.php?rest_route=\/wp\/v2\/pages\/3023\/revisions"}],"predecessor-version":[{"id":3024,"href":"https:\/\/bio-me.bio\/index.php?rest_route=\/wp\/v2\/pages\/3023\/revisions\/3024"}],"up":[{"embeddable":true,"href":"https:\/\/bio-me.bio\/index.php?rest_route=\/wp\/v2\/pages\/2666"}],"wp:attachment":[{"href":"https:\/\/bio-me.bio\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3023"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}