Class Dcc4PcOpsModeProgrammer
- All Implemented Interfaces:
PropertyChangeListener,EventListener,AddressedProgrammer,PropertyChangeFirer,PropertyChangeProvider,Disposable,Programmer
A read sends the POM read packet through the other connection's command station, and waits only for the decoder's RailCom reply, decoded by the reader. It doesn't use that connection's own ops-mode read: a command station that can't read RailCom keeps its programmer busy for seconds after each read, waiting for a value it will never get.
Packets are paced: each is handed to the command station only once it has had time to send the last one with its repeats, because a LocoNet command station drops a packet it's given while still busy, without telling sendPacket. A packet with no reply is sent again every RETRY_AFTER, up to MAX_SENDS times in all. Resending every second instead (2026-10-13) built a backlog the command station was still working through 20 s later.
Without a command station, the read goes through the other connection's programmer instead, and finishes with the first value that arrives: the RailCom reply, or the value that programmer reads back.
A write is sent the same way. The decoder answers a POM write with the value it then holds, so the write is done when that matches; if it never does, the write ends with ConfirmFailed. Without a command station, the other connection's programmer does the write and reports the result.
- See Also:
-
Nested Class Summary
Nested classes/interfaces inherited from interface jmri.Programmer
Programmer.Configurator, Programmer.WriteConfirmMode -
Field Summary
FieldsModifier and TypeFieldDescription(package private) booleanTrue while a read or confirm is waiting for its value.(package private) final CommandStationSends the POM packets; null to go through defaultProgrammer instead.(package private) int(package private) AddressedProgrammerManager(package private) Programmer(package private) static final longTime to leave per repeat before handing the command station another packet.(package private) intThe last value a write was answered with, or -1 for none yet.(package private) static final intHow many times a packet is sent in all while no answer comes, RETRY_AFTER apart.(package private) int(package private) boolean(package private) ProgListener(package private) static final intLongest a read or write waits when we send the POM packets: time for the last of theMAX_SENDSsends to be answered (answers come 160-270 ms after a send).(package private) RailCom(package private) static final intHow many times the command station sends a POM read packet.(package private) static final intLongest a read waits when it goes through the other connection's programmer (no command station to send the packets ourselves).(package private) static final intIf no reply has come after this long, the packet is sent once more, in case it or its answer was lost.(package private) static final intHow many times the command station sends a POM write packet.(package private) intThe value being written, or -1 for a read.Fields inherited from class jmri.jmrix.AbstractProgrammer
LONG_TIMEOUT, SHORT_TIMEOUTFields inherited from class jmri.beans.PropertyChangeSupport
propertyChangeSupport -
Constructor Summary
ConstructorsConstructorDescriptionDcc4PcOpsModeProgrammer(boolean pLongAddress, int pAddress, AddressedProgrammerManager dp) Dcc4PcOpsModeProgrammer(boolean pLongAddress, int pAddress, AddressedProgrammerManager dp, CommandStation cs) -
Method Summary
Modifier and TypeMethodDescriptionvoidconfirmCV(String cvName, int val, ProgListener p) Confirm the value of a CV using the specified programming mode.intbooleanGet the list ofProgrammingModesupported by this Programmer.(package private) static byte[]pomReadPacket(int address, boolean longAddr, int cvNum) The NMRA ops-mode "verify byte" packet (S-9.2.1 long-form CV access, instruction 1110 01VV), which a RailCom decoder answers with the CV's value on channel 2.voidThe loco's RailCom tag has a POM reply for the CV being read or written.voidreadCV(String CVname, ProgListener p) Perform a CV read in the system-specific manner, and using the specified programming mode.(package private) static voidFor tests: forget the pacing left by earlier sends.protected voidtimeout()Internal routine to handle a timeout, should be synchronized!voidwriteCV(String CVname, int val, ProgListener p) Perform a CV write in the system-specific manner, and using the specified programming mode.Methods inherited from class jmri.jmrix.AbstractProgrammer
decodeErrorCode, getBestMode, getCanRead, getCanRead, getCanWrite, getCanWrite, getMode, getWriteConfirmMode, registerFromCV, restartTimer, setMode, startLongTimer, startShortTimer, stopTimerMethods inherited from class jmri.beans.PropertyChangeSupport
addPropertyChangeListener, addPropertyChangeListener, fireIndexedPropertyChange, fireIndexedPropertyChange, fireIndexedPropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, getPropertyChangeListeners, getPropertyChangeListeners, removePropertyChangeListener, removePropertyChangeListenerMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface jmri.Programmer
addPropertyChangeListener, decodeErrorCode, dispose, getCanRead, getCanRead, getCanWrite, getCanWrite, getConfigurator, getMode, getWriteConfirmMode, notifyProgListenerEnd, readCV, removePropertyChangeListener, setMode
-
Field Details
-
pAddress
int pAddress -
pLongAddress
boolean pLongAddress -
rcTag
-
cv
int cv -
progListener
-
awaitingValue
boolean awaitingValueTrue while a read or confirm is waiting for its value. -
READ_TIMEOUT
Longest a read waits when it goes through the other connection's programmer (no command station to send the packets ourselves).- See Also:
-
RAILCOM_TIMEOUT
Longest a read or write waits when we send the POM packets: time for the last of theMAX_SENDSsends to be answered (answers come 160-270 ms after a send). With 5 s, the few CVs that got no answer at all took 40% of a Read All (2026-10-16).- See Also:
-
READ_REPEATS
How many times the command station sends a POM read packet. A decoder may need a moment to fetch the value, and then sends it in later cutouts; only one that follows the read packet itself can be matched to the CV, so it helps if the packet is still being repeated by then.- See Also:
-
WRITE_REPEATS
How many times the command station sends a POM write packet. A decoder only writes after two identical write packets in a row.- See Also:
-
GAP_PER_REPEAT
Time to leave per repeat before handing the command station another packet. A LocoNet command station drops a packet it's given while still sending the last one (it answers "busy", which sendPacket doesn't report), so on 2026-10-13 every write sent straight after another was lost. This is an estimate: about one DCC packet per repeat, with room for the command station's own refresh traffic.2026-10-15: 150 ms made no difference to how many sends went unanswered, so the losses aren't the command station being busy.
- See Also:
-
RETRY_AFTER
If no reply has come after this long, the packet is sent once more, in case it or its answer was lost. Answers normally come 160-270 ms after the send (2026-10-15); 1500 ms made each lost one cost far more than the answer itself.- See Also:
-
MAX_SENDS
How many times a packet is sent in all while no answer comes, RETRY_AFTER apart.- See Also:
-
defaultManager
-
defaultProgrammer
-
commandStation
Sends the POM packets; null to go through defaultProgrammer instead. -
writeValue
int writeValueThe value being written, or -1 for a read. A decoder answers a POM write with the value it then holds, so the write is done when that matches. -
lastWriteReply
int lastWriteReplyThe last value a write was answered with, or -1 for none yet.
-
-
Constructor Details
-
Dcc4PcOpsModeProgrammer
-
Dcc4PcOpsModeProgrammer
public Dcc4PcOpsModeProgrammer(boolean pLongAddress, int pAddress, AddressedProgrammerManager dp, @CheckForNull CommandStation cs) - Parameters:
pLongAddress- true for a long addresspAddress- the loco's addressdp- the other connection's programmer manager, for writescs- the other connection's command station, which sends the POM read packets; null to read through the programmer instead
-
-
Method Details
-
pomReadPacket
The NMRA ops-mode "verify byte" packet (S-9.2.1 long-form CV access, instruction 1110 01VV), which a RailCom decoder answers with the CV's value on channel 2. The data byte doesn't matter for a read.- Parameters:
address- the loco's addresslongAddr- true for a long addresscvNum- the CV, 1 to 1024- Returns:
- the packet, as
NmraPacketbuilds it forCommandStation.sendPacket(byte[], int), or empty if the address or CV is invalid
-
writeCV
Perform a CV write in the system-specific manner, and using the specified programming mode.Handles a general address space through a String address. Each programmer defines the acceptable formats.
Note that this returns before the write is complete; you have to provide a ProgListener to hear about completion. For simplicity, expect the return to be on the GUI thread.
Exceptions will only be thrown at the start, not during the actual programming sequence. A typical exception would be due to an invalid mode (though that should be prevented earlier) The POM write packet goes out through the command station, and the write is done when the decoder's RailCom reply shows the new value. Without a command station, the other connection's programmer does the write and reports the result.
- Specified by:
writeCVin interfaceProgrammer- Specified by:
writeCVin classAbstractProgrammer- Parameters:
CVname- the CV to writeval- the value to writep- the listener that will be notified of the write- Throws:
ProgrammerException- if unable to communicate
-
readCV
Perform a CV read in the system-specific manner, and using the specified programming mode.Handles a general address space through a String address. Each programmer defines the acceptable formats.
Note that this returns before the write is complete; you have to provide a ProgListener to hear about completion. For simplicity, expect the return to be on the GUI thread.
Exceptions will only be thrown at the start, not during the actual programming sequence. A typical exception would be due to an invalid mode (though that should be prevented earlier)
- Specified by:
readCVin interfaceProgrammer- Specified by:
readCVin classAbstractProgrammer- Parameters:
CVname- the CV to readp- the listener that will be notified of the read- Throws:
ProgrammerException- if unable to communicate
-
resetPacing
For tests: forget the pacing left by earlier sends. -
confirmCV
Confirm the value of a CV using the specified programming mode. On some systems, this is faster than a read.Handles a general address space through a String address. Each programmer defines the acceptable formats.
Note that this returns before the write is complete; you have to provide a ProgListener to hear about completion. For simplicity, expect the return to be on the GUI thread.
Exceptions will only be thrown at the start, not during the actual programming sequence. A typical exception would be due to an invalid mode (though that should be prevented earlier) Reads the CV and lets the listener know whether it matches. The command station's own confirm can't be used: it may only report that it sent the packets.
- Specified by:
confirmCVin interfaceProgrammer- Specified by:
confirmCVin classAbstractProgrammer- Parameters:
cvName- the CV to confirmval- the value to confirmp- the listener that will be notified of the confirmation- Throws:
ProgrammerException- if unable to communicate
-
getSupportedModes
Get the list ofProgrammingModesupported by this Programmer. If the order is significant, earlier modes are better. Types implemented here.- Specified by:
getSupportedModesin interfaceProgrammer- Specified by:
getSupportedModesin classAbstractProgrammer- Returns:
- the list of supported modes or an empty list
-
timeout
Internal routine to handle a timeout, should be synchronized!- Specified by:
timeoutin classAbstractProgrammer
-
propertyChange
The loco's RailCom tag has a POM reply for the CV being read or written.- Specified by:
propertyChangein interfacePropertyChangeListener
-
getLongAddress
- Specified by:
getLongAddressin interfaceAddressedProgrammer
-
getAddressNumber
- Specified by:
getAddressNumberin interfaceAddressedProgrammer
-
getAddress
- Specified by:
getAddressin interfaceAddressedProgrammer
-