001package jmri.jmrix.sprog; 002 003import java.util.ArrayList; 004import java.util.List; 005import javax.annotation.Nonnull; 006 007import jmri.AddressedProgrammer; 008import jmri.ProgListener; 009import jmri.ProgrammerException; 010import jmri.ProgrammingMode; 011 012/** 013 * Provide an Ops Mode Programmer via a wrapper what works with the SPROG 014 * command station object. 015 * <p> 016 * Functionally, this just creates packets to send via the command station. 017 * 018 * @see jmri.Programmer 019 * @author Andrew Crosland Copyright (C) 2006 020 */ 021public class SprogOpsModeProgrammer extends SprogProgrammer implements AddressedProgrammer { 022 023 int mAddress; 024 boolean mLongAddr; 025 private SprogSystemConnectionMemo _memo = null; 026 027 public SprogOpsModeProgrammer(int pAddress, boolean pLongAddr, SprogSystemConnectionMemo memo) { 028 super(memo); 029 mAddress = pAddress; 030 mLongAddr = pLongAddr; 031 _memo = memo; 032 } 033 034 /** 035 * {@inheritDoc} 036 * 037 * Forward a write request to an ops-mode write operation 038 */ 039 @Override 040 synchronized public void writeCV(String CVname, int val, ProgListener p) throws ProgrammerException { 041 final int CV = Integer.parseInt(CVname); 042 log.debug("write CV={} val={}", CV, val); 043 044 // record state. COMMANDSENT is just waiting for a reply... 045 useProgrammer(p); 046 progState = COMMANDSENT; 047 _val = val; 048 049 // Add the packet to the queue rather than send it directly 050 // [AC 23/01/16] Check that there is a free slot for the ops mode packet. 051 // Delay the reply to allow time for the ops mode packet to be sent and prevent all slots from filling up 052 // when writing multiple CVs, e.g. writing a sheet in the comprehensive programmer. 053 if (_memo.getCommandStation().opsModepacket(mAddress, mLongAddr, CV, val) != null) { 054 javax.swing.Timer t = new javax.swing.Timer(250, (java.awt.event.ActionEvent evt)->{notifyProgListenerEnd(_val, jmri.ProgListener.OK);}); 055 t.setRepeats(false); 056 t.start(); 057 } else { 058 progState = NOTPROGRAMMING; 059 notifyProgListenerEnd(_val, jmri.ProgListener.FailedTimeout); 060 } 061 } 062 063 /** 064 * {@inheritDoc} 065 */ 066 @Override 067 synchronized public void readCV(String CVname, ProgListener p) throws ProgrammerException { 068 // final int CV = Integer.parseInt(CVname); 069 log.error("readCV not available in this protocol"); 070 throw new ProgrammerException(); 071 } 072 073 /** 074 * {@inheritDoc} 075 */ 076 @Override 077 synchronized public void confirmCV(String CV, int val, ProgListener p) throws ProgrammerException { 078 log.error("confirmCV not available in this protocol"); 079 throw new ProgrammerException(); 080 } 081 082 /** 083 * {@inheritDoc} 084 * 085 * Types implemented here. 086 */ 087 @Override 088 @Nonnull 089 public List<ProgrammingMode> getSupportedModes() { 090 List<ProgrammingMode> ret = new ArrayList<ProgrammingMode>(); 091 ret.add(ProgrammingMode.OPSBYTEMODE); 092 return ret; 093 } 094 095 /** 096 * {@inheritDoc} 097 */ 098 @Override 099 synchronized public void notifyReply(SprogReply m) { 100 // We will not see any replies 101 } 102 103 /** 104 * {@inheritDoc} 105 * 106 * Can this ops-mode programmer read back values? For now, no, but maybe 107 * later. 108 * 109 * @return always false for now 110 */ 111 @Override 112 public boolean getCanRead() { 113 return false; 114 } 115 116 /** 117 * {@inheritDoc} 118 */ 119 @Override 120 public boolean getLongAddress() { 121 return mLongAddr; 122 } 123 124 /** 125 * {@inheritDoc} 126 */ 127 @Override 128 public int getAddressNumber() { 129 return mAddress; 130 } 131 132 /** 133 * {@inheritDoc} 134 */ 135 @Override 136 public String getAddress() { 137 return "" + getAddressNumber() + " " + getLongAddress(); 138 } 139 140 /** 141 * Ops-mode programming doesn't put the command station in programming mode, 142 * so we don't have to send an exit-programming command at end. Therefore, 143 * this routine does nothing except to replace the parent routine that does 144 * something. 145 */ 146 void cleanup() { 147 } 148 149 // initialize logging 150 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(SprogOpsModeProgrammer.class); 151 152}