Java Code Samples

The watchdog is a very powerful concept. Wikipedia says:

watchdog timer (sometimes called a computer operating properly or COP timer, or simply a watchdog) is an electronic timer that is used to detect and recover from computer malfunctions. During normal operation, the computer regularly resets the watchdog timer to prevent it from elapsing, or “timing out”. If, due to a hardware fault or program error, the computer fails to reset the watchdog, the timer will elapse and generate a timeout signal. The timeout signal is used to initiate corrective action or actions. The corrective actions typically include placing the computer system in a safe state and restoring normal system operation.

The watchdog on the JNIOR can also be used to cause an action to be scheduled to execute periodically.

This example will monitor the IO Log utilizing the IoLog class. There are many ways to watch IO for changes. You could simply poll the IO and see if it changes. You are likely to set up a polling routing on some interval. If that interval is not fast enough then you have the potential of missing an change. Using the IO Log ensures that you see that a transition occurred. You have the added benefit of getting the exact time of that transition to the millisecond. This helps if you are measuring the time between transitions.

package com.integpg;

import com.integpg.system.IoEvent;
import com.integpg.system.Iolog;
import java.util.Date;

public class IOLogSampleMain implements Runnable {

    private final Iolog _iolog = new Iolog();
    private Thread _thd;



    public static void main(String[] args) throws InterruptedException {
        new IOLogSampleMain().start();

        Thread.sleep(Integer.MAX_VALUE);
    }



    public void start() {
        if (null == _thd) {
            _thd = new Thread((Runnable) this);
            _thd.setName("IoLogMonitor");
            _thd.start();
        }
    }



    @Override
    @Override
    public void run() {
        long lastConsumedTimestamp = System.currentTimeMillis();

        while (true) {
            try {
                // refresh the iolog object so that we only get new events since the last time we queried it
                _iolog.refresh(lastConsumedTimestamp);
                // get the events for the inputs only
                IoEvent[] ioEvents = _iolog.getInputEvents();

                // make sure we were returned events
                if (ioEvents.length > 0) {
                    System.out.println("IoLogMonitor returned " + ioEvents.length + " events");
                    // go through each event and print some meaningful information about it
                    for (int index = ioEvents.length - 1; index >= 0; index--) {
                        IoEvent ioEvent = ioEvents[index];
                        System.out.println("ioEvent[" + index + "]: time: " + ioEvent.timestamp + " changed input mask: " + Long.toHexString(ioEvent.mask) + " input states mask: " + Long.toHexString(ioEvent.states));

                        // update our lastConsumedTimestamp with the date of the most recent event
                        if (ioEvent.timestamp > lastConsumedTimestamp) {
                            lastConsumedTimestamp = ioEvent.timestamp;
                            System.out.println("lastConsumedTimestamp: " + new Date(lastConsumedTimestamp));
                        }
                    }
                }

                Thread.sleep(100);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
}

We can take the Message Pump sample one step further. We can incorporate real-time web page communication. The web server supports WebSockets. WebSockets allow for real-time bidirectional communication. We can leverage this feature and have these messages put on the Message Pump so that our Java application can get them.

Our web page for the example looks like this.

In the code we have a button handler that will send the json formatted message to the web server.

            // register an onclick method so that we can post a message to get a random number from our 
            // sample java application.
            document.getElementById('random-number-button').onclick = function (e) {
                var getUpdates = {Message: "Post Message", Number: 2000, Content: "get-random-number"};
                _comm.sendJson(getUpdates);
            };

 

A full listing of the web page is as follows

<!DOCTYPE html>
<html lang="en">

    <head>
        <base href="/messagepumpsample/">

        <title>Message Pump Web Interface</title>

        <script src="comm.js" type="text/javascript"></script>
        <script src="md5.js" type="text/javascript"></script>

        <style>
            body { padding: 5px; }
        </style>

    </head>


    <body>

        <div>

            <h1>Message Pump Web Interface</h1>

            <button id="random-number-button">Get Random Number</button>
            <p style="width: 600px;">
                Clicking the button above will cause a message to get sent to the Web Server.  The Web Server 
                then places it in the System Message Pump.  Our sample Java application will then receive it and 
                for the sake of the sample will respond with a random number.  By placing the random number in a 
                message and back on to the System Message Pump with the same message type that it received, the 
                Operating System knows to send it back to the Web Server and in turn back to the sending Web 
                Socket connection.
            </p>

        </div>


        <script type="text/javascript">
            // our websocket communication object
            var _comm;
            var _loggedIn = false;

            // method called when the connection is successfully opened
            var onopen = function () {
                console.log("comm opened");
            };
            
            // method called when our websocket object receives a message from the web server
            var onmessage = function (evt) {
                var json = JSON.parse(evt.data);
                console.log(json);

                if (json.Message === "Monitor") {
                    if (!_loggedIn) {
                    }
                    _loggedIn = true;
                }

                //
                else if (json.Message === "Reply Message") {
                    if (2000 === json.Number) {
                        alert("Your Random Number is " + json.Content);
                    }
                }
            };
            
            // instantiate our websocket communications object and wire up some methods.  lastly call connect!
            _comm = new Comm();
            _comm.onopen = onopen;
            _comm.onmessage = onmessage;
            _comm.connect();


            
            // register an onclick method so that we can post a message to get a random number from our 
            // sample java application.
            document.getElementById('random-number-button').onclick = function (e) {
                var getUpdates = {Message: "Post Message", Number: 2000, Content: "get-random-number"};
                _comm.sendJson(getUpdates);
            };
        </script>
    </body>

</html>

To accomplish this we created a class to handle the get-random-number request. We could have handled this in our Main class but hey I like modularity.

package com.integpg.messagepumpsample;

import com.integpg.system.SystemMsg;
import java.util.Random;

public class RandomNumberMessageHandler implements MessagePumpListener {

    @Override
    public void messageReceived(SystemMsg systemMsg) {
        // this sample uses message type 2000
        if (2000 == systemMsg.type) {
            String content = new String(systemMsg.msg);
            System.out.println("content: " + content);
            
            Random rand = new Random();
            int randomNumber = rand.nextInt();
            
            SystemMsg responseMsg = new SystemMsg();
            responseMsg.type = 2000;
            responseMsg.msg = String.valueOf(randomNumber).getBytes();
            
            MessagePumpEngine.postMessage(responseMsg);
        }
    }

}

We also had to modify our init() method to attach our MessagePumpHandler.

package com.integpg.messagepumpsample;

import com.integpg.system.SystemMsg;
import java.util.Random;

public class RandomNumberMessageHandler implements MessagePumpListener {

    @Override
    public void messageReceived(SystemMsg systemMsg) {
        // this sample uses message type 2000
        if (2000 == systemMsg.type) {
            String content = new String(systemMsg.msg);
            System.out.println("content: " + content);
            
            // get a random number
            Random rand = new Random();
            int randomNumber = rand.nextInt();
            
            // build our response
            SystemMsg responseMsg = new SystemMsg();
            responseMsg.type = 2000;
            responseMsg.msg = String.valueOf(randomNumber).getBytes();
            MessagePumpEngine.postMessage(responseMsg);
        }
    }

}

Almost immediately upon clicking the button we get our response.

As you can see here the web page gives you an amazing ability to communicate with a Java application in real-time.

There are many times that you want to get a message from the system. You may also want to communicate between processes. To do either of these we employ the Message Pump.

In this example  we will monitor the messages that are going around the message pump inside the JNIOR.

We first need a class that will define all the message pump types

package com.integpg.messagepumpsample;

/**
 * A class that contains an enumeration of values for each message type.
 */
public class SystemMessageTypes {

    public static final int SM_SHUTDOWN = 0x01;
    public static final int SM_PROBE = 0x02;
    public static final int SM_GCRUN = 0x10;
    public static final int SM_WATCHDOG = 0x11;
    public static final int SM_SYSLOG = 0x12;
    public static final int SM_REGUPDATE = 0x40;
    public static final int SM_WEBSTARTUP = 0x60;
    public static final int SM_WEBSHUTDOWN = 0x61;
    public static final int SM_PROTCMDMSG = 0x70;
    public static final int SM_PROTCMDRESP = 0x71;
    public static final int SM_PIPEOPEN = 0x80;
    public static final int SM_PIPECLOSE = 0x81;
    public static final int SM_USER = 0x400;



    /**
     * @return a String definition based on the type parameter
     */
    public static String getMessageNameByType(int type) {
        switch (type) {
            case SM_SHUTDOWN:
                return "Shutdown";
            case SM_PROBE:
                return "Probe";
            case SM_GCRUN:
                return "GC Run";
            case SM_WATCHDOG:
                return "Watchdog";
            case SM_SYSLOG:
                return "Syslog";
            case SM_REGUPDATE:
                return "Registry Update";
            case SM_WEBSTARTUP:
                return "Web Server Startup";
            case SM_WEBSHUTDOWN:
                return "Web Server Shutdown";
            case SM_PROTCMDMSG:
                return "Protocol Command Message";
            case SM_PROTCMDRESP:
                return "Protocol Command Reesponse";
            case SM_PIPEOPEN:
                return "Pipe Opened";
            case SM_PIPECLOSE:
                return "Pipe Closed";
            default:
                if (type >= SM_USER) return "User Defined Type " + String.valueOf(type);
                else return "Unknown Type " + String.valueOf(type);
        }
    }
}

Not only does the above class define the types but it gives us a nice helper function to get a nice textual description for the message type.

We will create a class that will monitor the message pump. The biggest note to observe is that we MUST forward the message once we receive it so that other processes can see the message. The message pump message delivery is also time sensitive. If we receive the message and perform a lengthy process before re-posting it the we could cause the system to assert as the message pump timing has been violated.

package com.integpg.messagepumpsample;

import com.integpg.system.MessagePump;
import com.integpg.system.SystemMsg;
import java.util.Vector;

public class MessagePumpEngine implements Runnable {

    private static final MessagePumpEngine THIS = new MessagePumpEngine();
    private static final MessagePump MESSAGE_PUMP = new MessagePump();
    private static final Vector LISTENERS = new Vector<>();

    private static Thread _thread;



    /**
     * Singleton constructor
     */
    private MessagePumpEngine() {
    }



    /**
     * adds a listener that will be alerted of all received messages. The listener will be responsible for determining
     * if the message has meaning to them
     */
    public static void addListener(MessagePumpListener listener) {
        synchronized (LISTENERS) {
            LISTENERS.addElement(listener);
        }
    }



    /**
     * starts our message pump engine.
     */
    static void start() {
        if (null == _thread) {
            _thread = new Thread(THIS);
            _thread.setName("message-pump-engine");
            _thread.setDaemon(true);
            _thread.start();
        }
    }



    @Override
    public void run() {
        System.out.println("open the message pump and start monitoring.\r\n");
        MESSAGE_PUMP.open();

        for (;;) {
            // read all messages from the message pump
            SystemMsg systemMsg = MESSAGE_PUMP.getMessage();

            // we must repost as fast as we can
            MESSAGE_PUMP.postMessage(systemMsg);

            // notify all of our listeners
            synchronized (LISTENERS) {
                for (int i = 0; i < LISTENERS.size(); i++) {
                    MessagePumpListener listener = LISTENERS.elementAt(i);
                    listener.messageReceived(systemMsg);
                }
            }

        }
    }



    /**
     * Exposes the postMesssage method of the System MessagePump
     *
     * @param msg the message the will be sent to the system message pump
     */
    public static void postMessage(SystemMsg msg) {
        MESSAGE_PUMP.postMessage(msg);
    }
}

When the above class receives a message from the message pump it will want to alert any listeners.  Lets define the listener interface now.

package com.integpg.messagepumpsample;

import com.integpg.system.SystemMsg;

/**
 * An interface that outlines the method or methods that all classes that implement this interface must define.
 */
public interface MessagePumpListener {

    public void messageReceived(SystemMsg systemMsg);
}

Now that we have laid the ground work for the application lets glue the peices together.  Here is our Main class

package com.integpg.messagepumpsample;

/**
 * HexUtils will give us access to the hex dump so that we can show a meaningful representation of the data in each
 * message
 */
import com.integpg.janoslib.utils.HexUtils;
/**
 * System classes pertaining to the message pump itself and the class that will be returned from the getMessage call
 */
import com.integpg.system.SystemMsg;
/**
 * A class that will format a date string quickly
 */
import com.integpg.janoslib.text.QuickDateFormat;

/**
 * A class to demonstrate the Message Pump feature in the JNIOR.
 */
public class MessagePumpSampleMain implements MessagePumpListener {

    /**
     * the QuickDateFormat() class is part of a library of classes and are beyond the scope of this example.
     */
    private final static QuickDateFormat QUICK_DATE_FORMAT = new QuickDateFormat("MM-dd-yy HH:mm:ss.fff");



    public static void main(String[] args) throws InterruptedException {
        // instantiate our main class
        MessagePumpSampleMain msgPumpSample = new MessagePumpSampleMain();
        msgPumpSample.init();

        // the main method has nothing left to do.  let it sleep forever.  Most if not all of our other threads 
        // are daemon threads that would not keep the process from sxiting if this main thread completes.  
        // Sometimes we might do somehting in this thread but for the sake of this example we have nothing to do.
        Thread.sleep(Integer.MAX_VALUE);
    }



    public void init() {
        // the message pump engine is a singleton.  We do not have to instatiate another instance.  We can just 
        // use static methods to interface with it.  
        //
        // first we need to add in any listeners that should be alerted when a new message is received.  It 
        // will be up to those llisteners to determine if it cares about the message.
        MessagePumpEngine.addListener(this);
        MessagePumpEngine.addListener(new RegistryMessageHandler());

        // we are ready.  start listening
        MessagePumpEngine.start();
    }



    @Override
    public void messageReceived(SystemMsg systemMsg) {
        // the QUICK_DATE_FORMAT.format() call is part of a library of classes and are beyond the scope of this 
        // example.
        String dateString = QUICK_DATE_FORMAT.format(System.currentTimeMillis());
        // so we have a message.  what kind is it?
        String messageName = SystemMessageTypes.getMessageNameByType(systemMsg.type);
        // print out what we know about this message
        System.out.println(dateString + " - Process Msg: " + messageName);

        // if there is data in the message then we should dump it so that we can see what it is.
        if (0 < systemMsg.msg.length) {
            // the HexUtils.hexDump() call is part of a library of classes and are beyond the scope of this 
            // example.
            String hexDumpString = HexUtils.hexDump(systemMsg.msg);
            System.out.println(hexDumpString);
        }
    }

}

In the above lines 48 and 49 we add our listener classes.  Line 48 is the this object representing the Main class.  You can see what happens in the messageReceived() method starting at line 58.  The other listener is the RegistryMessageHandler class.  Here is the definition for that class.

package com.integpg.messagepumpsample;

import com.integpg.system.JANOS;
import com.integpg.system.SystemMsg;

public class RegistryMessageHandler implements MessagePumpListener {

    @Override
    public void messageReceived(SystemMsg systemMsg) {
        // we only care about registry key updates
        if (SystemMessageTypes.SM_REGUPDATE == systemMsg.type) {
            // get the key name from the message data
            String keyName = new String(systemMsg.msg);
            // now get teh new value
            String keyValue = JANOS.getRegistryString(keyName, "");
            System.out.println("Registry Update: " + keyName + " = " + keyValue);
        }
    }

}

Each time a message is received from the message pump each of our listeners is notified.  Each listener can check the message type to see if it cares about the message.  A sample output from the application shows three interesting events.  First, I opened the web page for the unit.  The web server is NOT always running unless the web server port is accessed.  Once the web server port was hit it caused the web server to spin up and send the Web Server Startup message.  The next two events were registry updates.  The Main class listener shows us that there was a Registry Update along with the HEX dump of the message payload.  Then the RegistryMessageHandler listener used the registry key that was updated to get the new value.  You can download the sample application JAR file below.

msgpump-monitor.jar - 23 KB - MD5: 00eb2d3b97bbc67c5d1d13a9901e9fbe

This sample shows you how to read a barcode scanner using the AUX port. You must have the correct settings to communicate successfully with your device. The settings for the port may be set using the setSerialPortParams() method. This method can only be called after the port has been successfully opened.

package barcodescanner;

import com.integpg.comm.AUXSerialPort;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;



public class BarcodeScanner {
    private static int BAUD = 19200;
        

    public static void main(String[] args) {
        AUXSerialPort auxPort = null;


        try {
            // init the aux port
            auxPort = new AUXSerialPort();
            // open the port
            System.out.println("Open the AUX Serial Port");
            auxPort.open();
            // set the parameters
            System.out.println("Set port parameters to " + BAUD + ", 8, none, 1");
            auxPort.setSerialPortParams(BAUD, 8, 1, 0);
        } catch (Exception ex) {
            ex.printStackTrace();
            // cant open the serial port so exit
            System.exit(-1);
        }


        try {
            // create our reader
            InputStream is = auxPort.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);

            // read the barcodes
            System.out.println("Ready to Scan Barcodes...");
            String line = null;
            // read the serial port in a loop to get all of the barcodes.  each barcode is terminated by a 
            // linefeed.  That means we can use readLine()
            while ((line = br.readLine()) != null) {
                System.out.println("Barcode: " + line);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

}

This sample requires that the MODBUS Server is running.

This sample is meant to show you how to gain access to the MODBUS scratch memory space. You can see in the MODBUS manual that the MODBUS addressing assigns a “scratch” address space starting at WORD 256.

Since WORDs are 2 bytes we know that the starting address is going to be 512. We can gain access to the “scratch” area by opening the Modbus00 immutable block. The Modbus00 immutable block does not exist until the MODBUS server has been started on the unit at least once in its lifetime. You can use the nv command to discover whether the Modbus00 block exists or not.

If the Modbus00 block does not exist then execute the MODBUS Server. Once the MODBUS Server has been executed the Modbus00 will exist.

The immutable example shown in the Immutable Class example uses an array of long values. We will use a byte array in this example.

package modbussample;  
  
import com.integpg.system.ArrayUtils;  
import com.integpg.system.Immutable;  
  
  
  
public class ModbusSample {  
  
    public static void main(String[] args) throws InterruptedException {  
        // open the Modbus00 immutable block  
        System.out.println("Open the MODBUS Store");  
        byte[] modbusStore = Immutable.getByteArray("Modbus00");  
  
        // if the block does not exist then alert the user and exit.  it is not our responsibility to create it  
        if (modbusStore == null) {  
            System.out.println("MODBUS store has not been created.  Please run the MODBUS Server application.");  
            System.exit(0);  
        }  
  
  
        // the modbus store must exist.  loop so that external changes by a client are seen by our application  
        while (true) {  
            // get and print the first 4 WORDs in our scratch area  
            short[] value = new short[]{  
                ArrayUtils.getShort(modbusStore, 512),  
                ArrayUtils.getShort(modbusStore, 514),  
                ArrayUtils.getShort(modbusStore, 516),  
                ArrayUtils.getShort(modbusStore, 518)  
            };  
            System.out.println("WORDs @0256: " + value[0] + ", " + value[1] + ", " + value[2] + ", " + value[3]);  
  
  
            // get and print the first 8 bytes that represent the first 4 WORDs in our scratch area  
            byte[] b = new byte[8];  
            ArrayUtils.arraycopy(modbusStore, 512, b, 0, b.length);  
            System.out.println("bytes @0512: " + hexDump(b, 0, b.length));  
  
  
            // sleep a little before checking again  
            Thread.sleep(1000);  
        }  
    }  
  
  
  
    public static String hexDump(byte[] bytes, int offset, int length) {  
        StringBuffer sb = new StringBuffer();  
        StringBuffer chars = new StringBuffer();  
  
        int i;  
        for (i = offset; i  
                < length; i++) { if (i % 16 == 0) { if (chars.length() > 0) {  
                    sb.append("  ");  
                    sb.append(chars.toString());  
                    chars  
                            = new StringBuffer();  
                    sb.append("\r\n");  
                }  
  
            } else if (i % 16 == 8) {  
                chars.append(" ");  
                sb.append("  ");  
            }  
  
            if (bytes[i] >= 32) {  
                chars.append((char) bytes[i]);  
            } else {  
                chars.append('.');  
            }  
  
            int p = sb.length();  
            sb.append(Integer.toHexString((bytes[i] & 0xff) / 16));  
            sb.append(Integer.toHexString((bytes[i] & 0xff) % 16));  
            sb.append(" ");  
        }  
  
        int mod = i % 16;  
        if (mod != 0) {  
            if (mod <= 8) { sb.append(" "); } for (i = 16 - (mod); i > 0; i--) {  
                sb.append("   ");  
            }  
  
            sb.append("  ");  
            sb.append(chars.toString());  
        }  
  
        return sb.toString();  
    }  
  
}  

Here is some sample output from our application. We used a PC MODBUS client to adjust the values of the registers in the MODBUS scratch address space. You can see the values changing during the execution of our application.

This sample shows you how to use the Immutable class. The immutable class represents persistent storage that can be accessed at the low level as an array of primitive types. This example shows the use of an array of longs. The long values in this application are date values that represent when the application was started.

package immutablesample;  
  
import com.integpg.system.Immutable;  
import java.util.Date;  
  
  
  
public class ImmutableSample {  
  
    public static void main(String[] args) {  
  
        // get an array of long values that represent the last 5 boot times  
        long[] lastFiveBootTimes = Immutable.getLongArray("BootTimes");  
  
        // if the array does not already exist then create an array of 5 long values  
        if (lastFiveBootTimes == null) lastFiveBootTimes = Immutable.createLongArray("BootTimes", 5);  
  
  
        // shift the previous 4 boot times  
        for (int i = 4; i > 0; i--) {  
            lastFiveBootTimes[i] = lastFiveBootTimes[i - 1];  
        }  
  
  
        // assign the most recent boot time  
        lastFiveBootTimes[0] = System.currentTimeMillis();  
  
  
        // loop through our last five boot times and print them in a readable format  
        for (int i = 0; i < 5; i++) {  
            long bootTime = lastFiveBootTimes[i];  
  
            if (bootTime > 0) {  
                System.out.println(new Date(bootTime));  
            }  
        }  
    }  
  
}  

Sometimes it is vital to ensure that only one copy of an application is running.  To do that JANOS has provided us the ability to register a process with the operating system.  Using the registerProcess(uid) call we can get the number of processes running with the given unique identifer.  This can become an issue if you have multiple run keys set to start the same application.

Here is the demo application.  The oneinstance application is started with the & parameter.  This tells the console session to run the application as a separate process.  The First time the application run it returns a process count of 1.  The process is allowed to proceed.

Since the application is running as a separate process from the console session we can start another instance now.  The returned count is now 2.  The code checks for a count greater than 1 and decides to exit.

Using this feature will help you be sure that there is only ever one instance of your application running at a time.  Here is the source for the sample application.

package oneinstance;

import com.integpg.system.JANOS;



public class Oneinstance {

    public static void main(String[] args) {
        // we assign a unique identifier to this application.  This can be ANY string.
        String uid = "abcdef";

        // we register the process with JANOS.  this call will return the number of processes 
        //  running with this uid.  The result should be 1 indicating that our process is now running.
        int processCount = JANOS.registerProcess(uid);
        System.out.println("# of processes running using this UID: " + processCount);
        if (processCount > 1) {
            System.out.println("There is another copy of this application already running. exit now.");
            return;
        }

        // now sleep for a while to give us time to start other instances of this application as a test
        try {
            System.out.println("We are allowed to continue as the only instance of this applicaiton");
            Thread.sleep(60000);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }

}

This sample shows you how to pulse multiple outputs and a single output. The method must take two binary masks. One describing the desired states durring the pulse and the other describing which channels will be pulsed.

package com.integpg;
import com.integpg.system.JANOS;
public class PulseOutputs {
    public static void main(String[] args) {
        // to get the states of the outputs use the JANOS class and the getOutputStates method
        int outputStates = JANOS.getOutputStates();
        //print the Output States through telnet (console) connection.
        System.out.println("Output States are: " + outputStates);
        //Pulse 8 Relay Outputs On for 5 seconds (5000 milliseconds) after which outputs will return to previous state.
        //All channels (1111 1111b)
        JANOS.setOutputPulsed(255, 255, 5000);
        //Sleep 10 seconds to so that there is a noticable difference between on and off states.
        try {
            Thread.sleep(10000);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
        int counter = 0;
        while(counter<5){
        //Pulse Channel 5 Relay Output On for 5 seconds (5000 milliseconds) after which output will return to previous state.
        //Channels   8765 4321
        //Channel 5 (0001 0000b)
        JANOS.setOutputPulsed(16, 16, 5000);
            try {
                Thread.sleep(10000);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            counter++;
            System.out.println("Counter: " + counter);
        }
    }
}

The classic Hello World application that runs on the JNIOR!

package helloworld;
public class HelloWorld {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        System.out.println("hello world");
    }
}

Sometimes you want to control the outputs. The outputs may be wired to things light lights, sirens, valves and maybe fans. This example will show you how

package com.integpg;
import com.integpg.system.JANOS;
public class WriteOutputs {
    public static void main(String[] args) {
        // to get the states of the outputs use the JANOS class and the getOutputStates method
        int outputStates = JANOS.getOutputStates();
        //print the Output States through telnet (console) connection.
        System.out.println("Output States are: " + outputStates);
        //set output relay for channel 5 (channel n-1) and true top turn the relay on, false to turn relay off.
        JANOS.setOutputRelay(4 , true);
        //Relay Output 5 should now be on.
        //print the Output States through telnet (console) connection.
        System.out.println("Output States are: " + outputStates);
    }
}