001package jmri.jmrix.can.cbus.simulator; 002 003import java.util.ArrayList; 004import java.util.concurrent.ThreadLocalRandom; 005 006import jmri.jmrix.AbstractMessage; 007import jmri.jmrix.can.CanReply; 008import jmri.jmrix.can.CanSystemConnectionMemo; 009import jmri.jmrix.can.cbus.CbusConstants; 010import jmri.jmrix.can.cbus.CbusMessage; 011import jmri.jmrix.can.cbus.CbusOpCodes; 012 013import org.slf4j.Logger; 014import org.slf4j.LoggerFactory; 015 016/** 017 * Simulating event request responses. 018 * 019 * @author Steve Young Copyright (C) 2018 020 * @see CbusSimulator 021 * @since 4.15.2 022 */ 023public class CbusEventResponder extends CbusSimCanListener { 024 025 private int _node; 026 private int _mode; 027 028 public ArrayList<String> evModes; 029 public ArrayList<String> evModesTip; 030 031 public CbusEventResponder( CanSystemConnectionMemo memod ){ 032 super(memod,null); 033 init(); 034 } 035 036 private void init(){ 037 _mode = 1; 038 _node = -1; 039 setDelay(50); 040 041 evModes = new ArrayList<>(); 042 evModesTip = new ArrayList<>(); 043 044 evModes.add(Bundle.getMessage("HighlightDisabled")); 045 evModesTip.add(null); 046 047 evModes.add(Bundle.getMessage("onOffRand")); 048 evModesTip.add(null); 049 050 evModes.add(Bundle.getMessage("odOnEvOff")); 051 evModesTip.add(null); 052 053 evModes.add(Bundle.getMessage("CbusEventOn")); 054 evModesTip.add(null); 055 056 evModes.add(Bundle.getMessage("CbusEventOff")); 057 evModesTip.add(null); 058 059 log.info("Simulated Event Responses: {}", evModes.get(_mode) ); 060 } 061 062 public void setMode(int mode){ 063 _mode = mode; 064 } 065 066 public int getMode() { 067 return _mode; 068 } 069 070 public void setNode(int node){ 071 _node = node; 072 } 073 074 public int getNode() { 075 return _node; 076 } 077 078 @Override 079 protected void startProcessFrame(AbstractMessage m) { 080 if (!CbusOpCodes.isEventRequest(m.getElement(0)) 081 || ( _mode == 0 ) 082 || ( _node != -1 && _node != CbusMessage.getNodeNumber(m) ) ) { 083 return; 084 } 085 086 int newopc = CbusConstants.CBUS_AROF; 087 if ( CbusMessage.getOpcode(m) == CbusConstants.CBUS_ASRQ ) { 088 if (getOnOrOffFromMode(m)) { 089 newopc = CbusConstants.CBUS_ARSON; 090 } else { 091 newopc = CbusConstants.CBUS_ARSOF; 092 } 093 } 094 else if (getOnOrOffFromMode(m)) { 095 newopc = CbusConstants.CBUS_ARON; 096 } 097 sendResponse(newopc,m); 098 } 099 100 private void sendResponse( int newopc, AbstractMessage m){ 101 CanReply r = new CanReply(5); 102 r.setNumDataElements(5); 103 r.setElement(0, newopc); 104 r.setElement(1, m.getElement(1)); 105 r.setElement(2, m.getElement(2)); 106 r.setElement(3, m.getElement(3)); 107 r.setElement(4, m.getElement(4)); 108 send.sendWithDelay(r,getSendIn(),getSendOut(),getDelay()); 109 } 110 111 private boolean getOnOrOffFromMode( AbstractMessage m ){ 112 boolean sendOn = false; 113 switch (_mode) { 114 case 1: // random 115 sendOn = ThreadLocalRandom.current().nextBoolean(); 116 break; 117 case 2: // Odd On / Even Off 118 sendOn = m.getElement(4) % 2 != 0; 119 break; 120 case 3: // on 121 sendOn = true; 122 break; 123 case 4: // off 124 sendOn = false; 125 break; 126 default: 127 break; 128 } 129 return sendOn; 130 } 131 132 private static final Logger log = LoggerFactory.getLogger(CbusEventResponder.class); 133 134}