Index: dialin/dg/dialysate_generator.py =================================================================== diff -u -rde47961f6e48e38b2118b4c437718031c854aaba -r441eda312faf87b49f0967d8413690c7f63f9b58 --- dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision de47961f6e48e38b2118b4c437718031c854aaba) +++ dialin/dg/dialysate_generator.py (.../dialysate_generator.py) (revision 441eda312faf87b49f0967d8413690c7f63f9b58) @@ -14,7 +14,6 @@ # ############################################################################ import struct -from time import sleep from .drain_pump import DGDrainPump from .hd_proxy import DGHDProxy from .load_cells import DGLoadCells @@ -38,21 +37,25 @@ MSG_ID_DG_OPERATION_MODE_BROADCAST = 0x0027 MSG_ID_LOGIN_TO_DG = 0xA000 MSG_ID_DG_MSG = 0xA001 - MSG_ID_DG_REQUEST_DG_VERSION = 0xA002 - MSG_ID_DG_DG_VERSION_RESPONSE = 0xA003 + MSG_ID_DG_REQUEST_DG_VERSION = 0x001C + MSG_ID_DG_DG_VERSION_RESPONSE = 0x001E # HD login password DG_LOGIN_PASSWORD = '123' # broadcast message field positions START_POS_DG_OP_MODE = DenaliMessage.PAYLOAD_START_INDEX END_POS_DG_OP_MODE = START_POS_DG_OP_MODE + 4 + START_POS_DG_SUB_MODE = END_POS_DG_OP_MODE + END_POS_DG_SUB_MODE = START_POS_DG_SUB_MODE + 4 # DG version message field positions START_POS_MAJOR = DenaliMessage.PAYLOAD_START_INDEX END_POS_MAJOR = START_POS_MAJOR + 1 START_POS_MINOR = END_POS_MAJOR END_POS_MINOR = START_POS_MINOR + 1 + START_POS_MICRO = END_POS_MINOR + END_POS_MICRO = START_POS_MICRO + 1 START_POS_BUILD = END_POS_MINOR END_POS_BUILD = START_POS_BUILD + 2 @@ -92,13 +95,15 @@ msg_id = self.MSG_ID_DG_OPERATION_MODE_BROADCAST self.can_interface.register_receiving_publication_function(channel_id, msg_id, self.handler_dg_op_mode_sync) - self.can_interface.register_receiving_publication_function(DenaliChannels.dg_to_dialin_ch_id, self.MSG_ID_DG_DG_VERSION_RESPONSE, - self.handler_dg_version) + self.can_interface.register_receiving_publication_function(DenaliChannels.dg_to_dialin_ch_id, + self.MSG_ID_DG_DG_VERSION_RESPONSE, + self.handler_dg_version) # initialize variables that will be populated by DG version response self.dg_version = '' # create properties self.dg_operation_mode = self.DG_OP_MODE_INIT_POST + self.dg_operation_sub_mode = 0 # Create command groups self.hd_proxy = DGHDProxy(self.can_interface) @@ -123,10 +128,12 @@ message['message'][self.START_POS_MAJOR:self.END_POS_MAJOR])) minor = struct.unpack('B', bytearray( message['message'][self.START_POS_MINOR:self.END_POS_MINOR])) + micro = struct.unpack('B', bytearray( + message['message'][self.START_POS_MICRO:self.END_POS_MICRO])) build = struct.unpack('H', bytearray( message['message'][self.START_POS_BUILD:self.END_POS_BUILD])) - self.dg_version = 'v' + str(major) + '.' + str(minor) + '.' + str(build) + self.dg_version = 'v' + str(major) + '.' + str(minor) + '.' + str(micro) + '-' + str(build) def handler_dg_op_mode_sync(self, message): """ @@ -139,8 +146,11 @@ mode = struct.unpack('i', bytearray( message['message'][self.START_POS_DG_OP_MODE:self.END_POS_DG_OP_MODE])) + smode = struct.unpack('i', bytearray( + message['message'][self.START_POS_DG_SUB_MODE:self.END_POS_DG_SUB_MODE])) self.dg_operation_mode = mode[0] + self.dg_operation_sub_mode = smode[0] def cmd_log_in_to_dg(self): """ Index: dialin/dg/drain_pump.py =================================================================== diff -u -r7b2d65304d1cc925e5000d9621fa195ce6a08cf1 -r441eda312faf87b49f0967d8413690c7f63f9b58 --- dialin/dg/drain_pump.py (.../drain_pump.py) (revision 7b2d65304d1cc925e5000d9621fa195ce6a08cf1) +++ dialin/dg/drain_pump.py (.../drain_pump.py) (revision 441eda312faf87b49f0967d8413690c7f63f9b58) @@ -36,8 +36,8 @@ # Drain pump broadcast message field positions START_POS_SET_SPD = DenaliMessage.PAYLOAD_START_INDEX END_POS_SET_SPD = START_POS_SET_SPD + 4 - START_POS_PWM = END_POS_SET_SPD - END_POS_PWM = START_POS_PWM + 4 + START_POS_DAC = END_POS_SET_SPD + END_POS_DAC = START_POS_DAC + 4 def __init__(self, can_interface=None): """ @@ -54,7 +54,7 @@ self.handler_drain_pump_sync) self.target_drain_pump_speed_RPM = 0 - self.pwm_duty_cycle_pct = 0.0 + self.dacValue = 0 def handler_drain_pump_sync(self, message): """ @@ -67,11 +67,11 @@ tgt = struct.unpack('i', bytearray( message['message'][self.START_POS_SET_SPD:self.END_POS_SET_SPD])) - pwm = struct.unpack('f', bytearray( - message['message'][self.START_POS_PWM:self.END_POS_PWM])) + dac = struct.unpack('i', bytearray( + message['message'][self.START_POS_DAC:self.END_POS_DAC])) self.target_drain_pump_speed_RPM = tgt[0] - self.pwm_duty_cycle_pct = pwm[0] + self.dacValue = dac[0] def cmd_drain_pump_speed_set_point_override(self, speed, reset=NO_RESET): """ Index: dialin/dg/hd_proxy.py =================================================================== diff -u -rd24761670b6f557bf44ff5bb762c119a2e7cc889 -r441eda312faf87b49f0967d8413690c7f63f9b58 --- dialin/dg/hd_proxy.py (.../hd_proxy.py) (revision d24761670b6f557bf44ff5bb762c119a2e7cc889) +++ dialin/dg/hd_proxy.py (.../hd_proxy.py) (revision 441eda312faf87b49f0967d8413690c7f63f9b58) @@ -29,6 +29,7 @@ MSG_ID_HD_FILL_CMD = 0x0022 MSG_ID_HD_DRAIN_CMD = 0x0023 MSG_ID_HD_START_STOP_DG_CMD = 0x0026 + MSG_ID_HD_START_STOP_DG_TRIMMER_HEATER = 0x002B # Reservoir IDs RESERVOIR1 = 0 @@ -165,3 +166,36 @@ print("Timeout!!!!") return False + def cmd_start_stop_trimmer_heater(self, start=True): + """ + Constructs and sends the start/stop DG trimmer heater command + + \param start: boolean - True = start heater, False = stop heater. + \returns 1 if successful, zero otherwise + """ + + if start: + cmd = 1 + str = "start " + else: + cmd = 0 + str = "stop" + payload = integer_to_bytearray(cmd) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, + message_id=self.MSG_ID_HD_START_STOP_DG_TRIMMER_HEATER, + payload=payload) + + print(str+"DG trimmer heater cmd sent to DG") + + # 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: + print("Timeout!!!!") + return False + Index: dialin/hd/ui_proxy.py =================================================================== diff -u -rcdd3a485aebd088ffcab9848e6f1d0ec50e29624 -r441eda312faf87b49f0967d8413690c7f63f9b58 --- dialin/hd/ui_proxy.py (.../ui_proxy.py) (revision cdd3a485aebd088ffcab9848e6f1d0ec50e29624) +++ dialin/hd/ui_proxy.py (.../ui_proxy.py) (revision 441eda312faf87b49f0967d8413690c7f63f9b58) @@ -53,6 +53,8 @@ END_POS_MAJOR = START_POS_MAJOR + 1 START_POS_MINOR = END_POS_MAJOR END_POS_MINOR = START_POS_MINOR + 1 + START_POS_MICRO = END_POS_MINOR + END_POS_MICRO = START_POS_MICRO + 1 START_POS_BUILD = END_POS_MINOR END_POS_BUILD = START_POS_BUILD + 2 @@ -166,6 +168,7 @@ \param message: response message from HD regarding valid treatment parameter ranges.\n U08 Major \n U08 Minor \n + U08 Micro \n U16 Build \n \returns none @@ -174,10 +177,12 @@ message['message'][self.START_POS_MAJOR:self.END_POS_MAJOR])) minor = struct.unpack('B', bytearray( message['message'][self.START_POS_MINOR:self.END_POS_MINOR])) + micro = struct.unpack('B', bytearray( + message['message'][self.START_POS_MICRO:self.END_POS_MICRO])) build = struct.unpack('H', bytearray( message['message'][self.START_POS_BUILD:self.END_POS_BUILD])) - self.hd_version = 'v'+str(major[0])+'.'+str(minor[0])+'.'+str(build[0]) + self.hd_version = 'v'+str(major[0])+'.'+str(minor[0])+'.'+str(micro[0])+'-'+str(build[0]) print(self.hd_version) def handler_treatment_param_ranges(self, message): Index: tests/SeansUFTest.py =================================================================== diff -u -rcdd3a485aebd088ffcab9848e6f1d0ec50e29624 -r441eda312faf87b49f0967d8413690c7f63f9b58 --- tests/SeansUFTest.py (.../SeansUFTest.py) (revision cdd3a485aebd088ffcab9848e6f1d0ec50e29624) +++ tests/SeansUFTest.py (.../SeansUFTest.py) (revision 441eda312faf87b49f0967d8413690c7f63f9b58) @@ -17,40 +17,54 @@ import sys sys.path.append("..") from dialin.hd.hemodialysis_device import HD +from dialin.dg.dialysate_generator import DG from time import sleep if __name__ == "__main__": # create an HD object called hd hd = HD() + # create a DG object called dg + dg = DG() sleep(2) - # log in to HD as tester + # log in to HD and DG as tester if hd.cmd_log_in_to_hd() == 0: exit(1) + if dg.cmd_log_in_to_dg() == 0: + exit(1) sleep(1) - loadCellGrams = float(1500.0) #start reservoir at 1.5 L (1,500 g) - hdUFRate = 20.0 #assuming UF rate is 20 mL/min - idealWeightChange = hdUFRate / 60.0 #if DPo is controlling perfectly, this would be the weight gain per second - - while hd.dialysate_outlet_flow.PWMDutyCyclePct < 15.0: #wait for treatment to start - hd.dialysate_outlet_flow.CmdSetLoadCellWeights(loadCellGrams, 0.0, 0.0, 0.0) - sleep(1) - - # simulate load cell increase over time w/ some response to UF control + # collect UF related data from HD and DG while True: sleep(1) - error = hd.dialysate_outlet_flow.PWMDutyCyclePct - hd.dialysate_outlet_flow.PWMDutyCyclePct - addedWeight = error * 0.1 - loadCellGrams += addedWeight - hd.dialysate_outlet_flow.CmdSetLoadCellWeights(loadCellGrams, 0.0, 0.0, 0.0) - print("DPi PWM: " + str(hd.dialysate_outlet_flow.PWMDutyCyclePct) + " DPo PWM: " + str(hd.dialysate_outlet_flow.PWMDutyCyclePct)) - print("Treatment Time: " + str(hd.treatment.TreatmentTimeElapsed) + " sec.") - print("Reservoir Vol.: " + str(loadCellGrams) + " mL.") - print("Reference Vol.: " + str(hd.dialysate_outlet_flow.ReferenceDialysateOutletUFVolume) + " mL.") - print("Meas. UF Vol.: " + str(hd.dialysate_outlet_flow.MeasuredDialysateOutletUFVolume) + " mL.") - print("") + pumpSetPts = "B," + str(hd.bloodflow.target_blood_flow_rate) + \ + ",DI," + str(hd.dialysate_inlet_flow.target_dialysate_inlet_flow_rate) + \ + ",DO,N/A,RO," + str(dg.ro_pump.target_pressure_psi) + \ + ",DR," + str(dg.drain_pump.target_drain_pump_speed_RPM) + pumpMeasSpds = "B.m," + str(hd.bloodflow.measured_blood_pump_speed) + \ + ",B.r," + str(hd.bloodflow.measured_blood_pump_rotor_speed) + \ + ",DI.m," + str(hd.dialysate_inlet_flow.measured_dialysate_inlet_pump_speed) + \ + ",DI.r," + str(hd.dialysate_inlet_flow.measured_dialysate_inlet_pump_rotor_speed) + \ + ",DO.m," + str(hd.dialysate_outlet_flow.measured_dialysate_outlet_pump_speed) + \ + ",DO.r," + str(hd.dialysate_outlet_flow.measured_dialysate_outlet_pump_rotor_speed) + pumpPWMs = "B,"+str(hd.bloodflow.pwm_duty_cycle_pct) + \ + ",DI," + str(hd.dialysate_inlet_flow.pwm_duty_cycle_pct) + \ + ",DO," + str(hd.dialysate_outlet_flow.pwm_duty_cycle_pct) + \ + ",RO," + str(dg.ro_pump.pwm_duty_cycle_pct) + \ + ",DR," + str(dg.drain_pump.dacValue) + loadCells = "A1," + str(dg.load_cells.load_cell_A1) + \ + ",B1," + str(dg.load_cells.load_cell_B1) + \ + ",A2," + str(dg.load_cells.load_cell_A2) + \ + ",B2," + str(dg.load_cells.load_cell_B2) + ultraFilt = "RfUF," + str(hd.dialysate_outlet_flow.reference_dialysate_outlet_uf_volume) + \ + ",MsUF," + str(hd.dialysate_outlet_flow.measured_dialysate_outlet_uf_volume) - exit(1) + print("Pump Set Points: "+pumpSetPts) + print(" Pump Speeds: "+pumpMeasSpds) + print(" Pump PWMs/DACs: "+pumpPWMs) + print(" Load Cells: "+loadCells) + print("Ultrafiltration: "+ultraFilt) +# exit(1) +