001package jmri.jmrix.loconet; 002 003import jmri.implementation.DefaultCabSignal; 004import jmri.LocoAddress; 005import jmri.SignalMast; 006import org.slf4j.Logger; 007import org.slf4j.LoggerFactory; 008 009/** 010 * Ln implementation of a Cab Signal Object, describing the state of the 011 * track ahead relative to a locomotive with a given address. This is 012 * effectively a mobile signal mast. 013 * 014 * @author Steve Young Copyright (C) 2018 015 * @author Paul Bender Copyright (C) 2019 016 */ 017public class LnCabSignal extends DefaultCabSignal { 018 019 private LocoNetSystemConnectionMemo _memo = null; 020 021 public LnCabSignal(LocoNetSystemConnectionMemo memo,LocoAddress address){ 022 super(address); 023 _memo = memo; 024 log.debug("created cab signal for {}",address); 025 } 026 027 /** 028 * A method for cleaning up the cab signal 029 */ 030 @Override 031 public void dispose(){ 032 super.dispose(); 033 _memo=null; 034 } 035 036 /** 037 * Forward the command to the layout that sets the displayed signal 038 * aspect for this address 039 */ 040 @Override 041 protected void forwardAspectToLayout(){ 042 LocoAddress locoaddr = getCabSignalAddress(); 043 SignalMast mast = getNextMast(); 044 // adapted from cabsignaller.py by Nigel Cliffe 045 // Message variables are Loco = Decimal loco address, 046 047 // Calculate the two byte loco address value 048 int locoD1 = locoaddr.getNumber() / 128; //integer division, automatically rounds 049 int locoD2 = locoaddr.getNumber() % 128; //modulo division, gets the remainder. 050 // determine the mast 051 // others are binary 1 or 0 052 // bit 4 = 1 show mast, bit 4 = 0 hide mast. 053 // bit 3 = 1 show vertical, bit 3 = 0 hide vertical 054 // bit 2 = 1 show diagonal, bit 2 = 0 hide diagonal 055 // bit 1 = 1 show horizontal, bit 1 = 0 hide horizontal 056 // bit 0 = 1 blink, bit 0 = 0 no blink 057 int signalD3=0; // default case, off. 058 059 if(mast!=null){ 060 String speed = (String) mast.getSignalSystem().getProperty(mast.getAspect(), "speed"); 061 // set aspect based on signal "speed" first. 062 switch(speed) { 063 case "Normal": 064 case "Clear": 065 signalD3 = 0x18; // show vertical; 066 break; 067 case "Limited": 068 signalD3 = 0x19; // show vertical blinking; 069 break; 070 case "Medium": 071 signalD3 = 0x14; // show diagonal; 072 break; 073 case "Stop": 074 signalD3 = 0x12; // show horizontal (stop); 075 break; 076 case "Restricting": 077 case "RestrictedSlow": 078 case "Restricted": 079 case "Slow": 080 signalD3 = 0x13; // blink horizontal 081 break; 082 default: { 083 // if no matching speed in the list above, check for 084 // the constant values in the SignalAppearanceMap. 085 if(mast.getAspect().equals(mast.getAppearanceMap().getSpecificAppearance(jmri.SignalAppearanceMap.PERMISSIVE))){ 086 signalD3 = 0x18; // show vertical; 087 } else if(mast.getAspect().equals(mast.getAppearanceMap().getSpecificAppearance(jmri.SignalAppearanceMap.DANGER))){ 088 signalD3 = 0x12; // show horizontal (stop); 089 } else if(mast.getAspect().equals(mast.getAppearanceMap().getSpecificAppearance(jmri.SignalAppearanceMap.HELD))){ 090 signalD3 = 0x12; // show horizontal (stop); 091 } else if(mast.getAspect().equals(mast.getAppearanceMap().getSpecificAppearance(jmri.SignalAppearanceMap.DARK))){ 092 signalD3 = 0x00; // show nothing; 093 } else { 094 signalD3 = 0x14; // show diagonal;*/ 095 } 096 } 097 } 098 } 099 // this is a litteral translation from the script. it should be 100 // created from a method in LocoNetMessage. 101 LocoNetMessage peerXFerMessage = new LocoNetMessage(16); 102 peerXFerMessage.setOpCode(229); 103 peerXFerMessage.setElement(1,16); 104 peerXFerMessage.setElement(2,127); 105 peerXFerMessage.setElement(3,0); 106 peerXFerMessage.setElement(4,0); 107 peerXFerMessage.setElement(5,0); 108 peerXFerMessage.setElement(6,locoD1); 109 peerXFerMessage.setElement(7,locoD2); 110 peerXFerMessage.setElement(8,signalD3); 111 peerXFerMessage.setElement(9,0); 112 peerXFerMessage.setElement(10,112); 113 peerXFerMessage.setElement(11,0); 114 peerXFerMessage.setElement(12,0); 115 peerXFerMessage.setElement(13,0); 116 peerXFerMessage.setElement(14,0); 117 peerXFerMessage.setElement(15,0); 118 119 _memo.getLnTrafficController().sendLocoNetMessage(peerXFerMessage); 120 } 121 122 /** 123 * Forward the command to the layout that clears any displayed signal 124 * for this address 125 */ 126 @Override 127 protected void resetLayoutCabSignal(){ 128 LocoAddress locoaddr = getCabSignalAddress(); 129 // Calculate the two byte loco address value 130 int locoD1 = locoaddr.getNumber() / 128; //integer division, automatically rounds 131 int locoD2 = locoaddr.getNumber() % 128; //modulo division, gets the remainder. 132 int signalD3=0; // off. 133 134 LocoNetMessage peerXFerMessage = new LocoNetMessage(16); 135 peerXFerMessage.setOpCode(229); 136 peerXFerMessage.setElement(1,16); 137 peerXFerMessage.setElement(2,127); 138 peerXFerMessage.setElement(3,0); 139 peerXFerMessage.setElement(4,0); 140 peerXFerMessage.setElement(5,0); 141 peerXFerMessage.setElement(6,locoD1); 142 peerXFerMessage.setElement(7,locoD2); 143 peerXFerMessage.setElement(8,signalD3); 144 peerXFerMessage.setElement(9,0); 145 peerXFerMessage.setElement(10,112); 146 peerXFerMessage.setElement(11,0); 147 peerXFerMessage.setElement(12,0); 148 peerXFerMessage.setElement(13,0); 149 peerXFerMessage.setElement(14,0); 150 peerXFerMessage.setElement(15,0); 151 _memo.getLnTrafficController().sendLocoNetMessage(peerXFerMessage); 152 } 153 154 private final static Logger log = LoggerFactory.getLogger(LnCabSignal.class); 155 156 157}