001package jmri.implementation; 002 003import jmri.CommandStation; 004import jmri.InstanceManager; 005import jmri.Turnout; 006import jmri.TurnoutOperator; 007import org.slf4j.Logger; 008import org.slf4j.LoggerFactory; 009 010/** 011 * Concrete subclass of TurnoutOperator for a turnout that has no feedback. This 012 * operator sends raw NMRA accessory decoder packets to the layout instead of 013 * using the built in turnout code. It should be used only with turnouts with 014 * DIRECT, ONESENSOR or TWOSENSOR feedback. This class is based on the 015 * NoFeedbackTurnoutOperator class. 016 * 017 * @author Paul Bender Copyright 2008 018 */ 019public class RawTurnoutOperator extends TurnoutOperator { 020 021 long interval; 022 int maxTries; 023 int tries = 0; 024 int address = 0; 025 CommandStation c; 026 027 public RawTurnoutOperator(AbstractTurnout t, long i, int mt) { 028 super(t); 029 String sysName = t.getSystemName(); 030 int startAddress = sysName.lastIndexOf("T"); 031 address = Integer.parseInt(sysName.substring(startAddress + 1, sysName.length())); 032 String prefix = t.getSystemName().substring(0, startAddress); 033 java.util.List<jmri.CommandStation> connList = jmri.InstanceManager.getList(jmri.CommandStation.class); 034 for (int x = 0; x < connList.size(); x++) { 035 jmri.CommandStation station = connList.get(x); 036 if (station.getSystemPrefix().equals(prefix)) { 037 c = station; 038 break; 039 } 040 } 041 if (c == null) { 042 c = InstanceManager.getNullableDefault(CommandStation.class); 043 log.error("No match against the command station for {}, so will use the default", sysName); 044 } 045 interval = i; 046 maxTries = mt; 047 } 048 049 private void sendCommand() { 050 byte pkt[] = jmri.NmraPacket.accDecoderPkt(address, myTurnout.getCommandedState() == Turnout.CLOSED); 051 c.sendPacket(pkt, 1); 052 } 053 054 /** 055 * Do the autmation for a turnout with no feedback. This means try maxTries 056 * times at an interval of interval. Note the call to operatorCheck each 057 * time we're about to actually do something - if we're no longer the 058 * current operator this throws TurnoutOperatorException which just 059 * terminates the thread. 060 */ 061 @Override 062 public void run() { 063 try { 064 operatorCheck(); 065 sendCommand(); 066 while (++tries < maxTries) { 067 try { 068 Thread.sleep(interval); 069 } catch (InterruptedException e) { 070 Thread.currentThread().interrupt(); // retain if needed later 071 } 072 operatorCheck(); 073 sendCommand(); 074 } 075 myTurnout.setKnownStateToCommanded(); 076 } catch (TurnoutOperatorException e) { 077 } 078 } 079 080 private final static Logger log = LoggerFactory.getLogger(RawTurnoutOperator.class); 081}