001package jmri.jmrix.roco.z21; 002 003import javax.annotation.Nonnull; 004import jmri.Turnout; 005import jmri.jmrix.lenz.XNetReply; 006import jmri.jmrix.lenz.XNetSystemConnectionMemo; 007import jmri.jmrix.lenz.XNetTurnoutManager; 008import org.slf4j.Logger; 009import org.slf4j.LoggerFactory; 010 011/** 012 * Implement z21 turnout manager. 013 * <p> 014 * System names are "XTnnn", where X is the user-configurable system prefix, 015 * nnn is the turnout number without padding. 016 * 017 * @author Paul Bender Copyright (C) 2016 018 */ 019public class Z21XNetTurnoutManager extends XNetTurnoutManager { 020 021 public Z21XNetTurnoutManager(XNetSystemConnectionMemo memo) { 022 super(memo); 023 } 024 025 // XNet-specific methods 026 027 /** 028 * {@inheritDoc} 029 */ 030 @Nonnull 031 @Override 032 protected Turnout createNewTurnout(@Nonnull String systemName, String userName) throws IllegalArgumentException { 033 int addr; 034 try { 035 addr = Integer.parseInt(systemName.substring(getSystemPrefix().length() + 1)); 036 } catch (NumberFormatException e) { 037 throw new IllegalArgumentException("Failed to convert systemName '"+systemName+"' to a numeric Turnout address"); 038 } 039 Turnout t = new Z21XNetTurnout(getSystemPrefix(), addr, tc); 040 t.setUserName(userName); 041 return t; 042 } 043 044 @Override 045 public boolean allowMultipleAdditions(@Nonnull String systemName) { 046 return true; 047 } 048 049 // listen for turnouts, creating them as needed 050 @Override 051 public void message(XNetReply l) { 052 log.debug("received message: {}", l); 053 if (l.getElement(0)==Z21Constants.LAN_X_TURNOUT_INFO) { 054 // bytes 2 and 3 are the address. 055 int address = (l.getElement(1) << 8) + l.getElement(2); 056 // the address sent byte the Z21 is one less than what JMRI's 057 // XpressNet code (and lenz systems) expect. 058 address = address + 1; 059 log.debug("message has address: {}", address); 060 // make sure we know about this turnout. 061 String s = getSystemNamePrefix() + address; 062 forwardMessageToTurnout(s,l); 063 } else { 064 super.message(l); // let the XpressNetTurnoutManager code 065 // handle any other replies. 066 } 067 } 068 069 @Override 070 protected void forwardMessageToTurnout(String s, XNetReply l){ 071 Z21XNetTurnout t = (Z21XNetTurnout) getBySystemName(s); 072 if ( null == t ) { 073 // need to create a new one, and send the message on 074 // to the newly created object. 075 ((Z21XNetTurnout) provideTurnout(s)).initMessageZ21(l); 076 } else { 077 // The turnout exists, forward this message to the 078 // turnout 079 t.message(l); 080 } 081 } 082 083 /** 084 * {@inheritDoc} 085 */ 086 @Override 087 @Nonnull 088 public String validateSystemNameFormat(@Nonnull String systemName, @Nonnull java.util.Locale locale) { 089 return this.validateSystemNameFormatOnlyNumeric(systemName, locale); 090 } 091 092 private static final Logger log = LoggerFactory.getLogger(Z21XNetTurnoutManager.class); 093 094}