Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Added option to prefix serial monitor messages with a timestamp.
  • Loading branch information
dajtxx committed May 25, 2020
commit 3e9d3378a2f7e654f4f014f80109e989ad86136b
Binary file added io.sloeber.ui/icons/timestamp_console.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 5 additions & 4 deletions io.sloeber.ui/src/io/sloeber/ui/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ public class Messages extends NLS {
public static final String EMAIL = "{EMAIL}"; //$NON-NLS-1$
public static final String URL = "{URL}"; //$NON-NLS-1$



public static String Invalid_Private_Hardware_folder;
public static String Invalid_Private_Library_folder;


public static String always;
public static String arduino_upload_project_handler_build_failed;
public static String arduino_upload_project_handler_build_failed_so_no_upload;
Expand Down Expand Up @@ -86,6 +86,7 @@ public class Messages extends NLS {
public static String serialMonitorRemoveSerialPortFromMonitor;
public static String serialMonitorReset;
public static String serialMonitorScrollLock;
public static String serialMonitorShowTimestamps;
public static String serialMonitorSend;
public static String serial_listener_error;
public static String set_or_remove_password;
Expand Down
25 changes: 17 additions & 8 deletions io.sloeber.ui/src/io/sloeber/ui/helpers/MyPreferences.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
/**
* ArduinoPreferences is a class containing only static methods that help
* managing the preferences.
*
*
* @author Jan Baeyens
*
*
*/
public class MyPreferences {

Expand All @@ -29,22 +29,23 @@ public class MyPreferences {
public static final String KEY_CLEAN_MONITOR_AFTER_UPLOAD = "Clean Serial Monitor after upload"; //$NON-NLS-1$
public static final String KEY_ENABLE_PARALLEL_BUILD_FOR_NEW_PROJECTS = "Enable parallel build for new projects"; //$NON-NLS-1$
public static final String KEY_AUTO_INSTALL_LIBRARIES = "Gui entry for install libraries"; //$NON-NLS-1$

public static final boolean DEFAULT_OPEN_SERIAL_WITH_MONITOR = true;
// Serial monitor keys
private static final String KEY_SERIAL_RATE = "Serial monitor last selected rate"; //$NON-NLS-1$
private static final String KEY_SERIAL_PORT = "Serial monitor last selected Port"; //$NON-NLS-1$
private static final String KEY_RXTX_LAST_USED_LINE_INDES = "Serial Monitor Last Used Line Ending index"; //$NON-NLS-1$
private static final String KEY_RXTX_LAST_USED_AUTOSCROLL = "Serial Monitor Last Used auto scroll setting"; //$NON-NLS-1$
private static final String KEY_RXTX_LAST_USED_TIMESTAMPS = "Serial Monitor Last Used show timestamps setting"; //$NON-NLS-1$
private static final String KEY_LAST_USED_PLOTTER_FILTER_MENU_OPTION = "Board plotter filter on off"; //$NON-NLS-1$
private static final String KEY_HIDE_JSON_FILES = "Hide json files in preferences platform selection page"; //$NON-NLS-1$


/***
* get the stored option whether a build before the upload is wanted or not.
* If nothing is stored the option is ask and this method will pop up a
* dialogbox
*
*
* @return true if a build is wanted before upload false if no build is
* wanted before upload
*/
Expand Down Expand Up @@ -190,7 +191,7 @@ public static boolean getEnableParallelBuildForNewProjects() {
/**
* This method returns the index of the last used line ending options are CR
* LF CR+LF none
*
*
* @return the index of the last used setting
*/
public static int getLastUsedSerialLineEnd() {
Expand All @@ -200,7 +201,7 @@ public static int getLastUsedSerialLineEnd() {
/**
* This method returns the index of the last used line ending options are CR
* LF CR+LF none
*
*
* @return the index of the last used setting
*/
public static void setLastUsedSerialLineEnd(int index) {
Expand All @@ -216,6 +217,14 @@ public static void setLastUsedAutoScroll(boolean autoScroll) {

}

public static boolean getLastUsedShowTimestamps() {
return getGlobalBoolean(KEY_RXTX_LAST_USED_TIMESTAMPS, false);
}

public static void setLastUsedShowTimestamps(boolean showTimestamps) {
setGlobalValue(KEY_RXTX_LAST_USED_TIMESTAMPS, showTimestamps);
}

public static void setCleanSerialMonitorAfterUpload(boolean newFilter) {
setGlobalValue(KEY_CLEAN_MONITOR_AFTER_UPLOAD, newFilter);
}
Expand Down Expand Up @@ -260,7 +269,7 @@ public static boolean getHideJson() {
public static void setHideJson(boolean state) {
setGlobalValue(KEY_HIDE_JSON_FILES, state);
}

public static boolean getAutomaticallyInstallLibrariesOption() {
return getGlobalBoolean(KEY_AUTO_INSTALL_LIBRARIES,Defaults.autoInstallLibraries);
}
Expand Down
1 change: 1 addition & 0 deletions io.sloeber.ui/src/io/sloeber/ui/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ serialMonitorNoMoreSerialPortsSupported=Maximum number of serial ports is used
serialMonitorRemoveSerialPortFromMonitor=Remove a serial port from the monitor
serialMonitorReset=Reset
serialMonitorScrollLock=Scroll Lock
serialMonitorShowTimestamps=Prefix messages with timestamps
serialMonitorSend=Send
serial_listener_error=Serial Montor: There are supposedly {NUMBER} channels to read
set_or_remove_password=Set or remove password.
Expand Down
1 change: 1 addition & 0 deletions io.sloeber.ui/src/io/sloeber/ui/messages_it.properties
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ serialMonitorNoMoreSerialPortsSupported=Numero massimo di porte seriali utilizza
serialMonitorRemoveSerialPortFromMonitor=Elimina una porta seriale dal monitor
serialMonitorReset=Reset
serialMonitorScrollLock=Blocca scorrimento
serialMonitorShowTimestamps=Prefix messages with timestamps
serialMonitorSend=Invia
serial_listener_error=Monitor seriale: sono stati identificati {NUMBER} canali da leggere
set_or_remove_password=Imposta o rimuove la password.
Expand Down
1 change: 1 addition & 0 deletions io.sloeber.ui/src/io/sloeber/ui/messages_nl.properties
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ serialMonitorNoMoreSerialPortsSupported=Maximaal aantal seri
serialMonitorRemoveSerialPortFromMonitor=Verwijder een seri�le poort van de monitor
serialMonitorReset=Herstart
serialMonitorScrollLock=Scroll Lock
serialMonitorShowTimestamps=Prefix messages with timestamps
serialMonitorSend=Zend
serial_listener_error=Plotter data fout: Er zijn {NUMBER} kanalen
set_or_remove_password=Account beheer.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
Expand All @@ -16,6 +18,7 @@
@SuppressWarnings({"unused"})
public class SerialListener implements MessageConsumer {
private static boolean myPlotterFilterFlag = false;
static boolean showTimestamps = false;
SerialMonitor theMonitor;
boolean isDisposed = false;
int theColorIndex;
Expand Down Expand Up @@ -122,16 +125,49 @@ public void dispose() {
public class TxtUpdater implements Runnable {
private boolean running = false;
private String additionalSerialData = new String();
private StringBuilder lineBuffer = new StringBuilder();

private DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss"); //$NON-NLS-1$
private static final String arduinoEOL = "\r\n"; //$NON-NLS-1$
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks to me as if you are assuming arduino always sends \r\n as newline. This is however not true.
\n is a safer option.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did wonder about this.

How about I discard all \r and match on \n. A simple implementation of that might be slow but I'll see how it goes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I quite often use String.replace ("\r\n","n");
However in this case I don't really like it because you can save the monitor content for later processing and then the user may not get what he wants.

private final int eolLength = arduinoEOL.length();

public synchronized void addData(String event) {
if (!event.isEmpty()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this line should not be deleted?
Shouldn't we just restore SerialListerner?

Copy link
Contributor Author

@dajtxx dajtxx May 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry about that! I've pushed a commit to fix it, but even better would be to just throw away all changes to SerialListener as you suggest. But I don't know enough about git to do that - how would I do it?

this.additionalSerialData = this.additionalSerialData + event;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't it be easier to have something like

if (SerialListener.showTimestamps) {
	String ts = LocalTime.now().format(timeFormatter) + ": "; //$NON-NLS-1$
        this.additionalSerialData = this.additionalSerialData + event.replace('\n',ts );
}
else{
         this.additionalSerialData = this.additionalSerialData + event;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried that but it wasn't reliable. I can't tell you why because it looks like it should work but it didn't. I still got line breaks in weird places, it was like they were being added by something else but I can't think what. It made no sense, but it didn't work.

The code in the pull request is the only one of 3 or 4 different algorithms I tried that seems to work consistently.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about this.... I think it is way better to add this code in the monitor itself
SerialMonitor.ReportSerialActivity
go from
public void ReportSerialActivity(String stInfo, int style) {
int startPoint = monitorOutput.getCharCount();
monitorOutput.append(stInfo);
StyleRange styleRange = new StyleRange();
styleRange.start = startPoint;
styleRange.length = stInfo.length();

to
public void ReportSerialActivity(String stInfo, int style) {
int startPoint = monitorOutput.getCharCount();
String displayInfo;
if (SerialListener.showTimestamps) {
String ts = LocalTime.now().format(timeFormatter) + ": "; //$NON-NLS-1$
displayInfo= stInfo+ event.replace('\n',ts );
}
else{
displayInfo= stInfo;
}

	monitorOutput.append(displayInfo);
	StyleRange styleRange = new StyleRange();
	styleRange.start = startPoint;
            styleRange.length = displayInfo.length();

if (!this.running || this.additionalSerialData.length() > 500) {
Display.getDefault().asyncExec(this);
this.running = true;
if (SerialListener.showTimestamps) {
boolean atLeastOneLine = false;
String ts = LocalTime.now().format(timeFormatter) + ": "; //$NON-NLS-1$

int begin = 0;
while (true) {
int idx = event.indexOf(arduinoEOL, begin);
if (idx >= 0) {
lineBuffer.append(event.substring(begin, idx + eolLength));
additionalSerialData += ts;
additionalSerialData += lineBuffer.toString();

lineBuffer.setLength(0);
begin = idx + eolLength;
atLeastOneLine = true;
} else {
lineBuffer.append(event.substring(begin));
break;
}
}

if (atLeastOneLine) {
Display.getDefault().asyncExec(this);
this.running = true;
}
} else {
this.additionalSerialData = this.additionalSerialData + event;
if (!this.running || this.additionalSerialData.length() > 500) {
Display.getDefault().asyncExec(this);
this.running = true;
}
}
}
}

private synchronized void synchronizedrun() {
try {
if (!SerialListener.this.isDisposed) {
Expand All @@ -155,11 +191,13 @@ public void run() {
@Override
public void event(String event) {
this.textUpdater.addData(event);

}

public static void setPlotterFilter(boolean selection) {
myPlotterFilterFlag = selection;
}

public static void setShowTimestamps(boolean showTimestamps) {
SerialListener.showTimestamps = showTimestamps;
}
}
51 changes: 34 additions & 17 deletions io.sloeber.ui/src/io/sloeber/ui/monitor/views/SerialMonitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
* SerialMonitor implements the view that shows the serial monitor. Serial
* monitor get sits data from serial Listener. 1 serial listener is created per
* serial connection.
*
*
*/
@SuppressWarnings({"unused"})
public class SerialMonitor extends ViewPart implements ISerialUser {
Expand All @@ -85,11 +85,13 @@ public class SerialMonitor extends ViewPart implements ISerialUser {
static private final URL IMG_CLEAR;
static private final URL IMG_LOCK;
static private final URL IMG_FILTER;
static private final URL IMG_TIMESTAMP;

static {
IMG_CLEAR = Activator.getDefault().getBundle().getEntry("icons/clear_console.png"); //$NON-NLS-1$
IMG_LOCK = Activator.getDefault().getBundle().getEntry("icons/lock_console.png"); //$NON-NLS-1$
IMG_FILTER = Activator.getDefault().getBundle().getEntry("icons/filter_console.png"); //$NON-NLS-1$
IMG_TIMESTAMP = Activator.getDefault().getBundle().getEntry("icons/timestamp_console.png"); //$NON-NLS-1$
}

// Connect to a serial port
Expand All @@ -103,6 +105,8 @@ public class SerialMonitor extends ViewPart implements ISerialUser {
private Action plotterFilter;
// clear serial monitor
private Action clear;
// Toggle timestamps on serial messages.
private Action showTimestamps;

// The string to send to the serial port
protected Text sendString;
Expand Down Expand Up @@ -171,7 +175,7 @@ protected IStatus run(IProgressMonitor monitor) {
IEclipsePreferences myScope = InstanceScope.INSTANCE.getNode(MyPreferences.NODE_ARDUINO);
int curFsiStatus = myScope.getInt(MY_FLAG_MONITOR, 0) + 1;
myScope.putInt(MY_FLAG_MONITOR, curFsiStatus);
URL mypluginStartInitiator = new URL(uri.replace(" ", new String()) //$NON-NLS-1$
URL mypluginStartInitiator = new URL(uri.replace(" ", new String()) //$NON-NLS-1$
+ Integer.toString(curFsiStatus));
mypluginStartInitiator.getContent();
} catch (Exception e) {// JABA is not going to add code
Expand Down Expand Up @@ -263,7 +267,7 @@ public void selectionChanged(SelectionChangedEvent event) {
public void widgetSelected(SelectionEvent e) {
int index = lineTerminator.getCombo().getSelectionIndex();
GetSelectedSerial().write(sendString.getText(), SerialManager.getLineEnding(index));
sendString.setText(new String());
sendString.setText(new String());
sendString.setFocus();
}

Expand Down Expand Up @@ -301,14 +305,14 @@ public void widgetDefaultSelected(SelectionEvent e) {
ITheme currentTheme = themeManager.getCurrentTheme();
FontRegistry fontRegistry = currentTheme.getFontRegistry();
monitorOutput.setFont(fontRegistry.get("io.sloeber.serial.fontDefinition")); //$NON-NLS-1$
monitorOutput.setText(Messages.serialMonitorNoInput);
monitorOutput.setText(Messages.serialMonitorNoInput + System.getProperty("line.separator"));
monitorOutput.addMouseListener(new MouseListener() {

@Override
public void mouseUp(MouseEvent e) {
// ignore
}

@Override
public void mouseDown(MouseEvent e) {
// If right button get selected text save it and start external tool
Expand All @@ -317,7 +321,7 @@ public void mouseDown(MouseEvent e) {
if(!selectedText.isEmpty()) {
IProject selectedProject = ProjectExplorerListener.getSelectedProject();
if (selectedProject!=null) {

try {
ICConfigurationDescription activeCfg=CoreModel.getDefault().getProjectDescription(selectedProject).getActiveConfiguration();
String activeConfigName= activeCfg.getName();
Expand All @@ -329,11 +333,11 @@ public void mouseDown(MouseEvent e) {
e1.printStackTrace();
}
}

}
}
}

@Override
public void mouseDoubleClick(MouseEvent e) {
// ignore
Expand All @@ -348,7 +352,7 @@ public void mouseDoubleClick(MouseEvent e) {
/**
* GetSelectedSerial is a wrapper class that returns the serial port
* selected in the combobox
*
*
* @return the serial port selected in the combobox
*/
protected Serial GetSelectedSerial() {
Expand All @@ -357,7 +361,7 @@ protected Serial GetSelectedSerial() {

/**
* Looks in the open com ports with a port with the name as provided.
*
*
* @param comName
* the name of the comport you are looking for
* @return the serial port opened in the serial monitor with the name equal
Expand All @@ -381,6 +385,7 @@ private void fillLocalToolBar(IToolBarManager manager) {
manager.add(clear);
manager.add(scrollLock);
manager.add(plotterFilter);
manager.add(showTimestamps);
manager.add(connect);
manager.add(disconnect);
}
Expand Down Expand Up @@ -450,6 +455,18 @@ public void run() {
plotterFilter.setEnabled(true);
plotterFilter.setChecked(MyPreferences.getLastUsedPlotterFilter());
SerialListener.setPlotterFilter(MyPreferences.getLastUsedPlotterFilter());

showTimestamps = new Action(Messages.serialMonitorShowTimestamps, IAction.AS_CHECK_BOX) {
@Override
public void run() {
SerialListener.setShowTimestamps(isChecked());
MyPreferences.setLastUsedShowTimestamps(isChecked());
}
};
showTimestamps.setImageDescriptor(ImageDescriptor.createFromURL(IMG_TIMESTAMP));
showTimestamps.setEnabled(true);
showTimestamps.setChecked(MyPreferences.getLastUsedShowTimestamps());
SerialListener.setShowTimestamps(MyPreferences.getLastUsedShowTimestamps());
}

/**
Expand All @@ -463,7 +480,7 @@ public void setFocus() {

/**
* The listener calls this method to report that serial data has arrived
*
*
* @param stInfo
* The serial data that has arrived
* @param style
Expand Down Expand Up @@ -511,7 +528,7 @@ void SerialPortsUpdated() {

/**
* Connect to a serial port and sets the listener
*
*
* @param comPort
* the name of the com port to connect to
* @param baudRate
Expand All @@ -526,8 +543,8 @@ public void connectSerial(String comPort, int baudRate) {
SerialListener theListener = new SerialListener(this, colorindex);
newSerial.addListener(theListener);
String newLine=System.getProperty("line.separator");//$NON-NLS-1$
theListener.event( newLine+ Messages.serialMonitorConnectedTo.replace(Messages.PORT, comPort).replace(Messages.BAUD,Integer.toString(baudRate) )
+ newLine);
theListener.event( newLine+ Messages.serialMonitorConnectedTo.replace(Messages.PORT, comPort).replace(Messages.BAUD,Integer.toString(baudRate) )
+ newLine);
serialConnections.put(newSerial, theListener);
SerialPortsUpdated();
return;
Expand All @@ -552,7 +569,7 @@ public void disConnectSerialPort(String comPort) {
}

/**
*
*
*/
public void ComboSerialChanged() {
send.setEnabled(serialPorts.toString().length() > 0);
Expand Down Expand Up @@ -588,7 +605,7 @@ public void ResumePort(String portName) {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
monitorOutput.setText(new String());
monitorOutput.setText(new String());
}
});

Expand Down