|
| 1 | +"""Record HEPA UV Testing.""" |
| 2 | +import datetime |
| 3 | +import argparse |
| 4 | +from typing import List, Any |
| 5 | +from abr_testing.automation import google_sheets_tool |
| 6 | +import os |
| 7 | +import sys |
| 8 | +import json |
| 9 | + |
| 10 | + |
| 11 | +def get_hepa_serials(storage_directory: str) -> List[List[Any]]: |
| 12 | + """Get HEPA / UV Serial Number.""" |
| 13 | + try: |
| 14 | + ips_path = os.path.join(storage_directory, "IPs.json") |
| 15 | + ip_file = json.load(open(ips_path)) |
| 16 | + robot_dict = ip_file.get("ip_address_list") |
| 17 | + except FileNotFoundError: |
| 18 | + print(f"Add IPs.json file to: {storage_directory}.") |
| 19 | + sys.exit() |
| 20 | + robot_name_and_hepa_serial = list(map(list, (zip(*robot_dict.values())))) |
| 21 | + return robot_name_and_hepa_serial |
| 22 | + |
| 23 | + |
| 24 | +def turning_uv_and_hepa_on( |
| 25 | + google_sheet: google_sheets_tool.google_sheet, all_robots: List[List[Any]] |
| 26 | +) -> None: |
| 27 | + """Create set of lines to add to google sheet.""" |
| 28 | + today = datetime.date.today() |
| 29 | + formatted_date = today.strftime("%m/%d/%Y") |
| 30 | + timestamp = datetime.datetime.now() |
| 31 | + formatted_timestamp = timestamp.strftime("%m/%d/%Y %H:%M:%S") |
| 32 | + num_robots = len(all_robots[0]) |
| 33 | + blank_column = [""] * num_robots |
| 34 | + date_column = [formatted_date] * num_robots |
| 35 | + fan_start_column = [formatted_timestamp] * num_robots |
| 36 | + uv_cycles_column = [1] * num_robots |
| 37 | + uv_duration_column = [15] * num_robots |
| 38 | + |
| 39 | + all_columns = [ |
| 40 | + date_column, |
| 41 | + all_robots[0], |
| 42 | + all_robots[1], |
| 43 | + fan_start_column, |
| 44 | + blank_column, |
| 45 | + blank_column, |
| 46 | + blank_column, |
| 47 | + uv_cycles_column, |
| 48 | + uv_duration_column, |
| 49 | + ] |
| 50 | + |
| 51 | + start_row = google_sheet.get_index_row() + 1 |
| 52 | + google_sheet.batch_update_cells(all_columns, "A", start_row, "1790601450") |
| 53 | + |
| 54 | + |
| 55 | +def turning_hepa_off_and_uv_on( |
| 56 | + google_sheet: google_sheets_tool.google_sheet, all_robots: List[List[str]] |
| 57 | +) -> None: |
| 58 | + """Records when Hepa is Turned Off and UV on.""" |
| 59 | + # List of Expected Headers |
| 60 | + expected_headers = { |
| 61 | + "Date", |
| 62 | + "Robot", |
| 63 | + "Hepa Filter Serial", |
| 64 | + "Fan Start Time", |
| 65 | + "Fan Stop Time", |
| 66 | + "Fan On Duration (timestamp)", |
| 67 | + "Fan On Duration (min)", |
| 68 | + "UV # of Cycles", |
| 69 | + "UV Duration (min)", |
| 70 | + "Errors", |
| 71 | + "Level", |
| 72 | + "Description", |
| 73 | + } |
| 74 | + all_data = google_sheet.get_all_data(expected_headers) |
| 75 | + todays_rows = [] |
| 76 | + |
| 77 | + # Initialize column-wise lists |
| 78 | + dates, robots, hepa_serials = [], [], [] |
| 79 | + fan_start_times, fan_stop_times, durations, durations_min = [], [], [], [] |
| 80 | + uv_cycles, uv_durations, errors, levels, descriptions = [], [], [], [], [] |
| 81 | + |
| 82 | + # Timestamp formatting |
| 83 | + today = datetime.date.today() |
| 84 | + formatted_date = today.strftime("%m/%d/%Y") |
| 85 | + timestamp = datetime.datetime.now() |
| 86 | + formatted_timestamp = timestamp.strftime("%m/%d/%Y %H:%M:%S") |
| 87 | + |
| 88 | + # Process matching rows |
| 89 | + for row in all_data: |
| 90 | + if (row["Date"] == formatted_date) and (row["Robot"] in all_robots[0]): |
| 91 | + start_time_str = row["Fan Start Time"] |
| 92 | + start_time = datetime.datetime.strptime(start_time_str, "%m/%d/%Y %H:%M:%S") |
| 93 | + |
| 94 | + duration = timestamp - start_time |
| 95 | + duration_str = str(duration) |
| 96 | + duration_min = duration.total_seconds() / 60 |
| 97 | + |
| 98 | + # Update row with new info |
| 99 | + row["Fan Stop Time"] = formatted_timestamp |
| 100 | + row["Fan On Duration (timestamp)"] = duration_str |
| 101 | + row["Fan On Duration (min)"] = duration_min |
| 102 | + row["UV # of Cycles"] = 2 |
| 103 | + row["UV Duration (min)"] = 30 |
| 104 | + |
| 105 | + todays_rows.append(row) |
| 106 | + |
| 107 | + # Populate columns |
| 108 | + dates.append(row["Date"]) |
| 109 | + robots.append(row["Robot"]) |
| 110 | + hepa_serials.append(row["Hepa Filter Serial"]) |
| 111 | + fan_start_times.append(row["Fan Start Time"]) |
| 112 | + fan_stop_times.append(row["Fan Stop Time"]) |
| 113 | + durations.append(duration_str) |
| 114 | + durations_min.append(duration_min) |
| 115 | + uv_cycles.append(2) |
| 116 | + uv_durations.append(30) |
| 117 | + errors.append(row.get("Errors", "")) |
| 118 | + levels.append(row.get("Level", "")) |
| 119 | + descriptions.append(row.get("Description", "")) |
| 120 | + |
| 121 | + # Combine all columns into a nested list |
| 122 | + nested_list = [ |
| 123 | + dates, |
| 124 | + robots, |
| 125 | + hepa_serials, |
| 126 | + fan_start_times, |
| 127 | + fan_stop_times, |
| 128 | + durations, |
| 129 | + durations_min, |
| 130 | + uv_cycles, |
| 131 | + uv_durations, |
| 132 | + errors, |
| 133 | + levels, |
| 134 | + descriptions, |
| 135 | + ] |
| 136 | + last_row_index = google_sheet.get_index_row() + 1 |
| 137 | + starting_row_index = last_row_index - len(all_robots[0]) |
| 138 | + row_nums = list(range(starting_row_index, last_row_index)) |
| 139 | + row_indices = [i - 1 for i in row_nums] # API needs 0-based |
| 140 | + google_sheet.batch_delete_rows(row_indices, "1790601450") |
| 141 | + google_sheet.update_row_index() |
| 142 | + google_sheet.batch_update_cells(nested_list, "A", starting_row_index, "1790601450") |
| 143 | + |
| 144 | + |
| 145 | +def run( |
| 146 | + turning_hepa_fan: str, |
| 147 | + google_sheet_name: str, |
| 148 | + storage_directory: str, |
| 149 | +) -> None: |
| 150 | + """Main control function.""" |
| 151 | + try: |
| 152 | + credentials_path = os.path.join(storage_directory, "credentials.json") |
| 153 | + except FileNotFoundError: |
| 154 | + print(f"Add credentials.json file to: {storage_directory}.") |
| 155 | + sys.exit() |
| 156 | + hepa_uv_sheet = google_sheets_tool.google_sheet( |
| 157 | + credentials_path, google_sheet_name, 5 |
| 158 | + ) |
| 159 | + robot_names_and_hepa_serials = get_hepa_serials(storage_directory) |
| 160 | + if turning_hepa_fan == "on": |
| 161 | + print("𖣘 TIME STAMPING START OF HEPA FANS & UV LIGHT.") |
| 162 | + else: |
| 163 | + print("𖣘 TIME STAMPING END OF HEPA FANS & UV LIGHT.") |
| 164 | + |
| 165 | + answer = input("Do you want to exclude any robots (y/n)?") |
| 166 | + if answer.lower == "y": |
| 167 | + robots_to_exclude = input( |
| 168 | + "Enter robots you want to exclude in a comma separated list: " |
| 169 | + ) |
| 170 | + exclude_list = [r.strip() for r in robots_to_exclude.split(",")] |
| 171 | + robots = robot_names_and_hepa_serials[0] |
| 172 | + serials = robot_names_and_hepa_serials[1] |
| 173 | + # Zip robots and serials into pairs, filter, then unzip back |
| 174 | + filtered_pairs = [ |
| 175 | + (r, s) for r, s in zip(robots, serials) if r not in exclude_list |
| 176 | + ] |
| 177 | + # Unzip into separate lists again |
| 178 | + filtered_robots, filtered_serials = ( |
| 179 | + zip(*filtered_pairs) if filtered_pairs else ([], []) |
| 180 | + ) |
| 181 | + robot_names_and_hepa_serials = [list(filtered_robots), list(filtered_serials)] |
| 182 | + else: |
| 183 | + robot_names_and_hepa_serials = robot_names_and_hepa_serials |
| 184 | + if turning_hepa_fan == "on": |
| 185 | + turning_uv_and_hepa_on(hepa_uv_sheet, robot_names_and_hepa_serials) |
| 186 | + else: |
| 187 | + turning_hepa_off_and_uv_on(hepa_uv_sheet, robot_names_and_hepa_serials) |
| 188 | + |
| 189 | + |
| 190 | +if __name__ == "__main__": |
| 191 | + parser = argparse.ArgumentParser(description="Record HEPA/UV Actions") |
| 192 | + parser.add_argument( |
| 193 | + "turning_hepa_fan", |
| 194 | + metavar="-hepa", |
| 195 | + type=str, |
| 196 | + nargs=1, |
| 197 | + help="'on' or 'off'", |
| 198 | + ) |
| 199 | + parser.add_argument( |
| 200 | + "google_sheet_name", |
| 201 | + metavar="-google_sheet", |
| 202 | + type=str, |
| 203 | + nargs=1, |
| 204 | + help="Google sheet name.", |
| 205 | + ) |
| 206 | + parser.add_argument( |
| 207 | + "storage_directory", |
| 208 | + metavar="-storage_directory", |
| 209 | + type=str, |
| 210 | + nargs=1, |
| 211 | + help="Path to long term storage directory for run logs.", |
| 212 | + ) |
| 213 | + args = parser.parse_args() |
| 214 | + turning_hepa_fan = args.turning_hepa_fan[0] |
| 215 | + google_sheet_name = args.google_sheet_name[0] |
| 216 | + storage_directory = args.storage_directory[0] |
| 217 | + run(turning_hepa_fan, google_sheet_name, storage_directory) |
0 commit comments