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}