001package jmri.jmrix.lenz.hornbyelite; 002 003import jmri.LocoAddress; 004import jmri.jmrix.lenz.XNetReply; 005import jmri.jmrix.lenz.XNetSystemConnectionMemo; 006import jmri.jmrix.lenz.XNetTrafficController; 007import org.slf4j.Logger; 008import org.slf4j.LoggerFactory; 009 010/** 011 * An implementation of DccThrottle with code specific to an XpressNet 012 * connection on the Hornby Elite. 013 * 014 * @author Paul Bender (C) 2008-2009 015 */ 016public class EliteXNetThrottle extends jmri.jmrix.lenz.XNetThrottle { 017 018 /** 019 * Interval to check the status of the throttle 020 */ 021 protected static final int statTimeoutValue = 5000; 022 private static final String MOMENTARY_FUNCTION_REQUEST_NOT_SUPPORTED_BY_ELITE = "Momentary function request not supported by Elite."; 023 024 /** 025 * Constructor. 026 * @param memo system connection. 027 * @param tc traffic controller. 028 */ 029 public EliteXNetThrottle(XNetSystemConnectionMemo memo, XNetTrafficController tc) { 030 super(memo, tc); 031 log.debug("Elite XNetThrottle constructor"); 032 } 033 034 /** 035 * Constructor by address. 036 * @param memo system connection. 037 * @param address loco address. 038 * @param tc system connection traffic controller. 039 */ 040 public EliteXNetThrottle(XNetSystemConnectionMemo memo, LocoAddress address, XNetTrafficController tc) { 041 super(memo, address, tc); 042 log.debug("Elite XNetThrottle constructor called for address {}",address); 043 } 044 045 /** 046 * Send the XpressNet message to set the Momentary state of locomotive 047 * functions F0, F1, F2, F3, F4. 048 */ 049 @Override 050 protected void sendMomentaryFunctionGroup1() { 051 log.debug(MOMENTARY_FUNCTION_REQUEST_NOT_SUPPORTED_BY_ELITE); 052 } 053 054 /** 055 * Send the XpressNet message to set the momentary state of functions F5, 056 * F6, F7, F8. 057 */ 058 @Override 059 protected void sendMomentaryFunctionGroup2() { 060 log.debug(MOMENTARY_FUNCTION_REQUEST_NOT_SUPPORTED_BY_ELITE); 061 } 062 063 /** 064 * Send the XpressNet message to set the momentary state of functions F9, 065 * F10, F11, F12. 066 */ 067 @Override 068 protected void sendMomentaryFunctionGroup3() { 069 log.debug(MOMENTARY_FUNCTION_REQUEST_NOT_SUPPORTED_BY_ELITE); 070 } 071 072 /** 073 * Send the XpressNet message to set the momentary state of functions F13, 074 * F14, F15, F16, F17, F18, F19, F20. 075 */ 076 @Override 077 protected void sendMomentaryFunctionGroup4() { 078 log.debug(MOMENTARY_FUNCTION_REQUEST_NOT_SUPPORTED_BY_ELITE); 079 } 080 081 /** 082 * Send the XpressNet message to set the momentary state of functions F21, 083 * F22, F23, F24, F25, F26, F27, F28. 084 */ 085 @Override 086 protected void sendMomentaryFunctionGroup5() { 087 log.debug(MOMENTARY_FUNCTION_REQUEST_NOT_SUPPORTED_BY_ELITE); 088 } 089 090 /** 091 * Send a request to get the status of functions from the command station. 092 */ 093 @Override 094 protected synchronized void sendFunctionStatusInformationRequest() { 095 log.debug(MOMENTARY_FUNCTION_REQUEST_NOT_SUPPORTED_BY_ELITE); 096 } 097 098 /** 099 * Handle incoming messages for this throttle. 100 */ 101 @Override 102 public void message(XNetReply l) { 103 // First, we want to see if this throttle is waiting for a message 104 //or not. 105 log.debug("Throttle - received message "); 106 if (requestState == THROTTLEIDLE) { 107 log.debug("Current throttle status is THROTTLEIDLE"); 108 // We haven't sent anything, but we might be told someone else 109 // has taken over this address 110 if (l.getElement(0) == 0xE5) { 111 log.debug("Throttle - message is LOCO_INFO_RESPONSE "); 112 if (l.getElement(1) == 0xF8) { 113 /* This is a Hornby Elite specific response 114 * which occurs when the Elite throttle changes 115 * speed. If this is for this throttle, 116 * we need to handle it. 117 * The address is in bytes 3 and 4*/ 118 if (getDccAddressHigh() == l.getElement(2) && getDccAddressLow() == l.getElement(3)) { 119 //Set the Is available flag to "False" 120 log.info("Loco {} in use by another device", getDccAddress()); 121 setIsAvailable(false); 122 // Set the speed step mode and availabliity 123 // from byte 5 124 parseSpeedAndAvailability(l.getElement(4)); 125 // Parse the speed step and direction from 126 // byte 6. 127 parseSpeedAndDirection(l.getElement(5)); 128 } 129 } else if (l.getElement(1) == 0xF9) { 130 /* This is a Hornby Elite specific response 131 * which occurs when the Elite throttle changes 132 * functions. If this is for this throttle, 133 * we need to handle it. 134 * The address is in bytes 3 and 4*/ 135 if (getDccAddressHigh() == l.getElement(2) && getDccAddressLow() == l.getElement(3)) { 136 // Set the Is available flag to "False" 137 log.info("Loco {} in use by another device", getDccAddress()); 138 setIsAvailable(false); 139 // Parse the function status from bytes 5 and 6. 140 parseFunctionInformation(l.getElement(4), 141 l.getElement(5)); 142 } 143 } 144 } 145 } 146 // We didn't find any Elite specific messages, so send the 147 // message on to the standard XpressNet throttle message handler 148 super.message(l); 149 } 150 151 /* 152 * Since the Elite sends status messages when the throttle changes, 153 * override the startStatusTimer/stopStatustimer method to do nothing. 154 */ 155 @Override 156 protected void startStatusTimer() { 157 // override default behavior 158 } 159 160 @Override 161 protected void stopStatusTimer() { 162 // override default behavior 163 } 164 165 // register for notification 166 private static final Logger log = LoggerFactory.getLogger(EliteXNetThrottle.class); 167 168}