Skip to content

Commit

Permalink
Merge pull request #1002 from OpenBCI/development
Browse files Browse the repository at this point in the history
Development 5.0.7
  • Loading branch information
retiutut authored Sep 29, 2021
2 parents 5313607 + 2edced4 commit 8db90eb
Show file tree
Hide file tree
Showing 19 changed files with 255 additions and 139 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ jobs:
branches:
only:
- master
- development

before_install:
- if [ "$TRAVIS_OS_NAME" = osx ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then openssl aes-256-cbc -K $encrypted_2f5d2771e3cb_key -iv $encrypted_2f5d2771e3cb_iv -in release_script/mac_only/Certificates.p12.enc -out release_script/mac_only/Certificates.p12 -d; fi
Expand Down Expand Up @@ -68,4 +69,4 @@ after_success:
notifications:
email:
on_success: never
on_failure: always
on_failure: always
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# v5.0.7

### Improvements
* Show info in footer when a new version of the GUI is available #992
* Further improvements to GUI Update Button logic
* Add GUI-wide settings class to keep certain settings across sessions and app starts #997
* Remove 30 second window option from Focus widget

### Bug Fixes
* Fix GUI not running on some Macs due to high-dpi screen code #987 #990 #1001
* Fix streaming multiple data types over LSL #971

# v5.0.6

### Improvements
Expand Down
17 changes: 9 additions & 8 deletions Networking-Test-Kit/LSL/lslStreamTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

# create a new inlet to read from the stream
inlet = StreamInlet(streams[0])
duration = 2
duration = 5

sleep(1)

Expand All @@ -18,17 +18,18 @@ def testLSLSamplingRate():
totalNumSamples = 0
validSamples = 0
numChunks = 0
print( "Testing Sampling Rates..." )

while time.time() <= start + duration:
# get chunks of samples
samples, timestamp = inlet.pull_chunk()
if samples:
chunk, timestamp = inlet.pull_chunk()
if chunk:
numChunks += 1
print( len(samples) )
totalNumSamples += len(samples)
# print(samples);
for sample in samples:
print(sample)
# print( len(chunk) )
totalNumSamples += len(chunk)
# print(chunk);
for sample in chunk:
# print(sample)
validSamples += 1

print( "Number of Chunks and Samples == {} , {}".format(numChunks, totalNumSamples) )
Expand Down
50 changes: 29 additions & 21 deletions Networking-Test-Kit/LSL/lslStreamTest_3Streams.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,43 +10,51 @@
import time

numStreams = 3
duration_seconds = 20
# first resolve an EEG stream on the lab network
print("looking for an EEG stream...")
stream1 = resolve_stream('type', 'EEG')
stream2 = resolve_stream('type', 'AUX')
stream3 = resolve_stream('type', 'FFT')
stream_1 = resolve_stream('type', 'EEG')
stream_2 = resolve_stream('type', 'AUX')
stream_3 = resolve_stream('type', 'FOCUS')

# create a new inlet to read from the stream
inlet = StreamInlet(stream1[0])
inlet2 = StreamInlet(stream2[0])
inlet3 = StreamInlet(stream3[0])
inlet = StreamInlet(stream_1[0])
intlet_2 = StreamInlet(stream_2[0])
intlet_3 = StreamInlet(stream_3[0])

def testLSLSamplingRates():
print( "Testing Sampling Rates..." )
print( "Testing Sampling Rates for {} seconds".format(duration_seconds) )
start = time.time()
numSamples1 = 0
numSamples2 = 0
numSamples3 = 0
while time.time() < start + 5:
num_samples_1 = 0
num_samples_2 = 0
num_samples_3 = 0
while time.time() < start + duration_seconds:
# get a new sample (you can also omit the timestamp part if you're not
# interested in it)
for i in range(numStreams):
if i == 0:
chunk, timestamps = inlet.pull_chunk()
if timestamps:
numSamples1 += 1
for sample in chunk:
if sample:
num_samples_1 += 1
#print(sample)
elif i == 1:
chunk, timestamps2 = inlet2.pull_chunk()
if timestamps2:
numSamples2 += 1
chunk, timestamps_2 = intlet_2.pull_chunk()
if timestamps_2:
for sample in chunk:
num_samples_2 += 1
#print(sample)
elif i == 2:
chunk, timestamps3 = inlet3.pull_chunk()
if timestamps3:
numSamples3 += 1
chunk, timestamps_3 = intlet_3.pull_chunk()
if timestamps_3:
for sample in chunk:
num_samples_3 += 1
#print(sample)
#print("Stream", i + 1, " == ", chunk)
print( "Stream 1 Sampling Rate == ", numSamples1, " | Type : EEG")
print( "Stream 2 Sampling Rate == ", numSamples2, " | Type : AUX")
print( "Stream 3 Sampling Rate == ", numSamples3, " | Type : FFT")
print( "Stream 1 Sampling Rate == ", num_samples_1 / duration_seconds, " | Type : EEG")
print( "Stream 2 Sampling Rate == ", num_samples_2 / duration_seconds, " | Type : AUX")
print( "Stream 3 Sampling Rate == ", num_samples_3 / duration_seconds, " | Type : FOCUS")


testLSLSamplingRates()
5 changes: 3 additions & 2 deletions Networking-Test-Kit/LSL/lslStreamTest_FFTplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@

last_print = time.time()
fps_counter = deque(maxlen=150)
duration = 5

# first resolve an EEG stream on the lab network
print("looking for an EEG stream...")
streams = resolve_stream('type', 'EEG')
streams = resolve_stream('type', 'FFT')
# create a new inlet to read from the stream
inlet = StreamInlet(streams[0])

channel_data = {}

for i in range(5): # how many iterations. Eventually this would be a while True
for i in range(duration): # how many iterations. Eventually this would be a while True

for i in range(16): # each of the 16 channels here
sample, timestamp = inlet.pull_sample()
Expand Down
2 changes: 1 addition & 1 deletion OpenBCI_GUI/ADS1299SettingsController.pde
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class ADS1299SettingsController {
}
}

boolean showCustomCommandUI = settings.expertModeToggle;
boolean showCustomCommandUI = guiSettings.getExpertModeBoolean();

//Draw background behind command buttons
pushStyle();
Expand Down
1 change: 0 additions & 1 deletion OpenBCI_GUI/ControlPanel.pde
Original file line number Diff line number Diff line change
Expand Up @@ -2778,7 +2778,6 @@ class InitBox {
}
} else {
//if system is already active ... stop session and flip button state back
outputInfo("Learn how to use this application and more at openbci.github.io/Documentation/");
setInitSessionButtonText("START SESSION");
topNav.setLockTopLeftSubNavCp5Objects(false); //Unlock top left subnav buttons
//creates new data file name so that you don't accidentally overwrite the old one
Expand Down
3 changes: 2 additions & 1 deletion OpenBCI_GUI/CustomCp5Classes.pde
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ class ButtonHelpText{
}

public void draw(){
if (!isVisible || settings.expertModeToggle) {
//When using expert mode, disable help text over UI objects
if (!isVisible || guiSettings.getExpertModeBoolean()) {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion OpenBCI_GUI/Debugging.pde
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class HelpWidget {
int padding;

//current text shown in help widget, based on most recent command
String currentOutput = "Learn how to use this application and more at openbci.github.io/Documentation/";
String currentOutput = "Learn how to use this application and more at docs.openbci.com";
OutputLevel curOutputLevel = OutputLevel.INFO;

HelpWidget(float _xPos, float _yPos, float _width, float _height) {
Expand Down
3 changes: 1 addition & 2 deletions OpenBCI_GUI/FocusEnums.pde
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ public enum FocusXLim implements FocusEnum
{
FIVE (0, 5, "5 sec"),
TEN (1, 10, "10 sec"),
TWENTY (2, 20, "20 sec"),
THIRTY (3, 30, "30 sec");
TWENTY (2, 20, "20 sec");

private int index;
private int value;
Expand Down
116 changes: 116 additions & 0 deletions OpenBCI_GUI/GuiSettings.pde
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.*;


interface GuiSettingsEnum {
public String getName();
}

enum ExpertModeEnum implements GuiSettingsEnum {
ON("Active", true),
OFF("Inactive", false);

private String name;
private boolean val;

ExpertModeEnum(String _name, boolean _val) {
this.name = _name;
this.val = _val;
}

@Override
public String getName() {
return name;
}

public boolean getBooleanValue() {
return val;
}
}

public class GuiSettingsValues {
private ExpertModeEnum expertMode = ExpertModeEnum.OFF;

public GuiSettingsValues() {
}
}

class GuiSettings {

public GuiSettingsValues values;
private String filename;

GuiSettings(String settingsDirectory) {

values = new GuiSettingsValues();

StringBuilder settingsFilename = new StringBuilder(settingsDirectory);
settingsFilename.append("GuiWideSettings.json");
filename = settingsFilename.toString();
File fileToCheck = new File(filename);
boolean fileExists = fileToCheck.exists();
if (fileExists) {
loadSettingsValues();
println("OpenBCI_GUI::Settings: Found and loaded existing GUI-wide Settings from file.");
} else {
println("OpenBCI_GUI::Settings: Creating new GUI-wide Settings file.");
saveToFile();
}
}

public boolean loadSettingsValues() {
try {
File file = new File(filename);
StringBuilder fileContents = new StringBuilder((int)file.length());
Scanner scanner = new Scanner(file);
while(scanner.hasNextLine()) {
fileContents.append(scanner.nextLine() + System.lineSeparator());
}
Gson gson = new Gson();
values = gson.fromJson(fileContents.toString(), GuiSettingsValues.class);
return true;
} catch (IOException e) {
e.printStackTrace();
outputWarn("OpenBCI_GUI::Settings: Error loading GUI-wide settings from file. Attempting to create a new one.");
//If there is an error, attempt to overwrite the file or create a new one
saveToFile();
return false;
}
}

public String getJson() {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
return gson.toJson(values);
}

public boolean saveToFile() {
String json = getJson();
try {
FileWriter writer = new FileWriter(filename);
writer.write(json);
writer.close();
println("OpenBCI_GUI::Settings: Successfully saved GUI-wide settings to file!");
return true;
} catch (IOException e) {
e.printStackTrace();
outputWarn("OpenBCI_GUI::Settings: Error saving GUI-wide settings to file. Please make an issue on GitHub.");
return false;
}
}

//Call this method at the end of GUI main Setup in OpenBCI_GUI.pde to make sure everything exists
//Has to be in this class to make sure other classes exist
public void applySettings() {
topNav.configSelector.toggleExpertModeFrontEnd(getExpertModeBoolean());
}

public void setExpertMode(ExpertModeEnum val) {
values.expertMode = val;
saveToFile();
}

public boolean getExpertModeBoolean() {
return values.expertMode.getBooleanValue();
}
}
4 changes: 2 additions & 2 deletions OpenBCI_GUI/Info.plist.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<key>CFBundleShortVersionString</key>
<string>5</string>
<key>CFBundleVersion</key>
<string>5.0.6</string>
<string>5.0.7</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>NSHumanReadableCopyright</key>
Expand All @@ -32,7 +32,7 @@
Copyright © 2021 OpenBCI
</string>
<key>CFBundleGetInfoString</key>
<string>July 2021</string>
<string>September 2021</string>
<!-- End of the set that can be customized -->

@@jvm_runtime@@
Expand Down
2 changes: 1 addition & 1 deletion OpenBCI_GUI/Interactivity.pde
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ synchronized void keyPressed() {
boolean anyActiveTextfields = isNetworkingTextActive() || textFieldIsActive;

if(!controlPanel.isOpen && !anyActiveTextfields){ //don't parse the key if the control panel is open
if (settings.expertModeToggle || key == ' ') { //Check if Expert Mode is On or Spacebar has been pressed
if (guiSettings.getExpertModeBoolean() || key == ' ') { //Check if Expert Mode is On or Spacebar has been pressed
if ((int(key) >=32) && (int(key) <= 126)) { //32 through 126 represent all the usual printable ASCII characters
parseKey(key);
}
Expand Down
Loading

0 comments on commit 8db90eb

Please sign in to comment.