342 lines
13 KiB
Plaintext
342 lines
13 KiB
Plaintext
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta name="generator" content="HTML Tidy for HTML5 for Apple macOS version 5.8.0">
|
|
<title>JMRI: Adding A New System</title>
|
|
<meta name="author" content="Bob Jacobsen">
|
|
<meta name="keywords" content="JMRI technical system add"><!--#include virtual="/help/en/parts/Style.shtml" -->
|
|
</head>
|
|
<body>
|
|
<!--#include virtual="/help/en/parts/Header.shtml" -->
|
|
|
|
<div id="mBody">
|
|
<!--#include virtual="Sidebar.shtml" -->
|
|
|
|
<div id="mainContent">
|
|
<h1>JMRI Code: Adding A New System</h1>
|
|
|
|
<p>This page describes the steps to add a new data-type, e.g. Powerline devices, to JMRI.</p>
|
|
|
|
<p>It uses as an example the addition of the "powerline" type in January 2008. This was
|
|
before several important migrations (SVN to Git; changes to the internal support for multiple
|
|
connections; changes to how the Preferences mechanism works; etc) so this may need
|
|
significant updating.</p>
|
|
|
|
<p>Some parts may also be useful if you're adding a new connection (e.g. through a network
|
|
link) to an existing system. If you do that, please mark those sections here for the next
|
|
person to come along.</p>
|
|
|
|
<p>Note that we don't do this very often, and the specifics are more important than the
|
|
generalities here. You should should make sure you understand the <a href=
|
|
"SystemStructure.shtml">intended system connection structure</a> which is documented on
|
|
<a href="SystemStructure.shtml">another page</a>.</p>
|
|
|
|
<p>We list the files that are modified and created in the order they were done in this case;
|
|
other orders may also work, and you might not need to do all these.</p>
|
|
|
|
<p>In this particular case, we started by copying an existing system implementation (SECSI).
|
|
This effects how we ordered this, and made the basic process move pretty quickly.</p>
|
|
|
|
<h3>Duplicate an existing system</h3>
|
|
|
|
<dl>
|
|
<dt>Create a duplicate file tree</dt>
|
|
|
|
<dd>
|
|
<p>Using whatever tool that useful to you, duplicate the src/jmri/jmrix subtree
|
|
corresponding to the existing system you want to copy.</p>
|
|
</dd>
|
|
|
|
<dt>Change the package name information</dt>
|
|
|
|
<dd>
|
|
<p>Using your favorite editor, change all the package names in the new files to their new
|
|
location. In this example, that was a bulk replace of "jmri.jmrix.secsi" with
|
|
"jmri.jmrix.powerline".</p>
|
|
</dd>
|
|
|
|
<dd>
|
|
<p>At this point, make sure you can compile. This code isn't consistent yet, but it
|
|
should compile.</p>
|
|
</dd>
|
|
|
|
<dt>Check copyright dates</dt>
|
|
|
|
<dd>
|
|
<p>Because you've copied a system that might not have been touched for a while, go
|
|
through and add the current year (and if need be, your name) to the copyright notices in
|
|
all the files.</p>
|
|
</dd>
|
|
|
|
<dt>Create Git structure</dt>
|
|
|
|
<dd>
|
|
<p>In this step, we put the basic Git structure in place.</p>
|
|
|
|
<ul>
|
|
<li>Add all the directories you've created to Git. In the example, this was:<br>
|
|
<code>git add powerline powerline/serialdriver powerline/serialmon<br>
|
|
git add powerline/configurexml powerline/serialdriver/configurexml</code></li>
|
|
|
|
<li>Add all the COPYING files:<br>
|
|
<code>git add powerline/COPYING powerline/*/COPYING powerline/*/*/COPYING</code></li>
|
|
|
|
<li>Finally, commmit those files (but only those files):<br>
|
|
<code>git commit -m"usual file" powerline</code></li>
|
|
</ul>
|
|
</dd>
|
|
|
|
<dd>
|
|
<p>At this point, make sure you can compile.</p>
|
|
</dd>
|
|
<!-- (The dl vs h3 structure is really messed up here and below) -->
|
|
</dl>
|
|
|
|
<h3>Do Basic Migration</h3>
|
|
|
|
<dl>
|
|
<dt>Migrate names</dt>
|
|
|
|
<dd>
|
|
<p>Using your favorite editor, change all occurances of the old system name into the new
|
|
one.</p>
|
|
<code>bbedit `grep -irl secsi powerline/`</code>
|
|
<p>Then search for and replace, perhaps not literally, all the occurances.</p>
|
|
|
|
<p>At this point, make sure you can compile.</p>
|
|
</dd>
|
|
|
|
<dt>Register system for preferences</dt>
|
|
|
|
<dd>
|
|
<p>Add the line <code>@ServiceProvider(service = ConnectionTypeList)</code> just before
|
|
the class definition so that the preferences system sees your new connection types. You
|
|
may also need to add the following import statements:<br>
|
|
<code>import org.openide.util.lookup.ServiceProvider;</code><br>
|
|
<code>import jmri.jmrix.ConnectionTypeList;</code></p>
|
|
</dd>
|
|
|
|
<dt>Update the documentation</dt>
|
|
|
|
<dd>
|
|
<ul>
|
|
<li>Most important, make an entry in the <a href="Names.shtml">Names.shtml</a> page for
|
|
the system letter.
|
|
</li>
|
|
|
|
<li>Add at least one page of documentation to the help/en/html/hardware area.</li>
|
|
|
|
<li>Link that from the <a href=
|
|
"../../hardware/index.shtml">help/en/html/hardware/index.shtml</a> hardware home page.
|
|
Include a link to the manufacturer's website if possible.
|
|
</li>
|
|
</ul>
|
|
</dd>
|
|
|
|
<dt>Create Basic JUnit Tests</dt>
|
|
|
|
<dd>
|
|
<p>For more information on this, see the <a href="JUnit.shtml">testing page</a>.</p>
|
|
</dd>
|
|
|
|
<dt>Duplicate directory</dt>
|
|
|
|
<dd>
|
|
<p>Following the steps above, duplicate the directory for the previous systems tests,
|
|
creating a new directory in test/jmri/jmrix to contain the tests. Change the package
|
|
names, check the copyright dates, create the Git structure, and migrate the names.</p>
|
|
</dd>
|
|
|
|
<dd>
|
|
<p>At this point, make sure you can compile both the main code (which wasn't changed in
|
|
this step) and the tests.</p>
|
|
|
|
<p>You should also be able to successfully run the tests in your new system (although
|
|
they were created for the old system's functionality): <code>ant tests
|
|
&&./runtest.csh jmri.jmrix.powerline.SerialTest</code></p>
|
|
|
|
<p>There is also a PowerShell script available, see the <a href="JUnit.shtml">JUnit</a>
|
|
page for more information</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<h3>Connect Basics to Rest of System</h3>
|
|
|
|
<dl>
|
|
<dt>Connect to configuration menus</dt>
|
|
|
|
<dd>
|
|
<p>Edit the jmri/jmrix/ActiveSystemsMenu.java file (two places),
|
|
src/jmri/jmrix/JmrixConfigPane.java (one place) and src/jmri/jmrix/SystemsMenu.java (one
|
|
place) files to add the new system.</p>
|
|
|
|
<p>Don't commit this to Git yet!</p>
|
|
</dd>
|
|
|
|
<dd>
|
|
<p>At this point, make sure you can compile and run DecoderPro, and that your new system
|
|
appears in the preferences panel.</p>
|
|
</dd>
|
|
|
|
<dt>Connect to test tree</dt>
|
|
|
|
<dd>
|
|
<p>Edit the test/jmri/jmrix/JmrixTest.java file to invoke your new system tests.</p>
|
|
|
|
<p>Don't commit this to Git yet!</p>
|
|
</dd>
|
|
|
|
<dd>
|
|
<p>At this point, when you "ant alltest", your new system's test should be run.</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<h3>Migrate to Basic Functionality</h3>
|
|
|
|
<dl>
|
|
<dt>Update connection options</dt>
|
|
|
|
<dd>
|
|
<p>Speeds, etc, in powerline/serialdriver/SerialDriverAdapter.java.</p>
|
|
</dd>
|
|
|
|
<dt>Get send/receive communications working</dt>
|
|
|
|
<dd>
|
|
<p>The first step is to get communications working so that you can send a message from
|
|
the "Send Command" window, and see it and the response in the "Monitor" window.</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<h3>Make It Easy to Use</h3>
|
|
|
|
<dl>
|
|
<dt>Add Possible Startup Items</dt>
|
|
|
|
<dd>
|
|
<p>Create a new system-specific `ActionListBundle.properties` file
|
|
(src/jmri/jmrix/powerline/PowerlineActionListBundle.properties) to add appropriate action
|
|
items. Make sure to update the <code>getActionModelResourceBundle()</code> method of the
|
|
SystemConnectionMemo to reference this newly created ActionListBundle.</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<h3>Complete the documentation</h3>
|
|
|
|
<dl>
|
|
<dt>Create The Help Tree</dt>
|
|
|
|
<dd>
|
|
<p>Start by duplicating, then edit, don't forget to update the index.</p>
|
|
|
|
<p>You'll also have to change the locations on the various frames</p>
|
|
</dd>
|
|
|
|
<dt>ant javadoc</dt>
|
|
|
|
<dd>
|
|
<p>Create the Javadocs, and fix any new (or old) problems.</p>
|
|
</dd>
|
|
|
|
<dt>Add the system to the "hardware" web pages</dt>
|
|
|
|
<dd>
|
|
<p>Edit help/en/html/hardware/index.shtml</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<h2>Adding a TCP/IP connection to an existing system</h2>
|
|
These are rough notes from adding a TCP/IP connection to the RFID type, by copying the
|
|
architecture of the C/MRI system.
|
|
<ol>
|
|
<li>Create a "networkdriver" directory in parallel to the "serialdriver" directory.<br>
|
|
<code>cp java/src/jmri/jmrix/cmri/serial/networkdriver/
|
|
java/src/jmri/jmrix/rfid/</code></li>
|
|
|
|
<li>Edit the package and import statements, all files. ".cmri.serial." to ".rfid.", then
|
|
".cmri." to ".rfid.".</li>
|
|
|
|
<li>Change the "setManufacturer" call in NetworkDriverAdapter.</li>
|
|
|
|
<li>C/MRI might not have been the best starting point, but it's what we've got. Some
|
|
specific edits needed:
|
|
<ul>
|
|
<li>Change CMRISystemConnectionMemo to RfidSystemConnectionMemo</li>
|
|
|
|
<li>Remove the reference to NodeConfigAction in ConnectionConfig (or use this as the
|
|
base for any special configuration you need; it was adding a "Configure Nodes"
|
|
button)</li>
|
|
|
|
<li>Change the name of SerialSensorManager throughout</li>
|
|
|
|
<li>Remove the SerialTurnoutManager SerialLightManager references (there aren't any in
|
|
RFID)</li>
|
|
|
|
<li>Add RfidReporterManager</li>
|
|
</ul>
|
|
</li>
|
|
|
|
<li>Needs a network driver:<br>
|
|
<code>cp java/src/jmri/jmrix/cmri/serial/SerialNetworkPortController.java
|
|
java/src/jmri/jmrix/rfid/RfidNetworkPortController.java</code><br>
|
|
and edit as above.</li>
|
|
|
|
<li>java/src/jmri/jmrix/rfid/networkdriver/configurexml/ConnectionConfigXml.java contains
|
|
dead code for configuring the C/MRI nodes (again, maybe not the right system to copy from).
|
|
Leave that for later by commenting out the body of extendElement(Element e) and
|
|
unpackElement(Element e).</li>
|
|
|
|
<li>Change references to SerialTrafficController to RfidTrafficController.</li>
|
|
|
|
<li>Another problem with C/MRI as a prototype is that it still has an instance() call in
|
|
NetworkDriverAdapter. Go to the RFID (multi-system capable) SerialDriverAdapter and copy
|
|
the structure there.
|
|
|
|
<pre>
|
|
<code>
|
|
// connect to the traffic controller
|
|
this.getSystemConnectionMemo().setRfidTrafficController(control);
|
|
control.setAdapterMemo(this.getSystemConnectionMemo());
|
|
control.connectPort(this);
|
|
control.sendInitString();
|
|
|
|
// declare up
|
|
jmri.jmrix.rfid.ActiveFlag.setActive();
|
|
</code>
|
|
</pre>(There's also a bunch of stuff before this in the configure() method that should just be
|
|
copied over, because the RFID connections also need some complicated configuration); the ctor also
|
|
needs some parts copied over.
|
|
</li>
|
|
|
|
<li>Add jmri.jmrix.rfid.networkdriver.ConnectionConfig to
|
|
java/src/jmri/jmrix/rfid//RfidConnectionTypeList.java</li>
|
|
|
|
<li>Change "RFID Device Connection" to "Direct Serial Connection" in
|
|
ConnectionConfig.name() The network connection will default to "Network Connection".</li>
|
|
|
|
<li>Check that configure/save/restart brings back all the configuration options. It should,
|
|
you copied the necessary code above, but check.</li>
|
|
</ol>
|
|
|
|
<h2>Connections with Complicated Setup</h2>
|
|
Some connection types need more configuration and/or setup than you can get with the usual
|
|
option1/option2/option3 mechanism. Tools available are:
|
|
<ul>
|
|
<li>loadDetails() in ConnectionConfig. This is invoked when setting up the preferences
|
|
window, and can be used to add additional controls. C/MRI uses this to add a "Configure
|
|
Nodes" button. RFID uses it to add listeners that control which combinations of options are
|
|
available.</li>
|
|
|
|
<li>extendElement(Element e) and unpackElement(Element e) in ConnectionConfigXml can be
|
|
used to store additional information and reload it, respectively. C/MRI uses this to store
|
|
its node information.</li>
|
|
</ul>
|
|
<!--#include virtual="/help/en/parts/Footer.shtml" -->
|
|
</div>
|
|
<!-- closes #mainContent-->
|
|
</div>
|
|
<!-- closes #mBody-->
|
|
<script src="/js/help.js"></script>
|
|
</body>
|
|
</html>
|