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}