001package jmri.jmrix.can.cbus.node; 002 003import javax.annotation.CheckForNull; 004 005import jmri.PowerManager; 006import jmri.jmrix.can.CanSystemConnectionMemo; 007import jmri.jmrix.can.cbus.CbusPowerManager; 008 009import org.slf4j.Logger; 010import org.slf4j.LoggerFactory; 011 012/** 013 * Class to represent a node. 014 * 015 * @author Steve Young Copyright (C) 2019 016 */ 017public class CbusBasicNodeWithMgrsCommandStation extends CbusBasicNodeWithManagers { 018 019 private int _csNum; 020 private boolean _StatResponseFlagsAccurate; 021 private int _csFlags; 022 023 /** 024 * Create a new CbusBasicNode with Managers and Command Station 025 * 026 * @param connmemo The CAN Connection to use 027 * @param nodenumber The Node Number 028 */ 029 public CbusBasicNodeWithMgrsCommandStation( @CheckForNull CanSystemConnectionMemo connmemo, int nodenumber) { 030 super(connmemo, nodenumber); 031 _csNum = -1; 032 _csFlags = -1; 033 _StatResponseFlagsAccurate = false; 034 } 035 036 /** 037 * Set a Command Station Number for this Node 038 * 039 * @param csnum Command station Number, normally 0 if using a single command 040 * station 041 */ 042 public void setCsNum(int csnum) { 043 _csNum = csnum; 044 } 045 046 /** 047 * Get Command station number. 048 * <p> 049 * 0 is normally default for a command station 050 * 051 * @return -1 if node is NOT a Command Station, else CS Number. 052 */ 053 public int getCsNum() { 054 return _csNum; 055 } 056 057 /** 058 * Set the flags reported by a Command Station 059 * <p> 060 * This will update Track Power On / Off, etc. as per the values passed. 061 * Currently unused by CANCMD v4 which sets the 062 * setStatResponseFlagsAccurate(false) 063 * 064 * @param flags the int value of the Command Station flags 065 */ 066 public void setCsFlags(int flags) { 067 log.debug("flags value {}", flags); 068 069 // flags value in STAT response not accurate for CANCMD v4 070 if (!getStatResponseFlagsAccurate()) { 071 return; 072 } 073 _csFlags = flags; 074 075 // 0 - Hardware Error (self test) 076 // 1 - Track Error 077 // 2 - Track On/ Off 078 // 3 - Bus On/ Halted 079 // 4 - EM. Stop all performed 080 // 5 - Reset done 081 // 6 - Service mode (programming) On/ Off 082 checkSingleFlag(0, "Command Station {} Reporting Hardware Error (self test)"); 083 checkSingleFlag(1, "Command Station {} Reporting Track Error"); 084 085 // flag 2 handled by CbusPowerManager 086 // listening for RSTAT flag bit 2 here rather than power manager in case in future 087 // we can direct to power zones rather than whole layout power 088 // it's also a per command station report than a per layout report 089 // TODO: JMRI has multiple PowerManagers so let the correct PowerManager 090 // just handle this correctly instead of assuming that the default 091 // is a CbusPowerManager 092 setTrackPower(((flags >> 2) & 1) == 1); 093 094 checkSingleFlag(3, "Command Station {} Reporting Bus Halted"); 095 096 } 097 098 private void setTrackPower(boolean powerOn) { 099 CbusPowerManager pm = (CbusPowerManager) _memo.get(PowerManager.class); 100 pm.updatePower(powerOn ? PowerManager.ON : PowerManager.OFF); 101 } 102 103 private void checkSingleFlag(int flagNum, String errorText) { 104 if (((_csFlags >> flagNum) & 1) == 1) { 105 log.error("{} CS{} Node {}",errorText, getCsNum(), getNodeNumber()); 106 } 107 } 108 109 /** 110 * Set Disable Command Station Flag Reporting 111 * 112 * @param accurate set false to ignore the Command Station Flags 113 */ 114 public void setStatResponseFlagsAccurate(boolean accurate) { 115 _StatResponseFlagsAccurate = accurate; 116 } 117 118 /** 119 * Get if Command Station Flag Reporting is accurate. Defaults to false 120 * 121 * @return true if accurate, else false 122 */ 123 public boolean getStatResponseFlagsAccurate() { 124 return _StatResponseFlagsAccurate; 125 } 126 127 private static final Logger log = LoggerFactory.getLogger(CbusBasicNodeWithMgrsCommandStation.class); 128 129}