001package jmri.jmrix.ieee802154.xbee; 002 003import com.digi.xbee.api.exceptions.InterfaceNotOpenException; 004import com.digi.xbee.api.exceptions.TimeoutException; 005import com.digi.xbee.api.exceptions.XBeeException; 006import com.digi.xbee.api.io.IOLine; 007import com.digi.xbee.api.io.IOValue; 008import jmri.Light; 009import jmri.implementation.AbstractLight; 010import org.slf4j.Logger; 011import org.slf4j.LoggerFactory; 012 013/** 014 * Light implementation for XBee systems. 015 * 016 * @author Paul Bender Copyright (C) 2014 017 */ 018public class XBeeLight extends AbstractLight { 019 020 private String nodeIdentifier; /* This is a string representation of 021 the XBee address in the system name 022 It may be an address or it may be 023 the NodeIdentifier string stored in 024 the NI parameter on the node.*/ 025 026 private XBeeNode node = null; // Which node does this belong too. 027 028 private int address; 029 private int pin; /* Which DIO pin does this light represent. */ 030 031 private String systemName; 032 033 protected XBeeTrafficController tc = null; 034 035 /** 036 * Create a Light object, with system and user names and a reference to the 037 * traffic controller. 038 * @param systemName Xbee system id : pin id 039 * @param userName User friendly name 040 * @param controller tc for connection for this node 041 */ 042 public XBeeLight(String systemName, String userName, XBeeTrafficController controller) { 043 super(systemName, userName); 044 tc = controller; 045 init(systemName); 046 } 047 048 public XBeeLight(String systemName, XBeeTrafficController controller) { 049 super(systemName); 050 tc = controller; 051 init(systemName); 052 } 053 054 /** 055 * Common initialization for both constructors 056 */ 057 private void init(String id) { 058 // store address 059 systemName = id; 060 jmri.jmrix.ieee802154.IEEE802154SystemConnectionMemo m = tc.getAdapterMemo(); 061 if( !(m instanceof XBeeConnectionMemo)) 062 { 063 log.error("Memo associated with the traffic controller is not the right type"); 064 throw new IllegalArgumentException("Memo associated with the traffic controller is not the right type"); 065 } else { 066 XBeeConnectionMemo memo = (XBeeConnectionMemo) m; 067 String prefix = memo.getLightManager().getSystemPrefix(); 068 if (systemName.contains(":")) { 069 //Address format passed is in the form of encoderAddress:input or L:light address 070 int seperator = systemName.indexOf(":"); 071 try { 072 nodeIdentifier = systemName.substring(prefix.length() + 1, seperator); 073 if ((node = (XBeeNode) tc.getNodeFromName(nodeIdentifier)) == null) { 074 if ((node = (XBeeNode) tc.getNodeFromAddress(nodeIdentifier)) == null) { 075 try { 076 node = (XBeeNode) tc.getNodeFromAddress(Integer.parseInt(nodeIdentifier)); 077 } catch (java.lang.NumberFormatException nfe) { 078 // if there was a number format exception, we couldn't 079 // find the node. 080 node = null; 081 } 082 } 083 } 084 pin = Integer.parseInt(systemName.substring(seperator + 1)); 085 } catch (NumberFormatException ex) { 086 log.debug("Unable to convert {} into the cab and input format of nn:xx", systemName); 087 } 088 } else { 089 try { 090 nodeIdentifier = systemName.substring(prefix.length() + 1, id.length() - 1); 091 address = Integer.parseInt(systemName.substring(prefix.length() + 1)); 092 node = (XBeeNode) tc.getNodeFromAddress(address / 10); 093 // calculate the pin to use. 094 pin = ((address) % 10); 095 } catch (NumberFormatException ex) { 096 log.debug("Unable to convert {} Hardware Address to a number", systemName); 097 } 098 } 099 if (log.isDebugEnabled()) { 100 log.debug("Created Light {} (NodeIdentifier {} D{})", systemName, nodeIdentifier, pin); 101 } 102 } 103 } 104 105 @Override 106 protected void doNewState(int oldState, int newState) { 107 try { 108 if((newState == Light.ON) ) { 109 node.getXBee().setDIOValue(IOLine.getDIO(pin),IOValue.HIGH); 110 } else { 111 node.getXBee().setDIOValue(IOLine.getDIO(pin),IOValue.LOW); 112 } 113 } catch (TimeoutException toe) { 114 log.error("Timeout setting IO line value for light {} on {}",getUserName(),node.getXBee()); 115 } catch (InterfaceNotOpenException ino) { 116 log.error("Interface Not Open setting IO line value for light {} on {}",getUserName(),node.getXBee()); 117 } catch (XBeeException xbe) { 118 log.error("Error setting IO line value for light {} on {}",getUserName(),node.getXBee()); 119 } 120 } 121 122 private final static Logger log = LoggerFactory.getLogger(XBeeLight.class); 123}