001package jmri.jmrix.bidib; 002 003import jmri.JmriException; 004import jmri.PowerManager; 005 006import java.beans.PropertyChangeListener; 007import org.bidib.jbidibc.messages.AddressData; 008import org.bidib.jbidibc.core.DefaultMessageListener; 009import org.bidib.jbidibc.core.MessageListener; 010import org.bidib.jbidibc.messages.enums.BoosterState; 011import org.bidib.jbidibc.messages.enums.CommandStationState; 012import org.bidib.jbidibc.messages.Node; 013import org.bidib.jbidibc.messages.StringData; 014import org.bidib.jbidibc.messages.enums.BoosterControl; 015import org.bidib.jbidibc.messages.message.BoostOnMessage; 016import org.bidib.jbidibc.messages.message.BoostOffMessage; 017import org.bidib.jbidibc.messages.message.BoostQueryMessage; 018import org.bidib.jbidibc.messages.message.CommandStationSetStateMessage; 019import org.slf4j.Logger; 020import org.slf4j.LoggerFactory; 021 022/** 023 * BiDiBPowerManager.java 024 * 025 * Description: PowerManager implementation for controlling layout power 026 * 027 * @author Bob Jacobsen Copyright (C) 2001 028 * @author Eckart Meyer Copyright (C) 2019-2023 029 * 030 */ 031public class BiDiBPowerManager implements PowerManager { 032 033 BiDiBTrafficController tc = null; 034 String userName = "BiDiB"; 035 int power = UNKNOWN; 036 MessageListener messageListener = null; 037 038 public BiDiBPowerManager(BiDiBSystemConnectionMemo memo) { 039 tc = memo.getBiDiBTrafficController(); 040 userName = memo.getUserName(); 041 createBoosterListener(); 042 // ask BiDiB for current booster status 043 tc.sendBiDiBMessage(new BoostQueryMessage(), tc.getFirstBoosterNode()); 044 } 045 046 @Override 047 public String getUserName() { 048 return userName; 049 } 050 051 052 @Override 053 public void setPower(int v) throws JmriException { 054 int old = power; 055 power = UNKNOWN; 056 checkTC(); 057 Node csnode = tc.getFirstCommandStationNode(); 058 if (v == ON) { 059 // send TRACK_POWER_ON 060 // At first MSG_BOOST_ON(0), then powering on the DCC generator: all booster will be switched on, 061 // except those where the FEATURE_BST_INHIBIT_AUTOSTART is set. 062 tc.sendBiDiBMessage(new BoostOnMessage(BoostOnMessage.BROADCAST_MESSAGE), tc.getRootNode()); 063 if (csnode != null) { 064 tc.sendBiDiBMessage(new CommandStationSetStateMessage(CommandStationState.GO), tc.getFirstCommandStationNode()); 065 } 066 067 } else if (v == OFF) { 068 // send TRACK_POWER_OFF 069 if (csnode != null) { 070 tc.sendBiDiBMessage(new CommandStationSetStateMessage(CommandStationState.OFF), csnode); 071 } 072 tc.sendBiDiBMessage(new BoostOffMessage(BoostOffMessage.BROADCAST_MESSAGE), tc.getRootNode()); 073 } 074 firePropertyChange(POWER, old, power); 075 } 076 077 /** 078 * {@inheritDoc} 079 */ 080 @Override 081 public int getPower() { 082 return power; 083 } 084 085 /** 086 * {@inheritDoc} 087 * 088 * Remove the Message Listener for this power manager 089 */ 090 @Override 091 public void dispose() throws JmriException { 092 if (messageListener != null) { 093 tc.removeMessageListener(messageListener); 094 messageListener = null; 095 } 096 tc = null; 097 } 098 099 /** 100 * @throws JmriException if we don't have a valid Traffic Controller 101 */ 102 private void checkTC() throws JmriException { 103 if (tc == null) { 104 throw new JmriException("attempt to use PowerManager after dispose"); 105 } 106 } 107 108 // to hear of changes 109 java.beans.PropertyChangeSupport pcs = new java.beans.PropertyChangeSupport(this); 110 111 /** 112 * {@inheritDoc} 113 */ 114 @Override 115 public synchronized void addPropertyChangeListener(java.beans.PropertyChangeListener l) { 116 pcs.addPropertyChangeListener(l); 117 } 118 119 protected void firePropertyChange(String p, Object old, Object n) { 120 pcs.firePropertyChange(p, old, n); 121 } 122 123 /** 124 * {@inheritDoc} 125 */ 126 @Override 127 public synchronized void removePropertyChangeListener(java.beans.PropertyChangeListener l) { 128 pcs.removePropertyChangeListener(l); 129 } 130 131 /** 132 * {@inheritDoc} 133 */ 134 @Override 135 public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { 136 pcs.addPropertyChangeListener(propertyName, listener); 137 } 138 139 /** 140 * {@inheritDoc} 141 */ 142 @Override 143 public PropertyChangeListener[] getPropertyChangeListeners() { 144 return pcs.getPropertyChangeListeners(); 145 } 146 147 /** 148 * {@inheritDoc} 149 */ 150 @Override 151 public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) { 152 return pcs.getPropertyChangeListeners(propertyName); 153 } 154 155 /** 156 * {@inheritDoc} 157 */ 158 @Override 159 public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { 160 pcs.removePropertyChangeListener(propertyName, listener); 161 } 162 163 private void createBoosterListener() { 164 // to listen to messages related to track power. 165 messageListener = new DefaultMessageListener() { 166 @Override 167 public void boosterState(byte[] address, int messageNum, BoosterState state, BoosterControl control) {//ByteUtils 168 Node node = tc.getNodeByAddr(address); //the sending node 169 log.info("POWER booster state was signalled: {}, control: {}, node: {}", state, control, node); 170 if (state == BoosterState.OFF_SHORT) { 171 log.warn("Short circuit detected on booster {} ({})", node.getStoredString(StringData.INDEX_USERNAME), node); 172 } 173 else if (state == BoosterState.OFF_HOT) { 174 log.warn("Overtemperature detected on booster {} ({})", node.getStoredString(StringData.INDEX_USERNAME), node); 175 } 176 if (node.equals(tc.getFirstBoosterNode())) { 177 int old = power; 178 power = BoosterState.isOnState(state) ? ON : OFF; 179 log.info("change {} from {} to {}", POWER, old, power); 180 firePropertyChange(POWER, old, power); 181 } 182 } 183 @Override 184 public void speed(byte[] address, int messageNum, AddressData addressData, int speed) { 185 //Node node = tc.getFirstCommandStationNode(); 186 //log.trace("speed: node UID: {}, node addr: {}, msg node addr: {}, address: {}, speed: {}", node.getUniqueId(), node.getAddr(), address, addressData, speed); 187 //if (NodeUtils.isAddressEqual(node.getAddr(), address)) { 188 //log.debug("SPEED was signalled, node addr: {}, speed: {}, loco: {}", node.getAddr(), speed, addressData); 189 //} 190 } 191 }; 192 tc.addMessageListener(messageListener); 193 } 194 195 // Initialize logging information 196 private static final Logger log = LoggerFactory.getLogger(BiDiBPowerManager.class); 197 198} 199 200 201