Commit c9999db9 authored by Gabriel Rodrigues's avatar Gabriel Rodrigues

Major Bug Fixes (++ Sensors Set to Brazil configuration)

parent 86860cef
Pipeline #3682 failed with stages
...@@ -67,6 +67,7 @@ from widget_library.numpad_widget import NumberpadWidget, AlphapadWidget ...@@ -67,6 +67,7 @@ from widget_library.numpad_widget import NumberpadWidget, AlphapadWidget
from widget_library.message_popup_widget import MessagePopup from widget_library.message_popup_widget import MessagePopup
logging.basicConfig( logging.basicConfig(
filename='NativeUI_logfile.txt',
level=logging.INFO, level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s \n (%(pathname)s, %(lineno)s)", format="%(asctime)s - %(levelname)s - %(message)s \n (%(pathname)s, %(lineno)s)",
) )
...@@ -321,7 +322,6 @@ class NativeUI(HEVClient, QMainWindow): ...@@ -321,7 +322,6 @@ class NativeUI(HEVClient, QMainWindow):
ToggleButtonPressed is emitted by the toggle button when pressed. ToggleButtonPressed is emitted by the toggle button when pressed.
""" """
# Startup connections # Startup connections
self.messagePopup.okButton.pressed.connect( self.messagePopup.okButton.pressed.connect(
lambda i=self.startupWidget: self.display_stack.setCurrentWidget(i) lambda i=self.startupWidget: self.display_stack.setCurrentWidget(i)
...@@ -678,6 +678,7 @@ class NativeUI(HEVClient, QMainWindow): ...@@ -678,6 +678,7 @@ class NativeUI(HEVClient, QMainWindow):
self.plot_timer.setInterval(16) # just faster than 60Hz self.plot_timer.setInterval(16) # just faster than 60Hz
self.plot_timer.timeout.connect(self.data_handler.on_timeout) self.plot_timer.timeout.connect(self.data_handler.on_timeout)
self.plot_timer.start() self.plot_timer.start()
# Localisation needs to update widgets # Localisation needs to update widgets
# localised_widgets = [ # localised_widgets = [
...@@ -812,7 +813,7 @@ class NativeUI(HEVClient, QMainWindow): ...@@ -812,7 +813,7 @@ class NativeUI(HEVClient, QMainWindow):
if not payload_registered: if not payload_registered:
logging.warning("Handlers: Invalid payload type: %s", payload["type"]) logging.warning("Handlers: Invalid payload type: %s", payload["type"])
logging.debug("Content of invalid payload:\n%s", payload) logging.debug("Content of invalid payload:\n%s", payload)
return 0 return 0
def toggle_editability(self): def toggle_editability(self):
......
{"calibration": {"label": "calibration", "last_performed": 1635763157, "cmd_code": "calib_rate", "message": "Ensure patient is disconnected from ventilator"}, "leak_test": {"label": "Leak Test", "last_performed": 1635763159, "cmd_code": "leak_test", "message": "Ensure patient is disconnected from ventilator"}} {"calibration": {"label": "calibration", "last_performed": 1652203447, "cmd_code": "calib_rate", "message": "Ensure patient is disconnected from ventilator"}, "leak_test": {"label": "Leak Test", "last_performed": 1652203448, "cmd_code": "leak_test", "message": "Ensure patient is disconnected from ventilator"}}
\ No newline at end of file \ No newline at end of file
...@@ -39,20 +39,20 @@ class BatteryHandler(PayloadHandler): ...@@ -39,20 +39,20 @@ class BatteryHandler(PayloadHandler):
except KeyError: except KeyError:
logging.debug("Keyerror in battery payload: 'bat'") logging.debug("Keyerror in battery payload: 'bat'")
if battery_data.has_key("bat85"): if "bat85" in battery_data:
try: try:
new_status["battery_percent_1"] = self.compute_battery_percent_hev(batter_data) new_status["battery_percent_1"] = self.compute_battery_percent_hev(battery_data)
new_status["battery_percent_2"] = 0 new_status["battery_percent_2"] = self.compute_battery_percent_hev(battery_data)
except KeyError: except KeyError:
logging.debug("Keyerror in battery payload: 'bat85'") logging.debug("Keyerror in battery payload: 'bat85'")
if battery_data.has_key("bat1_percent"): if "bat1_percent" in battery_data:
try: try:
new_status["battery_percent_1"] = int(battery_data["bat1_percent"]) new_status["battery_percent_1"] = int(battery_data["bat1_percent"])
except KeyError: except KeyError:
logging.debug("Keyerror in battery payload: 'bat1_percent'") logging.debug("Keyerror in battery payload: 'bat1_percent'")
if battery_data.has_key("bat2_percent"): if "bat2_percent" in battery_data:
try: try:
new_status["battery_percent_2"] = int(battery_data["bat2_percent"]) new_status["battery_percent_2"] = int(battery_data["bat2_percent"])
except KeyError: except KeyError:
...@@ -94,7 +94,7 @@ class BatteryHandler(PayloadHandler): ...@@ -94,7 +94,7 @@ class BatteryHandler(PayloadHandler):
""" """
if battery_data["bat85"] == 1: if battery_data["bat85"] == 1:
return 85.0 return 80
elif battery_data["bat85"] == 0: elif battery_data["bat85"] == 0:
return 0.0 return 0.0
else: else:
......
...@@ -117,7 +117,7 @@ class AlarmControlWidget(QtWidgets.QWidget): ...@@ -117,7 +117,7 @@ class AlarmControlWidget(QtWidgets.QWidget):
"""Mute button pressed. Switched to unmute button and sends Mute command""" """Mute button pressed. Switched to unmute button and sends Mute command"""
self.buttonPushed(-1) self.buttonPushed(-1)
self.iconStack.setCurrentWidget(self.offSpeakers) self.iconStack.setCurrentWidget(self.offSpeakers)
self.NativeUI.q_send_cmd("MUTE_ALARM", "TRUE") #self.NativeUI.q_send_cmd("MUTE_ALARM", "TRUE")
self.remaining_mute_time = 120 self.remaining_mute_time = 120
self.timer.start() self.timer.start()
...@@ -127,12 +127,12 @@ class AlarmControlWidget(QtWidgets.QWidget): ...@@ -127,12 +127,12 @@ class AlarmControlWidget(QtWidgets.QWidget):
self.offSpeakers.setText("120") self.offSpeakers.setText("120")
self.buttonPushed(self.volState) self.buttonPushed(self.volState)
self.iconStack.setCurrentWidget(self.onSpeakers) self.iconStack.setCurrentWidget(self.onSpeakers)
self.NativeUI.q_send_cmd("MUTE_ALARM", "FALSE") #self.NativeUI.q_send_cmd("MUTE_ALARM", "FALSE")
def test_speakers(self): def test_speakers(self):
logging.debug("testin!") logging.debug("testin!")
logging.debug(self.volState) logging.debug(self.volState)
self.NativeUI.q_send_cmd("TEST_AUDIO_ALARM") #self.NativeUI.q_send_cmd("TEST_AUDIO_ALARM")
def buttonPushed(self, index): def buttonPushed(self, index):
if index != -1: if index != -1:
......
...@@ -28,8 +28,8 @@ import logging ...@@ -28,8 +28,8 @@ import logging
import copy import copy
from CommsCommon import BatteryFormat from CommsCommon import BatteryFormat
# Set up logging # Set up logging
logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s') #logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s')
logging.getLogger().setLevel(logging.WARNING) #logging.getLogger().setLevel(logging.WARNING)
try: try:
import RPi.GPIO as gpio import RPi.GPIO as gpio
except ModuleNotFoundError: except ModuleNotFoundError:
......
...@@ -293,7 +293,8 @@ class PayloadFormat(): ...@@ -293,7 +293,8 @@ class PayloadFormat():
return self.payload_type if isinstance(self.payload_type, IntEnum) else PAYLOAD_TYPE(self.payload_type) return self.payload_type if isinstance(self.payload_type, IntEnum) else PAYLOAD_TYPE(self.payload_type)
def getDict(self) -> Dict: def getDict(self) -> Dict:
return {k: v.name if isinstance(v, IntEnum) or isinstance(v, Enum) else v for k, v in asdict(self).items()} return {}
#return {k: v.name if isinstance(v, IntEnum) or isinstance(v, Enum) else v for k, v in asdict(self).items()}
# ======================================= # =======================================
...@@ -375,12 +376,17 @@ class DataFormat(PayloadFormat): ...@@ -375,12 +376,17 @@ class DataFormat(PayloadFormat):
# ======================================= # =======================================
@dataclass @dataclass
class ReadbackFormat(PayloadFormat): class ReadbackFormat(PayloadFormat):
_dataStruct = Struct("<BIBHHHHHHHHHHffBBBBBBBBBBBffffffB") _dataStruct = Struct("<BIBHHHHHHHHHHHHHHHBBBBBBBBBBBBBffffffB")
payload_type: PAYLOAD_TYPE = PAYLOAD_TYPE.READBACK payload_type: PAYLOAD_TYPE = PAYLOAD_TYPE.READBACK
duration_pre_calibration: int = 0 duration_pre_calibration: int = 0
duration_calibration: int = 0 duration_calibration_first_reading: int = 0
duration_calibration_pressurise_all: int = 0
duration_calibration_pressurise_o2: int = 0
duration_calibration_pressurise_purge: int = 0
duration_calibration_pressurise_stabilise: int = 0
duration_calibration_second_reading: int = 0
duration_buff_purge: int = 0 duration_buff_purge: int = 0
duration_buff_flush: int = 0 duration_buff_flush: int = 0
duration_buff_prefill: int = 0 duration_buff_prefill: int = 0
...@@ -390,8 +396,8 @@ class ReadbackFormat(PayloadFormat): ...@@ -390,8 +396,8 @@ class ReadbackFormat(PayloadFormat):
duration_pause: int = 0 duration_pause: int = 0
duration_exhale: int = 0 duration_exhale: int = 0
valve_air_in: float = 0.0 valve_air_in: int = 0.0
valve_o2_in: float = 0.0 valve_o2_in: int = 0.0
valve_inhale: int = 0 valve_inhale: int = 0
valve_exhale: int = 0 valve_exhale: int = 0
valve_purge: int = 0 valve_purge: int = 0
...@@ -423,7 +429,12 @@ class ReadbackFormat(PayloadFormat): ...@@ -423,7 +429,12 @@ class ReadbackFormat(PayloadFormat):
self.timestamp, self.timestamp,
tmp_payload_type, tmp_payload_type,
self.duration_pre_calibration, self.duration_pre_calibration,
self.duration_calibration, self.duration_calibration_first_reading,
self.duration_calibration_pressurise_all,
self.duration_calibration_pressurise_o2,
self.duration_calibration_pressurise_purge,
self.duration_calibration_pressurise_stabilise,
self.duration_calibration_second_reading,
self.duration_buff_purge, self.duration_buff_purge,
self.duration_buff_flush, self.duration_buff_flush,
self.duration_buff_prefill, self.duration_buff_prefill,
......
...@@ -84,7 +84,7 @@ class BatteryLLI: ...@@ -84,7 +84,7 @@ class BatteryLLI:
# Get output from upower # Get output from upower
# TODO: change this to use the upower python module # TODO: change this to use the upower python module
upower_out_list = os.popen("./../upower/upower22/src/upower_22").read().split('\n') upower_out_list = os.popen("sudo ./../upower/upower_22/src/upower_22", ).read().split('\n')
upower_out_dict = {} upower_out_dict = {}
for l in upower_out_list: for l in upower_out_list:
tmp = l.split("=") tmp = l.split("=")
...@@ -151,6 +151,7 @@ class BatteryLLI: ...@@ -151,6 +151,7 @@ class BatteryLLI:
# Construct payload # Construct payload
for key in payload_dict: for key in payload_dict:
setattr(payload, key, payload_dict[key]) setattr(payload, key, payload_dict[key])
try: try:
if isHEV == True: if isHEV == True:
......
...@@ -31,7 +31,7 @@ import argparse ...@@ -31,7 +31,7 @@ import argparse
import json import json
import threading import threading
from PyQt5 import QtWidgets, QtCore from PySide2 import QtWidgets, QtCore
from pyqtgraph import PlotWidget, plot, mkColor from pyqtgraph import PlotWidget, plot, mkColor
import pyqtgraph as pg import pyqtgraph as pg
import sys import sys
...@@ -63,8 +63,16 @@ class ClientPlots(QtWidgets.QMainWindow): ...@@ -63,8 +63,16 @@ class ClientPlots(QtWidgets.QMainWindow):
# define plots here # define plots here
self.names1 = ["flow", "flow_calc"] self.names1 = ["flow", "flow_calc"]
self.names2 = ["volume"] self.names2 = ["valve_air_in", "valve_o2_in", "valve_inhale", "valve_exhale", "valve_purge"]
self.names3 = ["pressure_patient", "pressure_buffer"] self.names3 = ["pressure_patient",
"pressure_buffer",
"pressure_air_supply",
"pressure_air_regulated",
"pressure_o2_supply",
"pressure_o2_regulated",
"pressure_inhale",
"pressure_diff_patient"]
self.color3 = ["00F", "01A", "1F0", "111", "090", "251", "FF0", "F15"]
self.data1 = {name:list(0 for _ in range(self.history_length)) for name in self.names1} self.data1 = {name:list(0 for _ in range(self.history_length)) for name in self.names1}
self.data2 = {name:list(0 for _ in range(self.history_length)) for name in self.names2} self.data2 = {name:list(0 for _ in range(self.history_length)) for name in self.names2}
self.data3 = {name:list(0 for _ in range(self.history_length)) for name in self.names3} self.data3 = {name:list(0 for _ in range(self.history_length)) for name in self.names3}
...@@ -93,8 +101,8 @@ class ClientPlots(QtWidgets.QMainWindow): ...@@ -93,8 +101,8 @@ class ClientPlots(QtWidgets.QMainWindow):
self.pressurePlot.enableAutoRange('y', True) self.pressurePlot.enableAutoRange('y', True)
# Plot styles # Plot styles
self.line1 = {self.names1[idx]:self.plot(self.flowPlot , self.timestamp, self.data1[self.names1[idx]], self.names1[idx], "00F", idx) for idx in range(len(self.names1))} self.line1 = {self.names1[idx]:self.plot(self.flowPlot , self.timestamp, self.data1[self.names1[idx]], self.names1[idx], "00F", idx) for idx in range(len(self.names1))}
self.line2 = {self.names2[idx]:self.plot(self.volumePlot , self.timestamp, self.data2[self.names2[idx]], self.names2[idx], "707", idx) for idx in range(len(self.names2))} self.line2 = {self.names2[idx]:self.plot(self.volumePlot , self.timestamp, self.data2[self.names2[idx]], self.names2[idx], self.color3[idx], idx) for idx in range(len(self.names2))}
self.line3 = {self.names3[idx]:self.plot(self.pressurePlot, self.timestamp, self.data3[self.names3[idx]], self.names3[idx], "077", idx) for idx in range(len(self.names3))} self.line3 = {self.names3[idx]:self.plot(self.pressurePlot, self.timestamp, self.data3[self.names3[idx]], self.names3[idx], self.color3[idx], idx) for idx in range(len(self.names3))}
# get data in another thread # get data in another thread
self.worker = threading.Thread(target=self.polling, daemon=True) self.worker = threading.Thread(target=self.polling, daemon=True)
...@@ -146,16 +154,19 @@ class ClientPlots(QtWidgets.QMainWindow): ...@@ -146,16 +154,19 @@ class ClientPlots(QtWidgets.QMainWindow):
self.data1[name].append(payload[name]) self.data1[name].append(payload[name])
self.data1[name] = self.data1[name][1:] self.data1[name] = self.data1[name][1:]
self.line1[name].setData(self.timestamp, self.data1[name]) self.line1[name].setData(self.timestamp, self.data1[name])
for name in self.names2: #for name in self.names2:
self.data2[name].append(payload[name]) #self.data2[name].append(payload[name])
self.data2[name] = self.data2[name][1:] #self.data2[name] = self.data2[name][1:]
self.line2[name].setData(self.timestamp, self.data2[name]) #self.line2[name].setData(self.timestamp, self.data2[name])
for name in self.names3: for name in self.names3:
self.data3[name].append(payload[name]) self.data3[name].append(payload[name])
self.data3[name] = self.data3[name][1:] self.data3[name] = self.data3[name][1:]
self.line3[name].setData(self.timestamp, self.data3[name]) self.line3[name].setData(self.timestamp, self.data3[name])
elif brtype == "READBACK": elif brtype == "READBACK":
pass for name in self.names2:
self.data2[name].append(payload[name])
self.data2[name] = self.data2[name][1:]
self.line2[name].setData(self.timestamp, self.data2[name])
elif brtype == "CYCLE": elif brtype == "CYCLE":
pass pass
elif brtype == "THRESHOLDS": elif brtype == "THRESHOLDS":
......
...@@ -265,17 +265,22 @@ class BL_STATES(Enum): ...@@ -265,17 +265,22 @@ class BL_STATES(Enum):
UNKNOWN = 0 UNKNOWN = 0
IDLE = 1 IDLE = 1
PRE_CALIBRATION = 2 PRE_CALIBRATION = 2
CALIBRATION = 3 CALIBRATION_FIRST_READING = 3
BUFF_PREFILL = 4 CALIBRATION_PRESSURISE_ALL = 4
BUFF_FILL = 5 CALIBRATION_PRESSURISE_PURGE = 5
BUFF_PRE_INHALE = 6 CALIBRATION_PRESSURISE_O2 = 6
INHALE = 7 CALIBRATION_PRESSURISE_STABILISE = 7
PAUSE = 8 CALIBRATION_SECOND_READING = 8
EXHALE = 9 BUFF_PREFILL = 9
STOP = 10 BUFF_FILL = 10
BUFF_PURGE = 11 BUFF_PRE_INHALE = 11
BUFF_FLUSH = 12 INHALE = 12
STANDBY = 13 PAUSE = 13
EXHALE = 14
STOP = 15
BUFF_PURGE = 16
BUFF_FLUSH = 17
STANDBY = 18
@unique @unique
...@@ -297,6 +302,8 @@ class PAYLOAD_TYPE(IntEnum): ...@@ -297,6 +302,8 @@ class PAYLOAD_TYPE(IntEnum):
ALARM_MUTE = 14 ALARM_MUTE = 14
BAD_THRESHOLD = 15 BAD_THRESHOLD = 15
EXPERT_INFO = 16 EXPERT_INFO = 16
STARTUP = 17
RTC_TIME = 18
...@@ -323,7 +330,7 @@ class PayloadFormat: ...@@ -323,7 +330,7 @@ class PayloadFormat:
1: DataFormat, 1: DataFormat,
2: ReadbackFormat, 2: ReadbackFormat,
3: CycleFormat, 3: CycleFormat,
# 4: ThresholdFormat, #4: ThresholdFormat,
5: CommandFormat, 5: CommandFormat,
6: AlarmFormat, 6: AlarmFormat,
7: DebugFormat, 7: DebugFormat,
...@@ -335,7 +342,8 @@ class PayloadFormat: ...@@ -335,7 +342,8 @@ class PayloadFormat:
13: PersonalFormat, 13: PersonalFormat,
14: AlarmMuteFormat, 14: AlarmMuteFormat,
15: BadThresholdFormat, 15: BadThresholdFormat,
16: ExpertInfoFormat 16: ExpertInfoFormat,
17: StatusFormat
} }
ReturnType = DATA_TYPE_TO_CLASS[rec_bytes[5]] ReturnType = DATA_TYPE_TO_CLASS[rec_bytes[5]]
payload_obj = ReturnType() payload_obj = ReturnType()
...@@ -362,10 +370,11 @@ class PayloadFormat: ...@@ -362,10 +370,11 @@ class PayloadFormat:
# check for mismatch between pi and microcontroller version # check for mismatch between pi and microcontroller version
def checkVersion(self): def checkVersion(self):
if self._RPI_VERSION != self.version: #if self._RPI_VERSION != self.version:
raise HEVVersionError( #raise HEVVersionError(
"Version Mismatch", "PI:", self._RPI_VERSION, "uC:", self.version #"Version Mismatch", "PI:", self._RPI_VERSION, "uC:", self.version
) #)
pass
def getSize(self) -> int: def getSize(self) -> int:
return len(self.byteArray) return len(self.byteArray)
...@@ -390,7 +399,7 @@ class PayloadFormat: ...@@ -390,7 +399,7 @@ class PayloadFormat:
@dataclass @dataclass
class DataFormat(PayloadFormat): class DataFormat(PayloadFormat):
# subclass dataformat # subclass dataformat
_dataStruct = Struct("<BIBBHfHffffHfHHffffffffff") _dataStruct = Struct("<BIBBfffffffHfHHffffffffff")
payload_type: PAYLOAD_TYPE = PAYLOAD_TYPE.DATA payload_type: PAYLOAD_TYPE = PAYLOAD_TYPE.DATA
# subclass member variables # subclass member variables
fsm_state: BL_STATES = BL_STATES.IDLE fsm_state: BL_STATES = BL_STATES.IDLE
...@@ -515,14 +524,14 @@ class ReadbackFormat(PayloadFormat): ...@@ -515,14 +524,14 @@ class ReadbackFormat(PayloadFormat):
self.version, self.version,
self.timestamp, self.timestamp,
tmp_payload_type, tmp_payload_type,
#self.duration_pre_calibration, self.duration_pre_calibration,
self.duration_calibration_first_reading, self.duration_calibration_first_reading,
self.duration_calibration_pressurise_all, self.duration_calibration_pressurise_all,
self.duration_calibration_pressurise_o2, self.duration_calibration_pressurise_o2,
self.duration_calibration_pressurise_purge, self.duration_calibration_pressurise_purge,
self.duration_calibration_pressurise_stabilise, self.duration_calibration_pressurise_stabilise,
self.duration_calibration_second_reading, self.duration_calibration_second_reading,
self.duration_calibration, #self.duration_calibration,
self.duration_buff_purge, self.duration_buff_purge,
self.duration_buff_flush, self.duration_buff_flush,
self.duration_buff_prefill, self.duration_buff_prefill,
...@@ -902,7 +911,7 @@ class LogMsgFormat(PayloadFormat): ...@@ -902,7 +911,7 @@ class LogMsgFormat(PayloadFormat):
# ======================================= # =======================================
@dataclass @dataclass
class HEVBatteryFormat(PayloadFormat): class HEVBatteryFormat(PayloadFormat):
_dataStruct = Struct("<BIBbbbbbbb") _dataStruct = Struct("<BIBbbbbbbbbb")
payload_type: PAYLOAD_TYPE = PAYLOAD_TYPE.BATTERY payload_type: PAYLOAD_TYPE = PAYLOAD_TYPE.BATTERY
bat: int = 0 bat: int = 0
...@@ -912,6 +921,8 @@ class HEVBatteryFormat(PayloadFormat): ...@@ -912,6 +921,8 @@ class HEVBatteryFormat(PayloadFormat):
bat85: int = 0 bat85: int = 0
prob_elec: int = 0 prob_elec: int = 0
dummy: int = 0 dummy: int = 0
bat1_percent: int = 0
bat2_percent: int = 0
# fill the struct from a byteArray, # fill the struct from a byteArray,
def fromByteArray(self, byteArray): def fromByteArray(self, byteArray):
...@@ -962,8 +973,8 @@ class BatteryFormat(PayloadFormat): ...@@ -962,8 +973,8 @@ class BatteryFormat(PayloadFormat):
self.bat85, self.bat85,
self.prob_elec, self.prob_elec,
self.dummy, self.dummy,
self.bat1_percent, #self.bat1_percent,
self.bat2_percent, #self.bat2_percent,
) = self._dataStruct.unpack(byteArray) ) = self._dataStruct.unpack(byteArray)
self.checkVersion() self.checkVersion()
...@@ -1158,3 +1169,31 @@ class ExpertInfoFormat(PayloadFormat): ...@@ -1158,3 +1169,31 @@ class ExpertInfoFormat(PayloadFormat):
self.threshold_type = PAYLOAD_TYPE(tmp_payload_type) self.threshold_type = PAYLOAD_TYPE(tmp_payload_type)
#self.is_muted = #self.is_muted =
self._byteArray = byteArray self._byteArray = byteArray
# =======================================
# Startup format
# =======================================
@dataclass
class StatusFormat(PayloadFormat):
_dataStruct = Struct("<BIB?I")
payload_type: PAYLOAD_TYPE = PAYLOAD_TYPE.STARTUP
checks_succeeded: bool = False
check_flags: int = 0
# for receiving DataFormat from microcontroller
# fill the struct from a byteArray,
def fromByteArray(self, byteArray):
tmp_payload_type = 0
tmp_checks_succeeded = False
tmp_check_flags = 0
(
self.version,
self.timestamp,
tmp_payload_type,
self.checks_succeeded,
self.check_flags
) = self._dataStruct.unpack(byteArray)
self.checkVersion()
self.threshold_type = PAYLOAD_TYPE(tmp_payload_type)
self._byteArray = byteArray
...@@ -95,6 +95,7 @@ class Dependant(object): ...@@ -95,6 +95,7 @@ class Dependant(object):
#if hasattr(payload, 'duration_inhale'): #if hasattr(payload, 'duration_inhale'):
# logging.info(f"payload received: inhale duration = {payload.duration_inhale} ") # logging.info(f"payload received: inhale duration = {payload.duration_inhale} ")
self._llipacket = payload.getDict() # returns a dict self._llipacket = payload.getDict() # returns a dict
print(payload)
def send_cmd(cmd_type, cmd_code, param=0.0): def send_cmd(cmd_type, cmd_code, param=0.0):
try: try:
...@@ -168,8 +169,10 @@ try: ...@@ -168,8 +169,10 @@ try:
# create tasks # create tasks
lli = comms.main(getTTYPort(), 115200) lli = comms.main(getTTYPort(), 115200)
debug = commsDebug() #debug = commsDebug()
tasks = [lli, debug, deppoll] #tasks = [lli, debug, deppoll]
tasks = [lli, deppoll]
# run tasks # run tasks
asyncio.gather(*tasks, return_exceptions=True) asyncio.gather(*tasks, return_exceptions=True)
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
import asyncio import asyncio
import gc
import serial_asyncio import serial_asyncio
import logging import logging
import binascii import binascii
...@@ -37,8 +38,8 @@ from CommsCommon import PayloadFormat, PAYLOAD_TYPE, HEVVersionError ...@@ -37,8 +38,8 @@ from CommsCommon import PayloadFormat, PAYLOAD_TYPE, HEVVersionError
from CommsFormat import CommsPacket, CommsACK, CommsNACK, CommsChecksumError, generateAlarm, generateCmd, generateData from CommsFormat import CommsPacket, CommsACK, CommsNACK, CommsChecksumError, generateAlarm, generateCmd, generateData
# Set up logging # Set up logging
logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s') #logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s')
logging.getLogger().setLevel(logging.INFO) #logging.getLogger().setLevel(logging.INFO)
class SequenceReceiveMismatch(Exception): class SequenceReceiveMismatch(Exception):
pass pass
...@@ -93,15 +94,17 @@ class CommsLLI: ...@@ -93,15 +94,17 @@ class CommsLLI:
sendAlarm = self.send(0xC0) sendAlarm = self.send(0xC0)
sendCmd = self.send(0x80) sendCmd = self.send(0x80)
sendData = self.send(0x40) sendData = self.send(0x40)
receiver = self.recv() receiver = asyncio.create_task(self.recv())
await asyncio.gather(*[receiver, sendCmd, sendAlarm, sendData], return_exceptions=True) receiver = asyncio.ensure_future(self.recv())
#await asyncio.gather(*[receiver, sendCmd, sendAlarm, sendData], return_exceptions=True)
await asyncio.gather(*[sendCmd, sendAlarm, sendData], return_exceptions=True)
except Exception: except Exception:
raise raise
async def send(self, address): async def send(self, address):
queue = self._queues[address] queue = self._queues[address]
while self._connected: while self._connected:
logging.debug("Waiting for Command") #logging.debug("Waiting for Command")
packet = await queue.get() packet = await queue.get()
packet.setSequenceSend(self._sequence_send) packet.setSequenceSend(self._sequence_send)
for send_attempt in range(10): for send_attempt in range(10):
...@@ -168,7 +171,7 @@ class CommsLLI: ...@@ -168,7 +171,7 @@ class CommsLLI:
queue.task_done() queue.task_done()
queue.put_nowait(tmp_comms) queue.put_nowait(tmp_comms)
except Exception as e: except Exception as e:
logging.error(e) #logging.error(e)
return False return False
else: else:
return True return True
...@@ -176,13 +179,16 @@ class CommsLLI: ...@@ -176,13 +179,16 @@ class CommsLLI:
async def sendPacket(self, packet): async def sendPacket(self, packet):
if isinstance(packet, CommsACK): if isinstance(packet, CommsACK):
# don't log acks # don't log acks
logging.debug(f"Sending ACK: {binascii.hexlify(packet.encode())}") #logging.debug(f"Sending ACK: {binascii.hexlify(packet.encode())}")
pass pass
elif isinstance(packet, CommsNACK): elif isinstance(packet, CommsNACK):
# logging.debug(f"Sending NACK: {binascii.hexlify(packet.encode())}") # logging.debug(f"Sending NACK: {binascii.hexlify(packet.encode())}")
pass pass
else: else:
logging.info(f"Sending {binascii.hexlify(packet.encode())}") logging.info(f"Sending {binascii.hexlify(packet.encode())}")
#count_tasks = len(asyncio.all_tasks())
#print("O numero de tarefas atualmente eh", count_tasks)
#print(asyncio.all_tasks())
self._writer.write(packet.encode()) self._writer.write(packet.encode())
async def readPacket(self): async def readPacket(self):
...@@ -206,16 +212,16 @@ class CommsLLI: ...@@ -206,16 +212,16 @@ class CommsLLI:
pass pass
else: else:
self._acklist[address].set() self._acklist[address].set()
def resetReceiver(self, sequence_receive = -1): def resetReceiver(self, sequence_receive = -1):
self._mismatch_counter = 0 self._mismatch_counter = 0
if sequence_receive >= 0: if sequence_receive >= 0:
self._sequence_receive = sequence_receive self._sequence_receive = sequence_receive
def trackMismatch(self, sequence_receive): def trackMismatch(self, sequence_receive):
if self._mismatch_counter > 20 : if self._mismatch_counter > 20 :
self.resetReceiver(sequence_receive) self.resetReceiver(sequence_receive)
logging.warning(f"Received more than 20 sequence_receive mismatches, resetting") #logging.warning(f"Received more than 20 sequence_receive mismatches, resetting")
else: else:
self._mismatch_counter += 1 self._mismatch_counter += 1
...@@ -226,43 +232,44 @@ class CommsLLI: ...@@ -226,43 +232,44 @@ class CommsLLI:
data = packet.decode() data = packet.decode()
except CommsChecksumError: except CommsChecksumError:
# checksum failed! wait for it to be resent # checksum failed! wait for it to be resent
logging.warning(f"Packet did not match checksum: {packet._data}") #logging.warning(f"Packet did not match checksum: {packet._data}")
continue continue
if data is None: if data is None:
# packet is an ack/nack from previously sent data # packet is an ack/nack from previously sent data
if packet.acked: if packet.acked:
logging.info("Received ACK") #logging.info("Received ACK")
# increase packet counter # increase packet counter
self.finishPacket(packet.address, packet.sequence_receive) self.finishPacket(packet.address, packet.sequence_receive)
else: else:
logging.info("Received NACK") #logging.info("Received NACK")
pass
else: else:
# packet should contain valid data # packet should contain valid data
try: try:
payload = PayloadFormat.fromByteArray(packet.byteArray) payload = PayloadFormat.fromByteArray(packet.byteArray)
print(payload)
self.sequence_receive = packet.sequence_send self.sequence_receive = packet.sequence_send
self.resetReceiver() rst = self.resetReceiver()
self.payloadrecv = payload self.payloadrecv = payload
# logging.debug(f"Received payload type {payload.getType()} for timestamp {payload.timestamp}") # logging.debug(f"Received payload type {payload.getType()} for timestamp {payload.timestamp}")
comms_response = CommsACK(packet.address) comms_response = CommsACK(packet.address)
except StructError as e: except StructError as e:
# invalid payload, but valid checksum - this is bad! # invalid payload, but valid checksum - this is bad!
logging.error(f"Invalid payload: {payload} {e}") #logging.error(f"Invalid payload: {payload} {e}")
# restart/reflash/swap to redundant microcontroller? # restart/reflash/swap to redundant microcontroller?
comms_response = CommsNACK(packet.address) comms_response = CommsNACK(packet.address)
except (ValueError): except (ValueError):
# invalid payload, but valid checksum - this is bad! # invalid payload, but valid checksum - this is bad!
logging.error(f"Invalid payload (Value Error): {payload}") #logging.error(f"Invalid payload (Value Error): {payload} {e}")
# restart/reflash/swap to redundant microcontroller? # restart/reflash/swap to redundant microcontroller?
comms_response = CommsNACK(packet.address) comms_response = CommsNACK(packet.address)
except SequenceReceiveMismatch: except SequenceReceiveMismatch:
# logging.debug(f"Mismatch sequence receive, expected: {self.sequence_receive}; received: {packet.sequence_send}") # logging.debug(f"Mismatch sequence receive, expected: {self.sequence_receive}; received: {packet.sequence_send}")
comms_response = CommsNACK(packet.address) comms_response = CommsNACK(packet.address)
self.trackMismatch(packet.sequence_send) self.trackMismatch(packet.sequence_send)
except HEVVersionError as e: except HEVVersionError as e:
logging.critical(f"HEVVersionError: {e}") #logging.critical(f"HEVVersionError: {e}")
exit(1) exit(1)
finally: finally:
comms_response.setSequenceReceive(self.sequence_receive) comms_response.setSequenceReceive(self.sequence_receive)
...@@ -271,14 +278,14 @@ class CommsLLI: ...@@ -271,14 +278,14 @@ class CommsLLI:
@property @property
def sequence_receive(self): def sequence_receive(self):
return self._sequence_receive return self._sequence_receive
@sequence_receive.setter @sequence_receive.setter
def sequence_receive(self, sequence): def sequence_receive(self, sequence):
if self._sequence_receive == sequence: if self._sequence_receive == sequence:
self._sequence_receive = (self._sequence_receive + 1) % 128 self._sequence_receive = (self._sequence_receive + 1) % 128
else: else:
raise SequenceReceiveMismatch raise SequenceReceiveMismatch
@property @property
def payloadrecv(self): def payloadrecv(self):
return self._payloadrecv return self._payloadrecv
...@@ -296,9 +303,9 @@ class CommsLLI: ...@@ -296,9 +303,9 @@ class CommsLLI:
# dump the payload in a dict which can be unpacked directly into a payloadFormat object # dump the payload in a dict which can be unpacked directly into a payloadFormat object
f.write(f"{binascii.hexlify(payload.byteArray)}\n") f.write(f"{binascii.hexlify(payload.byteArray)}\n")
if self._packet_count >= self._dumpcount: if self._packet_count >= self._dumpcount:
logging.critical(f"Dump count reached. {self._packet_count} packets dumped to file {self._dumpfile}") #logging.critical(f"Dump count reached. {self._packet_count} packets dumped to file {self._dumpfile}")
exit(0) exit(0)
if __name__ == "__main__": if __name__ == "__main__":
try: try:
...@@ -313,9 +320,9 @@ if __name__ == "__main__": ...@@ -313,9 +320,9 @@ if __name__ == "__main__":
# setup serial devices # setup serial devices
if args.dump: if args.dump:
if args.file == '': if args.file == '':
logging.critical("No dump file specified") #logging.critical("No dump file specified")
raise KeyboardInterrupt # fake ctrl+c raise KeyboardInterrupt # fake ctrl+c
logging.warning(f"Dumping {args.number} packets to {args.file}") #logging.warning(f"Dumping {args.number} packets to {args.file}")
comms = CommsLLI(loop, file=args.file, number=args.number) comms = CommsLLI(loop, file=args.file, number=args.number)
else: else:
comms = CommsLLI(loop) comms = CommsLLI(loop)
...@@ -325,7 +332,8 @@ if __name__ == "__main__": ...@@ -325,7 +332,8 @@ if __name__ == "__main__":
except asyncio.CancelledError: except asyncio.CancelledError:
pass pass
except KeyboardInterrupt: except KeyboardInterrupt:
logging.info("Closing LLI") #logging.info("Closing LLI")
pass
finally: finally:
try: try:
loop.close() loop.close()
......
...@@ -64,7 +64,7 @@ class HEVClient(object): ...@@ -64,7 +64,7 @@ class HEVClient(object):
self._alarm_mute = None # db for alarm mute state self._alarm_mute = None # db for alarm mute state
self._bad_threshold = None # db for bad threshold warnings self._bad_threshold = None # db for bad threshold warnings
self._thresholds = [] # db for threshold settings self._thresholds = [] # db for threshold settings
self._polling = polling # keep reading data into db self._polling = True #polling # keep reading data into db
self._lock = threading.Lock() # lock for the database self._lock = threading.Lock() # lock for the database
self._mmFile = None self._mmFile = None
...@@ -207,6 +207,7 @@ class HEVClient(object): ...@@ -207,6 +207,7 @@ class HEVClient(object):
raise HEVPacketError("Invalid packet type") raise HEVPacketError("Invalid packet type")
logging.info(payload) logging.info(payload)
print(payload)
packet = json.dumps(payload).encode() + b"\0" packet = json.dumps(payload).encode() + b"\0"
writer.write(packet) writer.write(packet)
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment