001package jmri.jmrix.grapevine; 002 003import jmri.implementation.DefaultSignalHead; 004import org.slf4j.Logger; 005import org.slf4j.LoggerFactory; 006 007/** 008 * Extend jmri.AbstractSignalHead for grapevine serial signals. 009 * 010 * This object doesn't listen to the Grapevine serial communications. It 011 * probably should, however, in case. 012 * 013 * @author Bob Jacobsen Copyright (C) 2003, 2006, 2007 014 */ 015public class SerialSignalHead extends DefaultSignalHead { 016 017 GrapevineSystemConnectionMemo memo = null; 018 019 /** 020 * Create a SignalHead object, with only system name. 021 * 022 * @param systemName system name including prefix, should have ben previously validated 023 * @param _memo the associated SystemConnectionMemo 024 */ 025 public SerialSignalHead(String systemName, GrapevineSystemConnectionMemo _memo) { 026 super(systemName); 027 memo = _memo; 028 // Save system Name 029 tSystemName = systemName; 030 // Extract the Bit from the name 031 int num = SerialAddress.getBitFromSystemName(systemName, memo.getSystemPrefix()); // bit one is address zero 032 // num is 101-124, 201-224, 301-324, 401-424 033 output = (num % 100) - 1; // 0-23 034 bank = (num / 100) - 1; // 0 - 3 035 } 036 037 /** 038 * Create a SignalHead object, with both system and user names. 039 * 040 * @param systemName system name including prefix, should have ben previously validated 041 * @param userName free form name 042 * @param _memo the associated SystemConnectionMemo 043 */ 044 public SerialSignalHead(String systemName, String userName, GrapevineSystemConnectionMemo _memo) { 045 super(systemName, userName); 046 memo = _memo; 047 // Save system Name 048 tSystemName = systemName; 049 // Extract the Bit from the name 050 int num = SerialAddress.getBitFromSystemName(systemName, memo.getSystemPrefix()); // bit one is address zero 051 // num is 101-124, 201-224, 301-324, 401-424 052 output = (num % 100) - 1; // 0-23 053 bank = (num / 100) - 1; // 0 - 3 054 } 055 056 /** 057 * Handle a request to change state on layout 058 */ 059 @Override 060 protected void updateOutput() { 061 SerialNode tNode = SerialAddress.getNodeFromSystemName(tSystemName, memo.getTrafficController()); 062 if (tNode == null) { 063 // node does not exist, ignore call 064 log.error("Can't find node for {}, command ignored", tSystemName); 065 return; 066 } 067 068 boolean high = (output >= 12); 069 int tOut = output; 070 if (high) { 071 tOut = output - 12; 072 } 073 if ((bank < 0) || (bank > 4)) { 074 log.error("invalid bank {} for signal {}", bank, getSystemName()); 075 bank = 0; 076 } 077 078 // sort out states 079 int cmd; 080 if (mLit) { 081 switch (mAppearance) { 082 case RED: 083 cmd = 6; 084 break; 085 case FLASHRED: 086 cmd = 7; 087 break; 088 case YELLOW: 089 cmd = 2; 090 break; 091 case FLASHYELLOW: 092 cmd = 3; 093 break; 094 case GREEN: 095 cmd = 0; 096 break; 097 case FLASHGREEN: 098 cmd = 1; 099 break; 100 case DARK: 101 cmd = 4; 102 break; 103 default: 104 log.warn("Unexpected new appearance: {}", mAppearance); 105 cmd = 7; 106 break; // flash red for error 107 } 108 } else { 109 cmd = 4; // set dark if not lit 110 } 111 112 SerialMessage m = new SerialMessage(high ? 8 : 4); 113 int i = 0; 114 if (high) { 115 m.setElement(i++, tNode.getNodeAddress() | 0x80); // address 1 116 m.setElement(i++, 122); // shift command 117 m.setElement(i++, tNode.getNodeAddress() | 0x80); // address 2 118 m.setElement(i++, 0x10); // bank 1 119 m.setParity(i - 4); 120 } 121 m.setElement(i++, tNode.getNodeAddress() | 0x80); // address 1 122 m.setElement(i++, (tOut << 3) | cmd); 123 m.setElement(i++, tNode.getNodeAddress() | 0x80); // address 2 124 m.setElement(i++, bank << 4); // bank is most significant bits 125 m.setParity(i - 4); 126 memo.getTrafficController().sendSerialMessage(m, null); 127 } 128 129 // flashing is done on the cards, so we don't have to 130 // do it manually 131 @Override 132 public void startFlash() { 133 } 134 135 @Override 136 public void stopFlash() { 137 } 138 139 // data members 140 String tSystemName; // System Name of this signal head 141 int output; // output connector number, 0-23 142 int bank; // bank number, 0-3 143 144 private final static Logger log = LoggerFactory.getLogger(SerialSignalHead.class); 145 146}