-
Notifications
You must be signed in to change notification settings - Fork 8
Refactored GPIO to be testable and gradle upgrade #116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 4 commits
a3a4f91
b600c7e
74d5923
61d887c
5f0a827
078b669
e5a9b23
27f23f5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,3 +5,4 @@ | |
| **/xtend-gen/ | ||
| **/*.java._trace | ||
| **/*.xtendbin | ||
| !/src/main/vql-gen/* | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,18 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <classpath> | ||
| <classpathentry kind="src" path="src/main/java"/> | ||
| <classpathentry kind="src" path="src/main/xtend-gen"/> | ||
| <classpathentry kind="src" output="bin/main" path="src/main/java"> | ||
| <attributes> | ||
| <attribute name="gradle_scope" value="main"/> | ||
| <attribute name="gradle_used_by_scope" value="main,test"/> | ||
| </attributes> | ||
| </classpathentry> | ||
| <classpathentry kind="src" output="bin/main" path="src/main/xtend-gen"> | ||
| <attributes> | ||
| <attribute name="gradle_scope" value="main"/> | ||
| <attribute name="gradle_used_by_scope" value="main,test"/> | ||
| </attributes> | ||
| </classpathentry> | ||
| <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/> | ||
| <classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/> | ||
| <classpathentry kind="output" path="bin"/> | ||
| <classpathentry kind="output" path="bin/default"/> | ||
| </classpath> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,24 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <classpath> | ||
| <classpathentry kind="src" path="src/main/java"/> | ||
| <classpathentry kind="src" path="src/main/webapp"/> | ||
| <classpathentry kind="src" path="src/main/resources"/> | ||
| <classpathentry kind="src" output="bin/main" path="src/main/java"> | ||
| <attributes> | ||
| <attribute name="gradle_scope" value="main"/> | ||
| <attribute name="gradle_used_by_scope" value="main,test"/> | ||
| </attributes> | ||
| </classpathentry> | ||
| <classpathentry kind="src" output="bin/main" path="src/main/webapp"> | ||
| <attributes> | ||
| <attribute name="gradle_scope" value="main"/> | ||
| <attribute name="gradle_used_by_scope" value="main,test"/> | ||
| </attributes> | ||
| </classpathentry> | ||
| <classpathentry kind="src" output="bin/main" path="src/main/resources"> | ||
| <attributes> | ||
| <attribute name="gradle_scope" value="main"/> | ||
| <attribute name="gradle_used_by_scope" value="main,test"/> | ||
| </attributes> | ||
| </classpathentry> | ||
| <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/> | ||
| <classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/> | ||
| <classpathentry kind="output" path="bin"/> | ||
| <classpathentry kind="output" path="bin/default"/> | ||
| </classpath> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,24 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <classpath> | ||
| <classpathentry kind="src" path="src/main/java"/> | ||
| <classpathentry kind="src" path="src/main/resources"/> | ||
| <classpathentry kind="src" output="bin/main" path="src/main/java"> | ||
| <attributes> | ||
| <attribute name="gradle_scope" value="main"/> | ||
| <attribute name="gradle_used_by_scope" value="main,test"/> | ||
| </attributes> | ||
| </classpathentry> | ||
| <classpathentry kind="src" output="bin/test" path="src/test/java"> | ||
| <attributes> | ||
| <attribute name="gradle_scope" value="test"/> | ||
| <attribute name="gradle_used_by_scope" value="test"/> | ||
| </attributes> | ||
| </classpathentry> | ||
| <classpathentry kind="src" output="bin/main" path="src/main/resources"> | ||
| <attributes> | ||
| <attribute name="gradle_scope" value="main"/> | ||
| <attribute name="gradle_used_by_scope" value="main,test"/> | ||
| </attributes> | ||
| </classpathentry> | ||
| <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/> | ||
| <classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/> | ||
| <classpathentry kind="output" path="bin"/> | ||
| <classpathentry kind="output" path="bin/default"/> | ||
| </classpath> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| package hu.bme.mit.inf.modes3.components.gpiomanager; | ||
|
|
||
| import java.io.IOException; | ||
|
|
||
| import hu.bme.mit.inf.modes3.components.gpiomanager.Gpio.Level; | ||
|
|
||
| public interface CommandReader { | ||
| Level getGpioValue(String targetPath) throws IOException; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package hu.bme.mit.inf.modes3.components.gpiomanager; | ||
|
|
||
| import java.io.IOException; | ||
|
|
||
| public interface CommandWriter { | ||
| void executeCommand(String value, String targetFile) throws IOException; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,10 +6,8 @@ | |
| package hu.bme.mit.inf.modes3.components.gpiomanager; | ||
|
|
||
| import java.io.BufferedReader; | ||
| import java.io.BufferedWriter; | ||
| import java.io.FileNotFoundException; | ||
| import java.io.FileReader; | ||
| import java.io.FileWriter; | ||
| import java.io.IOException; | ||
| import java.util.ArrayList; | ||
| import java.util.Collections; | ||
|
|
@@ -57,13 +55,17 @@ public interface InputStateListener { | |
|
|
||
| private TimerTask _inputListenerTask; | ||
|
|
||
| private static CommandWriter WRITER; | ||
|
|
||
| private static CommandReader READER; | ||
benedekh marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| public Gpio(int pin, Direction direction) throws IOException, GpioNotConfiguratedException { | ||
|
||
| this._pin = pin; | ||
| this._direction = direction; | ||
|
|
||
| // export gpio pin first | ||
| try { | ||
| executeCommand(String.valueOf(_pin), GPIO_BASE_FOLDER + "export"); | ||
| WRITER.executeCommand(String.valueOf(_pin), GPIO_BASE_FOLDER + "export"); | ||
| } catch (Exception ex) { | ||
| Logger.error(TAG, "Pin export failed! Pin: %d", _pin); | ||
|
|
||
|
|
@@ -72,8 +74,8 @@ public Gpio(int pin, Direction direction) throws IOException, GpioNotConfigurate | |
| // in this case, we should unexport it and try to export it again | ||
| // if unexport fails also, there should be something wrong | ||
| try { | ||
| executeCommand(String.valueOf(_pin), GPIO_BASE_FOLDER + "unexport"); | ||
| executeCommand(String.valueOf(_pin), GPIO_BASE_FOLDER + "export"); | ||
| WRITER.executeCommand(String.valueOf(_pin), GPIO_BASE_FOLDER + "unexport"); | ||
| WRITER.executeCommand(String.valueOf(_pin), GPIO_BASE_FOLDER + "export"); | ||
| } catch (Exception ex2) { | ||
| Logger.error(TAG, "Pin re-export failed! Pin: %d", _pin); | ||
| throw ex2; | ||
|
|
@@ -84,7 +86,7 @@ public Gpio(int pin, Direction direction) throws IOException, GpioNotConfigurate | |
|
|
||
| // set direction of pin | ||
| try { | ||
| executeCommand(this._direction.toString().toLowerCase(), _gpioFolder + "direction"); | ||
| WRITER.executeCommand(this._direction.toString().toLowerCase(), _gpioFolder + "direction"); | ||
| } catch (Exception ex) { | ||
| Logger.error(TAG, "Pin direction setup failed! Pin: %d", _pin); | ||
| throw ex; | ||
|
|
@@ -93,7 +95,7 @@ public Gpio(int pin, Direction direction) throws IOException, GpioNotConfigurate | |
| switch (this._direction) { | ||
| case IN: | ||
| // setup edge detection as well | ||
| executeCommand("both", _gpioFolder + "edge"); | ||
| WRITER.executeCommand("both", _gpioFolder + "edge"); | ||
|
|
||
| setupInputChangeListening(); | ||
| break; | ||
|
|
@@ -107,7 +109,7 @@ public Gpio(int pin, Direction direction) throws IOException, GpioNotConfigurate | |
|
|
||
| public final void setLevel(Level level) throws IOException { | ||
| try { | ||
| executeCommand(level == Level.HIGH ? "1" : "0", _gpioFolder + "value"); | ||
| WRITER.executeCommand(level == Level.HIGH ? "1" : "0", _gpioFolder + "value"); | ||
| this._level = level; | ||
| } catch (IOException ex) { | ||
| Logger.error(TAG, "Level setting failed! Pin: %d", _pin); | ||
|
|
@@ -155,37 +157,36 @@ public final void removeInputStateListener(InputStateListener listener) { | |
| this.listeners.remove(listener); | ||
| } | ||
|
|
||
| private void executeCommand(String value, String targetFile) throws IOException { | ||
| Logger.info(TAG, "Trying to write \"%s\" to %s", value, targetFile); | ||
| try (BufferedWriter w = new BufferedWriter(new FileWriter(targetFile))) { | ||
| w.append(value); | ||
| w.newLine(); | ||
| w.flush(); | ||
| } | ||
| Logger.info(TAG, "Succeeded!"); | ||
| public static void setWriter(CommandWriter writer) { | ||
|
||
| WRITER = writer; | ||
| } | ||
|
|
||
| public static void setReader(CommandReader reader) { | ||
benedekh marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| READER = reader; | ||
| } | ||
|
|
||
| private class InputStateChangeListenerTask extends TimerTask { | ||
|
|
||
| @Override | ||
| public void run() { | ||
| try { | ||
| try (BufferedReader reader = new BufferedReader(new FileReader(_gpioFolder + "value"))) { | ||
| Level newLevel = reader.readLine().equals("1") ? Level.HIGH : Level.LOW; | ||
| if (!newLevel.equals(_level)) { | ||
| Logger.info(TAG, "Pin state changed! Pin: %d Value: %s", _pin, newLevel.toString()); | ||
| _level = newLevel; | ||
| listeners.stream().forEach((listener) -> { | ||
| try { | ||
| listener.levelStateChanged(_level); | ||
| } catch (Exception ex) { | ||
| Logger.error(TAG, "Error while notifying the InputStateChangeListener (%s)", | ||
| listener.toString()); | ||
| Logger.error(TAG, ex.getMessage()); | ||
| } | ||
| }); | ||
| } | ||
| Level newLvl = READER.getGpioValue(_gpioFolder + "value"); | ||
| // try (BufferedReader reader = new BufferedReader(new FileReader(_gpioFolder + "value"))) { | ||
ecsedigergo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // Level newLevel = reader.readLine().equals("1") ? Level.HIGH : Level.LOW; | ||
ecsedigergo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (newLvl != null && !newLvl.equals(_level)) { | ||
| Logger.info(TAG, "Pin state changed! Pin: %d Value: %s", _pin, newLvl.toString()); | ||
| _level = newLvl; | ||
| listeners.stream().forEach((listener) -> { | ||
| try { | ||
| listener.levelStateChanged(_level); | ||
| } catch (Exception ex) { | ||
| Logger.error(TAG, "Error while notifying the InputStateChangeListener (%s)", | ||
| listener.toString()); | ||
| Logger.error(TAG, ex.getMessage()); | ||
| } | ||
| }); | ||
| } | ||
| // } | ||
ecsedigergo marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| } catch (FileNotFoundException ex) { | ||
| Logger.error(TAG, "InputStateChangeListenerTask is aborted, because pin #%d's value file not found!", | ||
|
|
@@ -195,6 +196,9 @@ public void run() { | |
| Logger.error(TAG, "InputStateChangeListenerTask is aborted, IO error during file read on pin #%d", | ||
| _pin); | ||
| Logger.error(TAG, ex.getMessage()); | ||
| } catch (Exception ex) { | ||
| ex.printStackTrace(); | ||
| Logger.error(TAG, "Something is wrong here: " + ex.getMessage()); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -220,7 +224,7 @@ public final void cleanup() throws IOException, InterruptedException { | |
| _isInputListenerRunning = false; | ||
| Logger.info(TAG, "Listening service for pin #%d stopped.", _pin); | ||
| } | ||
| executeCommand(String.valueOf(_pin), GPIO_BASE_FOLDER + "unexport"); | ||
| WRITER.executeCommand(String.valueOf(_pin), GPIO_BASE_FOLDER + "unexport"); | ||
| } catch (IOException ex) { | ||
| Logger.error(TAG, "Pin unexport failed! Pin: %d", _pin); | ||
| throw ex; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this field static instead of instance level?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the field will be instance-level, then please follow the lowercase naming convention also.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because the GIPO Manager is a Singleton class and I want to set this writer from outside of the manager. So anyway it will have 1 instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But here the Gpio is neither a singleton nor a static-only class. So its methods and fields should be instance level.
That's another question, why is
GpioManagera Singleton class with static-only methods? It should be either singleton or static-only. Mixing the two does not make too much sense.