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