Index: dialin/common/alarm_defs.py =================================================================== diff -u -r8ea13ae6dd10732bfcc456798f4785c4d88c95d3 -rda3d88051a0ccd89f86ed4f6c2bbb0a067b6f148 --- dialin/common/alarm_defs.py (.../alarm_defs.py) (revision 8ea13ae6dd10732bfcc456798f4785c4d88c95d3) +++ dialin/common/alarm_defs.py (.../alarm_defs.py) (revision da3d88051a0ccd89f86ed4f6c2bbb0a067b6f148) @@ -13,10 +13,10 @@ # @date (original) 07-Aug-2020 # ############################################################################ -import enum +from enum import Enum, unique - -class AlarmList(enum.Enum): +@unique +class AlarmList(Enum): ALARM_ID_NO_ALARM = 0 # Indication for when no alarms is a possible situation ALARM_ID_HD_SOFTWARE_FAULT = 1 # HD Software fault. Software found itself in an unexpected state ALARM_ID_STUCK_BUTTON_TEST_FAILED = 2 # Stuck button POST failure. Stop or Off button detected to be pressed for at least 1 second during test shortly after power up @@ -96,7 +96,8 @@ ALARM_ID_DG_CRITICAL_DATA_ERROR = 76 # DG critical data integrity check failed. NUM_OF_ALARM_IDS = 77 # Total number of alarms -class AlarmPriorities: +@unique +class AlarmPriorities(Enum): ALARM_PRIORITY_NONE = 0 # Indicates not an alarm or no alarms active at this time ALARM_PRIORITY_LOW = 1 # Low priority alarm ALARM_PRIORITY_MEDIUM = 2 # Medium priority alarm Index: dialin/common/msg_defs.py =================================================================== diff -u -rd825321ce3b39a8119e6cabfcdc3b1408234dade -rda3d88051a0ccd89f86ed4f6c2bbb0a067b6f148 --- dialin/common/msg_defs.py (.../msg_defs.py) (revision d825321ce3b39a8119e6cabfcdc3b1408234dade) +++ dialin/common/msg_defs.py (.../msg_defs.py) (revision da3d88051a0ccd89f86ed4f6c2bbb0a067b6f148) @@ -13,9 +13,10 @@ # @date (original) 07-Aug-2020 # ############################################################################ -import enum +from enum import Enum, unique -class MsgIds(enum.Enum): +@unique +class MsgIds(Enum): MSG_ID_UNUSED = 0 # Zero is an undefined (un-used) message ID) MSG_ID_OFF_BUTTON_PRESS = 1 # HD/UI off button interactions MSG_ID_ALARM_STATUS = 2 # HD broadcast of system alarm state information @@ -183,8 +184,8 @@ END_OF_MSG_IDS = 0xFFF3 # End of system message IDs -class RequestRejectReasons(enum.Enum): - +@unique +class RequestRejectReasons(Enum): REQUEST_REJECT_REASON_NONE = 0 REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE = 1 REQUEST_REJECT_REASON_TIMEOUT_WAITING_FOR_USER_CONFIRM = 2 Index: dialin/hd/hemodialysis_device.py =================================================================== diff -u -rd825321ce3b39a8119e6cabfcdc3b1408234dade -rda3d88051a0ccd89f86ed4f6c2bbb0a067b6f148 --- dialin/hd/hemodialysis_device.py (.../hemodialysis_device.py) (revision d825321ce3b39a8119e6cabfcdc3b1408234dade) +++ dialin/hd/hemodialysis_device.py (.../hemodialysis_device.py) (revision da3d88051a0ccd89f86ed4f6c2bbb0a067b6f148) @@ -224,14 +224,5 @@ self.logger.debug("requesting HD software reset") # Send message - received_message = self.can_interface.send(message) - - if received_message is not None: - if received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] == 1: - self.logger.debug("HD is resetting...") - else: - self.logger.debug("HD reset request failed.") - return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] - else: - self.logger.debug("Timeout!!!!") - return False + self.can_interface.send(message, 0) + self.logger.debug("Sent request to HD to reset...") Index: dialin/ui/hd_simulator.py =================================================================== diff -u -ra45233b3e9562bb2b8ee19cd572f2d8d2f06bb5d -rda3d88051a0ccd89f86ed4f6c2bbb0a067b6f148 --- dialin/ui/hd_simulator.py (.../hd_simulator.py) (revision a45233b3e9562bb2b8ee19cd572f2d8d2f06bb5d) +++ dialin/ui/hd_simulator.py (.../hd_simulator.py) (revision da3d88051a0ccd89f86ed4f6c2bbb0a067b6f148) @@ -26,18 +26,61 @@ import struct from time import sleep -YES=1 -NO=0 +YES = 1 +NO = 0 -class HDSimulator(_AbstractSubSystem): + +class TreatmentParameterRejections: + def __init__(self): + self.param_request_valid = RequestRejectReasons.REQUEST_REJECT_REASON_NONE + self.param_blood_flow_rate = RequestRejectReasons.REQUEST_REJECT_REASON_NONE + self.param_dialysate_flow_rate = RequestRejectReasons.REQUEST_REJECT_REASON_NONE + self.param_duration = RequestRejectReasons.REQUEST_REJECT_REASON_NONE + self.param_heparin_stop_time = RequestRejectReasons.REQUEST_REJECT_REASON_NONE + self.param_saline_bolus = RequestRejectReasons.REQUEST_REJECT_REASON_NONE + self.param_acid_concentrate = RequestRejectReasons.REQUEST_REJECT_REASON_NONE + self.param_bicarbonate_concentrate = RequestRejectReasons.REQUEST_REJECT_REASON_NONE + self.param_dialyzer_type = RequestRejectReasons.REQUEST_REJECT_REASON_NONE + self.param_blood_pressure_measure_interval = RequestRejectReasons.REQUEST_REJECT_REASON_NONE + self.param_rinseback_flow_rate = RequestRejectReasons.REQUEST_REJECT_REASON_NONE + self.param_arterial_pressure_limit_low = RequestRejectReasons.REQUEST_REJECT_REASON_NONE + self.param_arterial_pressure_limit_high = RequestRejectReasons.REQUEST_REJECT_REASON_NONE + self.param_venous_pressure_limit_low = RequestRejectReasons.REQUEST_REJECT_REASON_NONE + self.param_venous_pressure_limit_high = RequestRejectReasons.REQUEST_REJECT_REASON_NONE + self.param_heparin_dispensing_rate = RequestRejectReasons.REQUEST_REJECT_REASON_NONE + self.param_heparin_bolus_volume = RequestRejectReasons.REQUEST_REJECT_REASON_NONE + self.param_dialysate_temp = RequestRejectReasons.REQUEST_REJECT_REASON_NONE + + def set_all_valid(self): + """ + Sets all parameters as valid + + @return: None + """ + for attr in dir(self): + if not callable(getattr(self, attr)) and attr.startswith("param_"): + self.__dict__[attr] = RequestRejectReasons.REQUEST_REJECT_REASON_NONE + + def set_all_invalid(self): + """ + Sets all treatment parameters to be invalid + + @return: None + """ + for attr in dir(self): + if not callable(getattr(self, attr)) and attr.startswith("param_"): + self.__dict__[attr] = RequestRejectReasons.REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE + + +class HDSimulator(_AbstractSubSystem): NUM_TREATMENT_PARAMETERS = 18 def __init__(self, can_interface="can0", log_level=None): super().__init__() - self._log_manager = _LogManager(log_level=log_level, log_filepath=self.__class__.__name__+".log") + self._log_manager = _LogManager(log_level=log_level, log_filepath=self.__class__.__name__ + ".log") self.logger = self._log_manager.logger self.can_interface = DenaliCanMessenger(can_interface=can_interface, logger=self.logger, @@ -60,6 +103,8 @@ self._handler_ui_end_treatment) self.alarms_simulator = HDProxyAlarms(self.can_interface, self.logger) + self.treatment_parameter_rejections = TreatmentParameterRejections() + def cmd_send_treatment_parameter_validation_response(self, rejections: List[RequestRejectReasons]): """ Sends a treatment parameter validation response @@ -262,23 +307,42 @@ @return: """ rejections = [ - RequestRejectReasons.REQUEST_REJECT_REASON_NONE, # requestValid - RequestRejectReasons.REQUEST_REJECT_REASON_NONE, # bloodFlowRate - RequestRejectReasons.REQUEST_REJECT_REASON_NONE, # dialysateFlowRate - RequestRejectReasons.REQUEST_REJECT_REASON_NONE, # duration - RequestRejectReasons.REQUEST_REJECT_REASON_NONE, # heparinStopTime - RequestRejectReasons.REQUEST_REJECT_REASON_NONE, # salineBolus - RequestRejectReasons.REQUEST_REJECT_REASON_NONE, # acidConcentrate - RequestRejectReasons.REQUEST_REJECT_REASON_NONE, # bicarbonateConcentrate - RequestRejectReasons.REQUEST_REJECT_REASON_NONE, # dialyzerType - RequestRejectReasons.REQUEST_REJECT_REASON_NONE, # bloodPressureMeasureInterval - RequestRejectReasons.REQUEST_REJECT_REASON_NONE, # rinsebackFlowRate - RequestRejectReasons.REQUEST_REJECT_REASON_NONE, # arterialPressureLimitLow - RequestRejectReasons.REQUEST_REJECT_REASON_NONE, # arterialPressureLimitHigh - RequestRejectReasons.REQUEST_REJECT_REASON_NONE, # venousPressureLimitLow - RequestRejectReasons.REQUEST_REJECT_REASON_NONE, # venousPressureLimitHigh - RequestRejectReasons.REQUEST_REJECT_REASON_NONE, # heparinDispensingRate - RequestRejectReasons.REQUEST_REJECT_REASON_NONE, # heparinBolusVolume - RequestRejectReasons.REQUEST_REJECT_REASON_NONE, # dialysateTemp + self.treatment_parameter_rejections.param_request_valid, + self.treatment_parameter_rejections.param_blood_flow_rate, + self.treatment_parameter_rejections.param_dialysate_flow_rate, + self.treatment_parameter_rejections.param_duration, + self.treatment_parameter_rejections.param_heparin_stop_time, + self.treatment_parameter_rejections.param_saline_bolus, + self.treatment_parameter_rejections.param_acid_concentrate, + self.treatment_parameter_rejections.param_bicarbonate_concentrate, + self.treatment_parameter_rejections.param_dialyzer_type, + self.treatment_parameter_rejections.param_blood_pressure_measure_interval, + self.treatment_parameter_rejections.param_rinseback_flow_rate, + self.treatment_parameter_rejections.param_arterial_pressure_limit_low, + self.treatment_parameter_rejections.param_arterial_pressure_limit_high, + self.treatment_parameter_rejections.param_venous_pressure_limit_low, + self.treatment_parameter_rejections.param_venous_pressure_limit_high, + self.treatment_parameter_rejections.param_heparin_dispensing_rate, + self.treatment_parameter_rejections.param_heparin_bolus_volume, + self.treatment_parameter_rejections.param_dialysate_temp ] + self.cmd_send_treatment_parameter_validation_response(rejections) + + def test_started(self, test_name: str): + """ + Logs that a test was started + + @param test_name: The name of the test + @return: None + """ + self.logger.info("Test Started: {0}".format(test_name)) + + def test_completed(self): + """ + Logs that a test was completed + + @return: None + """ + self.logger.info("Test Completed") + Index: dialin/ui/hd_simulator_alarms.py =================================================================== diff -u -rc864e886bc1b52d3a43f03c507425248c44a913f -rda3d88051a0ccd89f86ed4f6c2bbb0a067b6f148 --- dialin/ui/hd_simulator_alarms.py (.../hd_simulator_alarms.py) (revision c864e886bc1b52d3a43f03c507425248c44a913f) +++ dialin/ui/hd_simulator_alarms.py (.../hd_simulator_alarms.py) (revision da3d88051a0ccd89f86ed4f6c2bbb0a067b6f148) @@ -20,7 +20,7 @@ from ..utils.base import _AbstractSubSystem from ..utils.conversions import integer_to_bytearray from ..common.msg_defs import MsgIds -from ..common.alarm_defs import AlarmList, AlarmPriorities +from ..common.alarm_defs import AlarmList from time import sleep, time HIGH = 3 Index: tests/unit_tests/test_enums.py =================================================================== diff -u --- tests/unit_tests/test_enums.py (revision 0) +++ tests/unit_tests/test_enums.py (revision da3d88051a0ccd89f86ed4f6c2bbb0a067b6f148) @@ -0,0 +1,39 @@ +########################################################################### +# +# Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +# +# THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +# WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +# +# @file test_enums.py +# +# @author (last) Peter Lucia +# @date (last) 21-Aug-2020 +# @author (original) Peter Lucia +# @date (original) 11-Aug-2020 +# +############################################################################ +import unittest +import sys +sys.path.append("../../") + + +class Test(unittest.TestCase): + + def test_msg_defs(self): + try: + from dialin.common.msg_defs import MsgIds + from dialin.common.msg_defs import RequestRejectReasons + except ValueError as e: + self.fail("Could not import msg_defs: {0}".format(e)) + + def test_alarms(self): + try: + from dialin.common.alarm_defs import AlarmList + from dialin.common.alarm_defs import AlarmPriorities + except ValueError as e: + self.fail("Could not import alarm_defs: {0}".format(e)) + + +if __name__ == '__main__': + sys.exit(unittest.main(verbosity=2).result.wasSuccessful())