001package jmri.jmrix.xpa;
002
003import jmri.DccLocoAddress;
004import jmri.LocoAddress;
005import jmri.SpeedStepMode;
006import jmri.SystemConnectionMemo;
007import jmri.jmrix.AbstractThrottle;
008import org.slf4j.Logger;
009import org.slf4j.LoggerFactory;
010
011/**
012 * An XPA+Modem implementation of the Throttle for XpressNet Systems
013 *
014 * @author Paul Bender Copyright (C) 2004
015 */
016public class XpaThrottle extends AbstractThrottle {
017
018    private int speedvalue;
019    private final int address;
020    private final XpaTrafficController tc;
021
022    /**
023     * Create a throttle.
024     *
025     * @param address the address for the throttle
026     * @param t the controller for the system connection
027     * @param memo the System connection.
028     */
029    public XpaThrottle(LocoAddress address, XpaTrafficController t, SystemConnectionMemo memo) {
030        super(memo);
031        this.address = address.getNumber();
032        this.speedStepMode = SpeedStepMode.INCREMENTAL;
033        this.isForward = true;
034        synchronized(this) {
035            this.speedSetting = 0;
036        }
037        // Functions default to false
038        this.speedvalue = 0;
039        tc = t;
040        log.debug("XpaThrottle constructor called for address {}", address);
041    }
042
043    @Deprecated (since="5.13.3", forRemoval=true)
044    public XpaThrottle(LocoAddress address, XpaTrafficController t) {
045        this(address, t, jmri.InstanceManager.getDefault(jmri.jmrix.xpa.XpaSystemConnectionMemo.class));
046    }
047
048    /**
049     * Set the speed and direction.
050     * <p>
051     * This intentionally skips the emergency stop value of 1.
052     *
053     * @param speed Number from 0 to 1; less than zero is emergency stop
054     */
055    @Override
056    public void setSpeedSetting(float speed) {
057        super.setSpeedSetting(speed);
058        int value = Math.round((127) * speed);
059        if (value > 127) {
060            value = 127;    // max possible speed
061        }
062        if (speed > 0 && value == 0) {
063            value = 1;
064        }
065        if (this.speedvalue != value) {
066            XpaMessage m;
067            if (value < 0) {
068                value = 0;        // emergency stop
069                m = XpaMessage.getEStopMsg();
070                tc.sendXpaMessage(m, null);
071            } else if (value == 0) {
072                m = XpaMessage.getIdleMsg(address);
073                tc.sendXpaMessage(m, null);
074            } else if (value > this.speedvalue) {
075                // Increase the speed
076                int diff = value - speedvalue;
077                m = XpaMessage.getIncSpeedMsg(this.address, diff);
078                tc.sendXpaMessage(m, null);
079            } else if (value < this.speedvalue) {
080                // Decrease the speed
081                int diff = speedvalue - value;
082                m = XpaMessage.getDecSpeedMsg(this.address, diff);
083                tc.sendXpaMessage(m, null);
084            }
085        }
086        synchronized(this) {
087            this.speedSetting = speed;
088        }
089        this.speedvalue = value;
090    }
091
092    /** 
093     * {@inheritDoc}
094     */
095    @Override
096    public void setIsForward(boolean forward) {
097        super.setIsForward(forward);
098        XpaMessage m;
099        if (forward) {
100            m = XpaMessage.getDirForwardMsg(address);
101        } else {
102            m = XpaMessage.getDirReverseMsg(address);
103        }
104        tc.sendXpaMessage(m, null);
105    }
106    
107    /** 
108     * {@inheritDoc}
109     */
110    @Override
111    public void setFunction(int func, boolean value){
112        if ( func>=0 && func<13 && getFunction(func)!=value){
113            updateFunction(func,value);    
114            tc.sendXpaMessage(XpaMessage.getFunctionMsg(address, 0), null);
115        }
116        else {
117            super.setFunction(func,value);
118        }
119    }
120
121    /** 
122     * {@inheritDoc}
123     */
124    @Override
125    public void sendFunctionGroup1() {
126    }
127
128    /** 
129     * {@inheritDoc}
130     */
131    @Override
132    public void sendFunctionGroup2() {
133    }
134
135    /**
136     * {@inheritDoc}
137     */
138    @Override
139    public void sendFunctionGroup3() {
140    }
141
142    /** 
143     * {@inheritDoc}
144     */
145    @Override
146    public LocoAddress getLocoAddress() {
147        return new DccLocoAddress(address, XpaThrottleManager.isLongAddress(address));
148    }
149
150    /** 
151     * {@inheritDoc}
152     */
153    @Override
154    public void throttleDispose() {
155        finishRecord();
156    }
157
158    // initialize logging
159    private final static Logger log = LoggerFactory.getLogger(XpaThrottle.class);
160
161}