Skip to content

Commit

Permalink
MERG CBUS Reporter Update
Browse files Browse the repository at this point in the history
No longer creates reporters automatically
Increment range option enabled
Standardise CanMessage / CanReply ACDAT OPC
  • Loading branch information
icklesteve committed May 6, 2019
1 parent 0e99329 commit 802eeb0
Show file tree
Hide file tree
Showing 6 changed files with 239 additions and 157 deletions.
43 changes: 24 additions & 19 deletions help/en/html/hardware/can/cbus/Names.shtml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@

<ul class="snav">
<li><a href="#events">Event Name and Numbering</a></li>
<li><a href="#sysname">System Names</a></li>
<li><a href="#reporters">Reporters</a></li>
<li><a href="#sysname">System Names</a></li>
<li><a href="#summary">Summary of MERG CBUS Events</a></li>
<li><a href="#namingspec">Event Naming Specification</a></li>
<li><a href="#hex">Sending hex strings</a></li>
Expand Down Expand Up @@ -159,32 +160,36 @@
<p>See <a href="../../../doc/Technical/TurnoutFeedback.shtml">JMRI : Turnout Feedback</a> for more info.</p>


<h4><a name="reporters" id="reporters">Reporter ( RFID ) data from CBUS</a></h4>
<p><a href="../../../tools/Reporters.shtml">JMRI Reporters</a> do not have Off or On events, they just use a device ( short event ) or node number.</p>
<p>A typical system name for a reporter would be <code>MR123</code> or <code>MR1234</code> ( no event On or Off ) .</p>
<h4><a name="reporters" id="reporters">Reporter ( incl. RFID ) data from CBUS</a></h4>
<p><a href="../../../tools/Reporters.shtml">JMRI Reporters</a> do not have Off or On events,
they just use a device ( short event ) or node number.</p>

<p>Reporters are created by clicking the New button within the
<a href="../../../../package/jmri/jmrit/beantable/ReporterTable.shtml">Reporter Table</a>.</p>
<p>You can create multiple reporters by checking the Add Sequential Range option.</p>

<p>Like Turnouts Sensors and Lights, these are not created automatically in CBUS.</p>

<p>A typical system name for a reporter would be
<code>MR123</code> or <code>MR1234</code> ( no event On or Off ) .</p>
<p>The DDES and ACDAT OPC's are used for reporter data.</p>
<p>When a DDES or ACDAT OPC is heard on the network,
JMRI will look for a reporter matching the device or node number in the
<a href="../../../../package/jmri/jmrit/beantable/ReporterTable.shtml">Reporter Table</a>.</p>
JMRI will look for a reporter matching the device or node number in the Reporter Table.</p>

<p>If a reporter exists, the <a href="../../../tools/IdTags.shtml">ID tag</a>
within the 5 data bytes will be looked up from the
within the 5 data bytes will be looked up from the
<a href="../../../../package/jmri/jmrit/beantable/IdTagTable.shtml">ID Tag table</a>.</p>

<p>If there's no matching ID Tag on the table, one will be created and updated.</p>

<p>If the ID tag was previously active for another reporter,
the previous reporter will have the tag removed from its report.</p>

<p>If the DDES or ACDAT message is coming FROM JMRI, the previous reporter will not be updated,
the existing reporeter is only cleared by messages coming in to JMRI. </p>
<p>Reporters are created automatically and will populate the Reporter table when
a DDES or ACDAT OPC is heard on the network.</p>
<p>Valid reporter numbers are minimum 1, maximum 65535.</p>
<p>The DDES ( device number ) and ACDAT ( node number ) messages are
currently handled in exactly the same way, ie the first 2 bytes are used as the Reporter identifier.</p>
<p>This means that a reporter created via a DDES of device 77 will respond to a ACDAT of node 77,
and vice versa.</p>
the previous reporter will have the tag removed from its report.</p>

<p>Valid reporter numbers are minimum 0, to maximum 65535.</p>
<p>The DDES ( device number data ) and ACDAT ( node data ) messages are
currently handled in exactly the same way, ie the first 2 bytes are used as the Reporter identifier.</p>
<p>This means that a reporter created via a number of 77 will respond to
both DDES device 77 and ACDAT of node 77.</p>

<p>Reporters are saved in your main panel file, along with turnouts and sensors etc.</p>
<p>ID Tags cross-session automatically, no saving is necessary.</p>
Expand All @@ -193,8 +198,8 @@
<h2><a name="sysname" id="sysname">System Names</a></h2>
<div>
<p>When adding an item to your JMRI
<a href="../../../../package/jmri/jmrit/beantable/SensorTable.shtml">Sensor Table</a>,
<a href="../../../../package/jmri/jmrit/beantable/TurnoutTable.shtml">Turnout Table</a>,
<a href="../../../../package/jmri/jmrit/beantable/SensorTable.shtml">Sensor Table</a>,
<a href="../../../../package/jmri/jmrit/beantable/LightTable.shtml">Light Table</a> or
<a href="../../../../package/jmri/jmrit/beantable/ReporterTable.shtml">Reporter Table</a>,

Expand Down
5 changes: 4 additions & 1 deletion help/en/releasenotes/current-draft-note.shtml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@

<h4>MERG CBUS</h4>
<ul>
<li></li>
<li><a href="http://jmri.org/help/en/html/hardware/can/cbus/Names.shtml#reporters"
>CBUS Reporters</a> are no longer automatically created when hearing a DDES or ACDAT CBUS OPC.
<br>New CBUS Reporters can now be created in a sequential range.
</li>
</ul>

<h4>MQTT</h4>
Expand Down
99 changes: 43 additions & 56 deletions java/src/jmri/jmrix/can/cbus/CbusReporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,20 @@
* <P>
*
* @author Mark Riddoch Copyright (C) 2015
* @author Steve Young Copyright (c) 2019
*
*/
public class CbusReporter extends AbstractReporter implements CanListener {

private final int _number;
private TrafficController tc;

@SuppressWarnings("LeakingThisInConstructor")
public CbusReporter(int number, TrafficController tc, String prefix) { // a human-readable Reporter number must be specified!
public CbusReporter(int number, TrafficController tco, String prefix) { // a human-readable Reporter number must be specified!
super(prefix + "R" + number); // can't use prefix here, as still in construction
_number = number;
// At construction, register for messages
tc = tco;
tc.addCanListener(this);
log.debug("Added new reporter " + prefix + "R" + number);
}
Expand All @@ -55,75 +58,38 @@ public int getState() {

@Override
public void message(CanMessage m) {
if ( m.isExtended() || m.isRtr() ) {
return;
}
log.debug("CbusReporter: message " + m.getOpCode());
if (m.getOpCode() == CbusConstants.CBUS_DDES) {
RFIDReport(m);
} // nothing
RFIDReport( m );
}

@Override
public void reply(CanReply m) {
if ( m.isExtended() || m.isRtr() ) {
return;
}
log.debug("CbusReporter: reply " + m.getOpCode());
if (m.getOpCode() == CbusConstants.CBUS_DDES || m.getOpCode() == CbusConstants.CBUS_ACDAT) {
int addr = (m.getElement(1) << 8) + m.getElement(2);
if (addr != _number) {
log.debug("CBusReporter incorrect node number: " + addr + ", expected " + _number + "in reply");
return;
}
String buf;

buf = toTag(m.getElement(3), m.getElement(4), m.getElement(5), m.getElement(6), m.getElement(7));
log.debug("Report RFID tag read of tag: " + buf);
IdTag tag = InstanceManager.getDefault(IdTagManager.class).getIdTag(buf);
if (tag != null) {
CbusReporter r;
if ((r = (CbusReporter) tag.getWhereLastSeen()) != null) {
log.debug("Previous reporter: " + r.mSystemName);
if (r != this && r.getCurrentReport() == tag) {
log.debug("Notify previous");
r.clear();
} else {
log.debug("Current report was: " + r.getCurrentReport());
}
}
tag.setWhereLastSeen(this);
} else {
log.error("Failed to find tag for RFID:" + buf);
InstanceManager.getDefault(IdTagManager.class).newIdTag(buf, null);
}
setReport(tag);
setState(tag != null ? IdTag.SEEN : IdTag.UNSEEN);
} // nothing

RFIDReport( new CanMessage(m) );
}

public void clear() {
log.debug("reporter {} set to clear",toString());
setReport(null);
setState(IdTag.UNSEEN);
}

private void RFIDReport(CanMessage l) {
// check address
int addr = CbusMessage.getNodeNumber(l);
if (addr != _number) {
log.debug("CBusReporter incorrect node number: " + addr + ", expected node number: " + _number);
private void RFIDReport(CanMessage m) {
if ( m.isExtended() || m.isRtr() ) {
return;
}
String buf;
buf = toTag(l.getElement(3), l.getElement(4), l.getElement(5), l.getElement(6), l.getElement(7));
log.debug("Report RFID tag read of tag: " + buf);
IdTag tag = InstanceManager.getDefault(IdTagManager.class).getIdTag(buf);
if (tag == null) {
log.error("Failed to find tag for RFID:" + buf);
if ( m.getOpCode() != CbusConstants.CBUS_DDES && m.getOpCode() != CbusConstants.CBUS_ACDAT) {
return;
}
int addr = (m.getElement(1) << 8) + m.getElement(2);
if (addr == _number) {
log.debug("CBusReporter found for addr:{}", addr);
String buf = toTag(m.getElement(3), m.getElement(4), m.getElement(5), m.getElement(6), m.getElement(7));
log.debug("Report RFID tag read of tag: {}", buf);
IdTag tag = InstanceManager.getDefault(IdTagManager.class).provideIdTag(buf);
clearPreviousReporter(tag);
tag.setWhereLastSeen(this);
setReport(tag);
setState(IdTag.SEEN);
}
setReport(tag);
setState(tag != null ? IdTag.SEEN : IdTag.UNSEEN);
}

private String toTag(int b1, int b2, int b3, int b4, int b5) {
Expand All @@ -132,6 +98,27 @@ private String toTag(int b1, int b2, int b3, int b4, int b5) {
+ String.format("%02X", b4) + String.format("%02X", b5);
return rval;
}

// clear all previous reporter of the ID tag location
// there is no "exit" area message in CBUS
private void clearPreviousReporter(IdTag tag) {
log.debug("clear previous reporter for tag {}",tag);
CbusReporter r;
if ((r = (CbusReporter) tag.getWhereLastSeen()) != null) {
log.debug("previous reporter {} found",r);
if (r != this && r.getCurrentReport() == tag) {
r.clear();
}
}
}

/**
* {@inheritDoc}
*/
@Override
public void dispose() {
tc.removeCanListener(this);
}

private static final Logger log = LoggerFactory.getLogger(CbusReporter.class);
}
Loading

0 comments on commit 802eeb0

Please sign in to comment.