def check_sensor(parent_sensor_id: str) -> None:
    resp = requests.get(
        "https://www.purpleair.com/json?show={}".format(parent_sensor_id))
    if resp.status_code != 200:
        raise Exception("got {} responde code from purpleair".format(
            resp.status_code))

    try:
        resp_json = resp.json()
    except ValueError:
        return
    for sensor in resp_json.get("results"):
        sensor_id = sensor.get("ID")
        name = sensor.get("Label")
        stats = sensor.get("Stats")
        temp_f = sensor.get("temp_f")
        humidity = sensor.get("humidity")
        pressure = sensor.get("pressure")
        if stats:
            stats = json.loads(stats)
            pm25_10min_raw = stats.get("v1")
            if pm25_10min_raw:
                pm25_10min = max(float(pm25_10min_raw), 0)
                i_aqi = aqi.to_iaqi(aqi.POLLUTANT_PM25,
                                    str(pm25_10min),
                                    algo=aqi.ALGO_EPA)
                aqi_g.labels(parent_sensor_id=parent_sensor_id,
                             sensor_id=sensor_id,
                             sensor_name=name).set(i_aqi)

                # https://www.aqandu.org/airu_sensor#calibrationSection
                pm25_10min_AQandU = 0.778 * float(pm25_10min) + 2.65
                i_aqi_AQandU = aqi.to_iaqi(aqi.POLLUTANT_PM25,
                                           str(pm25_10min_AQandU),
                                           algo=aqi.ALGO_EPA)
                aqi_AQandU_g.labels(parent_sensor_id=parent_sensor_id,
                                    sensor_id=sensor_id,
                                    sensor_name=name).set(i_aqi_AQandU)

                # https://www.lrapa.org/DocumentCenter/View/4147/PurpleAir-Correction-Summary
                pm25_10min_LRAPA = max(0.5 * float(pm25_10min) - 0.66, 0)
                i_aqi_LRAPA = aqi.to_iaqi(aqi.POLLUTANT_PM25,
                                          str(pm25_10min_LRAPA),
                                          algo=aqi.ALGO_EPA)
                aqi_LRAPA_g.labels(parent_sensor_id=parent_sensor_id,
                                   sensor_id=sensor_id,
                                   sensor_name=name).set(i_aqi_LRAPA)

        if temp_f:
            temp_g.labels(parent_sensor_id=parent_sensor_id,
                          sensor_id=sensor_id,
                          sensor_name=name).set(float(temp_f))
        if pressure:
            pressure_g.labels(parent_sensor_id=parent_sensor_id,
                              sensor_id=sensor_id,
                              sensor_name=name).set(float(pressure))
        if humidity:
            humidity_g.labels(parent_sensor_id=parent_sensor_id,
                              sensor_id=sensor_id,
                              sensor_name=name).set(float(humidity))
def get_air_quality():
    # sudo usermod -a -G dialout yourusername
    # https://cdn.sparkfun.com/assets/parts/1/2/2/7/5/Laser_Dust_Sensor_Control_Protocol_V1.3.pdf

    # Start in reporting mode : query/home/pi/.local/bin
    sensor = SDS011("/dev/ttyUSB0", use_query_mode=True)
    sensor.set_work_period(work_time=0)  # work_time is continuous
    logging.debug('waking sensor')
    sensor.sleep(sleep=False)  # wake sensor
    logging.debug('waiting 30 seconds')
    time.sleep(30)  # capture 30 seconds of data
    logging.debug('running sensor query')
    result = sensor.query()
    logging.debug('sleeping sensor')
    sensor.sleep()  # sleep sensor
    # print(f"    PMT2.5: {pm25} μg/m3    PMT10 : {pm10} μg/m3")
    if result is None:
        logging.error("Sensor returned None")
        return None
    pm25, pm10 = result
    data = {
        'pm25': str(pm25),
        'pm10': str(pm10),
        'aqipm25': str(aqi.to_iaqi(aqi.POLLUTANT_PM25, str(pm25))),
        'aqipm10': str(aqi.to_iaqi(aqi.POLLUTANT_PM10, str(pm10)))
    }
    return data
Пример #3
0
def get_reading(field: str, monitor_id: int):

    sql = """
        SELECT
            ch_a.label,
            ch_a.""" + field + """,
            ch_b.""" + field + """,
            FROM_UNIXTIME(ch_a.recorded_at)
        FROM
            air_quality ch_a
        JOIN
            air_quality ch_b
        ON
            ch_a.recorded_at = ch_b.recorded_at
            AND ch_b.id = ch_a.id + 1
        WHERE
            ch_a.id = %(monitor_id)s
            AND ch_a.LastSeen > UNIX_TIMESTAMP(NOW() - INTERVAL 20 MINUTE)
        ORDER BY
            ch_a.recorded_at DESC
        LIMIT 1
    """

    bind = {"field": field, "monitor_id": monitor_id}

    cur.execute(sql, bind)
    response = cur.fetchone()

    try:
        # If one channel or the other is malfunctioning and reading zero, take the AQI value of the good channel
        if response[1] == 0:
            myaqi = aqi.to_iaqi(aqi.POLLUTANT_PM25,
                                response[2],
                                algo=aqi.ALGO_EPA)
        if response[2] == 0:
            myaqi = aqi.to_iaqi(aqi.POLLUTANT_PM25,
                                response[1],
                                algo=aqi.ALGO_EPA)

        # If they both have values, average them
        if response[1] > 0 and response[2] > 0:
            myaqi = aqi.to_iaqi(aqi.POLLUTANT_PM25,
                                (response[1] + response[2]) / 2,
                                algo=aqi.ALGO_EPA)

        data = Reading(id=monitor_id,
                       label=response[0],
                       field=field,
                       A=response[1],
                       B=response[2],
                       avg=(response[1] + response[2]) / 2,
                       time=response[3],
                       pct_diff=(response[1] - response[2]) / response[1],
                       aqi=myaqi,
                       aqi_level=get_aqi_level(myaqi))
    except:
        data = None

    return data
Пример #4
0
def process_data(d):
    r = struct.unpack('<HHxxBB', d[2:])
    #    pm25 = r[0]/10.0
    pm25 = aqi.to_iaqi(aqi.POLLUTANT_PM25, r[0] / 10.0, algo=aqi.ALGO_EPA)
    #    pm10 = r[1]/10.0
    pm10 = aqi.to_iaqi(aqi.POLLUTANT_PM10, r[1] / 10.0, algo=aqi.ALGO_EPA)
    checksum = sum(ord(v) for v in d[2:8]) % 256
    return [pm25, pm10]
Пример #5
0
def predict():
    """Predict tomorrow AQI value and PM2.5 value using XGBoost"""
    result = {"Yangon": {}, "Mandalay": {}}
    # load XGBoost model
    loaded_model = joblib.load("app/static/model.sav")
    # get current month
    month = datetime.now().month
    # get current season
    season = get_season(month)
    air = requests.get(
        'https://www.purpleair.com/json?show=9578|33329|26359|9618|26285|31425|51727|20389|36553|29855|33255|34545'
    )
    air = air.json()
    air = preprocessing_all(air)
    for a in air:
        r = {}
        data = {}
        # Yangon = 1, Mandalay = 0
        city = 1 if a["City"] == "Yangon" else 0
        temp = a["Temperature"]
        humd = a["Humidity"]
        center = 0
        # convert center name into respective value
        center = get_center(a["Label"])
        p_data = [[city, center, month, season, int(temp), int(humd)]]
        # convert into pandas DataFrame
        p_data = pd.DataFrame(p_data,
                              columns=[
                                  'City', 'Center', 'Month', 'Season',
                                  'Temperature_F', 'Humidity_%'
                              ])
        # predict
        aqi_p = loaded_model.predict(p_data)
        # convert into int value
        r["PM2.5"] = int(float(aqi_p.astype(str)[0]))
        # calculate AQI value
        r["AQI"] = int(
            aqi.to_iaqi(aqi.POLLUTANT_PM25, str(r["PM2.5"]),
                        algo=aqi.ALGO_EPA))
        data[a["Label"]] = r
        if city:
            result["Yangon"].update(data)
        else:
            result["Mandalay"].update(data)

    final = []
    # calculate average AQI and PM2.5 values
    for key, values in result.items():
        a = []
        pm = []
        for k, v in values.items():
            a.append(v["AQI"])
            pm.append(v["PM2.5"])
        a = float("{:.2f}".format(sum(a) / len(a)))
        pm = float("{:.2f}".format(sum(pm) / len(pm)))
        final.append({"Label": key, "AQI": a, "PM2.5": pm})

    final = jsonify(final)
    final.headers.add("Access-Control-Allow-Origin", "*")
    return final
Пример #6
0
def preprocessing_one(api_json):
    """Accept input json from purpleair API
    Return processed data in list format
    """
    result = {}
    result["Label"] = api_json["results"][0]["Label"]
    result["Lat"] = api_json["results"][0]["Lat"]
    result["Lon"] = api_json["results"][0]["Lon"]
    result["PM1_0"] = api_json["results"][0]["pm1_0_atm"]
    result["PM2_5"] = api_json["results"][0]["pm2_5_atm"]
    result["PM10_0"] = api_json["results"][0]["pm10_0_atm"]
    result["Humidity"] = api_json["results"][0]["humidity"]
    result["Temperature"] = api_json["results"][0]["temp_f"]
    result["Pressure"] = api_json["results"][0]["pressure"]
    # separate Yangon an Mandalay
    if "Mandalay" in api_json["results"][0]["Label"]:
        result["City"] = "Mandalay"
    else:
        result["City"] = "Yangon"
    # calculate AQI using PM2.5 value
    result["AQI"] = int(
        aqi.to_iaqi(aqi.POLLUTANT_PM25,
                    str(api_json["results"][0]["pm2_5_atm"]),
                    algo=aqi.ALGO_EPA))
    return result
Пример #7
0
 def handler(self, connection, addr):
     pid = os.getpid()
     BUFFER = 1024
     print(f"Handling connection {pid}.")
     received = bytes()
     while True:
         try:
             data = connection.recv(BUFFER)
         except SOCKET_TIMEOUT:
             break
         received += data
         # There is an extra 33 bytes that comes through the connection
         if sys.getsizeof(data) < (BUFFER + 33):
             break
         else:
             # Set a timeout. This is needed if the data is exactly the
             # length of the buffer - in that case without a timeout
             # we will get stuck in the recv part of the loop
             connection.settimeout(0.5)
     request = pickle.loads(data)
     if request.lower() == "time":
         response = pickle.dumps("{}".format(datetime.now()))
     elif request.lower() == "weather":
         response = self.get_weather()
     elif request.lower() == "airquality":
         myaqi = aqi.to_iaqi(aqi.POLLUTANT_PM25, '12', algo=aqi.ALGO_EPA)
         response = f"Air quality index is: {myaqi}"
     else:
         response = "Invalid command"
     connection.send(pickle.dumps(response))
     print(f"Returning response {response} to requester.")
     connection.close()
Пример #8
0
def preprocessing_all(api_json):
    """Accept input json from purpleair API
    Return processed data in list format
    """
    result = []
    count = 1
    # get data from 'result' key
    for apis in api_json["results"]:
        # get data only from parent Air Quality Meters
        if not "ParentID" in apis:
            one_res = {}
            one_res["Label"] = apis["Label"]
            one_res["Lat"] = apis["Lat"]
            one_res["Lon"] = apis["Lon"]
            one_res["PM1_0"] = apis["pm1_0_atm"]
            one_res["PM2_5"] = apis["pm2_5_atm"]
            one_res["PM10_0"] = apis["pm10_0_atm"]
            one_res["Humidity"] = apis["humidity"]
            one_res["Temperature"] = apis["temp_f"]
            one_res["Pressure"] = apis["pressure"]
            # calculate AQI using PM2.5 value
            one_res["AQI"] = int(
                aqi.to_iaqi(aqi.POLLUTANT_PM25,
                            str(apis["pm2_5_atm"]),
                            algo=aqi.ALGO_EPA))
            one_res["ID"] = count
            count = count + 1
            # separate Yangon an Mandalay
            if "Mandalay" in apis["Label"]:
                one_res["City"] = "Mandalay"
            else:
                one_res["City"] = "Yangon"
            result.append(one_res)
    return result
Пример #9
0
 def epa_pm100_aqi(self):
     # CONSIDER: Instead of averaging the two
     # sensors, should we just pick one?
     try:
         pm100 = statistics.mean(
             filter(bool, (self.pm100_a_avg, self.pm100_b_avg)))
         return aqi.to_iaqi(aqi.POLLUTANT_PM10, pm100, algo=aqi.ALGO_EPA)
     except statistics.StatisticsError:
         pass
Пример #10
0
 def apply_aqi(self, row, aqi_measure, column_name):
     try:
         return aqi.to_iaqi(aqi_measure,
                            str(row[column_name]),
                            algo=aqi.ALGO_EPA)
     except IndexError:
         # the value is too big for the calculator, will calculate the max value instead.
         return 501
     except Exception as e:
         print(e)
Пример #11
0
def get_particle_measure():
    port = "/dev/ttyS0"  # Set this to your serial port.
    baudrate = 9600

    # Prepare serial connection.
    ser = Serial(port,
                 baudrate=baudrate,
                 bytesize=EIGHTBITS,
                 parity=PARITY_NONE,
                 stopbits=STOPBITS_ONE)
    ser.flushInput()
    HEADER_BYTE = b"\xAA"
    COMMANDER_BYTE = b"\xC0"
    TAIL_BYTE = b"\xAB"
    byte, previousbyte = b"\x00", b"\x00"
    for i in range(10):
        previousbyte = byte
        byte = ser.read(size=1)
        # We got a valid packet header.
        if previousbyte == HEADER_BYTE and byte == COMMANDER_BYTE:
            packet = ser.read(size=8)  # Read 8 more bytes
            # Decode the packet - little endian, 2 shorts for pm2.5 and pm10, 2 ID bytes, checksum.
            readings = struct.unpack('<HHcccc', packet)

            # Measurements.
            pm_25 = readings[0] / 10.0
            pm_10 = readings[1] / 10.0

            # ID
            id = packet[4:6]
            # Prepare checksums.
            checksum = readings[4][0]
            calculated_checksum = sum(packet[:6]) & 0xFF
            checksum_verified = (calculated_checksum == checksum)

            # Message tail.
            tail = readings[5]

            if tail == TAIL_BYTE and checksum_verified:
                aqi_2_5 = aqi.to_iaqi(aqi.POLLUTANT_PM25, str(pm_25))
                aqi_10 = aqi.to_iaqi(aqi.POLLUTANT_PM10, str(pm_10))
                return [(pm_25, aqi_2_5), (pm_10, aqi_10)]
    return [(None, None), (None, None)]
def get_outdoor_data():
    # https://docs.google.com/document/d/15ijz94dXJ-YAZLi9iZ_RaBwrZ4KtYeCy08goGBwnbCU/edit
    result = requests.get(
        f"https://www.purpleair.com/json?key={config['PURPLE_AIR_KEY']}&show={config['PURPLE_AIR_DEVICE_ID']}"
    )
    field_map = {
        'pm2_5_atm': 'pm25',
        'pm10_0_atm': 'pm10',
        'LastSeen': 'LastSeen',
        'humidity': 'humidity',
        'temp_f': 'temp_f',
        'pressure': 'pressure'
    }
    data = {}
    logging.debug(json.dumps(result.json(), indent=4))
    for record in result.json().get('results', []):
        # https://github.com/MazamaScience/AirSensor/blob/master/documents/PurpleAir_CF=ATM_vs_CF=1.md
        for field in field_map.keys():
            if field in record:
                if field_map[field] not in data:
                    data[field_map[field]] = record[field]
                else:
                    if field in ['pm2_5_atm', 'pm10_0_atm']:
                        # Average the existing measurement in data with the new
                        # second measurement in record
                        data[field_map[field]] = "{:.2f}".format(
                            sum([
                                float(data[field_map[field]]),
                                float(record[field])
                            ]) / 2)
                    # We'll assume LastSeen values are similar
                    # TODO : Check for very old LastSeen values and error out or something
    data['aqipm25'] = str(aqi.to_iaqi(aqi.POLLUTANT_PM25, str(data['pm25'])))
    data['aqipm10'] = str(aqi.to_iaqi(aqi.POLLUTANT_PM10, str(data['pm10'])))
    data['temp_f'] = f"{float(data['temp_f']) + PURPLE_AIR_TEMP_OFFSET:.2f}"

    return data
Пример #13
0
    def test_create_aqis_correctly(self):
        print("Testing aqis correctly")
        deriver = Derive()  # create Cleaner object
        cleaner = Cleaner()  # create Cleaner object
        df = cleaner.load_csv_data('data')
        cleaner.clean_data(df)
        df_group = deriver.group_data_by_day(df)
        deriver.create_date_from_string(df_group, 'month', 'day', 'year')
        deriver.calc_aqis(df)

        aqi_value = df.iloc[10]['aqi_PM10']
        PM10_value = df.iloc[10]['PM10']
        test_aqi_value = aqi.to_iaqi(aqi.POLLUTANT_PM10, PM10_value, algo=aqi.ALGO_EPA)

        self.assertEqual(aqi_value, test_aqi_value)  # make sure the datframe has at least some rows.
Пример #14
0
    def read_pm_sensor(self):
        if self.dummy_data == True:
            pm = (random.randrange(0, 400, 1) / 2,
                  random.randrange(0, 400, 2) / 4, random.randrange(0, 250, 5),
                  random.randrange(0, 250, 5))
            return pm
        self.pm_sensor.sleep(sleep=False)
        pm25reads = []
        pm10reads = []
        time.sleep(self.measurement_delay)
        readcount = 0
        while readcount < 3:
            data = self.pm_sensor.query()
            pm25reads.append(data[0])
            pm10reads.append(data[1])
            time.sleep(2)
            readcount += 1
        self.pm_sensor.sleep()

        pm25raw = median(pm25reads)
        pm10raw = median(pm10reads)
        pm25aqi = aqi.to_iaqi(aqi.POLLUTANT_PM25, pm25raw, algo=aqi.ALGO_EPA)
        pm10aqi = aqi.to_iaqi(aqi.POLLUTANT_PM10, pm10raw, algo=aqi.ALGO_EPA)
        return (pm25raw, pm10raw, pm25aqi, pm10aqi)
Пример #15
0
def main():
    while True:
        with open('/home/pi/shared/src/airquality/aqi.json') as f:
            data = json.load(f)

        pm25 = []
        pm10 = []
        for element in data:
            # print(element)
            pm25.append(element['pm25'])
            pm10.append(element['pm10'])

        # print(statistics.mean(pm25))
        # print(statistics.median(pm25))
        # print('')
        # print(statistics.mean(pm10))
        # print(statistics.median(pm10))

        cur_aqi = aqi.to_iaqi(aqi.POLLUTANT_PM25,
                              statistics.mean(pm25),
                              algo=aqi.ALGO_EPA)

        # format and display
        print("AQI:\t%d" % cur_aqi)

        out_text = "%d" % cur_aqi

        oled.fill(0)
        oled.show()
        image = Image.new("1", (oled.width, oled.height))
        draw = ImageDraw.Draw(image)

        # oled.text(out_text, 5, 15, 1)
        # oled.show()

        (font_width, font_height) = font.getsize(out_text)
        draw.text((oled.width // 2 - font_width // 2,
                   oled.height // 2 - font_height // 2),
                  out_text,
                  font=font,
                  fill=255)

        oled.image(image)
        oled.show()

        time.sleep(300)
Пример #16
0
def get_reading(monitor):

    sql = """
        SELECT
            (aq1.PM2_5Value + aq2.PM2_5Value) / 2 as channel_avg,
            aq1.label,
            from_unixtime(aq1.recorded_at),
            aq1.record_id
        FROM
            air_quality aq1
        JOIN
            air_quality aq2
        ON
            aq1.record_id + 1 = aq2.record_id
        WHERE
            aq1.ID = %s
            AND aq1.AQI IS NULL
            AND aq1.recorded_at - aq1.lastseen < 1000; 
        """

    cur.execute(sql, monitor)
    conn.commit()
    response = cur.fetchall()

    print("Processing ", len(response), " readings")
    sql2 = """
        UPDATE
            air_quality aq
        SET
            AQI = %(aqi)s
        WHERE
            aq.record_id = %(record_id)s 
            OR aq.record_id = %(record_id)s + 1
    """
    updates = []

    for r in response:

        myaqi = aqi.to_iaqi(aqi.POLLUTANT_PM25, r[0], algo=aqi.ALGO_EPA)
        update = {"aqi": myaqi, "record_id": r[3]}
        print(update)
        updates.append(update)
        cur.execute(sql2, update)
        conn.commit()
Пример #17
0
    def get_aqi(self):
        if self.data_type == 'NO2':
            constant = aqi.POLLUTANT_NO2_1H
        elif self.data_type == 'O3':
            constant = aqi.POLLUTANT_O3_8H
        elif self.data_type == 'CO':
            constant = aqi.POLLUTANT_CO_8H
        elif self.data_type == 'SO2':
            constant = aqi.POLLUTANT_SO2_1H
        elif self.data_type == 'PM25':
            constant = aqi.POLLUTANT_PM25
        else:
            return 0

        try:
            my_aqi = aqi.to_iaqi(constant,
                                 str(self.get_avg()),
                                 algo=aqi.ALGO_EPA)
        except Exception as e:
            print 'out of range'
            return 0
        return my_aqi
Пример #18
0
def saveData():
    while True:
        max_data = open('max_data_size.txt', 'r')
        max_size = max_data.readline()
        max_data.close()
        start = time.time()  # takes unix time at start of using sensor to ensure stable readings
        try:
            ppm25 = sensor.query()[0]  # Query the sensor and then grabs the pm25 result from the list
            # The below lines figure out if the number can be converted to a AQI number. Must be 500 or below
            if ppm25 < 500:
                iaqi = aqi.to_iaqi(aqi.POLLUTANT_PM25, ppm25, algo=aqi.ALGO_EPA)  # Converts micrograms per m^3 to aqi
            else:
                iaqi = 500  # If ppm25 is bigger than 500 iaqi is automatically 500
        except:
            ppm25 = 'NO_DATA'
        data_file_size = os.stat('data.csv').st_size / (1024*1024)
        while float(max_size) <= data_file_size:  # While the size of the file is bigger than the max file size
            lines = list()  # makes empty list
            with open('data.csv', 'r') as readFile:  # Opens the data file
                reader = csv.reader(readFile)  # reads file into variable
                for row in reader:  # appends all lines into the list
                    lines.append(row)
                for line in lines:  # Deletes the first line from the list
                    lines.remove(line)
                    break  # has to break out of loop so as only to delete the first line from the list
            with open('data.csv', 'w', newline='') as writeFile:  # opens the file as write
                writer = csv.writer(writeFile)  # makes csv writer object
                writer.writerows(lines)  # writes the list to the file without the first item
        if ppm25 != 'NO_DATA':
            toappend = [iaqi, time.time()]  # Data formatted ready to be appended to the data file
            with open('data.csv', 'a+', newline='') as appendFile:
                append = csv.writer(appendFile)
                append.writerow(toappend)
        end = time.time()  # Takes time at end to ensure stable reading from sensor
        difference = 3 - (end - start)
        if difference > 0:
            time.sleep(difference)  # Ensures that the readings from the sensor are equally spaced apart
Пример #19
0
def handle_client(conn, addr):
    print(f"[NEW CONNECTION] {addr} connected.\n")

    connected = True
    while connected:
        msg_length = conn.recv(HEADER).decode(FORMAT)
        if msg_length:
            msg_length = int(msg_length)
            msg = conn.recv(msg_length).decode(FORMAT)

            if msg == DISCONNECT_MESSAGE:
                print(f"[DISCONNECTING] {addr}")
                connected = False
                break

            print(f"[{addr}] {msg}\n")
            if "weather" in msg.lower():
                conn.send(
                    f"The temperature today will be: {Data.temperature('celsius')['temp']}C"
                    .encode(FORMAT))
            elif "time" in msg.lower():
                now = datetime.now()
                current_time = now.strftime("%H:%M:%S")
                conn.send(
                    f"The time right now is: {current_time}".encode(FORMAT))
            elif "air quality" in msg.lower() or "aq" in msg.lower():
                myaqi = python - aqi.to_iaqi(python - aqi.POLLUTANT_PM25,
                                             '12',
                                             algo=python - aqi.ALGO_EPA)
                conn.send(f"The AQI (Air Quality Index) is: {myaqi}AQI".encode(
                    FORMAT))
            else:
                conn.send(
                    f"The command doesn't exist, please try again!".encode(
                        FORMAT))
    conn.close()
Пример #20
0
def conv_aqi(pm25, pm10):
    aqi25 = aqi.to_iaqi(aqi.POLLUTANT_PM25, str(pm25))
    aqi10 = aqi.to_iaqi(aqi.POLLUTANT_PM10, str(pm10))
    return aqi25, aqi10
Пример #21
0
#!/usr/bin/env python3
from sds011 import SDS011
import socket
import time
import aqi

UDP_IP = "10.0.0.20"
UDP_PORT = 1027
sock = socket.socket(
    socket.AF_INET,  # Internet
    socket.SOCK_DGRAM)  # UDP
sensor = SDS011("/dev/ttyUSB0", use_query_mode=True)
while True:
    sensor.sleep(sleep=False)
    time.sleep(30)
    data = sensor.query()
    #convert to AQI from micrograms/m^3
    aqi_2_5 = aqi.to_iaqi(aqi.POLLUTANT_PM25, str(data[0]))
    aqi_10 = aqi.to_iaqi(aqi.POLLUTANT_PM10, str(data[1]))
    aqi_data = (str(aqi_2_5).encode('utf-8'), str(aqi_10).encode('utf-8'))
    print(data)
    print(aqi_data)
    sensor.sleep()
    #   sock.sendto(str(data.encode('utf-8')), (UDP_IP,UDP_PORT))
    sock.sendto(str(aqi_data).encode('utf-8'), (UDP_IP, UDP_PORT))
    time.sleep(300)
Пример #22
0
def conv_aqi(pmt_2_5, pmt_10):
    aqi_2_5 = aqi.to_iaqi(aqi.POLLUTANT_PM25, str(pmt_2_5))
    aqi_10 = aqi.to_iaqi(aqi.POLLUTANT_PM10, str(pmt_10))
    return aqi_2_5, aqi_10
Пример #23
0
    def getData(self):

        for sensorID, devID in self.sensorDevices.iteritems():

            device = indigo.devices[devID]

            url = "https://www.purpleair.com/json?show={}".format(sensorID)
            try:
                response = requests.get(url)
            except requests.exceptions.RequestException as err:
                self.logger.error(u"{}: getData RequestException: {}".format(
                    device.name, err))
            else:
                self.logger.threaddebug(
                    u"{}: getData for sensor {}:\n{}".format(
                        device.name, sensorID, response.text))
                sensorData = response.json()['results'][0]

                sensor_aqi = int(
                    aqi.to_iaqi(aqi.POLLUTANT_PM25,
                                sensorData['PM2_5Value'],
                                algo=aqi.ALGO_EPA))
                state_list = [{
                    'key': 'sensorValue',
                    'value': sensor_aqi,
                    'uiValue': "{}".format(sensor_aqi)
                }, {
                    'key': 'Temperature',
                    'value': sensorData['temp_f'],
                    'decimalPlaces': 0
                }, {
                    'key': 'Humidity',
                    'value': sensorData['humidity'],
                    'decimalPlaces': 0
                }, {
                    'key': 'Pressure',
                    'value': sensorData['pressure'],
                    'decimalPlaces': 2
                }, {
                    'key': 'Label',
                    'value': sensorData['Label']
                }, {
                    'key': 'Latitude',
                    'value': sensorData['Lat']
                }, {
                    'key': 'Longitude',
                    'value': sensorData['Lon']
                }, {
                    'key': 'RSSI',
                    'value': sensorData['RSSI']
                }, {
                    'key': 'Uptime',
                    'value': sensorData['Uptime']
                }, {
                    'key': 'Version',
                    'value': sensorData['Version']
                }, {
                    'key': 'Hardware',
                    'value': sensorData['DEVICE_HARDWAREDISCOVERED']
                }, {
                    'key': 'p_0_3_um',
                    'value': sensorData['p_0_3_um']
                }, {
                    'key': 'p_0_5_um',
                    'value': sensorData['p_0_5_um']
                }, {
                    'key': 'p_10_0_um',
                    'value': sensorData['p_10_0_um']
                }, {
                    'key': 'p_1_0_um',
                    'value': sensorData['p_1_0_um']
                }, {
                    'key': 'p_2_5_um',
                    'value': sensorData['p_2_5_um']
                }, {
                    'key': 'p_5_0_um',
                    'value': sensorData['p_5_0_um']
                }, {
                    'key': 'pm10_0_atm',
                    'value': sensorData['pm10_0_atm']
                }, {
                    'key': 'pm10_0_cf_1',
                    'value': sensorData['pm10_0_cf_1']
                }, {
                    'key': 'pm1_0_atm',
                    'value': sensorData['pm1_0_atm']
                }, {
                    'key': 'pm1_0_cf_1',
                    'value': sensorData['pm1_0_cf_1']
                }, {
                    'key': 'pm2_5_atm',
                    'value': sensorData['pm2_5_atm']
                }, {
                    'key': 'pm2_5_cf_1',
                    'value': sensorData['pm2_5_cf_1']
                }]
                device.updateStatesOnServer(state_list)
Пример #24
0
# Monitoring AIR Quality with Raspberry, Adafruit and SDS sensor https://www.raspberrypi.org/blog/monitor-air-quality-with-a-raspberry-pi/
import serial, time
import aqi
from Adafruit_IO import Client
aio = Client(ADAFRUIT_USER, ADAFRUIT_PW)

ser = serial.Serial('/dev/ttyUSB0')

while True:
    data = []
    for index in range(0, 10):
        datum = ser.read()
        data.append(datum)

    pmtofive = int.from_bytes(b''.join(data[2:4]), byteorder='little') / 10
    pmtofive_aqi = str(
        aqi.to_iaqi(aqi.POLLUTANT_PM25, pmtofive, algo=aqi.ALGO_EPA))
    #print('PM 2.5: ', pmtofive)
    #print('PM 2.5 AQI', pmtofive_aqi)
    aio.send('air25', pmtofive)
    aio.send('air25-aqi', pmtofive_aqi)
    pmten = int.from_bytes(b''.join(data[4:6]), byteorder='little') / 10
    pmten_aqi = str(aqi.to_iaqi(aqi.POLLUTANT_PM10, pmten, algo=aqi.ALGO_EPA))
    #print('PM 10 AQI: ', pmten_aqi)
    aio.send('air10', pmten)
    aio.send('air10-aqi', pmten_aqi)
    #print('PM 10: ', pmten)
scope = ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive'] # what you want to access
credentials = ServiceAccountCredentials.from_json_keyfile_name('GSpreadPM25Peet-194a222ea2e4.json', scope)

client = gspread.authorize(credentials)
sheet = client.open("PM25_Peet").sheet1 # workbook.worksheet

#%% Define Serial
t = serial.Serial('com8',9600)   # modify the serial
#'/dev/ttyUSB0'



#while True:
for i in range(0,10):
    t.flushInput()
    time.sleep(0.5)
    retstr = t.read(10)
    if (len(retstr)==10):
        if(retstr[0]==0xaa and retstr[1]==0xc0):
            if sum(retstr[2:8]) % 256 == retstr[8]: # check if error occur from check-sum
                pm25  = (int(retstr[2])+int(retstr[3])*256) / 10 # in ug/m3
                pm10  = (int(retstr[4])+int(retstr[5])*256) / 10 # in ug/m3

                aqi25_us = int(aqi.to_iaqi(aqi.POLLUTANT_PM25, str(pm25), aqi.ALGO_EPA))
                aqi25_cn = int(aqi.to_iaqi(aqi.POLLUTANT_PM25, str(pm25), aqi.ALGO_MEP))
                
                print ("pm2.5:%.1f AQI_US: %d AQI_CN: %d"%(pm25,aqi25_us,aqi25_cn))
                
                sheet.append_row([time.ctime(),pm25,aqi25_us,aqi25_cn])
                
    
Пример #26
0
def insert_reading(reading):

    channel1 = """
        INSERT INTO
            air_quality(recorded_at, AGE, DEVICE_BRIGHTNESS, DEVICE_LOCATIONTYPE, \
                        Hidden, ID, Label, LastSeen, LastUpdateCheck, Lat, Lon, PM2_5Value, RSSI, Stats, \
                        THINGSPEAK_PRIMARY_ID, THINGSPEAK_PRIMARY_ID_READ_KEY, THINGSPEAK_SECONDARY_ID, THINGSPEAK_SECONDARY_ID_READ_KEY, \
                        Type, Uptime, Version, humidity, is_owner, pressure, temp_f, aqi, current_pm_2_5, 10_min_avg, 30_min_avg, 60_min_avg, 6_hr_avg, 24_hr_avg, 1_wk_avg)
        VALUES(
            UNIX_TIMESTAMP(NOW()),
            %(AGE)s,
            %(DEVICE_BRIGHTNESS)s,
            %(DEVICE_LOCATIONTYPE)s,
            %(Hidden)s,
            %(ID)s,
            %(Label)s,
            %(LastSeen)s,
            %(LastUpdateCheck)s,
            %(Lat)s,
            %(Lon)s,
            %(PM2_5Value)s,
            %(RSSI)s,
            %(Stats)s,
            %(THINGSPEAK_PRIMARY_ID)s,
            %(THINGSPEAK_PRIMARY_ID_READ_KEY)s,
            %(THINGSPEAK_SECONDARY_ID)s,
            %(THINGSPEAK_SECONDARY_ID_READ_KEY)s,
            %(Type)s,
            %(Uptime)s,
            %(Version)s,
            %(humidity)s,
            %(isOwner)s,
            %(pressure)s,
            %(temp_f)s,
            %(aqi)s,
            %(v)s,
            %(v1)s,
            %(v2)s,
            %(v3)s,
            %(v4)s,
            %(v5)s,
            %(v6)s
        )
    """

    channel2 = """
            INSERT INTO
                air_quality(recorded_at, AGE, Hidden, ID, Label, LastSeen, Lat, Lon, PM2_5Value, ParentID, Stats, \
                            THINGSPEAK_PRIMARY_ID, THINGSPEAK_PRIMARY_ID_READ_KEY, THINGSPEAK_SECONDARY_ID, THINGSPEAK_SECONDARY_ID_READ_KEY, \
                            is_owner, aqi, current_pm_2_5, 10_min_avg, 30_min_avg, 60_min_avg, 6_hr_avg, 24_hr_avg, 1_wk_avg)
            VALUES(
                UNIX_TIMESTAMP(NOW()),
                %(AGE)s,
                %(Hidden)s,
                %(ID)s,
                %(Label)s,
                %(LastSeen)s,
                %(Lat)s,
                %(Lon)s,
                %(PM2_5Value)s,
                %(ParentID)s,
                %(Stats)s,
                %(THINGSPEAK_PRIMARY_ID)s,
                %(THINGSPEAK_PRIMARY_ID_READ_KEY)s,
                %(THINGSPEAK_SECONDARY_ID)s,
                %(THINGSPEAK_SECONDARY_ID_READ_KEY)s,
                %(isOwner)s,
                %(aqi)s,
                %(v)s,
                %(v1)s,
                %(v2)s,
                %(v3)s,
                %(v4)s,
                %(v5)s,
                %(v6)s
            )
        """

    for r in reading:

        try:
            stats = json.loads(r['Stats'])
            r['v']  = stats['v']
            r['v1'] = stats['v1']
            r['v2'] = stats['v2']
            r['v3'] = stats['v3']
            r['v4'] = stats['v4']
            r['v5'] = stats['v5']
            r['v6'] = stats['v6']
            r['aqi']= aqi.to_iaqi(aqi.POLLUTANT_PM25, stats['v'], algo=aqi.ALGO_EPA)

            print(r['Label'], r['aqi'])

            # print(json.dumps(r, sort_keys=True, indent=4, separators=(',', ': ')))

            sql = channel2 if "ParentID" in r else channel1

            try:
                cur.execute(sql, r)
                conn.commit()
              #  print("Reading inserted")
            except Exception as e:
                print("Unable to insert reading")
                print(e)
        except Exception as e:
            print("Failed to insert readings")
            print(r)
            print(e)
Пример #27
0
 def process_pm2(self, pm2):
     pm2['pm2_aqi'] = aqi.to_iaqi(aqi.POLLUTANT_PM25, pm2['pm25_standard'])
     pm2['pm100_aqi'] = aqi.to_iaqi(aqi.POLLUTANT_PM25,
                                    pm2['pm100_standard'])
     return pm2
# aqi library
# https://media.readthedocs.org/pdf/python-aqi/latest/python-aqi.pdf
# pip install python-aqi

import serial  # module to read data from sensor
import time  # time management
import aqi  # conversion to US, CN , AQI index

t = serial.Serial('com8', 9600)  # modify the serial
#'/dev/ttyUSB0'

#while True:
for i in range(0, 10):
    t.flushInput()
    time.sleep(0.5)
    retstr = t.read(10)
    if (len(retstr) == 10):
        if (retstr[0] == 0xaa and retstr[1] == 0xc0):
            if sum(retstr[2:8]
                   ) % 256 == retstr[8]:  # check if error occur from check-sum
                pm25 = (int(retstr[2]) + int(retstr[3]) * 256) / 10  # in ug/m3
                pm10 = (int(retstr[4]) + int(retstr[5]) * 256) / 10  # in ug/m3

                aqi25_us = int(
                    aqi.to_iaqi(aqi.POLLUTANT_PM25, str(pm25), aqi.ALGO_EPA))
                aqi25_cn = int(
                    aqi.to_iaqi(aqi.POLLUTANT_PM25, str(pm25), aqi.ALGO_MEP))

                print("pm2.5:%.1f AQI_US: %d AQI_CN: %d" %
                      (pm25, aqi25_us, aqi25_cn))
Пример #29
0
# -*- coding: utf-8 -*-
"""
Created on Sun Feb  3 22:41:58 2019

@author: PeerapongE
"""
#

# United States Environmental Protection Agency (EPA) --> aqi.ALGO_EPA
# China Ministry of Environmental Protection (MEP) --> aqi.ALGO_MEP
import aqi

myaqi = int(aqi.to_iaqi(aqi.POLLUTANT_PM25, '12', aqi.ALGO_EPA))

print(myaqi)
Пример #30
0
 def test_to_iaqi(self):
     """Test IAQI conversion"""
     self.assertEqual(
         aqi.to_iaqi(aqi.POLLUTANT_O3_8H, '0.08753333', algo=aqi.ALGO_EPA),
         129)
Пример #31
0
 def test_to_iaqi(self):
     """Test IAQI conversion"""
     self.assertEqual(
         aqi.to_iaqi(aqi.POLLUTANT_O3_8H, '0.08753333', algo=aqi.ALGO_EPA),
         129)