co2_iaq.py
 1  # SPDX-FileCopyrightText: Copyright (c) 2022 JG for Cedar Grove Maker Studios
 2  #
 3  # SPDX-License-Identifier: MIT
 4  """
 5  `cedargrove_co2_iaq`
 6  ================================================================================
 7  
 8  Calculate the Indoor Quality Index (IAQ) from a CO2 concentration.
 9  
10  
11  * Author(s): JG
12  
13  Implementation Notes
14  --------------------
15  
16  **Hardware:**
17  
18  * Adafruit Adafruit PMSA003I Air Quality Breakout PID #4632
19  * Adafruit PM2.5 Air Quality Sensor and Breadboard Adapter Kit PID #3686
20  * Adafruit PM2.5 Air Quality Sensor with I2C Interface PID #4505
21  
22  **Software and Dependencies:**
23  
24  * Adafruit CircuitPython firmware for the supported boards:
25    https://circuitpython.org/downloads
26  
27  """
28  
29  __version__ = "0.0.0+auto.0"
30  __repo__ = "https://github.com/CedarGroveStudios/CircuitPython_AirQualityTools.git"
31  
32  # fmt: off
33  
34  # AQI color palette
35  RED    = 0xFF0000
36  YELLOW = 0xFFFF00
37  BLUE   = 0x0000FF
38  ORANGE = 0xFFA500
39  GREEN  = 0x00FF00
40  
41  # IAQ breakpoint list
42  #  CO2 ppm minimum, IAQ color, IAQ description
43  BREAKPOINTS = [
44      (5000, RED,    "DANGER"),
45      (2000, ORANGE, "WARNING"),
46      (1000, YELLOW, "POOR"),
47      ( 100, GREEN,  "GOOD"),
48  ]
49  # fmt: on
50  
51  
52  def co2_ppm_to_quality(co2_ppm):
53      """Calculate the Indoor Air Quality Index (IAQ) as derived from CO2 ppm
54      concentration. Returns a data valid flag, CO2 input concentration value, the
55      RGB warning color integer value, and the corresponding US English
56      description or warning.
57  
58      :param float co2_ppm: The CO2 concentration value in ppm. Range is 0
59      to 6000 ppm. No default value.
60      """
61  
62      if co2_ppm < 0:
63          return False, -1, BLUE, "INVALID"
64  
65      if co2_ppm > 6000:
66          return False, -1, RED, "OVERRANGE"
67  
68      # Check sensor reading using EPA breakpoints
69      for _, (co2_ppm_min, iaq_color, iaq_desc) in enumerate(BREAKPOINTS):
70          if co2_ppm > co2_ppm_min:
71              return True, co2_ppm, iaq_color, iaq_desc
72  
73      return False, -1, BLUE, "INVALID"