001package jmri.jmrix.can.cbus.node; 002 003// import javax.annotation.Nonnull; 004import javax.annotation.CheckForNull; 005 006import jmri.jmrix.can.CanSystemConnectionMemo; 007 008import org.slf4j.Logger; 009import org.slf4j.LoggerFactory; 010 011/** 012 * Class to represent a node. 013 * 014 * @author Steve Young Copyright (C) 2019 015 */ 016public class CbusNode extends CbusBasicNodeWithMgrsCommandStation { 017 018 private int _flags; 019 private String _userComment; 020 private boolean _sendsWRACKonNVSET; 021 private boolean _nvWriteInLearnOnly; 022 private boolean _liveUpdate; 023 public static int SINGLE_MESSAGE_TIMEOUT_TIME = 1500; 024 public static int BOOT_PROG_TIMEOUT_FAST = 10; 025 public static int BOOT_PROG_TIMEOUT_SLOW = 50; 026 public static int BOOT_LONG_TIMEOUT_TIME = 1500; 027 private String _nodeNameFromName; 028 private String resyncName = null; 029 030 /** 031 * Create a new CbusNode 032 * 033 * @param connmemo The CAN Connection to use 034 * @param nodenumber The Node Number 035 */ 036 public CbusNode ( @CheckForNull CanSystemConnectionMemo connmemo, int nodenumber ){ 037 super(connmemo,nodenumber); 038 039 _sendsWRACKonNVSET = true; 040 _nvWriteInLearnOnly = false; 041 _liveUpdate = false; 042 _flags = -1; 043 _userComment = ""; 044 _nodeNameFromName = ""; 045 } 046 047 /** 048 * Set Node UserName only if UserName not currently set 049 * used in RestoreFromFCU 050 * @param newName UserName of the node 051 */ 052 public void setNameIfNoName( String newName ) { 053 if ( getUserName().isEmpty() ){ 054 setUserName(newName); 055 } 056 } 057 058 /** 059 * Get Module Type Name from a previous NAME OPC response 060 * Used when a module type is not identified within JMRI. 061 * @return Module type name, NOT prefixed with CAN or ETH, may be empty. 062 */ 063 public String getNodeNameFromName(){ 064 return _nodeNameFromName; 065 } 066 067 /** 068 * Set Module Type Name 069 * Used when a module is not identified within JMRI so the NAME is requested. 070 * @param newName The module type name, should NOT be prefixed with CAN or ETH 071 */ 072 public void setNodeNameFromName( String newName ){ 073 if (newName==null) { 074 newName = ""; 075 } 076 _nodeNameFromName = newName; 077 notifyPropertyChangeListener("NAMECHANGE", null, null); 078 } 079 080 /** 081 * Set the Node Flags 082 * <p> 083 * Bit 0: Consumer 084 * Bit 1: Producer 085 * Bit 2: FLiM Mode 086 * Bit 3: The module supports bootloading 087 * Bit 4: The module can consume its own produced events 088 * Bit 5: Module is in learn mode - CBUS Spec 6c 089 * 090 * @param flags the int value of the flags. 091 */ 092 public void setNodeFlags(int flags) { 093 _flags = flags; 094 // if ( ( ( _flags >> 0 ) & 1 ) == 1 ){ 095 // log.debug("Consumer node"); 096 // } 097 098 if ( ( ( _flags >> 2 ) & 1 ) == 0 ){ 099 getNodeBackupManager().setNodeInSlim(); 100 getNodeEventManager().resetNodeEventsToZero(); // sets num events to 0 101 } 102 103 if ( ( ( _flags >> 5 ) & 1 ) == 1 ){ 104 log.debug("Node in learn mode"); 105 setNodeInLearnMode(true); 106 } 107 notifyPropertyChangeListener("PARAMETER", null, null); 108 } 109 110 /** 111 * Get Node Flags 112 * <p> 113 * Captured from a PNN node response 114 * @return flags in int form, will need decoding to bit, -1 if unset 115 */ 116 public int getNodeFlags() { 117 return _flags; 118 } 119 120 /** 121 * Get name of node being resync'ed 122 * 123 * @return String node name 124 */ 125 public String getResyncName() { 126 return resyncName; 127 } 128 129 /** 130 * Save module name when Resync is in progress 131 * 132 * Resync resets all node parameters, etc. To re0display the NV edit GUI 133 * before the resync completes we save a copy of the name of the node. 134 */ 135 protected void saveForResync() { 136 if (!CbusNodeConstants.getModuleType(this.getNodeParamManager().getParameter(1),this.getNodeParamManager().getParameter(3)).isEmpty() ){ 137 resyncName = CbusNodeConstants.getModuleType(this.getNodeParamManager().getParameter(1),this.getNodeParamManager().getParameter(3)); 138 } else { 139 resyncName = null; 140 } 141 } 142 143 /** 144 * Resets NV's, Events and Parameters 145 * 146 */ 147 protected void resetNodeAll() { 148 getNodeNvManager().reset(); 149 getNodeEventManager().resetNodeEvents(); 150 getNodeParamManager().clearParameters(); 151 getNodeTimerManager().resetTimeOutCounts(); 152 notifyPropertyChangeListener("PARAMETER", null, null); 153 } 154 155 /** 156 * Get a Node User Comment 157 * @return user generated comment string 158 * 159 */ 160 public String getUserComment() { 161 return _userComment; 162 } 163 164 /** 165 * Set a Node User Comment 166 * <p> 167 * Typically output from JTextArea 168 * <p> 169 * If a backup has completed for this session, updates the xml file 170 * 171 * @param comment user comment 172 */ 173 public void setUserComment(String comment) { 174 _userComment = comment; 175 if (getNodeBackupManager().getBackupStarted()) { 176 if (!getNodeBackupManager().doStore(false,getNodeStats().hasLoadErrors()) ) { 177 log.error("Unable to save User Comment to Node Backup File"); 178 } 179 } 180 } 181 182 /** 183 * Custom toString reports the Node Number Name 184 * @return string eg "1234 UserName" or "256 CANPAN" if no UserName. No trailing space. 185 * 186 * {@inheritDoc} 187 */ 188 @Override 189 public String toString(){ 190 return getNodeStats().getNodeNumberName(); 191 } 192 193 /** 194 * Reports just the name, not the user name. 195 * 196 * @return string eg "CANPAN" 197 * 198 */ 199 public String getName(){ 200 return getNodeStats().getNodeTypeName(); 201 } 202 203 /** 204 * Set node on network 205 * @param isFound false if not on network 206 */ 207 protected void nodeOnNetwork( boolean isFound ) { 208 209 if (!isFound) { 210 getNodeTimerManager().cancelTimers(); 211 getNodeParamManager().setParameters( new int[]{0} ); 212 213 // set events to 0 as if parameters cannot be fetched, 214 // no point in attempting anything else 215 getNodeEventManager().resetNodeEventsToZero(); 216 // if not already set as not on network, set that now 217 if ( !(getNodeBackupManager().getSessionBackupStatus() == CbusNodeConstants.BackupType.NOTONNETWORK )) { 218 getNodeBackupManager().nodeNotOnNetwork(); 219 } 220 notifyPropertyChangeListener("BACKUPS", null, null); 221 } 222 } 223 224 /** 225 * DO NOT RELY ON, TO BE REMOVED IN FUTURE RELEASE 226 * when the NV will automatically be queried if no NVSET is received 227 * 228 * @param sendsWRACK true if sends 229 */ 230 public void setsendsWRACKonNVSET( Boolean sendsWRACK ){ 231 _sendsWRACKonNVSET = sendsWRACK; 232 } 233 234 235 236 /** 237 * DO NOT RELY ON, TO BE REMOVED IN FUTURE RELEASE 238 * when the NV will automatically be queried if no NVSET is received 239 * 240 * @return true if sends WRACK, else false 241 */ 242 public boolean getsendsWRACKonNVSET() { 243 return _sendsWRACKonNVSET; 244 } 245 246 247 /** 248 * CANSERVO8C and related modules only accept NV writes in learn mode. 249 * 250 * This was used by the MERG FCU to update servo positions in "real time" in 251 * response to interaction with the GUI. Call this method to indicate that a 252 * node must be in learn mode to support NV writes. 253 * 254 * @param nvWriteInLearn true if node requires to be in learn mode for NV writes 255 */ 256 public void setnvWriteInLearnOnly( Boolean nvWriteInLearn ){ 257 _nvWriteInLearnOnly = nvWriteInLearn; 258 } 259 260 /** 261 * CANSERVO8C and related modules only accept NV writes in learn mode. 262 * 263 * This was used by the MERG FCU to update servo positions in "real time" in 264 * response to interaction with the GUI. Call this method to query if a 265 * node must be in learn mode to support NV writes. 266 * 267 * @return true if sends WRACK, else false 268 */ 269 public boolean getnvWriteInLearnOnly() { 270 return _nvWriteInLearnOnly; 271 } 272 273 /** 274 * Set flag to say node is in live update mode. 275 * 276 * @param liveUpdate true if in live update mode 277 */ 278 public void setliveUpdate(boolean liveUpdate) { 279 _liveUpdate = liveUpdate; 280 } 281 282 /** 283 * Get live update mode 284 * 285 * @return true in live update 286 */ 287 public boolean getliveUpdate() { 288 return _liveUpdate; 289 } 290 291 private static final Logger log = LoggerFactory.getLogger(CbusNode.class); 292 293}