import javax.swing.JTextField;
import de.republib.gui.MultiChannelSheet;
+import de.republib.pinet.GpioClient;
+import de.republib.util.Announcer;
import de.republib.util.FunctionPairData;
import de.republib.util.I18N;
import de.republib.util.MathFunction;
/**
* Created by hm on 03.07.16.
*/
-public class ControlCenter {
+public class ControlCenter implements Announcer {
+ private GpioClient client = null;
private JFrame frame;
+
private JPanel panelCenter;
- private JPanel panelOutput;
+ private GPIOSettings panelGPIOSettings;
private JPanel panelLog;
private JLabel labelStatusLine;
private MultiChannelSheet panelData;
private JTextField textFieldPort;
private JTabbedPane tabbedPane;
- public void populate() {
+ /**
+ * Constructor.
+ */
+ public ControlCenter() {
+
+ }
+
+ /**
+ * @return the client
+ */
+ public GpioClient getClient() {
+ final String host = this.textFieldServer.getText();
+ final String port = this.textFieldPort.getText();
+ final int port2 = port.length() == 0 ? 15000 : Integer.parseInt(port);
+ if (this.client == null || !this.client.sameAddress(host, port2)) {
+ this.client = new GpioClient(host, port2);
+ }
+
+ return this.client;
+ }
+
+ public void populate(String host, int port) {
this.frame = new JFrame(I18N.tr("Pinet Control Center"));
this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.frame.add(this.labelStatusLine = new JLabel(I18N.tr("welcome")), BorderLayout.SOUTH);
this.panelHead.add(new JLabel(I18N.tr("Server:")));
- this.panelHead.add(this.textFieldServer = new JTextField("localhost"));
+ this.panelHead.add(this.textFieldServer = new JTextField(host));
this.panelHead.add(new JLabel(I18N.tr("Port:")));
- this.panelHead.add(this.textFieldPort = new JTextField("15000"));
+ this.panelHead.add(this.textFieldPort = new JTextField(String.valueOf(port)));
this.panelCenter.add(this.tabbedPane = new JTabbedPane());
- this.tabbedPane.addTab(I18N.tr("Output"), this.panelOutput = new JPanel());
+ this.tabbedPane.addTab(I18N.tr("GPIO settings"), this.panelGPIOSettings = new GPIOSettings(this));
+ this.panelGPIOSettings.populate();
this.tabbedPane.addTab(I18N.tr("Diagram"), this.panelData = new MultiChannelSheet());
+ populateCurves();
+ this.tabbedPane.addTab(I18N.tr("Log"), this.panelLog = new JPanel());
+ }
+
+ private void populateCurves() {
FunctionPairData function = new FunctionPairData(MathFunction.X, 0.0, 10.0, 790);
function.setFactor(9.0);
function.setOffset(1.0);
this.panelData.addChannel(function);
function = new FunctionPairData(MathFunction.TAN, 0.0, 1.0, 790);
this.panelData.addChannel(function);
- this.tabbedPane.addTab(I18N.tr("Log"), this.panelLog = new JPanel());
+
}
public void run() {
this.frame.pack();
this.frame.setVisible(true);
}
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see de.republib.util.Announcer#say(int, java.lang.String)
+ */
+ @Override
+ public void say(int level, final String message) {
+ String prefix = null;
+ switch (level) {
+ case Announcer.ERROR:
+ prefix = "+++ ";
+ break;
+ case Announcer.WARNING:
+ prefix = "*** ";
+ break;
+ default:
+ }
+ if (prefix == null) {
+ this.labelStatusLine.setText(message);
+ } else {
+ this.labelStatusLine.setText(prefix + message);
+ }
+ }
}
--- /dev/null
+/**
+ *
+ */
+package de.republib.pinet.gui;
+
+import java.awt.Component;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import de.republib.pinet.GpioClient;
+import de.republib.pinet.PinNumber;
+import de.republib.util.Announcer;
+import de.republib.util.DynBytes;
+import de.republib.util.I18N;
+
+/**
+ * Manages the register page "GPIO Settings".
+ *
+ * @author hm
+ *
+ */
+public class GPIOSettings extends JPanel {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ private GPIOTable gpioTable;
+ private OutputData panelOutputData;
+ private final ControlCenter center;
+
+ /**
+ *
+ * @param center
+ * @return
+ */
+ public GPIOSettings(ControlCenter center) {
+ this.center = center;
+ }
+
+ public void populate() {
+
+ this.gpioTable = new GPIOTable();
+ add(this.gpioTable);
+ final PinData panelPinData = new PinData(this.gpioTable);
+ this.gpioTable.setPanelPinData(panelPinData);
+ add(panelPinData);
+ add(this.panelOutputData = new OutputData(this.center, panelPinData));
+ }
+}
+
+class GPIOTable extends JPanel implements ActionListener {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ private final PinButton[] pinButtons = new PinButton[40];
+
+ private final JLabel[] columnNames = { new JLabel(I18N.tr("Name")), new JLabel(I18N.tr("Pin")),
+ new JLabel(I18N.tr("Pin")), new JLabel(I18N.tr("Name")) };
+
+ private final Object[][] cells;
+ PinData panelPinData;
+
+ /**
+ * Constructor.
+ */
+ public GPIOTable() {
+ super(new GridLayout(21, 4));
+ this.panelPinData = this.panelPinData;
+ this.pinButtons[0] = new PinButton(0, I18N.tr("+3.3V"), null);
+ this.pinButtons[1] = new PinButton(1, I18N.tr("+5V"), null);
+ this.pinButtons[2] = new PinButton(2, "SDA1", PinNumber.PIN_RPi2_03);
+ this.pinButtons[3] = new PinButton(3, I18N.tr("+5V"), null);
+ this.pinButtons[4] = new PinButton(4, "SCL1", PinNumber.PIN_RPi2_05);
+ this.pinButtons[5] = new PinButton(5, I18N.tr("GND"), null);
+ this.pinButtons[6] = new PinButton(6, "GCLK", PinNumber.PIN_RPi2_07);
+ this.pinButtons[7] = new PinButton(7, "TXD0", PinNumber.PIN_RPi2_08);
+ this.pinButtons[8] = new PinButton(8, I18N.tr("GND"), null);
+ this.pinButtons[9] = new PinButton(9, "RXD0", PinNumber.PIN_RPi2_10);
+ this.pinButtons[10] = new PinButton(10, "GEN0", PinNumber.PIN_RPi2_11);
+ this.pinButtons[11] = new PinButton(11, "GEN1", PinNumber.PIN_RPi2_12);
+ this.pinButtons[12] = new PinButton(12, "GEN2", PinNumber.PIN_RPi2_13);
+ this.pinButtons[13] = new PinButton(13, I18N.tr("GND"), null);
+ this.pinButtons[14] = new PinButton(14, "GEN3", PinNumber.PIN_RPi2_15);
+ this.pinButtons[15] = new PinButton(15, "GEN4", PinNumber.PIN_RPi2_16);
+ this.pinButtons[16] = new PinButton(16, I18N.tr("+3.3V"), null);
+ this.pinButtons[17] = new PinButton(17, "GEN5", PinNumber.PIN_RPi2_18);
+ this.pinButtons[18] = new PinButton(18, "SPI_MOSI", PinNumber.PIN_RPi2_19);
+ this.pinButtons[19] = new PinButton(19, I18N.tr("GND"), null);
+ this.pinButtons[20] = new PinButton(20, "SPI_MISO", PinNumber.PIN_RPi2_21);
+ this.pinButtons[21] = new PinButton(21, "GEN6", PinNumber.PIN_RPi2_22);
+ this.pinButtons[22] = new PinButton(22, "SPI_SCLK", PinNumber.PIN_RPi2_23);
+ this.pinButtons[23] = new PinButton(23, "SPI_CE0", PinNumber.PIN_RPi2_24);
+ this.pinButtons[24] = new PinButton(24, I18N.tr("GND"), null);
+ this.pinButtons[25] = new PinButton(25, "SPI_CE1", PinNumber.PIN_RPi2_26);
+ this.pinButtons[26] = new PinButton(26, "I2C_ID_SC", PinNumber.PIN_RPi2_27);
+ this.pinButtons[27] = new PinButton(27, "I2C_ID_SD", PinNumber.PIN_RPi2_28);
+ this.pinButtons[28] = new PinButton(28, null, PinNumber.PIN_RPi2_29);
+ this.pinButtons[29] = new PinButton(29, I18N.tr("GND"), null);
+ this.pinButtons[30] = new PinButton(30, null, PinNumber.PIN_RPi2_31);
+ this.pinButtons[31] = new PinButton(31, null, PinNumber.PIN_RPi2_32);
+ this.pinButtons[32] = new PinButton(32, null, PinNumber.PIN_RPi2_33);
+ this.pinButtons[33] = new PinButton(33, I18N.tr("GND"), null);
+ this.pinButtons[34] = new PinButton(34, null, PinNumber.PIN_RPi2_35);
+ this.pinButtons[35] = new PinButton(35, null, PinNumber.PIN_RPi2_36);
+ this.pinButtons[36] = new PinButton(36, null, PinNumber.PIN_RPi2_37);
+ this.pinButtons[37] = new PinButton(37, null, PinNumber.PIN_RPi2_38);
+ this.pinButtons[38] = new PinButton(38, I18N.tr("GND"), null);
+ this.pinButtons[39] = new PinButton(39, null, PinNumber.PIN_RPi2_40);
+ for (final PinButton pinButton : this.pinButtons) {
+ pinButton.addActionListener(this);
+ }
+
+ this.cells = new Object[20][4];
+ for (int row = 0; row < 20; row++) {
+ PinButton button = this.pinButtons[row * 2];
+ this.cells[row][0] = new JLabel(button.getTitle());
+ this.cells[row][1] = button;
+ button = this.pinButtons[row * 2 + 1];
+ this.cells[row][2] = button;
+ this.cells[row][3] = new JLabel(button.getTitle());
+ }
+ populate();
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ final PinButton button = (PinButton) e.getSource();
+ this.panelPinData.fillData(button);
+ }
+
+ public Component getCell(int row, int column) {
+ final Component rc = (Component) this.cells[row][column];
+ return rc;
+ }
+
+ /**
+ * @return the pinButtons
+ */
+ public PinButton getPinButton(int index) {
+ return this.pinButtons[index];
+ }
+
+ public void populate() {
+ int col;
+ for (col = 0; col < 4; col++) {
+ add(this.columnNames[col]);
+ }
+ for (int row = 0; row < 20; row++) {
+ for (col = 0; col < 4; col++) {
+ add((Component) this.cells[row][col]);
+ }
+ }
+ }
+
+ /**
+ * @param panelPinData
+ * the panelPinData to set
+ */
+ public void setPanelPinData(PinData panelPinData) {
+ this.panelPinData = panelPinData;
+ }
+}
+
+/**
+ * Shows and manages the panel controlling the output behaviour of a pin.
+ *
+ * @author hm
+ *
+ */
+class OutputData extends JPanel implements ActionListener {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ private final static String[] modes = { I18N.tr("Blink") };
+ private JComboBox<String> comboMode;
+ private JTextField textCount;
+ private JTextField textHigh;
+ private JTextField textLow;
+ private JButton buttonRun;
+ private final ControlCenter center;
+ private final PinData pinData;
+
+ /**
+ * Constructor.
+ */
+ public OutputData(ControlCenter center, PinData pinData) {
+ super(new GridLayout(0, 2));
+ this.center = center;
+ this.pinData = pinData;
+ add(new JLabel(I18N.tr("Mode:")));
+ add(this.comboMode = new JComboBox<>(OutputData.modes));
+ add(new JLabel(I18N.tr("Count:")));
+ add(this.textCount = new JTextField("10"));
+ add(new JLabel(I18N.tr("High:")));
+ add(this.textHigh = new JTextField("500"));
+ add(new JLabel(I18N.tr("Low:")));
+ add(this.textLow = new JTextField("500"));
+ add(new JLabel(""));
+ add(this.buttonRun = new JButton(I18N.tr("Start")));
+ this.buttonRun.addActionListener(this);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ final GpioClient client = this.center.getClient();
+ final PinButton current = this.pinData.getCurrentPin();
+ final int count = numberOf(this.textCount, 10);
+ final int high = numberOf(this.textHigh, 500);
+ final int low = numberOf(this.textLow, 500);
+ this.center.say(Announcer.LOG, String.format(I18N.tr("blinking started on pin %d"), current.getPinNumber()));
+ final DynBytes answer = client.blink(current.getPinNumber(), count, high, low);
+ if (answer.startsWith("OK")) {
+ this.center.say(Announcer.LOG,
+ String.format(I18N.tr("pin %d blinks %d times"), current.getPinNumber(), count));
+ }
+ }
+
+ /**
+ * Gets a number from a text field.
+ *
+ * @param text
+ * the text field
+ * @param defaultValue
+ * the return value for invalid field values
+ * @return <i>defaultValue</i>: invalid field value<br>
+ * otherwise: the value of the field as integer
+ */
+ private int numberOf(JTextField text, int defaultValue) {
+ int rc = defaultValue;
+ try {
+ rc = Integer.parseInt(text.getText());
+ } catch (final NumberFormatException e) {
+ this.center.say(Announcer.ERROR,
+ String.format(I18N.tr("not a number: '%s' used instead: %d"), text.getText(), rc));
+ text.setText(String.valueOf(rc));
+ }
+ return rc;
+ }
+}
+
+class PinButton extends JButton {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ private final PinNumber pinNumber;
+ private final String title;
+
+ int index;
+
+ /**
+ * Constructor.
+ *
+ * @param title
+ * <i>null</i>: the title is generated from the
+ * <i>pinNumber<i><br>
+ * otherwise: the title of the pin
+ * @param pinNumber
+ * <i>null</i>: not a IO pin, e.g. ground or +3.3V<br>
+ * otherwise: the pin number
+ */
+ public PinButton(int index, String title, PinNumber pinNumber) {
+ super(pinNumber == null ? title : String.valueOf(index + 1));
+ this.index = index;
+ this.title = title == null ? pinNumber.getName() : title;
+ this.pinNumber = pinNumber;
+ }
+
+ /**
+ * @return the index
+ */
+ public int getIndex() {
+ return this.index;
+ }
+
+ /**
+ * @return the pinNumber
+ */
+ public PinNumber getPinNumber() {
+ return this.pinNumber;
+ }
+
+ /**
+ * @return the title
+ */
+ public String getTitle() {
+ return this.title;
+ }
+}
+
+/**
+ * Shows and manages the data of the current pin in a panel.
+ *
+ * @author hm
+ *
+ */
+class PinData extends JPanel {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ private JLabel labelPin;
+ private JLabel labelInternalNo;
+ private JLabel labelTitle;
+ private JComboBox<String> comboMode;
+ private final String[] modes = { I18N.tr("undefined"), I18N.tr("input"), I18N.tr("output") };
+ private PinButton currentPin = null;
+
+ /**
+ * Constructor.
+ *
+ * @param table
+ * info about the pins
+ */
+ public PinData(GPIOTable table) {
+ super(new GridLayout(0, 2));
+ add(new JLabel(I18N.tr("Pin No:")));
+ add(this.labelPin = new JLabel());
+ add(new JLabel(I18N.tr("GPIO number:")));
+ add(this.labelInternalNo = new JLabel());
+ add(new JLabel(I18N.tr("Title:")));
+ add(this.labelTitle = new JLabel());
+ add(new JLabel(I18N.tr("Mode:")));
+ add(this.comboMode = new JComboBox<>(this.modes));
+ add(new JLabel());
+ fillData(table.getPinButton(11));
+ }
+
+ /**
+ * Fills the data of the panel from the current pin.
+ *
+ * @param button
+ * properties of the pin
+ */
+ public void fillData(PinButton button) {
+ this.currentPin = button;
+ final PinNumber number = button.getPinNumber();
+ this.labelPin.setText(String.valueOf(button.getIndex() + 1));
+ this.labelInternalNo.setText(number == null ? "-" : String.valueOf(number.getNumber()));
+ this.labelTitle.setText(button.getTitle());
+ this.comboMode.setVisible(number != null);
+ this.comboMode.setSelectedIndex(0);
+ }
+
+ /**
+ * @return the currentPin
+ */
+ public PinButton getCurrentPin() {
+ return this.currentPin;
+ }
+}
\ No newline at end of file
Assert.assertEquals(buffer.getBlocksize(), 17);
}
+ @org.testng.annotations.Test
+ public void testCompare() throws Exception {
+ final DynBytes buffer = new DynBytes(16, 16);
+ buffer.append((byte) 0x41).append((byte) 0x31).append((byte) 0x61);
+ final byte[] buffer2 = { 0x41, 0x31, 0x61 };
+ // buffer == buffer2
+ Assert.assertEquals(buffer.compare(buffer2, 0, 0, 1), 0);
+ Assert.assertEquals(buffer.compare(buffer2, 0, 0, 2), 0);
+ Assert.assertEquals(buffer.compare(buffer2, 0, 0, 3), 0);
+ Assert.assertEquals(buffer.compare(buffer2, 0, 0, 4), 0);
+ // buffer < buffer2
+ Assert.assertEquals(buffer.compare(buffer2, 0, 1, 1), -0x10);
+ Assert.assertEquals(buffer.compare(buffer2, 0, 1, 2), -0x10);
+ // buffer > buffer2
+ Assert.assertEquals(buffer.compare(buffer2, 1, 0, 1), 0x10);
+ Assert.assertEquals(buffer.compare(buffer2, 1, 0, 2), 0x10);
+ // different length:
+ final byte[] buffer3 = { 0x41, 0x31 };
+ // buffer > buffer3
+ Assert.assertEquals(buffer.compare(buffer3, 0, 0, 4), 1);
+ Assert.assertEquals(buffer.compare(buffer3, 1, 1, 4), 1);
+ final byte[] buffer4 = { 0x41, 0x31, 0x61, 0x62 };
+ // buffer < buffer4
+ Assert.assertEquals(buffer.compare(buffer4, 0, 0, 4), -1);
+ Assert.assertEquals(buffer.compare(buffer4, 1, 1, 4), -1);
+ Assert.assertEquals(buffer.compare(buffer4, 2, 2, 4), -1);
+
+ // wrong indexes:
+ // too large in value:
+ Assert.assertEquals(buffer.compare(buffer2, 3, 0, 2), -1);
+ // too large in buffer:
+ Assert.assertEquals(buffer.compare(buffer2, 0, 4, 2), 1);
+ // both too large:
+ Assert.assertEquals(buffer.compare(buffer2, 3, 4, 2), 0);
+
+ // to small in value:
+ Assert.assertEquals(buffer.compare(buffer2, -1, 0, 2), -1);
+ // too small in buffer:
+ Assert.assertEquals(buffer.compare(buffer2, 4, -1, 2), 1);
+ }
+
@org.testng.annotations.Test
public void testEnsureSize() throws Exception {
final DynBytes buffer = new DynBytes(2, 2);