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