########################################################################### # # 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 drain_pump.py # # @date 14-Apr-2020 # @author S. Nash # # @brief # # ############################################################################ import struct from ..utils.conversions import integer_to_bytearray from .constants import RESET, NO_RESET from ..protocols.CAN import (DenaliMessage, DenaliChannels) from ..utils.base import _AbstractSubSystem, _publish from logging import Logger class DGDrainPump(_AbstractSubSystem): """ Dialysate Generator (DG) Dialin API sub-class for drain pump related commands. """ # Drain pump message IDs MSG_ID_DG_DRAIN_PUMP_PUBLISHED_DATA = 0x0024 MSG_ID_DG_DRAIN_PUMP_SET_SPEED_OVERRIDE = 0xA00B MSG_ID_DG_DRAIN_PUMP_BROADAST_INTERVAL_OVERRIDE = 0xA00C, # 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_DAC = END_POS_SET_SPD END_POS_DAC = START_POS_DAC + 4 def __init__(self, can_interface, logger: Logger): """ DGDrainPump constructor """ super().__init__() self.can_interface = can_interface self.logger = logger if self.can_interface is not None: channel_id = DenaliChannels.dg_sync_broadcast_ch_id msg_id = self.MSG_ID_DG_DRAIN_PUMP_PUBLISHED_DATA self.can_interface.register_receiving_publication_function(channel_id, msg_id, self._handler_drain_pump_sync) self.target_drain_pump_speed_RPM = 0 self.dac_value = 0 def get_target_drain_pump_speed(self): """ Gets the target drain pump speed @return: The target drain pump speed (RPM) """ return self.target_drain_pump_speed_RPM def get_dac_value(self): """ Gets the dac value @return: The dac value (int) """ return self.dac_value @_publish(["target_drain_pump_speed_RPM", "dac_value"]) def _handler_drain_pump_sync(self, message): """ Handles published drain pump data messages. Drain pump data are captured for reference. @param message: published drain pump data message @return: none """ tgt = struct.unpack('i', bytearray( message['message'][self.START_POS_SET_SPD:self.END_POS_SET_SPD])) dac = struct.unpack('i', bytearray( message['message'][self.START_POS_DAC:self.END_POS_DAC])) self.target_drain_pump_speed_RPM = tgt[0] self.dac_value = dac[0] def cmd_drain_pump_speed_set_point_override(self, speed, reset=NO_RESET): """ Constructs and sends the drain pump speed set point override command @param speed: integer - speed set point (in RPM) 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) spd = integer_to_bytearray(speed) payload = rst + spd message = DenaliMessage.build_message(channel_id=DenaliChannels.dialin_to_dg_ch_id, message_id=self.MSG_ID_DG_DRAIN_PUMP_SET_SPEED_OVERRIDE, payload=payload) self.logger.debug("override drain pump speed set point") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(speed) self.logger.debug("Drain pump set point overridden to " + str_res + " RPM: " + 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_drain_pump_data_broadcast_interval_override(self, ms, reset=NO_RESET): """ Constructs and sends the drain pump speed set point override command @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_dg_ch_id, message_id=self.MSG_ID_DG_DRAIN_PUMP_BROADAST_INTERVAL_OVERRIDE, payload=payload) self.logger.debug("override drain pump data broadcast interval") # Send message received_message = self.can_interface.send(message) # If there is content... if received_message is not None: # self.logger.debug(received_message) if reset == RESET: str_res = "reset back to normal" else: str_res = str(mis) self.logger.debug( "Drain pump data broadcast interval overridden to " + str_res + " ms: " + 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