Renamed packaging to HyperCon. Added javadoc comments. Added build script for auto jar-build.

Former-commit-id: d54f184b3b9fad359c5469361d6f93a8b884a00b
This commit is contained in:
T. van der Zwan 2013-09-30 15:40:51 +02:00
parent 6792321192
commit 3b232ad4f5
36 changed files with 572 additions and 302 deletions

View File

@ -0,0 +1,26 @@
<?xml version="1.0"?>
<project default="main" basedir=".">
<property name="deploy.dir" value="${basedir}/deploy" />
<target name="main" depends="make_deploy_dir, build" description="Build HyperCon, the Hyperion configuration file builder" />
<target name="build" depends="make_deploy_dir" description="Create HyperCon.jar">
<jar destfile="HyperCon.jar">
<manifest>
<attribute name="Main-Class" value="org.hyperion.hypercon.Main" />
</manifest>
<fileset dir="classes" />
</jar>
<move file="HyperCon.jar" todir="${deploy.dir}" />
</target>
<target name="clear">
<delete dir="{deploy.dir}" quiet="true" />
</target>
<target name="make_deploy_dir">
<mkdir dir="${deploy.dir}" />
</target>
</project>

View File

@ -1,23 +0,0 @@
package org.hyperion.config;
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JApplet;
import org.hyperion.config.gui.ConfigPanel;
public class HyperionConfigApplet extends JApplet {
public HyperionConfigApplet() {
super();
initialise();
}
private void initialise() {
setPreferredSize(new Dimension(600, 300));
add(new ConfigPanel(), BorderLayout.CENTER);
}
}

View File

@ -1,24 +0,0 @@
package org.hyperion.config;
import javax.swing.JFrame;
import javax.swing.UIManager;
import org.hyperion.config.gui.ConfigPanel;
public class Main {
public static void main(String[] pArgs) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {}
JFrame frame = new JFrame();
frame.setTitle("Hyperion configuration Tool");
frame.setSize(1300, 600);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setContentPane(new ConfigPanel());
frame.setVisible(true);
}
}

View File

@ -1,29 +0,0 @@
package org.hyperion.config.spec;
public enum BootSequence {
rainbow,
knight_rider,
none;
public static BootSequence fromString(String pStr) {
for (BootSequence seq : values()) {
if (seq.toString().equalsIgnoreCase(pStr)) {
return seq;
}
}
return none;
}
@Override
public String toString() {
switch(this) {
case rainbow:
return "Rainbow";
case knight_rider:
return "Kinght Rider";
case none:
return "None";
}
return "None";
}
}

View File

@ -1,22 +0,0 @@
package org.hyperion.config.spec;
public enum BorderSide {
top_left (0.75*Math.PI),
top(0.5*Math.PI),
top_right(0.25*Math.PI),
right(0.0*Math.PI),
bottom_right(-0.25*Math.PI),
bottom(-0.5*Math.PI),
bottom_left(-0.75*Math.PI),
left(1.0*Math.PI);
private final double mAngle;
BorderSide(double pAngle) {
mAngle = pAngle;
}
public double getAngle() {
return mAngle;
}
}

View File

@ -1,9 +0,0 @@
package org.hyperion.config.spec;
public enum DeviceType {
ws2801,
test,
none;
}

View File

@ -1,21 +0,0 @@
package org.hyperion.config.spec;
import java.util.Observable;
public class ImageProcessConfig extends Observable {
/** The 'integration depth' of the leds along the horizontal axis of the tv */
public double horizontalDepth = 0.05;
/** The 'integration depth' of the leds along the vertical axis of the tv */
public double verticalDepth = 0.05;
/** The fraction of overlap from one to another led */
public double overlapFraction = 0.0;
public boolean blackBorderRemoval = true;
@Override
public void setChanged() {
super.setChanged();
}
}

View File

@ -1,21 +0,0 @@
package org.hyperion.config.spec;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
public class Led {
public int mLedSeqNr;
public BorderSide mSide;
public Point2D mLocation;
public Rectangle2D mImageRectangle;
@Override
public String toString() {
return "Led[" + mLedSeqNr + "] Location=" + mLocation + " Rectangle=" + mImageRectangle;
}
}

View File

@ -1,83 +0,0 @@
package org.hyperion.config.spec;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
public class Ws2801Led extends JComponent {
enum Border {
top,
topleft,
left,
bottomleft,
bottom,
bottomright,
right,
topright;
}
final int size = 12;
final int halfSize = size/2;
final Border mBorder;
public Ws2801Led(Border pBorder) {
mBorder = pBorder;
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
// g2d.setColor(Color.BLACK);
// g2d.drawRect(0, 0, getWidth()-1, getHeight()-1);
switch (mBorder) {
case top:
g2d.translate(getWidth()/2, getHeight());
break;
case topleft:
g2d.translate(getWidth(), getHeight());
g2d.rotate(1.75*Math.PI);
break;
case left:
g2d.translate(0, getHeight()/2);
g2d.rotate(Math.PI*0.5);
break;
case bottomleft:
g2d.translate(getWidth(), 0);
g2d.rotate(-0.75*Math.PI);
break;
case bottom:
g2d.translate(getWidth()/2, 0);
g2d.rotate(Math.PI*1.0);
break;
case bottomright:
g2d.rotate(0.75*Math.PI);
break;
case right:
g2d.translate(getWidth(), getHeight()/2);
g2d.rotate(Math.PI*1.5);
break;
case topright:
g2d.translate(0, getHeight());
g2d.rotate(0.25*Math.PI);
break;
}
g2d.setColor(new Color(255, 0, 0, 172));
g2d.fillRoundRect(-3, -12, 6, 6, 2, 2);
g2d.setColor(new Color(255, 0, 0, 255));
g2d.drawRoundRect(-3, -12, 6, 6, 2, 2);
g2d.setColor(Color.GRAY);
g2d.drawRect(-halfSize, -halfSize, size, halfSize);
g2d.fillRect(-halfSize, -halfSize, size, halfSize);
}
}

View File

@ -0,0 +1,34 @@
package org.hyperion.hypercon;
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JApplet;
import org.hyperion.hypercon.gui.ConfigPanel;
/**
* Class for starting HyperCon (Hyperion configuration file builder) as a Applet (within a browser)
*
*/
public class HyperConApplet extends JApplet {
/**
* Constructs the HyperCon Applet
*/
public HyperConApplet() {
super();
initialise();
}
/**
* Initialises this applet
*/
private void initialise() {
setPreferredSize(new Dimension(600, 300));
// Add the HyperCon configuration panel
add(new ConfigPanel(), BorderLayout.CENTER);
}
}

View File

@ -1,16 +1,28 @@
package org.hyperion.config; package org.hyperion.hypercon;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.util.Vector; import java.util.Vector;
import org.hyperion.config.spec.BorderSide; import org.hyperion.hypercon.spec.BorderSide;
import org.hyperion.config.spec.ImageProcessConfig; import org.hyperion.hypercon.spec.ImageProcessConfig;
import org.hyperion.config.spec.Led; import org.hyperion.hypercon.spec.Led;
import org.hyperion.config.spec.LedFrameConstruction; import org.hyperion.hypercon.spec.LedFrameConstruction;
/**
* The LedFrameFactory translates user specifications (number of leds, etc) to actual led
* specifications (location of led, depth and width of integration, etc)
*/
public class LedFrameFactory { public class LedFrameFactory {
/**
* Convenience method for increasing the led counter (it might actually decrease if the frame is
* counter clockwise)
*
* @param frameSpec The specification of the led-frame
* @param pLedCounter The current led counter
* @return The counter/index of the next led
*/
private static int increase(LedFrameConstruction frameSpec, int pLedCounter) { private static int increase(LedFrameConstruction frameSpec, int pLedCounter) {
if (frameSpec.clockwiseDirection) { if (frameSpec.clockwiseDirection) {
return (pLedCounter+1)%frameSpec.getLedCount(); return (pLedCounter+1)%frameSpec.getLedCount();
@ -23,6 +35,14 @@ public class LedFrameFactory {
} }
/**
* Translate a 'frame' and picture integration specification to per-led specification
*
* @param frameSpec The specification of the led frame
* @param processConfig The picture integration specification
*
* @return The per-led specification
*/
public static Vector<Led> construct(LedFrameConstruction frameSpec, ImageProcessConfig processConfig) { public static Vector<Led> construct(LedFrameConstruction frameSpec, ImageProcessConfig processConfig) {
Vector<Led> mLeds = new Vector<>(); Vector<Led> mLeds = new Vector<>();
@ -31,71 +51,104 @@ public class LedFrameFactory {
return mLeds; return mLeds;
} }
// Determine the led-number of the top-left led
int iLed = (totalLedCount - frameSpec.firstLedOffset)%totalLedCount; int iLed = (totalLedCount - frameSpec.firstLedOffset)%totalLedCount;
if (iLed < 0) { if (iLed < 0) {
iLed += totalLedCount; iLed += totalLedCount;
} }
// Construct the top-left led (if top-left is enabled)
if (frameSpec.topLeftCorner) { if (frameSpec.topLeftCorner) {
mLeds.add(createLed(frameSpec, processConfig, iLed, 0.0, 0.0, processConfig.overlapFraction, BorderSide.top_left)); mLeds.add(createLed(frameSpec, processConfig, iLed, 0.0, 0.0, processConfig.getOverlapFraction(), BorderSide.top_left));
iLed = increase(frameSpec, iLed); iLed = increase(frameSpec, iLed);
} }
// Construct all leds along the top of the screen (if any)
if (frameSpec.topLedCnt > 0) { if (frameSpec.topLedCnt > 0) {
// Determine the led-spacing
int ledCnt = frameSpec.topLedCnt; int ledCnt = frameSpec.topLedCnt;
double ledSpacing = (double)1.0/(ledCnt); double ledSpacing = (double)1.0/(ledCnt);
for (int iTop=0; iTop<ledCnt; ++iTop) { for (int iTop=0; iTop<ledCnt; ++iTop) {
// Compute the location of this led
double led_x = ledSpacing/2.0 + iTop * ledSpacing; double led_x = ledSpacing/2.0 + iTop * ledSpacing;
double led_y = 0; double led_y = 0;
mLeds.add(createLed(frameSpec, processConfig, iLed, led_x, led_y, processConfig.overlapFraction, BorderSide.top)); // Construct and add the single led specification to the list of leds
mLeds.add(createLed(frameSpec, processConfig, iLed, led_x, led_y, processConfig.getOverlapFraction(), BorderSide.top));
iLed = increase(frameSpec, iLed); iLed = increase(frameSpec, iLed);
} }
} }
// Construct the top-right led (if top-right is enabled)
if (frameSpec.topRightCorner) { if (frameSpec.topRightCorner) {
mLeds.add(createLed(frameSpec, processConfig, iLed, 1.0, 0.0, processConfig.overlapFraction, BorderSide.top_right)); mLeds.add(createLed(frameSpec, processConfig, iLed, 1.0, 0.0, processConfig.getOverlapFraction(), BorderSide.top_right));
iLed = increase(frameSpec, iLed); iLed = increase(frameSpec, iLed);
} }
// Construct all leds along the right of the screen (if any)
if (frameSpec.rightLedCnt > 0) { if (frameSpec.rightLedCnt > 0) {
// Determine the led-spacing
int ledCnt = frameSpec.rightLedCnt; int ledCnt = frameSpec.rightLedCnt;
double ledSpacing = 1.0/ledCnt; double ledSpacing = 1.0/ledCnt;
for (int iRight=0; iRight<ledCnt; ++iRight) { for (int iRight=0; iRight<ledCnt; ++iRight) {
// Compute the location of this led
double led_x = 1.0; double led_x = 1.0;
double led_y = ledSpacing/2.0 + iRight * ledSpacing; double led_y = ledSpacing/2.0 + iRight * ledSpacing;
mLeds.add(createLed(frameSpec, processConfig, iLed, led_x, led_y, processConfig.overlapFraction, BorderSide.right)); // Construct and add the single led specification to the list of leds
mLeds.add(createLed(frameSpec, processConfig, iLed, led_x, led_y, processConfig.getOverlapFraction(), BorderSide.right));
iLed = increase(frameSpec, iLed); iLed = increase(frameSpec, iLed);
} }
} }
// Construct the bottom-right led (if bottom-right is enabled)
if (frameSpec.bottomRightCorner) { if (frameSpec.bottomRightCorner) {
mLeds.add(createLed(frameSpec, processConfig, iLed, 1.0, 1.0, processConfig.overlapFraction, BorderSide.bottom_right)); mLeds.add(createLed(frameSpec, processConfig, iLed, 1.0, 1.0, processConfig.getOverlapFraction(), BorderSide.bottom_right));
iLed = increase(frameSpec, iLed); iLed = increase(frameSpec, iLed);
} }
// Construct all leds along the bottom of the screen (if any)
if (frameSpec.bottomLedCnt > 0) { if (frameSpec.bottomLedCnt > 0) {
// Determine the led-spacing (based on top-leds [=bottom leds + gap size])
int ledCnt = frameSpec.topLedCnt; int ledCnt = frameSpec.topLedCnt;
double ledSpacing = (double)1.0/ledCnt; double ledSpacing = (double)1.0/ledCnt;
for (int iBottom=(ledCnt-1); iBottom>=0; --iBottom) { for (int iBottom=(ledCnt-1); iBottom>=0; --iBottom) {
// Special case for the bottom-gap
if (iBottom > (frameSpec.bottomLedCnt-1)/2 && iBottom < ledCnt - frameSpec.bottomLedCnt/2) { if (iBottom > (frameSpec.bottomLedCnt-1)/2 && iBottom < ledCnt - frameSpec.bottomLedCnt/2) {
continue; continue;
} }
// Compute the location of this led
double led_x = ledSpacing/2.0 + iBottom * ledSpacing; double led_x = ledSpacing/2.0 + iBottom * ledSpacing;
double led_y = 1.0; double led_y = 1.0;
mLeds.add(createLed(frameSpec, processConfig, iLed, led_x, led_y, processConfig.overlapFraction, BorderSide.bottom)); // Construct and add the single led specification to the list of leds
mLeds.add(createLed(frameSpec, processConfig, iLed, led_x, led_y, processConfig.getOverlapFraction(), BorderSide.bottom));
iLed = increase(frameSpec, iLed); iLed = increase(frameSpec, iLed);
} }
} }
// Construct the bottom-left led (if bottom-left is enabled)
if (frameSpec.bottomLeftCorner) { if (frameSpec.bottomLeftCorner) {
mLeds.add(createLed(frameSpec, processConfig, iLed, 0.0, 1.0, processConfig.overlapFraction, BorderSide.bottom_left)); mLeds.add(createLed(frameSpec, processConfig, iLed, 0.0, 1.0, processConfig.getOverlapFraction(), BorderSide.bottom_left));
iLed = increase(frameSpec, iLed); iLed = increase(frameSpec, iLed);
} }
// Construct all leds along the left of the screen (if any)
if (frameSpec.leftLedCnt > 0) { if (frameSpec.leftLedCnt > 0) {
// Determine the led-spacing
int ledCnt = frameSpec.leftLedCnt; int ledCnt = frameSpec.leftLedCnt;
double ledSpacing = (double)1.0/ledCnt; double ledSpacing = (double)1.0/ledCnt;
for (int iRight=(ledCnt-1); iRight>=0; --iRight) { for (int iRight=(ledCnt-1); iRight>=0; --iRight) {
// Compute the location of this led
double led_x = 0.0; double led_x = 0.0;
double led_y = ledSpacing/2.0 + iRight * ledSpacing; double led_y = ledSpacing/2.0 + iRight * ledSpacing;
mLeds.add(createLed(frameSpec, processConfig, iLed, led_x, led_y, processConfig.overlapFraction, BorderSide.left)); // Construct and add the single led specification to the list of leds
mLeds.add(createLed(frameSpec, processConfig, iLed, led_x, led_y, processConfig.getOverlapFraction(), BorderSide.left));
iLed = increase(frameSpec, iLed); iLed = increase(frameSpec, iLed);
} }
} }
@ -103,6 +156,19 @@ public class LedFrameFactory {
return mLeds; return mLeds;
} }
/**
* Constructs the specification of a single led
*
* @param pFrameSpec The overall led-frame specification
* @param pProcessSpec The overall image-processing specification
* @param seqNr The number of the led
* @param x_frac The x location of the led in fractional range [0.0; 1.0]
* @param y_frac The y location of the led in fractional range [0.0; 1.0]
* @param overlap_frac The fractional overlap of the led integration with its neighbor
* @param pBorderSide The side on which the led is located
*
* @return The image integration specifications of the single led
*/
private static Led createLed(LedFrameConstruction pFrameSpec, ImageProcessConfig pProcessSpec, int seqNr, double x_frac, double y_frac, double overlap_frac, BorderSide pBorderSide) { private static Led createLed(LedFrameConstruction pFrameSpec, ImageProcessConfig pProcessSpec, int seqNr, double x_frac, double y_frac, double overlap_frac, BorderSide pBorderSide) {
Led led = new Led(); Led led = new Led();
led.mLedSeqNr = seqNr; led.mLedSeqNr = seqNr;
@ -114,51 +180,50 @@ public class LedFrameFactory {
switch (pBorderSide) { switch (pBorderSide) {
case top_left: { case top_left: {
led.mImageRectangle = new Rectangle2D.Double(0.0, 0.0, pProcessSpec.verticalDepth, pProcessSpec.horizontalDepth); led.mImageRectangle = new Rectangle2D.Double(0.0, 0.0, pProcessSpec.getVerticalDepth(), pProcessSpec.getHorizontalDepth());
break; break;
} }
case top_right: { case top_right: {
led.mImageRectangle = new Rectangle2D.Double(1.0-pProcessSpec.verticalDepth, 0.0, pProcessSpec.verticalDepth, pProcessSpec.horizontalDepth); led.mImageRectangle = new Rectangle2D.Double(1.0-pProcessSpec.getVerticalDepth(), 0.0, pProcessSpec.getVerticalDepth(), pProcessSpec.getHorizontalDepth());
break; break;
} }
case bottom_left: { case bottom_left: {
led.mImageRectangle = new Rectangle2D.Double(0.0, 1.0-pProcessSpec.horizontalDepth, pProcessSpec.verticalDepth, pProcessSpec.horizontalDepth); led.mImageRectangle = new Rectangle2D.Double(0.0, 1.0-pProcessSpec.getHorizontalDepth(), pProcessSpec.getVerticalDepth(), pProcessSpec.getHorizontalDepth());
break; break;
} }
case bottom_right: { case bottom_right: {
led.mImageRectangle = new Rectangle2D.Double(1.0-pProcessSpec.verticalDepth, 1.0-pProcessSpec.horizontalDepth, pProcessSpec.verticalDepth, pProcessSpec.horizontalDepth); led.mImageRectangle = new Rectangle2D.Double(1.0-pProcessSpec.getVerticalDepth(), 1.0-pProcessSpec.getHorizontalDepth(), pProcessSpec.getVerticalDepth(), pProcessSpec.getHorizontalDepth());
break; break;
} }
case top:{ case top:{
double intXmin_frac = Math.max(0.0, x_frac-widthFrac); double intXmin_frac = Math.max(0.0, x_frac-widthFrac);
double intXmax_frac = Math.min(x_frac+widthFrac, 1.0); double intXmax_frac = Math.min(x_frac+widthFrac, 1.0);
led.mImageRectangle = new Rectangle2D.Double(intXmin_frac, 0.0, intXmax_frac-intXmin_frac, pProcessSpec.horizontalDepth); led.mImageRectangle = new Rectangle2D.Double(intXmin_frac, 0.0, intXmax_frac-intXmin_frac, pProcessSpec.getHorizontalDepth());
break; break;
} }
case bottom: case bottom:
{ {
double intXmin_frac = Math.max(0.0, x_frac-widthFrac); double intXmin_frac = Math.max(0.0, x_frac-widthFrac);
double intXmax_frac = Math.min(x_frac+widthFrac, 1.0); double intXmax_frac = Math.min(x_frac+widthFrac, 1.0);
led.mImageRectangle = new Rectangle2D.Double(intXmin_frac, 1.0-pProcessSpec.horizontalDepth, intXmax_frac-intXmin_frac, pProcessSpec.horizontalDepth); led.mImageRectangle = new Rectangle2D.Double(intXmin_frac, 1.0-pProcessSpec.getHorizontalDepth(), intXmax_frac-intXmin_frac, pProcessSpec.getHorizontalDepth());
break; break;
} }
case left: { case left: {
double intYmin_frac = Math.max(0.0, y_frac-heightFrac); double intYmin_frac = Math.max(0.0, y_frac-heightFrac);
double intYmax_frac = Math.min(y_frac+heightFrac, 1.0); double intYmax_frac = Math.min(y_frac+heightFrac, 1.0);
led.mImageRectangle = new Rectangle2D.Double(0.0, intYmin_frac, pProcessSpec.verticalDepth, intYmax_frac-intYmin_frac); led.mImageRectangle = new Rectangle2D.Double(0.0, intYmin_frac, pProcessSpec.getVerticalDepth(), intYmax_frac-intYmin_frac);
break; break;
} }
case right: case right:
double intYmin_frac = Math.max(0.0, y_frac-heightFrac); double intYmin_frac = Math.max(0.0, y_frac-heightFrac);
double intYmax_frac = Math.min(y_frac+heightFrac, 1.0); double intYmax_frac = Math.min(y_frac+heightFrac, 1.0);
led.mImageRectangle = new Rectangle2D.Double(1.0-pProcessSpec.verticalDepth, intYmin_frac, pProcessSpec.verticalDepth, intYmax_frac-intYmin_frac); led.mImageRectangle = new Rectangle2D.Double(1.0-pProcessSpec.getVerticalDepth(), intYmin_frac, pProcessSpec.getVerticalDepth(), intYmax_frac-intYmin_frac);
break; break;
} }
return led; return led;
} }
} }

View File

@ -1,17 +1,19 @@
package org.hyperion.config; package org.hyperion.hypercon;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.util.Locale; import java.util.Locale;
import java.util.Vector; import java.util.Vector;
import org.hyperion.config.spec.ColorConfig; import org.hyperion.hypercon.spec.ColorConfig;
import org.hyperion.config.spec.DeviceConfig; import org.hyperion.hypercon.spec.DeviceConfig;
import org.hyperion.config.spec.ImageProcessConfig; import org.hyperion.hypercon.spec.ImageProcessConfig;
import org.hyperion.config.spec.Led; import org.hyperion.hypercon.spec.Led;
import org.hyperion.config.spec.LedFrameConstruction; import org.hyperion.hypercon.spec.LedFrameConstruction;
import org.hyperion.config.spec.MiscConfig; import org.hyperion.hypercon.spec.MiscConfig;
/**
* The full configuration of Hyperion with sub-items for device, color and miscelanuous items.
*/
public class LedString { public class LedString {
/** The configuration of the output device */ /** The configuration of the output device */
@ -31,6 +33,13 @@ public class LedString {
/** The translation of the led frame construction and image processing to individual led configuration */ /** The translation of the led frame construction and image processing to individual led configuration */
public Vector<Led> leds; public Vector<Led> leds;
/**
* Writes the configuration to the given file
*
* @param mFilename The absolute filename
*
* @throws IOException If unable to write the given file
*/
public void saveConfigFile(String mFilename) throws IOException { public void saveConfigFile(String mFilename) throws IOException {
try (FileWriter fw = new FileWriter(mFilename)) { try (FileWriter fw = new FileWriter(mFilename)) {
@ -57,6 +66,11 @@ public class LedString {
} }
} }
/**
* Converts the list with leds specifications to a JSON string as used by the Hyperion Deamon
*
* @return The JSON string with led-specifications
*/
String ledToJsonString() { String ledToJsonString() {
StringBuffer strBuf = new StringBuffer(); StringBuffer strBuf = new StringBuffer();
strBuf.append("\t\"leds\" : \n"); strBuf.append("\t\"leds\" : \n");

View File

@ -0,0 +1,37 @@
package org.hyperion.hypercon;
import javax.swing.JFrame;
import javax.swing.UIManager;
import org.hyperion.hypercon.gui.ConfigPanel;
/**
* (static) Main-class for starting HyperCon (the Hyperion configuration file builder) as a standard
* JAVA application (contains the entry-point).
*/
public class Main {
/**
* Entry point to start HyperCon
*
* @param pArgs HyperCon does not have command line arguments
*/
public static void main(String[] pArgs) {
try {
// Configure swing to use the system default look and feel
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {}
// Create a frame for the configuration panel
JFrame frame = new JFrame();
frame.setTitle("Hyperion configuration Tool");
frame.setSize(1300, 600);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// Add the HyperCon configuration panel
frame.setContentPane(new ConfigPanel());
// Show the frame
frame.setVisible(true);
}
}

View File

@ -1,4 +1,4 @@
package org.hyperion.config.gui; package org.hyperion.hypercon.gui;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.BoxLayout; import javax.swing.BoxLayout;
@ -8,6 +8,11 @@ import javax.swing.JPanel;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel; import javax.swing.SpinnerNumberModel;
/**
* Configuration panel for the ColorConfig.
*
* NB This has not been integrated in the GUI jet!
*/
public class ColorConfigPanel extends JPanel { public class ColorConfigPanel extends JPanel {
private JPanel mRgbTransformPanel; private JPanel mRgbTransformPanel;
private JLabel mThresholdLabel; private JLabel mThresholdLabel;

View File

@ -1,4 +1,4 @@
package org.hyperion.config.gui; package org.hyperion.hypercon.gui;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.Dimension; import java.awt.Dimension;
@ -15,17 +15,23 @@ import javax.swing.JButton;
import javax.swing.JFileChooser; import javax.swing.JFileChooser;
import javax.swing.JPanel; import javax.swing.JPanel;
import org.hyperion.config.LedFrameFactory; import org.hyperion.hypercon.LedFrameFactory;
import org.hyperion.config.LedString; import org.hyperion.hypercon.LedString;
/**
* The main-config panel of HyperCon. Includes the configuration and the panels to edit and
* write-out the configuration. This can be placed on JFrame, JDialog or JApplet as required.
*/
public class ConfigPanel extends JPanel { public class ConfigPanel extends JPanel {
/** The LED configuration information*/
private final LedString ledString = new LedString(); private final LedString ledString = new LedString();
/** Action for write the Hyperion deamon configuration file */
private final Action mSaveConfigAction = new AbstractAction("Create Hyperion Configuration") { private final Action mSaveConfigAction = new AbstractAction("Create Hyperion Configuration") {
JFileChooser fileChooser = new JFileChooser();
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
JFileChooser fileChooser = new JFileChooser();
if (fileChooser.showSaveDialog(ConfigPanel.this) != JFileChooser.APPROVE_OPTION) { if (fileChooser.showSaveDialog(ConfigPanel.this) != JFileChooser.APPROVE_OPTION) {
return; return;
} }
@ -39,27 +45,39 @@ public class ConfigPanel extends JPanel {
} }
}; };
/** The panel for containing the example 'Hyperion TV' */
private JPanel mTvPanel; private JPanel mTvPanel;
/** The simulated 'Hyperion TV' */
private JHyperionTv mHyperionTv; private JHyperionTv mHyperionTv;
private JPanel mConstructionPanel; /** The left (WEST) side panel containing the diferent configuration panels */
private JPanel mIntegrationPanel;
private JPanel mSpecificationPanel; private JPanel mSpecificationPanel;
/** The panel for specifying the construction of the LED-Frame */
private JPanel mConstructionPanel;
/** The panel for specifying the image integration */
private JPanel mIntegrationPanel;
/** The panel for specifying the miscallenuous configuration */
private MiscConfigPanel mMiscPanel; private MiscConfigPanel mMiscPanel;
/** The button connected to mSaveConfigAction */
private JButton mSaveConfigButton; private JButton mSaveConfigButton;
/**
* Constructs the configuration panel with a default initialised led-frame and configuration
*/
public ConfigPanel() { public ConfigPanel() {
super(); super();
initialise(); initialise();
// Compute the individual leds for the current configuration
ledString.leds = LedFrameFactory.construct(ledString.mLedFrameConfig, ledString.mProcessConfig); ledString.leds = LedFrameFactory.construct(ledString.mLedFrameConfig, ledString.mProcessConfig);
mHyperionTv.setLeds(ledString.leds); mHyperionTv.setLeds(ledString.leds);
// Add Observer to update the individual leds if the configuration changes
final Observer observer = new Observer() { final Observer observer = new Observer() {
@Override @Override
public void update(Observable o, Object arg) { public void update(Observable o, Object arg) {
@ -72,6 +90,9 @@ public class ConfigPanel extends JPanel {
ledString.mProcessConfig.addObserver(observer); ledString.mProcessConfig.addObserver(observer);
} }
/**
* Initialises the config-panel
*/
private void initialise() { private void initialise() {
setLayout(new BorderLayout()); setLayout(new BorderLayout());
@ -80,6 +101,11 @@ public class ConfigPanel extends JPanel {
} }
/**
* Created, if not exists, and returns the panel holding the simulated 'Hyperion TV'
*
* @return The Tv panel
*/
private JPanel getTvPanel() { private JPanel getTvPanel() {
if (mTvPanel == null) { if (mTvPanel == null) {
mTvPanel = new JPanel(); mTvPanel = new JPanel();

View File

@ -1,4 +1,4 @@
package org.hyperion.config.gui; package org.hyperion.hypercon.gui;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
@ -15,7 +15,7 @@ import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
import org.hyperion.config.spec.ImageProcessConfig; import org.hyperion.hypercon.spec.ImageProcessConfig;
public class ImageProcessPanel extends JPanel implements Observer { public class ImageProcessPanel extends JPanel implements Observer {
@ -126,25 +126,30 @@ public class ImageProcessPanel extends JPanel implements Observer {
@Override @Override
public void update(Observable pObs, Object pArg) { public void update(Observable pObs, Object pArg) {
if (pObs == mProcessConfig && pArg != this) { if (pObs == mProcessConfig && pArg != this) {
mHorizontalDepthSpinner.setValue(mProcessConfig.horizontalDepth * 100.0); mHorizontalDepthSpinner.setValue(mProcessConfig.getHorizontalDepth() * 100.0);
mVerticalDepthSpinner.setValue(mProcessConfig.verticalDepth * 100.0); mVerticalDepthSpinner.setValue(mProcessConfig.getVerticalDepth() * 100.0);
mOverlapSpinner.setValue(mProcessConfig.overlapFraction * 100.0); mOverlapSpinner.setValue(mProcessConfig.getOverlapFraction() * 100.0);
} }
} }
private final ActionListener mActionListener = new ActionListener() { private final ActionListener mActionListener = new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
mProcessConfig.blackBorderRemoval = (mBlackborderDetectorCombo.getSelectedItem() == "On"); // Update the processing configuration
mProcessConfig.setBlackBorderRemoval((mBlackborderDetectorCombo.getSelectedItem() == "On"));
// Notify observers
mProcessConfig.notifyObservers(this);
} }
}; };
private final ChangeListener mChangeListener = new ChangeListener() { private final ChangeListener mChangeListener = new ChangeListener() {
@Override @Override
public void stateChanged(ChangeEvent e) { public void stateChanged(ChangeEvent e) {
mProcessConfig.horizontalDepth = ((Double)mHorizontalDepthSpinner.getValue())/100.0; // Update the processing configuration
mProcessConfig.verticalDepth = ((Double)mVerticalDepthSpinner.getValue())/100.0; mProcessConfig.setHorizontalDepth(((Double)mHorizontalDepthSpinner.getValue())/100.0);
mProcessConfig.overlapFraction = ((Double)mOverlapSpinner.getValue())/100.0; mProcessConfig.setVerticalDepth(((Double)mVerticalDepthSpinner.getValue())/100.0);
mProcessConfig.setOverlapFraction(((Double)mOverlapSpinner.getValue())/100.0);
mProcessConfig.setChanged();
// Notify observers
mProcessConfig.notifyObservers(this); mProcessConfig.notifyObservers(this);
} }
}; };

View File

@ -1,4 +1,4 @@
package org.hyperion.config.gui; package org.hyperion.hypercon.gui;
import java.awt.BasicStroke; import java.awt.BasicStroke;
import java.awt.BorderLayout; import java.awt.BorderLayout;
@ -28,7 +28,7 @@ import javax.swing.JMenu;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import org.hyperion.config.spec.Led; import org.hyperion.hypercon.spec.Led;
public class JHyperionTv extends Component { public class JHyperionTv extends Component {
@ -293,7 +293,7 @@ public class JHyperionTv extends Component {
ledPaint.screenX = led.lastX; ledPaint.screenX = led.lastX;
ledPaint.screenY = led.lastY; ledPaint.screenY = led.lastY;
ledPaint.angle_rad = 0.5*Math.PI - led.led.mSide.getAngle(); ledPaint.angle_rad = 0.5*Math.PI - led.led.mSide.getAngle_rad();
ledPaint.seqNr = led.led.mLedSeqNr; ledPaint.seqNr = led.led.mLedSeqNr;
} }

View File

@ -1,4 +1,4 @@
package org.hyperion.config.gui; package org.hyperion.hypercon.gui;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
@ -13,8 +13,8 @@ import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
import org.hyperion.config.spec.DeviceType; import org.hyperion.hypercon.spec.DeviceType;
import org.hyperion.config.spec.LedFrameConstruction; import org.hyperion.hypercon.spec.LedFrameConstruction;
public class LedFramePanel extends JPanel { public class LedFramePanel extends JPanel {

View File

@ -1,4 +1,4 @@
package org.hyperion.config.gui; package org.hyperion.hypercon.gui;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
@ -8,8 +8,8 @@ import javax.swing.JComboBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import org.hyperion.config.spec.BootSequence; import org.hyperion.hypercon.spec.BootSequence;
import org.hyperion.config.spec.MiscConfig; import org.hyperion.hypercon.spec.MiscConfig;
public class MiscConfigPanel extends JPanel { public class MiscConfigPanel extends JPanel {

View File

@ -0,0 +1,31 @@
package org.hyperion.hypercon.spec;
/**
* Enumeration of possible boot sequences
*/
public enum BootSequence {
/** The rainbow boot sequence */
rainbow,
/** The Knight Rider (or KITT) boot sequence */
knight_rider,
/** No boot sequence */
none;
/**
* Returns a string representation of the BootSequence
*
* @return String representation of this boot-sequence
*/
@Override
public String toString() {
switch(this) {
case rainbow:
return "Rainbow";
case knight_rider:
return "Kinght Rider";
case none:
return "None";
}
return "None";
}
}

View File

@ -0,0 +1,37 @@
package org.hyperion.hypercon.spec;
/**
* Enumeration of possible led-locations (aka border-sides). This also contains the specification of
* the angle at which the led is placed along a specific border (0.0rad = pointing right).
*/
public enum BorderSide {
top_left (0.75*Math.PI),
top(0.5*Math.PI),
top_right(0.25*Math.PI),
right(0.0*Math.PI),
bottom_right(-0.25*Math.PI),
bottom(-0.5*Math.PI),
bottom_left(-0.75*Math.PI),
left(1.0*Math.PI);
/** The angle of the led [rad] */
private final double mAngle_rad;
/**
* Constructs the BorderSide with the given led angle
*
* @param pAngle_rad The angle of the led [rad]
*/
BorderSide(double pAngle_rad) {
mAngle_rad = pAngle_rad;
}
/**
* Returns the angle of the led placement
*
* @return The angle of the led [rad]
*/
public double getAngle_rad() {
return mAngle_rad;
}
}

View File

@ -1,27 +1,49 @@
package org.hyperion.config.spec; package org.hyperion.hypercon.spec;
import java.util.Locale; import java.util.Locale;
/**
* The color tuning parameters of the different color channels (both in RGB space as in HSV space)
*/
public class ColorConfig { public class ColorConfig {
/** The saturation gain (in HSV space) */
double mSaturationGain = 1.0; double mSaturationGain = 1.0;
/** The value gain (in HSV space) */
double mValueGain = 1.0; double mValueGain = 1.0;
/** The minimum required RED-value (in RGB space) */
double mRedThreshold = 0.0; double mRedThreshold = 0.0;
/** The gamma-curve correct for the RED-value (in RGB space) */
double mRedGamma = 1.0; double mRedGamma = 1.0;
/** The black-level of the RED-value (in RGB space) */
double mRedBlacklevel = 0.0; double mRedBlacklevel = 0.0;
/** The white-level of the RED-value (in RGB space) */
double mRedWhitelevel = 1.0; double mRedWhitelevel = 1.0;
/** The minimum required GREEN-value (in RGB space) */
double mGreenThreshold = 0.0; double mGreenThreshold = 0.0;
/** The gamma-curve correct for the GREEN-value (in RGB space) */
double mGreenGamma = 1.0; double mGreenGamma = 1.0;
/** The black-level of the GREEN-value (in RGB space) */
double mGreenBlacklevel = 0.0; double mGreenBlacklevel = 0.0;
/** The white-level of the GREEN-value (in RGB space) */
double mGreenWhitelevel = 1.0; double mGreenWhitelevel = 1.0;
/** The minimum required BLUE-value (in RGB space) */
double mBlueThreshold = 0.0; double mBlueThreshold = 0.0;
/** The gamma-curve correct for the BLUE-value (in RGB space) */
double mBlueGamma = 1.0; double mBlueGamma = 1.0;
/** The black-level of the BLUE-value (in RGB space) */
double mBlueBlacklevel = 0.0; double mBlueBlacklevel = 0.0;
/** The white-level of the BLUE-value (in RGB space) */
double mBlueWhitelevel = 1.0; double mBlueWhitelevel = 1.0;
/**
* Creates the JSON string of the configuration as used in the Hyperion daemon configfile
*
* @return The JSON string of this ColorConfig
*/
public String toJsonString() { public String toJsonString() {
StringBuffer strBuf = new StringBuffer(); StringBuffer strBuf = new StringBuffer();
strBuf.append("\t\"color\" :\n"); strBuf.append("\t\"color\" :\n");
@ -33,7 +55,12 @@ public class ColorConfig {
return strBuf.toString(); return strBuf.toString();
} }
public String hsvToJsonString() { /**
* Creates the JSON string of the HSV-subconfiguration as used in the Hyperion deaomn configfile
*
* @return The JSON string of the HSV-config
*/
private String hsvToJsonString() {
StringBuffer strBuf = new StringBuffer(); StringBuffer strBuf = new StringBuffer();
strBuf.append("\t\t\"hsv\" :\n"); strBuf.append("\t\t\"hsv\" :\n");
strBuf.append("\t\t{\n"); strBuf.append("\t\t{\n");
@ -44,7 +71,12 @@ public class ColorConfig {
return strBuf.toString(); return strBuf.toString();
} }
public String rgbToJsonString() { /**
* Creates the JSON string of the RGB-subconfiguration as used in the Hyperion deaomn configfile
*
* @return The JSON string of the RGB-config
*/
private String rgbToJsonString() {
StringBuffer strBuf = new StringBuffer(); StringBuffer strBuf = new StringBuffer();
strBuf.append("\t\t\"red\" :\n"); strBuf.append("\t\t\"red\" :\n");

View File

@ -1,12 +1,24 @@
package org.hyperion.config.spec; package org.hyperion.hypercon.spec;
/**
* The device specific configuration
*/
public class DeviceConfig { public class DeviceConfig {
/** The name of the device */
String mName = "MyPi"; String mName = "MyPi";
/** The type specification of the device */
DeviceType mType = DeviceType.ws2801; DeviceType mType = DeviceType.ws2801;
/** The device 'file' name */
String mOutput = "/dev/spidev0.0"; String mOutput = "/dev/spidev0.0";
/** The baudrate of the device */
int mBaudrate = 48000; int mBaudrate = 48000;
/**
* Creates the JSON string of the configuration as used in the Hyperion daemon configfile
*
* @return The JSON string of this DeviceConfig
*/
public String toJsonString() { public String toJsonString() {
StringBuffer strBuf = new StringBuffer(); StringBuffer strBuf = new StringBuffer();
strBuf.append("\t\"device\" :\n"); strBuf.append("\t\"device\" :\n");

View File

@ -0,0 +1,13 @@
package org.hyperion.hypercon.spec;
/**
* Enumeration of known device types
*/
public enum DeviceType {
/** WS2801 Led String device with one continuous shift-register */
ws2801,
/** Test device for writing color values to file-output */
test,
/** No device, no output is generated */
none;
}

View File

@ -0,0 +1,110 @@
package org.hyperion.hypercon.spec;
import java.util.Observable;
import org.hyperion.hypercon.LedFrameFactory;
/**
* Configuration parameters for the image processing. These settings are translated using the
* {@link LedFrameFactory} to configuration items used in the Hyperion daemon configfile.
*
*/
public class ImageProcessConfig extends Observable {
/** The 'integration depth' of the leds along the horizontal axis of the tv */
private double mHorizontalDepth = 0.05;
/** The 'integration depth' of the leds along the vertical axis of the tv */
private double mVerticalDepth = 0.05;
/** The fraction of overlap from one to another led */
private double mOverlapFraction = 0.0;
/** Flag indicating that black borders are excluded in the image processing */
private boolean mBlackBorderRemoval = true;
/**
* Returns the horizontal depth (top and bottom) of the image integration as a fraction of the
* image [0.0; 1.0]
*
* @return The horizontal integration depth [0.0; 1.0]
*/
public double getHorizontalDepth() {
return mHorizontalDepth;
}
/**
* Sets the horizontal depth (top and bottom) of the image integration as a fraction of the
* image [0.0; 1.0]
*
* @param pHorizontalDepth The horizontal integration depth [0.0; 1.0]
*/
public void setHorizontalDepth(double pHorizontalDepth) {
if (mHorizontalDepth != pHorizontalDepth) {
mHorizontalDepth = pHorizontalDepth;
setChanged();
}
}
/**
* Returns the vertical depth (left and right) of the image integration as a fraction of the
* image [0.0; 1.0]
*
* @return The vertical integration depth [0.0; 1.0]
*/
public double getVerticalDepth() {
return mVerticalDepth;
}
/**
* Sets the vertical depth (left and right) of the image integration as a fraction of the
* image [0.0; 1.0]
*
* @param pVerticalDepth The vertical integration depth [0.0; 1.0]
*/
public void setVerticalDepth(double pVerticalDepth) {
if (mVerticalDepth != pVerticalDepth) {
mVerticalDepth = pVerticalDepth;
setChanged();
}
}
/**
* Returns the fractional overlap of one integration tile with its neighbors
*
* @return The fractional overlap of the integration tiles
*/
public double getOverlapFraction() {
return mOverlapFraction;
}
/**
* Sets the fractional overlap of one integration tile with its neighbors
*
* @param pOverlapFraction The fractional overlap of the integration tiles
*/
public void setOverlapFraction(double pOverlapFraction) {
if (mOverlapFraction != pOverlapFraction) {
mOverlapFraction = pOverlapFraction;
setChanged();
}
}
/**
* Returns the black border removal flag
* @return True if black border removal is enabled else false
*/
public boolean isBlackBorderRemoval() {
return mBlackBorderRemoval;
}
/**
* Sets the black border removal flag
* @param pBlackBorderRemoval True if black border removal is enabled else false
*/
public void setBlackBorderRemoval(boolean pBlackBorderRemoval) {
if (mBlackBorderRemoval != pBlackBorderRemoval) {
mBlackBorderRemoval = pBlackBorderRemoval;
setChanged();
}
}
}

View File

@ -0,0 +1,33 @@
package org.hyperion.hypercon.spec;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
/**
* Led specification with fractional location along screen border and fractional-rectangle for
* integrating an image into led color
*/
public class Led {
/** The sequence number of the led */
public int mLedSeqNr;
/** The side along which the led is placed */
public BorderSide mSide;
/** The fractional location of the led */
public Point2D mLocation;
/** The fractional rectangle for image integration */
public Rectangle2D mImageRectangle;
/**
* String representation of the led specification
*
* @return The led specs as nice readable string
*/
@Override
public String toString() {
return "Led[" + mLedSeqNr + "] Location=" + mLocation + " Rectangle=" + mImageRectangle;
}
}

View File

@ -1,4 +1,4 @@
package org.hyperion.config.spec; package org.hyperion.hypercon.spec;
import java.util.Observable; import java.util.Observable;
@ -6,12 +6,15 @@ import java.util.Observable;
/** /**
* The LedFrame describes the construction of leds along the sides of the TV screen. * The LedFrame describes the construction of leds along the sides of the TV screen.
*
*/ */
public class LedFrameConstruction extends Observable { public class LedFrameConstruction extends Observable {
/**
* Enumeration of the led configuration direction
*/
public enum Direction { public enum Direction {
/** Clockwise led configuration */
clockwise, clockwise,
/** Counter Clockwise led configuration */
counter_clockwise; counter_clockwise;
} }

View File

@ -1,24 +1,43 @@
package org.hyperion.config.spec; package org.hyperion.hypercon.spec;
import java.util.Locale; import java.util.Locale;
/**
* Miscellaneous configuration items for the Hyperion daemon.
*/
public class MiscConfig { public class MiscConfig {
/** The selected boot sequence */
public BootSequence mBootSequence = BootSequence.rainbow; public BootSequence mBootSequence = BootSequence.rainbow;
/** The length of the boot sequence [ms] */
public int mBootSequenceLength_ms = 3000; public int mBootSequenceLength_ms = 3000;
/** The width of 'grabbed' frames (screen shots) [pixels] */
public int mFrameGrabberWidth = 64; public int mFrameGrabberWidth = 64;
/** The height of 'grabbed' frames (screen shots) [pixels] */
public int mFrameGrabberHeight = 64; public int mFrameGrabberHeight = 64;
/** The interval of frame grabs (screen shots) [ms] */
public int mFrameGrabberInterval_ms = 100; public int mFrameGrabberInterval_ms = 100;
/** Flag enabling/disabling XBMC communication */
public boolean mXbmcChecker = true; public boolean mXbmcChecker = true;
/** The IP-address of XBMC */
public String mXbmcAddress = "127.0.0.1"; public String mXbmcAddress = "127.0.0.1";
/** The TCP JSON-Port of XBMC */
public int mXbmcTcpPort = 9090; public int mXbmcTcpPort = 9090;
/** Flag indicating that the frame-grabber is on during video playback */
public boolean mVideoOn = true; public boolean mVideoOn = true;
/** Flag indicating that the frame-grabber is on during XBMC menu */
public boolean mMenuOn = false; public boolean mMenuOn = false;
/** Flag indicating that the frame-grabber is on during picture slideshow */
public boolean mPictureOn = false; public boolean mPictureOn = false;
/** Flag indicating that the frame-grabber is on during audio playback */
public boolean mAudioOn = false; public boolean mAudioOn = false;
/**
* Creates the JSON string of the configuration as used in the Hyperion daemon configfile
*
* @return The JSON string of this MiscConfig
*/
public String toJsonString() { public String toJsonString() {
StringBuffer strBuf = new StringBuffer(); StringBuffer strBuf = new StringBuffer();
strBuf.append("\t\"bootsequence\" :\n"); strBuf.append("\t\"bootsequence\" :\n");