001package jmri.jmrix.oaktree; 002 003import jmri.Turnout; 004import jmri.implementation.AbstractTurnout; 005import org.slf4j.Logger; 006import org.slf4j.LoggerFactory; 007 008/** 009 * Extend jmri.AbstractTurnout for Oak Tree serial layouts. 010 * 011 * This object doesn't listen to the Oak Tree serial communications. This is 012 * because it should be the only object that is sending messages for this 013 * turnout; more than one Turnout object pointing to a single device is not 014 * allowed. 015 * 016 * @author Bob Jacobsen Copyright (C) 2003, 2006 017 */ 018public class SerialTurnout extends AbstractTurnout { 019 020 private OakTreeSystemConnectionMemo _memo = null; 021 022 /** 023 * Create a Turnout object, with both system and user names. 024 * <p> 025 * 'systemName' was previously validated in SerialTurnoutManager 026 * @param systemName turnout system name 027 * @param userName turnout user name 028 * @param memo system connection 029 */ 030 public SerialTurnout(String systemName, String userName, OakTreeSystemConnectionMemo memo) { 031 super(systemName, userName); 032 // Save system Name 033 tSystemName = systemName; 034 _memo = memo; 035 // Extract the Bit from the name 036 tBit = SerialAddress.getBitFromSystemName(systemName, _memo.getSystemPrefix()); 037 } 038 039 /** 040 * {@inheritDoc} 041 */ 042 @Override 043 protected void forwardCommandChangeToLayout(int newState) { 044 // implementing classes will typically have a function/listener to get 045 // updates from the layout, which will then call 046 // public void firePropertyChange(String propertyName, 047 // Object oldValue, 048 // Object newValue) 049 // _once_ if anything has changed state (or set the commanded state directly) 050 051 // sort out states 052 if ((newState & Turnout.CLOSED) != 0) { 053 // first look for the double case, which we can't handle 054 if ((newState & Turnout.THROWN) != 0) { 055 // this is the disaster case! 056 log.error("Cannot command both CLOSED and THROWN {}", newState); 057 return; 058 } else { 059 // send a CLOSED command 060 sendMessage(!getInverted()); 061 } 062 } else { 063 // send a THROWN command 064 sendMessage(getInverted()); 065 } 066 } 067 068 @Override 069 protected void turnoutPushbuttonLockout(boolean _pushButtonLockout) { 070 log.debug("Send command to {} Pushbutton", (_pushButtonLockout ? "Lock" : "Unlock")); 071 } 072 073 // data members 074 String tSystemName; // System Name of this turnout 075 int tBit; // bit number of turnout control in Serial node 076 077 protected void sendMessage(boolean closed) { 078 SerialNode tNode = SerialAddress.getNodeFromSystemName(tSystemName, _memo.getTrafficController()); 079 if (tNode == null) { 080 // node does not exist, ignore call 081 return; 082 } 083 tNode.setOutputBit(tBit, closed); 084 } 085 086 private final static Logger log = LoggerFactory.getLogger(SerialTurnout.class); 087 088}