Index: dialin/common/msg_defs.py =================================================================== diff -u -r0a5edee793018705c54562d73a9a1d5ee648cb41 -r3b8ec241845f0bfbeebc3f6e14160b9e7148fc3b --- dialin/common/msg_defs.py (.../msg_defs.py) (revision 0a5edee793018705c54562d73a9a1d5ee648cb41) +++ dialin/common/msg_defs.py (.../msg_defs.py) (revision 3b8ec241845f0bfbeebc3f6e14160b9e7148fc3b) @@ -110,6 +110,22 @@ MSG_ID_HD_BLOOD_PRIME_PROGRESS = 0x59 # HD broadcast of blood prime progress MSG_ID_HD_RECIRC_PROGRESS = 0x5A # HD broadcast of treatment re-circulate progress MSG_ID_DG_CHANGE_VALVE_SETTING_CMD = 0x5B # HD request to DG to change valve setting + MSG_ID_PRE_TREATMENT_STATE = 0x5C # HD broadcast of pre-treatment state + MSG_ID_UI_SAMPLE_WATER_CMD = 0x5D # UI sample water sub-mode user request + MSG_ID_HD_SAMPLE_WATER_CMD_RESPONSE = 0x5E # HD sample water sub-mode request response + MSG_ID_UI_SAMPLE_WATER_RESULT = 0x5F # UI sample water result message + MSG_ID_DG_FILTER_FLUSH_PROGRESS = 0x60 # DG broadcast of filter flush progress + MSG_ID_HD_NO_CART_SELF_TEST_PROGRESS = 0x61 # HD broadcast of no cartridge self-tests progress + MSG_ID_UI_INSTALLATION_CONFIRM = 0x62 # UI disposable installation user confirmation + MSG_ID_HD_DRY_SELF_TEST_PROGRESS = 0x63 # HD broadcast of dry self-tests progress + MSG_ID_UI_CONTINUE_TO_TREATMENT_REQUEST = 0x64 # UI user has requested to continue to treatment + MSG_ID_HD_CONTINUE_TO_TREATMENT_RESPONSE = 0x65 # HD response to user request to continue to treatment + MSG_ID_UI_PATIENT_CONNECTION_CONFIRM = 0x66 # UI user has confirmed patient connection completed + MSG_ID_HD_PATIENT_CONNECTION_CONFIRM_RESPONSE = 0x67 # HD response to user confirmation of patient connection + MSG_ID_UI_CONSUMABLE_INSTALL_CONFIRM = 0x68 # UI user has confirmed consumable install + MSG_ID_HD_SYRINGE_PUMP_DATA = 0x69 # HD broadcast of syringe pump data + MSG_ID_HD_FLUID_LEAK_STATE = 0x6A # HD broadcast of fluid leak state + MSG_ID_DG_FLUID_LEAK_STATE = 0x6B # DG broadcast of fluid leak state MSG_ID_CAN_ERROR_COUNT = 0x999 # test code in support of EMC testing @@ -156,9 +172,9 @@ MSG_ID_HD_ACCEL_OVERRIDE = 0x8027 # HD accelerometer sensor override request MSG_ID_HD_ACCEL_MAX_OVERRIDE = 0x8028 # HD accelerometer sensor max. override request MSG_ID_HD_ACCEL_SEND_INTERVAL_OVERRIDE = 0x8029 # HD accelerometer data broadcast interval override request - MSG_ID_HD_ACCEL_SET_CALIBRATION = 0x802A # HD accelerometer set calibration factors request - MSG_ID_HD_BLOOD_FLOW_SET_CALIBRATION = 0x802B # Blood flow set calibration factors request - MSG_ID_HD_DIALYSATE_FLOW_SET_CALIBRATION = 0x802C # Dialysate flow set calibration factors request + MSG_ID_HD_SYRINGE_PUMP_SEND_INTERVAL_OVERRIDE = 0x802A # HD syringe pump data broadcast interval override request + MSG_ID_HD_SYRINGE_PUMP_OPERATION_REQUEST = 0x802B # HD syringe pump operation request + MSG_ID_HD_SYRINGE_PUMP_MEASURED_RATE_OVERRIDE = 0x802C # HD syringe pump measured rate override request MSG_ID_HD_SET_PARAMETER_TREATMENT_PARAMETER = 0x802D # Set a treatment parameter (will change actual setting, not an override) MSG_ID_HD_VALVES_HOME = 0x802E # Home an HD Valve MSG_ID_HD_VALVES_POSITION_OVERRIDE = 0x802F # Set an HD valve to a position in counts @@ -173,8 +189,8 @@ MSG_ID_DIAL_IN_PUMP_HOME_CMD = 0x8038 # Dialysate inlet pump home command MSG_ID_DIAL_OUT_PUMP_HOME_CMD = 0x8039 # Dialysate outlet pump home command MSG_ID_SUPER_CLEAR_ALARMS_CMD = 0x803A # Clears all alarms (even if non-recoverable or fault) - MSG_ID_HD_REQUEST_CALIBRATION_DATA = 0x803B # Requests calibration data from HD - MSG_ID_HD_ERASE_CALIBRATION_DATA = 0x803C # Requests calibration data on HD be erased + MSG_ID_HD_SYRINGE_PUMP_MEASURED_FORCE_OVERRIDE = 0x803B # HD syringe pump measured force override request + MSG_ID_HD_SYRINGE_PUMP_SYRINGE_DETECT_OVERRIDE = 0x803C # HD syringe pump measured syringe detection override request MSG_ID_HD_SET_CALIBRATION_RECORD = 0x803D # HD set calibration record that is received from Dialin MSG_ID_HD_GET_CALIBRATION_RECORD = 0x803E # HD get calibration record that is requested from Dialin MSG_ID_HD_SEND_CALIBRATION_RECORD = 0x803F # HD send calibration record to CAN bus to be received in Dialin (equivalent to publish) @@ -185,6 +201,11 @@ MSG_ID_HD_SET_SERVICE_RECORD = 0x8044 # HD set service record that is received from Dialin MSG_ID_HD_SEND_SERVICE_RECORD = 0x8045 # HD send service record to CAN bus to be received in Dialin (equivalent to publish) MSG_ID_HD_SET_OP_MODE_REQUEST = 0x8046 # HD set operation mode request + MSG_ID_HD_FLUID_LEAK_SEND_INTERVAL_OVERRIDE = 0x8047 # HD fluid leak state broadcast interval override request + MSG_ID_HD_FLUID_LEAK_STATE_DETECTOR_OVERRIDE = 0x8048 # HD fluid leak state detector override request + MSG_ID_HD_SYRINGE_PUMP_MEASURED_HOME_OVERRIDE = 0x8049 # HD syringe pump measured home override request + MSG_ID_HD_SYRINGE_PUMP_MEASURED_POSITION_OVERRIDE = 0x804A # HD syringe pump measured position override request + MSG_ID_HD_SYRINGE_PUMP_MEASURED_VOLUME_OVERRIDE = 0x804B # HD syringe pump measured volume delivered override request MSG_ID_DG_TESTER_LOGIN_REQUEST = 0XA000 # DG tester log-in MSG_ID_DG_ALARM_STATE_OVERRIDE = 0xA001 # DG alarm state override message ID Index: dialin/hd/air_trap.py =================================================================== diff -u -r91dc90bd009bdbf5621dcaa1bc12ab3d691673f7 -r3b8ec241845f0bfbeebc3f6e14160b9e7148fc3b --- dialin/hd/air_trap.py (.../air_trap.py) (revision 91dc90bd009bdbf5621dcaa1bc12ab3d691673f7) +++ dialin/hd/air_trap.py (.../air_trap.py) (revision 3b8ec241845f0bfbeebc3f6e14160b9e7148fc3b) @@ -16,7 +16,7 @@ import struct from ..utils.conversions import integer_to_bytearray, float_to_bytearray from .constants import RESET,NO_RESET -from ..common.msg_defs import MsgIds +from ..common.msg_defs import MsgIds, MsgFieldPositions from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish @@ -30,12 +30,6 @@ Hemodialysis Delivery (HD) Dialin API sub-class for air trap related commands. """ - # Air trap broadcast message field positions - START_POS_LOWER_LEVEL = DenaliMessage.PAYLOAD_START_INDEX - END_POS_LOWER_LEVEL = START_POS_LOWER_LEVEL + 4 - START_POS_UPPER_LEVEL = END_POS_LOWER_LEVEL - END_POS_UPPER_LEVEL = START_POS_UPPER_LEVEL + 4 - # Air trap level sensor IDs LOWER_LEVEL_SENSOR = 0 UPPER_LEVEL_SENSOR = 1 @@ -97,9 +91,9 @@ """ lower = struct.unpack('i', bytearray( - message['message'][self.START_POS_LOWER_LEVEL:self.END_POS_LOWER_LEVEL])) + message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1])) upper = struct.unpack('i', bytearray( - message['message'][self.START_POS_UPPER_LEVEL:self.END_POS_UPPER_LEVEL])) + message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2])) self.lower_level = lower[0] self.upper_level = upper[0] Index: dialin/hd/hemodialysis_device.py =================================================================== diff -u -r0a5edee793018705c54562d73a9a1d5ee648cb41 -r3b8ec241845f0bfbeebc3f6e14160b9e7148fc3b --- dialin/hd/hemodialysis_device.py (.../hemodialysis_device.py) (revision 0a5edee793018705c54562d73a9a1d5ee648cb41) +++ dialin/hd/hemodialysis_device.py (.../hemodialysis_device.py) (revision 3b8ec241845f0bfbeebc3f6e14160b9e7148fc3b) @@ -27,6 +27,7 @@ from .treatment import HDTreatment from .valves import HDValves from .pressure_occlusion import HDPressureOcclusion +from .syringe_pump import HDSyringePump from ..protocols.CAN import (DenaliMessage, DenaliCanMessenger, DenaliChannels) @@ -117,6 +118,7 @@ self.dialysate_outlet_flow = HDDialysateOutletFlow(self.can_interface, self.logger) self.treatment = HDTreatment(self.can_interface, self.logger) self.pressure_occlusion = HDPressureOcclusion(self.can_interface, self.logger) + self.syringe_pump = HDSyringePump(self.can_interface, self.logger) self.valves = HDValves(self.can_interface, self.logger) def get_operation_mode(self): Index: dialin/hd/syringe_pump.py =================================================================== diff -u --- dialin/hd/syringe_pump.py (revision 0) +++ dialin/hd/syringe_pump.py (revision 3b8ec241845f0bfbeebc3f6e14160b9e7148fc3b) @@ -0,0 +1,496 @@ +########################################################################### +# +# 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 air_trap.py +# +# @author (last) Peter Lucia +# @date (last) 02-Oct-2020 +# @author (original) Sean Nash +# @date (original) 21-Sep-2020 +# +############################################################################ +import struct +from ..utils.conversions import integer_to_bytearray, float_to_bytearray +from .constants import RESET,NO_RESET +from ..common.msg_defs import MsgIds, MsgFieldPositions +from ..protocols.CAN import (DenaliMessage, + DenaliChannels) +from ..utils.base import _AbstractSubSystem, _publish +from logging import Logger + + +class HDSyringePump(_AbstractSubSystem): + """ + HDSyringePump + + Hemodialysis Delivery (HD) Dialin API sub-class for syringe pump related commands. + """ + + # Syringe pump states + SYRINGE_PUMP_INIT_STATE = 0 + SYRINGE_PUMP_OFF_STATE = 1 + SYRINGE_PUMP_RETRACT_STATE = 2 + SYRINGE_PUMP_SEEK_STATE = 3 + SYRINGE_PUMP_PRIME_STATE = 4 + SYRINGE_PUMP_HEP_BOLUS_STATE = 5 + SYRINGE_PUMP_HEP_CONTINUOUS_STATE = 6 + SYRINGE_PUMP_CONFIG_FORCE_SENSOR_STATE = 7 + + # Syringe pump operations + SYRINGE_PUMP_OP_STOP = 0 + SYRINGE_PUMP_OP_RETRACT = 1 + SYRINGE_PUMP_OP_SEEK_AND_PRIME = 2 + SYRINGE_PUMP_OP_BOLUS = 3 + SYRINGE_PUMP_OP_CONTINUOUS = 4 + + def __init__(self, can_interface, logger: Logger): + """ + + @param can_interface: Denali Can Messenger object + """ + super().__init__() + self.can_interface = can_interface + self.logger = logger + + if self.can_interface is not None: + channel_id = DenaliChannels.hd_sync_broadcast_ch_id + msg_id = MsgIds.MSG_ID_HD_SYRINGE_PUMP_DATA.value + self.can_interface.register_receiving_publication_function(channel_id, msg_id, + self._handler_syringe_pump_data) + + self.syringe_pump_state = self.SYRINGE_PUMP_INIT_STATE + self.syringe_pump_set_rate_ml_hr = 0.0 + self.syringe_pump_meas_rate_ml_hr = 0.0 + self.syringe_pump_position = 0 + self.syringe_pump_volume_ml = 0.0 + self.syringe_pump_home_v = 0.0 + self.syringe_pump_switch_v = 0.0 + self.syringe_pump_force_v = 0.0 + + def get_syringe_pump_state(self): + """ + Gets the current syringe pump state. + + @return: latest published syringe pump state. + SYRINGE_PUMP_INIT_STATE = 0 + SYRINGE_PUMP_OFF_STATE = 1 + SYRINGE_PUMP_RETRACT_STATE = 2 + SYRINGE_PUMP_SEEK_STATE = 3 + SYRINGE_PUMP_PRIME_STATE = 4 + SYRINGE_PUMP_HEP_BOLUS_STATE = 5 + SYRINGE_PUMP_HEP_CONTINUOUS_STATE = 6 + SYRINGE_PUMP_CONFIG_FORCE_SENSOR_STATE = 7 + """ + return self.syringe_pump_set_rate_ml_hr + + def get_syringe_pump_set_rate(self): + """ + Gets the current set syringe pump rate. + + @return: latest published syringe pump set rate (in mL/hr). + """ + return self.syringe_pump_set_rate_ml_hr + + def get_syringe_pump_meas_rate(self): + """ + Gets the current measured syringe pump rate. + + @return: latest published syringe pump measured rate (in mL/hr). + """ + return self.syringe_pump_meas_rate_ml_hr + + def get_syringe_pump_position(self): + """ + Gets the current syringe pump position. + + @return: latest published syringe pump position (in encoder counts). + """ + return self.syringe_pump_position + + def get_syringe_pump_volume_delivered_ml(self): + """ + Gets the current syringe pump volume delivered. + + @return: latest published syringe pump volume delivered (in mL). + """ + return self.syringe_pump_volume_ml + + def get_syringe_pump_home_v(self): + """ + Gets the current syringe pump home voltage reading + + @return: latest published voltage read from the home optical sensor + """ + return self.syringe_pump_home_v + + def get_syringe_pump_switch_v(self): + """ + Gets the current syringe pump switch voltage reading + + @return: latest published voltage read from the syringe detection switch + """ + return self.syringe_pump_switch_v + + def get_syringe_pump_force_v(self): + """ + Gets the current syringe pump force voltage reading + + @return: latest published voltage read from the force sensor + """ + return self.syringe_pump_force_v + + @_publish(["syringe_pump_state", "syringe_pump_set_rate_ml_hr", + "syringe_pump_meas_rate_ml_hr","syringe_pump_position", + "syringe_pump_volume_ml","syringe_pump_home_v", + "syringe_pump_switch_v","syringe_pump_force_v"]) + def _handler_syringe_pump_data(self, message): + """ + Handles published syringe pump data messages. Syringe pump data are captured + for reference. + + @param message: published syringe pump data message + @return: None + """ + + sta = struct.unpack('i', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_1:MsgFieldPositions.END_POS_FIELD_1])) + srt = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_2:MsgFieldPositions.END_POS_FIELD_2])) + mrt = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_3:MsgFieldPositions.END_POS_FIELD_3])) + pos = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_4:MsgFieldPositions.END_POS_FIELD_4])) + vol = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_5:MsgFieldPositions.END_POS_FIELD_5])) + hom = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_6:MsgFieldPositions.END_POS_FIELD_6])) + det = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_7:MsgFieldPositions.END_POS_FIELD_7])) + frc = struct.unpack('f', bytearray( + message['message'][MsgFieldPositions.START_POS_FIELD_8:MsgFieldPositions.END_POS_FIELD_8])) + + self.syringe_pump_state = sta[0] + self.syringe_pump_set_rate_ml_hr = srt[0] + self.syringe_pump_meas_rate_ml_hr = mrt[0] + self.syringe_pump_position = pos[0] + self.syringe_pump_volume_ml = vol[0] + self.syringe_pump_home_v = hom[0] + self.syringe_pump_switch_v = det[0] + self.syringe_pump_force_v = frc[0] + + def cmd_syringe_pump_operation(self, operation=SYRINGE_PUMP_OP_STOP, rate=0.0, volume=0.0): + """ + Constructs and sends the syringe pump operation command + Constraints: + Must be logged into HD. + Syringe pump must be in appropriate state for the given operation. + Given rate/volume (when applicable) must be within valid range for the given operation. + + @param operation: unsigned int - ID of operation being requested + @param rate: float - target rate for given operation (if applicable) + @param volume: float - target volume for given operation (if applicable) + @return: 1 if successful, zero otherwise + + Syringe pump operation IDs: + SYRINGE_PUMP_OP_STOP = 0 + SYRINGE_PUMP_OP_RETRACT = 1 + SYRINGE_PUMP_OP_SEEK_AND_PRIME = 2 + SYRINGE_PUMP_OP_BOLUS = 3 + SYRINGE_PUMP_OP_CONTINUOUS = 4 + """ + + op = integer_to_bytearray(operation) + rat = float_to_bytearray(rate) + vol = float_to_bytearray(volume) + payload = op + rat + vol + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_DG_AIR_TRAP_LEVEL_SENSOR_OVERRIDE.value, + payload=payload) + + self.logger.debug("requesting syringe pump operation " + str(operation) + + ", rate=" + str(rate) + + ", volume=" + str(volume)) + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_syringe_pump_data_broadcast_interval_override(self, ms=1000, reset=NO_RESET): + """ + Constructs and sends the syringe pump data broadcast interval override command + Constraints: + Must be logged into HD. + Given interval must be non-zero and a multiple of the HD general task interval (50 ms). + + @param ms: integer - interval (in ms) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + rst = integer_to_bytearray(reset) + mis = integer_to_bytearray(ms) + payload = rst + mis + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_SYRINGE_PUMP_SEND_INTERVAL_OVERRIDE.value, + payload=payload) + + self.logger.debug("override HD syringe pump data broadcast interval") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal: " + else: + str_res = str(ms) + " ms: " + self.logger.debug("Syringe pump data broadcast interval overridden to " + str_res + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_syringe_pump_meas_position_override(self, position=0, reset=NO_RESET): + """ + Constructs and sends the syringe pump measured position override command + Constraints: + Must be logged into HD. + + @param position: integer - position (in encoder counts) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + rst = integer_to_bytearray(reset) + pos = integer_to_bytearray(position) + payload = rst + pos + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_SYRINGE_PUMP_MEASURED_POSITION_OVERRIDE.value, + payload=payload) + + self.logger.debug("override HD syringe pump measured position") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal: " + else: + str_res = str(position) + " encoder counts: " + self.logger.debug("Syringe pump measured position overridden to " + str_res + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_syringe_pump_meas_rate_override(self, rate=0.0, reset=NO_RESET): + """ + Constructs and sends the syringe pump measured rate override command + Constraints: + Must be logged into HD. + + @param rate: float - rate (in mL/hr) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + rst = integer_to_bytearray(reset) + rat = integer_to_bytearray(rate) + payload = rst + rat + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_SYRINGE_PUMP_MEASURED_RATE_OVERRIDE.value, + payload=payload) + + self.logger.debug("override HD syringe pump measured rate") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal: " + else: + str_res = str(rate) + " mL/hr: " + self.logger.debug("Syringe pump measured rate overridden to " + str_res + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_syringe_pump_meas_force_override(self, volts=0.0, reset=NO_RESET): + """ + Constructs and sends the syringe pump measured force override command + Constraints: + Must be logged into HD. + + @param volts: float - volts to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + rst = integer_to_bytearray(reset) + vol = integer_to_bytearray(volts) + payload = rst + vol + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_SYRINGE_PUMP_MEASURED_FORCE_OVERRIDE.value, + payload=payload) + + self.logger.debug("override HD syringe pump measured force") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal: " + else: + str_res = str(volts) + " volts: " + self.logger.debug("Syringe pump measured force overridden to " + str_res + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_syringe_pump_meas_detect_override(self, volts=0.0, reset=NO_RESET): + """ + Constructs and sends the syringe pump measured syringe detect override command + Constraints: + Must be logged into HD. + + @param volts: float - volts to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + rst = integer_to_bytearray(reset) + vol = integer_to_bytearray(volts) + payload = rst + vol + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_SYRINGE_PUMP_SYRINGE_DETECT_OVERRIDE.value, + payload=payload) + + self.logger.debug("override HD syringe pump measured syringe detection") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal: " + else: + str_res = str(volts) + " volts: " + self.logger.debug("Syringe pump measured syringe detection overridden to " + str_res + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_syringe_pump_meas_home_override(self, volts=0.0, reset=NO_RESET): + """ + Constructs and sends the syringe pump measured home override command + Constraints: + Must be logged into HD. + + @param volts: float - volts to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + rst = integer_to_bytearray(reset) + vol = integer_to_bytearray(volts) + payload = rst + vol + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_SYRINGE_PUMP_MEASURED_HOME_OVERRIDE.value, + payload=payload) + + self.logger.debug("override HD syringe pump measured home") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal: " + else: + str_res = str(volts) + " volts: " + self.logger.debug("Syringe pump measured home overridden to " + str_res + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False + + def cmd_syringe_pump_meas_volume_override(self, volume=0.0, reset=NO_RESET): + """ + Constructs and sends the syringe pump measured volume override command + Constraints: + Must be logged into HD. + + @param volume: float - volume (in mL) to override with + @param reset: integer - 1 to reset a previous override, 0 to override + @return: 1 if successful, zero otherwise + """ + + rst = integer_to_bytearray(reset) + vol = integer_to_bytearray(volume) + payload = rst + vol + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_hd_ch_id, + message_id=MsgIds.MSG_ID_HD_SYRINGE_PUMP_MEASURED_VOLUME_OVERRIDE.value, + payload=payload) + + self.logger.debug("override HD syringe pump measured volume delivered") + + # Send message + received_message = self.can_interface.send(message) + + # If there is content... + if received_message is not None: + if reset == RESET: + str_res = "reset back to normal: " + else: + str_res = str(volume) + " mL: " + self.logger.debug("Syringe pump measured volume overridden to " + str_res + + str(received_message['message'][DenaliMessage.PAYLOAD_START_INDEX])) + # response payload is OK or not OK + return received_message['message'][DenaliMessage.PAYLOAD_START_INDEX] + else: + self.logger.debug("Timeout!!!!") + return False +