Index: dialin/dg/sw_config.py =================================================================== diff -u -r7b757e5f7c3787ee2e8af80716767707ac2bab74 -r3e92417e035803f1401d5818f0117859ee049d9e --- dialin/dg/sw_config.py (.../sw_config.py) (revision 7b757e5f7c3787ee2e8af80716767707ac2bab74) +++ dialin/dg/sw_config.py (.../sw_config.py) (revision 3e92417e035803f1401d5818f0117859ee049d9e) @@ -155,14 +155,17 @@ """ self.logger.debug("Received a complete dg software configuration record.") - def cmd_set_dg_sw_config_record(self, dg_sw_config_record: OrderedDict) -> bool: + def cmd_set_dg_sw_config_record(self, excel_report_path: str) -> bool: """ Handles updating the DG software configuration record and sends it to FW. - @param dg_sw_config_record: (OrderedDict) the dg software configuration record to be sent + @param excel_report_path: (str) the directory in which the excel report of the software configuration is located @return: True upon success, False otherwise """ - record_packets = self._utilities.prepare_record_to_send_to_fw(dg_sw_config_record) + self._utilities.get_sw_configs_from_excel(self.dg_sw_config_record, excel_report_path, + self._NON_VOLATILE_RECORD_NAME) + print(self.dg_sw_config_record) + record_packets = self._utilities.prepare_record_to_send_to_fw(self.dg_sw_config_record) self.logger.debug('Setting DG sw config record') @@ -246,13 +249,23 @@ return sw_configs, groups_byte_size def cmd_get_dg_sw_config_record(self, report_address: str = None): + """ + Publicly accessible function to request the DG software configuration record and write the record to excel. + @param report_address: the address that the report needs to be written to. The default is None so it picks an + address and writes the excel report. + + @return: none + """ + # Create the excel report self._utilities.prepare_excel_report(self._FIRMWARE_STACK_NAME, self._NON_VOLATILE_RECORD_NAME, report_address) self._cmd_request_dg_sw_config_record() + observer = Observer("dg_sw_config_record") - observer.update() + self.attach(observer) while not observer.received: - sleep(0.2) + sleep(0.1) + self._utilities.write_sw_config_to_excel(self.dg_sw_config_record) Index: dialin/utils/nv_ops_utils.py =================================================================== diff -u -r7b757e5f7c3787ee2e8af80716767707ac2bab74 -r3e92417e035803f1401d5818f0117859ee049d9e --- dialin/utils/nv_ops_utils.py (.../nv_ops_utils.py) (revision 7b757e5f7c3787ee2e8af80716767707ac2bab74) +++ dialin/utils/nv_ops_utils.py (.../nv_ops_utils.py) (revision 3e92417e035803f1401d5818f0117859ee049d9e) @@ -13,6 +13,7 @@ # @date (original) 21-Feb-2021 # ############################################################################ +import os.path import struct import time from logging import Logger @@ -28,7 +29,7 @@ self.prop = prop def update(self, message): - print("Message: {0}".format(message)) + self.received = message.get(self.prop, False) @@ -92,6 +93,9 @@ _PAYLOAD_TOTAL_MSG_INDEX = 1 _PAYLOAD_TOTAL_BYTES_INDEX = 2 + _SW_CONFIGS_TITLE_COL = 'SW Configurations' + _SW_CONFIGS_VALUE_COL = 'Status' + def __init__(self, logger: Logger): """ Constructor for the NVOptsUtils class @@ -151,12 +155,17 @@ # If a directory is provided and there is not a folder in that address, create the # directory. Set the workspace directory to the provided directory. If a directory was not # provided, create a workspace in the default position - if not os.path.isdir(directory) and directory is not None: - # Create the directory and go to it - os.mkdir(directory) + default_nv_directory = firmware_stack + '_NV_Records' + + if directory is not None: + directory = os.path.join(directory, default_nv_directory) + if not os.path.isdir(directory): + # Create the directory and go to it + os.mkdir(directory) + self._workspace_dir = directory + os.chdir(self._workspace_dir) else: - default_nv_directory = firmware_stack + 'NV_Records' self._create_workspace(default_nv_directory) self._record_name = record_name @@ -850,3 +859,72 @@ padding_size = (math.ceil(total_byte_size / max_buffer_size) * max_buffer_size) - total_byte_size return padding_size + + def write_sw_config_to_excel(self, sw_configs: OrderedDict): + """ + Publicly accessible function to write the software configurations into an excel report + + @param sw_configs: (ordered dictionary) the configurations record to write to excel + + @return none + """ + row = 1 + names_col_number = 2 + + write_to_excel(self._excel_workbook, self._record_name, row, names_col_number, self._SW_CONFIGS_TITLE_COL, + bold=True, freeze=True) + + values_col_number = 3 + write_to_excel(self._excel_workbook, self._record_name, row, values_col_number, self._SW_CONFIGS_VALUE_COL, + bold=True) + + # Prepare for writing the values + row += 1 + + for key, values in sw_configs['sw_configs'].items(): + + write_to_excel(self._excel_workbook, self._record_name, row, names_col_number, key, bold=True) + write_to_excel(self._excel_workbook, self._record_name, row, values_col_number, values[1]) + row += 1 + + save_report(self._excel_workbook, self._workspace_dir, 'SW-Configs') + + def get_sw_configs_from_excel(self, sw_configs_dict: OrderedDict, excel_path: str, sw_config_excel_tab: str): + + row = 1 + col = 1 + title_col = None + value_col = None + max_col_to_go = 50 + self._excel_workbook = load_excel_report(excel_path) + active_sheet = self._excel_workbook[sw_config_excel_tab] + + while True: + # Loop through the cells in the title row + value = active_sheet.cell(row=row, column=col).value + # Remove the extra characters from the read value in the excel and compare it with the name of the alarm ID + # col title. If the search kept going beyond the max allowed column, break out of the loop + if col >= max_col_to_go: + break + + if value is not None: + if value.strip() == self._SW_CONFIGS_TITLE_COL: + title_col = col + if value.strip() == self._SW_CONFIGS_VALUE_COL: + value_col = col + + if title_col is not None and value_col is not None: + break + else: + col += 1 + + last_non_empty_row = active_sheet.max_row + + fw_sw_configs = sw_configs_dict['sw_configs'] + + for row in range(2, last_non_empty_row + 1): + config = active_sheet.cell(row=row, column=title_col).value + + if config is not None: + if config.strip() in fw_sw_configs: + fw_sw_configs[config.strip()][1] = active_sheet.cell(row=row, column=value_col).value Index: tests/dg_tests.py =================================================================== diff -u -r7b757e5f7c3787ee2e8af80716767707ac2bab74 -r3e92417e035803f1401d5818f0117859ee049d9e --- tests/dg_tests.py (.../dg_tests.py) (revision 7b757e5f7c3787ee2e8af80716767707ac2bab74) +++ tests/dg_tests.py (.../dg_tests.py) (revision 3e92417e035803f1401d5818f0117859ee049d9e) @@ -372,8 +372,9 @@ heaters = get_heaters_info() dg_fans = get_dg_fans_info() hd_fans = get_hd_fans_info() + conc = get_concentrate_pumps_info() - var = disinfect + load_cell + drain + ro + temp + heaters + dg_fans + hd_fans + valves + '\r' + var = disinfect + load_cell + drain + ro + temp + heaters + dg_fans + hd_fans + valves + conc + '\r' print(var) f.write(var) @@ -509,7 +510,8 @@ start_time = datetime.now() i = 0 while True: - info = str(fan) + ', ' + str(datetime.now() - start_time) + ', ' + get_dg_fans_info() + '\r' + info = str(fan) + ', ' + str(datetime.now() - start_time) + ', ' + get_dg_fans_info() + \ + str(dg.alarms.alarm_states[AlarmList.ALARM_ID_DG_FAN_RPM_OUT_OF_RANGE.value]) + '\r' print(info) f.write(info) @@ -538,7 +540,7 @@ hd.cmd_log_in_to_hd() sleep(1) - # run_heat_disinfect() + run_heat_disinfect() # run_chemical_disinfect() @@ -552,7 +554,7 @@ # test_hd_fans_alarms() - test_dg_fans_alarms() + # test_dg_fans_alarms() Index: tests/peter/test_dg_records.py =================================================================== diff -u -r4b8f0afb5aafc2409327ec47aad264ab500e69f7 -r3e92417e035803f1401d5818f0117859ee049d9e --- tests/peter/test_dg_records.py (.../test_dg_records.py) (revision 4b8f0afb5aafc2409327ec47aad264ab500e69f7) +++ tests/peter/test_dg_records.py (.../test_dg_records.py) (revision 3e92417e035803f1401d5818f0117859ee049d9e) @@ -179,16 +179,21 @@ #print(dg.cmd_ui_request_dg_version()) #dg.sw_configs.cmd_reset_dg_sw_config_record() - dg.sw_configs.cmd_request_dg_sw_config_record() + #dg.sw_configs.cmd_get_dg_sw_config_record() + + dg.sw_configs.cmd_set_dg_sw_config_record('/home/fw/DG_NV_Records/2022-01-22-SW-CONFIGS-Record.xlsx') + + """ observer = Observer("dg_sw_config_record") dg.sw_configs.attach(observer) while not observer.received: sleep(0.2) + """ + #dg.sw_configs.dg_sw_config_record['sw_configs'][SWConfigs.SW_CONFIG_DISABLE_HEATERS_MONITOR.name][1] = 1 + #print(dg.sw_configs.dg_sw_config_record) - dg.sw_configs.dg_sw_config_record['sw_configs'][SWConfigs.SW_CONFIG_DISABLE_HEATERS_MONITOR.name][1] = 1 - print(dg.sw_configs.dg_sw_config_record) + #dg.sw_configs.cmd_set_dg_sw_config_record(dg.sw_configs.dg_sw_config_record) - dg.sw_configs.cmd_set_dg_sw_config_record(dg.sw_configs.dg_sw_config_record) def test_dg_calibration_record(): @@ -314,8 +319,8 @@ if __name__ == "__main__": - test_dg_reset_record() - #test_dg_sw_config_record() + # test_dg_reset_record() + test_dg_sw_config_record() #test_dg_calibration_record() # test_dg_service_record() #test_dg_system_record()