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