001package jmri.jmrix.can.cbus.node; 002 003import java.util.Arrays; 004import java.util.Objects; 005import jmri.util.StringUtil; 006 007import org.slf4j.Logger; 008import org.slf4j.LoggerFactory; 009 010/** 011 * Class to represent an event stored on a node. 012 * <p> 013 * Custom Equals method 014 * 015 * @author Steve Young Copyright (C) 2019 016 */ 017public class CbusNodeEvent extends CbusBasicNodeEvent implements Comparable<CbusNodeEvent> { 018 019 private int[] _evVarArr; 020 021 /** 022 * Set the value of the event variable array by index 023 * 024 * @param memo CAN System Connection 025 * @param nn Event node Number 026 * @param en Event event or device number 027 * @param thisnode Host node number 028 * @param index number assigned by node, -1 if unknown 029 * @param maxEvVar Maximum event variables for the event 030 */ 031 public CbusNodeEvent( jmri.jmrix.can.CanSystemConnectionMemo memo, int nn, int en, int thisnode, int index, int maxEvVar){ 032 super(memo,nn,en,thisnode,index); 033 _evVarArr = new int[Math.max(maxEvVar, 0)]; 034 java.util.Arrays.fill(_evVarArr,-1); 035 } 036 037 protected CbusNodeEvent( int nn, int en, int thisnode, String eventString ){ 038 super(null,nn,en,thisnode,-1); 039 _evVarArr = StringUtil.intBytesWithTotalFromNonSpacedHexString(eventString,false); 040 setTempFcuNodeName(null); 041 } 042 043 protected CbusNodeEvent( CbusNodeEvent existing ) { 044 super(null,existing.getNn(),existing.getEn(),existing.getParentNn(),existing.getIndex()); 045 setEvArr( Arrays.copyOf( 046 existing.getEvVarArray(), 047 existing.getEvVarArray().length) ); 048 setTempFcuNodeName ( existing.getTempFcuNodeName()); 049 050 } 051 052 /** 053 * Set the value of the event variable array by index 054 * 055 * @param index event variable index, minimum 1 056 * @param value min 0 max 255 057 */ 058 public void setEvVar(int index, int value) { 059 if ( index < 1 ) { 060 log.error("Event Index needs to be more than 0"); 061 return; 062 } 063 if ( _evVarArr == null || index > _evVarArr.length ) { 064 log.error("Event Variable Index {} out of range, {} has {} Event Variables", 065 index, this, getNumEvVars() ); 066 return; 067 } 068 if (value > 255 ) { 069 log.error("Event Variable value needs to be less than 255 (oxff)"); 070 return; 071 } 072 _evVarArr[(index-1)]=value; 073 notifyModel(); 074 075 } 076 077 /** 078 * Set the value of the event variable array by existing array 079 * 080 * @param newArray event variable array, 1st value index 0 should be 1st event value, NOT total 081 */ 082 public final void setEvArr( int[] newArray ){ 083 _evVarArr = newArray; 084 notifyModel(); 085 } 086 087 /** 088 * Returns the value of an event variable 089 * 090 * @param index of the variable, no array offset needed, 1 is 1 091 * @return the decimal event indexed variable value, -1 if unknown or index out of range 092 */ 093 public int getEvVar(int index) { 094 if ( _evVarArr == null || index < 1 || index > _evVarArr.length ) { 095 log.error("Event Variable Index {} out of range, {} has {} Event Variables", 096 index, this, getNumEvVars() ); 097 return -1; 098 } 099 return _evVarArr[(index-1)]; 100 } 101 102 public int[] getEvVarArray() { 103 return _evVarArr; 104 } 105 106 /** 107 * Returns all event variables as a single string 108 * <p> 109 * eg. /"1, 13, 1, 0, 0/" 110 * 111 * @return the decimal string for of the array, unknown values are blanked 112 */ 113 public String getEvVarString(){ 114 StringBuilder n = new StringBuilder(); 115 // n.append("[ "); 116 for(int i = 0; i< _evVarArr.length; i++){ 117 if ( _evVarArr[i] > -1 ) { 118 n.append( _evVarArr[i] ); 119 } 120 else { 121 n.append( " " ); 122 } 123 if ( i != ( _evVarArr.length-1 ) ) { 124 n.append( ", " ); 125 } 126 } 127 // n.append(" ]"); 128 return n.toString(); 129 } 130 131 /** 132 * Returns all event variables as a single hex string 133 * <p> 134 * eg. returns 0104D6A0 135 * 136 * @return the hex string for of the array 137 */ 138 public String getHexEvVarString() { 139 if (getEvVarArray() != null) { 140 return StringUtil.hexStringFromInts(getEvVarArray()).replaceAll("\\s", ""); 141 } 142 return ""; 143 } 144 145 /** 146 * Returns the number of unknown event variables 147 * 148 * @return the decimal outstanding total 149 */ 150 public int getOutstandingVars() { 151 if ( getEvVarArray() == null ){ 152 return 0; 153 } 154 int count = 0; 155 for (int val : getEvVarArray()){ 156 if (val == -1) { 157 count ++; 158 } 159 } 160 return count; 161 } 162 163 /** 164 * Returns the index of the next unknown event variable 165 * @return the decimal index value else 0 if all known 166 */ 167 public int getNextOutstanding() { 168 for (int i = 0; i < _evVarArr.length; i++) { 169 if ( _evVarArr[i] == -1) { 170 return i+1; 171 } 172 } 173 return 0; 174 } 175 176 /** 177 * Get the number of event variables 178 * by Array Length 179 * 180 * @return number of event variables 181 */ 182 public int getNumEvVars() { 183 if ( _evVarArr == null ) { 184 return 0; 185 } 186 return _evVarArr.length; 187 } 188 189 /** 190 * Sets unknown event variables to 0 191 * 192 */ 193 protected void allOutstandingEvVarsNotNeeded(){ 194 for (int i = 0; i < _evVarArr.length; i++) { 195 if ( _evVarArr[i] == -1) { 196 _evVarArr[i] = 0; 197 } 198 } 199 } 200 201 /** 202 * {@inheritDoc} 203 * <p> 204 * Custom method to compare Node Num, Ev Num, Parent Node Num, Event Variables 205 */ 206 @Override 207 public boolean equals(Object o) { 208 if (!(o instanceof CbusNodeEvent)) { 209 return false; 210 } 211 CbusNodeEvent t = (CbusNodeEvent) o; 212 if ( this.getEn()!=t.getEn() || this.getNn()!=t.getNn() ) { 213 return false; 214 } 215 if ( this.getParentNn()!=t.getParentNn() ) { 216 return false; 217 } 218 return this.getHexEvVarString().equals(t.getHexEvVarString()); 219 } 220 221 /** {@inheritDoc} */ 222 @Override 223 public int hashCode() { 224 return Objects.hash(getEn(), getNn(), getParentNn(), getHexEvVarString()); 225 } 226 227 /** 228 * {@inheritDoc} 229 * Compares to the Node / Event numbers of the Event 230 */ 231 @Override 232 public int compareTo(CbusNodeEvent o) { 233 return Integer.compare(this.listOrder(),o.listOrder()); 234 } 235 236 private int listOrder(){ 237 return (getNn()*65535+getEn())+100+(Objects.hash(getHexEvVarString())%100); 238 } 239 240 private static final Logger log = LoggerFactory.getLogger(CbusNodeEvent.class); 241 242}