Author Archives for Bruce Cloutier

PASSWD Command November 28, 2017 2:53 pm
USERDEL Command November 28, 2017 2:31 pm
USERMOD Command November 28, 2017 2:23 pm
USERS Command November 28, 2017 1:42 pm
MODE Command November 28, 2017 10:22 am
Preemptive Multitasking November 27, 2017 11:51 am
FIND, GREP and EGREP Commands November 22, 2017 11:32 am
Standard Isolated Digital Input November 22, 2017 9:37 am
IOLOG Command November 21, 2017 1:36 pm
THD Command November 17, 2017 2:22 pm
Have you changed the 'jnior' account password? November 10, 2017 5:33 pm
JNIOR Connectors November 10, 2017 10:47 am
What is the DCP? November 9, 2017 4:51 pm
PS Command November 6, 2017 2:42 pm
CTRL-C November 6, 2017 1:15 pm
Using DEL November 6, 2017 1:06 pm
MANIFEST Command October 31, 2017 4:43 pm
Relay Control October 31, 2017 3:12 pm
CAT Command October 31, 2017 2:52 pm
















The WHOAMI command can be used to verify your login. While it seems trivial this command may be useful if you walk up to an existing login and need to confirm its permissions.

bruce_dev /> whoami
 jnior       1  Administrator
bruce_dev />

A password may be changed using the PASSWD command. The PASSWD command is available to all active accounts but only an Administrator can use it to alter the password of another account by specifying the account user name.

In addition, if you are not an Administrator changing the password on another account you will be asked to enter the current password before you can provide a new password. This is an added level of security.

bruce_dev /> help passwd
PASSWD [user]

Sets the password for the user. Defaults to the current user.

bruce_dev />

The USERDEL command removes 1 or more users from the system. This is not reversible. If you are uncertain about the deletion of a user you can add the Disabled tag to temporarily close the account using the USERMOD command. Multiple users can be removed by listing the users on the command line separated by spaces. The following would remove the ‘admin’, ‘user’ and ‘guest accounts.

userdel admin user guest

Note that there is no confirmation so use this command carefully. The command has no options and you must specify at least 1 user.

bruce_dev /> userdel
USERDEL user...

Removes one or more users from the system.
Multiple users can be specified separated by spaces.

bruce_dev />

You cannot remove yourself by the way. This command is also only available to an Administrator account.

The USERMOD command allows you to add or remove user account privileges or tags.

bruce_dev /> help usermod
USERMOD user

Options:
 +A,-A          Add or remove Administrator rights
 +C,-C          Add or remove Control rights
 +D,-D          Disable or Enable the account

Modifies user privileges.

bruce_dev />

The Series 4 uses three different tags: Administrator, Control, and Disabled. These are described under the USERS command topic. Basically accounts tagged as Administrator can do everything. An account tagged for Control can only manipulate I/O status. And, a Disabled account is just that, disabled.

The USERMOD command actually violates the JANOS standard for command options. This command uses the plus sign ‘+’ as well as the dash ‘-‘ to designate an option. This is a legacy thing left over from the Series 3.

The following command disables the ‘user’ account by adding the Disabled tag:

usermod +d user

This would re-enable the account by removing the Disabled tag:

usermod -d user

Note that the USERMOD command can only modify a single user. So you cannot add a tag to a set of users. You must also specify a user.

If you are at all concerned about security the USERS command is important! The JNIOR ships with four (4) default user accounts each with an obvious password. Two (2) of those accounts are Administrators. Most customers are not aware of this. We have seen where a customer will change the password for the ‘jnior’ account and think they are good to go. In reality the ‘admin’ account remains active and accessible with the default password. The USERS command is the only way you can see what accounts are active.

The USERS command is part of JANOS and new to the Series 4. While the account situation, as far as having two (2) administrators, is the same with the Series 3 you can only see the active accounts on those older JNIORs by viewing the content of the /etc/passwd file. That file is not present on the Series 4.

Here is a default account status as shipped.

412dmx_r00 /> users
 admin       3  Administrator
 guest       0  Disabled
 jnior       1  Administrator
 user        2  Control, Disabled

412dmx_r00 />

In addition to the two (2) active administrator accounts there are two other account. Not that those are Disabled by default. JANOS allows you to disable an account without deleting it. It was not possible to do that with the Series 3. In that case the ‘user’ and ‘guest’ accounts are active.

The USERS command has no options. It lists each account and the tags associated. There are 3 possible tags:

Administrator

An account tagged as Administrator has full access to the JNIOR. An administrator can access any file regardless of its permissions. An administrator can utilize every command available at the command line and can fully configure the JNIOR. An account with the Administrator tag has access to all of the capability afforded by the Control tag.

Control

An account tagged as Control can manipulate I/O. This includes toggling relays and adjusting external module I/O settings. These users cannot configure the JNIOR and are subject to all file permissions.

Disabled

You cannot log into a Disabled account. The account still exists and can be restored at any point. This tag can be used to temporarily make an account inaccessible.

The account tags can be added or removed using the USERMOD command. Users can be added or removed using the USERADD command or USERDEL command respectively.

The MODE command is rarely used and has one specific purpose. It controls whether or not the RS-232 (COM) port at the bottom of the JNIOR next to the LAN port is to be used for boot messages and command line interaction.

Issue the MODE command without parameters and it will display the current status of the “diagnostics port”. By default it is enabled. You would disable this if you were to use that serial port as part of your application to communicate with another device. In that case any spontaneous messages or command line interception would cause your protocol communications to fail, so you disable it.

To disable the diagnostics port issue the MODE -S command. You can think of the ‘S’ option as being “Silent”.

To enable the diagnostics port issue the MODE -V command. Okay in this case the option perhaps means “Verbose”. This is the default.

Now there is an Easter Egg here. JANOS has a few undocumented command options. There are very few and most of them provide some cryptic debug information more or less for my use. But here’s one for you.

The MODE -A command is undocumented. This enables the AUX port for command line interaction. Once you issue the MODE -A command any character received on the AUX port will start a command line process there. You cannot disable this mode. It is reset on reboot.

This “feature” was added to facilitate production program and test. The builder that initially programs the JNIOR and tests all of its I/O uses a command line connection through the AUX port to test the AUX port.

Here we see that a command line process is now active on the AUX port.

bruce_dev /> ps -v
      runtime       mem  hnd stk frm     id    desc
          36.667                          0: Idle Process
           1.395    2.6K   7   9          1: Network Service
           1.320    1.3K   7  17          2: System
           0.048   34.5K   7  12          4: Command/AUX
4 total          39.547 uptime

bruce_dev />

For this to work, you must not have an application running that uses the AUX port for communications. If you have used an application on that port you may need to prevent it from running on boot and to reboot the unit. The application may program timeouts and other port features that will interfere with the command line use. The port must also be set for 115,200 baud.

In order to breath life into a being you must get its heart beating. For a generic operating system the heart is it’s multitasking capability. In developing JANOS one of the very first modules that was created was the one responsible for coordinating the execution of multiple independent processes.

Practically every microprocessor program that has been written is responsible for, and therefore juggles, more than one task. Even those that seem to be so specific so as to be focused on one single task end up responsible for two or more sub-tasks. That doesn’t imply though that every program need implement sophisticated multitasking algorithms. In most cases a simple loop need be employed to cycle through the various tasks at hand.

With a focused application a control loop is often sufficient. In this case task A, B, C, etc. are executed in sequence if they are needed. Once all tasks have been given the chance to run the loop is repeated. Depending on the needs of the application a loop may repeat as often as possible or it may have the luxury of sleeping. The latter being helpful in reducing power requirements.

The rate at which a control loop repeats is variable and dependent on the number of tasks that needs to execute in each cycle and the amount of time each task takes to complete. If there is one task that is time sensitive there can be issues. If the total time required by the other tasks that need to run delays the loop too long, the time critical task may fail. The programmer has to take this into consideration. This can be a real problem if any task becomes dependent upon an external event and must wait for an indeterminate amount of time.

When a task has to wait it is prudent to move on and let other activities be performed in the meantime. We can employ a state machine. Here we break the current task down into a set of sub-tasks where a variable is used to keep track of the current sub-task. If a task has to wait it exits allowing other tasks in the main control loop a chance to run. When the main loop returns to the task at hand, the state machine takes us back to the point where we left off. If we still have to wait we exit again otherwise we handle the next step in the current task.

With fairly complex applications, the main control loop can become complex. The programmer may need to implement some kind of priority scheme. This would increase the time allotted for a set of tasks and force others to take a backseat. Then if multiple tasks require state machine implementations the overall dynamics start to become fuzzy. The programmer suddenly finds situations where the system may behave strangely leading to tweaks and eventually a feeling of careful balance. It works but you are now cautious not to add much more to it. Not without emphasizing testing.

Consider a generic operating system such as JANOS. Here there is a spectrum of system tasks that may be optionally running. Then there can also be multiple programs developed by others (of varying skill levels) running in the system and requiring CPU time. The resulting set of tasks can be so unpredictable that a simple tasking loop is doomed to failure.

A program may need to wait on a communications channel and the third-party programmer does not realize the need to return to allow other tasks to run. At a minimum this slows the system down and suddenly the task handling network traffic might start to cause timeouts and protocol failures. You just cannot predict this let alone control it with the simple loop approach.

So rather than to even try, JANOS employed a preemptive approach right from the start. Now every task becomes a process. Each process executes within its own context. Every context is isolated from other contexts creating independent processes. A timeslice is defined. For JANOS a timeslice is 32 milliseconds. JANOS allows each process to run for up to one timeslice before forcibly moving on to another. A process can relinquish its timeslice when it is waiting on something but it cannot monopolize the CPU.

In coding JANOS the main.c program was the first created. It performs some initial configuration and starts the Process Engine. From that moment on the system became capable of executing more than one process. The main.c procedure then dubbed itself the “Startup Process”. Once it completes its required steps it renames itself as the “Idle Process” and falls into the tight wait loop. From that point forward it becomes solely responsible for collecting unused CPU time. This being the equivalent of twiddling your thumbs.

Before becoming the Idle Process mode the Startup Process initializes the Network Service. This process runs at all times and with priority to insure that all network traffic is handled properly and in a timely fashion. The Startup Process also starts the System process. The System process consists of a simple control loop executing low-priority background tasks such as logging, memory cleanup and event notification. These are the three low-level processes in the OS that run always and cannot be stopped.

Here some of the complexity becomes apparent. In addition to the three base processes that I have described we see some others. The jaccess.jar program is running. This is an application that the HoneyPot uses to create the Mirai Botnet Map web page that it serves to the public. While the Web Server process is required for you to access those pages it is likely running here because I have the DCP open in my browser. In fact the Console process there is mine as well. This results from a session in the Console tab of the DCP and that is where I executed the PS command you see above.

Finally there is a Command process running for some other random IP address. That indicates that there is a Telnet session open. On the HoneyPot those are generally from a Mirai infected host trying (unsuccessfully) to log into this JNIOR. Under JANOS there can be as many as 16 separate processes (including the Idle Process) running at one time.

So what is in the Process Engine that creates this preemptive multitasking environment? It may or may not seem complex to you. I have managed to create a preemptive environment on a variety of processors including the Z80, HP’s early entry into the minicomputer market, CP/M running on early Intel processors and many others. Notably I added this to the Dallas DS80C400 which created the multitasking capability found in the Series 3 JNIOR. The TINI OS that forms the basis of the Series 3 OS is not originally capable of multitasking. JANOS runs preemptive multitasking quite successfully on the Renesas RX63N.

To create a preemptive multitasking environment you need a few basic things. The first is a good 1 millisecond interrupt forming a process tick. You also need a way to switch program context with a minimum of overhead. And finally there needs to be a good atomic means to create a mutex (mutual exclusion object). That being a synchronization technique to control access to system resources when multiple processes are contending for them.

The main.c program during the initialization of JANOS sets up one of the timer registers in the RX63N to divide down the system clock and generate an interrupt every millisecond. The Process Engine first uses this to tally milliseconds and thereby track uptime and to create a real-time software clock. Then on every 32nd tick the Process Engine moves forward to see if another process is pending execution. In that case the context is changed and the next process is allowed to run.

The RX63N uses two stack areas. There is a User Stack which programs normally use to PUSH and POP data. The C Subroutine entry implementation also allocates local variables on that stack. For software to be re-entrant and therefore functional in such a multitasking environment it must store all of its variables on the stack. Now that can include pointers where each instance of that subroutine might allocate its own memory blocks and save the pointers. Later the route needs to release those blocks to avoid memory leaks. The point being that the “context” is really the stack content.

In addition to the User Stack the RX63N also uses an Interrupt Stack. When an interrupt occurs, for instance when the internal timer register is ready to signal 1 millisecond, The program pointer and certain critical resisters are save on the Interrupt Stack before running the interrupt service routine.

So for JANOS to change processes it simply saves the User and Interrupt stack pointers in the Process Table for the current process and then locates the next process that is ready to execute. The User and Interrupt stack pointers are updated from the Process Table for that process and we return from the tick interrupt. Ahh, but now we are not returned to where were just interrupted but to where the new task was interrupted before and so it continues. The originally interrupted process then waits for its turn to run again.

To change processes and context we swap two stack pointers. This is an extremely efficient (time wise) and low-overhead task swap. We do have to push all of the other registers onto the stack before swapping to insure and complete context swap. It happens very quickly. JANOS jumps cleanly from one process to the next without any process realizing it had been set aside temporarily.

This approach requires that we pre-assign 16 independent User Stacks and 16 independent Interrupt Stacks in the Process Table. Fortunately the RX63N has sufficient internal high speed RAM. The Process Engine initialization called by main.c gets that done before enabling the 1 millisecond tick.

Now to create a new process a PROC_create() method is provided that defines the starting point for the new process and passes a couple of useful parameters. The Web Server for instance starts at an entry point named HTTP_process(). An new entry is added to the Process Table for the new process. The name of the new process is one of the parameters supplied. The User and Interrupt stacks for the new process are initialized with content and initial values as would be expected when a return from the 1 millisecond interrupt is executed. Once everything is in order a flag for the new process is set allowing it to execute. We return from the creation routine to do other things but when our timeslice is up, the new process also proceeds from the point we defined.

If a program runs non-stop for its 32 millisecond timeslice it will be preempted. It then waits until it can continue after other tasks get their time in the sun. If a process needs to wait it can release its timeslice by calling PROC_yield(). This call generates a software interrupt that then performs the process swap and starts a new timeslice. The yielding process will continue once others have had a chance.

Often we know about how long we will need to wait. In this case we can release our timeslice for a certain number of milliseconds by calling PROC_sleep(). Here we not only allow our process to swap but also set a timer telling the Process Engine that we won’t be ready to execute for a while.

Along these lines to keep options open and flexible there is also a PROC_delayed() call. This sets the wait time so our process won’t run again until the specified time (uptime as opposed to RTC time). Add to this a PROC_pause() method that stops a process until another process specifically allows it to run again.

Finally there is a PROC_terminate() method which, like it says, terminates the process. This removes the process from the Process Table .

A process may be preempted at any time. This is likely to be in the middle of the assembly language executing a C statement. There are times when critical system structures are being read and updated. An interruption an an inopportune moment can invalidate an update and cause system issues. This is handled through the implementation of a CRITICAL SECTION.

A process can execute an ENTER_CRITICALSECTION macro. This establishes a section of code that cannot be swapped. Once the critical system structures are updated the EXIT_CRITICALSECTION macro restores normal swapping. While this seems to violate our statement earlier that the CPU cannot be monopolized, the Critical Section functionality is only available for use in JANOS system code and not by external application programs. It is not available to third party programmers. Those programs cannot monopolize the system. At least not so easily.

Critical Sections can be nested. That is just handled as a counter which is incremented upon section entry and decremented on exit. As a result there are very few situations where system interrupts must be disabled to prevent issues. This keeps the interrupt processing system ready at all times to service interrupts. Interrupts are not missed.

As a result of all this, the Web Server for example can be written without concern for anything else that may be running. It can also execute processes of its own. An example here is the PHP Scripting Engine which is started by the Web Server. This allows the Web Server to service other requests while a PHP program is compiled and then executed. Such complex interactions occur very smoothly and cleanly.

When a tick generates an interrupt only some registers are preserved on the stack. JANOS uses some inline assembly to also push R6 thru R13 and FP register. The two stack pointers are then passed to the scheduler which may or may not update them depending on what else need to run.

CODE: SELECT ALL

/* -- inline asm -------------------------------------------------------------
** inline_call_tick()
**
** Saves processor state in a consistent manner and manages the stack 
** pointers independent of C optimization effects.
** -------------------------------------------------------------------------*/
#pragma inline_asm inline_call_tick
static void inline_call_tick(void)
{
	PUSHM	R6-R13		; save balance of registers
	PUSHC	FPSW		; save FP register

	MVFC	USP,R1		; snapshot both stack pointers
	MVFC	ISP,R2
	BSR.W	_tick_proc	; perform task processing

	MVTC	R2,ISP		; update both stack pointers
	MVTC	R1,USP

	POPC	FPSW		; restore
	POPM	R6-R13
}

These are the additional registers that I mention needed to be saved.

Once the Process Engine became available the main.c proceeded to start Network and System processes as I have mentioned. Eventually in development of JANOS the Network process has to start receiving and then sending packets over the Ethernet LAN. That makes sense but we are kind of blind. That makes it difficult to develop and debug.

So the next process that we created was designed to handle command line interaction through the serial RS-232 (COM) port. The main.cprogram had been outputting notification strings on this port as the various events were occurring but we couldn’t interact with it. Just prior to becoming the Idle process the main.c program outputs a “Hit any key to login” message. We are not going to start a process for command line interaction until we know that there is someone there to use it.

This established the need for Polling Routines. A polling routine is a routine that can optionally be associated with a process class. It is called once every millisecond tick. Obviously these routines cannot do anything lengthy or they would significantly add to the overhead in the process engine. We would use this to detect an “any key” condition on the port and to then start the command line process.

So a structure for process design had started to evolve. The main.c program calls an initialization routine for each subsystem. For the command line process it calls CMD_initialize(). This initialization routine would indicate that it is “Starting command services” and issue the “Hit any key” message. Eventually when we got the network up and running it would start a Telnet server. The CMD_initialize() routine registers the CMD_polling() routine before returning. That polling routine merely checks the status of the serial port buffer and if a character is pending (the ANY key) and the command line process is not running, the CMD_process() is started.

Eventually we will use polling routines to check and handle timeouts and watchdogs among other tasks. It is a key aspect of the process engine and perhaps even a necessity.

FIND, GREP and EGREP are all aliases for the same command. These allow you to search a text file for matches to another string. For example:

HoneyPot /> find NTP jniorsys.log     
10/24/17 10:16:38.000, Clock synchronized via NTP (-5)
10/24/17 12:21:59.000, Clock synchronized via NTP (-35)
10/24/17 12:23:21.000, Clock synchronized via NTP (+5)
10/25/17 13:55:55.000, Clock synchronized via NTP (-23)
10/25/17 14:13:59.000, Clock synchronized via NTP (-5)
10/26/17 15:38:34.000, Clock synchronized via NTP (-21)
10/26/17 18:37:50.000, Clock synchronized via NTP (-52)
10/26/17 20:17:50.000, Clock synchronized via NTP (-28)
10/27/17 14:03:21.000, Clock synchronized via NTP (-27)
10/27/17 14:48:22.000, Clock synchronized via NTP (-5)
10/31/17 09:53:57.000, Clock synchronized via NTP (-43)
 .
 .
 .

This can be very useful if you are looking for a specific entry in a log file. Here is the HELP for the command. The only difference in the aliases is that the EGREP usage assumes the -E option allowing the search string to be a standard REGEX expression. It is the same as GREP -E or FIND -E.

HoneyPot /> help egrep
EGREP regex filespec

Options:
 regex          Regular Expression to match
 filespec       File specification
 -E             Use Regular Expressions (EGREP default)
 -C             Count lines
 -H             Print filespec
 -N             Print line numbers
 -I             Case-independent comparisons
 -M             Underline match

Peforms text file search.
Aliases: FIND, GREP, EGREP

HoneyPot />

The search string (or regex) is case-dependent. You can use the -I option to perform a case-independent search. For eample:

HoneyPot /> find manifest jniorsys.log     
11/22/17 08:26:27.567, FTP/50.197.34.73:64227 transferred /flash/manifest.json [116.6 kbps]

HoneyPot /> find -i manifest jniorsys.log     
11/02/17 08:28:32.943, Manifest updated.
11/02/17 08:32:43.210, Manifest updated.
11/02/17 11:31:03.541, Manifest updated.
11/20/17 07:38:17.390, Manifest updated.
11/22/17 08:26:27.567, FTP/50.197.34.73:64227 transferred /flash/manifest.json [116.6 kbps]

HoneyPot />

You will need to enclose you search string in quotes if searching for something containing a space. For example:

HoneyPot /> find -i "manifest updated" jniorsys.log     
11/02/17 08:28:32.943, Manifest updated.
11/02/17 08:32:43.210, Manifest updated.
11/02/17 11:31:03.541, Manifest updated.
11/20/17 07:38:17.390, Manifest updated.

HoneyPot />

The -C option counts the lines.

HoneyPot /> find -ic "manifest updated" jniorsys.log
 6 lines matched
HoneyPot /> 

Alright now there are 6 lines because I just updated using the MANIFEST command twice having seen that it has been a while.

HoneyPot /> find -i "manifest updated" jniorsys.log 
11/02/17 08:28:32.943, Manifest updated.
11/02/17 08:32:43.210, Manifest updated.
11/02/17 11:31:03.541, Manifest updated.
11/20/17 07:38:17.390, Manifest updated.
11/22/17 10:20:35.847, Manifest updated.
11/22/17 10:20:45.876, Manifest updated.

HoneyPot />

The -N option will include the file line numbers with the matched lines. And, if you know the case of what you are searching for you don’t need the -I option.

HoneyPot /> find -n "Manifest updated" jniorsys.log
  356: 11/02/17 08:28:32.943, Manifest updated.
  357: 11/02/17 08:32:43.210, Manifest updated.
  362: 11/02/17 11:31:03.541, Manifest updated.
  812: 11/20/17 07:38:17.390, Manifest updated.
  930: 11/22/17 10:20:35.847, Manifest updated.
  931: 11/22/17 10:20:45.876, Manifest updated.

HoneyPot />

As a general rule (with very few exceptions) options on the command line can be entered separately or combined. The may appear anywhere on the command line.

HoneyPot /> find -i "manifest updated" jniorsys.log -c 
 6 lines matched
HoneyPot />

Commands and options are not case-sensitive by the way.

The -H option not only provides the line number in the file but also includes the file specification which some error processors like to use.

HoneyPot /> find -h "Manifest updated" jniorsys.log   
/jniorsys.log[356]: 11/02/17 08:28:32.943, Manifest updated.
/jniorsys.log[357]: 11/02/17 08:32:43.210, Manifest updated.
/jniorsys.log[362]: 11/02/17 11:31:03.541, Manifest updated.
/jniorsys.log[812]: 11/20/17 07:38:17.390, Manifest updated.
/jniorsys.log[930]: 11/22/17 10:20:35.847, Manifest updated.
/jniorsys.log[931]: 11/22/17 10:20:45.876, Manifest updated.

HoneyPot />

Note that the output at the command line can be sent to a file using the traditional ‘>’ (create new file) or ‘>>’ (append to file) syntax.

HoneyPot /> find -h "Manifest updated" jniorsys.log > updates.txt

HoneyPot /> cat updates.txt
/jniorsys.log[356]: 11/02/17 08:28:32.943, Manifest updated.
/jniorsys.log[357]: 11/02/17 08:32:43.210, Manifest updated.
/jniorsys.log[362]: 11/02/17 11:31:03.541, Manifest updated.
/jniorsys.log[812]: 11/20/17 07:38:17.390, Manifest updated.
/jniorsys.log[930]: 11/22/17 10:20:35.847, Manifest updated.
/jniorsys.log[931]: 11/22/17 10:20:45.876, Manifest updated.

HoneyPot />

The Underline match option -M is interesting and unique to JANOS. This is especially useful when debugging a REGEX search. It works for any search as for example:

HoneyPot /> find -m "Manifest updated" jniorsys.log              
11/02/17 08:28:32.943, Manifest updated.
                       ----------------
11/02/17 08:32:43.210, Manifest updated.
                       ----------------
11/02/17 11:31:03.541, Manifest updated.
                       ----------------
11/20/17 07:38:17.390, Manifest updated.
                       ----------------
11/22/17 10:20:35.847, Manifest updated.
                       ----------------
11/22/17 10:20:45.876, Manifest updated.
                       ----------------

HoneyPot />

Finally, what about using REGEX? Regular Expressions are a kind of search language which can be used to specify some very complex search requirements. When the -E option or the EGREP command is used the search string can specify a standard REGEX. JANOS implements most but not all aspects of standard Regular Expressions. Here is an example:

HoneyPot /> egrep "NTP \\([+-][0-9][0-9]+)" jniorsys.log   
10/24/17 12:21:59.000, Clock synchronized via NTP (-35)
10/25/17 13:55:55.000, Clock synchronized via NTP (-23)
10/26/17 15:38:34.000, Clock synchronized via NTP (-21)
10/26/17 18:37:50.000, Clock synchronized via NTP (-52)
10/26/17 20:17:50.000, Clock synchronized via NTP (-28)
10/27/17 14:03:21.000, Clock synchronized via NTP (-27)
10/31/17 09:53:57.000, Clock synchronized via NTP (-43)
10/31/17 13:03:01.000, Clock synchronized via NTP (-53)
11/01/17 01:37:37.000, Clock synchronized via NTP (-17)
11/02/17 08:28:06.000, Clock synchronized via NTP (-54)
11/07/17 14:27:47.000, Clock synchronized via NTP (-46)
11/14/17 09:07:59.000, Clock synchronized via NTP (-42)
11/15/17 07:59:34.000, Clock synchronized via NTP (-27)
11/17/17 14:01:52.000, Clock synchronized via NTP (-57)
11/21/17 01:37:48.000, Clock synchronized via NTP (-25)
11/21/17 08:57:01.000, Clock synchronized via NTP (-56)
11/22/17 01:33:16.000, Clock synchronized via NTP (-14)

HoneyPot /> egrep "NTP \\([+-][0-9])" jniorsys.log -c   
 14 lines matched
HoneyPot />

Here we listed all of the Clock synchronization events that made adjustments of 10 or more milliseconds in either direction. Then we count how many others (less than 10 milliseconds).

It is important to note that when escaping characters in a REGEX on the command line you must escape the escaping character. So in Regex you would escape the open parenthesis (which would normally start a group) using \(. On the command line this must be entered as \\( as you can see.

Try the last search with the -M to underline matches.

HoneyPot /> egrep "NTP \\([+-][0-9])" jniorsys.log -m  
10/24/17 10:16:38.000, Clock synchronized via NTP (-5)
                                              --------
  \0(8) "NTP (-5)"
10/24/17 12:23:21.000, Clock synchronized via NTP (+5)
                                              --------
  \0(8) "NTP (+5)"
10/25/17 14:13:59.000, Clock synchronized via NTP (-5)
                                              --------
  \0(8) "NTP (-5)"
10/27/17 14:48:22.000, Clock synchronized via NTP (-5)
 .
 .
 .
HoneyPot />

You can see that with a Regex the matching groups are also displayed along with its length. With Regex, Group 0 (\0) is the entire match. We can separate the magnitude of the adjustment into its own group as follows.

CODE: SELECT ALL

HoneyPot /> egrep "NTP \\([+-]([0-9][0-9]+))" jniorsys.log -m
10/24/17 12:21:59.000, Clock synchronized via NTP (-35)
                                              ---------
  \0(9) "NTP (-35)"
  \1(2) "35"
10/25/17 13:55:55.000, Clock synchronized via NTP (-23)
                                              ---------
  \0(9) "NTP (-23)"
  \1(2) "23"
10/26/17 15:38:34.000, Clock synchronized via NTP (-21)
                                              ---------
  \0(9) "NTP (-21)"
  \1(2) "21"
10/26/17 18:37:50.000, Clock synchronized via NTP (-52)
                                              ---------
  \0(9) "NTP (-52)"
  \1(2) "52"
10/26/17 20:17:50.000, Clock synchronized via NTP (-28)
                                              ---------
  \0(9) "NTP (-28)"
  \1(2) "28"
10/27/17 14:03:21.000, Clock synchronized via NTP (-27)
                                              ---------
  \0(9) "NTP (-27)"
  \1(2) "27"
10/31/17 09:53:57.000, Clock synchronized via NTP (-43)
                                              ---------
  \0(9) "NTP (-43)"
  \1(2) "43"
10/31/17 13:03:01.000, Clock synchronized via NTP (-53)
                                              ---------
  \0(9) "NTP (-53)"
  \1(2) "53"
11/01/17 01:37:37.000, Clock synchronized via NTP (-17)
                                              ---------
  \0(9) "NTP (-17)"
  \1(2) "17"
11/02/17 08:28:06.000, Clock synchronized via NTP (-54)
                                              ---------
  \0(9) "NTP (-54)"
  \1(2) "54"
11/07/17 14:27:47.000, Clock synchronized via NTP (-46)
                                              ---------
  \0(9) "NTP (-46)"
  \1(2) "46"
11/14/17 09:07:59.000, Clock synchronized via NTP (-42)
                                              ---------
  \0(9) "NTP (-42)"
  \1(2) "42"
11/15/17 07:59:34.000, Clock synchronized via NTP (-27)
                                              ---------
  \0(9) "NTP (-27)"
  \1(2) "27"
11/17/17 14:01:52.000, Clock synchronized via NTP (-57)
                                              ---------
  \0(9) "NTP (-57)"
  \1(2) "57"
11/21/17 01:37:48.000, Clock synchronized via NTP (-25)
                                              ---------
  \0(9) "NTP (-25)"
  \1(2) "25"
11/21/17 08:57:01.000, Clock synchronized via NTP (-56)
                                              ---------
  \0(9) "NTP (-56)"
  \1(2) "56"
11/22/17 01:33:16.000, Clock synchronized via NTP (-14)
                                              ---------
  \0(9) "NTP (-14)"
  \1(2) "14"

HoneyPot /> 

As we hoped Group 1 (\1) contains the part of the match representing the magnitude of the adjustment. You can probably figure out how to include the sign of the adjustment in the group now if that was what you really wanted.

The -M option can be very useful in creating and debugging a Regex for use elsewhere in an application or PHP script.

I should probably cover Regular Expressions in some detail someplace. I put that on the TODO list.

By the way, we have been searching the system log (syslog) as stored in the /jniorsys.log file. That is not all of the event history available. You might notice in the Syslog tab of the DCP that entries go further back in time. So if we had wanted to search all of our syslog history then we could do the following.

HoneyPot /> cat jniorsys.log.bak > syslog.txt

HoneyPot /> cat jniorsys.log >> syslog.txt

HoneyPot /> egrep "NTP \\([+-][0-9])" syslog.txt             
09/27/17 10:40:32.000, Clock synchronized via NTP (+4)
10/24/17 10:16:38.000, Clock synchronized via NTP (-5)
10/24/17 12:23:21.000, Clock synchronized via NTP (+5)
10/25/17 14:13:59.000, Clock synchronized via NTP (-5)
10/27/17 14:48:22.000, Clock synchronized via NTP (-5)
11/14/17 09:23:24.000, Clock synchronized via NTP (+7)
11/14/17 10:08:44.000, Clock synchronized via NTP (-9)
11/15/17 02:13:57.000, Clock synchronized via NTP (+2)
11/15/17 08:06:37.000, Clock synchronized via NTP (+2)
11/15/17 08:11:08.000, Clock synchronized via NTP (+4)
11/15/17 08:15:41.000, Clock synchronized via NTP (+0)
11/15/17 08:18:55.000, Clock synchronized via NTP (-1)
11/15/17 08:21:40.000, Clock synchronized via NTP (+5)
11/17/17 14:45:24.000, Clock synchronized via NTP (-7)
11/18/17 03:26:33.000, Clock synchronized via NTP (-2)

HoneyPot /> rm syslog.txt

HoneyPot />

Seems that there is only one such event prior to October 24th. The syslog ages to a .BAK file when it grows to about 64KB in size.

This shows how you can concatenate files under JANOS. I haven’t implemented some of the syntax of the DOS COPY command that would let you do that. Maybe some day. There doesn’t seem to be much demand for it.

Did you know that every JNIOR since the beginning of time has used the same isolated digital input design? It is not that this design is particularly special. It is more that a better one hasn’t been suggested or required.

Here it is from external connector to the RX63N processor pin (right to left).

The input is optically isolated by the device U12. That means that you can bring a signal from a distance and not have to worry about it being referenced to any local GND. You won’t create any ground loop. There is no common connection between signals (they all need not be referenced to GND). To activate the input then all you have to do is turn that LED on.

The diode D34 protects the isolator LED from high voltages. You can put 30V on this input and not risk LED damage. The extra voltage above 5V is dropped across the 910 Ohm 1 Watt resistor. The input is limited by that 1W power rating. The maximum voltage is 35VDC. And 1 Watt is a lot of heat so you probably want to limit the amount of time that the input sits at that voltage.

To deal with that limitation you could add a series resistance. The maximum voltage is 5V above the square root of the series resistance assuming 1W resistors. So if you want to sense the presence of a 120VAC signal you might insert a 20K series resistance. I will leave the Ohm’s Law exercise to you. Just make sure that you can dissipate the power.

The input can be considered to have about a 1200 Ohm input impedance. It is not a high-impedance input. Therefore any signal used to drive an input must be able to deliver current into a 1200 Ohm resistance and turn on the isolation LED.

The circuit after the isolator creates a 2 KHz low-pass filter. Basically we’ve specified that input signals should not exceed 2000 Hz. The reasoning behind this lies in the need to be kind to the processor. Each input transition generates a software interrupt and executes some code. This allows JANOS to know when the state of the input changes, perform some debounce, and log the event. If this happens too fast the system can be overwhelmed having to execute interrupt code back to back and not get anything else done. That’s not ideal. So the hardware prevents it.

The processor can handle faster signals to be sure. But not if several of the inputs are cranking like that. Besides, the JNIOR is not targeted into applications that process high speed signals.

Now the RED LED that you see when the input is active is driven by the output of that filter. In other words, if the after the filter the hardware thinks that the input is ON then it turns the LED on. So those LEDs are software driven. They illuminate when the input is high enough to activate regardless of how the input is configured internally.

I’ve been meaning to see if there is a more cost-effective and compact implementation for that filter. It was implements old-school with separate gates. Works though.

The input signal then interrupts the processor. In the Series 4 each separate input has its own interrupt channel. That was not the case in the Series 3 where we had some trouble insuring that all of the input channels were properly counted when triggering simultaneously. There is no issue in the Series 4. Each input can be configured.

This shows the input signal processing. In this case we go from left to right. The DIN input generates interrupts. It can be optionally inverted by configuration prior to the debounce logic. This is consistent with the Series 3. Logically though you might want to invert an input afterprocessing. That inversion can be performed by the Conditioning block which finalizes the input state for the system. This is an extension in the Series 4.

The debounce delay by default is set to 200 milliseconds. Basically when an input that has been in one state for a while changes the new state is recognized immediately. The debounce timer then is started. During the delay time additional transitions restart the debounce timer and those state changes are ignored. The reported state is then refreshed once the timer does expire. The trigger is rearmed at that point.

This debounce approach effectively stretches an input pulse until it has been stable for the delay period. So if you want to detect the presence of a 60 Hz AC signal then you need to set the debounce delay long enough to ignore the time when the AC signal does not drive the input. That would be at least 17 milliseconds.

Latching

Input Latching is optional. When not enabled the function is bypassed as indicated in the flow diagram. When enabled it can be configured to latch either the HIGH or LOW state. Once latched the input state will remain the same until the input is reset. This would allow you to catch and deal with a pulse or otherwise not lose track of the fact that some alarm condition had triggered.

The latching can be configured to time out. This will latch a pulse and allow it to reset itself after a period of time. You can use this to stretch a short pulse so logic downstream has the time to detect it and to deal with it.

Counting

Once the input has been debounced and optionally latched it will be counted. The counter can be configured to count a LOW to HIGH transition (0->1) or a HIGH to LOW transition (1->0). Each counter can be reset to 0 or set to any initial value. These can even be manually incremented by an application.

When counters are displayed they can be scaled and shown with unique units. A counter can trigger an alarm when it reaches predefined values. Alarms can send email notifications.

Metering

The Usage Meter totals the length of time that an input has been active. You can tally time for the HIGH state or for the LOW state depending on configuration. Usage meters can be reset to 0. This can be useful in monitoring the operating time of a piece of equipment. An alarm can be triggered when the usage meter reaches a configured amount of time. Alarms can send email notifications. This could be helpful as a reminder for the performance of preventive maintenance.

Logging

All input and output signal transitions are by default logged. The IOLOG command can be used to review I/O activity.

Conditioning

Finally the input state can be conditioned (Series 4 only). Here the input state can be optionally inverted or forced to a HIGH (1) or LOW (0) state. The forced states may be of use in debugging applications or disabling an input without having to physically disconnect it. A forced input is masked but continues to be counted and metered.

Alarming

Note that alarms are available for Counters, Metering, and Input State. Alarms can be configured through the Registry or DCP. These can send unique email notifications.

In summary…

A digital input seems like it is a simple thing with just a HIGH or LOW input state. There is however a lot more to it. We have seen here what effect the hardware has and how the input can be configured. All of this before the input state ever affects any application.

We are all familiar with logs. These are text files someplace that list events such as logins, configuration changes, errors, etc. On the JNIOR the jniorsys.log file is one such log. These things are useful for systems and web servers. The JNIOR is also a controller and it can be very useful to have a log of I/O activity either digital or serial. This is provided by the IOLOG command.

bruce_dev /> help iolog
IOLOG

Options:
 -T             Indicate transitions
 -R             Reset logs
 -A             AUX Serial log
 -S             Sensor Port log
 -O             Output to stdout

Generates jniorio.log file from available logs.

bruce_dev />

The above HELP alludes to some different logging capabilities. There is something with transitions. That is a detailed log of recent Digital Input and Relay Output transitions. That even includes relays contained in the external expansion modules. The AUX port supports a bidirectional Transmission Log that details communications traffic that includes both the bytes and the timing. There is also a log for the Sensor Port.

The Series 4 JNIOR by default logs all all of this activity to internal buffers. At any time you can dump the log buffers into a file or to the display using the IOLOG command. The IOLOG -R command can be used to reset a log. This can be useful in debugging where you don’t want to be distracted by prior data. I will show some examples.

Let’s start with the AUX Serial Port since it is fresh in my mind. Here the IOLOG -AR command will remove historical data from the AUX port transmission log. The does not affect the other logs. The IOLOG -AO comand will display the log content. For example…

bruce_dev /> iolog -ao
--  11/21/17 12:13:04.991
 FE  56  01  FE  56  02  FE  56  03  FE  56  04  FE  56  05  FE     ~V.~V.~V.~V.~V.~
 56  06  FE  58  FE  52  FE  9D  13  FE  9C  40  FE  42  01  FE     V.~X~R~..~.@~B.~
 47  01  01  34  31  30  20  53  4E  20  36  31  34  30  37  30     G..410 SN 614070
 35  30  30  20  20  20  20  4A  41  4E  4F  53  20  76  31  2E     500    JANOS v1.
 36  2E  33  2D  72  63  33  20  20  20  20  62  72  75  63  65     6.3-rc3    bruce
 5F  64  65  76  20  20  20  20  20  20  20  20  20  20  20  31     _dev           1
 30  2E  30  2E  30  2E  35  39  20  20  20  20  20  20  20  20     0.0.0.59        
 20  20  20  FE  42  01                                                ~B.
--  11/21/17 12:13:14.872  +9.741
-43- FE  47  01  01  7E  44  69  67  69  74  61  6C  20  49  6E     C~G..~Digital In
 70  75  74  73  20  20  20  20  20  20  52  65  6C  61  79  20     puts      Relay 
 4F  75  74  70  75  74  73  20  20  20  20  20  20  20  43  6C     Outputs       Cl
 6F  63  6B  20  20  20  FE  47  01  04  20  53  70  6C  61  73     ock   ~G.. Splas
 68  20  53  63  72  65  65  6E  FE  42  01                         h Screen~B.
--  11/21/17 12:13:24.860  +9.873
-48- FE  47  01  01  20  FE  47  01  02  7E  FE  42  01 -48- FE     H~G.. ~G..~~B.H~
 47  01  02  20  FE  47  01  03  7E  FE  42  01                     G.. ~G..~~B.
--  11/21/17 12:13:31.967  +6.306
-45- FE  47  02  01  20  20  20  20  20  20  20  20  20  20  20     E~G..           
 20  20  20  FE  47  01  02  54  75  65  20  4E  6F  76  20  32        ~G..Tue Nov 2
 31  20  31  32  3A  31  33  3A  33  32  20  45  53  54  20  32     1 12:13:32 EST 2
 30  31  37  FE  47  02  04  20  20  20  20  20  20  20  20  20     017~G..         
 20  20  20  20  FE  42  01  FE  47  13  02  33  FE  42  01  FE         ~B.~G..3~B.~
 47  13  02  34  FE  42  01  FE  47  13  02  35  FE  42  01  FE     G..4~B.~G..5~B.~
 47  13  02  36  FE  42  01  FE  47  13  02  37  FE  42  01  FE     G..6~B.~G..7~B.~
 47  13  02  38  FE  42  01  FE  47  13  02  39  FE  42  01  FE     G..8~B.~G..9~B.~
 47  12  02  34  30  FE  42  01  FE  47  13  02  31  FE  42  01     G..40~B.~G..1~B.
 FE  47  13  02  32  FE  42  01  FE  47  13  02  33  FE  42  01     ~G..2~B.~G..3~B.
 FE  47  13  02  34  FE  42  01 -44- FE  47  02  01  44  69  67     ~G..4~B.D~G..Dig
 69  74  61  6C  20  49  6E  70  75  74  73  FE  47  01  02  20     ital Inputs~G.. 
 52  65  6C  61  79  20  4F  75  74  70  75  74  73  20  20  20     Relay Outputs   
 20  20  20  7E  43  6C  6F  63  6B  20  20  FE  47  02  04  53        ~Clock  ~G..S
 70  6C  61  73  68  20  53  63  72  65  65  6E  FE  42  01         plash Screen~B.

bruce_dev /> iolog -ar
AUX logs reset
bruce_dev /> iolog -ao

bruce_dev />

Here we see data in a traditional dump format with 16 bytes displayed in hexadecimal on the left and an ASCII representation of each byte on the right. If the byte does not represent a printable ASCII character it is replaced with a period ‘.’ in the text display.

The AUX serial communications can be bidirectional. Bytes received by the JNIOR are shown enclosed by a dash ‘-‘. In the example above there are single characters received (keypress codes). When a longer message is received the dashes make the incoming data appear to be desplayed over a background line. It is just a way to distinguish direction.

If the channel remains quiet for a couple of seconds, the IOLOG output includes a timestamp and includes the duration of the pause. All of this can be very helpful in debugging a serial communications based application.

The data displayed here is actual results from an HMI test. The content is explained in detail in a different thread. Here is the link to that discussion viewtopic.php?f=5&t=158&start=20#p316. The interface program generating these communications was developed in the thread.

The AUX Transmission log can be sent to a file using the IOLOG -A command.

bruce_dev /> iolog -a
 auxio.log generated.
bruce_dev />

The file will then contain the data in the same format displayed in the prior post.

The Digital I/O log has quite a different appearance. This is generated using the IOLOG -O command. The digital log is the default log assumed by the command.

bruce_dev /> iolog -o
11/15/17 08:40:27.085, DIN ---- 0000 0000, RLY ---- ---- 0000 0000
11/21/17 09:45:27.073, DIN ---- 0000 0000, RLY ---- ---- 0000 0001
11/21/17 09:45:27.848, DIN ---- 0000 0000, RLY ---- ---- 0000 0000
11/21/17 09:45:29.549, DIN ---- 0000 0000, RLY ---- ---- 0000 0100
11/21/17 09:45:30.330, DIN ---- 0000 0000, RLY ---- ---- 0000 0000
11/21/17 09:45:31.582, DIN ---- 0000 0000, RLY ---- ---- 0000 0010
11/21/17 09:45:32.619, DIN ---- 0000 0000, RLY ---- ---- 0000 0000
11/21/17 10:05:55.007, DIN ---- 0000 0000, RLY ---- ---- 0000 0010
11/21/17 10:05:56.056, DIN ---- 0000 0000, RLY ---- ---- 0000 0000
11/21/17 10:05:58.144, DIN ---- 0000 0000, RLY ---- ---- 0000 0100
11/21/17 10:05:59.943, DIN ---- 0000 0000, RLY ---- ---- 0000 0000
11/21/17 10:06:05.996, DIN ---- 0000 0000, RLY ---- ---- 0000 0100
11/21/17 10:06:09.173, DIN ---- 0000 0000, RLY ---- ---- 0000 0000
11/21/17 10:06:11.282, DIN ---- 0000 0000, RLY ---- ---- 0000 0010
11/21/17 10:06:12.518, DIN ---- 0000 0000, RLY ---- ---- 0000 0000
11/21/17 10:10:58.434, DIN ---- 0000 0000, RLY ---- ---- 0000 0010
11/21/17 10:22:00.468, DIN ---- 0000 0000, RLY ---- ---- 0000 0000
11/21/17 10:25:21.980, DIN ---- 0000 0000, RLY ---- ---- 0000 0010
11/21/17 10:28:43.913, DIN ---- 0000 0000, RLY ---- ---- 0000 0000
11/21/17 10:44:08.223, DIN ---- 0000 0000, RLY ---- ---- 0000 0001
11/21/17 10:44:09.621, DIN ---- 0000 0000, RLY ---- ---- 0000 0000
11/21/17 10:44:10.585, DIN ---- 0000 0000, RLY ---- ---- 0000 0010
11/21/17 10:45:39.208, DIN ---- 0000 0000, RLY ---- ---- 0000 0000
11/21/17 10:48:23.797, DIN ---- 0000 0000, RLY ---- ---- 0000 0100
11/21/17 10:48:24.859, DIN ---- 0000 0000, RLY ---- ---- 0000 0000
11/21/17 10:51:09.241, DIN ---- 0000 0000, RLY ---- ---- 0000 0010
11/21/17 10:52:02.613, DIN ---- 0000 0000, RLY ---- ---- 0000 0011
11/21/17 10:52:04.316, DIN ---- 0000 0000, RLY ---- ---- 0000 0010
11/21/17 10:52:05.107, DIN ---- 0000 0000, RLY ---- ---- 0000 0011
11/21/17 10:52:05.891, DIN ---- 0000 0000, RLY ---- ---- 0000 0010
11/21/17 10:52:08.636, DIN ---- 0000 0000, RLY ---- ---- 0000 0000
11/21/17 10:52:09.168, DIN ---- 0000 0000, RLY ---- ---- 0000 0010
11/21/17 10:54:14.726, DIN ---- 0000 0000, RLY ---- ---- 0000 0011
11/21/17 10:54:25.912, DIN ---- 0000 0000, RLY ---- ---- 0000 0010
11/21/17 10:55:35.680, DIN ---- 0000 0000, RLY ---- ---- 0000 0000
11/21/17 11:00:48.609, DIN ---- 0000 0000, RLY ---- ---- 0000 0010
11/21/17 11:00:52.456, DIN ---- 0000 0000, RLY ---- ---- 0000 0000
11/21/17 11:05:50.782, DIN ---- 0000 0000, RLY ---- ---- 0000 0100
11/21/17 11:07:27.885, DIN ---- 0000 0000, RLY ---- ---- 0000 0110
11/21/17 11:09:21.747, DIN ---- 0000 0000, RLY ---- ---- 0000 0100
11/21/17 11:09:22.243, DIN ---- 0000 0000, RLY ---- ---- 0000 0110
11/21/17 11:40:23.259, DIN ---- 0000 0000, RLY ---- ---- 0000 0100
11/21/17 11:40:24.670, DIN ---- 0000 0000, RLY ---- ---- 0000 0000
11/21/17 11:59:31.745, DIN ---- 0000 0000, RLY ---- ---- 0000 0010
11/21/17 11:59:33.136, DIN ---- 0000 0000, RLY ---- ---- 0000 0110
11/21/17 12:00:18.043, DIN ---- 0000 0000, RLY ---- ---- 0000 0010
11/21/17 12:05:08.749, DIN ---- 0000 0000, RLY ---- ---- 0000 0000
11/21/17 12:05:10.141, DIN ---- 0000 0000, RLY ---- ---- 0000 0010
11/21/17 12:42:49.123, DIN ---- 0000 0000, RLY ---- ---- 0000 0000

bruce_dev />

This log is generated by combining separate input and output logs. Each can contain up to 500 transitions. Depending on how frequently inputs and relays change you could have data spanning weeks or simply minutes.

Each line represents at least one transition. There is a timestamp to the millisecond. A ‘1’ indicates when an input (DIN) is activated or a Relay (RLY) closed. The inputs and relays are shown from right to left. So the last transition in the above log shows Relay Output 2 opening. There can be up to 16 relays and 12 inputs logged.

The IOLOG -R command will reset the digital log and not affect others. The IOLOG command without options will store the digital log in a file.

bruce_dev /> iolog
 jniorio.log generated.
bruce_dev />

There is also a log for the Sensor Port but unless you are intimately familiar with Dallas 1-Wire communications none of it will make sense. You can write an application to take control over the Sensor Port and communicate with a custom device or non-standard device. It you are working at that level then this log could be very helpful. The Sensor Port log follows the same format as the AUX Transmission Log.

So you’re developing an application. It works, but you question if it is efficient or not. That is where the THD command comes in. The THD command will show all of the threads that are active in each Java application that is running.

This command will also show other useful JVM information. Information such as the number of unique classes that have been loaded, the amount of memory that has been allocated to hold that class information, process time, heap memory usage, stack usage and class object memory usage.

Then each thread is listed showing its processor usage time, thread name, the class that implements the thread, parent thread, state and whether or not the thread is a daemon thread.

Lastly any Watchdog that has been activated is listed with its name, the action that will be carried out should the watchdog be triggered and how long until the watchdog will be triggered should it not be fed.

Here is a quick application that tests the Watchdog. You can see that at the time the thd command was executed the Watchdog was about to expire, within 1 second.

kev-dev /> thd
   9 classes loaded.   44.7 KB
   1 JVM instances active.
Command/10.0.0.27:55691/flash/watchdogTest.jar         0.557   mem: 20.9K  pid: 36  stk: 0.3K  obj: 2.1K  cls: 12.4K
         0.150  1: main, java/lang/Thread, main, SLEEP
     Watchdog: 'Watchdog Test', WDT_REBOOT, remaining = 0.880s

Here is the code listing for the above test application.

package watchdogtest;
 
import com.integpg.system.JANOS;
import com.integpg.system.Watchdog;
 
/**
 * This application tests the watchdog. A watchdog will be registered with the operating system. It will be fed a few
 * times and then left to be triggered. When it gets triggered we should see the registered action get carried out.
 */
public class WatchdogTest {
 
    public static void main(String[] args) throws InterruptedException {
        // instantiate the watchdog and register it to reboot when it gets triggered
        Watchdog watchdog = new Watchdog("Watchdog Test");
        watchdog.setAction(Watchdog.WDT_REBOOT);
        watchdog.activate(60000);
        // log to the syslog so that we can see exactly when the operating system reboots
        JANOS.syslog("Watchdog Started");
 
        // sleep for 30 seconds and then feed the watchdog.
        Thread.sleep(30000);
        watchdog.refresh();
        JANOS.syslog("Watchdog fed");
 
        // sleep for longer than the watchdog duration.  This will allow the watchdog to get triggered.  We 
        // should see that the reboot occurs 60 seconds after the last time the watchdog was fed
        Thread.sleep(120000);
    }
 
}

And here is the associated log entries from the jniorsys.log. As expected the timing works out. The watchdog was started, 30 seconds later we log that it was fed and then 60 seconds later we get the Assertion indicating that the reboot sequence has been commenced. 15 seconds are given to applications and system processes for safe shutdown.

11/17/17 14:13:19.302, Watchdog Started
11/17/17 14:13:49.368, Watchdog fed
11/17/17 14:14:49.487, ** Assertion: Watchdog Test watchdog triggered reboot (Line 1139)
11/17/17 14:14:49.496, ** Terminating: System
11/17/17 14:15:05.937, ** Reboot on assertion: Watchdog Test watchdog triggered reboot (Line 1139)
11/17/17 14:15:05.945, -- JANOS 412 v1.6.3-rc2 initialized (POR: 58)

So we recommend that you change passwords. A lot of our customers don’t see the need since their JNIORs are on secure networks supposedly.
But, it is important to note that if you do change the password for the ‘jnior’ account that isn’t enough. There is another Administrator account, ‘admin’. Don’t forget to change that password. Or, just disable or delete the account. There are also ‘user’ and ‘guest’ accounts that may or may not be active.
This is an issue with both Series 3 and Series 4 JNIORs.

The JNIOR Connector Kit contains 5 connectors. Four (4) are the 8-position female screw terminal types for I/O connections and one (1) a 4-position connector of the same style for the power connection. The latter will also be found on power supplies that are obtained from INTEG. here are the part numbers.

They look like this. The others having 8 positions of course.

These are SINGLE ROW FEMALE TERMINAL BLOCK PLUG 0.200″ 5.08MM PITCH. Color is irrelevant although INTEG tries to supply BLACK for digital signals and power, and GREEN for analog (external modules).

There are alternatives to these connectors that you can source separately. INTEG does not stock an alternative although arrangements can be made upon request.

Connectors are generally an expensive part of the product. These two-part connectors add value to the JNIOR.

Some wiring hints…

If multi-strand cables are used it is recommended that either the stripped end of the wire be properly tinned or some form of crimp pin be employed. If neither is convenient then insure that the stripped wire is tightly and cleanly twisted and clamped securely by the connector. Cables should have sufficient slack so as to not stress the connection as connectors are inserted or removed. Ty-wrap cables for a single connector together within 3″ of the connector to provide strength in numbers.

If solid cable is used then it is important that cables have sufficient slack so as to not bend the cable at the connector when the connector is inserted or removed. Ty-wrap cables for a single connector together for added protection.

Screw terminals should be hand-tightened strongly. Periodically check screws and tighten as necessary. Repeated changes in temperature can over time loosen screws.

Clamping more than one cable at a connector position is not recommended. In this case the clamping mechanism will grab the largest diameter wire more strongly creating an intermittent and loose connection with the other. If you must chain wiring in this fashion either tin wires together or tightly and cleanly twist them before clamping. Carefully wiggle both wires separately to insure that both have been securely captured.

When stripping wire use the proper tool with the proper wire gauge setting. Be careful not to cut into the copper conductor. This is highly likely if using a knife to remove the insulator. This can completely cut outer strands of multi-stranded cables reducing their current carrying capacity and increasing the possibility of a poor connection when clamped. Over time as cables are flexed cables that are improperly stripped will tend to break where the insulator has been cut.

If your wiring reaches the JNIOR from above you may consider a connector style where the cables leave the connector at 90 degree angles. For example you can source connectors like this one.

This is Pheonix part nubmer 1836901 and these are available from other manufacturers.

There are screwless connectors. These use spring force to achieve clamping and have the advantage of not loosening over time. There are different approaches. Here is one example.

If strain relief is an issue it is best to secure the cabling to the connector. An arrangement like this can be helpful. This eliminates the flex at the cable end where wires may break or loosen.

Now if you are willing to carry another crimping tool you can take a different approach. This would be much more appropriate when the JNIOR is installed within another product or rack mounting. Here you by just the housing and crimp a pin on each wire which is then inserted.

Here there is no question of loosening and strain relief is built-in. That assumes you are proficient at crimping. This is Pheonix 1808832 and I will attach the data sheet as well.

1808832

If you are using the JNIOR PCB without the housing as part of your product and are will to purchase in quantities of say 100 and allow for a standard lead time we can accommodate any connector arrangement. The PCB holes are on 0.200″ (5.08mm) centers.

Depending on the commitment we can also create a custom PCB to meet your specific needs. This is not as expensive as you might think. Cost does depend on quantity. Call us. We are willing to work with you.

There is no cost in asking.

DCP stands for “Dynamic Configuration Pages”. This is just a fancy name for the default website served by the Series 4 JNIOR out of the box. Once you have powered your JNIOR, connected it to the network, and assigned it an IP Address you can access the DCP using your favorite browser. This website is contained in, and served from, the /flash/www.zip file on the JNIOR.

You can use the DCP to monitor your JNIOR. Through the Input/Output tab you can see the status of each Digital Input and Output Relay. This tab offers two pages (listed down the left column). These are the Internal I/O and External I/O pages. If you log into an account with sufficient permissions you can control the relays. The appearance of this page can be configured through the Configuration tab. The labels can be redefined as might be appropriate for your application. You can remove unused inputs and outputs and even mask features such as usage metering if not of use.

The External I/O refers to external modules that you may optionally use with your JNIOR. INTEG can supply a Power Relay module, analog modules for 10V or 4-20ma, and even temperature sensors. One or more of these may be daisy-chained on the Sensor Port. If you have any of those they can be monitored and controlled in the External section of the Input/Output tab.

The Configuration tab is available only to Administrator accounts. This provides a dozen and a half pages covering most every aspect of your JNIOR.

The Display page configures settings that affect the appearance of the Input/Output Internal page. Here you may disable any channel which simply removes the channel from view on the Input/Output tab. This does not disable the function of the input or output. It merely allows you to hide unused or background channels. Similarly you can hide Counters, Usage Meters, Alarm indications and Controls. For relay outputs you can select the Pulse control instead of Toggle if appropriate. You may even alter the coloring used in showing the input or output state.

Note that each item of configuration is associated with a Registry Key. If you hold the mouse over a setting the related key is displayed in a Tooltip. Configuration settings that differ from default will appear in the Registry which can be viewed and edited directly using the Registry tab. More on that in a bit. While the mouse is hovering you may hit F1 to view the built-in Registry documentation.

The Labels page provides the ability to configure the text displayed on the Input/Output Internal page. In addition to Descriptions and I/O State labels you can change the units for the Counter.

This page is shown for the Model 410 which has 8 inputs and 8 outputs. The DCP will display different arrangements for the Model 412 and 414. The former having 12 relay outputs and only 4 inputs. The latter with 12 inputs and only 4 outputs.

The Inputs page affects the function of each input. Here you can configure inversion, debounce and a number of other characteristics for each of the available inputs.

A Block Diagram is available through the provided link to help in visualizing input configuration. We can cover the details under another topic.

The Counters page sets counter configuration for each input. The JNIOR counts each activation of an input. Here you can configure how that is to happen and how it is displayed. You can scale a counter if each activation represented a number of items or a fractional amount of something. Here you can see the value of changing the displayed counter units which are configured on the Labels page.

Here you can also configure two different Alarm levels. Alarms are displayed on the Input/Output Internal page. They are also Events that can issue email notifications.

On this page you can also mouse over an input and click the displayed “X” to easily reset a counter to 0.

The Outputs page provides state configuration for Usage Metering. The JNIOR tallies time for each activated input or output. This would potentially be useful for Preventative Maintenance. Here you can also set the default Pulse duration that would be used if you elected to configure a Pulse control (button) for the output on the Input/Output Internal page.

The Metering page displays the accumulated time for each Usage Meter. Like the Counters page you can mouse over a Channel and click the displayed “X” to reset the usage. Here you can also set the active usage state and configure alarms. This alarm can be set to send an email notification on the Events page.

The JNIOR has two serial ports. The Serial I/O page can be used to set communications parameters for each port. The defaults are shown.

Generally an Application Program is used to perform communications over a serial port. The program itself may configure communications parameters. There are times where you may wish to set the parameters outside of an application. The IOLOG command provides access to a Transmission Log for the AUX port. You can set the Baud Rate and then check the IOLOG to see if data has been received properly.

The Applications page lists Registered Applications. Applications are automatically Registered during boot provided that a JAR file exists in the /flash folder containing a properly formatted appinfo.ini file. The content of the Applications page then may vary significantly from one JNIOR to another.

An application may be set to run at boot. When you check the box associated with the application the appropriate Registry Run Key is created. On reboot the application will automatically start. If available a link is displayed that can lead to additional configuration pages specific to the application.

Note that the checkbox only affects the status of the application after boot. The starting and stopping of applications at any other time is performed at the Command Line which can be accessed through the Console tab.

Each JNIOR has the ability to send email notifications. Applications can be written to generate emails and potentially received them. Outgoing email requires a valid client account. The Mail-Account page is used to configure the outgoing email capability.

Here the Mail Server is something like smtp.comcast.net and the From Address would be the email address for a Comcast account. When you enter the SMTP Username you will be asked for a valid Password. The password is securely stored in the Registry. The remaining settings define the SMTP port, security and other characteristics for the communication. These are the credentials use in submitting outgoing emails.

Email notifications can be generated for a number of Events if enabled. JANOS has default structures for those notifications. You can optionally define any number of custom email messages as Profiles using the Mail-Profiles page. When the default content is insufficient these profiles can be referenced by name to define custom email recipients and content.

There is a small set of built-in events. The Events page is used to configure the actions associated with those events. For the most part this involves enabling an email notification and defining an optional email profile.

Beyond those listed here an unlimited number of events and actions can be accommodated through application programming or direct configuration of the Registry.

Note that the automatic starting of application programs can be disabled here without need for removing the Run keys.

The JNIOR is shipped configured with an IP Address of 10.0.0.201. This likely will not work for you.

To configure the network addressing you can run the Support Tool. The Support Tool is a Windows application that you can download for free from the INTEG website http://www.integpg.com/support/jnior/. You can also make a serial connection to the RS-232 (COM) port and use the IPCONFIG command at the command line.

Once you can access the DCP you can modify settings through the Network page.

The Security page offers a couple of settings.

The Series 4 JNIOR can perform secure communications using Public Key encryption and SSL/TLSv1.2. By default a 1024-bit RSA key pair is used in concert with automatic self-signed certificates. This means that you can access the DCP using a HTTPS connection. You can also perform secure FTP transfers and Telnet connections. The latter is best done with a client program available from us. Of course, you do not need either FTP or Telnet as the DCP offers most of that functionality.

While it doesn’t seem prudent you can disable the SSL capability here by deselecting SSL Enabled. Perhaps more appropriate is enabling SSL Required. In this case FTP and Telnet connections must perform STARTTLS and proceed securely. The standard HTTP port (Port 80) is closed. You can continue to make the secure connection using HTTPS (Port 443). Email will only be transmitted securely.

IP Address filtering is available. The Allowed IP Addresses field can be set with a comma delimited list of IP addresses that can make connection to the unit. This field can also contain a sophisticated filter string. It is recommended that the documentation (use F1) be viewed before setting this field. You can block yourself. In that case you will need to make the serial Command Line connection and remove the filter through the REGISTRY command.

The Telnet page simply lets you relocate the port. You may want to do that to hide it from casual connections. You can also disable the server entirely. You can do that since you can access the Command Line through the Console tab of the DCP.

The WebServer page is used to configure the Web Server. Here you can relocate either the HTTP or HTTPS ports or both. You can disable the Web Server entirely. That also prevents use of the DCP but your application might demand the limited access.

By default web access requires a login. You can disable the login requirement and to do so you must also define a user account for anonymous access. If your JNIOR is physically secure and the network is isolated from the larger network you might disable the login. If otherwise you have some pages that you wish to share publicly you can place them in the /flash/public root. Pages are served from that area without the need for authentication.

You can relocate or disable FTP using the FTP page. You can disable FTP and still manage the JNIOR’s file system through the Folders tab of the DCP.

Anonymous FTP access is not recommended. You can allow that by defining a user account to be used for that.

The JNIOR Protocol is deprecated and not recommended for new applications. The Series 4 offers a more modern Websockets interface which performs all of the same function and much more. It is also not binary. The JNIOR Protocol is still supported.

The Protocol page can be used to relocate the JNIOR Protocol port. The server can also be disabled.

We would recommend disabling the JNIOR Protocol unless you know that it is used. It is also highly recommended that the login requirement not be disabled. If you do so you must then define a user account for the anonymous access.

And finally for the Configuration tab is a page for the configuration of external modules. If you use an external module it will be listed here on the Modules page. If you have recently connected a module and don’t see that one you can select ‘rescan’ to update the list.

If the external module has configuration setting those can be seen by expanding the module. Click the triangle shape. For instance the 4ROUT labels can be altered for use on the Input/Output Externals page.

The Console tab provides access to the Command Line interface. This is similar to a Telnet connection but performed entirely through the web interface (Websockets). Note that an additional login is required here.

You can cut and paste here. That would be one advantage over a Telnet client. You can also drag a file to this window. That will place the file into the /temp folder convenient for further use from the command line. You might drag a UPD here and once it transfers use the JRUPDATE command to update the operating system as an example.

The Folders tab provides a file explorer formatted view into the file system.

You can navigate through folders by clicking on the left tree or double-clicking folders on the right as you might expect. Files can be selected and downloaded. You can also delete files and create folders. Drag and Drop is supported both into and out of the folder. Although in that case there is some variation in availability depending on the browser you are using. I use Chrome extensively. That seems to provide all of the needed capability.

If you need to move entire folders including subfolders then FTP is a better bet. Here I recommend FileZilla. https://filezilla-project.org/

The Registry tab provides an explorer view into the Registry. Here you can edit and remove keys as needed. Each setting found in the Configuration tab is associated with a Registry Key. You can make settings here if you know the proper key and format.

It is recommended that you become familiar with the Registry, There are some settings that are not accommodated by the DCP GUI. You will need to enter those here. The Registry can also be manipulated from the Command Line.

The DCP contains built-in and detailed Registry documentation.

The Syslog tab displays the System log detail in chronological order with the most recent event at the top. This is the content of the /jniorsys.log and /jniorsys.log.bak files concatenated. You can scroll then through all of the available log history in order from most recent to the oldest.

Here I’ll show a segment of the HoneyPot Syslog since my development unit sees a lot of crazy use and its log is full of confusing stuff. In fact you can see in this log where JANOS was recently updated. The infected.json file that keeps getting updated is the database for the http://honeypot.integpg.com/map.php application running on that unit. The HoneyPot JNIOR is connected directly to the Internet.

The Peers tab provides quick link access to other JNIORs that you may have on the network. The Series 4 JNIOR is aware of nearby peer products. Here you can move to the DCP on these other units using the link provided. That can be convenient if you have many JNIORs. Okay, so here at INTEG the Peer list gets crazy.

For many this list will be short if there are any at all.

And FINALLY! We have the About tab. This actually contains some text and potentially useful information.

 

The PS Command displays the current processes. JANOS is a preemptive multi-tasking environment. It can execute up to 16 processes using a simple priority scheme. Each process is given an ID and each new process receives a unique ID. For example:

412dmx_r01 /> ps
      0: Idle Process
      1: Network Service
      2: System
      7: Command/Serial
4 total     2:19:16.988 uptime

412dmx_r01 />

The Idle Process (PID 0) collects time when the system has nothing to do; The Network Service (PID 1) handles all network activity on a high priority basis; And, the System Process (PID 2) performs all routine system activities. These 3 processes are created at boot and always appear in the process list. The PS -V command provides a more verbose output format that contains more information.

412dmx_r01 /> ps -v
      runtime       mem  hnd stk frm     id    desc
     2:24:35.303                          0: Idle Process
           3.991    2.7K   7  11          1: Network Service
          11.217    1.3K   7  13          2: System
          12.246   37.9K   7  20          7: Command/Serial
4 total     2:25:36.193 uptime

412dmx_r01 />

This displays the runtime accumulated by each process. The Idle Process should accumulate the most runtime. If that is not the case then perhaps there tight loops in an application that could benefit from a Thread.sleep().

This also displays the amount of memory assigned to the process (mem). If this number were to continually grow with subsequent PS -V commands, then the application may have a memory leak. You might be creating an array and never pruning old entries. Or, there could be a JANOS issue that we would very much appreciate you pointing out to us.

The Handle count is displayed (hnd). Handles represent I/O streams such as stdin, stdout, stderr, comin, comout, auxin, and auxout. These are the 7 default streams. If you open a file or a network stream a handle is assigned. An application can have a number of handles however these too should not increase with time. They also can leak if not properly closed.

Each process has its own stack. The percentage of stack usage is displayed (stk). If a stack overflows it s percentage would reach 100. This is not desirable.

JANOS can execute Java programs. A Java Virtual Machine is launched for each program. In those cases the number of stack frames in use is displayed (frm). This number is limited by the amount of memory. It should be fairly stable for any application.

Other processes may appear in the process list. For example:

412dmx_r01 /> ps -v
      runtime       mem  hnd stk frm     id    desc
     2:47:44.211                          0: Idle Process
           4.879    2.7K   7  11          1: Network Service
          12.895    1.3K   7  13          2: System
           2.939   73.9K   9  20         10: Web Server
          16.721   38.3K   7  20          7: Command/Serial
           0.057   33.8K   7  12         13: Console/10.0.0.20:13948
           0.499   33.8K   7  12         14: Command/10.0.0.20:13981
7 total     2:48:57.353 uptime

412dmx_r01 />

The Web Server is executed to handle connections from browsers. This process is started automatically and remains active for as long as there are valid and active web connections. If there are several minutes of inactivity the Web Server will terminate. It would be restarted should another connection request be received. A single Web Server process handles all web connections.

The Command/Serial process here indicates that I am connected via the RS-232 (COM) port and have an active command line session. Here I must be careful to use the EXIT or BYE command or the process will remain active. Simply disconnecting the cable will not remove this process. There can be only one active serial command line connection.

The Command/[IP Address:Port] process indicates that I have connected to a command line through Telnet (Port 23). This will terminate once that network connection is closed. Each Telnet connection is its own process.

And the Console/[IP Address:Port] process indicates that there is a Console Session open through the DCP (or other Websockets connection). There are multiple ways to access the command line. You can tell them apart by their process name. Each Console Session is its own process.

The Protocol Server may appear as a process. Like the Web Server the Protocol Server handles one or more JNIOR Protocol connections. The service is automatically started when a JNIOR Protocol (Port 9200) connection is requested. After a period of inactivity the Protocol Server will terminate.

The JNIOR Protocol is a deprecated binary protocol which can be used to configure, control and monitor the JNIOR. It is supported however we recommend that new applications use the Websockets Interface. The latter has the same functionality and much more. It is a modern interface.

Unlike the Web Server and Protocol Server each FTP (File Transfer Protocol) connection is its own process. These will appear as FTP/[IP Address:Port].

JANOS can make secure network connections using TLSv1.2. When secure communications are active the Secure Transport process will run. A single Secure Transport process handles all secure communications. It augments network streams belonging to other processes by imposing the TLS protocol and performing the associated encryption and decryption.

The Security Update process is related and is executed when new RSA Keys are being generated. The process of generating a new key pair is computationally intensive. The Security Update process performs that task at a low priority and in the background. JANOS can generate a new set of keys periodically. It then updates its own self-signed certificates. This represents a level of security unprecedented in an embedded controller. The Administrator can install externally generated keys and signed certificates.

Finally each application runs as its own process. Each is a JVM. These will be indicated by program name along with an indication as to how the program was executed. For example.

412dmx_r01 /> ps -v
      runtime       mem  hnd stk frm     id    desc
           1.956                          0: Idle Process
           1.335    1.2K   7   1          1: Network Service
           0.062    1.2K   7  15          2: System
           1.362   58.6K   7  24   7      3: Run/Dmx.jar
           0.020   34.3K   7  12          4: Command/Serial
5 total           4.760 uptime

412dmx_r01 />

here the DMX.jar program was started through a Registry Run key. Compare with the following where the same program has been started at the command line.

412dmx_r01 /> ps -v
      runtime       mem  hnd stk frm     id    desc
        1:51.124                          0: Idle Process
           1.406    2.7K   7   8          1: Network Service
           0.540    1.2K   7  15          2: System
           1.210   51.9K   7  24   7      5: Command/Serial/dmx
           0.081   34.7K   7  12          4: Command/Serial
5 total        2:24.376 uptime

412dmx_r01 />

Notice in the previous post how the application program has a number of stack frames (frm). These programs are executed by a JVM.

Ctrl-C (hole Ctrl and press ‘C’) interrupts an executing Java application when run from the current command line. If you need to stop an application that has been started from a different Console session or through a Registry Run key you will need to use the KILL command.

If an application is not running then Ctrl-C redisplays the Console Welcome banner. This is a quick way to see the current Model, Serial Number and JANOS version. It tells you the current time and uptime. Note that there are other ways to obtain all of that information but the banner is quick. Just hit Ctrl-C.

The display of the current “Uptime” in the banner is a recent addition. Normally this will display “System up time”. However, if the unit has been running uninterrupted for a record amount of time this will indicate the uptime as “Record up time”.

The banner is supplied when you make a Telnet connection before any login is required. The information in the banner is thereby made public.

The DEL key is used to delete characters as you would expect. It has one additional use. If entered as the first and only character on a command line it will toggle the use of the hostname in the prompt string.

The command line prompt displays both the hostname and the working directory/folder. Depending on the length of the hostname and what the current working directory may be the prompt can be lengthy. The DEL key can be used to shorten the prompt string by removing the hostname. The current working folder is always displayed.

The MANIFEST command is a utility that you can use to monitor the health of the file collection on the JNIOR.

If you copy a file from your PC to the JNIOR how do you know that the file has completely and accurately transferred?

Let’s look at the DCP file /flash/www.zip. Let’s see how we can tell if it is perfect.

bruce_dev /> manifest flash/www.zip
JNIOR Manifest      Tue Oct 31 15:49:01 EDT 2017
  Size                  MD5                  File Specification
 182900   2c6ce5c5d365ea53b437a3760d6f4dd0  [Modified] /flash/www.zip
End of Manifest (1 files listed)

bruce_dev />

MANIFEST tells me the size of the file and also the MD5. That is a unique (ugly) hexadecimal value calculated from the file content. If I calculate the MD5 for the file on the PC it should match. So lets see.

File Properties

2017-10-31_15-51-42.png

MD5 Matches

Wait! How do you get those Checksums in the File Properties?

There are many ways to get the MD5 of a file. I found this tool that you install and it adds this to the properties dialog. Here is the link http://code.kliu.org/hashcheck/. It’s sweet.

Don’t like the MD5 hash then use the -H option for the SHA-1 hash. It still matches!

bruce_dev /> manifest flash/www.zip -h
JNIOR Manifest      Tue Oct 31 15:59:14 EDT 2017
  Size                  SHA-1                        File Specification
 182900   34eda6ecf2cbd0f136ec4adef0cfb442a11f8254  [Modified] /flash/www.zip
End of Manifest (1 files listed)

bruce_dev />

Or the -C option for the simpler CRC32. It still matches!

bruce_dev /> manifest flash/www.zip -c
JNIOR Manifest      Tue Oct 31 16:00:41 EDT 2017
  Size     CRC32     File Specification
 182900   2a1f06bd  [Modified] /flash/www.zip
End of Manifest (1 files listed)

bruce_dev />

Pretty sure that file is accurately over on the JNIOR. What do you think?

It is not just about comparing checksums or hash values. You can use MANIFEST to monitor the ongoing status of your files. Here is the HELP for the command.

bruce_dev /> help manifest
MANIFEST [filespec]

Options:
 -S,-R          Include subfolders
 -U             Update reference point
 -C             Report CRC32
 -H             Report SHA-1
 -L             List differences only
 filespec       May contain wildcards

Produces a manifest of file system content including checksums.

bruce_dev />

Okay so we have experienced the -H and -C options. The -S (and -R alias) seems straight forward. If you use a wildcard this option will process subfolders as well.

The -U option creates a reference point. This is a manifest.json database containing file details. MANIFEST can use this database at a later time so you can detect changes, new files and missing files. In short, you will know what has changed and what has not on your JNIOR. That has some merit.

For example we will run MANIFEST -U to make sure that our reference point is set. I will then remove a file and let’s see if MANIFEST can detect it. The MANIFEST command without file specification processes ALL files on the JNIOR. The -L option lists differences.

bruce_dev /> manifest -ul
JNIOR Manifest      Tue Oct 31 16:10:52 EDT 2017
  Size                  MD5                  File Specification
End of Manifest (0 files listed)

bruce_dev /> dir help.txt -l
total 1
-rw-r--r--   1 jnior     root       17110 Oct 31 14:10 help.txt
  1920.7 KB available

bruce_dev /> rm help.txt

bruce_dev /> manifest -l
JNIOR Manifest      Tue Oct 31 16:11:37 EDT 2017
  Size                  MD5                  File Specification
                                            [Missing] /help.txt
End of Manifest (0 files listed)

bruce_dev />

Here we can see that the help.txt file is Missing.

MANIFEST will report missing, new and changed files. In fact if a file changes but its timestamp has not, then it is reported as corrupt. Use of this utility can really help develop confidence in your file system content. You just need to create that reference point.

By the way, there are 2 copies of manifest.json. One is /manifest.json and the other is /flash/manifest.json. One is backup for the other. They are the same. So if for some reason the SRAM is reformatted there is a copy still in the Flash. If Flash is reformatted there is a copy still in the SRAM which holds the root of the file system.

Probably the most basic function that the JNIOR can perform is to close and open one of its relays. This is one of the ways the JNIOR controls the world around it. The Model 410 has 8 relays; The Model 412 has 12 relays; And, the Model 414 has just 4 relays. The number of inputs varies as 8, 4 and 12 respectively.

These are small signal relays. Early production JNIORs (with Omron relays) are limited to 1A. We currently use relays that can handle 2A. Voltages as high as 120VAC or more may be used. The limiting factor though is the current and the inductance of the load. If you use one of the relay outputs to drive something like a larger relay’s coil you should make sure there is a flywheel diode for Back EMF Suppression in the circuit. Otherwise the spark that would occur across the contains will seriously limit the life of the relay. A MOV device would be even better.

The Power 4ROUT external module that we have available uses 10A relays and has built-in MOV devices across each contact pair. The part is Panasonic ERZ-V07D431 VARISTOR 430V 1.75KA DISC 7MM. These can obtained from DigiKey among other places. If you are driving an inductive load you can purchase these or similar devices and place one across the relay outputs to extend the relay life.

ERZ-V07D431 VARISTOR

There are a number of good pages on the Internet that address this concern. You can search on “Back EMF Suppression” for more information.

Each Series 4 has at least two relays that can be modified by internal jumper to function Normally Closed (NC). The Model 412 has 4 that can be so configured.

Right out of the box you can control the relays. Once you have connected the JNIOR to your network and set the IP addressing you can point your browser at the unit and open the DCP. Log in as the administrator. The default username is ‘jnior’ and the password is ‘jnior’.

DCP Default Page

Here you can click on a “Toggle” button to turn on (close) and off (open) each relay. In the configuration section you can change the control to “Pulse” as I have done here for Relay Output 8. You can define the pulse duration in milliseconds. In fact, through configuration settings you can alter many aspects of this screen including the labels. The display can then reflect your application.

A “guest” login will only be able to view the status. The control buttons are not displayed.

So if you allow access to the JNIOR through your router you can control relays from anywhere in the world. It is highly recommended of course that you change the administrator’s password. I would also disable the “admin”, “user” and “guest” accounts if you do not need them. Use the USERS command in the Command Line Console to see the status of accounts. If you open your JNIOR up to the world you need to make sure that it is secure.

Command Line Relay Control

You can control the relays from the Command Line Console using the JRMON command. The Command Line Console is available as a tab in the DCP (see image in prior post), through a Telnet (Port 23) connection, or through connection to the Serial RS-232 (COM) port at the bottom next to the LAN port on the JNIOR.

The JRMON command will start an ASCII based real-time I/O status and command console. If you wish to control you need to use the JRMON -C option to enable command input. Here a “C1” closes Relay Output 1, “O1” opens that relay, and “Q” exits the mode.

JRMON Control

The 0’s and 1’s reflect the real-time status of inputs and outputs. In this case we have a Model 410 with 8 inputs (all off) and 8 relays (all off to start). Here additional relays will appear if you have a Model 412 or add 1 or more external 4ROUT modules. The number of inputs also follows with model with up to 12 inputs on a Model 414.

You can execute a JRMON -X command at the Command Line and not invoke the real-time display. The following command closes Relay Output 2 and opens Relay Output 1.

jrmon -x c2o1

The JRMON is useful in debugging Digital I/O using the serial RS-232 (COM) port and through a Telnet connection. If you have network access though perhaps the DCP is more convenient as the Graphical User Interface is nicer. You would likely not need to use the JRMON command through the DCP Console tab.

JNIOR Protocol

The JNIOR Protocol is deprecated and not recommended for new development. It is still supported however. For the Series 3 this was the protocol to use for remotely controlling the JNIOR. It is a binary protocol and very efficient. Experienced programmers can develop drivers to handle the JNIOR Protocol. INTEG supplies an SDK and API allowing PC applications to utilize the JNIOR Protocol. The Series 4 provides a more modern approach through a built-in Websockets interface. It’s use is preferred.

I have attached the current JNIOR Protocol specification. Relays can be controlled through this protocol using the Command Message (Message Type 10). The status of the JNIOR is obtained through the Monitor Message (Message Type 1). The JNIOR Protocol is not strictly Master-Slave. While there are commands and responses, there are unsolicited messages. The Monitor Message is supplied by exception whenever I/O status changes. You do not need to poll for status as you would with MODBUS for instance. You would just wait and consume Monitor Messages when supplied. The Websockets interface is similar.

JNIOR Protocol

Websockets Interface

With the Series 3 the configuration pages reached using the browser were required to execute Java Applets. The applet is the only way of making the JNIOR Protocol connection (Port 9200) for web use. Today both the applet and the JNIOR binary protocol are outdated.

The Series 4 Dynamic Configuration Pages (DCP) are also accessed through the browser. These use modern Dynamic HTML and JavaScript. This communicates with the JNIOR through a Websockets connection which is supported by all browsers over the same HTTP or HTTPS connections. The Series 4 built-in Websockets interface uses JSON messaging and provides for a wider set of capabilities. The DCP can manage files on the JNIOR, offer Command Line Console access, and monitor real-time Syslog status. There is much more. A PC Application can make a Websockets connection as well.

Both the Websockets Interface and the JNIOR Protocol can be used to remotely control relay outputs and maintain status of JNIOR I/O.

The current Websockets documentation is a Wiki in our Redmine system at INTEG. I have generated a PDF copy of that document and attached it here. We will help you make use of this protocol.

Builtin_Websocket_Access

Program Control

There is one more way to control relays. That is through an application program running on the JNIOR. Application programs are written in Java and can be generated by Netbeans or any Java IDE and compiler. The Series 4 operating system (JANOS) can execute Java JAR files directly. You write your program using the JNIOR runtime libraries, load it onto the JNIOR and execute it. Applications can be set to start at boot.

You can do just about anything with an application program on the JNIOR. Manipulating the JNIOR I/O is obviously one of the most important.

For example the following program when executed closes Relay Output 1.

package jtest;
 
import com.integpg.system.JANOS;
 
public class Main {
    
    public static void main(String[] args) throws Exception {
        
        JANOS.setOutputRelay(0, true);
            
    }
}
    

Relay Test Program

In this case I created a Project in Netbeans. I referenced the JanosClasses.jar runtime libraries (available in the JNIOR’s /etc folder). The program must be built to run in the JNIOR environment. It’s close to but not the same as a standard Java Runtime environment for the PC. It has additional classes like the JANOS class that provide for JNIOR functionality.

The program is compiled and the JAR copied from the dist folder into the /flash folder on the JNIOR. I just drag and dropped it into the proper folder using the Folders tab of the DCP.

Then from the command line just type the program name “jtest” to execute. It takes a second for the JVM to load and start the program. The relay then closes.

By the way, I like to include the “throws Exception” or “throws Throwable” in my main method when I am first developing a program. Later I will remove it and then be forced by the compiler to place necessary try-catch clauses to get error handling as it needs to be. Uncaught exceptions are nicely reported by the JNIOR.

Other Control Methods

There are still other ways to control JNIOR I/O. For one you can enable the MODBUS protocol. The JNIOR can be configured as either a MODBUS Server or MODBUS Client. Addressing is defined for the JNIOR I/O. There are a number of standard applications that INTEG supplies. The CINEMA application for instance allows you to define macros that are triggered by certain events and those can manipulate the I/O.

Did I miss any? Maybe you know of another?

The CAT command outputs the content of a file to the display. It has an alias the TYPE command.

bruce_dev /> help cat
CAT filespec

Options:
 -H             Dump file in hex
 -J             Formats JSON
 -P             Displays last page

Displays the contents of a file.
Aliases: CAT, TYPE

bruce_dev />

This is obviously meant for text files such as the LOG files (jniorsys.log for instance). But there are a couple of options.

The CAT -P option displays the last 25 lines of a text file. The jniorsys.log file can get quite lengthy as it may contain up to 64KB in characters. Each new event is added to the end of the file (displayed in reverse order in the Syslog tab of the DCP). So if you are interested only in the most recent events, use the -P option to display just the end of the file.

Here’s an example of a text file.

bruce_dev /> cat jniorboot.log
10/31/17 10:15:08.636, -- Model 410 v1.6.3-rc0.4 - JANOS Series 4
10/31/17 10:15:08.655, Copyright (c) 2012-2017 INTEG Process Group, Inc., Gibsonia PA USA
10/31/17 10:15:08.675, JANOS written and developed by Bruce Cloutier
10/31/17 10:15:08.694, Serial Number: 614070500
10/31/17 10:15:08.713, File System mounted
10/31/17 10:15:08.733, Registry mounted
10/31/17 10:15:08.783, Network Initialized
10/31/17 10:15:08.803, Ethernet Address: 9c:8d:1a:00:07:ee
10/31/17 10:15:08.922, Sensor Port initialized
10/31/17 10:15:08.978, I/O services initialized
10/31/17 10:15:09.020, FTP server enabled for port 21
10/31/17 10:15:09.041, Protocol server enabled for port 9200
10/31/17 10:15:09.063, WebServer enabled for port 80
10/31/17 10:15:09.084, Secure WebServer enabled for port 443
10/31/17 10:15:09.105, Telnet server enabled for port 23
10/31/17 10:15:09.134, POR: 5749
10/31/17 10:15:09.155, Cumulative Runtime: 7 Weeks 4 Days 8 Hours 50:17.827
10/31/17 10:15:09.175, Boot Completed [2.2 seconds]

bruce_dev />

The CAT -H option dumps a file in hexadecimal. I’ll insert it in a CODE box so you can scroll it.

CODE: SELECT ALL

bruce_dev /> cat -h jniorboot.log
00000000  31 30 2f 33 31 2f 31 37  20 31 30 3a 31 35 3a 30  10/31/17 .10:15:0
00000010  38 2e 35 39 30 2c 20 2a  2a 20 4f 53 20 43 52 43  8.590,.* *.OS.CRC
00000020  20 64 65 74 61 69 6c 20  75 70 64 61 74 65 64 0d  .detail. updated.
00000030  0a 31 30 2f 33 31 2f 31  37 20 31 30 3a 31 35 3a  .10/31/1 7.10:15:
00000040  30 38 2e 36 33 36 2c 20  2d 2d 20 4d 6f 64 65 6c  08.636,. --.Model
00000050  20 34 31 30 20 76 31 2e  36 2e 33 2d 72 63 30 2e  .410.v1. 6.3-rc0.
00000060  34 20 2d 20 4a 41 4e 4f  53 20 53 65 72 69 65 73  4.-.JANO S.Series
00000070  20 34 0d 0a 31 30 2f 33  31 2f 31 37 20 31 30 3a  .4..10/3 1/17.10:
00000080  31 35 3a 30 38 2e 36 35  35 2c 20 43 6f 70 79 72  15:08.65 5,.Copyr
00000090  69 67 68 74 20 28 63 29  20 32 30 31 32 2d 32 30  ight.(c) .2012-20
000000A0  31 37 20 49 4e 54 45 47  20 50 72 6f 63 65 73 73  17.INTEG .Process
000000B0  20 47 72 6f 75 70 2c 20  49 6e 63 2e 2c 20 47 69  .Group,. Inc.,.Gi
000000C0  62 73 6f 6e 69 61 20 50  41 20 55 53 41 0d 0a 31  bsonia.P A.USA..1
000000D0  30 2f 33 31 2f 31 37 20  31 30 3a 31 35 3a 30 38  0/31/17. 10:15:08
000000E0  2e 36 37 35 2c 20 4a 41  4e 4f 53 20 77 72 69 74  .675,.JA NOS.writ
000000F0  74 65 6e 20 61 6e 64 20  64 65 76 65 6c 6f 70 65  ten.and. develope
00000100  64 20 62 79 20 42 72 75  63 65 20 43 6c 6f 75 74  d.by.Bru ce.Clout
00000110  69 65 72 0d 0a 31 30 2f  33 31 2f 31 37 20 31 30  ier..10/ 31/17.10
00000120  3a 31 35 3a 30 38 2e 36  39 34 2c 20 53 65 72 69  :15:08.6 94,.Seri
00000130  61 6c 20 4e 75 6d 62 65  72 3a 20 36 31 34 30 37  al.Numbe r:.61407
00000140  30 35 30 30 0d 0a 31 30  2f 33 31 2f 31 37 20 31  0500..10 /31/17.1
00000150  30 3a 31 35 3a 30 38 2e  37 31 33 2c 20 46 69 6c  0:15:08. 713,.Fil
00000160  65 20 53 79 73 74 65 6d  20 6d 6f 75 6e 74 65 64  e.System .mounted
00000170  0d 0a 31 30 2f 33 31 2f  31 37 20 31 30 3a 31 35  ..10/31/ 17.10:15
00000180  3a 30 38 2e 37 33 33 2c  20 52 65 67 69 73 74 72  :08.733, .Registr
00000190  79 20 6d 6f 75 6e 74 65  64 0d 0a 31 30 2f 33 31  y.mounte d..10/31
000001A0  2f 31 37 20 31 30 3a 31  35 3a 30 38 2e 37 38 33  /17.10:1 5:08.783
000001B0  2c 20 4e 65 74 77 6f 72  6b 20 49 6e 69 74 69 61  ,.Networ k.Initia
000001C0  6c 69 7a 65 64 0d 0a 31  30 2f 33 31 2f 31 37 20  lized..1 0/31/17.
000001D0  31 30 3a 31 35 3a 30 38  2e 38 30 33 2c 20 45 74  10:15:08 .803,.Et
000001E0  68 65 72 6e 65 74 20 41  64 64 72 65 73 73 3a 20  hernet.A ddress:.
000001F0  39 63 3a 38 64 3a 31 61  3a 30 30 3a 30 37 3a 65  9c:8d:1a :00:07:e
00000200  65 0d 0a 31 30 2f 33 31  2f 31 37 20 31 30 3a 31  e..10/31 /17.10:1
00000210  35 3a 30 38 2e 39 32 32  2c 20 53 65 6e 73 6f 72  5:08.922 ,.Sensor
00000220  20 50 6f 72 74 20 69 6e  69 74 69 61 6c 69 7a 65  .Port.in itialize
00000230  64 0d 0a 31 30 2f 33 31  2f 31 37 20 31 30 3a 31  d..10/31 /17.10:1
00000240  35 3a 30 38 2e 39 37 38  2c 20 49 2f 4f 20 73 65  5:08.978 ,.I/O.se
00000250  72 76 69 63 65 73 20 69  6e 69 74 69 61 6c 69 7a  rvices.i nitializ
00000260  65 64 0d 0a 31 30 2f 33  31 2f 31 37 20 31 30 3a  ed..10/3 1/17.10:
00000270  31 35 3a 30 39 2e 30 32  30 2c 20 46 54 50 20 73  15:09.02 0,.FTP.s
00000280  65 72 76 65 72 20 65 6e  61 62 6c 65 64 20 66 6f  erver.en abled.fo
00000290  72 20 70 6f 72 74 20 32  31 0d 0a 31 30 2f 33 31  r.port.2 1..10/31
000002A0  2f 31 37 20 31 30 3a 31  35 3a 30 39 2e 30 34 31  /17.10:1 5:09.041
000002B0  2c 20 50 72 6f 74 6f 63  6f 6c 20 73 65 72 76 65  ,.Protoc ol.serve
000002C0  72 20 65 6e 61 62 6c 65  64 20 66 6f 72 20 70 6f  r.enable d.for.po
000002D0  72 74 20 39 32 30 30 0d  0a 31 30 2f 33 31 2f 31  rt.9200. .10/31/1
000002E0  37 20 31 30 3a 31 35 3a  30 39 2e 30 36 33 2c 20  7.10:15: 09.063,.
000002F0  57 65 62 53 65 72 76 65  72 20 65 6e 61 62 6c 65  WebServe r.enable
00000300  64 20 66 6f 72 20 70 6f  72 74 20 38 30 0d 0a 31  d.for.po rt.80..1
00000310  30 2f 33 31 2f 31 37 20  31 30 3a 31 35 3a 30 39  0/31/17. 10:15:09
00000320  2e 30 38 34 2c 20 53 65  63 75 72 65 20 57 65 62  .084,.Se cure.Web
00000330  53 65 72 76 65 72 20 65  6e 61 62 6c 65 64 20 66  Server.e nabled.f
00000340  6f 72 20 70 6f 72 74 20  34 34 33 0d 0a 31 30 2f  or.port. 443..10/
00000350  33 31 2f 31 37 20 31 30  3a 31 35 3a 30 39 2e 31  31/17.10 :15:09.1
00000360  30 35 2c 20 54 65 6c 6e  65 74 20 73 65 72 76 65  05,.Teln et.serve
00000370  72 20 65 6e 61 62 6c 65  64 20 66 6f 72 20 70 6f  r.enable d.for.po
00000380  72 74 20 32 33 0d 0a 31  30 2f 33 31 2f 31 37 20  rt.23..1 0/31/17.
00000390  31 30 3a 31 35 3a 30 39  2e 31 33 34 2c 20 50 4f  10:15:09 .134,.PO
000003A0  52 3a 20 35 37 34 39 0d  0a 31 30 2f 33 31 2f 31  R:.5749. .10/31/1
000003B0  37 20 31 30 3a 31 35 3a  30 39 2e 31 35 35 2c 20  7.10:15: 09.155,.
000003C0  43 75 6d 75 6c 61 74 69  76 65 20 52 75 6e 74 69  Cumulati ve.Runti
000003D0  6d 65 3a 20 37 20 57 65  65 6b 73 20 34 20 44 61  me:.7.We eks.4.Da
000003E0  79 73 20 38 20 48 6f 75  72 73 20 35 30 3a 31 37  ys.8.Hou rs.50:17
000003F0  2e 38 32 37 0d 0a 31 30  2f 33 31 2f 31 37 20 31  .827..10 /31/17.1
00000400  30 3a 31 35 3a 30 39 2e  31 37 35 2c 20 42 6f 6f  0:15:09. 175,.Boo
00000410  74 20 43 6f 6d 70 6c 65  74 65 64 20 5b 32 2e 32  t.Comple ted.[2.2
00000420  20 73 65 63 6f 6e 64 73  5d 0d 0a                 .seconds ]..

bruce_dev />

This can be useful at times.

And finally one interesting option. The CAT -J command will format a JSON file. JANOS can work with JSON (http://www.json.org/) and you may create files in that format for configuration or database operations. The MANIFEST command keeps its database in JSON format. I’ll dump it and add it here in a CODE block so you can scroll through it.

CODE: Select All


bruce_dev /> cat -j manifest.json
{
  "model":"410",
  "serno":614070500,
  "vers":"v1.6.3-b3",
  "date":"10/26/17 14:07:19",
  "files":{
    "/etc/janosclasses.jar":{
      "length":243492,
      "date":1507823966,
      "md5":"9b428bdd71054cb88c7e46851dba7307",
      "crc":"d81734ca",
      "sha":"ca80fd476f2ac6fc2d2b39b65faad72a9570a1ca"
    },
    "/flash/serialcontrol.jar":{
      "length":31344,
      "date":1450364184,
      "md5":"b349e02b7efc64c0dfe5eb74292a5ee6",
      "crc":"3a005104"
    },
    "/flash/serialethernet.jar":{
      "length":25266,
      "date":1433505362,
      "md5":"ee5e266bb8418b4223a666bd046a8c56",
      "crc":"c3961df2"
    },
    "/flash/modbusserver.jar":{
      "length":51907,
      "date":1502219129,
      "md5":"77c16d6134dbd7ec93313fbad2b00d93",
      "crc":"b7456b42",
      "sha":"fad4ecc3d1607aafe0a385a10fb5ee90eff521bd"
    },
    "/flash/snmp.jar":{
      "length":239949,
      "date":1493062048,
      "md5":"b77d35c322ef6645f1eca9d22b29400b",
      "crc":"a4073dcb",
      "sha":"44a3c2b41a2375ef603063cc9b04642903dad973"
    },
    "/flash/www/base64.js":{
      "length":3493,
      "date":1433505378,
      "md5":"1138db1b5a6e165beae3ed81739dd2ec",
      "crc":"baceb6f6"
    },
    "/flash/www/configure/index.html":{
      "length":1349,
      "date":1433505382,
      "md5":"0454014aecfd0b7d9e4ce1efe0979139",
      "crc":"11ba5486"
    },
    "/flash/www/jr310applet.jar":{
      "length":287159,
      "date":1441207703,
      "md5":"f9c4840e7244824b75858a1a40dfb163",
      "crc":"3d1d0c72"
    },
    "/flash/www/jniorprotocol.jar":{
      "length":115148,
      "date":1441207710,
      "md5":"404b40c4293bf3c334e3b88e2fe0dd10",
      "crc":"5143ec4f"
    },
    "/flash/www/jniorprotocolhelpers.jar":{
      "length":34991,
      "date":1433505394,
      "md5":"b08e33e0c21e6c075b9b242bf092b68e",
      "crc":"48990308"
    },
    "/flash/www/task/index.html":{
      "length":1415,
      "date":1433505397,
      "md5":"bbdc32dce371881b3eebd15f5b3fce96",
      "crc":"cdbe02e4"
    },
    "/flash/www/taskmanagerinterface.jar":{
      "length":123052,
      "date":1433505400,
      "md5":"077cddccee476fab552d52a5eefd26a7",
      "crc":"647bb4b3"
    },
    "/flash/www/jquery/jquery-1.9.0.min.js":{
      "length":93071,
      "date":1433505404,
      "md5":"2b869ea9c8edd4c2243c5d44f665f632",
      "crc":"6a2a8434"
    },
    "/flash/www/jquery/jquery-ui.css":{
      "length":33441,
      "date":1433505405,
      "md5":"c6bd2971b8e625f2ae43ede9f655a27b",
      "crc":"0497b7a6"
    },
    "/flash/www/jquery/jquery-ui.min.js":{
      "length":96395,
      "date":1433505409,
      "md5":"8f636d4c90ea0abfcbb25528c635bf7d",
      "crc":"820662f5"
    },
    "/flash/www/vendor/bowser/bowser_0.7.2.min.js":{
      "length":3359,
      "date":1433505412,
      "md5":"61a36d48aad1298b17284b53f6ce3fd1",
      "crc":"22deb9e6"
    },
    "/flash/www/text":{
      "length":1336,
      "date":1434044220,
      "md5":"bab65804218b18b9e1a79f2d8e873259",
      "crc":"dda17d61"
    },
    "/flash/www/cycle":{
      "length":419,
      "date":1434044214,
      "md5":"9eb9bbdae70c1f994ebb7f51b18783b8",
      "crc":"9e496eb9"
    },
    "/flash/slaveservice.jar":{
      "length":73323,
      "date":1465435094,
      "md5":"cd6f5e177d75675607e9523d52e133f7",
      "crc":"9a871cd7"
    },
    "/flash/ftp.jar":{
      "length":9563,
      "date":1475783634,
      "md5":"793e460054f07867685e87f98fd402e6",
      "crc":"36fd641e"
    },
    "/flash/task.ini":{
      "length":4311,
      "date":1433782061,
      "md5":"b1f877ac198306b266311eab557ed1dd",
      "crc":"36a57579"
    },
    "/flash/task.jar":{
      "length":102655,
      "date":1434645611,
      "md5":"1979b16970127f2c38912777cb105133",
      "crc":"ed4d6ad7"
    },
    "/flash/jnior.ini":{
      "length":4874,
      "date":1509041097,
      "md5":"7d723f1d36f2f743d2cb6b9b3ba456a6",
      "crc":"ae5d2732",
      "sha":"e798e12e57bedaacb9bdfd9ef11c2ad863e6691e"
    },
    "/jniorsys.log":{
      "length":32844,
      "date":1509041111,
      "md5":"6fa593ed95db856d0825bae724dce983",
      "crc":"d4d89669",
      "sha":"8ba4e9a6563b0a5dc2c0c5726446427d648ac727"
    },
    "/jniorboot.log.bak":{
      "length":1041,
      "date":946684814,
      "md5":"dfe9684a2933723a8cb54c30e4ee910e",
      "crc":"b0dcd002",
      "sha":"5f32c14164cf2ae3570ac0e06ec486c70ffe77e6"
    },
    "/jniorboot.log":{
      "length":995,
      "date":1509041097,
      "md5":"1a3f2d4e7d92774c72b4b1a05465a09b",
      "crc":"c5855a0b",
      "sha":"29ca5cf807094c8212d7fd467fd506e043c2582c"
    },
    "/flash/benchmark.jar":{
      "length":24351,
      "date":1464873509,
      "md5":"987f4044786771f31e0656cf91ed73f3",
      "crc":"1eed095a"
    },
    "/flash/threadtest.jar":{
      "length":3601,
      "date":1434645124,
      "md5":"902ce61cbd2524ca9b83dea335c395d3",
      "crc":"cd2479ff"
    },
    "/flash/test4to20.jar":{
      "length":3862,
      "date":1434659455,
      "md5":"a2e309c9d6dd112e5303aa76d2470740",
      "crc":"976f8208"
    },
    "/flash/dirs.bat":{
      "length":87,
      "date":1435691869,
      "md5":"531d655733ee668d829f9b3bdad96038",
      "crc":"6a11f77a"
    },
    "/flash/www/console/index.php":{
      "length":4347,
      "date":1438974987,
      "md5":"8728680bbc36d369429f7ca2c73cce7d",
      "crc":"c939c423"
    },
    "/flash/clean.bat":{
      "length":56,
      "date":1436532855,
      "md5":"ac9ce6553e1629412fb426b342440493",
      "crc":"3b661614"
    },
    "/flash/jnior1024.key":{
      "length":887,
      "date":1437746752,
      "md5":"b76b5351a92fdcc8d9b6b38ca62d8d71",
      "crc":"7983e14c"
    },
    "/flash/www/config/md5.js":{
      "length":5693,
      "date":1433505379,
      "md5":"a60fec5a81f207ff99ec1b97e3ccad0e",
      "crc":"e2a43d16"
    },
    "/flash/www/config/node.png":{
      "length":253,
      "date":1440435886,
      "md5":"1a8dbfaf1771a06e48dea0e3dc604392",
      "crc":"799c6dfc"
    },
    "/flash/www/config/tabs-styles.css":{
      "length":970,
      "date":1477590404,
      "md5":"68bca7015f51e26ab42199b5eb17a356",
      "crc":"f8870a33"
    },
    "/flash/www/config/tabs.js":{
      "length":3662,
      "date":1449678641,
      "md5":"ff728c86018341548ee70028062c89e0",
      "crc":"1a813112"
    },
    "/flash/www/config/styles.css":{
      "length":4450,
      "date":1504814044,
      "md5":"9ad78cca1b794dbcf9db3c55f1be5f1b",
      "crc":"acbd2e14",
      "sha":"3cf0bbc864840994a49f62d0ae00df6d8eb47ef3"
    },
    "/flash/www/config/comm.js":{
      "length":3541,
      "date":1507912287,
      "md5":"e7d2e56a443176d6150bbcc8b56e1911",
      "crc":"0ac0ed26",
      "sha":"5e66b96227779c5ef3736a7ca891a43cacffbbf1"
    },
    "/flash/www/config/console.js":{
      "length":5137,
      "date":1504815652,
      "md5":"33289e4b09f462efdb50e8d30d22d791",
      "crc":"b89fe380",
      "sha":"c2f3ea4fc0344d43b0c30b7f60b2b6c79c1f4817"
    },
    "/flash/www/config/config.js":{
      "length":12639,
      "date":1507912576,
      "md5":"75bf22a88d8a23b17de267607b88a14c",
      "crc":"d693e2f4",
      "sha":"cf9e9bcf7cc7d79ae648b241af16ee194199d7b3"
    },
    "/flash/www/config/index.php":{
      "length":22103,
      "date":1508861011,
      "md5":"12541c75de413fa0a33fc83313a1302e",
      "crc":"9c9d30a2",
      "sha":"f1f264aa446f2e02f106f56c87997ed305b335a7"
    },
    "/flash/www/jnior.ico":{
      "length":3262,
      "date":1439548680,
      "md5":"1c3b3dda6b10c6259fcf7c068b760f09",
      "crc":"051803eb"
    },
    "/flash/www/favicon.ico":{
      "length":156790,
      "date":1486410493,
      "md5":"07cb90c7f3573eff80222269625ed1dd",
      "crc":"7e367afa",
      "sha":"284add71fe3d3ba48fba059b88ff5143d3964b1d"
    },
    "/flash/analogpresets.jar":{
      "length":163902,
      "date":1441372806,
      "md5":"25eacc647412535e320302d3680ce327",
      "crc":"e6b656fc"
    },
    "/flash/www/config/config.css.php":{
      "length":1045,
      "date":1475072901,
      "md5":"1692861e9abd7f8d81f5b7cf8a176046",
      "crc":"4c386a21"
    },
    "/flash/www/config/inputs.png":{
      "length":18047,
      "date":1443116143,
      "md5":"e2151c93b6cdeaa154d15fab486ae61b",
      "crc":"16290877"
    },
    "/flash/www/config/loading.gif":{
      "length":3236,
      "date":1264096270,
      "md5":"d96f6517e00399c37a9765e045eaaf22",
      "crc":"16f442ed"
    },
    "/flash/jtest.jar":{
      "length":1832,
      "date":1508935076,
      "md5":"acbcb808b9db8e4ffc5a3d7ab873c411",
      "crc":"a2062204",
      "sha":"d6adbbebc98f9922fe73e5f23c98ff892045377e"
    },
    "/flash/www/vendor/angular_1.3.15/angular.min.js":{
      "length":125909,
      "date":1449498838,
      "md5":"ca1a58818682c3e858a585f283ab9beb",
      "crc":"9d8147d7"
    },
    "/flash/www/vendor/bootstrap_3.3.0/css/bootstrap-theme.css":{
      "length":21740,
      "date":1449498835,
      "md5":"c64043a3388612233d7eb947918a9bfc",
      "crc":"638f58a3"
    },
    "/flash/www/vendor/bootstrap_3.3.0/css/bootstrap-theme.css.map":{
      "length":41933,
      "date":1449498838,
      "md5":"c5da8241305bfe7e19919e6e943739eb",
      "crc":"11260772"
    },
    "/flash/www/vendor/bootstrap_3.3.0/css/bootstrap-theme.min.css":{
      "length":19199,
      "date":1449498840,
      "md5":"374df0ad5809a5314b0577802430a272",
      "crc":"8b3c47b7"
    },
    "/flash/www/vendor/bootstrap_3.3.0/css/bootstrap.css":{
      "length":137590,
      "date":1449498845,
      "md5":"ad6381ebfa541b55b0152349c6cabf76",
      "crc":"371e67da"
    },
    "/flash/www/vendor/bootstrap_3.3.0/css/bootstrap.css.map":{
      "length":366866,
      "date":1449498854,
      "md5":"4ba278e0c420d166e5a0eb71545f9509",
      "crc":"b7c9868d"
    },
    "/flash/www/vendor/bootstrap_3.3.0/css/bootstrap.min.css":{
      "length":114011,
      "date":1449498852,
      "md5":"78e7f91c0c4cca415e0683626aa23925",
      "crc":"34387388"
    },
    "/flash/www/vendor/bootstrap_3.3.0/fonts/glyphicons-halflings-regular.eot":{
      "length":20335,
      "date":1449498855,
      "md5":"7ad17c6085dee9a33787bac28fb23d46",
      "crc":"f171b590"
    },
    "/flash/www/vendor/bootstrap_3.3.0/fonts/glyphicons-halflings-regular.svg":{
      "length":62926,
      "date":1449498857,
      "md5":"ff423a4251cf2986555523dfe315c42b",
      "crc":"385cd4ad"
    },
    "/flash/www/vendor/bootstrap_3.3.0/fonts/glyphicons-halflings-regular.ttf":{
      "length":41280,
      "date":1449498858,
      "md5":"e49d52e74b7689a0727def99da31f3eb",
      "crc":"0617f1ff"
    },
    "/flash/www/vendor/bootstrap_3.3.0/fonts/glyphicons-halflings-regular.woff":{
      "length":23320,
      "date":1449498858,
      "md5":"68ed1dac06bf0409c18ae7bc62889170",
      "crc":"cec1a35c"
    },
    "/flash/www/vendor/bootstrap_3.3.0/js/bootstrap.min.js":{
      "length":34653,
      "date":1449498862,
      "md5":"281cd50dd9f58c5550620fc148a7bc39",
      "crc":"32d6c689"
    },
    "/flash/www/vendor/bootstrap_3.3.0/js/bootstrap.js":{
      "length":65813,
      "date":1449498862,
      "md5":"d5a03d9cca57637f008124916b86b585",
      "crc":"f504a7b3"
    },
    "/flash/www/vendor/bootstrap_3.3.0/js/npm.js":{
      "length":484,
      "date":1449498863,
      "md5":"ccb7f3909e30b1eb8f65a24393c6e12b",
      "crc":"cc50e34d"
    },
    "/flash/www/vendor/jquery_1.11.1/jquery-1.11.1.min.map":{
      "length":141680,
      "date":1449498870,
      "md5":"ffbeb16578d8cdf58104889baacbbef2",
      "crc":"e4e92bfd"
    },
    "/flash/www/vendor/jquery_1.11.1/jquery-1.11.1.min.js":{
      "length":95786,
      "date":1449498869,
      "md5":"8101d596b2b8fa35fe3a634ea342d7c3",
      "crc":"804ff984"
    },
    "/flash/www/config/integlogo.png":{
      "length":5773,
      "date":1449163436,
      "md5":"9111308273dadea73f5d09a5e02c7311",
      "crc":"60c4e184"
    },
    "/flash/utility.jar":{
      "length":106794,
      "date":1449773066,
      "md5":"ac559b91b537dfa70720a416f32f2960",
      "crc":"888936f1"
    },
    "/flash/generators/json/colour.js":{
      "length":4327,
      "date":1449774238,
      "md5":"c67e10d0e0e698fcdbbbadcaa55600d4",
      "crc":"19e8a38f"
    },
    "/flash/generators/json/ethernet.js":{
      "length":1409,
      "date":1449774238,
      "md5":"1b6bae08feb93f6bd345a3780c3acb69",
      "crc":"848097a7"
    },
    "/flash/generators/json/inputs.js":{
      "length":2825,
      "date":1449774239,
      "md5":"6959db5a769ff3ceea45bf606bda940a",
      "crc":"c544d780"
    },
    "/flash/generators/json/lists.js":{
      "length":12006,
      "date":1449774239,
      "md5":"5cc489ac77db7a3369b2ffc30cbd3a86",
      "crc":"ba761254"
    },
    "/flash/generators/json/logic.js":{
      "length":4404,
      "date":1449774239,
      "md5":"9cd1cf854976ebb69a6c20a7ac88d2f9",
      "crc":"6c2189f9"
    },
    "/flash/generators/json/loops.js":{
      "length":6040,
      "date":1449774239,
      "md5":"e8e9021b5d4eb2e0cc43f11ad5b3bfd7",
      "crc":"b30a758a"
    },
    "/flash/generators/json/math.js":{
      "length":14673,
      "date":1449774240,
      "md5":"fa22c29efc362e02d8f35838fcca46e5",
      "crc":"8fc62e67"
    },
    "/flash/generators/json/other.js":{
      "length":983,
      "date":1449774240,
      "md5":"dd77f555bc9b50ed17a215d7935f10ab",
      "crc":"3e07810d"
    },
    "/flash/generators/json/outputs.js":{
      "length":3861,
      "date":1449774240,
      "md5":"72a118cd7829b5a510e5a901d8863d6e",
      "crc":"bdd5e320"
    },
    "/flash/generators/json/procedures.js":{
      "length":3945,
      "date":1449774240,
      "md5":"cb9fb880bebb3375273353fafc12dc9c",
      "crc":"20d43aad"
    },
    "/flash/generators/json/text.js":{
      "length":1363,
      "date":1449774241,
      "md5":"a0bd39f638202a0800c100b4eac3cbc3",
      "crc":"b17b24d6"
    },
    "/flash/generators/json/timing.js":{
      "length":2638,
      "date":1449774241,
      "md5":"b1ee803dd8e6e00de74e0a3269f0a2ff",
      "crc":"489061b8"
    },
    "/flash/generators/json/variables.js":{
      "length":1500,
      "date":1449774241,
      "md5":"fecce79a400d5e4e1edbe521699fa604",
      "crc":"cb724c91"
    },
    "/flash/generators/json.js":{
      "length":4115,
      "date":1449774238,
      "md5":"cc72f2468eb970110f3f6f0278f43467",
      "crc":"25a98f30"
    },
    "/flash/www/config/link_to.png":{
      "length":259,
      "date":1450466976,
      "md5":"b1ed68183be4f97ce1793139496dbbb4",
      "crc":"a067876a"
    },
    "/flash/www/config/collapsed.png":{
      "length":232,
      "date":1452087215,
      "md5":"ef7dd392142824ec54b7b7188717411c",
      "crc":"c7bd8428"
    },
    "/flash/www/config/linked.png":{
      "length":174,
      "date":1452088114,
      "md5":"56d2755d08a0857ff6e7750c4b2822dd",
      "crc":"ff59187e"
    },
    "/flash/www/config/expanded.png":{
      "length":238,
      "date":1452097812,
      "md5":"905b26e96849524dd6c37e1878f66779",
      "crc":"68686921"
    },
    "/flash/www/config/registry.js":{
      "length":8276,
      "date":1452271284,
      "md5":"fc35855793b2bbfe577e420f34cb0dda",
      "crc":"6c73e25a"
    },
    "/flash/www/config/deletex.png":{
      "length":240,
      "date":1452284181,
      "md5":"2750f1e60d0222d7f3c0752207fb41e7",
      "crc":"386b823b"
    },
    "/flash/www/config/modules.js":{
      "length":13520,
      "date":1484149578,
      "md5":"5d79964a8ca70cc7dc0504c343be3e3c",
      "crc":"3c09b9e2",
      "sha":"d6f0b3ec60796662acd105694ef39543e3dc50a2"
    },
    "/flash/www/logging.php":{
      "length":4853,
      "date":1463582298,
      "md5":"170c17bd0962f434eebe699129491912",
      "crc":"dce15f4e"
    },
    "/flash/www/slaving.zip":{
      "length":113815,
      "date":1465493787,
      "md5":"b3e85080154b5a7dc10078a6c6fe75c7",
      "crc":"975c987e"
    },
    "/flash/0-10vtest.jar":{
      "length":5053,
      "date":1438104444,
      "md5":"3a7be82077e29c598bdd8694d47805f4",
      "crc":"05e27897"
    },
    "/flash/4routtest.jar":{
      "length":2993,
      "date":1373644405,
      "md5":"14381605ec8f2f0d0dbe34843b7178b8",
      "crc":"8240fc03"
    },
    "/flash/environ.jar":{
      "length":3881,
      "date":1476102546,
      "md5":"8d738f0145516d287174a00dda32dabc",
      "crc":"ff1ecc8b"
    },
    "/flash/current.key":{
      "length":898,
      "date":1455116261,
      "md5":"035a0d79bd6c8258c12111479fe7353e",
      "crc":"cbdd8ffe"
    },
    "/flash/serialtest.jar":{
      "length":4532,
      "date":1457448880,
      "md5":"48fc4bd9421a5cf275b42235d2f4e2cb",
      "crc":"6d86943b"
    },
    "/flash/intellij.jar":{
      "length":969,
      "date":1464918560,
      "md5":"aea445862e32190fa61abc5d97e5b25f",
      "crc":"959a1596"
    },
    "/flash/jmodule.jar":{
      "length":5580,
      "date":1465240063,
      "md5":"af7d42f427d0e711c4a79c8e1c1d341d",
      "crc":"40058988"
    },
    "/flash/udptest.jar":{
      "length":5811,
      "date":1465328251,
      "md5":"5bbc399b4eb1f5ec427ccbf93c8b135d",
      "crc":"3d976325"
    },
    "/flash/buffer.jar":{
      "length":95325,
      "date":1467321013,
      "md5":"0c66b2a130de483b64b91d87471eb952",
      "crc":"5d0819e2"
    },
    "/flash/display.jar":{
      "length":2992,
      "date":1468953410,
      "md5":"efcfc78470e98842f52579c81c088a2d",
      "crc":"5ec67fd0"
    },
    "/flash/rz.jar":{
      "length":13079,
      "date":1469638127,
      "md5":"c4b7e9f4072d64e3dde9fe5a62406a1e",
      "crc":"20367148"
    },
    "/flash/www/config/folder.png":{
      "length":329,
      "date":1454662486,
      "md5":"316b7810fa502618b4e85788a82617a8",
      "crc":"55f20187"
    },
    "/flash/www/config/file.png":{
      "length":286,
      "date":1454662486,
      "md5":"1b75c23448e9c6eed675404f6130491d",
      "crc":"d327c449"
    },
    "/flash/www/config/warning.png":{
      "length":3068,
      "date":1332275646,
      "md5":"9c96d831cfc50fdedfdc980bc2abb2cf",
      "crc":"e90bb05a"
    },
    "/flash/www/config/folders.js":{
      "length":19270,
      "date":1504815735,
      "md5":"c7a59ef1aea3aad95d3315627d3a3b29",
      "crc":"6b1adf25",
      "sha":"93d7e851c9a1a65ed45b7c1bbe4368d3d941b32f"
    },
    "/flash/clktest.jar":{
      "length":2616,
      "date":1470249535,
      "md5":"345b4a9a22ec05bc89bb291b7b047e0e",
      "crc":"270f1d8b"
    },
    "/flash/timesearch.jar":{
      "length":4180,
      "date":1471371624,
      "md5":"bf719e65d8f4be9d7348a621ac69bc2b",
      "crc":"25075aa7"
    },
    "/flash/janosruntime_1.5.1.jar":{
      "length":1621696,
      "date":1472744987,
      "md5":"b8beb71b94b36129534ef4d6ec13f5ab",
      "crc":"abc7b327"
    },
    "/flash/www/config/relays.js":{
      "length":4189,
      "date":1484587793,
      "md5":"803af5c2431b8f58c110260b3f317838",
      "crc":"ee9ab3af",
      "sha":"21ec766fe220bd0618b43050851f9cd67dd1bf54"
    },
    "/flash/www/config/temperature.js":{
      "length":2870,
      "date":1475245816,
      "md5":"262c339513007cd746ee01da9a4a843f",
      "crc":"d062a444"
    },
    "/flash/www/config/dimmer.js":{
      "length":8255,
      "date":1475265861,
      "md5":"e7213c6fb8c263ac71acb766e62dc4ce",
      "crc":"b9edf051"
    },
    "/flash/www/config/range.css":{
      "length":2212,
      "date":1475499110,
      "md5":"6932c76ab79879ea4c5d826d9cb60db9",
      "crc":"3334dfd1"
    },
    "/flash/www/config/analog.js":{
      "length":7267,
      "date":1484587793,
      "md5":"87abcaf68dea5e2e203326a55bc2bca5",
      "crc":"9766b532",
      "sha":"dd788111904d41826164ea151f78dd4b3e3b84e6"
    },
    "/flash/www/config/ledon.png":{
      "length":626,
      "date":1475506220,
      "md5":"6018d69896fcba49da54c39d8ee19803",
      "crc":"32a65f15"
    },
    "/flash/www/config/panel.js":{
      "length":2038,
      "date":1475509052,
      "md5":"e0631cb06777f63f0a071f7aa5d198d0",
      "crc":"a38a7db3"
    },
    "/flash/www/config/ledoff.png":{
      "length":757,
      "date":1475509575,
      "md5":"4bb71e412a20ae6f098a29b195b10e13",
      "crc":"3fd16f7a"
    },
    "/flash/jpanel.jar":{
      "length":3142,
      "date":1358430294,
      "md5":"39825ccddf7b61c1ad41d261d84f4950",
      "crc":"446bee7f"
    },
    "/flash/www/config/syslog.js":{
      "length":1929,
      "date":1496773328,
      "md5":"4e8ecca50284c2aeae8e8b90db27ded8",
      "crc":"ac2a2541",
      "sha":"e413d70cc2bb6717448bc84c2980abc764bc3dd6"
    },
    "/flash/www/config/peers.js":{
      "length":5885,
      "date":1505835290,
      "md5":"2536fc521f916341b98183f6ce0b2453",
      "crc":"f2a44392",
      "sha":"5d949b8daa8e5081f19c88e42af968b24955e02c"
    },
    "/flash/www/index.php":{
      "length":356,
      "date":1477657721,
      "md5":"3ba20cf61f44f9ace09104261acf2711",
      "crc":"7f8eaed3"
    },
    "/flash/www/www.zip":{
      "length":85751,
      "date":1477663620,
      "md5":"296baa71d70bf40c1ad6ee0c71066c49",
      "crc":"69922bd1"
    },
    "/flash/www/download1.php":{
      "length":465,
      "date":1480616431,
      "md5":"1f69c84031dbdbe9aeecd634c0ab9607",
      "sha":"9770a8f6534f17f86eeb332309b7cbe07441022e",
      "crc":"c7b59619"
    },
    "/flash/www/short.php":{
      "length":273,
      "date":1481120537,
      "md5":"2fb318c42bd07c0ec34551502bc20c73",
      "sha":"9b9831ca6abda2a14a922e058430fe114b8b34e0",
      "crc":"fbca8ae2"
    },
    "/flash/peerbot.jar":{
      "length":2488,
      "date":1482355836,
      "md5":"b09d3118cefb7e9b3db6a16fc68954a3",
      "sha":"b4cacde3347d8c4e2b4dd464aef26da441db4eaf",
      "crc":"7973e5cf"
    },
    "/flash/ctrlc.jar":{
      "length":1510,
      "date":1482421756,
      "md5":"b7ce2da5b761674e626ae62c4b9edbcc",
      "sha":"51a17a3f092333a0a48aa8e6dcebe0ce99cef3de",
      "crc":"bd2a0810"
    },
    "/flash/www.zip":{
      "length":87642,
      "date":1505216713,
      "md5":"0d0cc1e611d77f48a9e7a48a5c5007b5",
      "sha":"27371cf36e32d70e2460510d233737a5f01a4ed1",
      "crc":"bebf23bf"
    },
    "/flash/www/config/favicon.ico":{
      "length":766,
      "date":1486410493,
      "md5":"07cb90c7f3573eff80222269625ed1dd",
      "sha":"284add71fe3d3ba48fba059b88ff5143d3964b1d",
      "crc":"7e367afa"
    },
    "/flash/www/map.html":{
      "length":1170,
      "date":1485380108,
      "md5":"901c9971c3c591b3d736cd91516960de",
      "sha":"5ded94156ca71884af1afae0fcaf1e78d3bac23d",
      "crc":"71f8c837"
    },
    "/flash/jmanifest.jar":{
      "length":5651,
      "date":1485192866,
      "md5":"dfb84226c647a42295d9f671cfb99fa5",
      "sha":"a7331cca377c1f96e400ddd5044c01a175ee230f",
      "crc":"1a64c6d6"
    },
    "/flash/jping.jar":{
      "length":2174,
      "date":1485201152,
      "md5":"0d533008847888e0dfcf497c0cff1a96",
      "sha":"75fbff5a973b8dac3408fdda46e47e708b585e58",
      "crc":"f1203f43"
    },
    "/flash/jaccess.jar":{
      "length":4820,
      "date":1485805203,
      "md5":"29ce866873686dd133a724e4db29c690",
      "sha":"239bf75c1597a25fdbbbb78798fe72971ca15f63",
      "crc":"e5ae0d1c"
    },
    "/flash/somepath/path2/testx.php":{
      "length":5282,
      "date":1486397961,
      "md5":"ce1a071b258c936c65679d6bb67db198",
      "sha":"30342828ebaeb69cd8ecefd75f2dd01e80c6388b",
      "crc":"ecd9251a"
    },
    "/flash/bruce_dev.cer":{
      "length":902,
      "date":1487172768,
      "md5":"e9917f27384ddee36817c04c8cde9199",
      "sha":"4b2b82a042a0019679c1b071956278f6ddd1f27b",
      "crc":"115ed2ae"
    },
    "/flash/www/config/registrydoc.css":{
      "length":21460,
      "date":1504201641,
      "md5":"15423ca727b03e6b1581910c6ca2eab5",
      "sha":"f521b53a4518e7490768d2a8ae0e707c1dfb943b",
      "crc":"0d5fd8c9"
    },
    "/flash/www/config/registrydoc.html":{
      "length":169108,
      "date":1508861014,
      "md5":"c34c31da746778b07448512e982af5b0",
      "sha":"f10f92e1a065faacbb557208fa1e4578dfde64e6",
      "crc":"c6979f37"
    },
    "/flash/www/panel/comm.js":{
      "length":4715,
      "date":1498074333,
      "md5":"44aa80868230fbfeee0a3c48c390896d",
      "sha":"37b479f65e7e8221d6fd9349439a8193cc645ba7",
      "crc":"0d5e92bd"
    },
    "/flash/www/panel/index.php":{
      "length":2648,
      "date":1501526934,
      "md5":"923ce6739971521191f9000662f38323",
      "sha":"a35d1d5f24da487be376595b46598e162e0f5310",
      "crc":"ffd86d7b"
    },
    "/flash/www/panel/panel.js":{
      "length":993,
      "date":1501527049,
      "md5":"9d9a2cbb435ffe8af5bd9d8c0598dccd",
      "sha":"2ef881dc8d90b4b0fb80a59d717c7125ca23fb04",
      "crc":"4fcd0f37"
    },
    "/flash/www/panel/panel.css":{
      "length":2586,
      "date":1501527291,
      "md5":"2a3a66d14d7bc6d4b01dfbd745205c7d",
      "sha":"886770297a07a594b88430d5db4ae9e23738d118",
      "crc":"2dd8a81d"
    },
    "/flash/www/graphr.zip":{
      "length":556637,
      "date":1506536442,
      "md5":"891b1dfa8d774b85aefcbd8791abe11f",
      "sha":"e5d204333658bd5c2f7c5b5ff682911124a10766",
      "crc":"62d153fb"
    },
    "/flash/public/dcp.zip":{
      "length":181914,
      "date":1504795829,
      "md5":"655e8587293f35f11c5c24fc38201d2f",
      "sha":"5fcfd8e38826e648f98f8d50f3613deb0d6312b6",
      "crc":"da99b7d0"
    },
    "/flash/test.txt":{
      "length":304,
      "date":1495131459,
      "md5":"fc9f1f5e67928ccb9be3aeaa66cd9e52",
      "sha":"6100d999f484f98ab476408c801dd000e579a62c",
      "crc":"765047c5"
    },
    "/flash/dmx.jar":{
      "length":4476,
      "date":1500567859,
      "md5":"3fd35bbe6bbf53a32aecf273275d1839",
      "sha":"4f702a87adb060294b553e6bd212672727d5d25f",
      "crc":"e81db9aa"
    },
    "/flash/juptime.jar":{
      "length":3201,
      "date":1506713589,
      "md5":"d4c2482fae18482727c1b2afabcf94b4",
      "sha":"86268b720b99760a4ebdb803db53f3f7fd18fd18",
      "crc":"44b0878c"
    },
    "/flash/jscan.jar":{
      "length":2189,
      "date":1507141493,
      "md5":"a0a42e17f003cedcac9c8e662ada6b36",
      "sha":"f1cafb56fdae33b66fff9b20cd2ff2705d96da9e",
      "crc":"60f00fe2"
    }
  }
}
bruce_dev />