Skip to content

Commit

Permalink
group sensors
Browse files Browse the repository at this point in the history
- even more coverage for group sensors
  • Loading branch information
carlkidcrypto committed Nov 15, 2023
1 parent dbfe58c commit 9459edc
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 16 deletions.
2 changes: 1 addition & 1 deletion purpleair_data_logger/PurpleAirDataLogger.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def _run_loop_for_storing_group_sensors_data(self, json_config_file) -> None:
print(
"_run_loop_for_storing_group_sensors_data - Beep boop I am alive...\n\n"
)
logic_for_storing_group_sensors_data(
group_id_to_use = logic_for_storing_group_sensors_data(
self, group_id_to_use, json_config_file
)
sleep(self.send_request_every_x_seconds)
Expand Down
11 changes: 7 additions & 4 deletions purpleair_data_logger/PurpleAirDataLoggerHelpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from purpleair_api.PurpleAirAPIConstants import ACCEPTED_FIELD_NAMES_DICT
from purpleair_api.PurpleAirAPI import debug_log, PurpleAirAPIError
import argparse
from time import sleep
import time


def generate_common_arg_parser(argparse_description=""):
Expand Down Expand Up @@ -292,14 +292,14 @@ def logic_for_storing_multiple_sensors_data(padl_obj, json_config_file) -> None:

def logic_for_storing_group_sensors_data(
padl_obj, group_id_to_use, json_config_file
) -> None:
) -> int:
"""
A method containing the run loop for inserting a group sensors' data into the data logger.
:param PurpleAirDataLogger padl_obj: A valid instance of PurpleAirDataLogger.
:param str: The group id to be used. Starts out being `None` then gets filled out.
:param dict json_config_file: A dictionary object of the json config file using json load.
:return None
:return The group_id int
"""

if group_id_to_use is None:
Expand All @@ -314,6 +314,7 @@ def logic_for_storing_group_sensors_data(
# Find the first name that matches our sensor_group_name. No use to continue further
if bool(name == json_config_file["sensor_group_name"]):
does_sensor_group_name_exist = True
print("here")
group_id_to_use = id
break

Expand All @@ -331,7 +332,7 @@ def logic_for_storing_group_sensors_data(
print(
f"Waiting {padl_obj.send_request_every_x_seconds} seconds for group to be created on server..."
)
sleep(padl_obj.send_request_every_x_seconds)
time.sleep(padl_obj.send_request_every_x_seconds)

else:
print(
Expand Down Expand Up @@ -402,6 +403,8 @@ def logic_for_storing_group_sensors_data(
requesting new data again..."""
)

return members_data["group_id"]


def logic_for_storing_local_sensors_data(padl_obj, json_config_file) -> None:
"""
Expand Down
115 changes: 104 additions & 11 deletions tests/test_purpleair_data_logger_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import requests_mock
import sys
from json import load, dumps
import time
from mock import patch

sys.path.append("../")

Expand Down Expand Up @@ -256,7 +258,10 @@ def test_logic_for_storing_multiple_sensors_data(self):
padl.store_sensor_data.side_effect = [DATA_OUT_3, DATA_OUT_4, DATA_OUT_5]
self.assertEqual(padl.store_sensor_data.call_count, 3)

def test_logic_for_storing_group_sensors_data_with_adding_group(self):
@patch("time.sleep", return_value=None)
def test_logic_for_storing_group_sensors_data_with_group_id_none(
self, patched_time_sleep
):
"""
Test the main logic for the PurpleAirDataLogger.`_run_loop_for_storing_group_sensors_data` method.
"""
Expand Down Expand Up @@ -291,12 +296,14 @@ def test_logic_for_storing_group_sensors_data_with_adding_group(self):

expected_return_data_1 = {
"groups": [
{"name": "A Name Goes Here!", "id": 1234},
{"name": "A Name Goes Here", "id": 1234},
{"name": "A Name Goes Here!", "id": 12345},
{"name": "A Name Goes Here!!", "id": 123456},
]
}
expected_return_data_2 = {}
expected_return_data_3 = {

expected_return_data_2 = {"group_id": 1234}
expected_return_data_3 = {}
expected_return_data_4 = {
"api_version": "V1.0.11-0.0.42",
"time_stamp": 1676784867,
"data_time_stamp": 1676784847,
Expand All @@ -309,8 +316,9 @@ def test_logic_for_storing_group_sensors_data_with_adding_group(self):

# Action & Expected Result
expected_url_request_1 = "https://api.purpleair.com/v1/groups/"
expected_url_request_2 = "https://api.purpleair.com/v1/groups/1234/members"
expected_url_request_3 = "https://api.purpleair.com/v1/groups/1234/members?fields=name,icon,model,hardware,location_type,private,latitude,longitude,altitude,position_rating,led_brightness,firmware_version,firmware_upgrade,rssi,uptime,pa_latency,memory,last_seen,last_modified,date_created,channel_state,channel_flags,channel_flags_manual,channel_flags_auto,confidence,confidence_manual,confidence_auto,humidity,humidity_a,humidity_b,temperature,temperature_a,temperature_b,pressure,pressure_a,pressure_b,voc,voc_a,voc_b,ozone1,analog_input,pm1.0,pm1.0_a,pm1.0_b,pm1.0_atm,pm1.0_atm_a,pm1.0_atm_b,pm1.0_cf_1,pm1.0_cf_1_a,pm1.0_cf_1_b,pm2.5_alt,pm2.5_alt_a,pm2.5_alt_b,pm2.5,pm2.5_a,pm2.5_b,pm2.5_atm,pm2.5_atm_a,pm2.5_atm_b,pm2.5_cf_1,pm2.5_cf_1_a,pm2.5_cf_1_b,pm2.5_10minute,pm2.5_10minute_a,pm2.5_10minute_b,pm2.5_30minute,pm2.5_30minute_a,pm2.5_30minute_b,pm2.5_60minute,pm2.5_60minute_a,pm2.5_60minute_b,pm2.5_6hour,pm2.5_6hour_a,pm2.5_6hour_b,pm2.5_24hour,pm2.5_24hour_a,pm2.5_24hour_b,pm2.5_1week,pm2.5_1week_a,pm2.5_1week_b,pm10.0,pm10.0_a,pm10.0_b,pm10.0_atm,pm10.0_atm_a,pm10.0_atm_b,pm10.0_cf_1,pm10.0_cf_1_a,pm10.0_cf_1_b,0.3_um_count,0.3_um_count_a,0.3_um_count_b,0.5_um_count,0.5_um_count_a,0.5_um_count_b,1.0_um_count,1.0_um_count_a,1.0_um_count_b,2.5_um_count,2.5_um_count_a,2.5_um_count_b,5.0_um_count,5.0_um_count_a,5.0_um_count_b,10.0_um_count,10.0_um_count_a,10.0_um_count_b,primary_id_a,primary_key_a,secondary_id_a,secondary_key_a,primary_id_b,primary_key_b,secondary_id_b,secondary_key_b"
expected_url_request_2 = "https://api.purpleair.com/v1/groups"
expected_url_request_3 = "https://api.purpleair.com/v1/groups/1234/members"
expected_url_request_4 = "https://api.purpleair.com/v1/groups/1234/members?fields=name,icon,model,hardware,location_type,private,latitude,longitude,altitude,position_rating,led_brightness,firmware_version,firmware_upgrade,rssi,uptime,pa_latency,memory,last_seen,last_modified,date_created,channel_state,channel_flags,channel_flags_manual,channel_flags_auto,confidence,confidence_manual,confidence_auto,humidity,humidity_a,humidity_b,temperature,temperature_a,temperature_b,pressure,pressure_a,pressure_b,voc,voc_a,voc_b,ozone1,analog_input,pm1.0,pm1.0_a,pm1.0_b,pm1.0_atm,pm1.0_atm_a,pm1.0_atm_b,pm1.0_cf_1,pm1.0_cf_1_a,pm1.0_cf_1_b,pm2.5_alt,pm2.5_alt_a,pm2.5_alt_b,pm2.5,pm2.5_a,pm2.5_b,pm2.5_atm,pm2.5_atm_a,pm2.5_atm_b,pm2.5_cf_1,pm2.5_cf_1_a,pm2.5_cf_1_b,pm2.5_10minute,pm2.5_10minute_a,pm2.5_10minute_b,pm2.5_30minute,pm2.5_30minute_a,pm2.5_30minute_b,pm2.5_60minute,pm2.5_60minute_a,pm2.5_60minute_b,pm2.5_6hour,pm2.5_6hour_a,pm2.5_6hour_b,pm2.5_24hour,pm2.5_24hour_a,pm2.5_24hour_b,pm2.5_1week,pm2.5_1week_a,pm2.5_1week_b,pm10.0,pm10.0_a,pm10.0_b,pm10.0_atm,pm10.0_atm_a,pm10.0_atm_b,pm10.0_cf_1,pm10.0_cf_1_a,pm10.0_cf_1_b,0.3_um_count,0.3_um_count_a,0.3_um_count_b,0.5_um_count,0.5_um_count_a,0.5_um_count_b,1.0_um_count,1.0_um_count_a,1.0_um_count_b,2.5_um_count,2.5_um_count_a,2.5_um_count_b,5.0_um_count,5.0_um_count_a,5.0_um_count_b,10.0_um_count,10.0_um_count_a,10.0_um_count_b,primary_id_a,primary_key_a,secondary_id_a,secondary_key_a,primary_id_b,primary_key_b,secondary_id_b,secondary_key_b"

with requests_mock.Mocker() as m1:
m1.get(
Expand All @@ -323,14 +331,21 @@ def test_logic_for_storing_group_sensors_data_with_adding_group(self):
text=f"{dumps(expected_return_data_2)}",
status_code=200,
)
m1.get(
m1.post(
expected_url_request_3,
text=f"{dumps(expected_return_data_3)}",
status_code=200,
)
logic_for_storing_group_sensors_data(padl, None, json_config_file)
m1.get(
expected_url_request_4,
text=f"{dumps(expected_return_data_4)}",
status_code=200,
)
self.assertEqual(
logic_for_storing_group_sensors_data(padl, None, json_config_file), 1234
)

def test_logic_for_storing_group_sensors_data_without_adding_group(self):
def test_logic_for_storing_group_sensors_data_without_group_id_1234(self):
"""
Test the main logic for the PurpleAirDataLogger.`_run_loop_for_storing_group_sensors_data` method.
"""
Expand Down Expand Up @@ -382,7 +397,85 @@ def test_logic_for_storing_group_sensors_data_without_adding_group(self):
text=f"{dumps(expected_return_data)}",
status_code=200,
)
logic_for_storing_group_sensors_data(padl, 1234, json_config_file)
self.assertEqual(
logic_for_storing_group_sensors_data(padl, 1234, json_config_file), 1234
)

def test_logic_for_storing_group_sensors_data_with_adding_group_id_4321_duplicate(
self,
):
"""
Test the main logic for the PurpleAirDataLogger.`_run_loop_for_storing_group_sensors_data` method.
"""

# Setup
expected_url_request = "https://api.purpleair.com/v1/keys"
padl = None
with requests_mock.Mocker() as m:
m.get(
expected_url_request,
text='{"api_version" : "1.1.1", "time_stamp": 123456789, "api_key_type": "READ"}',
status_code=200,
)
padl = PurpleAirDataLogger(PurpleAirApiReadKey="123456789")
padl.store_sensor_data = MagicMock(name="store_sensor_data")
json_config_file = {
"sensor_group_name": "A Name Goes Here",
"add_sensors_to_group": True,
"sensor_index_list": [77, 81, 95079, 167897],
"poll_interval_seconds": 60,
"fields": "name, icon, model, hardware, location_type, private, latitude, longitude, altitude, position_rating, led_brightness, firmware_version, firmware_upgrade, rssi, uptime, pa_latency, memory, last_seen, last_modified, date_created, channel_state, channel_flags, channel_flags_manual, channel_flags_auto, confidence, confidence_manual, confidence_auto,humidity, humidity_a, humidity_b, temperature, temperature_a, temperature_b, pressure, pressure_a, pressure_b,voc, voc_a, voc_b, ozone1, analog_input,pm1.0, pm1.0_a, pm1.0_b, pm1.0_atm, pm1.0_atm_a, pm1.0_atm_b, pm1.0_cf_1, pm1.0_cf_1_a,pm1.0_cf_1_b,pm2.5_alt, pm2.5_alt_a, pm2.5_alt_b, pm2.5, pm2.5_a, pm2.5_b, pm2.5_atm, pm2.5_atm_a, pm2.5_atm_b, pm2.5_cf_1, pm2.5_cf_1_a, pm2.5_cf_1_b,pm2.5_10minute, pm2.5_10minute_a, pm2.5_10minute_b, pm2.5_30minute, pm2.5_30minute_a, pm2.5_30minute_b, pm2.5_60minute, pm2.5_60minute_a, pm2.5_60minute_b, pm2.5_6hour, pm2.5_6hour_a, pm2.5_6hour_b,pm2.5_24hour, pm2.5_24hour_a, pm2.5_24hour_b, pm2.5_1week, pm2.5_1week_a, pm2.5_1week_b,pm10.0, pm10.0_a, pm10.0_b, pm10.0_atm, pm10.0_atm_a, pm10.0_atm_b, pm10.0_cf_1, pm10.0_cf_1_a, pm10.0_cf_1_b,0.3_um_count,0.3_um_count_a,0.3_um_count_b,0.5_um_count,0.5_um_count_a,0.5_um_count_b,1.0_um_count,1.0_um_count_a,1.0_um_count_b,2.5_um_count,2.5_um_count_a,2.5_um_count_b,5.0_um_count,5.0_um_count_a,5.0_um_count_b,10.0_um_count,10.0_um_count_a,10.0_um_count_b,primary_id_a, primary_key_a, secondary_id_a, secondary_key_a, primary_id_b, primary_key_b, secondary_id_b, secondary_key_b",
"location_type": None,
"read_keys": None,
"show_only": None,
"modified_since": None,
"max_age": None,
"nwlng": None,
"nwlat": None,
"selng": None,
"selat": None,
}

expected_return_data_1 = {
"groups": [
{"name": "A Name Goes Here!", "id": 4321},
{"name": "A Name Goes Here", "id": 4321},
]
}
expected_return_data_2 = {}
expected_return_data_3 = {
"api_version": "V1.0.11-0.0.42",
"time_stamp": 1676784867,
"data_time_stamp": 1676784847,
"group_id": 4321,
"max_age": 604800,
"firmware_default_version": "7.02",
"fields": ["sensor_index", "name"],
"data": [[77, "Sunnyside"], [81, "Sherwood Hills 2"]],
}

# Action & Expected Result
expected_url_request_1 = "https://api.purpleair.com/v1/groups/"
expected_url_request_2 = "https://api.purpleair.com/v1/groups/4321/members"
expected_url_request_3 = "https://api.purpleair.com/v1/groups/4321/members?fields=name,icon,model,hardware,location_type,private,latitude,longitude,altitude,position_rating,led_brightness,firmware_version,firmware_upgrade,rssi,uptime,pa_latency,memory,last_seen,last_modified,date_created,channel_state,channel_flags,channel_flags_manual,channel_flags_auto,confidence,confidence_manual,confidence_auto,humidity,humidity_a,humidity_b,temperature,temperature_a,temperature_b,pressure,pressure_a,pressure_b,voc,voc_a,voc_b,ozone1,analog_input,pm1.0,pm1.0_a,pm1.0_b,pm1.0_atm,pm1.0_atm_a,pm1.0_atm_b,pm1.0_cf_1,pm1.0_cf_1_a,pm1.0_cf_1_b,pm2.5_alt,pm2.5_alt_a,pm2.5_alt_b,pm2.5,pm2.5_a,pm2.5_b,pm2.5_atm,pm2.5_atm_a,pm2.5_atm_b,pm2.5_cf_1,pm2.5_cf_1_a,pm2.5_cf_1_b,pm2.5_10minute,pm2.5_10minute_a,pm2.5_10minute_b,pm2.5_30minute,pm2.5_30minute_a,pm2.5_30minute_b,pm2.5_60minute,pm2.5_60minute_a,pm2.5_60minute_b,pm2.5_6hour,pm2.5_6hour_a,pm2.5_6hour_b,pm2.5_24hour,pm2.5_24hour_a,pm2.5_24hour_b,pm2.5_1week,pm2.5_1week_a,pm2.5_1week_b,pm10.0,pm10.0_a,pm10.0_b,pm10.0_atm,pm10.0_atm_a,pm10.0_atm_b,pm10.0_cf_1,pm10.0_cf_1_a,pm10.0_cf_1_b,0.3_um_count,0.3_um_count_a,0.3_um_count_b,0.5_um_count,0.5_um_count_a,0.5_um_count_b,1.0_um_count,1.0_um_count_a,1.0_um_count_b,2.5_um_count,2.5_um_count_a,2.5_um_count_b,5.0_um_count,5.0_um_count_a,5.0_um_count_b,10.0_um_count,10.0_um_count_a,10.0_um_count_b,primary_id_a,primary_key_a,secondary_id_a,secondary_key_a,primary_id_b,primary_key_b,secondary_id_b,secondary_key_b"

with requests_mock.Mocker() as m1:
m1.get(
expected_url_request_1,
text=f"{dumps(expected_return_data_1)}",
status_code=200,
)
m1.post(
expected_url_request_2,
text=f"{dumps(expected_return_data_2)}",
status_code=200,
)
m1.get(
expected_url_request_3,
text=f"{dumps(expected_return_data_3)}",
status_code=200,
)
logic_for_storing_group_sensors_data(padl, None, json_config_file)

def test_logic_for_storing_local_sensors_data(self):
""" """
Expand Down

0 comments on commit 9459edc

Please sign in to comment.