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}