# -*- coding: utf-8 -*- ## # Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. # copyright # 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 denaliMessages.py # date 2020/04/08 # author Behrouz NematiPour # import subprocess import utils import messageBuilder from enum import IntEnum class GuiActionType(IntEnum): Unknown = 0 PowerOff = 1 KeepAlive = 7 BloodFlow = 5 DialysateInletFlow = 8 DialysateOutletFlow = 11 TreatmentTime = 13 PowerOffBroadcast = 14 AlarmStatus = 2 AlarmTriggered = 3 AlarmCleared = 4 PressureOcclusion = 9 AdjustBloodDialysateReq = 23 # 23 AdjustBloodDialysateRsp = 24 # 24 TreatmentRanges = 26 # 26 String = 65279 Acknow = 65535 def send_acknowledge_HD(): subprocess.call(['cansend', 'can0', '020#A5.01.00.FF.FF.00.44.00']) def send_acknowledge_UI(): subprocess.call(['cansend', 'can0', '100#A5.01.00.FF.FF.00.44.00']) def show_PowerOffDialog(): subprocess.call(['cansend', 'can0', '020#A5.01.00.01.00.01.00.38']) def hide_PowerOffDialog(): subprocess.call(['cansend', 'can0', '020#A5.01.00.01.00.01.01.09']) def show_PowerOffNotificationDialog(): subprocess.call(['cansend', 'can0', '040#A5.01.00.0E.00.00.24.00']) def show_PowerOffRejectionDialog(): subprocess.call(['cansend', 'can0', '020#A5.01.00.01.00.01.02.5A']) ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def buildSetTreatmentParamRanges(vMinTreatmentDuration, vMaxTreatmentDuration, vMinUFVolume, vMaxUFVolume, vMinDialysateFlowRate, vMaxDialysateFlowRate): msg = messageBuilder.buildMessage( GuiActionType.TreatmentRanges, 4 * 6, utils.toU32(vMinTreatmentDuration), utils.toU32(vMaxTreatmentDuration), utils.toU32(vMinUFVolume ), utils.toU32(vMaxUFVolume ), utils.toU32(vMinDialysateFlowRate), utils.toU32(vMaxDialysateFlowRate) ) return messageBuilder.toFrames(msg) ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def setTreatmentParamRanges(vMinTreatmentDuration, vMaxTreatmentDuration, vMinUFVolume, vMaxUFVolume, vMinDialysateFlowRate, vMaxDialysateFlowRate): # This message needs to be acknowledged by seq# 01.00 : just call send_acknowledge_UI after this # ------------------------------------------vvvvv----------------------------------------------- frames = buildSetTreatmentParamRanges(vMinTreatmentDuration, vMaxTreatmentDuration, vMinUFVolume, vMaxUFVolume, vMinDialysateFlowRate, vMaxDialysateFlowRate) frames = messageBuilder.toCandumpFormat(frames) for frame in frames: subprocess.call(['cansend', 'can0', '020#{}'.format(frame)]) ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def buildSetTreatmentBloodFlowRate(vFlowSetPt, vMeasFlow = 0, vRotSpd = 0, vMotSpd = 0, vMCSpd = 0, vMCCurr = 0, vPWM = 0): msg = messageBuilder.buildMessage( 5, 4 * 7, utils.toU32(vFlowSetPt ), utils.toU32(vMeasFlow ), # it has to be F32 and at this moment I haven't implemented and I don't currently need it utils.toU32(vRotSpd ), # it has to be F32 and at this moment I haven't implemented and I don't currently need it utils.toU32(vMotSpd ), # it has to be F32 and at this moment I haven't implemented and I don't currently need it utils.toU32(vMCSpd ), # it has to be F32 and at this moment I haven't implemented and I don't currently need it utils.toU32(vMCCurr ), # it has to be F32 and at this moment I haven't implemented and I don't currently need it utils.toU32(vPWM ) # it has to be F32 and at this moment I haven't implemented and I don't currently need it ) return messageBuilder.toFrames(msg) ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def setTreatmentBloodFlowRate(vFlowSetPt): frames = buildSetTreatmentBloodFlowRate(vFlowSetPt) frames = messageBuilder.toCandumpFormat(frames) for frame in frames: subprocess.call(['cansend', 'can0', '040#{}'.format(frame)]) ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def buildSetTreatmentDialysateFlowRate(vFlowSetPt, vMeasFlow = 0, vRotSpd = 0, vMotSpd = 0, vMCSpd = 0, vMCCurr = 0, vPWM = 0): msg = messageBuilder.buildMessage( 8, 4 * 7, utils.toU32(vFlowSetPt ), utils.toU32(vMeasFlow ), # it has to be F32 and at this moment I haven't implemented and I don't currently need it utils.toU32(vRotSpd ), # it has to be F32 and at this moment I haven't implemented and I don't currently need it utils.toU32(vMotSpd ), # it has to be F32 and at this moment I haven't implemented and I don't currently need it utils.toU32(vMCSpd ), # it has to be F32 and at this moment I haven't implemented and I don't currently need it utils.toU32(vMCCurr ), # it has to be F32 and at this moment I haven't implemented and I don't currently need it utils.toU32(vPWM ) # it has to be F32 and at this moment I haven't implemented and I don't currently need it ) return messageBuilder.toFrames(msg) ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def setTreatmentDialysateFlowRate(vFlowSetPt): frames = buildSetTreatmentDialysateFlowRate(vFlowSetPt) frames = messageBuilder.toCandumpFormat(frames) for frame in frames: subprocess.call(['cansend', 'can0', '040#{}'.format(frame)]) ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def buildTreatmentAdjustBloodDialysateResponse(vAccepted, vReason, vBloodRate, vDialysate): msg = messageBuilder.buildMessage( GuiActionType.AdjustBloodDialysateRsp, 4 * 4, utils.toU32(vAccepted), utils.toU32(vReason), utils.toU32(vBloodRate), utils.toU32(vDialysate) ) return messageBuilder.toFrames(msg) def sendTreatmentAdjustBloodDialysateResponse(vAccepted, vReason, vBloodRate, vDialysate): frames = buildTreatmentAdjustBloodDialysateResponse(vAccepted, vReason, vBloodRate, vDialysate) frames = messageBuilder.toCandumpFormat(frames) for frame in frames: subprocess.call(['cansend', 'can0', '020#{}'.format(frame)]) ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def buildTreatmentTime(vSecsTotal, vSecsElap, vSecsRem): msg = messageBuilder.buildMessage( GuiActionType.TreatmentTime, 3 * 4, utils.toU32(vSecsTotal ), utils.toU32(vSecsElap ), utils.toU32(vSecsRem ) ) return messageBuilder.toFrames(msg) ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def setTreatmentTime(vSecsTotal, vSecsElap, vSecsRem): frames = buildTreatmentTime(vSecsTotal, vSecsElap, vSecsRem) frames = messageBuilder.toCandumpFormat(frames) for frame in frames: subprocess.call(['cansend', 'can0', '040#{}'.format(frame)]) ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def buildAlarm(vState, vTop, vEsclatesIn, vSilentExpires, vFlags): msg = messageBuilder.buildMessage( GuiActionType.AlarmStatus, 4 * 4 + 2, utils.toU32(vState ), utils.toU32(vTop ), utils.toU32(vEsclatesIn ), utils.toU32(vSilentExpires ), utils.toU16(vFlags ) ) return messageBuilder.toFrames(msg) ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def sendAlarm(vState, vTop, vEsclatesIn, vSilentExpires, vFlags): frames = buildAlarm(vState, vTop, vEsclatesIn, vSilentExpires, vFlags) frames = messageBuilder.toCandumpFormat(frames) for frame in frames: subprocess.call(['cansend', 'can0', '001#{}'.format(frame)])