Index: dialin/ui/hd_simulator_alarms.py =================================================================== diff -u -rbfb0c47181dc8a73d09825ab697a7799dd520417 -rb20262631dc86edf5c3550762bc888089fa2626d --- dialin/ui/hd_simulator_alarms.py (.../hd_simulator_alarms.py) (revision bfb0c47181dc8a73d09825ab697a7799dd520417) +++ dialin/ui/hd_simulator_alarms.py (.../hd_simulator_alarms.py) (revision b20262631dc86edf5c3550762bc888089fa2626d) @@ -128,19 +128,7 @@ self.can_interface.register_receiving_publication_function(DenaliChannels.ui_to_hd_ch_id, MsgIds.MSG_ID_UI_SET_ALARM_AUDIO_VOLUME_LEVEL_CMD.value, self._handler_request_override_alarm_volume) - self._start_broadcasts() - def _start_broadcasts(self): - """ - Starts broadcasting data messages - @return: None - """ - - # while True: - # self._send_alarm_volume_broadcast() - # sleep(1) - pass - def _send_alarm_volume_broadcast(self): """ Sends the alarm volume broadcast message Index: dialin/utils/__init__.py =================================================================== diff -u -rbfb0c47181dc8a73d09825ab697a7799dd520417 -rb20262631dc86edf5c3550762bc888089fa2626d --- dialin/utils/__init__.py (.../__init__.py) (revision bfb0c47181dc8a73d09825ab697a7799dd520417) +++ dialin/utils/__init__.py (.../__init__.py) (revision b20262631dc86edf5c3550762bc888089fa2626d) @@ -3,5 +3,6 @@ from .conversions import * from .excel_ops import * from .nv_ops_utils import * +from .data_logger import DataLogger YES = 1 NO = 0 \ No newline at end of file Index: dialin/utils/data_logger.py =================================================================== diff -u --- dialin/utils/data_logger.py (revision 0) +++ dialin/utils/data_logger.py (revision b20262631dc86edf5c3550762bc888089fa2626d) @@ -0,0 +1,118 @@ +import glob +import os +import shutil +import threading +from collections import deque +from logging import Logger +from time import sleep +from typing import Tuple + +import pandas as pd + +from dialin.utils.base import _FauxLogger + + +class DataLogger: + + MAX_CHUNK_SIZE = 20 + + def __init__(self, + folder: str = "/tmp/", # must be the full path + logger: Logger = _FauxLogger()): + """ + Logs data to xlsx file + :param filepath: (str) the destination filepath + + """ + super().__init__() + self.queue = deque() # Thread safe + self.thread = threading.Thread(target=self.logging_scheduler, daemon=True) + self.base_folder = folder + self.csv_writers = {} + self.logger = logger + self.thread.start() + + def logging_scheduler(self) -> None: + """ + Called on each timer event. Calls the data logger method + :param event: + :return: + """ + while True: + self.do_data_logging() + sleep(0.05) + + def add_data(self, data: Tuple): + """ + + :param data: (Tuple) the data to add to the queue + :return: None + """ + # ("module", "timestamp", "header", "value") + self.queue.append(data) + + def do_data_logging(self) -> None: + """ + Called on teach timer event. Logs the data currently in deque + :return: None + """ + + i = 0 + while self.queue: + module, timestamp, data_name, data_value = self.queue.pop() + filename = module + folder = os.path.join(self.base_folder, filename + "Log") + if not os.path.isdir(folder): + os.mkdir(folder) + filepath = os.path.join(folder, data_name + ".csv") + + if not os.path.exists(filepath): + header = ["timestamp", data_name] + with open(filepath, 'w') as f: + f.write(",".join(header) + "\n") + else: + with open(filepath, 'a') as f: + f.write(timestamp + ", " + data_value + "\n") + + i += 1 + if i >= self.MAX_CHUNK_SIZE: + break + + def export_to_xlsx(self, output_path: str): + """ + Called when the user wishes to export all captured logs to a xlsx file + + :param output_path: (str) the destination output path + :return: None + """ + log_path = os.path.join(self.base_folder, "*Log") + folders = glob.glob(log_path) + if len(folders) == 0: + self.logger.debug("No folder with data to export") + return + writer = pd.ExcelWriter(output_path) + for folder in folders: + files = os.path.join(folder, "*.csv") + csv_files = glob.glob(files) + module_name = os.path.basename(folder) + df = pd.DataFrame() + for csv_file in csv_files: + df_data = pd.read_csv(csv_file) + df_data = df_data.set_index("timestamp") + df = df.join(df_data, how="outer") + df.to_excel(writer, sheet_name=module_name) + self.logger.debug("Added {0} to {1}".format(module_name, output_path)) + writer.save() + self.logger.debug("Finished data export to {0}".format(output_path)) + + def clear_logs(self): + """ + Called when the user clears the logs + :return: None + """ + log_path = os.path.join(self.base_folder, "*Log") + folders = glob.glob(log_path) + for folder in folders: + self.logger.debug("Removing {0}".format(folder)) + shutil.rmtree(folder) + Index: tests/peter/test_dg_thermistors.py =================================================================== diff -u --- tests/peter/test_dg_thermistors.py (revision 0) +++ tests/peter/test_dg_thermistors.py (revision b20262631dc86edf5c3550762bc888089fa2626d) @@ -0,0 +1,47 @@ +########################################################################### +# +# 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 test_alarms.py +# +# @author (last) Peter Lucia +# @date (last) 02-Feb-2020 +# @author (original) Peter Lucia +# @date (original) 02-Feb-2020 +# +############################################################################ +import numpy as np +import sys +from time import sleep +sys.path.append("..") +from dialin import DGSimulator +from dialin.protocols.CAN import DenaliMessage, DenaliChannels +from dialin.common import MsgIds +from dialin.utils.conversions import integer_to_bytearray, float_to_bytearray + + +def run(): + dg_sim = DGSimulator(log_level="DEBUG") + + while True: + onboard_temp = np.random.randint(0, 65535) + power_supply_1 = np.random.randint(0, 65535) + power_supply_2 = np.random.randint(0, 65535) + + payload = float_to_bytearray(onboard_temp) + payload += float_to_bytearray(power_supply_1) + payload += float_to_bytearray(power_supply_2) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dg_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_DG_THERMISTORS_DATA.value, + payload=payload) + + dg_sim.can_interface.send(message, 0) + sleep(1) + + +if __name__ == '__main__': + run() Index: tests/peter/test_dg_valves.py =================================================================== diff -u --- tests/peter/test_dg_valves.py (revision 0) +++ tests/peter/test_dg_valves.py (revision b20262631dc86edf5c3550762bc888089fa2626d) @@ -0,0 +1,43 @@ +########################################################################### +# +# 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 test_alarms.py +# +# @author (last) Peter Lucia +# @date (last) 02-Feb-2020 +# @author (original) Peter Lucia +# @date (original) 02-Feb-2020 +# +############################################################################ +import numpy as np +import sys +from time import sleep +sys.path.append("..") +from dialin import DGSimulator +from dialin.protocols.CAN import DenaliMessage, DenaliChannels +from dialin.common import MsgIds +from dialin.utils.conversions import integer_to_bytearray, float_to_bytearray + + +def run(): + dg_sim = DGSimulator(log_level="DEBUG") + + while True: + vlv_states = np.random.randint(0, 65535) + + payload = integer_to_bytearray(vlv_states) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.dg_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_DG_VALVES_STATES.value, + payload=payload) + + dg_sim.can_interface.send(message, 0) + sleep(1) + + +if __name__ == '__main__': + run() Index: tests/peter/test_hd_valves.py =================================================================== diff -u --- tests/peter/test_hd_valves.py (revision 0) +++ tests/peter/test_hd_valves.py (revision b20262631dc86edf5c3550762bc888089fa2626d) @@ -0,0 +1,63 @@ +########################################################################### +# +# 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 test_alarms.py +# +# @author (last) Peter Lucia +# @date (last) 02-Feb-2020 +# @author (original) Peter Lucia +# @date (original) 02-Feb-2020 +# +############################################################################ +import numpy as np +import sys +from time import sleep +sys.path.append("..") +from dialin import HDSimulator +from dialin.protocols.CAN import DenaliMessage, DenaliChannels +from dialin.common import MsgIds +from dialin.utils.conversions import integer_to_bytearray, float_to_bytearray + + +def run(): + hd_sim = HDSimulator(log_level="DEBUG") + + while True: + vlv_id = np.random.randint(0, 5) + state_id = np.random.randint(0, 1) + pos_id = np.random.randint(0, 1) + pos_cnt = np.random.randint(0, 1) + next_pos = np.random.randint(0, 1) + current = np.random.uniform(0, 250) + pos_c = np.random.randint(0, 100) + pos_a = np.random.randint(0, 100) + pos_b = np.random.randint(0, 100) + pwm = np.random.randint(0, 100) + air_trap = np.random.randint(0, 100) + + payload = integer_to_bytearray(vlv_id) + payload += integer_to_bytearray(state_id) + payload += integer_to_bytearray(pos_id) + payload += integer_to_bytearray(pos_cnt) + payload += integer_to_bytearray(next_pos) + payload += float_to_bytearray(current) + payload += integer_to_bytearray(pos_c) + payload += integer_to_bytearray(pos_a) + payload += integer_to_bytearray(pos_b) + payload += integer_to_bytearray(pwm) + payload += integer_to_bytearray(air_trap) + + message = DenaliMessage.build_message(channel_id=DenaliChannels.hd_sync_broadcast_ch_id, + message_id=MsgIds.MSG_ID_HD_VALVES_DATA.value, + payload=payload) + + hd_sim.can_interface.send(message, 0) + sleep(1) + + +if __name__ == '__main__': + run() Fisheye: Tag b20262631dc86edf5c3550762bc888089fa2626d refers to a dead (removed) revision in file `tests/peter/test_valves.py'. Fisheye: No comparison available. Pass `N' to diff?