001package jmri.jmrix.nce; 002 003import jmri.JmriException; 004import jmri.Sensor; 005import org.slf4j.Logger; 006import org.slf4j.LoggerFactory; 007 008/** 009 * Model an NCE AIU 010 * <p> 011 * These AIUs are numbered ala the cab bus, from 1 to 63. AIU number 1 carries 012 * sensors 1 to 14; AIU 2 from 17 to 30, etc. 013 * <p> 014 * The array of sensor states is used to update sensor known state only when 015 * there's a change on the cab bus. This allows for the sensor state to be 016 * updated within the program, keeping this updated state until the next change 017 * on the cab bus. E.g. you can manually change a state via an icon, and not 018 * have it change back the next time that AIU is polled. 019 * 020 * @author Bob Jacobsen Copyright (C) 2003, 2005 021 */ 022public class NceAIU { 023 024 public NceAIU() { 025 for (int i = 0; i < 15; i++) { 026 sensorArray[i] = null; 027 sensorLastSetting[i] = Sensor.UNKNOWN; 028 } 029 } 030 031 Sensor[] sensorArray = new Sensor[15]; 032 int[] sensorLastSetting = new int[15]; 033 int lastAIUValue = 0xc000; // can't ever take this value 034 035 /** 036 * 037 * @param bits int value of response from poll command 038 */ 039 public void markChanges(int bits) { 040 if (bits != lastAIUValue) { 041 if (log.isDebugEnabled()) { 042 log.debug("sensor array change from {} to {}", Integer.toHexString(lastAIUValue), Integer.toHexString(bits)); 043 } 044 lastAIUValue = bits; 045 for (int i = 0; i < 14; i++) { 046 if (sensorArray[i] != null) { 047 boolean value = ((bits & 1) == 0) ^ sensorArray[i].getInverted(); 048 if (value) { 049 sensorChange(i, Sensor.ACTIVE); 050 } else { 051 sensorChange(i, Sensor.INACTIVE); 052 } 053 } 054 bits = bits / 2; 055 } 056 } 057 } 058 059 /** 060 * set state of a single sensor based on AIU input 061 * 062 * @param offset sensor number within the current array 063 * @param newState new state (Sensor.ACTIVE / .INACTIVE) 064 */ 065 public void sensorChange(int offset, int newState) { 066 if (sensorArray[offset] != null && sensorLastSetting[offset] != newState) { 067 sensorLastSetting[offset] = newState; 068 if (log.isDebugEnabled()) { 069 String newStateStr = "Active"; 070 if (newState == Sensor.INACTIVE) { 071 newStateStr = "Inactive"; 072 } 073 log.debug("setting sensor {}: {}", sensorArray[offset].getSystemName(), newStateStr); 074 } 075 try { 076 sensorArray[offset].setKnownState(newState); 077 } catch (JmriException e) { 078 log.error("exception in sensorChange", e); 079 } 080 } 081 } 082 083 /** 084 * The numbers here are 0 to 15, not 1 to 16 085 * @param s bit within the AIU card 086 * @param i index for AIU card 087 * 088 */ 089 public void registerSensor(Sensor s, int i) { 090 sensorArray[i] = s; 091 } 092 093 /** 094 * Return the sensor object for the specified AIU 095 * 096 * @param index AIU index (0..15) 097 * @return sensor object 098 */ 099 public Sensor getSensor(int index) { 100 return sensorArray[index]; 101 } 102 103 private final static Logger log = LoggerFactory.getLogger(NceAIU.class); 104} 105 106