diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 100f4ed..7221472 --- a/README.md +++ b/README.md @@ -1 +1,82 @@ -# SpikesLogger \ No newline at end of file +## Warnings! +- ### [python sucks](https://gitlab.com/TzintzeneT/dont-use-python), do not use python at home. +- ### Windows "defender" sucks, you can see that this app is no virus, it is open source. +# SpikesLogger +![SpikesLogger screenshot](images/Screenshot1.png "Awesome app") + +Welcome to the official SpikesLogger repo! +this app is the desktop part of the SpikesLogger real-time FRC logger. +The SpikesLogger uses the NetworkTables server on the roboRIO to log values from the robot to your computer. + +You can download the latest release from [here](https://github.com/Spikes-2212-Programming-Guild/SpikesLogger/releases), or build it yourself with the [commands below](#build-commands). +the SpikesLogger is designed to replace the System.out.println() statement you use every time you want to log some value when you run your code. +it is meant to be used for debugging but feel free to use it as you want. + +# Logging Values +1. _FIRST_, from your computer connect to your robot's network, then set the "server IP" in the app settings to your roborio's IP. +2. _SECOND_, as explained below, to log the values from your robot, you can use a couple of methods. + +**note:** make sure to not log the temp value in the app settings, otherwise it will not be logged. +if for some odd reason you want to log "SeaOttersAreSoFuckingCuteINeedThemInMyRoomRightNow", +you can change it to a different value. + +### Using SpikesLib2 +you can [install SpikesLib2](https://github.com/Spikes-2212-Programming-Guild/SpikesLib2#installation) +and use the built-in SpikesLogger using +``` +SpikesLogger sl = new SpikesLogger(); +``` +you can use the regular log function with: +``` +sl.log(value); +``` + +and you can use the log command (which will return a command): +``` +sl.logCommand(value); +``` +There are also the `logWithTimestamp` and `logWithTimestampCommand` +to log your values with a timestamp. + +### Using the NetworkTables Directly +Although not recommended, you can put the values that you want to log at a certain location in the NetworkTables, for example: SpikesLogger/output. +After that, you need to put that NetworkTables location at the "Logger Location" in the app settings and hit apply. + +**make sure** to not update the value periodically unless you want to log that same value periodically. + +this method is not recommended because you can accidentally put the value in the wrong place, +or do other stupid things you won't notice and will drive you insane. + + +### Creating Your Own Robot Logger +You can create your own robot logger in your preferred language (Java/C++/Python) to use with this desktop app. +You can take a look at the [SpikesLogger class](https://github.com/Spikes-2212-Programming-Guild/SpikesLib2/blob/dev/src/main/java/com/spikes2212/dashboard/SpikesLogger.java) +in SpikesLib2 for inspiration or just create one from scratch. +To do that, you'll need to make sure you are putting all of the values at the same location at the NetworkTables, +and you also need to put the "Logger Location" in the desktop app settings as that NetworkTables location. + + +# Build Commands: +### for linux: +```commandline + pyinstaller --onefile --add-data "SpikesLoggerSmallLogo.png:." SpikesLogger.py +``` +### for windows and mac: +```commandline + pyinstaller --onefile --windowed --icon=SpikesLoggerIcon.ico --add-data "SpikesLoggerSmallLogo.png:." SpikesLogger.py +``` + +## convert the .ui GUI file to Python +```commandline +pyuic6 LoggerGUI.ui -o LoggerGUI.py +``` + +## created using pain and FOSS +This app is licensed under the awesome GPLv3 licence, and written in Python (unfortunately). + +### other projects making this app possible: +- QT (PyQt6, Qt Designer) +- RobotPy (PyNetworkTables) +- pyinstaller (Compiling this) +- GIMP (logo design) +- PyCharm (because VSCode is broken and PyCharm is awesome unlike python) \ No newline at end of file diff --git a/images/Screenshot1.png b/images/Screenshot1.png new file mode 100644 index 0000000..bd60aac Binary files /dev/null and b/images/Screenshot1.png differ diff --git a/images/SpikesLoggerLogo.png b/images/SpikesLoggerLogo.png new file mode 100755 index 0000000..7d4b013 Binary files /dev/null and b/images/SpikesLoggerLogo.png differ diff --git a/images/SpikesLoggerLogo.xcf b/images/SpikesLoggerLogo.xcf new file mode 100755 index 0000000..60e9929 Binary files /dev/null and b/images/SpikesLoggerLogo.xcf differ diff --git a/src/EditConfig.py b/src/EditConfig.py new file mode 100755 index 0000000..980fff1 --- /dev/null +++ b/src/EditConfig.py @@ -0,0 +1,27 @@ +import json + + +def applyChanges(ip, save_location, logger_nt_location, temp_value): + conf_data = { + "logger-nt-location": logger_nt_location, + "save-location": save_location, + "serverip": ip, + "temp-value": temp_value + } + with open('../SpikesLog.conf', 'w') as file: + json.dump(conf_data, file) + print('config file saved') + + +def getData(): + try: + with open('../SpikesLog.conf', 'r') as json_file: + conf_data = json.load(json_file) + except: + conf_data = { + "logger-nt-location": "SpikesLogger/output", + "save-location": "logs", + "serverip": "255.255.255.255", + "temp-value": "SeaOttersAreSoFuckingCuteINeedThemInMyRoomRightNow" # Thanks to Mr. Borito our beloved alumn who went to FIRST service year + } + return conf_data diff --git a/src/LoggerGUI.py b/src/LoggerGUI.py new file mode 100755 index 0000000..185f3c0 --- /dev/null +++ b/src/LoggerGUI.py @@ -0,0 +1,196 @@ +# Form implementation generated from reading ui file 'LoggerGUI.ui' +# +# Created by: PyQt6 UI code generator 6.4.2 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + + +class Ui_SpikesLoggerGuiWindow(object): + def setupUi(self, SpikesLoggerGuiWindow): + SpikesLoggerGuiWindow.setObjectName("SpikesLoggerGuiWindow") + SpikesLoggerGuiWindow.resize(844, 719) + self.centralwidget = QtWidgets.QWidget(parent=SpikesLoggerGuiWindow) + self.centralwidget.setObjectName("centralwidget") + self.gridLayout = QtWidgets.QGridLayout(self.centralwidget) + self.gridLayout.setObjectName("gridLayout") + self.tabWidget = QtWidgets.QTabWidget(parent=self.centralwidget) + self.tabWidget.setObjectName("tabWidget") + self.logsTab = QtWidgets.QWidget() + self.logsTab.setObjectName("logsTab") + self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.logsTab) + self.horizontalLayout_3.setObjectName("horizontalLayout_3") + self.scrollArea = QtWidgets.QScrollArea(parent=self.logsTab) + self.scrollArea.setMaximumSize(QtCore.QSize(16777215, 16777215)) + self.scrollArea.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustIgnored) + self.scrollArea.setWidgetResizable(True) + self.scrollArea.setAlignment(QtCore.Qt.AlignmentFlag.AlignBottom|QtCore.Qt.AlignmentFlag.AlignJustify) + self.scrollArea.setObjectName("scrollArea") + self.ConsoleScrollArea = QtWidgets.QWidget() + self.ConsoleScrollArea.setGeometry(QtCore.QRect(0, 0, 802, 538)) + self.ConsoleScrollArea.setObjectName("ConsoleScrollArea") + self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.ConsoleScrollArea) + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.logsConsole = QtWidgets.QLabel(parent=self.ConsoleScrollArea) + self.logsConsole.setAlignment(QtCore.Qt.AlignmentFlag.AlignLeading|QtCore.Qt.AlignmentFlag.AlignLeft|QtCore.Qt.AlignmentFlag.AlignTop) + self.logsConsole.setObjectName("logsConsole") + self.horizontalLayout_2.addWidget(self.logsConsole) + self.scrollArea.setWidget(self.ConsoleScrollArea) + self.horizontalLayout_3.addWidget(self.scrollArea) + self.tabWidget.addTab(self.logsTab, "") + self.settingsTab = QtWidgets.QWidget() + self.settingsTab.setObjectName("settingsTab") + self.verticalLayout = QtWidgets.QVBoxLayout(self.settingsTab) + self.verticalLayout.setSizeConstraint(QtWidgets.QLayout.SizeConstraint.SetDefaultConstraint) + self.verticalLayout.setObjectName("verticalLayout") + self.gridLayout_2 = QtWidgets.QGridLayout() + self.gridLayout_2.setObjectName("gridLayout_2") + self.TempValue = QtWidgets.QLineEdit(parent=self.settingsTab) + self.TempValue.setObjectName("TempValue") + self.gridLayout_2.addWidget(self.TempValue, 3, 2, 1, 1) + self.ServerIP = QtWidgets.QLineEdit(parent=self.settingsTab) + self.ServerIP.setObjectName("ServerIP") + self.gridLayout_2.addWidget(self.ServerIP, 2, 2, 1, 1) + self.label_3 = QtWidgets.QLabel(parent=self.settingsTab) + self.label_3.setObjectName("label_3") + self.gridLayout_2.addWidget(self.label_3, 1, 0, 1, 1) + self.label_4 = QtWidgets.QLabel(parent=self.settingsTab) + self.label_4.setObjectName("label_4") + self.gridLayout_2.addWidget(self.label_4, 2, 0, 1, 1) + self.networkTablesLoggerLocation = QtWidgets.QLineEdit(parent=self.settingsTab) + self.networkTablesLoggerLocation.setInputMask("") + self.networkTablesLoggerLocation.setObjectName("networkTablesLoggerLocation") + self.gridLayout_2.addWidget(self.networkTablesLoggerLocation, 0, 2, 1, 1) + self.label_5 = QtWidgets.QLabel(parent=self.settingsTab) + self.label_5.setObjectName("label_5") + self.gridLayout_2.addWidget(self.label_5, 3, 0, 1, 1) + self.label_2 = QtWidgets.QLabel(parent=self.settingsTab) + self.label_2.setObjectName("label_2") + self.gridLayout_2.addWidget(self.label_2, 0, 0, 1, 1) + self.ChooseDirPushButton = QtWidgets.QPushButton(parent=self.settingsTab) + font = QtGui.QFont() + font.setBold(False) + self.ChooseDirPushButton.setFont(font) + self.ChooseDirPushButton.setCursor(QtGui.QCursor(QtCore.Qt.CursorShape.ArrowCursor)) + self.ChooseDirPushButton.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight) + self.ChooseDirPushButton.setObjectName("ChooseDirPushButton") + self.gridLayout_2.addWidget(self.ChooseDirPushButton, 1, 2, 1, 1) + self.verticalLayout.addLayout(self.gridLayout_2) + self.applyChangesPushButton = QtWidgets.QPushButton(parent=self.settingsTab) + self.applyChangesPushButton.setObjectName("applyChangesPushButton") + self.verticalLayout.addWidget(self.applyChangesPushButton) + self.label_8 = QtWidgets.QLabel(parent=self.settingsTab) + self.label_8.setText("") + self.label_8.setObjectName("label_8") + self.verticalLayout.addWidget(self.label_8) + self.label_6 = QtWidgets.QLabel(parent=self.settingsTab) + font = QtGui.QFont() + font.setPointSize(20) + self.label_6.setFont(font) + self.label_6.setObjectName("label_6") + self.verticalLayout.addWidget(self.label_6) + self.label_7 = QtWidgets.QLabel(parent=self.settingsTab) + self.label_7.setWordWrap(True) + self.label_7.setObjectName("label_7") + self.verticalLayout.addWidget(self.label_7) + spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.verticalLayout.addItem(spacerItem) + self.tabWidget.addTab(self.settingsTab, "") + self.gridLayout.addWidget(self.tabWidget, 9, 0, 1, 2) + self.horizontalLayout = QtWidgets.QHBoxLayout() + self.horizontalLayout.setObjectName("horizontalLayout") + self.StartPushButton = QtWidgets.QPushButton(parent=self.centralwidget) + self.StartPushButton.setObjectName("StartPushButton") + self.horizontalLayout.addWidget(self.StartPushButton) + self.PausePushButton = QtWidgets.QPushButton(parent=self.centralwidget) + self.PausePushButton.setObjectName("PausePushButton") + self.horizontalLayout.addWidget(self.PausePushButton) + self.SaveAndStopPushButton = QtWidgets.QPushButton(parent=self.centralwidget) + self.SaveAndStopPushButton.setAutoDefault(False) + self.SaveAndStopPushButton.setObjectName("SaveAndStopPushButton") + self.horizontalLayout.addWidget(self.SaveAndStopPushButton) + self.gridLayout.addLayout(self.horizontalLayout, 11, 0, 1, 2) + self.horizontalLayout_4 = QtWidgets.QHBoxLayout() + self.horizontalLayout_4.setObjectName("horizontalLayout_4") + spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout_4.addItem(spacerItem1) + self.label = QtWidgets.QLabel(parent=self.centralwidget) + font = QtGui.QFont() + font.setPointSize(14) + self.label.setFont(font) + self.label.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight|QtCore.Qt.AlignmentFlag.AlignTrailing|QtCore.Qt.AlignmentFlag.AlignVCenter) + self.label.setObjectName("label") + self.horizontalLayout_4.addWidget(self.label) + self.StatusLabel = QtWidgets.QLabel(parent=self.centralwidget) + font = QtGui.QFont() + font.setPointSize(14) + self.StatusLabel.setFont(font) + self.StatusLabel.setObjectName("StatusLabel") + self.horizontalLayout_4.addWidget(self.StatusLabel) + self.gridLayout.addLayout(self.horizontalLayout_4, 0, 1, 1, 1) + SpikesLoggerGuiWindow.setCentralWidget(self.centralwidget) + self.menubar = QtWidgets.QMenuBar(parent=SpikesLoggerGuiWindow) + self.menubar.setGeometry(QtCore.QRect(0, 0, 844, 23)) + self.menubar.setObjectName("menubar") + self.menuSpikesLogger = QtWidgets.QMenu(parent=self.menubar) + self.menuSpikesLogger.setObjectName("menuSpikesLogger") + self.menuHelp = QtWidgets.QMenu(parent=self.menubar) + self.menuHelp.setObjectName("menuHelp") + SpikesLoggerGuiWindow.setMenuBar(self.menubar) + self.statusbar = QtWidgets.QStatusBar(parent=SpikesLoggerGuiWindow) + self.statusbar.setObjectName("statusbar") + SpikesLoggerGuiWindow.setStatusBar(self.statusbar) + self.actionOpen_file = QtGui.QAction(parent=SpikesLoggerGuiWindow) + self.actionOpen_file.setObjectName("actionOpen_file") + self.actionCreate_new_log = QtGui.QAction(parent=SpikesLoggerGuiWindow) + self.actionCreate_new_log.setObjectName("actionCreate_new_log") + self.actionAbout = QtGui.QAction(parent=SpikesLoggerGuiWindow) + self.actionAbout.setObjectName("actionAbout") + self.actionUpdate = QtGui.QAction(parent=SpikesLoggerGuiWindow) + self.actionUpdate.setObjectName("actionUpdate") + self.actionSource_code = QtGui.QAction(parent=SpikesLoggerGuiWindow) + self.actionSource_code.setObjectName("actionSource_code") + self.menuSpikesLogger.addAction(self.actionUpdate) + self.menuSpikesLogger.addSeparator() + self.menuSpikesLogger.addAction(self.actionSource_code) + self.menuSpikesLogger.addSeparator() + self.menuHelp.addAction(self.actionAbout) + self.menubar.addAction(self.menuSpikesLogger.menuAction()) + self.menubar.addAction(self.menuHelp.menuAction()) + + self.retranslateUi(SpikesLoggerGuiWindow) + self.tabWidget.setCurrentIndex(0) + QtCore.QMetaObject.connectSlotsByName(SpikesLoggerGuiWindow) + + def retranslateUi(self, SpikesLoggerGuiWindow): + _translate = QtCore.QCoreApplication.translate + SpikesLoggerGuiWindow.setWindowTitle(_translate("SpikesLoggerGuiWindow", "Spikes logger")) + self.logsConsole.setText(_translate("SpikesLoggerGuiWindow", "Click start to start logging...")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.logsTab), _translate("SpikesLoggerGuiWindow", "Logs")) + self.TempValue.setText(_translate("SpikesLoggerGuiWindow", "SeaOttersAreSoFuckingCuteINeedThemInMyRoomRightNow")) + self.ServerIP.setText(_translate("SpikesLoggerGuiWindow", "255.255.255.255")) + self.label_3.setText(_translate("SpikesLoggerGuiWindow", "Logs save location")) + self.label_4.setText(_translate("SpikesLoggerGuiWindow", "Server IP")) + self.networkTablesLoggerLocation.setText(_translate("SpikesLoggerGuiWindow", "SpikesLogger/output")) + self.label_5.setText(_translate("SpikesLoggerGuiWindow", "Temp value")) + self.label_2.setText(_translate("SpikesLoggerGuiWindow", "Logger location")) + self.ChooseDirPushButton.setText(_translate("SpikesLoggerGuiWindow", "/logs")) + self.applyChangesPushButton.setText(_translate("SpikesLoggerGuiWindow", "Apply")) + self.label_6.setText(_translate("SpikesLoggerGuiWindow", "How to use?")) + self.label_7.setText(_translate("SpikesLoggerGuiWindow", "

FIRST, make sure you are using a compatible logger on your robot (for example: SpikesLogger from SpikesLib). You can also put the value you want to log at the same location in the networktables as the Logger location in the settings above, although it is not recommended, and you need to make sure to not update the value periodically unless you want to log that same value periodically.

Enter your roborio IP and choose the location to save the logs to. after that you can start logging by pressing start, pause and save logs. You can change the temp value but make sure to set it to a value that is not likely to be logged.

To save the settings you can use the apply button.

")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.settingsTab), _translate("SpikesLoggerGuiWindow", "Settings")) + self.StartPushButton.setText(_translate("SpikesLoggerGuiWindow", "Start")) + self.PausePushButton.setText(_translate("SpikesLoggerGuiWindow", "Pause")) + self.SaveAndStopPushButton.setText(_translate("SpikesLoggerGuiWindow", "Stop and save")) + self.label.setText(_translate("SpikesLoggerGuiWindow", "Status:")) + self.StatusLabel.setText(_translate("SpikesLoggerGuiWindow", "off")) + self.menuSpikesLogger.setTitle(_translate("SpikesLoggerGuiWindow", "SpikesLogger")) + self.menuHelp.setTitle(_translate("SpikesLoggerGuiWindow", "Help")) + self.actionOpen_file.setText(_translate("SpikesLoggerGuiWindow", "Open log")) + self.actionCreate_new_log.setText(_translate("SpikesLoggerGuiWindow", "Create new log")) + self.actionAbout.setText(_translate("SpikesLoggerGuiWindow", "About")) + self.actionUpdate.setText(_translate("SpikesLoggerGuiWindow", "Update")) + self.actionSource_code.setText(_translate("SpikesLoggerGuiWindow", "Source code")) diff --git a/src/LoggerGUI.ui b/src/LoggerGUI.ui new file mode 100755 index 0000000..cefb758 --- /dev/null +++ b/src/LoggerGUI.ui @@ -0,0 +1,336 @@ + + + SpikesLoggerGuiWindow + + + + 0 + 0 + 844 + 719 + + + + Spikes logger + + + + + + + 0 + + + + Logs + + + + + + + 16777215 + 16777215 + + + + QAbstractScrollArea::AdjustIgnored + + + true + + + Qt::AlignBottom|Qt::AlignJustify + + + + + 0 + 0 + 802 + 538 + + + + + + + Click start to start logging... + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + + + + + Settings + + + + QLayout::SetDefaultConstraint + + + + + + + SeaOttersAreSoFuckingCuteINeedThemInMyRoomRightNow + + + + + + + 255.255.255.255 + + + + + + + Logs save location + + + + + + + Server IP + + + + + + + + + + SpikesLogger/output + + + + + + + Temp value + + + + + + + Logger location + + + + + + + + false + + + + ArrowCursor + + + Qt::LeftToRight + + + /logs + + + + + + + + + Apply + + + + + + + + + + + + + + + 20 + + + + How to use? + + + + + + + <html><head/><body><p><span style=" font-style:italic;">FIRST</span>, make sure you are using a compatible logger on your robot (for example: SpikesLogger from SpikesLib). You can also put the value you want to log at the same location in the networktables as the Logger location in the settings above, although it is not recommended, and you need to make sure to not update the value periodically unless you want to log that same value periodically.</p><p>Enter your roborio IP and choose the location to save the logs to. after that you can start logging by pressing start, pause and save logs. You can change the temp value but make sure to set it to a value that is not likely to be logged.</p><p>To save the settings you can use the apply button.</p></body></html> + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + Start + + + + + + + Pause + + + + + + + Stop and save + + + false + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 14 + + + + Status: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 14 + + + + <font color='red'>off</font> + + + + + + + + + + + 0 + 0 + 844 + 23 + + + + + SpikesLogger + + + + + + + + + Help + + + + + + + + + + Open log + + + + + Create new log + + + + + About + + + + + Update + + + + + Source code + + + + + + diff --git a/src/SaveLogs.py b/src/SaveLogs.py new file mode 100755 index 0000000..f8cd049 --- /dev/null +++ b/src/SaveLogs.py @@ -0,0 +1,37 @@ +import datetime +import EditConfig +import os + + +def write(data): + + save_path = EditConfig.getData().get('save-location') + '/' + + name = 'log_from_' + str(datetime.datetime.now()) + # Windows is stupid, and cannot deal with a formatted time in a file name so I have to change it for the windows losers + # BTW, when trying to save a file with ":" in the name you will not get an error, you will get this stupid exit code: + # Process finished with exit code -1073740791 (0xC0000409) + name = name.replace(":", "-") + + if not os.path.exists(save_path): + os.makedirs(save_path) + + file_number = 1 + + if os.path.isfile(name + ".txt"): + + while os.path.isfile(name + "(" + str(file_number) + ").txt"): + file_number += 1 + + else: + file_number = -1 + + file_number = str(file_number) + + if file_number == "-1": + log_file = open(save_path + name + ".txt", 'w') + else: + log_file = open(save_path + name + "(" + file_number + ").txt", 'w') + + log_file.write(data) + log_file.close() diff --git a/src/SpikesLogger.py b/src/SpikesLogger.py new file mode 100755 index 0000000..c1941be --- /dev/null +++ b/src/SpikesLogger.py @@ -0,0 +1,163 @@ +import atexit +import os +import sys + +from PyQt6.QtGui import QIcon +from networktables import NetworkTables +from PyQt6 import QtWidgets +from PyQt6.QtWidgets import QApplication, QFileDialog +import webbrowser + +import EditConfig +import LoggerGUI +import SaveLogs + +conf_data = None +ip = "255.255.255.255" +logger_location = "SpikesLogger/output" +nt_dir = logger_location.rsplit('/')[0] +nt_value = logger_location.rsplit('/')[1] +temp_value = "SeaOttersAreSoFuckingCuteINeedThemInMyRoomRightNow" # Thanks to Mr Borito our beloved alumn/mentor who went to FIRST service year + +gui = None +current_log = "" + + +# get the data from the config file +def load_conf_data(): + global conf_data, ip, logger_location, nt_dir, nt_value, temp_value + + conf_data = EditConfig.getData() + ip = str(conf_data.get("serverip")) + logger_location = str(conf_data.get("logger-nt-location")) + nt_dir = logger_location.rsplit('/')[0] + nt_value = logger_location.rsplit('/')[1] + temp_value = str(conf_data.get("temp-value")) + +load_conf_data() + +# when value is logged +def value_changed(table, key, value, isNew): + global current_log + if value != temp_value: + print("logged: " + value) + table.putString(nt_value, temp_value) + current_log += value + '\n' + gui.update_gui(current_log) + + +def start_logging(): + load_conf_data() + NetworkTables.initialize(server=ip) + SpikesLogger_table.addEntryListener(key=nt_value, listener=value_changed) + print('started (ip: ' + ip + " | location: " + nt_dir + "/" + nt_value + ")") + gui.StatusLabel.setText("logging") + + +def pause_logging(): + SpikesLogger_table.removeEntryListener(listener=value_changed) + print('paused') + try: + gui.StatusLabel.setText("paused") + except: + print('gui is closed hmmmm') + + +def stop_and_save(): + global current_log, gui + pause_logging() + try: + gui.StatusLabel.setText("off") + except: + print('gui is closed') + if current_log != "": + SaveLogs.write(current_log) + current_log = "" + print('saved') + try: + gui.update_gui("Log file saved, press start to start logging...") + except: + print('gui is closed') + + +def resource_path(relative_path): + try: + base_path = sys._MEIPASS + except Exception: + base_path = os.path.abspath(".") + + return os.path.join(base_path, relative_path) + + +class SpikesLoggerGUI(QtWidgets.QMainWindow, LoggerGUI.Ui_SpikesLoggerGuiWindow): + + def __init__(self, parent=None): + global gui + + super(SpikesLoggerGUI, self).__init__(parent) + self.setupUi(self) + + self.StartPushButton.clicked.connect(start_logging) + self.PausePushButton.clicked.connect(pause_logging) + self.SaveAndStopPushButton.clicked.connect(stop_and_save) + self.applyChangesPushButton.clicked.connect(self.apply_changes) + + self.ServerIP.setText(conf_data.get("serverip")) + self.ChooseDirPushButton.setText(conf_data.get("save-location")) + self.networkTablesLoggerLocation.setText(conf_data.get("logger-nt-location")) + self.TempValue.setText(conf_data.get("temp-value")) + self.ChooseDirPushButton.clicked.connect(self.open_file_dialog) + + self.actionUpdate.triggered.connect(update_app) + self.actionAbout.triggered.connect(run_about) + self.actionSource_code.triggered.connect(see_source_code) + + self.setWindowIcon(QIcon(resource_path("SpikesLoggerSmallLogo.png"))) + + gui = self + + def apply_changes(self): + EditConfig.applyChanges(self.ServerIP.text(), self.ChooseDirPushButton.text(), self.networkTablesLoggerLocation.text(), self.TempValue.text()) + + def update_gui(self, log): + self.logsConsole.setText(log) + self.scrollArea.ensureVisible(0, self.logsConsole.height()) + + def open_file_dialog(self): + save_path = QFileDialog.getExistingDirectoryUrl().path() + if save_path != "": + if os.name == "nt": # the nt Windows kernel + save_path = save_path.removeprefix("/") + self.ChooseDirPushButton.setText(save_path) + + +def run_gui(): + app = QApplication(sys.argv) + form = SpikesLoggerGUI() + form.show() + app.exec() + + +# Python suckssss!!!11!!!1!!!11 +# if you want to, you can create a normal about dialog yourself, +# but use this text tho if you do: +# SpikesLogger is an app developed by The Spikes #2212 used to log values from the robot to the computer in real time. +# the source code is available here under GPLv3 licence. +def run_about(): + webbrowser.open('https://github.com/Spikes-2212-Programming-Guild/SpikesLogger/blob/main/README.md') + + +def update_app(): + webbrowser.open('https://github.com/Spikes-2212-Programming-Guild/SpikesLogger/releases') + + +def see_source_code(): + webbrowser.open('https://github.com/Spikes-2212-Programming-Guild/SpikesLogger') + + +if __name__ == '__main__': + global SpikesLogger_table + load_conf_data() + SpikesLogger_table = NetworkTables.getTable(nt_dir) + atexit.register(stop_and_save) + run_gui() diff --git a/src/SpikesLoggerIcon.ico b/src/SpikesLoggerIcon.ico new file mode 100755 index 0000000..8f29ccd Binary files /dev/null and b/src/SpikesLoggerIcon.ico differ diff --git a/src/SpikesLoggerSmallLogo.png b/src/SpikesLoggerSmallLogo.png new file mode 100755 index 0000000..514264c Binary files /dev/null and b/src/SpikesLoggerSmallLogo.png differ