001package jmri.jmrix.direct; 002 003import jmri.CommandStation; 004import jmri.DccLocoAddress; 005import jmri.LocoAddress; 006import jmri.SystemConnectionMemo; 007import jmri.jmrix.AbstractThrottle; 008 009/** 010 * An implementation of DccThrottle with code specific to a Direct serial 011 * connection. 012 * 013 * @author Bob Jacobsen Copyright (C) 2004 014 */ 015public class Throttle extends AbstractThrottle { 016 017 private final CommandStation tcl; 018 019 /** 020 * Constructor. 021 * @param address loco address. 022 * @param tc system connection traffic controller. 023 * @param memo the system connection. 024 */ 025 public Throttle(DccLocoAddress address, CommandStation tc, SystemConnectionMemo memo) { 026 super(memo); 027 tcl = tc; 028 029 // cache settings. 030 synchronized(this) { 031 this.speedSetting = 0; 032 } 033 // Functions default to false 034 this.address = address; 035 this.isForward = true; 036 } 037 038 @Deprecated (since="5.13.3", forRemoval=true) 039 public Throttle(DccLocoAddress address, CommandStation tc) { 040 this(address, tc, jmri.InstanceManager.getDefault(SystemConnectionMemo.class)); 041 } 042 043 DccLocoAddress address; 044 045 @Override 046 public LocoAddress getLocoAddress() { 047 return address; 048 } 049 050 /** 051 * Send the message to set the state of functions F0, F1, F2, F3, F4. 052 */ 053 @Override 054 protected void sendFunctionGroup1() { 055 byte[] result = jmri.NmraPacket.function0Through4Packet(address.getNumber(), address.isLongAddress(), 056 getFunction(0), getFunction(1), getFunction(2), getFunction(3), getFunction(4)); 057 058 tcl.sendPacket(result, 1); 059 } 060 061 /** 062 * Send the message to set the state of functions F5, F6, F7, F8. 063 */ 064 @Override 065 protected void sendFunctionGroup2() { 066 067 byte[] result = jmri.NmraPacket.function5Through8Packet(address.getNumber(), address.isLongAddress(), 068 getFunction(5), getFunction(6), getFunction(7), getFunction(8)); 069 070 tcl.sendPacket(result, 1); 071 } 072 073 /** 074 * Send the message to set the state of functions F9, F10, F11, F12. 075 */ 076 @Override 077 protected void sendFunctionGroup3() { 078 079 byte[] result = jmri.NmraPacket.function9Through12Packet(address.getNumber(), address.isLongAddress(), 080 getFunction(9), getFunction(10), getFunction(11), getFunction(12)); 081 082 tcl.sendPacket(result, 1); 083 } 084 085 /** 086 * Set the speed and direction. 087 * <p> 088 * This intentionally skips the emergency stop value of 1. 089 * 090 * @param speed Number from 0 to 1; less than zero is emergency stop 091 */ 092 @Override 093 public synchronized void setSpeedSetting(float speed) { 094 float oldSpeed = this.speedSetting; 095 this.speedSetting = speed; 096 int value = (int) ((127 - 1) * speed); // -1 for rescale to avoid estop 097 if (value > 0) { 098 value = value + 1; // skip estop 099 } 100 if (value > 127) { 101 value = 127; // max possible speed 102 } 103 if (value < 0) { 104 value = 1; // emergency stop 105 } 106 String step = "" + value; 107 108 Message m = new Message(1 + step.length()); 109 int i = 0; // message index counter 110 if (isForward) { 111 m.setElement(i++, '>'); 112 } else { 113 m.setElement(i++, '<'); 114 } 115 116 for (int j = 0; j < step.length(); j++) { 117 m.setElement(i++, step.charAt(j)); 118 } 119 firePropertyChange(SPEEDSETTING, oldSpeed, this.speedSetting); 120 record(speed); 121 // tcl.sendMessage(m, null); 122 } 123 124 @Override 125 public void setIsForward(boolean forward) { 126 boolean old = isForward; 127 isForward = forward; 128 synchronized(this) { 129 setSpeedSetting(speedSetting); // send the command 130 } 131 firePropertyChange(ISFORWARD, old, isForward); 132 } 133 134 @Override 135 public void throttleDispose() { 136 finishRecord(); 137 } 138 139 // initialize logging 140 // private final static Logger log = LoggerFactory.getLogger(Throttle.class); 141 142}