Tag Archive: immutable

View on GitHub

The PowerEventLog application uses an immutable array to keep track of when the JNIOR turns on and off. It takes the values in an immutable array and stores them in a log file called powereventlog.

The application starts by checking if another instance of  itself is already running. If there is one already running, the instance of it trying to launch terminates itself. After checking that, it then gets the time that the application started on the JNIOR. The Immutable block is then returned (or created if it doesn’t exist yet.) to hold/retrieve the values of when the JNIOR last turned off and when it booted up again. The stop and start times of the JNIOR are re-formatted as date strings to be more readable. The log files being created are then checked to see if a backup needs to be created. Lastly, the stop and start times of the JNIOR are written to the log file, and then the times are updated for the next time the JNIOR turns off.

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.

Modbus Registry Bit Address Ranges

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.");  
        // 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  
    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("  ");  
                            = new StringBuffer();  
            } else if (i % 16 == 8) {  
                chars.append(" ");  
                sb.append("  ");  
            if (bytes[i] >= 32) {  
                chars.append((char) bytes[i]);  
            } else {  
            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("  ");  
        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 information will withstand reboots and application terminations. You can view Immutable data by typing the ‘nv’ command in the command line of a JNIOR. If using only one data type, you can express to create an immutable array of that data type, but if you want your array to have mixed data types inside it, you have to use a byte array. 

Using Immutable Blocks

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. The long array is part of an Immutable block, therefore the application start times don’t go away until overwritten or manual removed. This application holds up to the last five application start times.

View on GitHub

I put the built jar file of this example application into the JNIOR’s flash folder and ran it from the Web UI’s console tab. After it has successfully run, I run the application multiple times, and it shows each time it runs a new application start time added to its immutable array.