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