diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 5f354ae..543aa57 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -7,7 +7,6 @@ on:
- '**/*.md'
branches:
- master
- - release/**
pull_request:
paths-ignore:
- '*.md'
@@ -45,9 +44,21 @@ jobs:
name: codecov-umbrella
fail_ci_if_error: true
- - name: Release
- if: github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/v')
- env:
- GITHUB_PKG_USERNAME: javatmc
- GITHUB_PKG_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: ./gradlew publish
+ # - name: Release
+ # if: github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/v')
+ # env:
+ # GITHUB_PKG_USERNAME: javatmc
+ # GITHUB_PKG_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ # run: ./gradlew publish
+
+ lint:
+ name: Lint
+ runs-on: ubuntu-latest
+ container:
+ image: openjdk:8
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: Checkstyle
+ run: ./gradlew checkstyleMain --info
diff --git a/build.gradle b/build.gradle
index c425f36..28b2d1a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -11,6 +11,7 @@ subprojects {
apply plugin: 'java'
apply plugin: 'maven-publish'
apply plugin: 'jacoco'
+ apply plugin: 'checkstyle'
repositories {
jcenter()
@@ -46,6 +47,14 @@ subprojects {
}
}
+ checkstyle {
+ toolVersion '8.39'
+ sourceSets = []
+ configFile = file("${rootDir}/config/checkstyle/checkstyle.xml")
+ ignoreFailures = false
+ maxWarnings = 0
+ }
+
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
diff --git a/codecov.yml b/codecov.yml
index 7061475..08c8263 100644
--- a/codecov.yml
+++ b/codecov.yml
@@ -9,4 +9,4 @@ coverage:
base: auto
flags:
- unittests
- if_ci_failed: error
\ No newline at end of file
+ if_ci_failed: error
diff --git a/config/checkstyle/checkstyle-suppressions.xml b/config/checkstyle/checkstyle-suppressions.xml
new file mode 100644
index 0000000..0595d59
--- /dev/null
+++ b/config/checkstyle/checkstyle-suppressions.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
new file mode 100644
index 0000000..37c4bbf
--- /dev/null
+++ b/config/checkstyle/checkstyle.xml
@@ -0,0 +1,361 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/measure-apps/src/main/java/org/jtmc/app/BatterySimulator.java b/measure-apps/src/main/java/org/jtmc/app/BatterySimulator.java
index 8ec9cf6..7fa3e93 100644
--- a/measure-apps/src/main/java/org/jtmc/app/BatterySimulator.java
+++ b/measure-apps/src/main/java/org/jtmc/app/BatterySimulator.java
@@ -1,8 +1,9 @@
package org.jtmc.app;
/**
- * BatterySimulator
+ * BatterySimulator is an application used to simulate battery discharge over
+ * time.
*/
public class BatterySimulator {
-
-}
\ No newline at end of file
+
+}
diff --git a/measure-apps/src/main/java/org/jtmc/app/BodePlotter.java b/measure-apps/src/main/java/org/jtmc/app/BodePlotter.java
index 8080bda..8e81ccf 100644
--- a/measure-apps/src/main/java/org/jtmc/app/BodePlotter.java
+++ b/measure-apps/src/main/java/org/jtmc/app/BodePlotter.java
@@ -1,20 +1,21 @@
package org.jtmc.app;
/**
- * BodePlotter
+ * BodePlotter is an application used to plot the amplitude and phase difference
+ * when a device under test is given a stimuli in a range of frequencies.
*/
public class BodePlotter {
- float amplitude;
+ float amplitude;
- float offset;
+ float offset;
- float load;
+ float load;
- float startFrequency;
+ float startFrequency;
- float stopFrequency;
+ float stopFrequency;
- int points;
+ int points;
-}
\ No newline at end of file
+}
diff --git a/measure-apps/src/main/java/org/jtmc/app/DCEfficiency.java b/measure-apps/src/main/java/org/jtmc/app/DCEfficiency.java
index 79b7d8d..fd5dc0b 100644
--- a/measure-apps/src/main/java/org/jtmc/app/DCEfficiency.java
+++ b/measure-apps/src/main/java/org/jtmc/app/DCEfficiency.java
@@ -1,16 +1,17 @@
package org.jtmc.app;
/**
- * DCEfficiency
+ * DCEfficiency is an application to measure the efficiency of a DC Power supply
+ * over the given current range at the set voltage.
*/
public class DCEfficiency {
- double voltage;
+ double voltage;
- double startCurrent;
+ double startCurrent;
- double stopCurrent;
+ double stopCurrent;
- int points;
-
-}
\ No newline at end of file
+ int points;
+
+}
diff --git a/measure-apps/src/main/java/org/jtmc/app/IVPlotter.java b/measure-apps/src/main/java/org/jtmc/app/IVPlotter.java
index 7ae7b28..5104188 100644
--- a/measure-apps/src/main/java/org/jtmc/app/IVPlotter.java
+++ b/measure-apps/src/main/java/org/jtmc/app/IVPlotter.java
@@ -1,9 +1,9 @@
package org.jtmc.app;
/**
- * IVPlotter
+ * IVPlotter is an application used to plot the current under the given voltage
+ * range.
*/
public class IVPlotter {
-
-}
\ No newline at end of file
+}
diff --git a/measure-cli/src/main/java/org/jtmc/cli/JMeasureCLI.java b/measure-cli/src/main/java/org/jtmc/cli/JMeasureCLI.java
index f1ab7d0..124ed65 100644
--- a/measure-cli/src/main/java/org/jtmc/cli/JMeasureCLI.java
+++ b/measure-cli/src/main/java/org/jtmc/cli/JMeasureCLI.java
@@ -2,20 +2,22 @@
import org.jtmc.cli.lxi.LXIDiscover;
import org.jtmc.cli.scpi.SCPISend;
-
import picocli.CommandLine;
import picocli.CommandLine.Command;
+/**
+ * JMeasureCLI provides command line access to instruments.
+ */
@Command(
- subcommands = {
- LXIDiscover.class,
- SCPISend.class
- }
+ subcommands = {
+ LXIDiscover.class,
+ SCPISend.class
+ }
)
public class JMeasureCLI {
- public static void main(String[] args) {
- int exitCode = new CommandLine(new JMeasureCLI()).execute(args);
- System.exit(exitCode);
- }
-}
\ No newline at end of file
+ public static void main(String[] args) {
+ int exitCode = new CommandLine(new JMeasureCLI()).execute(args);
+ System.exit(exitCode);
+ }
+}
diff --git a/measure-cli/src/main/java/org/jtmc/cli/lxi/LXIDiscover.java b/measure-cli/src/main/java/org/jtmc/cli/lxi/LXIDiscover.java
index 409de22..0f66933 100644
--- a/measure-cli/src/main/java/org/jtmc/cli/lxi/LXIDiscover.java
+++ b/measure-cli/src/main/java/org/jtmc/cli/lxi/LXIDiscover.java
@@ -1,5 +1,6 @@
package org.jtmc.cli.lxi;
+import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Collections;
@@ -11,158 +12,196 @@
import java.util.concurrent.Callable;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-
import org.jtmc.core.lxi.LXIDiscovery;
-import org.jtmc.core.lxi.LXIDiscovery.LXIInstrumentEndpoint;
+import org.jtmc.core.lxi.LXIInstrumentEndpoint;
import org.jtmc.core.lxi.mdns.MDNSDiscovery;
import org.jtmc.core.lxi.mdns.MDNSServiceType;
import org.jtmc.core.lxi.vxi11.VXI11Discovery;
-
import picocli.CommandLine.ArgGroup;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
/**
- * LXICommand
+ * LXICommand is used to discover instruments on a network.
*/
@Command(name = "lxi-discover")
public class LXIDiscover implements Callable {
- @Option(
- names = { "--interface", "-i" },
- description = "Network interface to discover on, if not specified then it will broadcast on all interfaces",
- required = false)
- public NetworkInterface networkInterface;
-
- @ArgGroup(exclusive = true)
- public DiscoverySettings discoverySettings;
-
- @Option(names = {"--json"}, description = "Outputs a JSON formatted instrument array", defaultValue = "false")
- public boolean jsonOutput;
-
- @Option(names = {"--no-warnings"}, description = "Disables warnings in the output", defaultValue = "false")
- public boolean noWarnings;
-
- public LXIDiscover() {
- this.discoverySettings = new DiscoverySettings();
- this.discoverySettings.vxi11Settings = new VXI11Settings();
- }
-
- public static class DiscoverySettings {
- @ArgGroup(exclusive = false)
- public VXI11Settings vxi11Settings;
-
- @ArgGroup(exclusive = false)
- public MDNSSettings mdnsSettings;
-
- LXIDiscovery discovery() {
- return vxi11Settings != null ? vxi11Settings.discovery() : mdnsSettings.discovery();
- }
- }
-
- public static class VXI11Settings {
- @Option(names = { "--vxi11" }, description = "Enables VXI-11 based instrument discovery", defaultValue = "true")
- public boolean vxi11DiscoveryEnabled;
-
- @Option(names = {"--vxi11-no-resolve"}, description = "Disables automatic device identification", defaultValue = "false")
- public boolean vxi11noResolve;
-
- @Option(names = {"--vxi11-retransmissions" }, description = "Number of retransmission, useful when using unreliable connection", defaultValue = "1")
- public int vxi11retransmissions;
-
- @Option(names = {"--vxi11-timeout" }, description = "Specify the timeout of a response in milliseconds", defaultValue = "1000")
- public int vxi11timeout;
-
- public VXI11Settings() {
- this.vxi11DiscoveryEnabled = true;
- this.vxi11noResolve = false;
- this.vxi11retransmissions = 1;
- this.vxi11timeout = 1000;
- }
-
- LXIDiscovery discovery() {
- return new VXI11Discovery(!vxi11noResolve, vxi11retransmissions, vxi11timeout);
- }
- }
-
- public static class MDNSSettings {
- @Option(names = { "--mdns" }, description = "Enables mDNS based instrument discovery", defaultValue = "false")
- public boolean mdnsDiscoveryEnabled;
-
- @Option(names = { "--mdns-services" }, description = "Specify mDNS service types to search")
- public List mdnsServiceTypes = Collections.singletonList(MDNSServiceType.LXI);
-
- LXIDiscovery discovery() {
- return new MDNSDiscovery(mdnsServiceTypes);
- }
- }
-
- @Override
- public Integer call() throws Exception {
- //Collecting network interfaces to discover on
- Stream interfaces;
- if (networkInterface == null) {
- // Not using NetworkInterface.networkInterfaces() as it's only introduced in
- // Java 9
- List interfaceList = new LinkedList<>();
- Enumeration interfaceEnumeration = NetworkInterface.getNetworkInterfaces();
- while (interfaceEnumeration.hasMoreElements()) {
- interfaceList.add(interfaceEnumeration.nextElement());
- }
- interfaces = interfaceList.stream();
- } else {
- interfaces = Collections.singletonList(networkInterface).stream();
- }
-
- //Running discovery tool
- LXIDiscovery discoveryTool = discoverySettings.discovery();
- List warnings = new ArrayList<>();
- Set instruments = interfaces.flatMap(i -> {
- try {
- return discoveryTool.discover(i).stream();
- } catch (Exception e) {
- if(!noWarnings) {
- warnings.add("Warning " + e.getClass() + ":" + e.getMessage());
- }
- return Collections.emptySet().stream();
- }
- }).collect(Collectors.toCollection(HashSet::new));
-
- //Printing out the result
- if(jsonOutput) {
- ObjectMapper mapper = new ObjectMapper();
- InstrumentListJSON json = new InstrumentListJSON(instruments, warnings);
- mapper.writeValue(System.out, json);
- }
- else {
- instruments.forEach(endpoint -> {
- System.out.println("Found " + endpoint.getDeviceIdentifier().value() + " at " + endpoint.getHost() + ":" + endpoint.getPort() + " ("+endpoint.getClass().getSimpleName()+")");
- });
- warnings.forEach(warning -> {
- System.out.println(warning);
- });
- }
- return 0;
- }
-
- public static class InstrumentListJSON {
- Set instruments;
-
- List warnings;
-
- public InstrumentListJSON(Set instruments, List warnings) {
- this.instruments = instruments;
- this.warnings = warnings;
- }
-
- public Set getInstruments() {
- return instruments;
- }
-
- public List getWarnings() {
- return warnings;
- }
- }
-}
\ No newline at end of file
+ @Option(
+ names = { "--interface", "-i" },
+ description = "Network interface to run discovery on, "
+ + "if not specified then it will broadcast on all interfaces",
+ required = false)
+ public NetworkInterface networkInterface;
+
+ @ArgGroup(exclusive = true)
+ public DiscoverySettings discoverySettings;
+
+ @Option(
+ names = {"--json"},
+ description = "Outputs a JSON formatted instrument array",
+ defaultValue = "false")
+ public boolean jsonOutput;
+
+ @Option(
+ names = {"--no-warnings"},
+ description = "Disables warnings in the output",
+ defaultValue = "false")
+ public boolean noWarnings;
+
+ public LXIDiscover() {
+ this.discoverySettings = new DiscoverySettings();
+ this.discoverySettings.vxi11Settings = new VXI11Settings();
+ }
+
+ /**
+ * DiscoverySettings holds the possible discovery methods.
+ */
+ public static class DiscoverySettings {
+ @ArgGroup(exclusive = false)
+ public VXI11Settings vxi11Settings;
+
+ @ArgGroup(exclusive = false)
+ public MDNSSettings mdnsSettings;
+
+ LXIDiscovery discovery() {
+ return vxi11Settings != null ? vxi11Settings.discovery() : mdnsSettings.discovery();
+ }
+ }
+
+ /**
+ * VXI11Settings holds the options for VXI11 based instrument discovery.
+ */
+ public static class VXI11Settings {
+ @Option(
+ names = { "--vxi11" },
+ description = "Enables VXI-11 based instrument discovery",
+ defaultValue = "true")
+ public boolean vxi11DiscoveryEnabled;
+
+ @Option(
+ names = {"--vxi11-no-resolve"},
+ description = "Disables automatic device identification",
+ defaultValue = "false")
+ public boolean vxi11noResolve;
+
+ @Option(
+ names = {"--vxi11-retransmissions" },
+ description = "Number of retransmission, useful when using unreliable connection",
+ defaultValue = "1")
+ public int vxi11retransmissions;
+
+ @Option(
+ names = {"--vxi11-timeout" },
+ description = "Specify the timeout of a response in milliseconds",
+ defaultValue = "1000")
+ public int vxi11timeout;
+
+ VXI11Settings() {
+ this.vxi11DiscoveryEnabled = true;
+ this.vxi11noResolve = false;
+ this.vxi11retransmissions = 1;
+ this.vxi11timeout = 1000;
+ }
+
+ LXIDiscovery discovery() {
+ return new VXI11Discovery(!vxi11noResolve, vxi11retransmissions, vxi11timeout);
+ }
+ }
+
+ /**
+ * MDNSSettings holds the options for mDNS based instrument discovery.
+ */
+ public static class MDNSSettings {
+ @Option(
+ names = { "--mdns" },
+ description = "Enables mDNS based instrument discovery",
+ defaultValue = "false")
+ public boolean mdnsDiscoveryEnabled;
+
+ @Option(
+ names = { "--mdns-services" },
+ description = "Specify mDNS service types to search")
+ public List mdnsServiceTypes = Collections.singletonList(MDNSServiceType.LXI);
+
+ LXIDiscovery discovery() {
+ return new MDNSDiscovery(mdnsServiceTypes);
+ }
+ }
+
+ @Override
+ public Integer call() throws Exception {
+ //Collecting network interfaces to discover on
+ Stream interfaces;
+ if (networkInterface == null) {
+ // Not using NetworkInterface.networkInterfaces() as it's only introduced in
+ // Java 9
+ List interfaceList = new LinkedList<>();
+ Enumeration interfaceEnumeration = NetworkInterface.getNetworkInterfaces();
+ while (interfaceEnumeration.hasMoreElements()) {
+ interfaceList.add(interfaceEnumeration.nextElement());
+ }
+ interfaces = interfaceList.stream();
+ } else {
+ interfaces = Collections.singletonList(networkInterface).stream();
+ }
+
+ //Running discovery tool
+ LXIDiscovery discoveryTool = discoverySettings.discovery();
+ List warnings = new ArrayList<>();
+ Set instruments = interfaces.flatMap(i -> {
+ try {
+ return discoveryTool.discover(i).stream();
+ } catch (Exception e) {
+ if (!noWarnings) {
+ warnings.add("Warning " + e.getClass() + ":" + e.getMessage());
+ }
+ return Collections.emptySet().stream();
+ }
+ }).collect(Collectors.toCollection(HashSet::new));
+
+ //Printing out the result
+ if (jsonOutput) {
+ ObjectMapper mapper = new ObjectMapper();
+ InstrumentListJSON json = new InstrumentListJSON(instruments, warnings);
+ mapper.writeValue(System.out, json);
+ } else {
+ instruments.forEach(endpoint -> {
+ System.out.printf("Found %s at %s:%g (%s)",
+ endpoint.getDeviceIdentifier().value(),
+ endpoint.getHost(),
+ endpoint.getPort(),
+ endpoint.getClass().getSimpleName());
+ });
+ warnings.forEach(warning -> {
+ System.out.println(warning);
+ });
+ }
+ return 0;
+ }
+
+ /**
+ * InstrumentListJSON is a container for instrument discovery result.
+ */
+ public static class InstrumentListJSON {
+
+ Set instruments;
+
+ List warnings;
+
+ public InstrumentListJSON(Set instruments, List warnings) {
+ this.instruments = instruments;
+ this.warnings = warnings;
+ }
+
+ public Set getInstruments() {
+ return instruments;
+ }
+
+ public List getWarnings() {
+ return warnings;
+ }
+
+ }
+
+}
diff --git a/measure-cli/src/main/java/org/jtmc/cli/scpi/SCPISend.java b/measure-cli/src/main/java/org/jtmc/cli/scpi/SCPISend.java
index c5addfb..f6c02bb 100644
--- a/measure-cli/src/main/java/org/jtmc/cli/scpi/SCPISend.java
+++ b/measure-cli/src/main/java/org/jtmc/cli/scpi/SCPISend.java
@@ -3,35 +3,49 @@
import java.io.File;
import java.util.List;
import java.util.concurrent.Callable;
-
import org.jtmc.cli.visa.VISASocketOption;
-
+import org.jtmc.core.device.ISocket;
+import org.jtmc.core.scpi.SCPICommand;
+import org.jtmc.core.scpi.socket.RawSCPISocket;
import picocli.CommandLine.ArgGroup;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
+/**
+ * SCPISend is a command that can be used to send SCPI commands to instruments.
+ */
@Command(name = "scpi-send")
public class SCPISend implements Callable {
-
- @ArgGroup(exclusive = true)
- Input input;
-
- @ArgGroup(exclusive = true)
- VISASocketOption socketOption;
-
- class Input {
- @Option(names = {"--commands", "-c"}, required = false)
- List commands;
-
- @Option(names = {"--script"}, required = false)
- File script;
-
- @Option(names = {"--interactive", "-i"}, required = true)
- boolean interactive;
- }
-
- @Override
- public Integer call() throws Exception {
- return 1;
- }
-}
\ No newline at end of file
+
+ @ArgGroup(exclusive = true)
+ Input input;
+
+ @ArgGroup(exclusive = true)
+ VISASocketOption socketOption;
+
+ static class Input {
+ @Option(names = {"--commands", "-c"}, required = false)
+ List commands;
+
+ @Option(names = {"--script"}, required = false)
+ File script;
+
+ @Option(names = {"--interactive", "-i"}, required = true)
+ boolean interactive;
+ }
+
+ @Override
+ public Integer call() throws Exception {
+ try (ISocket socket = socketOption.getSocket()) {
+ RawSCPISocket scpiSocket = new RawSCPISocket(socket);
+ for (String command : input.commands) {
+ SCPICommand scpiCommand = new SCPICommand(command);
+ scpiSocket.send(scpiCommand);
+ if (scpiCommand.isQuery()) {
+ System.out.println(scpiSocket.receive(1000));
+ }
+ }
+ return 0;
+ }
+ }
+}
diff --git a/measure-cli/src/main/java/org/jtmc/cli/visa/RawSocketOption.java b/measure-cli/src/main/java/org/jtmc/cli/visa/RawSocketOption.java
index 3a0cf73..45aae1a 100644
--- a/measure-cli/src/main/java/org/jtmc/cli/visa/RawSocketOption.java
+++ b/measure-cli/src/main/java/org/jtmc/cli/visa/RawSocketOption.java
@@ -1,24 +1,25 @@
package org.jtmc.cli.visa;
import java.io.IOException;
-
import org.jtmc.core.lxi.raw.RawSocket;
-
import picocli.CommandLine.Option;
+/**
+ * RawSocketOptions holds the arguments of a RawSocket.
+ */
public class RawSocketOption {
- @Option(names = { "--raw-host" }, required = true)
- String host;
+ @Option(names = { "--raw-host" }, required = true)
+ String host;
- @Option(names = { "--raw-port" }, required = true)
- int port;
+ @Option(names = { "--raw-port" }, required = true)
+ int port;
- @Option(names = { "--raw-board" }, defaultValue = "0")
- int board;
+ @Option(names = { "--raw-board" }, defaultValue = "0")
+ int board;
- public RawSocket getSocket() throws IOException {
- return new RawSocket(host, port, board);
- }
+ public RawSocket getSocket() throws IOException {
+ return new RawSocket(host, port, board);
+ }
-}
\ No newline at end of file
+}
diff --git a/measure-cli/src/main/java/org/jtmc/cli/visa/SerialSocketOption.java b/measure-cli/src/main/java/org/jtmc/cli/visa/SerialSocketOption.java
index 9b5cfe1..49c7ed8 100644
--- a/measure-cli/src/main/java/org/jtmc/cli/visa/SerialSocketOption.java
+++ b/measure-cli/src/main/java/org/jtmc/cli/visa/SerialSocketOption.java
@@ -1,38 +1,54 @@
package org.jtmc.cli.visa;
import java.io.IOException;
-
import org.jtmc.core.serial.FlowControl;
import org.jtmc.core.serial.Parity;
import org.jtmc.core.serial.SerialSocket;
import org.jtmc.core.serial.StopBits;
-
import picocli.CommandLine.ArgGroup;
import picocli.CommandLine.Option;
+/**
+ * SerialSocketOption holds the arguments of a SerialSocket.
+ */
public class SerialSocketOption {
- @Option(names = { "--serial-port" })
- String port;
-
- @ArgGroup(exclusive = false)
- SerialSocketDetailedConfiguration socket;
-
- public SerialSocket getSocket() throws IOException {
- return new SerialSocket(port, socket.baudrate, socket.databits, socket.parity, socket.stopbits, FlowControl.NONE);
- }
-
- public static class SerialSocketDetailedConfiguration {
- @Option(names = {"--serial-baudrate"}, defaultValue = "9600")
- int baudrate;
-
- @Option(names = {"--serial-databits"}, defaultValue = "8")
- int databits;
-
- @Option(names = {"--serial-parity"}, defaultValue = "NONE")
- Parity parity;
-
- @Option(names = {"--serial-stopbits"}, defaultValue = "1")
- StopBits stopbits;
-
- }
-}
\ No newline at end of file
+ @Option(names = { "--serial-port" })
+ String port;
+
+ @ArgGroup(exclusive = false)
+ SerialSocketDetailedConfiguration socket;
+
+ /**
+ * Returns the configured Serial socket.
+ * @return Serial socket
+ * @throws IOException if there was an error opening the socket
+ */
+ public SerialSocket getSocket() throws IOException {
+ return new SerialSocket(
+ port,
+ socket.baudrate,
+ socket.databits,
+ socket.parity,
+ socket.stopbits,
+ FlowControl.NONE);
+ }
+
+ /**
+ * SerialSocketDetailedConfiguration is an argument group that allows configuring
+ * the SerialSocket's options individually.
+ */
+ public static class SerialSocketDetailedConfiguration {
+ @Option(names = {"--serial-baudrate"}, defaultValue = "9600")
+ int baudrate;
+
+ @Option(names = {"--serial-databits"}, defaultValue = "8")
+ int databits;
+
+ @Option(names = {"--serial-parity"}, defaultValue = "NONE")
+ Parity parity;
+
+ @Option(names = {"--serial-stopbits"}, defaultValue = "1")
+ StopBits stopbits;
+
+ }
+}
diff --git a/measure-cli/src/main/java/org/jtmc/cli/visa/VISASocketOption.java b/measure-cli/src/main/java/org/jtmc/cli/visa/VISASocketOption.java
index 2752808..a39d83b 100644
--- a/measure-cli/src/main/java/org/jtmc/cli/visa/VISASocketOption.java
+++ b/measure-cli/src/main/java/org/jtmc/cli/visa/VISASocketOption.java
@@ -1,17 +1,41 @@
package org.jtmc.cli.visa;
+import java.io.IOException;
+import org.jtmc.core.device.ISocket;
import picocli.CommandLine.ArgGroup;
import picocli.CommandLine.Option;
+/**
+ * VISASocketOption is a composite argument group that holds the underlying
+ * socket implementations' options.
+ */
public class VISASocketOption {
- @ArgGroup(exclusive = false)
- RawSocketOption rawSocket;
-
- @ArgGroup(exclusive = false)
- SerialSocketOption serialSocket;
+ @ArgGroup(exclusive = false)
+ RawSocketOption rawSocket;
- @Option(names = {"--resource"})
- String resourceString;
-
-}
\ No newline at end of file
+ @ArgGroup(exclusive = false)
+ SerialSocketOption serialSocket;
+
+ @ArgGroup(exclusive = false)
+ VXI11SocketOption vxi11Socket;
+
+ @Option(names = { "--resource" })
+ String resourceString;
+
+ /**
+ * Returns the underlying socket implementation.
+ * @return Socket
+ * @throws IOException if there was an error opening the socket
+ */
+ public ISocket getSocket() throws IOException {
+ if (rawSocket != null) {
+ return rawSocket.getSocket();
+ } else if (serialSocket != null) {
+ return serialSocket.getSocket();
+ } else if (vxi11Socket != null) {
+ return vxi11Socket.getSocket();
+ }
+ return null;
+ }
+}
diff --git a/measure-cli/src/main/java/org/jtmc/cli/visa/VXI11SocketOption.java b/measure-cli/src/main/java/org/jtmc/cli/visa/VXI11SocketOption.java
index 4836e79..81580d6 100644
--- a/measure-cli/src/main/java/org/jtmc/cli/visa/VXI11SocketOption.java
+++ b/measure-cli/src/main/java/org/jtmc/cli/visa/VXI11SocketOption.java
@@ -2,35 +2,36 @@
import java.io.IOException;
import java.net.InetAddress;
-
import org.jtmc.core.lxi.vxi11.VXI11Socket;
-
import picocli.CommandLine.Option;
+/**
+ * VXI11SocketOption holds the arguments of a VXI11Socket.
+ */
public class VXI11SocketOption {
- @Option(names = { "--vxi11-host" }, required = true)
- InetAddress host;
+ @Option(names = { "--vxi11-host" }, required = true)
+ InetAddress host;
- @Option(names = { "--vxi11-port" }, defaultValue = "0")
- int port;
+ @Option(names = { "--vxi11-port" }, defaultValue = "0")
+ int port;
- @Option(names = { "--vxi11-name" }, defaultValue = "inst0")
- String name;
+ @Option(names = { "--vxi11-name" }, defaultValue = "inst0")
+ String name;
- @Option(names = {"--vxi11-lock"}, defaultValue = "false")
- boolean lock;
+ @Option(names = {"--vxi11-lock"}, defaultValue = "false")
+ boolean lock;
- @Option(names = {"--vxi1-lock-timeout"}, defaultValue = "0")
- int lockTimeout;
+ @Option(names = {"--vxi1-lock-timeout"}, defaultValue = "0")
+ int lockTimeout;
- @Option(names = {"--vxi1-io-timeout"}, defaultValue = "0")
- int ioTimeout;
+ @Option(names = {"--vxi1-io-timeout"}, defaultValue = "0")
+ int ioTimeout;
- @Option(names = {"--vxi1-write-block-size"}, defaultValue = "8128")
- int writeBlockSize;
+ @Option(names = {"--vxi1-write-block-size"}, defaultValue = "8128")
+ int writeBlockSize;
- public VXI11Socket getSocket() throws IOException {
- return new VXI11Socket(host, name, port, lock, lockTimeout, ioTimeout, writeBlockSize);
- }
-}
\ No newline at end of file
+ public VXI11Socket getSocket() throws IOException {
+ return new VXI11Socket(host, name, port, lock, lockTimeout, ioTimeout, writeBlockSize);
+ }
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/device/Connectable.java b/measure-core/src/main/java/org/jtmc/core/device/Connectable.java
index 0f618fa..322ab3c 100644
--- a/measure-core/src/main/java/org/jtmc/core/device/Connectable.java
+++ b/measure-core/src/main/java/org/jtmc/core/device/Connectable.java
@@ -1,23 +1,25 @@
package org.jtmc.core.device;
/**
- * Connectable is any device that has a binary state of connection, either connected or disconnected
+ * Connectable is any device that has a binary state of connection,
+ * either connected or disconnected.
*/
public interface Connectable extends AutoCloseable {
- /**
- * Returns whether or not the device is connected
- *
- * @return {@code true} if the device is connected
- */
- public boolean isConnected();
+ /**
+ * Returns whether or not the device is connected.
+ *
+ * @return {@code true} if the device is connected
+ */
+ public boolean isConnected();
- /**
- * Disconnects the device
- *
- *
This operation should be idempotent, meaning that calling it
- * multiple times shouldn't affect the state of the connection beyond the first call
- */
- @Override
- public void close();
-}
\ No newline at end of file
+ /**
+ * Disconnects the device.
+ *
+ *
This operation should be idempotent, meaning that calling it
+ * multiple times shouldn't affect the state of the connection beyond
+ * the first call
+ */
+ @Override
+ public void close();
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/device/ISocket.java b/measure-core/src/main/java/org/jtmc/core/device/ISocket.java
index 82adbba..10fbbd6 100644
--- a/measure-core/src/main/java/org/jtmc/core/device/ISocket.java
+++ b/measure-core/src/main/java/org/jtmc/core/device/ISocket.java
@@ -5,47 +5,50 @@
import java.nio.ByteBuffer;
/**
- * ISocket is a connectable socket that's capable of transmitting and receiving byte streams
+ * ISocket is a connectable socket that's capable of transmitting and receiving byte streams.
*/
public interface ISocket extends Connectable {
- /**
- * Transmits the given message to the device
- *
- * @param message Message as a byte buffer
- * @throws IOException if there was an error sending the message
- */
- void send(final ByteBuffer message) throws IOException;
+ /**
+ * Transmits the given message to the device.
+ *
+ * @param message Message as a byte buffer
+ * @throws IOException if there was an error sending the message
+ */
+ void send(final ByteBuffer message) throws IOException;
- /**
- * Receives a message from the device until the given byte count has been reached
- *
- * @param count Message's length
- * @param timeout Maximum time to wait for the given number of bytes to be received
- * @return Message as a byte buffer
- * @throws IOException If there was an error during reception
- * @throws TimeoutException If the timeout has been reached
- */
- ByteBuffer receive(final int count, final long timeout) throws IOException, SocketTimeoutException;
+ /**
+ * Receives a message from the device until the given byte count has been reached.
+ *
+ * @param count Message's length
+ * @param timeout Maximum time to wait for the given number of bytes to be received
+ * @return Message as a byte buffer
+ * @throws IOException If there was an error during reception
+ * @throws TimeoutException If the timeout has been reached
+ */
+ ByteBuffer receive(
+ final int count,
+ final long timeout) throws IOException, SocketTimeoutException;
- /**
- * Receives a message from the device until the given character has been reached
- *
- * @param termination Termination character, like '\n'
- * @param timeout Maximum time to wait for the given character to be reached
- * @return Message as a byte buffer
- * @throws IOException If there was an error during reception
- * @throws TimeoutException If the timeout has been reached
- */
- ByteBuffer receive(final char termination, final long timeout) throws IOException, SocketTimeoutException;
-
- /**
- * Returns the VISA resource string associated with this socket instance
- *
- *
Using the returned the String the Socket factory must be able to recreate the connection
- * (or there should be at least 1 public constructor with a single String parameter)
- *
- * @return VISA Resource string
- */
- public String getResourceString();
-}
\ No newline at end of file
+ /**
+ * Receives a message from the device until the given character has been reached.
+ *
+ * @param termination Termination character, like '\n'
+ * @param timeout Maximum time to wait for the given character to be reached
+ * @return Message as a byte buffer
+ * @throws IOException If there was an error during reception
+ * @throws TimeoutException If the timeout has been reached
+ */
+ ByteBuffer receive(
+ final char termination, final long timeout) throws IOException, SocketTimeoutException;
+
+ /**
+ * Returns the VISA resource string associated with this socket instance.
+ *
+ *
Using the returned the String the Socket factory must be able to recreate the connection
+ * (or there should be at least 1 public constructor with a single String parameter)
+ *
+ * @return VISA Resource string
+ */
+ public String getResourceString();
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/instrument/DCPowerSupply.java b/measure-core/src/main/java/org/jtmc/core/instrument/DCPowerSupply.java
index 80b8c32..07364cf 100644
--- a/measure-core/src/main/java/org/jtmc/core/instrument/DCPowerSupply.java
+++ b/measure-core/src/main/java/org/jtmc/core/instrument/DCPowerSupply.java
@@ -3,37 +3,85 @@
import java.util.Collection;
/**
- * A DC power supply is a device capable of outputting a set voltage or a set current
+ * A DC power supply is a device capable of outputting a set voltage
+ * or a set current.
*
* @author Balazs Eszes
*/
public interface DCPowerSupply {
- Collection getPowerOutputs();
+ Collection getPowerOutputs();
- default PowerOutput getPowerOutput(int index) {
- return this.getPowerOutputs().stream().skip(index).findFirst().get();
- }
+ /**
+ * Returns the power output at the given index.
+ *
+ * @param index Output index (zero indexed)
+ * @return Power output
+ */
+ default PowerOutput getPowerOutput(int index) {
+ return this.getPowerOutputs().stream().skip(index).findFirst().get();
+ }
- default PowerOutput getPowerOutput(String name) {
- return this.getPowerOutputs().stream().filter(channel -> channel.getName().equals(name)).findFirst().get();
- }
+ /**
+ * Returns the power output with the given name.
+ *
+ * @param name Output name
+ * @return Power output
+ */
+ default PowerOutput getPowerOutput(String name) {
+ return this.getPowerOutputs()
+ .stream()
+ .filter(channel -> channel.getName().equals(name))
+ .findFirst()
+ .get();
+ }
- public static interface PowerOutput {
- String getName();
+ /**
+ * PowerOutput is used to represent a hardware output capable to sourcing and
+ * optionally sinking current.
+ */
+ public static interface PowerOutput {
+ /**
+ * Returns the human readable name of the output.
+ *
+ * @return Power output name
+ */
+ String getName();
- void setEnabled(boolean enabled);
+ /**
+ * Enables or disables the power output.
+ *
+ * @param enabled if {@code true} the output is enabled
+ */
+ void setEnabled(boolean enabled);
- void setMaximumVoltage(double voltage);
+ /**
+ * Sets the maximum voltage the channel tries to output also known
+ * as 'Set voltage'.
+ *
+ * @param voltage Set voltage
+ */
+ void setMaximumVoltage(double voltage);
- double getMaximumVoltage();
+ double getMaximumVoltage();
- void setMaximumCurrent(double current);
+ void setMaximumCurrent(double current);
- double getMaximumCurrent();
+ double getMaximumCurrent();
- double getVoltage();
+ /**
+ * Returns the voltage currently output by the power output.
+ *
+ * @return Output voltage
+ */
+ double getVoltage();
- double getCurrent();
- }
-}
\ No newline at end of file
+ /**
+ * Return the current (amperes) currently output by the power output.
+ *
+ * @return Output amperes
+ */
+ double getCurrent();
+ }
+
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/instrument/FunctionGenerator.java b/measure-core/src/main/java/org/jtmc/core/instrument/FunctionGenerator.java
index 0d48531..42878aa 100644
--- a/measure-core/src/main/java/org/jtmc/core/instrument/FunctionGenerator.java
+++ b/measure-core/src/main/java/org/jtmc/core/instrument/FunctionGenerator.java
@@ -1,58 +1,70 @@
package org.jtmc.core.instrument;
import java.util.Collection;
-
import org.jtmc.core.visa.exception.InstrumentException;
/**
- * A waveform generator is a device capable of outputting a changing voltage signal
+ * A waveform generator is a device capable of outputting a changing voltage signal.
*
* @author Balazs Eszes
*/
public interface FunctionGenerator {
- Collection getAnalogOutputs();
+ Collection getAnalogOutputs();
- public static interface AnalogOutput {
- String getName();
+ /**
+ * AnalogOutput represents a physical output.
+ */
+ public static interface AnalogOutput {
+ String getName();
- void setEnabled(boolean enabled) throws InstrumentException;
+ void setEnabled(boolean enabled) throws InstrumentException;
- void setOperationMode(OperationMode operationMode) throws InstrumentException;
+ void setOperationMode(OperationMode operationMode) throws InstrumentException;
- void setImpedance(double impedance) throws InstrumentException;
+ void setImpedance(double impedance) throws InstrumentException;
- // Commons
+ // Commons
- void setAmplitude(double amplitude) throws InstrumentException;
+ void setAmplitude(double amplitude) throws InstrumentException;
- void setOffset(double offset) throws InstrumentException;
+ void setOffset(double offset) throws InstrumentException;
- void setFrequency(double frequency) throws InstrumentException;
+ void setFrequency(double frequency) throws InstrumentException;
- void setPhase(double phase) throws InstrumentException;
+ void setPhase(double phase) throws InstrumentException;
- // Builtin
+ void setWaveformType(WaveformType waveformType) throws InstrumentException;
- void setWaveformType(WaveformType waveformType) throws InstrumentException;
+ default void setWaveform(
+ WaveformType waveformType,
+ double amplitude,
+ double offset,
+ double frequency,
+ double phase) throws InstrumentException {
+
+ }
- default void setWaveform(WaveformType waveformType, double amplitude, double offset, double frequency, double phase) throws InstrumentException {
-
- }
+ // Arbitrary
- // Arbitrary
+ //void setWaveform();
- //void setWaveform();
+ //void setSampleRate();
- //void setSampleRate();
+ }
- }
+ /**
+ * Waveform types supported by most Function generators.
+ */
+ public static enum WaveformType {
+ SINE, SQUARE, TRIANGLE, RAMPUP, RAMPDOWN, DC, NOISE
+ }
- public static enum WaveformType {
- SINE, SQUARE, TRIANGLE, RAMPUP, RAMPDOWN, DC, NOISE
- }
+ /**
+ * Operation modes.
+ */
+ public static enum OperationMode {
+ CONTINUOUS, BURST
+ }
- public static enum OperationMode {
- CONTINUOUS, BURST
- }
-}
\ No newline at end of file
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/instrument/LogicAnalyzer.java b/measure-core/src/main/java/org/jtmc/core/instrument/LogicAnalyzer.java
index 3b253b5..6d31d3d 100644
--- a/measure-core/src/main/java/org/jtmc/core/instrument/LogicAnalyzer.java
+++ b/measure-core/src/main/java/org/jtmc/core/instrument/LogicAnalyzer.java
@@ -4,35 +4,48 @@
/**
* A logic analyzer is a device capable of making binary signal measurements
- * over time
+ * over time.
*
* @author Balazs Eszes
*/
public interface LogicAnalyzer extends TimeDomainAnalyzer {
- public final static double TTL = 1.5f;
+ public static final double TTL = 1.5f;
- public final static double CMOS = 1.65f;
+ public static final double CMOS = 1.65f;
- public final static double LVCMOS3V3 = 1.65f;
+ public static final double LVCMOS3V3 = 1.65f;
- public final static double LVCMOS2V5 = 1.25f;
+ public static final double LVCMOS2V5 = 1.25f;
- Collection getDigitalInputs();
+ Collection getDigitalInputs();
- default DigitalInput getDigitalInput(int index) {
- return this.getDigitalInputs().stream().skip(index).findFirst().get();
- }
+ default DigitalInput getDigitalInput(int index) {
+ return this.getDigitalInputs().stream().skip(index).findFirst().get();
+ }
- default DigitalInput getDigitalInput(String name) {
- return this.getDigitalInputs().stream().filter(channel -> channel.getName().equals(name)).findFirst().get();
- }
+ /**
+ * Returns the digital input with the matching name.
+ * @param name Input name
+ * @return Digital Input
+ */
+ default DigitalInput getDigitalInput(String name) {
+ return this.getDigitalInputs()
+ .stream()
+ .filter(channel -> channel.getName()
+ .equals(name))
+ .findFirst()
+ .get();
+ }
- public static interface DigitalInput {
- String getName();
+ /**
+ * DigitalInput represents a physical input recording logical values.
+ */
+ public static interface DigitalInput {
+ String getName();
- void setEnabled(boolean enabled);
+ void setEnabled(boolean enabled);
- void setThreshold(double threshold);
- }
-}
\ No newline at end of file
+ void setThreshold(double threshold);
+ }
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/instrument/Oscilloscope.java b/measure-core/src/main/java/org/jtmc/core/instrument/Oscilloscope.java
index 46e3bfb..c98917e 100644
--- a/measure-core/src/main/java/org/jtmc/core/instrument/Oscilloscope.java
+++ b/measure-core/src/main/java/org/jtmc/core/instrument/Oscilloscope.java
@@ -1,51 +1,60 @@
package org.jtmc.core.instrument;
+import java.util.Collection;
+import java.util.Optional;
import org.jtmc.core.instrument.common.Coupling;
import org.jtmc.core.signal.analog.AnalogSignal;
import org.jtmc.core.visa.exception.InstrumentException;
-import java.util.Collection;
-import java.util.Optional;
-
/**
- * An oscilloscope is a device capable of making voltage measurements over time
+ * An oscilloscope is a device capable of making voltage measurements over time.
*
* @author Balazs Eszes
*/
public interface Oscilloscope extends TimeDomainAnalyzer {
- Collection getAnalogInputs();
-
- default AnalogInput getAnalogInput(int index) {
- return this.getAnalogInputs().stream().skip(index).findFirst().get();
- }
+ Collection getAnalogInputs();
- default AnalogInput getAnalogInput(String name) {
- return this.getAnalogInputs().stream().filter(channel -> channel.getName().equals(name)).findFirst().get();
- }
+ default AnalogInput getAnalogInput(int index) {
+ return this.getAnalogInputs().stream().skip(index).findFirst().get();
+ }
- public static interface AnalogInput {
- String getName();
+ /**
+ * Returns the analog input with the matching name.
+ * @param name Input name
+ * @return Analog Input
+ */
+ default AnalogInput getAnalogInput(String name) {
+ return this.getAnalogInputs()
+ .stream()
+ .filter(channel -> channel.getName().equals(name))
+ .findFirst()
+ .get();
+ }
- void setEnabled(boolean enabled) throws InstrumentException;
+ /**
+ * AnalogInput represents a physical input recording numerical values.
+ */
+ public static interface AnalogInput {
+ String getName();
- void setRange(double range) throws InstrumentException;
+ void setEnabled(boolean enabled) throws InstrumentException;
- void setOffset(double offset) throws InstrumentException;
+ void setRange(double range) throws InstrumentException;
- void setProbeAttenuation(double attenuation) throws InstrumentException;
+ void setOffset(double offset) throws InstrumentException;
- void setProbeSense(boolean enable) throws InstrumentException;
+ void setProbeAttenuation(double attenuation) throws InstrumentException;
- void setImpedance(double impedance) throws InstrumentException;
+ void setProbeSense(boolean enable) throws InstrumentException;
- void setBandwidthLimit(double bandwidthLimit) throws InstrumentException;
+ void setImpedance(double impedance) throws InstrumentException;
- void setCoupling(Coupling coupling) throws InstrumentException;
+ void setBandwidthLimit(double bandwidthLimit) throws InstrumentException;
- Optional getAnalogInputSignal(int channel) throws InstrumentException;
- }
+ void setCoupling(Coupling coupling) throws InstrumentException;
- //Supplier<>
+ Optional getAnalogInputSignal(int channel) throws InstrumentException;
+ }
-}
\ No newline at end of file
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/instrument/TimeDomainAnalyzer.java b/measure-core/src/main/java/org/jtmc/core/instrument/TimeDomainAnalyzer.java
index e248dc7..e2929f7 100644
--- a/measure-core/src/main/java/org/jtmc/core/instrument/TimeDomainAnalyzer.java
+++ b/measure-core/src/main/java/org/jtmc/core/instrument/TimeDomainAnalyzer.java
@@ -3,43 +3,56 @@
import org.jtmc.core.visa.exception.InstrumentException;
/**
- * TimeDomainAnalyzer is any device capable of time correlated measurements
+ * TimeDomainAnalyzer is any device capable of time correlated measurements.
*
* @author Balazs Eszes
*/
public interface TimeDomainAnalyzer {
- //TODO: move to trigger subsystem
- void setRunState(RunState state) throws InstrumentException;
+ //TODO: move to trigger subsystem
+ void setRunState(RunState state) throws InstrumentException;
- public static enum RunState {
- AUTO, NORMAL, SINGLE, STOP;
- }
+ /**
+ * RunState represents the method which is used to trigger an acquisition.
+ */
+ public static enum RunState {
+ AUTO, NORMAL, SINGLE, STOP;
+ }
- AcquisitionBaseSystem acquisition();
+ AcquisitionBaseSystem acquisition();
- public static interface AcquisitionBaseSystem {
+ /**
+ * AcquisitionBaseSystem controls how time correlated measurements are made.
+ */
+ public static interface AcquisitionBaseSystem {
- void setTimespan(double span) throws InstrumentException;
+ void setTimespan(double span) throws InstrumentException;
- void setSampleCount(long count) throws InstrumentException;
+ void setSampleCount(long count) throws InstrumentException;
- long getSampleCount() throws InstrumentException;
+ long getSampleCount() throws InstrumentException;
- double getSampleRate() throws InstrumentException;
+ double getSampleRate() throws InstrumentException;
- void setTimeOffset(double offset) throws InstrumentException;
-
- void setMode(AcquisitionMode mode) throws InstrumentException;
+ void setTimeOffset(double offset) throws InstrumentException;
+
+ void setMode(AcquisitionMode mode) throws InstrumentException;
- public static enum AcquisitionMode {
- NORMAL, HIGH_RESOLUTION, AVERAGE, PEAK, ENVELOPE
- }
+ /**
+ * AcquisitionMode controls how multiple measurements are evaluated into one.
+ */
+ public static enum AcquisitionMode {
+ NORMAL, HIGH_RESOLUTION, AVERAGE, PEAK, ENVELOPE
+ }
- AcquisitionState getState() throws InstrumentException;
+ AcquisitionState getState() throws InstrumentException;
- public static enum AcquisitionState {
- COMPLETE, INPROGRESS, UNKNOWN
- }
- }
-}
\ No newline at end of file
+ /**
+ * AcquisitionState represents the current measurement availability.
+ */
+ public static enum AcquisitionState {
+ COMPLETE, INPROGRESS, UNKNOWN
+ }
+ }
+
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/instrument/common/Coupling.java b/measure-core/src/main/java/org/jtmc/core/instrument/common/Coupling.java
index 339d783..b3bb72b 100644
--- a/measure-core/src/main/java/org/jtmc/core/instrument/common/Coupling.java
+++ b/measure-core/src/main/java/org/jtmc/core/instrument/common/Coupling.java
@@ -1,5 +1,23 @@
package org.jtmc.core.instrument.common;
+/**
+ * Coupling represents how a hardware input is connected to the sensing.
+ * circuit
+ */
public enum Coupling {
- AC, DC, GND
-}
\ No newline at end of file
+ /**
+ * A capacitor in series is activated on the sense line.
+ */
+ AC,
+
+ /**
+ * The input is directly connected to the sensing circuit.
+ */
+ DC,
+
+ /**
+ * The sense circuit's input is grounded instead of being connected to the
+ * physical input.
+ */
+ GND
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/instrument/common/Impedance.java b/measure-core/src/main/java/org/jtmc/core/instrument/common/Impedance.java
index cbf2b2f..4ae9c34 100644
--- a/measure-core/src/main/java/org/jtmc/core/instrument/common/Impedance.java
+++ b/measure-core/src/main/java/org/jtmc/core/instrument/common/Impedance.java
@@ -1,8 +1,20 @@
package org.jtmc.core.instrument.common;
+/**
+ * Contains common impedance values used in test and measurement.
+ *
+ *
Users and instrument drivers should use these values for a consistent
+ * experience across devices.
+ */
public class Impedance {
-
- public static final double Z50 = 50.0;
+
+ /**
+ * Represents a 50Ohm load.
+ */
+ public static final double Z50 = 50.0;
- public static final double HIZ = Double.MAX_VALUE;
-}
\ No newline at end of file
+ /**
+ * Represents a High Impedance load.
+ */
+ public static final double HIZ = Double.MAX_VALUE;
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/lxi/LXIDiscovery.java b/measure-core/src/main/java/org/jtmc/core/lxi/LXIDiscovery.java
index 859f02b..e4618a4 100644
--- a/measure-core/src/main/java/org/jtmc/core/lxi/LXIDiscovery.java
+++ b/measure-core/src/main/java/org/jtmc/core/lxi/LXIDiscovery.java
@@ -1,110 +1,52 @@
package org.jtmc.core.lxi;
import java.io.IOException;
-import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.HashSet;
-import java.util.Objects;
import java.util.Set;
-
-import org.jtmc.core.visa.DeviceIdentifier;
import org.jtmc.core.visa.VisaException;
import org.jtmc.core.visa.instrument.InstrumentDiscovery;
-import org.jtmc.core.visa.instrument.InstrumentEndpoint;
/**
- * LXIDiscovery is the interface for discovering LXI devices on the network
+ * LXIDiscovery is an interface for discovering LXI devices on the network.
*/
public interface LXIDiscovery extends InstrumentDiscovery {
- /**
- * Returns LXI devices found through the given network interface
- *
- * @param networkInterface Network Interface
- * @return LXI Instrument Endpoints
- * @throws IOException if there was an error during device discovery
- */
- Set extends LXIInstrumentEndpoint> discover(NetworkInterface networkInterface) throws IOException;
-
- /**
- * Returns LXI devices found through all of the available network interfaces
- * @return LXI Instrument Endpoints
- * @throws VisaException if there was an error during device discovery
- */
- @Override
- default Set discover() throws VisaException {
- try {
- Enumeration interfaces = NetworkInterface.getNetworkInterfaces();
- Set endpoints = new HashSet<>();
- while(interfaces.hasMoreElements()) {
- try {
- NetworkInterface intf = interfaces.nextElement();
- endpoints.addAll(
- discover(intf));
- } catch (IOException e) {
- //TODO: log exception
- }
- }
- return endpoints;
- } catch(SocketException e) {
- throw new VisaException(e);
- }
- }
-
- /**
- * LXI Instrument Endpoints identify a host on the network and a port through
- * which the instrument is accessible
- */
- public abstract static class LXIInstrumentEndpoint implements InstrumentEndpoint {
-
- private final InetAddress host;
-
- private final int port;
-
- private final DeviceIdentifier deviceIdentifier;
-
- public LXIInstrumentEndpoint(InetAddress host, int port, DeviceIdentifier deviceIdentifier) {
- this.host = host;
- this.port = port;
- this.deviceIdentifier = deviceIdentifier;
- }
-
- public InetAddress getHost() {
- return host;
- }
-
- public int getPort() {
- return port;
- }
-
- /**
- * Returns the Device identifier of this instrument, when the device identifier cannot be resolved
- * it will return DeviceIdentifier.UNKNOWN
- *
- * @return Device identifier
- */
- public DeviceIdentifier getDeviceIdentifier() {
- return deviceIdentifier;
- }
-
- @Override
- public boolean equals(Object obj) {
- if(this == obj) {
- return true;
- }
- if(obj == null) {
- return false;
- }
- LXIInstrumentEndpoint endpoint = (LXIInstrumentEndpoint) obj;
- return Objects.equals(this.host, endpoint.host) && Objects.equals(this.port, endpoint.port);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(this.host, this.port);
- }
-
- }
-}
\ No newline at end of file
+ /**
+ * Returns LXI devices found through the given network interface.
+ *
+ * @param networkInterface Network Interface
+ * @return LXI Instrument Endpoints
+ * @throws IOException if there was an error during device discovery
+ */
+ Set extends LXIInstrumentEndpoint> discover(
+ NetworkInterface networkInterface) throws IOException;
+
+ /**
+ * Returns LXI devices found through all of the available network interfaces.
+ *
+ * @return LXI Instrument Endpoints
+ * @throws VisaException if there was an error during device discovery
+ */
+ @Override
+ default Set discover() throws VisaException {
+ try {
+ Enumeration interfaces = NetworkInterface.getNetworkInterfaces();
+ Set endpoints = new HashSet<>();
+ while (interfaces.hasMoreElements()) {
+ try {
+ NetworkInterface intf = interfaces.nextElement();
+ endpoints.addAll(discover(intf));
+ } catch (IOException e) {
+ //TODO: log exception
+ }
+ }
+ return endpoints;
+ } catch (SocketException e) {
+ throw new VisaException(e);
+ }
+ }
+
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/lxi/LXIInstrumentEndpoint.java b/measure-core/src/main/java/org/jtmc/core/lxi/LXIInstrumentEndpoint.java
new file mode 100644
index 0000000..74b3856
--- /dev/null
+++ b/measure-core/src/main/java/org/jtmc/core/lxi/LXIInstrumentEndpoint.java
@@ -0,0 +1,70 @@
+package org.jtmc.core.lxi;
+
+import java.net.InetAddress;
+import java.util.Objects;
+import org.jtmc.core.visa.DeviceIdentifier;
+import org.jtmc.core.visa.instrument.InstrumentEndpoint;
+
+/**
+ * LXI Instrument Endpoints identify a host on the network and a port through
+ * which the instrument is accessible.
+ */
+public abstract class LXIInstrumentEndpoint implements InstrumentEndpoint {
+
+ private final InetAddress host;
+
+ private final int port;
+
+ private final DeviceIdentifier deviceIdentifier;
+
+ /**
+ * Constructs a new LXI Instrument Endpoint by specifying it's network address and port.
+ *
+ * @param host Instrument's host address
+ * @param port Port number
+ * @param deviceIdentifier DeviceIdentifier
+ */
+ public LXIInstrumentEndpoint(InetAddress host, int port, DeviceIdentifier deviceIdentifier) {
+ this.host = host;
+ this.port = port;
+ this.deviceIdentifier = deviceIdentifier;
+ }
+
+ public InetAddress getHost() {
+ return host;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ /**
+ * Returns the Device identifier of this instrument,
+ * if the device identifier cannot be resolved it returns
+ * DeviceIdentifier.UNKNOWN
+ *
+ * @return Device identifier
+ */
+ public DeviceIdentifier getDeviceIdentifier() {
+ return deviceIdentifier;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ LXIInstrumentEndpoint endpoint = (LXIInstrumentEndpoint) obj;
+ return Objects.equals(this.host, endpoint.host)
+ && Objects.equals(this.port, endpoint.port);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(this.host, this.port);
+ }
+
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/lxi/mdns/MDNS.java b/measure-core/src/main/java/org/jtmc/core/lxi/mdns/MDNS.java
index 5cf631b..3b5c164 100644
--- a/measure-core/src/main/java/org/jtmc/core/lxi/mdns/MDNS.java
+++ b/measure-core/src/main/java/org/jtmc/core/lxi/mdns/MDNS.java
@@ -1,32 +1,48 @@
package org.jtmc.core.lxi.mdns;
import javax.jmdns.ServiceInfo;
-
import org.jtmc.core.visa.DeviceIdentifier;
+/**
+ * Contains mDNS related utility functions.
+ */
public class MDNS {
- /**
- * Converts MDNS Service Information into DeviceIdentifier according to the keys
- *
- * @param serviceInfo
- * @return
- */
- public static DeviceIdentifier resolveDeviceIdentifier(ServiceInfo serviceInfo) {
- String manufacturer = serviceInfo.getPropertyString("Manufacturer");
- String model = serviceInfo.getPropertyString("Model");
- String serialNumber = serviceInfo.getPropertyString("SerialNumber");
- String firmwareVersion = serviceInfo.getPropertyString("FirmwareVersion");
-
- return DeviceIdentifier.from(manufacturer, model, serialNumber, firmwareVersion);
- }
-
- public static String convertDeviceIdentifierToRecordKeys(DeviceIdentifier identifier) {
- StringBuffer buffer = new StringBuffer();
- buffer.append("Manufacturer=" + identifier.getManufacturer() + "\n");
- buffer.append("Model=" + identifier.getModel() + "\n");
- buffer.append("SerialNumber=" + identifier.getSerialNumber() + "\n");
- buffer.append("FirmwareVersion=" + identifier.getFirmwareVersion());
- return buffer.toString();
- }
+ /**
+ * Converts MDNS Service Information into DeviceIdentifier according to
+ * the keys in the mDNS text record.
+ *
+ *
For more details see: LXI Specification 1.5.01, Section 10.4.3
+ *
+ * @param serviceInfo mDNS text record
+ * @return DeviceIdentifier
+ */
+ public static DeviceIdentifier getDeviceIdentifier(ServiceInfo serviceInfo) {
+ String manufacturer = serviceInfo.getPropertyString("Manufacturer");
+ String model = serviceInfo.getPropertyString("Model");
+ String serialNumber = serviceInfo.getPropertyString("SerialNumber");
+ String firmwareVersion = serviceInfo.getPropertyString("FirmwareVersion");
+
+ return DeviceIdentifier.from(
+ manufacturer, model, serialNumber, firmwareVersion);
+ }
+
+ /**
+ * Returns the mDNS text record of a DeviceIdentifier according to the LXI
+ * mDNS discovery specification.
+ *
+ *
For more details see: LXI Specification 1.5.01, Section 10.4.3
+ *
+ * @param identifier DeviceIdentifier
+ * @return mDNS TXT record
+ */
+ public static String convertToTextRecord(DeviceIdentifier identifier) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("Manufacturer=" + identifier.getManufacturer() + "\n");
+ buffer.append("Model=" + identifier.getModel() + "\n");
+ buffer.append("SerialNumber=" + identifier.getSerialNumber() + "\n");
+ buffer.append("FirmwareVersion=" + identifier.getFirmwareVersion());
+
+ return buffer.toString();
+ }
}
diff --git a/measure-core/src/main/java/org/jtmc/core/lxi/mdns/MDNSDiscovery.java b/measure-core/src/main/java/org/jtmc/core/lxi/mdns/MDNSDiscovery.java
index 412e856..bd90d2f 100644
--- a/measure-core/src/main/java/org/jtmc/core/lxi/mdns/MDNSDiscovery.java
+++ b/measure-core/src/main/java/org/jtmc/core/lxi/mdns/MDNSDiscovery.java
@@ -1,84 +1,95 @@
package org.jtmc.core.lxi.mdns;
import java.io.IOException;
+import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-
import javax.jmdns.JmDNS;
import javax.jmdns.ServiceEvent;
import javax.jmdns.ServiceListener;
-
import org.jtmc.core.lxi.LXIDiscovery;
+import org.jtmc.core.lxi.LXIInstrumentEndpoint;
import org.jtmc.core.lxi.raw.RawInstrumentEndpoint;
import org.jtmc.core.lxi.vxi11.VXI11InstrumentEndpoint;
+import org.jtmc.core.visa.DeviceIdentifier;
/**
- * MDNSDiscovery
+ * MDNSDiscovery implements LXI instrument discovery using the mDNS protocol.
*/
public class MDNSDiscovery implements LXIDiscovery {
- private int timeout = 1000;
+ private int timeout = 1000;
+
+ private List serviceTypes;
- private List serviceTypes;
+ public MDNSDiscovery() {
+ this(MDNSServiceType.LXI);
+ }
- public MDNSDiscovery() {
- this(MDNSServiceType.LXI);
- }
+ public MDNSDiscovery(MDNSServiceType... types) {
+ this(Arrays.asList(types));
+ }
- public MDNSDiscovery(MDNSServiceType... types) {
- this(Arrays.asList(types));
- }
+ public MDNSDiscovery(List types) {
+ this.serviceTypes = new ArrayList<>(types);
+ }
- public MDNSDiscovery(List types) {
- this.serviceTypes = new ArrayList<>(types);
- }
+ @Override
+ public Set discover(NetworkInterface networkInterface) throws IOException {
+ try (JmDNS jmdns = JmDNS.create(networkInterface.getInterfaceAddresses().get(0).getAddress())) {
+ Set devices = new HashSet<>();
+ ServiceListener callback = new ServiceListener() {
+
+ @Override
+ public void serviceResolved(ServiceEvent event) {
+ LXIInstrumentEndpoint endpoint = convertToEndpoint(event);
+ if (endpoint != null) {
+ devices.add(endpoint);
+ }
+ }
+
+ @Override
+ public void serviceRemoved(ServiceEvent event) {
+
+ }
+
+ @Override
+ public void serviceAdded(ServiceEvent event) {
- @Override
- public Set discover(NetworkInterface networkInterface) throws IOException {
- try(JmDNS jmdns = JmDNS.create(networkInterface.getInterfaceAddresses().get(0).getAddress())) {
- Set devices = new HashSet<>();
- ServiceListener callback = new ServiceListener(){
-
- @Override
- public void serviceResolved(ServiceEvent event) {
- LXIInstrumentEndpoint endpoint = getEndpoint(event);
- if(endpoint != null) {
- devices.add(endpoint);
- }
- }
-
- @Override
- public void serviceRemoved(ServiceEvent event) {
-
- }
-
- @Override
- public void serviceAdded(ServiceEvent event) {
+ }
+ };
+ serviceTypes.forEach(type -> jmdns.addServiceListener(type.fqdn(), callback));
+
+ Thread.sleep(timeout);
- }
- };
- serviceTypes.forEach(type -> jmdns.addServiceListener(type.fqdn(), callback));
-
- Thread.sleep(timeout);
+ return devices;
+ } catch (InterruptedException e) {
+ throw new IOException("MDNS discovery was interrupted.");
+ }
+ }
- return devices;
- } catch (InterruptedException e) {
- throw new IOException("MDNS discovery was interrupted.");
- }
- }
+ /**
+ * Converts an mDNS service discovery event into a connectable
+ * LXI Instrument endpoint.
+ *
+ * @param event mDNS discovery event
+ * @return LXI Instrument endpoint
+ */
+ private static LXIInstrumentEndpoint convertToEndpoint(ServiceEvent event) {
+ InetAddress host = event.getInfo().getInetAddresses()[0];
+ int port = event.getInfo().getPort();
+ DeviceIdentifier deviceIdentifier = MDNS.getDeviceIdentifier(event.getInfo());
- private static LXIInstrumentEndpoint getEndpoint(ServiceEvent event) {
- if(event.getType().equals(MDNSServiceType.VXI11.fqdn())) {
- return new VXI11InstrumentEndpoint(event.getInfo().getInetAddresses()[0], event.getInfo().getPort(), MDNS.resolveDeviceIdentifier(event.getInfo()));
- }
- else if(event.getType().equals(MDNSServiceType.SCPI_RAW.fqdn())) {
- return new RawInstrumentEndpoint(event.getInfo().getInetAddresses()[0], event.getInfo().getPort(), MDNS.resolveDeviceIdentifier(event.getInfo()));
- }
- return null;
- }
+ if (event.getType().equals(MDNSServiceType.VXI11.fqdn())) {
+ return new VXI11InstrumentEndpoint(host, port, deviceIdentifier);
+ } else if (event.getType().equals(MDNSServiceType.SCPI_RAW.fqdn())) {
+ return new RawInstrumentEndpoint(host, port, deviceIdentifier);
+ }
+ return null;
+ }
-}
\ No newline at end of file
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/lxi/mdns/MDNSServiceType.java b/measure-core/src/main/java/org/jtmc/core/lxi/mdns/MDNSServiceType.java
index c43939f..ec83850 100644
--- a/measure-core/src/main/java/org/jtmc/core/lxi/mdns/MDNSServiceType.java
+++ b/measure-core/src/main/java/org/jtmc/core/lxi/mdns/MDNSServiceType.java
@@ -1,31 +1,59 @@
package org.jtmc.core.lxi.mdns;
/**
- * Contains mDNS service types that are used to discover
- * LXI capable devices
+ * Contains mDNS service types that are used to discover LXI capable devices.
+ *
+ *
For more details see: LXI Specification 1.5.01, Section 10.4.3.10
*/
public enum MDNSServiceType {
- LXI("_lxi._tcp.local"),
- HTTP("_http._tcp.local"),
- HISLIP("_hislip._tcp.local"),
- SCPI_RAW("_scpi-raw._tcp.local"),
- SCPI_TELNET("_scpi-telnet._tcp.local"),
- VXI11("_vxi11._tcp.local");
-
- private String fqdn;
-
- public final static MDNSServiceType[] ALL = MDNSServiceType.values();
-
- private MDNSServiceType(String fqdn) {
- this.fqdn = fqdn;
- }
-
- /**
- * Returns the fully qualified name of the mDNS service
- * @return Fully Qualified mDNS service name
- */
- public String fqdn() {
- return fqdn;
- }
-
-}
\ No newline at end of file
+
+ /**
+ * LXI Service type denotes an endpoint capable of identification via HTTP
+ * the service is expected to be on port 80.
+ */
+ LXI("_lxi._tcp.local"),
+
+ /**
+ * HTTP Service type denotes an endpoint that may be accessed
+ * from a web browser.
+ */
+ HTTP("_http._tcp.local"),
+
+ /**
+ * HiSLIP Service type denotes an endpoint hosting a HiSLIP server.
+ */
+ HISLIP("_hislip._tcp.local"),
+
+ /**
+ * SCPI Raw Service type denotes an endpoint hosting a TCP server
+ * interpreting raw SCPI commands.
+ */
+ SCPI_RAW("_scpi-raw._tcp.local"),
+
+ /**
+ * SCPI Telnet Service type denotes an endpoint hosting a Telnet server
+ * interpreting SCPI commands.
+ */
+ SCPI_TELNET("_scpi-telnet._tcp.local"),
+
+ /**
+ * VXI11 Service type denotes an endpoint hosting a VXI-11 Server.
+ */
+ VXI11("_vxi11._tcp.local");
+
+ private String fqdn;
+
+ public static final MDNSServiceType[] ALL = MDNSServiceType.values();
+
+ private MDNSServiceType(String fqdn) {
+ this.fqdn = fqdn;
+ }
+
+ /**
+ * Returns the fully qualified name of the mDNS service.
+ * @return Fully Qualified mDNS service name
+ */
+ public String fqdn() {
+ return fqdn;
+ }
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/lxi/mdns/package-info.java b/measure-core/src/main/java/org/jtmc/core/lxi/mdns/package-info.java
new file mode 100644
index 0000000..f2871e6
--- /dev/null
+++ b/measure-core/src/main/java/org/jtmc/core/lxi/mdns/package-info.java
@@ -0,0 +1,9 @@
+/**
+ * Contains classes related to LXI Instrument discovery using mDNS
+ *
+ *
The implementation uses the jMDNS library and provides an abstraction
+ * optimized for LXI instrument discovery
+ *
+ *
For more details see: LXI Specification 1.5.01, Section 10.3
+ */
+package org.jtmc.core.lxi.mdns;
diff --git a/measure-core/src/main/java/org/jtmc/core/lxi/package-info.java b/measure-core/src/main/java/org/jtmc/core/lxi/package-info.java
index 258164b..137a821 100644
--- a/measure-core/src/main/java/org/jtmc/core/lxi/package-info.java
+++ b/measure-core/src/main/java/org/jtmc/core/lxi/package-info.java
@@ -1,11 +1,14 @@
/**
- * Contains packages and classes related to communication with LAN based instruments
+ * Contains packages and classes related to communication
+ * with LAN based instruments
*
- *
The implementation of the protocols and interfaces are while required by the LXI specification, are
- * not exclusive to LXI devices. In fact some manufacturers only partially satisfy the standard, for
- * example they might have VXI-11, but they don't have a web interface or don't support mDNS.
+ *
The implementation of the protocols and interfaces are while required by
+ * the LXI specification, are not exclusive to LXI devices.
+ * In fact some manufacturers only partially satisfy the standard, for example
+ * they might have VXI-11, but they don't have a web interface
+ * or don't support mDNS.
*
- *
*/
public class VXI11 {
- /**
- * Device core functionality
- */
- public static class DeviceCore {
- public final static int PROGRAM = 0x0607AF;
- public final static int VERSION = 1;
+ /**
+ * Device core functionality.
+ */
+ public static class DeviceCore {
+ public static final int PROGRAM = 0x0607AF;
+ public static final int VERSION = 1;
- public final static int CREATE_LINK = 10;
- public final static int DEVICE_WRITE = 11;
- public final static int DEVICE_READ = 12;
- public final static int DEVICE_READSTB = 13;
- public final static int DEVICE_TRIGGER = 14;
- public final static int DEVICE_CLEAR = 15;
- public final static int DEVICE_REMOTE = 16;
- public final static int DEVICE_LOCAL = 17;
- public final static int DEVICE_LOCK = 18;
- public final static int DEVICE_UNLOCK = 19;
- public final static int DEVICE_ENABLE_SRQ = 20;
- public final static int DEVICE_DOCMD = 22;
- public final static int DESTROY_LINK = 23;
- public final static int CREATE_INTR_CHANNEL = 25;
- public final static int DESTROY_INTR_CHANNEL = 26;
- }
+ public static final int CREATE_LINK = 10;
+ public static final int DEVICE_WRITE = 11;
+ public static final int DEVICE_READ = 12;
+ public static final int DEVICE_READSTB = 13;
+ public static final int DEVICE_TRIGGER = 14;
+ public static final int DEVICE_CLEAR = 15;
+ public static final int DEVICE_REMOTE = 16;
+ public static final int DEVICE_LOCAL = 17;
+ public static final int DEVICE_LOCK = 18;
+ public static final int DEVICE_UNLOCK = 19;
+ public static final int DEVICE_ENABLE_SRQ = 20;
+ public static final int DEVICE_DOCMD = 22;
+ public static final int DESTROY_LINK = 23;
+ public static final int CREATE_INTR_CHANNEL = 25;
+ public static final int DESTROY_INTR_CHANNEL = 26;
+ }
- /**
- * Interrupt functionality (optional)
- */
- public static class DeviceInterrupt {
- public final static int PROGRAM = 0x0607B1;
- public final static int VERSION = 1;
+ /**
+ * Interrupt functionality (optional).
+ */
+ public static class DeviceInterrupt {
+ public static final int PROGRAM = 0x0607B1;
+ public static final int VERSION = 1;
- public final static int DEVICE_INTR_SRQ = 30;
- }
+ public static final int DEVICE_INTR_SRQ = 30;
+ }
- /**
- * Asynchronous functionality (optional)
- */
- public static class DeviceAsync {
- public final static int PROGRAM = 0x0607B0;
- public final static int VERSION = 1;
+ /**
+ * Asynchronous functionality (optional).
+ */
+ public static class DeviceAsync {
+ public static final int PROGRAM = 0x0607B0;
+ public static final int VERSION = 1;
- public final static int DEVICE_ABORT = 1;
- }
+ public static final int DEVICE_ABORT = 1;
+ }
+
+ /**
+ * Error codes.
+ *
+ *
Found in VXI-11 Rev 1.0 specification Table B.2
+ */
+ public static class ErrorCode {
+ public static final int NO_ERROR = 0;
+ public static final int SYNTAX_ERROR = 2;
+ public static final int DEVICE_NOT_ACCESSIBLE = 3;
+ public static final int INVALID_LINK_IDENTIFIER = 4;
+ public static final int PARAMETER_ERROR = 5;
+ public static final int CHANNEL_NOT_ESTABLISHED = 6;
+ public static final int OPERATION_NOT_SUPPORTED = 8;
+ public static final int OUT_OF_RESOURCES = 9;
+ public static final int DEVICE_LOCKED_BY_ANOTHER_LINK = 11;
+ public static final int NO_LOCK_HELD_BY_THIS_LINK = 12;
+ public static final int IO_TIMEOUT = 15;
+ public static final int IO_ERROR = 17;
+ public static final int INVALID_ADDRESS = 21;
+ public static final int ABORT = 23;
+ public static final int CHANNEL_ALREADY_ESTABLISHED = 29;
/**
- * Error codes
+ * Returns the name of the error for the given code.
*
- *
- * Found in VXI-11 Rev 1.0 specification Table B.2
+ * @param code Error code
+ * @return Error name
*/
- public static class ErrorCode {
- public final static int NO_ERROR = 0;
- public final static int SYNTAX_ERROR = 2;
- public final static int DEVICE_NOT_ACCESSIBLE = 3;
- public final static int INVALID_LINK_IDENTIFIER = 4;
- public final static int PARAMETER_ERROR = 5;
- public final static int CHANNEL_NOT_ESTABLISHED = 6;
- public final static int OPERATION_NOT_SUPPORTED = 8;
- public final static int OUT_OF_RESOURCES = 9;
- public final static int DEVICE_LOCKED_BY_ANOTHER_LINK = 11;
- public final static int NO_LOCK_HELD_BY_THIS_LINK = 12;
- public final static int IO_TIMEOUT = 15;
- public final static int IO_ERROR = 17;
- public final static int INVALID_ADDRESS = 21;
- public final static int ABORT = 23;
- public final static int CHANNEL_ALREADY_ESTABLISHED = 29;
-
- /**
- * Returns the name of the error for the given code
- * @param code Error code
- * @return Error name
- */
- public static String getErrorName(int code) {
- try {
- for(Field field : ErrorCode.class.getFields()) {
- if(field.getType() == int.class && field.getInt(null) == code) {
- return field.getName();
- }
- }
- return "UNKNOWN";
- } catch(IllegalAccessException e) {
- return "UNKNOWN";
- }
+ public static String getErrorName(int code) {
+ try {
+ for (Field field : ErrorCode.class.getFields()) {
+ if (field.getType() == int.class && field.getInt(null) == code) {
+ return field.getName();
+ }
}
+ return "UNKNOWN";
+ } catch (IllegalAccessException e) {
+ return "UNKNOWN";
+ }
+ }
- /**
- * Returns an error string consisting of the error name and error code
- * @param code Error code
- * @return Error string in the format 'NAME (CODE)'
- */
- public static String getErrorString(int code) {
- return getErrorName(code) + " (" + code + ")";
- }
+ /**
+ * Returns an error string consisting of the error name and error code.
+ *
+ * @param code Error code
+ * @return Error string in the format 'NAME (CODE)'
+ */
+ public static String getErrorString(int code) {
+ return getErrorName(code) + " (" + code + ")";
}
-}
\ No newline at end of file
+ }
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/VXI11Discovery.java b/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/VXI11Discovery.java
index 5dffd4f..735da07 100644
--- a/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/VXI11Discovery.java
+++ b/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/VXI11Discovery.java
@@ -9,7 +9,6 @@
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
-
import org.acplt.oncrpc.OncRpcBroadcastEvent;
import org.acplt.oncrpc.OncRpcBroadcastListener;
import org.acplt.oncrpc.OncRpcException;
@@ -25,141 +24,147 @@
/**
* VXI11Discovery implements RPC based instrument discovery
*
- *
- * This implementation broadcasts RPC Portmap queries over UDP. The portmap
+ *
This implementation broadcasts RPC Portmap queries over UDP. The portmap
* parameters specifically look for the existence of the VXI-11 Device Core
* program over TCP.
*/
public class VXI11Discovery implements LXIDiscovery {
- /**
- * Default timeout, 1 second as specified in the LXI standard
- */
- public final static int DEFAULT_TIMEOUT = 1000;
-
- private int timeout;
-
- private boolean resolveDeviceInfo;
-
- private int retransmissions;
-
- /**
- * Constructs a new VXI-11 discovery tool using the default parameters
- *
- *
- *
1 second timeout
- *
Don't resolve device identifiers
- *
Retransmit 1 time
- */
- public VXI11Discovery() {
- this(false);
- }
-
- /**
- * Constructs a new VXI-11 discovery tool
- *
- * @param resolveDeviceInfo If {@code true} then after discovering devices it
- * will attempt to do an identification query
- */
- public VXI11Discovery(boolean resolveDeviceInfo) {
- this(resolveDeviceInfo, 1);
- }
-
- /**
- * Constructs a new VXI-11 discovery tool
- *
- * @param resolveDeviceInfo If {@code true} then after discovering devices it
- * will attempt to do an identification query
- * @param retransmissions The number of retransmissions when broadcasting the
- * portmap message, {@code 0} specifies no
- * retranmissions so it will do a total of {@code 1}
- * tranmission
- */
- public VXI11Discovery(boolean resolveDeviceInfo, int retransmissions) {
- this(resolveDeviceInfo, retransmissions, DEFAULT_TIMEOUT);
- }
-
- /**
- * Constructs a new VXI-11 discovery tool
- *
- * @param resolveDeviceInfo If {@code true} then after discovering devices it
- * will attempt to do an identification query
- * @param retransmissions The number of retransmissions when broadcasting the
- * portmap message, {@code 0} specifies no
- * retranmissions so it will do a total of {@code 1}
- * tranmission
- * @param timeout Time to wait for portmap responses in milliseconds
- */
- public VXI11Discovery(boolean resolveDeviceInfo, int retransmissions, int timeout) {
- this.timeout = timeout;
- this.resolveDeviceInfo = resolveDeviceInfo;
- this.retransmissions = retransmissions;
- }
-
- @Override
- public Set discover(NetworkInterface networkInterface) throws IOException {
- try {
- InetAddress bcast = getBroadcastAddress(networkInterface);
- OncRpcUdpClient rpcClient = (OncRpcUdpClient) OncRpcUdpClient.newOncRpcClient(bcast, Portmap.PROGRAM,
- Portmap.VERSION, Portmap.PORT, OncRpcProtocols.ONCRPC_UDP);
- rpcClient.setTimeout(timeout);
-
- Set devices = new HashSet<>();
-
- PortmapResponse response = new PortmapResponse();
- OncRpcBroadcastListener callback = new OncRpcBroadcastListener() {
- @Override
- public void replyReceived(OncRpcBroadcastEvent evt) {
- VXI11InstrumentEndpoint endpoint = new VXI11InstrumentEndpoint(evt.getReplyAddress(),
- response.getPort(), DeviceIdentifier.UNKNOWN);
- devices.add(endpoint);
- }
- };
-
- for (int i = 0; i < retransmissions + 1; i++) {
- rpcClient.broadcastCall(Portmap.PROC_GETPORT, new PortmapParams(VXI11.DeviceCore.PROGRAM,
- VXI11.DeviceCore.VERSION, OncRpcProtocols.ONCRPC_TCP, 4), response, callback);
- }
-
- if (resolveDeviceInfo) {
- Set resolved = devices.stream().map(endpoint -> {
- try (VXI11Socket socket = endpoint.connect()) {
- RawSCPISocket scpiSocket = new RawSCPISocket(socket);
- return new VXI11InstrumentEndpoint(endpoint.getHost(), endpoint.getPort(),
- scpiSocket.getDeviceIdentifier());
- } catch (IOException e) {
- return endpoint;
- }
- }).collect(Collectors.toSet());
- return resolved;
- }
-
- return devices;
- } catch (OncRpcException e) {
- throw new IOException(e);
- } catch (IllegalArgumentException e) {
- throw new IOException(e);
- }
- }
-
- /**
- * Returns a broadcast address for the given network interface
- *
- * @param networkInterface Network interface
- * @return Broadcast IP Address
- * @throws SocketException If the network interface is unavailable
- */
- private static InetAddress getBroadcastAddress(NetworkInterface networkInterface) throws SocketException {
- if (!networkInterface.isUp() || networkInterface.isVirtual()) {
- throw new IllegalArgumentException(
- "Network interface '" + networkInterface.getName() + "' unavailable or is virtual.");
- }
- Optional address = networkInterface.getInterfaceAddresses().stream()
- .filter(addr -> addr.getBroadcast() != null).findFirst();
- return address
- .orElseThrow(() -> new IllegalArgumentException(
- "Network interface '" + networkInterface.getName() + "' has no broadcast address"))
- .getBroadcast();
- }
-
-}
\ No newline at end of file
+ /**
+ * Default timeout, 1 second as specified in the LXI standard.
+ */
+ public static final int DEFAULT_TIMEOUT = 1000;
+
+ private int timeout;
+
+ private boolean resolveDeviceInfo;
+
+ private int retransmissions;
+
+ /**
+ * Constructs a new VXI-11 discovery tool using the default parameters.
+ *
+ *
+ *
1 second timeout
+ *
Don't resolve device identifiers
+ *
Retransmit 1 time
+ *
+ */
+ public VXI11Discovery() {
+ this(false);
+ }
+
+ /**
+ * Constructs a new VXI-11 discovery tool.
+ *
+ * @param resolveDeviceInfo If {@code true} then after discovering devices it
+ * will attempt to do an identification query
+ */
+ public VXI11Discovery(boolean resolveDeviceInfo) {
+ this(resolveDeviceInfo, 1);
+ }
+
+ /**
+ * Constructs a new VXI-11 discovery tool.
+ *
+ * @param resolveDeviceInfo If {@code true} then after discovering devices it
+ * will attempt to do an identification query
+ * @param retransmissions The number of retransmissions when broadcasting the
+ * portmap message, {@code 0} specifies no
+ * retranmissions so it will do a total of {@code 1}
+ * tranmission
+ */
+ public VXI11Discovery(boolean resolveDeviceInfo, int retransmissions) {
+ this(resolveDeviceInfo, retransmissions, DEFAULT_TIMEOUT);
+ }
+
+ /**
+ * Constructs a new VXI-11 discovery tool.
+ *
+ * @param resolveDeviceInfo If {@code true} then after discovering devices it
+ * will attempt to do an identification query
+ * @param retransmissions The number of retransmissions when broadcasting the
+ * portmap message, {@code 0} specifies no
+ * retranmissions so it will do a total of {@code 1}
+ * tranmission
+ * @param timeout Time to wait for portmap responses in milliseconds
+ */
+ public VXI11Discovery(boolean resolveDeviceInfo, int retransmissions, int timeout) {
+ this.timeout = timeout;
+ this.resolveDeviceInfo = resolveDeviceInfo;
+ this.retransmissions = retransmissions;
+ }
+
+ @Override
+ public Set discover(
+ NetworkInterface networkInterface) throws IOException {
+ try {
+ InetAddress bcast = getBroadcastAddress(networkInterface);
+ OncRpcUdpClient rpcClient = (OncRpcUdpClient) OncRpcUdpClient.newOncRpcClient(bcast,
+ Portmap.PROGRAM, Portmap.VERSION, Portmap.PORT, OncRpcProtocols.ONCRPC_UDP);
+ rpcClient.setTimeout(timeout);
+
+ Set devices = new HashSet<>();
+
+ PortmapResponse response = new PortmapResponse();
+ OncRpcBroadcastListener callback = new OncRpcBroadcastListener() {
+ @Override
+ public void replyReceived(OncRpcBroadcastEvent evt) {
+ VXI11InstrumentEndpoint endpoint = new VXI11InstrumentEndpoint(evt.getReplyAddress(),
+ response.getPort(), DeviceIdentifier.UNKNOWN);
+ devices.add(endpoint);
+ }
+ };
+
+ //TODO: find out where the 4 comes from
+ PortmapParams portmapRequest = new PortmapParams(
+ VXI11.DeviceCore.PROGRAM, VXI11.DeviceCore.VERSION, OncRpcProtocols.ONCRPC_TCP, 4);
+
+ for (int i = 0; i < retransmissions + 1; i++) {
+ rpcClient.broadcastCall(Portmap.PROC_GETPORT, portmapRequest, response, callback);
+ }
+
+ if (resolveDeviceInfo) {
+ Set resolved = devices.stream().map(endpoint -> {
+ try (VXI11Socket socket = endpoint.connect()) {
+ RawSCPISocket scpiSocket = new RawSCPISocket(socket);
+ return new VXI11InstrumentEndpoint(endpoint.getHost(), endpoint.getPort(),
+ scpiSocket.getDeviceIdentifier());
+ } catch (IOException e) {
+ return endpoint;
+ }
+ }).collect(Collectors.toSet());
+ return resolved;
+ }
+
+ return devices;
+ } catch (OncRpcException e) {
+ throw new IOException(e);
+ } catch (IllegalArgumentException e) {
+ throw new IOException(e);
+ }
+ }
+
+ /**
+ * Returns a broadcast address for the given network interface.
+ *
+ * @param networkInterface Network interface
+ * @return Broadcast IP Address
+ * @throws SocketException If the network interface is unavailable
+ */
+ private static InetAddress getBroadcastAddress(
+ NetworkInterface networkInterface) throws SocketException {
+
+ if (!networkInterface.isUp() || networkInterface.isVirtual()) {
+ throw new IllegalArgumentException(
+ "Network interface '" + networkInterface.getName() + "' unavailable or is virtual.");
+ }
+ Optional address = networkInterface.getInterfaceAddresses().stream()
+ .filter(addr -> addr.getBroadcast() != null).findFirst();
+ return address
+ .orElseThrow(() -> new IllegalArgumentException(
+ "Network interface '" + networkInterface.getName() + "' has no broadcast address"))
+ .getBroadcast();
+ }
+
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/VXI11Exception.java b/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/VXI11Exception.java
index 8ad611d..e0e3217 100644
--- a/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/VXI11Exception.java
+++ b/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/VXI11Exception.java
@@ -1,34 +1,35 @@
package org.jtmc.core.lxi.vxi11;
import java.io.IOException;
-
import org.jtmc.core.lxi.vxi11.VXI11.ErrorCode;
/**
- * VXI11Exception is a convenience exception for indicating an exception while using the VXI-11 Protocol
+ * VXI11Exception is used for indicating an exception while using
+ * the VXI-11 Protocol.
*/
public class VXI11Exception extends IOException {
- private static final long serialVersionUID = 9011406167109584636L;
+ private static final long serialVersionUID = 9011406167109584636L;
- /**
- * Constructs a VXI11Exception based on the error code
- * @param code VXI-11 Error code
- */
- public VXI11Exception(int code) {
- super("VXI11 Error: " + ErrorCode.getErrorString(code));
- }
+ /**
+ * Constructs a VXI11Exception based on the error code.
+ *
+ * @param code VXI-11 Error code
+ */
+ public VXI11Exception(int code) {
+ super("VXI-11 Error: " + ErrorCode.getErrorString(code));
+ }
- public VXI11Exception(String message) {
- super(message);
- }
+ public VXI11Exception(String message) {
+ super(message);
+ }
- public VXI11Exception(Throwable cause) {
- super(cause);
- }
+ public VXI11Exception(Throwable cause) {
+ super(cause);
+ }
- public VXI11Exception(String message, Throwable cause) {
- super(message, cause);
- }
+ public VXI11Exception(String message, Throwable cause) {
+ super(message, cause);
+ }
-}
\ No newline at end of file
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/VXI11InstrumentEndpoint.java b/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/VXI11InstrumentEndpoint.java
index 0191ec7..70d74a8 100644
--- a/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/VXI11InstrumentEndpoint.java
+++ b/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/VXI11InstrumentEndpoint.java
@@ -2,19 +2,25 @@
import java.io.IOException;
import java.net.InetAddress;
-
-import org.jtmc.core.lxi.LXIDiscovery.LXIInstrumentEndpoint;
+import org.jtmc.core.lxi.LXIInstrumentEndpoint;
import org.jtmc.core.visa.DeviceIdentifier;
+/**
+ * VXI11InstrumentEndpoint is used to instantiate VXI-11 connections
+ * to instruments.
+ */
public class VXI11InstrumentEndpoint extends LXIInstrumentEndpoint {
- public VXI11InstrumentEndpoint(InetAddress host, int port, DeviceIdentifier deviceIdentifier) {
- super(host, port, deviceIdentifier);
- }
+ public VXI11InstrumentEndpoint(
+ InetAddress host,
+ int port,
+ DeviceIdentifier deviceIdentifier) {
+ super(host, port, deviceIdentifier);
+ }
- @Override
- public VXI11Socket connect() throws IOException {
- return new VXI11Socket(this.getHost(), this.getPort());
- }
+ @Override
+ public VXI11Socket connect() throws IOException {
+ return new VXI11Socket(this.getHost(), this.getPort());
+ }
-}
\ No newline at end of file
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/VXI11Socket.java b/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/VXI11Socket.java
index 5853d9e..a924aa8 100644
--- a/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/VXI11Socket.java
+++ b/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/VXI11Socket.java
@@ -6,7 +6,6 @@
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
-
import org.acplt.oncrpc.OncRpcClient;
import org.acplt.oncrpc.OncRpcException;
import org.acplt.oncrpc.OncRpcProtocols;
@@ -22,172 +21,237 @@
import org.jtmc.core.lxi.vxi11.rpc.DeviceWriteResponse;
/**
- * VXI11Socket
+ * VXI11Socket implements the VXI11 RPC interface.
*/
public class VXI11Socket implements ISocket {
- public final static int DEFAULT_IO_TIMEOUT = 2000;
-
- public final static int DEFAULT_WRITE_BLOCK_SIZE = 8128;
-
- //TODO: update value
- public final static int CLIENT_ID = 1234567;
-
- private final InetAddress host;
-
- private final int port;
-
- private final String name;
-
- private int lockTimeout;
-
- private int ioTimeout;
-
- private int writeBlockSize;
-
- private transient OncRpcClient client;
-
- private transient CreateLinkResponse link;
-
- public VXI11Socket(final InetAddress host) throws IOException {
- this(host, 0, "inst0");
- }
-
- public VXI11Socket(final InetAddress host, final int port) throws IOException {
- this(host, port, "inst0");
- }
-
- public VXI11Socket(final InetAddress host, final int port, final String instrumentName) throws IOException {
- this(host, instrumentName, port, false, 0, DEFAULT_IO_TIMEOUT, DEFAULT_WRITE_BLOCK_SIZE);
- }
-
- public VXI11Socket(final InetAddress host, final String name, int port, boolean lock, int lockTimeout, int ioTimeout, int writeBlockSize) throws IOException {
- this.host = host;
- this.port = port;
- this.name = name;
- this.lockTimeout = lockTimeout;
- this.ioTimeout = ioTimeout;
- this.writeBlockSize = writeBlockSize;
-
- try {
- client = OncRpcClient.newOncRpcClient(host, VXI11.DeviceCore.PROGRAM, VXI11.DeviceCore.VERSION, port, OncRpcProtocols.ONCRPC_TCP);
- link = createLink(CLIENT_ID, lock, lockTimeout, name);
- } catch (OncRpcException e) {
- client = null;
- throw new IOException(e);
- }
- }
-
- private CreateLinkResponse createLink(int clientId, boolean lockDevice, int lockTimeout, String device) throws OncRpcException {
- CreateLinkResponse response = new CreateLinkResponse();
- client.call(VXI11.DeviceCore.CREATE_LINK, VXI11.DeviceCore.VERSION, new CreateLinkParams(clientId, lockDevice, lockTimeout, device), response);
- return response;
- }
-
- private DeviceWriteResponse write(int linkId, int ioTimeout, int lockTimeout, DeviceFlags flags, byte... data) throws OncRpcException {
- DeviceWriteParams params = new DeviceWriteParams(new DeviceLink(linkId), ioTimeout, lockTimeout, flags, data);
- DeviceWriteResponse response = new DeviceWriteResponse();
- client.call(VXI11.DeviceCore.DEVICE_WRITE, VXI11.DeviceCore.VERSION, params, response);
- return response;
- }
-
- private DeviceReadResponse read(int linkId, int size, int ioTimeout, int lockTimeout, DeviceFlags flags, byte termination) throws OncRpcException {
- DeviceReadParams params = new DeviceReadParams(new DeviceLink(linkId), size, ioTimeout, lockTimeout, flags, termination);
- DeviceReadResponse response = new DeviceReadResponse();
- client.call(VXI11.DeviceCore.DEVICE_READ, VXI11.DeviceCore.VERSION, params, response);
- return response;
- }
-
- private DeviceError destroyLink(int linkId) throws OncRpcException {
- DeviceError error = new DeviceError();
- client.call(VXI11.DeviceCore.DESTROY_LINK, VXI11.DeviceCore.VERSION, new DeviceLink(linkId), error);
- return error;
- }
-
- public int getPort() {
- return port;
- }
-
- @Override
- public void close() {
- try {
- destroyLink(link.getLinkId());
- client.close();
- } catch(OncRpcException e) {
- //log warning
- } finally {
- client = null;
- }
- }
-
- @Override
- public boolean isConnected() {
- return client != null;
- }
-
- @Override
- public String getResourceString() {
- return "TCPIP::" + this.host + "::" + this.name + "::INSTR";
- }
-
- @Override
- public void send(ByteBuffer message) throws IOException {
- if(!message.hasArray()) {
- throw new IOException("Message empty.");
- }
- try {
- int offset = 0;
- int size = message.capacity();
- byte[] block = new byte[Math.min(size, writeBlockSize)];
- while(offset < size) {
- message.get(block, offset, size - offset > writeBlockSize ? writeBlockSize : size);
- DeviceFlags flags = new DeviceFlags(false, offset + writeBlockSize >= size, false);
- DeviceWriteResponse response = this.write(link.getLinkId(), ioTimeout, lockTimeout, flags, block);
- if(response.getError() != VXI11.ErrorCode.NO_ERROR) {
- throw new VXI11Exception(response.getError());
- }
- offset += writeBlockSize;
- }
- } catch(OncRpcException e) {
- throw new IOException(e);
- }
- }
-
- @Override
- public ByteBuffer receive(int count, long timeout) throws IOException, SocketTimeoutException {
- try {
- DeviceReadResponse response = this.read(link.getLinkId(), count, (int)timeout, lockTimeout, new DeviceFlags(false, false, false), (byte)0);
- if(response.getError() != VXI11.ErrorCode.NO_ERROR) {
- throw new VXI11Exception(response.getError());
- }
- return ByteBuffer.wrap(response.data);
- } catch(OncRpcException e) {
- throw new IOException(e);
- }
- }
-
- @Override
- public ByteBuffer receive(char delimiter, long timeout) throws IOException, SocketTimeoutException {
- try {
- ArrayList buffer = new ArrayList<>();
- DeviceReadResponse response = null;
- while(response == null || !response.isEOISet()) {
- response = this.read(link.getLinkId(), SocketOptions.SO_RCVBUF, (int)timeout, lockTimeout, new DeviceFlags(false, false, false), (byte)delimiter);
- if(response.getError() != VXI11.ErrorCode.NO_ERROR) {
- throw new VXI11Exception(response.getError());
- }
- }
-
- buffer.add(response.data);
- int length = buffer.stream().mapToInt(array -> array.length).sum();
- ByteBuffer data = ByteBuffer.allocate(length);
- buffer.stream().forEach(data::put);
-
- return data;
- }
- catch(OncRpcException e) {
- throw new IOException(e);
- }
- }
-
-}
\ No newline at end of file
+ public static final int DEFAULT_IO_TIMEOUT = 2000;
+
+ public static final int DEFAULT_WRITE_BLOCK_SIZE = 8128;
+
+ //TODO: update value
+ public static final int CLIENT_ID = 1234567;
+
+ private final InetAddress host;
+
+ private final int port;
+
+ private final String name;
+
+ private int lockTimeout;
+
+ private int ioTimeout;
+
+ private int writeBlockSize;
+
+ private transient OncRpcClient client;
+
+ private transient CreateLinkResponse link;
+
+ public VXI11Socket(final InetAddress host) throws IOException {
+ this(host, 0, "inst0");
+ }
+
+ public VXI11Socket(final InetAddress host, final int port) throws IOException {
+ this(host, port, "inst0");
+ }
+
+ public VXI11Socket(
+ final InetAddress host,
+ final int port,
+ final String instrumentName) throws IOException {
+ this(host, instrumentName, port, false, 0, DEFAULT_IO_TIMEOUT, DEFAULT_WRITE_BLOCK_SIZE);
+ }
+
+ /**
+ * Creates a new VXI11Socket with the given parameters.
+ * @param host IP Address of the intrument
+ * @param name Name to be given to the instrument
+ * @param port Port number of the instrument, use 0 to use Portmap interface for
+ * @param lock when {@code true} the instrument will be locked for {@code lockTimeout}
+ * @param lockTimeout Maximum time to lock the device for
+ * @param ioTimeout Maximum time to wait for IO operations to complete.
+ * @param writeBlockSize Number of bytes to write in a single write operation
+ * @throws IOException when
+ */
+ public VXI11Socket(
+ final InetAddress host,
+ final String name,
+ int port,
+ boolean lock,
+ int lockTimeout,
+ int ioTimeout,
+ int writeBlockSize) throws IOException {
+ this.host = host;
+ this.port = port;
+ this.name = name;
+ this.lockTimeout = lockTimeout;
+ this.ioTimeout = ioTimeout;
+ this.writeBlockSize = writeBlockSize;
+
+ try {
+ client = OncRpcClient.newOncRpcClient(host,
+ VXI11.DeviceCore.PROGRAM,
+ VXI11.DeviceCore.VERSION,
+ port,
+ OncRpcProtocols.ONCRPC_TCP);
+ link = createLink(CLIENT_ID, lock, lockTimeout, name);
+ } catch (OncRpcException e) {
+ client = null;
+ throw new IOException(e);
+ }
+ }
+
+ private CreateLinkResponse createLink(
+ int clientId,
+ boolean lockDevice,
+ int lockTimeout,
+ String device) throws OncRpcException {
+ CreateLinkResponse response = new CreateLinkResponse();
+ CreateLinkParams params = new CreateLinkParams(clientId, lockDevice, lockTimeout, device);
+ client.call(VXI11.DeviceCore.CREATE_LINK, VXI11.DeviceCore.VERSION, params, response);
+ return response;
+ }
+
+ private DeviceWriteResponse write(
+ int linkId,
+ int ioTimeout,
+ int lockTimeout,
+ DeviceFlags flags,
+ byte... data) throws OncRpcException {
+ DeviceLink link = new DeviceLink(linkId);
+ DeviceWriteParams params = new DeviceWriteParams(link, ioTimeout, lockTimeout, flags, data);
+ DeviceWriteResponse response = new DeviceWriteResponse();
+ client.call(VXI11.DeviceCore.DEVICE_WRITE, VXI11.DeviceCore.VERSION, params, response);
+ return response;
+ }
+
+ private DeviceReadResponse read(
+ int linkId,
+ int size,
+ int ioTimeout,
+ int lockTimeout,
+ DeviceFlags flags,
+ byte termination) throws OncRpcException {
+ DeviceLink link = new DeviceLink(linkId);
+ DeviceReadParams params = new DeviceReadParams(link,
+ size,
+ ioTimeout,
+ lockTimeout,
+ flags,
+ termination);
+ DeviceReadResponse response = new DeviceReadResponse();
+ client.call(VXI11.DeviceCore.DEVICE_READ, VXI11.DeviceCore.VERSION, params, response);
+ return response;
+ }
+
+ private DeviceError destroyLink(int linkId) throws OncRpcException {
+ DeviceError error = new DeviceError();
+ DeviceLink link = new DeviceLink(linkId);
+ client.call(VXI11.DeviceCore.DESTROY_LINK, VXI11.DeviceCore.VERSION, link, error);
+ return error;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ @Override
+ public void close() {
+ try {
+ destroyLink(link.getLinkId());
+ client.close();
+ } catch (OncRpcException e) {
+ //log warning
+ } finally {
+ client = null;
+ }
+ }
+
+ @Override
+ public boolean isConnected() {
+ return client != null;
+ }
+
+ @Override
+ public String getResourceString() {
+ return "TCPIP::" + this.host + "::" + this.name + "::INSTR";
+ }
+
+ @Override
+ public void send(ByteBuffer message) throws IOException {
+ if (!message.hasArray()) {
+ throw new IOException("Message empty.");
+ }
+ try {
+ int offset = 0;
+ int size = message.capacity();
+ byte[] block = new byte[Math.min(size, writeBlockSize)];
+ while (offset < size) {
+ message.get(block, offset, size - offset > writeBlockSize ? writeBlockSize : size);
+ DeviceFlags flags = new DeviceFlags(false, offset + writeBlockSize >= size, false);
+ DeviceWriteResponse response = this.write(link.getLinkId(),
+ ioTimeout,
+ lockTimeout,
+ flags,
+ block);
+ if (response.getError() != VXI11.ErrorCode.NO_ERROR) {
+ throw new VXI11Exception(response.getError());
+ }
+ offset += writeBlockSize;
+ }
+ } catch (OncRpcException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override
+ public ByteBuffer receive(int count, long timeout) throws IOException, SocketTimeoutException {
+ try {
+ DeviceFlags flags = new DeviceFlags(false, false, false);
+ DeviceReadResponse response = this.read(link.getLinkId(),
+ count,
+ (int) timeout,
+ lockTimeout,
+ flags,
+ (byte) 0);
+ if (response.getError() != VXI11.ErrorCode.NO_ERROR) {
+ throw new VXI11Exception(response.getError());
+ }
+ return ByteBuffer.wrap(response.data);
+ } catch (OncRpcException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override
+ public ByteBuffer receive(char delimiter, long timeout)
+ throws IOException, SocketTimeoutException {
+ try {
+ ArrayList buffer = new ArrayList<>();
+ DeviceReadResponse response = null;
+ DeviceFlags flags = new DeviceFlags(false, false, false);
+ while (response == null || !response.isEOISet()) {
+ response = this.read(link.getLinkId(),
+ SocketOptions.SO_RCVBUF,
+ (int) timeout,
+ lockTimeout,
+ flags,
+ (byte) delimiter);
+ if (response.getError() != VXI11.ErrorCode.NO_ERROR) {
+ throw new VXI11Exception(response.getError());
+ }
+ }
+
+ buffer.add(response.data);
+ int length = buffer.stream().mapToInt(array -> array.length).sum();
+ ByteBuffer data = ByteBuffer.allocate(length);
+ buffer.stream().forEach(data::put);
+
+ return data;
+ } catch (OncRpcException e) {
+ throw new IOException(e);
+ }
+ }
+
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/VXI11SocketFactory.java b/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/VXI11SocketFactory.java
index b2617f6..5505dcc 100644
--- a/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/VXI11SocketFactory.java
+++ b/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/VXI11SocketFactory.java
@@ -4,40 +4,35 @@
import java.net.InetAddress;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-
import org.jtmc.core.visa.exception.UnsupportedSocketException;
import org.jtmc.core.visa.factory.ISocketFactory;
/**
- * This factory class is capable of creating VXI-11 sockets for SCPI
- * communication
- *
- *
- * It supports the VISA resource string syntax for VXI-11 sockets.
- *
- * Format: TCPIP[board]::[host address][::Instrument Name][::INSTR]
+ * This factory class is capable of creating VXI-11 sockets from VISA
+ * resource strings.
+ *
+ *
Format: TCPIP[board]::[host address][::Instrument Name][::INSTR]
*/
public class VXI11SocketFactory implements ISocketFactory {
- private Pattern pattern = Pattern.compile("TCPIP(?[0-9]*)::(?[^:]{1,})(::?[^:]{1,})?(::INSTR)?");
-
- @Override
- public boolean supports(String resourceString) {
- return pattern.matcher(resourceString).matches();
- }
-
- @Override
- public VXI11Socket create(String resourceString) throws IOException, UnsupportedSocketException {
- Matcher matcher = pattern.matcher(resourceString);
- if(!matcher.matches()) {
- throw new UnsupportedSocketException();
- }
- //int board = Integer.parseInt(matcher.group("board"));
- String host = matcher.group("host");
- String instrument = matcher.group("instrument");
-
- return new VXI11Socket(InetAddress.getByName(host), 0, instrument);
- }
-
-
-}
\ No newline at end of file
+ private static final Pattern pattern = Pattern.compile(
+ "TCPIP(?[0-9]*)::(?[^:]{1,})(::?[^:]{1,})?(::INSTR)?");
+
+ @Override
+ public boolean supports(String resourceString) {
+ return pattern.matcher(resourceString).matches();
+ }
+
+ @Override
+ public VXI11Socket create(String resourceString) throws IOException, UnsupportedSocketException {
+ Matcher matcher = pattern.matcher(resourceString);
+ if (!matcher.matches()) {
+ throw new UnsupportedSocketException();
+ }
+ //int board = Integer.parseInt(matcher.group("board"));
+ String host = matcher.group("host");
+ String instrument = matcher.group("instrument");
+
+ return new VXI11Socket(InetAddress.getByName(host), 0, instrument);
+ }
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/package-info.java b/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/package-info.java
new file mode 100644
index 0000000..e991d32
--- /dev/null
+++ b/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Contains classes for interaction with VXI11 based instruments.
+ */
+package org.jtmc.core.lxi.vxi11;
diff --git a/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/portmap/Portmap.java b/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/portmap/Portmap.java
index fc15e64..bbfef9d 100644
--- a/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/portmap/Portmap.java
+++ b/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/portmap/Portmap.java
@@ -1,17 +1,19 @@
package org.jtmc.core.lxi.vxi11.portmap;
/**
- * Portmap
+ * Portmap is a service of ONC RPC for finding
+ * RPC endpoints on a network. This class contains constants
+ * used by the protocol.
*
- * https://tools.ietf.org/html/rfc1833
+ *
More information: https://tools.ietf.org/html/rfc1833
*/
public class Portmap {
- public final static int PROGRAM = 100000;
+ public static final int PROGRAM = 100000;
- public final static int VERSION = 2;
+ public static final int VERSION = 2;
- public final static int PORT = 111;
+ public static final int PORT = 111;
- public final static int PROC_GETPORT = 3;
-}
\ No newline at end of file
+ public static final int PROC_GETPORT = 3;
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/portmap/PortmapParams.java b/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/portmap/PortmapParams.java
index cb9f16d..143302b 100644
--- a/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/portmap/PortmapParams.java
+++ b/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/portmap/PortmapParams.java
@@ -7,41 +7,52 @@
import org.acplt.oncrpc.XdrDecodingStream;
import org.acplt.oncrpc.XdrEncodingStream;
+/**
+ * PortmapParams contains request information for Portmap requests.
+ */
public class PortmapParams implements XdrAble {
- private int program;
-
- private int version;
-
- private int protocol;
-
- private int port;
-
- private int data = 0;
-
- public PortmapParams(int program, int version, int protocol, int port) {
- this.program = program;
- this.version = version;
- this.protocol = protocol;
- this.port = port;
- }
-
- @Override
- public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException {
- xdr.xdrEncodeInt(program);
- xdr.xdrEncodeInt(version);
- xdr.xdrEncodeInt(protocol);
- xdr.xdrEncodeInt(port);
- xdr.xdrEncodeInt(data);
- }
-
- @Override
- public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException {
- program = xdr.xdrDecodeInt();
- version = xdr.xdrDecodeInt();
- protocol = xdr.xdrDecodeInt();
- port = xdr.xdrDecodeInt();
- data = xdr.xdrDecodeInt();
- }
-
-}
\ No newline at end of file
+ private int program;
+
+ private int version;
+
+ private int protocol;
+
+ private int port;
+
+ private int data = 0;
+
+ /**
+ * Constructs a new PortmapParam request container.
+ *
+ * @param program Program ID to discover
+ * @param version Program Version number
+ * @param protocol Underlying protocol (TCP or UDP)
+ * @param port Port number
+ */
+ public PortmapParams(int program, int version, int protocol, int port) {
+ this.program = program;
+ this.version = version;
+ this.protocol = protocol;
+ this.port = port;
+ }
+
+ @Override
+ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException {
+ xdr.xdrEncodeInt(program);
+ xdr.xdrEncodeInt(version);
+ xdr.xdrEncodeInt(protocol);
+ xdr.xdrEncodeInt(port);
+ xdr.xdrEncodeInt(data);
+ }
+
+ @Override
+ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException {
+ program = xdr.xdrDecodeInt();
+ version = xdr.xdrDecodeInt();
+ protocol = xdr.xdrDecodeInt();
+ port = xdr.xdrDecodeInt();
+ data = xdr.xdrDecodeInt();
+ }
+
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/portmap/PortmapResponse.java b/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/portmap/PortmapResponse.java
index d618c83..07fd3c1 100644
--- a/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/portmap/PortmapResponse.java
+++ b/measure-core/src/main/java/org/jtmc/core/lxi/vxi11/portmap/PortmapResponse.java
@@ -1,28 +1,32 @@
package org.jtmc.core.lxi.vxi11.portmap;
import java.io.IOException;
-
import org.acplt.oncrpc.OncRpcException;
import org.acplt.oncrpc.XdrAble;
import org.acplt.oncrpc.XdrDecodingStream;
import org.acplt.oncrpc.XdrEncodingStream;
/**
- * PortmapResponse
+ * PortmapResponse contains response information for Portmap responses.
*/
public class PortmapResponse implements XdrAble {
- private int port;
+ private int port;
- public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException {
- xdr.xdrEncodeInt(port);
- }
+ public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException {
+ xdr.xdrEncodeInt(port);
+ }
- public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException {
- port = xdr.xdrDecodeInt();
- }
-
- public int getPort() {
- return port;
- }
-}
\ No newline at end of file
+ public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException {
+ port = xdr.xdrDecodeInt();
+ }
+
+ /**
+ * Returns the port number for the given response.
+ *
+ * @return Port number
+ */
+ public int getPort() {
+ return port;
+ }
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/scpi/ISCPISocket.java b/measure-core/src/main/java/org/jtmc/core/scpi/ISCPISocket.java
index dca822d..155e9ae 100644
--- a/measure-core/src/main/java/org/jtmc/core/scpi/ISCPISocket.java
+++ b/measure-core/src/main/java/org/jtmc/core/scpi/ISCPISocket.java
@@ -2,90 +2,113 @@
import java.io.IOException;
import java.net.SocketTimeoutException;
-
import org.jtmc.core.visa.DeviceIdentifier;
/**
- * ISCPISocket is the standard interface for sending SCPI commands and receiving responses
+ * ISCPISocket is the standard interface for sending SCPI commands
+ * and receiving responses.
*/
public interface ISCPISocket {
- public final static long DEFAULT_TIMEOUT = 1000;
+ public static final long DEFAULT_TIMEOUT = 1000;
+
+ /**
+ * Sends SCPI commands to the device, how they're being sent is up to
+ * the socket implementation.
+ *
+ *
The operation should be atomic, so either all commands should succeed
+ * or the device's state shall not change
+ *
+ * @param commands SCPI commands to send
+ * @throws IOException if there was an error communication with the device
+ */
+ public void send(SCPICommand... commands) throws IOException;
- /**
- * Sends SCPI commands to the device, how they're being sent is up to the socket implementation
- *
- * The operation should be atomic, so either all commands should succeed or the device's state shall not change
- *
- * @param commands SCPI commands to send
- * @throws IOException if
- */
- public void send(SCPICommand... commands) throws IOException;
+ /**
+ * Receives a SCPI response from the device.
+ *
+ *
The operation has to return {@code Optional.empty()} if the method
+ * timed out with no response.
+ *
+ * @param timeout Time to wait for a response, if 0 then wait indefinitely
+ * @return Device response as string
+ * @throws IOException if there was an error communication with the device
+ */
+ public String receive(long timeout)
+ throws SocketTimeoutException, IOException;
- /**
- * Receives a SCPI response from the device
- *
- * The operation has to return {@code Optional.empty()} if the method timed out with no response
- *
- * @param timeout Time to wait for a response, if 0 then wait indefinitely
- * @return Device response as string
- * @throws IOException If the
- */
- public String receive(long timeout) throws SocketTimeoutException, IOException;
+ /**
+ * Receives part of the response from the device, up until the
+ * given character count has been reached.
+ *
+ * @param count Number of characters to receive
+ * @param timeout Maximum time to wait for a response
+ * @return Device response as string
+ * @throws IOException if there was an error communication with the device
+ */
+ String receive(int count, long timeout)
+ throws SocketTimeoutException, IOException;
- /**
- * Receives part of the response from the device, up until the given character count has been reached
- * @param count
- * @param timeout
- * @return
- * @throws IOException
- */
- String receive(int count, long timeout) throws SocketTimeoutException, IOException;
+ /**
+ * Sends a SCPI command to the device and then waits for a response.
+ *
+ * @param command SCPI command to send
+ * @param timeout Maximum time to wait for a response
+ * @return Response to the SCPI command
+ * @throws IOException if there was an error communication with the device
+ */
+ default String query(SCPICommand command, long timeout)
+ throws SocketTimeoutException, IOException {
+ this.send(command);
+ return this.receive(timeout);
+ }
- /**
- * Sends a SCPI command to the device and then waits for a response
- * @param command
- * @param timeout
- * @return
- * @throws IOException
- */
- default String query(SCPICommand command, long timeout) throws SocketTimeoutException, IOException {
- this.send(command);
- return this.receive(timeout);
- }
+ /**
+ * Returns the device identifier of the SCPI device this socket is connected
+ * to by sending an {@code *IDN?} query to the device.
+ *
+ * @return Device Identifier
+ * @throws SocketTimeoutException if the device didn't respond within
+ * the default timeout
+ * @throws IOException if there was an error communicating with the device
+ */
+ default DeviceIdentifier getDeviceIdentifier()
+ throws SocketTimeoutException, IOException {
+ try {
+ return DeviceIdentifier.from(this.query(SCPI.idnQuery, DEFAULT_TIMEOUT));
+ } catch (IllegalArgumentException e) {
+ throw new IOException("Cannot resolve device identifier", e);
+ }
+ }
- /**
- * Returns the device identifier of the SCPI device this socket is connected to by sending
- * an {@code *IDN?} query to the device
- *
- * @return Device Identifier
- * @throws SocketTimeoutException if the device didn't respond within the default timeout
- * @throws IOException if there was an error communicating with the device
- */
- default DeviceIdentifier getDeviceIdentifier() throws SocketTimeoutException, IOException {
- try {
- return DeviceIdentifier.from(this.query(SCPI.idnQuery, DEFAULT_TIMEOUT));
- } catch(IllegalArgumentException e) {
- throw new IOException("Cannot resolve device identifier", e);
- }
- }
+ /**
+ * Resets the device by sending the standard SCPI reset command.
+ *
+ * @see SCPI.resetDevice
+ * @throws IOException if there was an error communication with the device
+ */
+ default void reset() throws IOException {
+ this.send(SCPI.resetDevice);
+ }
- /**
- * Resets the device by sending the standard SCPI reset command
- *
- * @see SCPI.resetDevice
- * @throws IOException
- */
- default void reset() throws IOException {
- this.send(SCPI.resetDevice);
- }
+ /**
+ * Clears the device status by sending the standard SCPI status clear command.
+ *
+ * @throws IOException if there was an error communication with the device
+ */
+ default void clearStatus() throws IOException {
+ this.send(SCPI.clearStatus);
+ }
- default void clearStatus() throws IOException {
- this.send(SCPI.clearStatus);
- }
+ /**
+ * Sends an operation complete query to the device then waits for a response.
+ *
+ * @param timeout Maximum time to wait for the operation to complete
+ * @throws IOException if there was an error communication with the device
+ */
+ default void waitForOperation(long timeout) throws IOException {
+ this.send(SCPI.opcQuery);
+ this.receive(timeout);
+ }
- default void waitForOperation(long timeout) throws IOException {
- this.send(SCPI.opcQuery);
- this.receive(timeout);
- }
-}
\ No newline at end of file
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/scpi/SCPI.java b/measure-core/src/main/java/org/jtmc/core/scpi/SCPI.java
index 8590f5d..640044a 100644
--- a/measure-core/src/main/java/org/jtmc/core/scpi/SCPI.java
+++ b/measure-core/src/main/java/org/jtmc/core/scpi/SCPI.java
@@ -1,32 +1,35 @@
package org.jtmc.core.scpi;
/**
- * Includes standard SCPI commands, such as resetting the device, waiting for an operation
+ * Includes standard SCPI commands, such as resetting the device,
+ * waiting for an operation.
*/
public final class SCPI {
- /**
- * The standard command to query a device's identifier
- *
- * The response is four comma-separated fields 'Manufacturer,Model,SerialNumber,FirmwareVersion'
- */
- public final static SCPICommand idnQuery = SCPICommand.builder().query("*IDN").build();
+ /**
+ * The standard command to query a device's identifier.
+ *
+ *
The response is four comma-separated fields
+ * 'Manufacturer,Model,SerialNumber,FirmwareVersion'
+ */
+ public static final SCPICommand idnQuery = SCPICommand.builder().query("*IDN").build();
- /**
- * The standard command to query whether the device has finished it's last operation
- *
- * In sequential mode the response is a single '1' character
- */
- public final static SCPICommand opcQuery = SCPICommand.builder().query("*OPC").build();
+ /**
+ * The standard command to query whether the device has finished
+ * it's last operation.
+ *
+ *
In sequential mode the response is a single '1' character
+ */
+ public static final SCPICommand opcQuery = SCPICommand.builder().query("*OPC").build();
- /**
- * The standard command to reset the device into a known state
- *
- * The reset state is dependent on the particular device
- */
- public final static SCPICommand resetDevice = SCPICommand.builder().command("*RST").build();
+ /**
+ * The standard command to reset the device into a known state.
+ *
+ *
The reset state is dependent on the particular device
+ */
+ public static final SCPICommand resetDevice = SCPICommand.builder().command("*RST").build();
- public final static SCPICommand clearStatus = SCPICommand.builder().query("*CLS").build();
+ public static final SCPICommand clearStatus = SCPICommand.builder().query("*CLS").build();
- public final static SCPICommand testDevice = SCPICommand.builder().query("*TST").build();
-}
\ No newline at end of file
+ public static final SCPICommand testDevice = SCPICommand.builder().query("*TST").build();
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/scpi/SCPICommand.java b/measure-core/src/main/java/org/jtmc/core/scpi/SCPICommand.java
index 3755082..512fde7 100644
--- a/measure-core/src/main/java/org/jtmc/core/scpi/SCPICommand.java
+++ b/measure-core/src/main/java/org/jtmc/core/scpi/SCPICommand.java
@@ -8,261 +8,231 @@
import java.util.Optional;
/**
- * SCPICommand is a message understood by SCPI devices
- *
- *
- * In general the command format:
- *
- * ROOT:SUB:CMD PARAM1,PARAM2,...
- *
+ * SCPICommand is a message understood by SCPI devices.
*
+ *
In general the command format: "ROOT:SUB:CMD PARAM1,PARAM2,..."
*/
public final class SCPICommand {
- private String raw;
-
- private String command;
-
- private List parameters;
-
- /**
- * Constructs a SCPICommand using the command and a list of parameters
- * @param command Command
- * @param params List of parameters
- */
- public SCPICommand(String command, List params) {
- if(command.contains(" ") || command.contains(",")) {
- throw new IllegalArgumentException("Invalid command");
- }
- this.command = command;
- this.parameters = Collections.unmodifiableList(params);
- this.raw = this.toString();
- }
-
- /**
- * Constructs a SCPICommand using the command and an array of parameters
- *
- * @param command Command
- * @param params Parameters
- */
- public SCPICommand(String command, String... params) {
- this(command, Arrays.asList(params));
- }
-
- /**
- * Constructs a SCPICommand from it's raw string representation
- * @param raw Raw string (CMD:SUBCMD PARAM1,PARAM2)
- */
- public SCPICommand(String raw) {
- this.raw = raw;
-
- int firstSpace = this.raw.indexOf(" ");
- if(firstSpace == -1 || firstSpace == raw.length()) {
- this.command = this.raw;
- this.parameters = Collections.unmodifiableList(Collections.emptyList());
- }
- else {
- this.command = raw.substring(0, firstSpace);
- String[] params = raw.substring(firstSpace+1, raw.length()).split(",");
- this.parameters = Collections.unmodifiableList(Arrays.asList(params));
- }
- }
-
- /**
- * @return the command
- */
- public String getCommand() {
- return command;
- }
-
- /**
- * @return the raw
- */
- public String getRaw() {
- return raw;
- }
-
- /**
- * @return the parameters
- */
- public List getParameters() {
- return parameters;
- }
-
- /**
- * Returns the SCPI command in it's string format, equivalent to {@see getRaw()}
- *
- * @return SCPI command string
- */
- @Override
- public String toString() {
- if(raw != null) {
- return raw;
- }
- StringBuilder builder = new StringBuilder();
- builder.append(this.getCommand());
- if(this.getParameters().size() != 0) {
- builder.append(" ");
- }
- Iterator it = this.getParameters().iterator();
- while(it.hasNext()) {
- String param = it.next();
- builder.append(param);
- if(it.hasNext()) {
- builder.append(",");
- }
- }
- return builder.toString();
- }
-
- /**
- * Returns the given parameter's value
- *
- * E.g: for {@code CMD PARAM1,VALUE1}, {@code getParameter("PARAM1")} would return VALUE1
- *
- * @param name Parameter's name
- * @return Parameter's value, empty if parameter doesn't exist or doesn't have a value associated to it
- */
- public Optional getParameter(String name) {
- Iterator it = parameters.iterator();
- while(it.hasNext()) {
- if(it.next().equals(name)) {
- if(it.hasNext()) {
- return Optional.of(it.next());
- }
- else {
- return Optional.empty();
- }
- }
- }
- return Optional.empty();
- }
-
- /**
- * Returns the given parameter's value as float
- *
- * @param name Parameter's name
- * @return Parameter's value
- *
- * @throws NumberFormatException if the value can't be parsed as float
- */
- public Optional getFloat(String name) {
- return this.getParameter(name)
- .map(value -> value != null ? Float.parseFloat(value) : null);
- }
-
- /**
- * Returns the given parameter's value as int
- *
- * @param name Parameter's name
- * @return Parameter's value
- *
- * @throws NumberFormatException if the value can't be parsed as integer
- */
- public Optional getInt(String name) {
- return this.getParameter(name)
- .map(value -> value != null ? Integer.parseInt(value) : null);
- }
-
- /**
- * Returns whether or not the given parameter exists
- *
- * @param param Parameter's name
- * @return {@code true} if there's such parameter
- */
- public boolean hasParameter(String param) {
- return this.parameters.contains(param);
- }
-
- /**
- * Returns a mutable command builder
- *
- * @return Mutable builder instance
- */
- public static Builder builder() {
- return new Builder();
- }
-
- /**
- * A mutable class for building SCPI commands
- *
- *
- * Method calls can be chained for compact usage
- *
- *
For more information see
+ * SCPI-99 Standard
*/
-package org.jtmc.core.scpi;
\ No newline at end of file
+package org.jtmc.core.scpi;
diff --git a/measure-core/src/main/java/org/jtmc/core/scpi/socket/RawSCPISocket.java b/measure-core/src/main/java/org/jtmc/core/scpi/socket/RawSCPISocket.java
index 7bc6af3..1983720 100644
--- a/measure-core/src/main/java/org/jtmc/core/scpi/socket/RawSCPISocket.java
+++ b/measure-core/src/main/java/org/jtmc/core/scpi/socket/RawSCPISocket.java
@@ -5,14 +5,13 @@
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
-
import org.jtmc.core.device.ISocket;
import org.jtmc.core.scpi.ISCPISocket;
import org.jtmc.core.scpi.SCPICommand;
/**
* RawSCPISocket implements the most common way of sending SCPI commands
- * to instruments
+ * to instruments.
*
*
By default it will send SCPI commands as is with newline terminations appended
* after each command
@@ -21,83 +20,91 @@
*/
public class RawSCPISocket implements ISCPISocket {
- public final static char DEFAULT_TERMINATION = '\n';
+ public static final char DEFAULT_TERMINATION = '\n';
- public final static char DEFAULT_SEPARATOR = ';';
+ public static final char DEFAULT_SEPARATOR = ';';
- private final char termination;
+ private final char termination;
- private final char separator;
+ private final char separator;
- private final ISocket socket;
+ private final ISocket socket;
- private final Charset charset;
+ private final Charset charset;
- /**
- * Constructs a RawSCPISocket with the default termination and separator characters
- *
- * @param socket Socket to the instrument
- */
- public RawSCPISocket(final ISocket socket) {
- this(socket, DEFAULT_TERMINATION, DEFAULT_SEPARATOR);
- }
+ /**
+ * Constructs a RawSCPISocket with the default termination and
+ * separator characters.
+ *
+ * @param socket Socket to the instrument
+ */
+ public RawSCPISocket(final ISocket socket) {
+ this(socket, DEFAULT_TERMINATION, DEFAULT_SEPARATOR);
+ }
- /**
- * Constructs a RawSCPISocket with the provided termination and separator characters
- *
- * @param socket Socket to the instrument
- * @param termination Character used to terminate all commands
- * @param separator Character used to separate commands
- */
- public RawSCPISocket(final ISocket socket, final char termination, final char separator) {
- this(socket, termination, separator, StandardCharsets.ISO_8859_1);
- }
+ /**
+ * Constructs a RawSCPISocket with the provided termination and
+ * separator characters.
+ *
+ * @param socket Socket to the instrument
+ * @param termination Character used to terminate all commands
+ * @param separator Character used to separate commands
+ */
+ public RawSCPISocket(final ISocket socket, final char termination, final char separator) {
+ this(socket, termination, separator, StandardCharsets.ISO_8859_1);
+ }
- /**
- * Constructs a RawSCPISocket with the default termination and separator characters
- *
- * @param socket Socket to the instrument
- * @param termination Character used to terminate all commands
- * @param separator Character used to separate commands
- * @param charset Character encoding to use
- */
- public RawSCPISocket(final ISocket socket, final char termination, final char separator, final Charset charset) {
- this.socket = socket;
- this.termination = termination;
- this.separator = separator;
- this.charset = charset;
- }
+ /**
+ * Constructs a RawSCPISocket with the default termination and
+ * separator characters.
+ *
+ * @param socket Socket to the instrument
+ * @param termination Character used to terminate all commands
+ * @param separator Character used to separate commands
+ * @param charset Character encoding to use
+ */
+ public RawSCPISocket(
+ final ISocket socket,
+ final char termination,
+ final char separator,
+ final Charset charset) {
+ this.socket = socket;
+ this.termination = termination;
+ this.separator = separator;
+ this.charset = charset;
+ }
- @Override
- public void send(SCPICommand... commands) throws IOException {
- if(commands.length == 0) {
- return;
- }
- ByteBuffer output = ByteBuffer.wrap(concat(this.termination, this.separator, commands).getBytes(charset));
- socket.send(output);
- }
+ @Override
+ public void send(SCPICommand... commands) throws IOException {
+ if (commands.length == 0) {
+ return;
+ }
+ ByteBuffer output = ByteBuffer.wrap(
+ concat(this.termination, this.separator, commands).getBytes(charset));
+ socket.send(output);
+ }
- @Override
- public String receive(long timeout) throws SocketTimeoutException, IOException {
- ByteBuffer response = socket.receive(this.termination, timeout);
- return new String(response.array(), charset);
- }
+ @Override
+ public String receive(long timeout) throws SocketTimeoutException, IOException {
+ ByteBuffer response = socket.receive(this.termination, timeout);
+ return new String(response.array(), charset);
+ }
- @Override
- public String receive(int count, long timeout) throws SocketTimeoutException, IOException {
- ByteBuffer response = socket.receive(count, timeout);
- return new String(response.array(), charset);
- }
-
- static String concat(char termination, char separator, SCPICommand... commands) {
- StringBuilder builder = new StringBuilder();
- for(int i=0;i[0-9]+)/(?[0-9])/(?[NOEMS])/(?[12])");
-
- /**
- * Constructs a SerialSocket using a string configuration
- *
- *
Format: Baudrate/Databits/Parity/Stopbits
- *
- *
Baudrate: any integer
- *
Databits: integer, 5-8
- *
Parity: N (None), O (Odd), E (Even), M (Mark), S (Space)
- *
- *
Example: 9600/8/N/1
- *
- * @param port Port identifier, on Windows COMn, on Unix /dev/ttySn
- * @param params Configuration as string
- * @return Serial socket
- * @throws IOException
- */
- public static SerialSocket create(String port, String params) throws IOException {
- Matcher matcher = CONFIG_PATTERN.matcher(params);
- if(!matcher.matches()) {
- throw new IllegalArgumentException("Invalid serial socket configuration: " + params);
- }
- int baudrate = Integer.parseInt(matcher.group("baudrate"));
- int databits = Integer.parseInt(matcher.group("databits"));
- String parity = matcher.group("parity");
- int stopbits = Integer.parseInt(matcher.group("stopbits"));
-
- return new SerialSocket(port, baudrate, databits, Parity.valueOf(parity.charAt(0)), StopBits.valueOf(stopbits));
- }
-
- @Override
- public void close() {
- socket.closePort();
- }
-
- @Override
- public boolean isConnected() {
- return this.socket != null && this.socket.isOpen();
- }
-
- @Override
- public String getResourceString() {
- return "ASRL" + SerialSocketFactory.getPortNumber(this.socket.getSystemPortName());
- }
-
- @Override
- public void send(ByteBuffer message) throws IOException, SerialPortIOException, SerialPortTimeoutException {
- if(socket == null) {
- throw new IOException("Socket is closed.");
- }
- if(!message.hasArray()) {
- throw new IllegalArgumentException("Message empty.");
- }
- socket.getOutputStream().write(message.array());
- }
-
- @Override
- public ByteBuffer receive(int count, long timeout) throws IOException, SocketTimeoutException {
- //int previousTimeout = socket.getSerialPortTimeout();
- //socket.setSerialPortTimeout((int)timeout);
- //socket.setComPortTimeouts(newTimeoutMode, newReadTimeout, newWriteTimeout);
-
- byte[] input = new byte[count];
- socket.getInputStream().read(input);
-
- //socket.setSerialPortTimeout(previousTimeout);
-
- return ByteBuffer.wrap(input);
- }
-
- @Override
- public ByteBuffer receive(char delimiter, long timeout) throws IOException, SocketTimeoutException {
- try {
- //int previousTimeout = socket.getSerialPortTimeout();
- //socket.setSerialPortTimeout((int)timeout);
-
- ArrayList input = new ArrayList<>();
- byte in = (byte) socket.getInputStream().read();
- while(in != delimiter) {
- input.add(in);
- in = (byte) socket.getInputStream().read();
- }
- //socket.setSerialPortTimeout(previousTimeout);
- ByteBuffer bytes = ByteBuffer.allocate(input.size());
- for(byte b : input) {
- bytes.put(b);
- }
- return bytes;
- } catch(SerialPortTimeoutException e) {
- throw new SocketTimeoutException(e.getMessage());
- }
- }
-
-}
\ No newline at end of file
+ private SerialPort socket;
+
+ /**
+ * Constructs a Serial socket with the provided baudrate and default 8 bit data length,
+ * no parity and a single stopbit. Flow control is disabled.
+ *
+ * @param port Port identifier, on Windows COMn, on Unix /dev/ttySn
+ * @param baudrate Baudrate
+ * @throws IOException if there was an error opening the socket
+ */
+ public SerialSocket(String port, int baudrate) throws IOException {
+ this(port, baudrate, 8, Parity.NONE, StopBits.ONE);
+ }
+
+ /**
+ * Constructs a Serial socket with the provided parameters. Flow control is disabled.
+ *
+ * @param port Port identifier, on Windows COMn, on Unix /dev/ttySn
+ * @param baudrate Baudrate
+ * @param databits Number of databits, valid values are {@code 5-8}
+ * @param parity Parity bit (None, Even, Odd, Mark, Space)
+ * @param stopbits Stop bit count
+ * @throws IOException if there was an error opening the socket
+ */
+ public SerialSocket(
+ String port,
+ int baudrate,
+ int databits,
+ Parity parity,
+ StopBits stopbits) throws IOException {
+ this(port, baudrate, databits, parity, stopbits, FlowControl.NONE);
+ }
+
+ /**
+ * Constructs a Serial socket with the provided parameters.
+ *
+ * @param port Port identifier, on Windows COMn, on Unix /dev/ttySn
+ * @param baudrate Baudrate
+ * @param databits Number of databits, valid values are {@code 5-8}
+ * @param parity Parity bit (None, Even, Odd, Mark, Space)
+ * @param stopbits Stop bit count
+ * @param flowControl Flow control mode
+ * @throws IOException if there was an error opening the socket
+ */
+ public SerialSocket(
+ String port,
+ int baudrate,
+ int databits,
+ Parity parity,
+ StopBits stopbits,
+ FlowControl flowControl) throws IOException {
+ this.socket = SerialPort.getCommPort(port);
+ this.socket.openPort();
+ this.socket.setBaudRate(baudrate);
+ this.socket.setNumDataBits(databits);
+ this.socket.setParity(parity.getId());
+ this.socket.setNumStopBits(stopbits.getId());
+ this.socket.setFlowControl(flowControl.getValue());
+ }
+
+ private static final Pattern CONFIG_PATTERN = Pattern.compile(
+ "(?[0-9]+)/(?[0-9])/(?[NOEMS])/(?[12])");
+
+ /**
+ * Constructs a SerialSocket using a string configuration.
+ *
+ *
Format: Baudrate/Databits/Parity/Stopbits
+ *
+ *
Baudrate: any integer
+ *
+ *
Databits: integer, 5-8
+ *
+ *
Parity: N (None), O (Odd), E (Even), M (Mark), S (Space)
+ *
+ *
Example: 9600/8/N/1
+ *
+ * @param port Port identifier, on Windows COMn, on Unix /dev/ttySn
+ * @param params Configuration as string
+ * @return Serial socket
+ * @throws IOException if there was an error opening the socket
+ */
+ public static SerialSocket create(String port, String params) throws IOException {
+ Matcher matcher = CONFIG_PATTERN.matcher(params);
+ if (!matcher.matches()) {
+ throw new IllegalArgumentException("Invalid serial socket configuration: " + params);
+ }
+ int baudrate = Integer.parseInt(matcher.group("baudrate"));
+ int databits = Integer.parseInt(matcher.group("databits"));
+ String parity = matcher.group("parity");
+ String stopbits = matcher.group("stopbits");
+
+ return new SerialSocket(
+ port,
+ baudrate,
+ databits,
+ Parity.valueOf(parity.charAt(0)),
+ StopBits.from(stopbits));
+ }
+
+ @Override
+ public void close() {
+ socket.closePort();
+ }
+
+ @Override
+ public boolean isConnected() {
+ return this.socket != null && this.socket.isOpen();
+ }
+
+ @Override
+ public String getResourceString() {
+ return "ASRL" + SerialSocketFactory.getPortNumber(this.socket.getSystemPortName());
+ }
+
+ @Override
+ public void send(ByteBuffer message)
+ throws IOException, SerialPortIOException, SerialPortTimeoutException {
+ if (socket == null) {
+ throw new IOException("Socket is closed.");
+ }
+ if (!message.hasArray()) {
+ throw new IllegalArgumentException("Message empty.");
+ }
+ socket.getOutputStream().write(message.array());
+ }
+
+ @Override
+ public ByteBuffer receive(int count, long timeout)
+ throws IOException, SocketTimeoutException {
+ //int previousTimeout = socket.getSerialPortTimeout();
+ //socket.setSerialPortTimeout((int)timeout);
+ //socket.setComPortTimeouts(newTimeoutMode, newReadTimeout, newWriteTimeout);
+
+ byte[] input = new byte[count];
+ socket.getInputStream().read(input);
+
+ //socket.setSerialPortTimeout(previousTimeout);
+
+ return ByteBuffer.wrap(input);
+ }
+
+ @Override
+ public ByteBuffer receive(char delimiter, long timeout)
+ throws IOException, SocketTimeoutException {
+ try {
+ //int previousTimeout = socket.getSerialPortTimeout();
+ //socket.setSerialPortTimeout((int)timeout);
+
+ ArrayList input = new ArrayList<>();
+ byte in = (byte) socket.getInputStream().read();
+ while (in != delimiter) {
+ input.add(in);
+ in = (byte) socket.getInputStream().read();
+ }
+ //socket.setSerialPortTimeout(previousTimeout);
+ ByteBuffer bytes = ByteBuffer.allocate(input.size());
+ for (byte b : input) {
+ bytes.put(b);
+ }
+ return bytes;
+ } catch (SerialPortTimeoutException e) {
+ throw new SocketTimeoutException(e.getMessage());
+ }
+ }
+
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/serial/SerialSocketFactory.java b/measure-core/src/main/java/org/jtmc/core/serial/SerialSocketFactory.java
index 334caac..ef27133 100644
--- a/measure-core/src/main/java/org/jtmc/core/serial/SerialSocketFactory.java
+++ b/measure-core/src/main/java/org/jtmc/core/serial/SerialSocketFactory.java
@@ -6,44 +6,48 @@
import org.jtmc.core.visa.factory.ISocketFactory;
/**
- * SerialSocketFactory
+ * SerialSocketFactory can be used to instantiate Serial Socket using
+ * a VISA resource string.
*/
public class SerialSocketFactory implements ISocketFactory {
- private Pattern pattern = Pattern.compile("ASRL(?[0-9]*)::INSTR");
-
- @Override
- public boolean supports(String connectionInfo) {
- return pattern.matcher(connectionInfo).matches();
- }
-
- @Override
- public SerialSocket create(String connectionInfo) throws IOException {
- Matcher matcher = pattern.matcher(connectionInfo);
- if(matcher.matches()) {
- int port = Integer.parseInt(matcher.group("port"));
- //TODO: serial configuration
- return new SerialSocket(getPortPath(port), 9600);
- }
- throw new IllegalArgumentException(connectionInfo + " doesn't match " + pattern.pattern());
- }
-
- /**
- *
- * @param port
- * @return
- */
- public static String getPortPath(int port) {
- String os = System.getProperty("os.name");
- if(os.startsWith("Windows")) {
- return "COM" + port;
- } else if(os.contains("nix") || os.contains("nux")) {
- return "/dev/ttyS" + port;
- }
- return null;
- }
-
- public static int getPortNumber(String portPath) {
- return 0;
- }
-}
\ No newline at end of file
+ private static final Pattern pattern = Pattern.compile(
+ "ASRL(?[0-9]*)::INSTR");
+
+ @Override
+ public boolean supports(String connectionInfo) {
+ return pattern.matcher(connectionInfo).matches();
+ }
+
+ @Override
+ public SerialSocket create(String connectionInfo) throws IOException {
+ Matcher matcher = pattern.matcher(connectionInfo);
+ if (matcher.matches()) {
+ int port = Integer.parseInt(matcher.group("port"));
+ //TODO: serial configuration
+ return new SerialSocket(getPortPath(port), 9600);
+ }
+ throw new IllegalArgumentException(connectionInfo + " doesn't match " + pattern.pattern());
+ }
+
+ /**
+ * Returns the serial port name for the given number.
+ *
+ * @param port Port number
+ * @return Serial port name
+ */
+ public static String getPortPath(int port) {
+ String os = System.getProperty("os.name");
+ if (os.startsWith("Windows")) {
+ return "COM" + port;
+ } else if (os.contains("nix") || os.contains("nux")) {
+ return "/dev/ttyS" + port;
+ }
+ return null;
+ }
+
+ public static int getPortNumber(String portPath) {
+ return 0;
+ }
+
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/serial/StopBits.java b/measure-core/src/main/java/org/jtmc/core/serial/StopBits.java
index d656313..0200534 100644
--- a/measure-core/src/main/java/org/jtmc/core/serial/StopBits.java
+++ b/measure-core/src/main/java/org/jtmc/core/serial/StopBits.java
@@ -2,38 +2,61 @@
import com.fazecast.jSerialComm.SerialPort;
+/**
+ * StopBits represents the spacing after each UART byte.
+ */
public enum StopBits {
- ONE(SerialPort.ONE_STOP_BIT, 1.0f),
- ONE_AND_HALF(SerialPort.ONE_POINT_FIVE_STOP_BITS, 1.5f),
- TWO(SerialPort.TWO_STOP_BITS, 2.0f);
-
- private int id;
-
- private float bitcount;
-
- private StopBits(int id, float bitcount) {
- this.id = id;
- this.bitcount = bitcount;
- }
-
- public int getId() {
- return id;
- }
-
- public float getBitCount() {
- return bitcount;
- }
-
- public static StopBits valueOf(float bitcount) {
- if(bitcount == 1.0f) {
- return StopBits.ONE;
- }
- else if(bitcount == 1.5f) {
- return StopBits.ONE_AND_HALF;
- }
- else if(bitcount == 2.0f) {
- return StopBits.TWO;
- }
- throw new IllegalArgumentException("Invalid stopbit value: " + bitcount);
- }
-}
\ No newline at end of file
+ ONE(SerialPort.ONE_STOP_BIT, 1.0f),
+ ONE_AND_HALF(SerialPort.ONE_POINT_FIVE_STOP_BITS, 1.5f),
+ TWO(SerialPort.TWO_STOP_BITS, 2.0f);
+
+ private int id;
+
+ private float bitcount;
+
+ private StopBits(int id, float bitcount) {
+ this.id = id;
+ this.bitcount = bitcount;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public float getBitCount() {
+ return bitcount;
+ }
+
+ /**
+ * Returns the stopbits for the given bitcount.
+ *
+ * @param bitcount Bitcount (floating)
+ * @return Stopbits
+ */
+ public static StopBits from(float bitcount) {
+ if (bitcount == 1.0f) {
+ return StopBits.ONE;
+ } else if (bitcount == 1.5f) {
+ return StopBits.ONE_AND_HALF;
+ } else if (bitcount == 2.0f) {
+ return StopBits.TWO;
+ }
+ throw new IllegalArgumentException("Invalid stopbit value: " + bitcount);
+ }
+
+ /**
+ * Returns the stopbits for the given bitcount.
+ *
+ * @param bitcount Bitcount (string), one of '1', '1.5', '2'
+ * @return Stopbits
+ */
+ public static StopBits from(String bitcount) {
+ switch (bitcount) {
+ case "1": return StopBits.ONE;
+ case "1.5": return StopBits.ONE_AND_HALF;
+ case "2": return StopBits.TWO;
+ default:
+ throw new IllegalArgumentException("Invalid stopbit value: " + bitcount);
+ }
+ }
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/signal/CompositeSignal.java b/measure-core/src/main/java/org/jtmc/core/signal/CompositeSignal.java
index 4adca94..e1b8b90 100644
--- a/measure-core/src/main/java/org/jtmc/core/signal/CompositeSignal.java
+++ b/measure-core/src/main/java/org/jtmc/core/signal/CompositeSignal.java
@@ -5,37 +5,37 @@
import java.util.Set;
/**
- * CompositeSignal
+ * CompositeSignal contains multiple time correlated signals.
*/
public class CompositeSignal> {
- private String id;
+ private String id;
- private Set> signals = new HashSet<>();
+ private Set> signals = new HashSet<>();
- public CompositeSignal(String id) {
- this.id = id;
- }
+ public CompositeSignal(String id) {
+ this.id = id;
+ }
- public CompositeSignal(Signal signal) {
- this(signal.getId());
- this.signals.add(signal);
- }
+ public CompositeSignal(Signal signal) {
+ this(signal.getId());
+ this.signals.add(signal);
+ }
- protected void add(Signal signal) {
- signals.add(signal);
- }
+ protected void add(Signal signal) {
+ signals.add(signal);
+ }
- public Optional> getSignal(String id) {
- return signals.stream().filter(signal -> signal.getId().equals(id)).findFirst();
- }
+ public Optional> getSignal(String id) {
+ return signals.stream().filter(signal -> signal.getId().equals(id)).findFirst();
+ }
- public Set> getSignals() {
- return signals;
- }
+ public Set> getSignals() {
+ return signals;
+ }
- public String getId() {
- return id;
- }
+ public String getId() {
+ return id;
+ }
-}
\ No newline at end of file
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/signal/Signal.java b/measure-core/src/main/java/org/jtmc/core/signal/Signal.java
index dd029d6..84d1249 100644
--- a/measure-core/src/main/java/org/jtmc/core/signal/Signal.java
+++ b/measure-core/src/main/java/org/jtmc/core/signal/Signal.java
@@ -7,81 +7,86 @@
import java.util.stream.Stream;
/**
+ * Signal is a container for time series values.
*
- * @param
+ * @param Value type
*/
public class Signal> {
-
- private String id;
-
- private TreeSet> data = new TreeSet>((a, b) -> Double.compare(a.time, b.time));
-
- public Signal(String id) {
- this.id = id;
- }
+
+ private String id;
+
+ private TreeSet> data = new TreeSet>(
+ (a, b) -> Double.compare(a.time, b.time));
+
+ public Signal(String id) {
+ this.id = id;
+ }
- public Signal(Signal signal) {
- this(signal.getId());
- this.data.addAll(signal.getData());
- }
+ public Signal(Signal signal) {
+ this(signal.getId());
+ this.data.addAll(signal.getData());
+ }
- public > Signal(Signal signal, Function transform) {
- this(signal.getId());
- signal.stream().map(p -> new DataPoint(p.time, transform.apply(p.value))).forEach(this::add);
- }
-
- public Set> getData() {
- return data;
- }
+ public > Signal(Signal signal, Function transform) {
+ this(signal.getId());
+ signal.stream().map(p -> new DataPoint(p.time, transform.apply(p.value))).forEach(this::add);
+ }
+
+ public Set> getData() {
+ return data;
+ }
- public String getId() {
- return id;
- }
-
- public void add(DataPoint dp) {
- this.data.add(dp);
- }
-
- public void add(double time, T value) {
- this.data.add(new DataPoint(time, value));
- }
+ public String getId() {
+ return id;
+ }
+
+ public void add(DataPoint dp) {
+ this.data.add(dp);
+ }
+
+ public void add(double time, T value) {
+ this.data.add(new DataPoint(time, value));
+ }
- public Stream> stream() {
- return this.data.stream();
- }
+ public Stream> stream() {
+ return this.data.stream();
+ }
- public T first() {
- return this.data.first().value;
- }
+ public T first() {
+ return this.data.first().value;
+ }
- public T last() {
- return this.data.last().value;
- }
-
- public double period() {
- return data.last().time;
- }
+ public T last() {
+ return this.data.last().value;
+ }
+
+ public double period() {
+ return data.last().time;
+ }
- public T min() {
- return Collections.min(data).value;
- }
+ public T min() {
+ return Collections.min(data).value;
+ }
- public T max() {
- return Collections.max(data).value;
- }
+ public T max() {
+ return Collections.max(data).value;
+ }
- public static class DataPoint> implements Comparable> {
- public final double time;
- public final T value;
+ /**
+ * DataPoint is a single measurement at a given time with a given value.
+ */
+ public static class DataPoint> implements Comparable> {
+ public final double time;
+ public final T value;
- public DataPoint(double time, T value) {
- this.time = time;
- this.value = value;
- }
-
- @Override
- public int compareTo(DataPoint arg0) {
- return this.value.compareTo(arg0.value);
- }
- }
+ public DataPoint(double time, T value) {
+ this.time = time;
+ this.value = value;
+ }
+
+ @Override
+ public int compareTo(DataPoint arg0) {
+ return this.value.compareTo(arg0.value);
+ }
+ }
}
diff --git a/measure-core/src/main/java/org/jtmc/core/signal/Waveform.java b/measure-core/src/main/java/org/jtmc/core/signal/Waveform.java
deleted file mode 100644
index a83cb40..0000000
--- a/measure-core/src/main/java/org/jtmc/core/signal/Waveform.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.jtmc.core.signal;
-
-import org.jtmc.core.util.EnumParameters;
-
-import org.jtmc.core.signal.Waveform.WaveformParameter;
-
-public class Waveform extends EnumParameters {
-
- public static enum WaveformParameter {
- PERIOD, FREQUENCY, AMPLITUDE, OFFSET, DUTY, SYMMETRY, PHASE, STDEV, MEAN, WIDTH, RISE, FALL, DELAY;
- }
-
- public static enum WaveformType {
- SINE, SQUARE, RAMP, PULSE, NOISE, DC;
- }
-
-}
\ No newline at end of file
diff --git a/measure-core/src/main/java/org/jtmc/core/signal/WaveformUtil.java b/measure-core/src/main/java/org/jtmc/core/signal/WaveformUtil.java
index c865f78..7f89328 100644
--- a/measure-core/src/main/java/org/jtmc/core/signal/WaveformUtil.java
+++ b/measure-core/src/main/java/org/jtmc/core/signal/WaveformUtil.java
@@ -1,9 +1,8 @@
package org.jtmc.core.signal;
/**
- * WaveformUtil
+ * WaveformUtil provides methods for creating waveforms.
*/
public class WaveformUtil {
-
-}
\ No newline at end of file
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/signal/analog/AnalogSampler.java b/measure-core/src/main/java/org/jtmc/core/signal/analog/AnalogSampler.java
index e56f6f7..dbb9b79 100644
--- a/measure-core/src/main/java/org/jtmc/core/signal/analog/AnalogSampler.java
+++ b/measure-core/src/main/java/org/jtmc/core/signal/analog/AnalogSampler.java
@@ -3,8 +3,8 @@
import org.jtmc.core.signal.sampler.Sampler;
/**
- * AnalogSampler takes an analog signal and transforms it into another analog signal
+ * AnalogSampler takes an analog signal and transforms it into another analog signal.
*/
public interface AnalogSampler extends Sampler {
-
-}
\ No newline at end of file
+
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/signal/analog/AnalogSignal.java b/measure-core/src/main/java/org/jtmc/core/signal/analog/AnalogSignal.java
index 6476c1c..b897641 100644
--- a/measure-core/src/main/java/org/jtmc/core/signal/analog/AnalogSignal.java
+++ b/measure-core/src/main/java/org/jtmc/core/signal/analog/AnalogSignal.java
@@ -4,24 +4,24 @@
import org.jtmc.core.signal.Signal;
/**
- * AnalogSignal
+ * AnalogSignal is a numeric signal consisting of a floating point number stream.
*/
public class AnalogSignal extends Signal {
- public AnalogSignal(String id) {
- super(id);
- }
+ public AnalogSignal(String id) {
+ super(id);
+ }
- public > AnalogSignal(Signal signal, Function transform) {
- super(signal, transform);
- }
+ public > AnalogSignal(Signal signal, Function transform) {
+ super(signal, transform);
+ }
- public double amplitude() {
- return max() - min();
- }
-
- public double offset() {
- return (max() + min()) / 2.0;
- }
-
-}
\ No newline at end of file
+ public double amplitude() {
+ return max() - min();
+ }
+
+ public double offset() {
+ return (max() + min()) / 2.0;
+ }
+
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/signal/digital/BinarySampler.java b/measure-core/src/main/java/org/jtmc/core/signal/digital/BinarySampler.java
index 3d4c036..64188af 100644
--- a/measure-core/src/main/java/org/jtmc/core/signal/digital/BinarySampler.java
+++ b/measure-core/src/main/java/org/jtmc/core/signal/digital/BinarySampler.java
@@ -3,9 +3,8 @@
import org.jtmc.core.signal.sampler.Sampler;
/**
- * BinarySampler takes a binary signal and outputs a transformed binary signal
+ * BinarySampler takes a binary signal and outputs a transformed binary signal.
*/
public interface BinarySampler extends Sampler {
-
-}
\ No newline at end of file
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/signal/digital/BinarySignal.java b/measure-core/src/main/java/org/jtmc/core/signal/digital/BinarySignal.java
index 59b4da8..b6cbfbd 100644
--- a/measure-core/src/main/java/org/jtmc/core/signal/digital/BinarySignal.java
+++ b/measure-core/src/main/java/org/jtmc/core/signal/digital/BinarySignal.java
@@ -3,12 +3,12 @@
import org.jtmc.core.signal.Signal;
/**
- * AnalogSignal
+ * BinarySignal is a logical signal consisting and 0's and 1's.
*/
public class BinarySignal extends Signal {
- public BinarySignal(String id) {
- super(id);
- }
-
-}
\ No newline at end of file
+ public BinarySignal(String id) {
+ super(id);
+ }
+
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/signal/sampler/EdgeSampler.java b/measure-core/src/main/java/org/jtmc/core/signal/sampler/EdgeSampler.java
index a6dbaa7..661c268 100644
--- a/measure-core/src/main/java/org/jtmc/core/signal/sampler/EdgeSampler.java
+++ b/measure-core/src/main/java/org/jtmc/core/signal/sampler/EdgeSampler.java
@@ -1,41 +1,41 @@
package org.jtmc.core.signal.sampler;
import java.util.Iterator;
-
import org.jtmc.core.signal.Signal;
import org.jtmc.core.signal.Signal.DataPoint;
/**
- * EdgeSampler takes any signal and outputs a signal which is sampled at the given rate
+ * EdgeSampler takes any signal and outputs a signal which is sampled at the given rate.
*/
public class EdgeSampler> implements Sampler> {
- private long points;
+ private long points;
- public EdgeSampler(long points) {
- this.points = points;
- }
+ public EdgeSampler(long points) {
+ this.points = points;
+ }
- @Override
- public Signal sample(Signal signal) {
- Signal output = new Signal(signal.getId());
- double timestep = signal.period() / points;
-
- Iterator> point = signal.getData().iterator();
- int index = 0;
-
- while(point.hasNext()) {
- DataPoint p = point.next();
- for(;index * timestep < p.time || (!point.hasNext() && index < points);index++) {
- output.add(index * timestep, p.value);
- }
- }
-
- return output;
- }
+ @Override
+ public Signal sample(Signal signal) {
+ Signal output = new Signal(signal.getId());
+ double timestep = signal.period() / points;
+
+ Iterator> point = signal.getData().iterator();
+ int index = 0;
+
+ while (point.hasNext()) {
+ DataPoint p = point.next();
+ while (index * timestep < p.time || (!point.hasNext() && index < points)) {
+ output.add(index * timestep, p.value);
+ index++;
+ }
+ }
+
+ return output;
+ }
- public long getPoints() {
- return points;
- }
-
-}
\ No newline at end of file
+ public long getPoints() {
+ return points;
+ }
+
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/signal/sampler/LinearSampler.java b/measure-core/src/main/java/org/jtmc/core/signal/sampler/LinearSampler.java
index dcbe439..eb923b5 100644
--- a/measure-core/src/main/java/org/jtmc/core/signal/sampler/LinearSampler.java
+++ b/measure-core/src/main/java/org/jtmc/core/signal/sampler/LinearSampler.java
@@ -3,13 +3,14 @@
import org.jtmc.core.signal.Signal;
/**
- * LinearSampler
+ * LinearSampler takes any numeric signal and uses linear interpolation between
+ * values to fill out the missing parts.
*/
public class LinearSampler> implements Sampler> {
- @Override
- public Signal sample(Signal signal) {
- return null;
- }
+ @Override
+ public Signal sample(Signal signal) {
+ return null;
+ }
-}
\ No newline at end of file
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/signal/sampler/Sampler.java b/measure-core/src/main/java/org/jtmc/core/signal/sampler/Sampler.java
index f451cfe..36688b2 100644
--- a/measure-core/src/main/java/org/jtmc/core/signal/sampler/Sampler.java
+++ b/measure-core/src/main/java/org/jtmc/core/signal/sampler/Sampler.java
@@ -3,19 +3,19 @@
import org.jtmc.core.signal.Signal;
/**
- * A sampler takes in an existing signal and converts it to a different signal
+ * A sampler takes in an existing signal and converts it to a different signal.
*
*
For example it may take an Analog Signal then using some threshold
* it could convert it into a digital signal
*/
public interface Sampler, U extends Signal extends Comparable>>> {
- /**
- * Converts the given signal into a different signal
- *
- * @param signal Input signal
- * @return Transformed signal
- */
- public U sample(Signal signal);
+ /**
+ * Converts the given signal into a different signal.
+ *
+ * @param signal Input signal
+ * @return Transformed signal
+ */
+ public U sample(Signal signal);
-}
\ No newline at end of file
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/signal/sampler/SincFilter.java b/measure-core/src/main/java/org/jtmc/core/signal/sampler/SincFilter.java
index c1df05d..e1269b7 100644
--- a/measure-core/src/main/java/org/jtmc/core/signal/sampler/SincFilter.java
+++ b/measure-core/src/main/java/org/jtmc/core/signal/sampler/SincFilter.java
@@ -1,8 +1,8 @@
package org.jtmc.core.signal.sampler;
/**
- * SincSampler
+ * SincFilter takes any numeric signal and uses Sine over X to interpolate the signal.
*/
public class SincFilter {
-
-}
\ No newline at end of file
+ //TODO: implement
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/util/EnumParameters.java b/measure-core/src/main/java/org/jtmc/core/util/EnumParameters.java
index b9e7215..9095ac5 100644
--- a/measure-core/src/main/java/org/jtmc/core/util/EnumParameters.java
+++ b/measure-core/src/main/java/org/jtmc/core/util/EnumParameters.java
@@ -7,94 +7,102 @@
import java.util.Set;
/**
- * EnumParameters is a convenience class for building prototype objects
+ * EnumParameters is a convenience class for building prototype objects.
*/
public abstract class EnumParameters> {
- private Map params = new HashMap<>();
+ private Map params = new HashMap<>();
- /**
- * Returns the parameters that have an assigned value
- * @return Set of parameters
- */
- public Set getParameters() {
- return new HashSet<>(params.keySet());
- }
+ /**
+ * Returns the parameters that have an assigned value.
+ *
+ * @return Set of parameters
+ */
+ public Set getParameters() {
+ return new HashSet<>(params.keySet());
+ }
- /**
- * Returns a given parameter as float
- * @param param Parameter
- * @return Float value
- * @throws ClassCastException if the parameter isn't float
- */
- public float getFloat(T param) {
- return (float) params.get(param);
- }
+ /**
+ * Returns a given parameter as float.
+ *
+ * @param param Parameter
+ * @return Float value
+ * @throws ClassCastException if the parameter isn't float
+ */
+ public float getFloat(T param) {
+ return (float) params.get(param);
+ }
- /**
- * Returns a given parameter as int
- * @param param Parameter
- * @return Integer value
- * @throws ClassCastException if the parameter isn't int
- */
- public int getInt(T param) {
- return (int) params.get(param);
- }
+ /**
+ * Returns a given parameter as int.
+ *
+ * @param param Parameter
+ * @return Integer value
+ * @throws ClassCastException if the parameter isn't int
+ */
+ public int getInt(T param) {
+ return (int) params.get(param);
+ }
- /**
- * Returns a given parameter as boolean
- * @param param Parameter
- * @return Boolean value
- * @throws ClassCastException if the parameter isn't boolean
- */
- public boolean getBoolean(T param) {
- return (boolean) params.get(param);
- }
+ /**
+ * Returns a given parameter as boolean.
+ *
+ * @param param Parameter
+ * @return Boolean value
+ * @throws ClassCastException if the parameter isn't boolean
+ */
+ public boolean getBoolean(T param) {
+ return (boolean) params.get(param);
+ }
- /**
- * Assigns the given object to the parameter
- * @param param Parameter
- * @param value Assigned value
- * @return Previously assigned value
- */
- protected Object put(T param, Object value) {
- return params.put(param, value);
- }
+ /**
+ * Assigns the given object to the parameter.
+ *
+ * @param param Parameter
+ * @param value Assigned value
+ * @return Previously assigned value
+ */
+ protected Object put(T param, Object value) {
+ return params.put(param, value);
+ }
- /**
- * Removes the assigned value from given parameter
- * @param param Parameter
- * @return Assigned value
- */
- protected Object remove(T param) {
- return params.remove(param);
- }
+ /**
+ * Removes the assigned value from given parameter.
+ *
+ * @param param Parameter
+ * @return Assigned value
+ */
+ protected Object remove(T param) {
+ return params.remove(param);
+ }
- /**
- * Returns whether the parameter has any value assigned to it
- * @param param Parameter
- * @return {@code true} if the parameter has an object assigned to it
- */
- public boolean has(T param) {
- return params.containsKey(param);
- }
+ /**
+ * Returns whether the parameter has any value assigned to it.
+ *
+ * @param param Parameter
+ * @return {@code true} if the parameter has an object assigned to it
+ */
+ public boolean has(T param) {
+ return params.containsKey(param);
+ }
- /**
- * Optionally returns the value associated to the given parameter
- * @param Type of the parameter
- * @param param Parameter
- * @return Optional of value, {@code null} if the parameter has no value or isn't of type {@code U}
- */
- @SuppressWarnings("unchecked")
- public Optional get(T param) {
- try {
- Object o = params.get(param);
- if(o == null) {
- return Optional.empty();
- }
- return Optional.of((U) o);
- } catch(ClassCastException e) {
- return Optional.empty();
- }
- }
-}
\ No newline at end of file
+ /**
+ * Optionally returns the value associated to the given parameter.
+ *
+ * @param Type of the parameter
+ * @param param Parameter
+ * @return Optional of value, empty if the parameter has no value or isn't of type {@code U}
+ */
+ @SuppressWarnings("unchecked")
+ public Optional get(T param) {
+ try {
+ Object o = params.get(param);
+ if (o == null) {
+ return Optional.empty();
+ }
+ return Optional.of((U) o);
+ } catch (ClassCastException e) {
+ return Optional.empty();
+ }
+ }
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/util/Units.java b/measure-core/src/main/java/org/jtmc/core/util/Units.java
index dbb5960..11e33a0 100644
--- a/measure-core/src/main/java/org/jtmc/core/util/Units.java
+++ b/measure-core/src/main/java/org/jtmc/core/util/Units.java
@@ -3,68 +3,65 @@
import java.util.Locale;
/**
- * Util
+ * Units provides user friendly unit conversion methods.
*/
public final class Units {
- public static final double MEGA = 1000000.0;
-
- public static final double KILO = 1000.0;
-
- public static final double MILLI = 0.001;
-
- public static final double MICRO = 0.000001;
-
- public static final double NANO = 0.000000001;
-
- public static final double PICO = 0.00000000001;
-
- public static double mega(double value) {
- return MEGA * value;
- }
-
- public static double kilo(double value) {
- return KILO * value;
- }
-
- public static double milli(double value) {
- return MILLI * value;
- }
-
- public static double micro(double value) {
- return MICRO * value;
- }
-
- public static double nano(double value) {
- return NANO * value;
- }
-
- public static double nV(double nanovolts) {
- return nano(nanovolts);
- }
-
- public static double mV(double millivolts) {
- return milli(millivolts);
- }
-
- public static String auto(double value, int digits, String unit) {
- double abs = Math.abs(value);
- if(abs >= 1) {
- return toString(value, 1, digits, unit);
- }
- else if(abs >= Units.milli(1)) {
- return toString(value, MILLI, digits, "m" + unit);
- }
- else if(abs >= Units.micro(1)) {
- return toString(value, MICRO, digits, "u" + unit);
- }
- else if(abs >= Units.nano(1)) {
- return toString(value, NANO, digits, "n" + unit);
- }
- return toString(value, NANO, digits, unit);
- }
-
- private static String toString(double value, double range, int digits, String unit) {
- return String.format(Locale.US, "%.0" + digits + "f" + unit, value / range);
- }
-}
\ No newline at end of file
+ public static final double MEGA = 1000000.0;
+
+ public static final double KILO = 1000.0;
+
+ public static final double MILLI = 0.001;
+
+ public static final double MICRO = 0.000001;
+
+ public static final double NANO = 0.000000001;
+
+ public static final double PICO = 0.00000000001;
+
+ public static double mega(double value) {
+ return MEGA * value;
+ }
+
+ public static double kilo(double value) {
+ return KILO * value;
+ }
+
+ public static double milli(double value) {
+ return MILLI * value;
+ }
+
+ public static double micro(double value) {
+ return MICRO * value;
+ }
+
+ public static double nano(double value) {
+ return NANO * value;
+ }
+
+ /**
+ * Converts a floating point number into a string with the SI-prefixum and unit appended.
+ *
+ * @param value Input value
+ * @param digits Number of digits to keep
+ * @param unit Unit type
+ * @return Value with SI-prefixum and unit
+ */
+ public static String auto(double value, int digits, String unit) {
+ double abs = Math.abs(value);
+ if (abs >= 1) {
+ return toString(value, 1, digits, unit);
+ } else if (abs >= Units.milli(1)) {
+ return toString(value, MILLI, digits, "m" + unit);
+ } else if (abs >= Units.micro(1)) {
+ return toString(value, MICRO, digits, "u" + unit);
+ } else if (abs >= Units.nano(1)) {
+ return toString(value, NANO, digits, "n" + unit);
+ }
+ return toString(value, NANO, digits, unit);
+ }
+
+ private static String toString(double value, double range, int digits, String unit) {
+ return String.format(Locale.US, "%.0" + digits + "f" + unit, value / range);
+ }
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/visa/DeviceIdentifier.java b/measure-core/src/main/java/org/jtmc/core/visa/DeviceIdentifier.java
index 7c4aafa..20116d3 100644
--- a/measure-core/src/main/java/org/jtmc/core/visa/DeviceIdentifier.java
+++ b/measure-core/src/main/java/org/jtmc/core/visa/DeviceIdentifier.java
@@ -1,91 +1,102 @@
package org.jtmc.core.visa;
/**
- * Device identifier, specified in the SCPI-99 standard
+ * DeviceIdentifier holds instrument information as specified in the SCPI-99 standard.
*
- *
- * Includes the device vendor, model, serial number and firmware version
+ *
Includes the following properties:
+ *
+ *
Device vendor
+ *
Model
+ *
Serial number
+ *
Firmware version
+ *
*/
public final class DeviceIdentifier {
- public final static DeviceIdentifier UNKNOWN = new DeviceIdentifier("-", "-", "-", "-");
+ public static final DeviceIdentifier UNKNOWN = new DeviceIdentifier("-", "-", "-", "-");
- private final String manufacturer;
- private final String model;
- private final String serialNumber;
- private final String firmwareVersion;
+ private final String manufacturer;
+ private final String model;
+ private final String serialNumber;
+ private final String firmwareVersion;
- /**
- * @param manufacturer
- * @param model
- * @param serialNumber
- * @param firmwareVersion
- */
- private DeviceIdentifier(String manufacturer, String model, String serialNumber, String firmwareVersion) {
- this.manufacturer = manufacturer;
- this.model = model;
- this.serialNumber = serialNumber;
- this.firmwareVersion = firmwareVersion;
- }
+ private DeviceIdentifier(
+ String manufacturer,
+ String model,
+ String serialNumber,
+ String firmwareVersion) {
+ this.manufacturer = manufacturer;
+ this.model = model;
+ this.serialNumber = serialNumber;
+ this.firmwareVersion = firmwareVersion;
+ }
- /**
- * Constructs an Identifier from the format seen in the LXI Discovery and Identification specification
- *
- * @param raw Raw string in the
- * @return Device identifier object
- */
- public static DeviceIdentifier from(String raw) {
- String[] info = raw.trim().split(",");
- if(info.length != 4) {
- throw new IllegalArgumentException("bad identifier: " + raw + " must be 4 comma-separated fields");
- }
- return new DeviceIdentifier(info[0], info[1], info[2], info[3]);
- }
+ /**
+ * Constructs an Identifier from the format seen in the LXI Discovery
+ * and Identification specification.
+ *
+ * @param raw Raw string in the
+ * @return Device identifier object
+ */
+ public static DeviceIdentifier from(String raw) {
+ String[] info = raw.trim().split(",");
+ if (info.length != 4) {
+ throw new IllegalArgumentException(
+ "Bad device identifier: \'" + raw + "\' must be 4 comma-separated fields");
+ }
+ return new DeviceIdentifier(info[0], info[1], info[2], info[3]);
+ }
- /**
- * Constructs an Identifier from the fields found in LXI Discovery and Identification specification
- *
- * @param manufacturer Manufacturer of the device
- * @param model Model number
- * @param serialNumber Serial number
- * @param firmwareVersion Firmware version
- * @return Device identifier object
- */
- public static DeviceIdentifier from(String manufacturer, String model, String serialNumber, String firmwareVersion) {
- return new DeviceIdentifier(manufacturer, model, serialNumber, firmwareVersion);
- }
+ /**
+ * Constructs an Identifier from the fields found in LXI Discovery
+ * and Identification specification.
+ *
+ * @param manufacturer Manufacturer of the device
+ * @param model Model number
+ * @param serialNumber Serial number
+ * @param firmwareVersion Firmware version
+ * @return Device identifier object
+ */
+ public static DeviceIdentifier from(
+ String manufacturer,
+ String model,
+ String serialNumber,
+ String firmwareVersion) {
+ return new DeviceIdentifier(manufacturer, model, serialNumber, firmwareVersion);
+ }
- public String getManufacturer() {
- return manufacturer;
- }
+ public String getManufacturer() {
+ return manufacturer;
+ }
- public String getModel() {
- return model;
- }
+ public String getModel() {
+ return model;
+ }
- public String getSerialNumber() {
- return serialNumber;
- }
+ public String getSerialNumber() {
+ return serialNumber;
+ }
- public String getFirmwareVersion() {
- return firmwareVersion;
- }
+ public String getFirmwareVersion() {
+ return firmwareVersion;
+ }
- /**
- * Returns the string representation of this identifier
- * @return Raw string identifier
- */
- public String value() {
- return manufacturer + "," + model + "," + serialNumber + "," + firmwareVersion;
- }
+ /**
+ * Returns the string representation of this identifier.
+ * @return Raw string identifier
+ */
+ public String value() {
+ return manufacturer + "," + model + "," + serialNumber + "," + firmwareVersion;
+ }
- /**
- * Returns a string representing this identifier in a debug friendly way
- * @return Debug string
- */
- @Override
- public String toString() {
- //TODO: rework format
- return "[mf=" + manufacturer + ";model=" + model + ";sn=" + serialNumber + ";ver=" + firmwareVersion + "]";
- }
-}
\ No newline at end of file
+ /**
+ * Returns a string representing this identifier in a debug friendly way.
+ * @return Debug string
+ */
+ @Override
+ public String toString() {
+ //TODO: rework format
+ return "[mf=" + manufacturer + ";model=" + model
+ + ";sn=" + serialNumber + ";ver=" + firmwareVersion + "]";
+ }
+}
diff --git a/measure-core/src/main/java/org/jtmc/core/visa/VISAResourceManager.java b/measure-core/src/main/java/org/jtmc/core/visa/VISAResourceManager.java
index 818b7a5..fb9b1cc 100644
--- a/measure-core/src/main/java/org/jtmc/core/visa/VISAResourceManager.java
+++ b/measure-core/src/main/java/org/jtmc/core/visa/VISAResourceManager.java
@@ -6,68 +6,87 @@
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
-
import org.jtmc.core.device.ISocket;
import org.jtmc.core.visa.exception.UnsupportedSocketException;
import org.jtmc.core.visa.factory.ISocketFactory;
+
/**
- * VISAResourceManager
+ * VISAResourceManager can be used to connect instruments.
*/
public class VISAResourceManager implements AutoCloseable {
- private ISocketFactory socketFactory;
+ private ISocketFactory socketFactory;
- private List> factories;
+ private List> factories;
- private transient List sockets;
+ private transient List sockets;
- public VISAResourceManager(final ISocketFactory socketFactory, List> factories) {
- this.socketFactory = socketFactory;
- this.factories = new LinkedList<>(factories);
- this.sockets = new LinkedList<>();
- }
+ /**
+ * Creates a new VISAResourceManager with the given socket factory and device factories.
+ * @param socketFactory Factory for creating sockets
+ * @param factories Device factories
+ */
+ public VISAResourceManager(
+ final ISocketFactory socketFactory,
+ List> factories) {
+ this.socketFactory = socketFactory;
+ this.factories = new LinkedList<>(factories);
+ this.sockets = new LinkedList<>();
+ }
- public ISocket connect(String resourceString) throws IOException, VisaException {
- return socketFactory.create(resourceString);
- }
+ public ISocket connect(String resourceString) throws IOException, VisaException {
+ return socketFactory.create(resourceString);
+ }
- public T connect(String resourceString, Class klass) throws IOException, VisaException {
- ISocket socket = this.connect(resourceString);
+ /**
+ * Connects a new instrument using the given resource string and casting it to the
+ * required type.
+ *
+ * @param Preferred return type
+ * @param resourceString VISA Resource string
+ * @param klass Class of the return type
+ * @return Device driver
+ * @throws IOException if there was an error connecting to the device
+ * @throws VisaException if there was an error creating a driver for the device
+ */
+ public T connect(String resourceString, Class klass) throws IOException, VisaException {
+ ISocket socket = this.connect(resourceString);
- ArrayList