2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.airquality.internal.api;
15 import static org.openhab.binding.airquality.internal.api.Index.*;
17 import java.math.BigDecimal;
18 import java.math.RoundingMode;
21 import javax.measure.Unit;
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.openhab.core.library.types.QuantityType;
25 import org.openhab.core.library.unit.Units;
26 import org.openhab.core.types.State;
27 import org.openhab.core.types.UnDefType;
30 * The {@link Pollutant} enum lists all measures
31 * of the AQI Level associated with their standard color.
33 * @author Gaƫl L'hopital - Initial contribution
36 public enum Pollutant {
37 PM25(Units.MICROGRAM_PER_CUBICMETRE, 1,
38 Set.of(SensitiveGroup.RESPIRATORY, SensitiveGroup.HEART, SensitiveGroup.ELDERLY, SensitiveGroup.CHILDREN),
39 new ConcentrationRange(0, 12, ZERO), new ConcentrationRange(12.1, 35.4, FIFTY),
40 new ConcentrationRange(35.5, 55.4, ONE_HUNDRED), new ConcentrationRange(55.5, 150.4, ONE_HUNDRED_FIFTY),
41 new ConcentrationRange(150.5, 250.4, TWO_HUNDRED), new ConcentrationRange(250.5, 350.4, THREE_HUNDRED),
42 new ConcentrationRange(350.5, 500.4, FOUR_HUNDRED)),
43 PM10(Units.MICROGRAM_PER_CUBICMETRE, 0, Set.of(SensitiveGroup.RESPIRATORY), new ConcentrationRange(0, 54, ZERO),
44 new ConcentrationRange(55, 154, FIFTY), new ConcentrationRange(155, 254, ONE_HUNDRED),
45 new ConcentrationRange(255, 354, ONE_HUNDRED_FIFTY), new ConcentrationRange(355, 424, TWO_HUNDRED),
46 new ConcentrationRange(425, 504, THREE_HUNDRED), new ConcentrationRange(505, 604, FOUR_HUNDRED)),
47 NO2(Units.PARTS_PER_BILLION, 0,
48 Set.of(SensitiveGroup.ASTHMA, SensitiveGroup.RESPIRATORY, SensitiveGroup.ELDERLY, SensitiveGroup.CHILDREN),
49 new ConcentrationRange(0, 53, ZERO), new ConcentrationRange(54, 100, FIFTY),
50 new ConcentrationRange(101, 360, ONE_HUNDRED), new ConcentrationRange(361, 649, ONE_HUNDRED_FIFTY),
51 new ConcentrationRange(650, 1249, TWO_HUNDRED), new ConcentrationRange(1250, 1649, THREE_HUNDRED),
52 new ConcentrationRange(1650, 2049, FOUR_HUNDRED)),
53 SO2(Units.PARTS_PER_BILLION, 0, Set.of(SensitiveGroup.ASTHMA), new ConcentrationRange(0, 35, ZERO),
54 new ConcentrationRange(36, 75, FIFTY), new ConcentrationRange(76, 185, ONE_HUNDRED),
55 new ConcentrationRange(186, 304, ONE_HUNDRED_FIFTY), new ConcentrationRange(305, 604, TWO_HUNDRED),
56 new ConcentrationRange(605, 804, THREE_HUNDRED), new ConcentrationRange(805, 1004, FOUR_HUNDRED)),
57 CO(Units.PARTS_PER_BILLION, 1, Set.of(SensitiveGroup.HEART), new ConcentrationRange(0, 4.4, ZERO),
58 new ConcentrationRange(4.5, 9.4, FIFTY), new ConcentrationRange(9.5, 12.4, ONE_HUNDRED),
59 new ConcentrationRange(12.5, 15.4, ONE_HUNDRED_FIFTY), new ConcentrationRange(15.5, 30.4, TWO_HUNDRED),
60 new ConcentrationRange(30.5, 40.4, THREE_HUNDRED), new ConcentrationRange(40.5, 50.4, FOUR_HUNDRED)),
61 O3(Units.PARTS_PER_BILLION, 3, Set.of(SensitiveGroup.CHILDREN, SensitiveGroup.ASTHMA),
62 new ConcentrationRange(0, 54, ZERO), new ConcentrationRange(55, 124, FIFTY),
63 new ConcentrationRange(125, 164, ONE_HUNDRED), new ConcentrationRange(165, 204, ONE_HUNDRED_FIFTY),
64 new ConcentrationRange(205, 404, TWO_HUNDRED), new ConcentrationRange(405, 504, THREE_HUNDRED),
65 new ConcentrationRange(505, 604, FOUR_HUNDRED));
67 public static enum SensitiveGroup {
75 public final Set<SensitiveGroup> sensitiveGroups;
76 private final Unit<?> unit;
77 private final Set<ConcentrationRange> breakpoints;
78 private final int scale;
80 Pollutant(Unit<?> unit, int scale, Set<SensitiveGroup> groups, ConcentrationRange... concentrations) {
81 this.sensitiveGroups = groups;
83 this.breakpoints = Set.of(concentrations);
87 public State toQuantity(double idx) {
88 for (ConcentrationRange concentration : breakpoints) {
89 double equivalent = concentration.getConcentration(idx);
90 if (equivalent != -1) {
91 return new QuantityType<>(BigDecimal.valueOf(equivalent).setScale(scale, RoundingMode.HALF_UP), unit);
94 return UnDefType.UNDEF;