001package jmri.jmrix.lenz; 002 003import jmri.JmriException; 004import jmri.managers.AbstractPowerManager; 005 006import org.slf4j.Logger; 007import org.slf4j.LoggerFactory; 008 009/** 010 * PowerManager implementation for controlling layout power. 011 * 012 * @author Bob Jacobsen Copyright (C) 2001 013 * @author Paul Bender Copyright (C) 2003-2010 014 */ 015public class XNetPowerManager extends AbstractPowerManager<XNetSystemConnectionMemo> implements XNetListener { 016 017 XNetTrafficController tc; 018 019 public XNetPowerManager(XNetSystemConnectionMemo memo) { 020 super(memo); 021 // connect to the TrafficManager 022 tc = memo.getXNetTrafficController(); 023 tc.addXNetListener(XNetInterface.CS_INFO, this); 024 // request the current command station status 025 tc.sendXNetMessage(XNetMessage.getCSStatusRequestMessage(), this); 026 } 027 028 @Override 029 public boolean implementsIdle() { 030 // XPressNet implements idle via the broadcast emergency stop commands. 031 return true; 032 } 033 034 @Override 035 public void setPower(int v) throws JmriException { 036 int old = power; 037 power = UNKNOWN; 038 checkTC(); 039 switch (v) { 040 case ON: 041 // send RESUME_OPS 042 tc.sendXNetMessage(XNetMessage.getResumeOperationsMsg(), this); 043 break; 044 case OFF: 045 // send EMERGENCY_OFF 046 tc.sendXNetMessage(XNetMessage.getEmergencyOffMsg(), this); 047 break; 048 case IDLE: 049 // send EMERGENCY_STOP 050 tc.sendXNetMessage(XNetMessage.getEmergencyStopMsg(), this); 051 break; 052 default: 053 break; 054 } 055 firePowerPropertyChange(old, power); 056 } 057 058 // to free resources when no longer used 059 @Override 060 public void dispose() { 061 tc.removeXNetListener(XNetInterface.CS_INFO, this); 062 tc = null; 063 } 064 065 private void checkTC() throws JmriException { 066 if (tc == null) { 067 throw new JmriException("attempt to use PowerManager after dispose"); 068 } 069 } 070 071 // to listen for Broadcast messages related to track power. 072 // There are 5 messages to listen for 073 @Override 074 public void message(XNetReply m) { 075 int old = power; 076 log.debug("Message received: {}", m); 077 if (m.getElement(0) == XNetConstants.CS_INFO 078 && m.getElement(1) == XNetConstants.BC_NORMAL_OPERATIONS) { 079 // First, we check for a "normal operations resumed message" 080 // This indicates the power to the track is ON 081 power = ON; 082 } else if (m.getElement(0) == XNetConstants.CS_INFO 083 && m.getElement(1) == XNetConstants.BC_EVERYTHING_OFF) { 084 // Next, we check for a Track Power Off message 085 // This indicates the power to the track is OFF 086 power = OFF; 087 } else if (m.getElement(0) == XNetConstants.BC_EMERGENCY_STOP 088 && m.getElement(1) == XNetConstants.BC_EVERYTHING_OFF) { 089 // Then, we check for an "Emergency Stop" message 090 // This indicates the track power is ON, but all 091 // locomotives are stopped 092 power = IDLE; 093 } else if (m.getElement(0) == XNetConstants.CS_INFO 094 && m.getElement(1) == XNetConstants.BC_SERVICE_MODE_ENTRY) { 095 // Next we check for a "Service Mode Entry" message 096 // This indicatse track power is off on the mainline. 097 power = OFF; 098 } else if (m.getElement(0) == XNetConstants.CS_REQUEST_RESPONSE 099 && m.getElement(1) == XNetConstants.CS_STATUS_RESPONSE) { 100 // Finally, we look at for the response to a Command 101 // Station Status Request 102 int statusByte = m.getElement(2); 103 if ((statusByte & 0x01) == 0x01) { 104 // Command station is in Emergency Off Mode 105 power = OFF; 106 } else if ((statusByte & 0x02) == 0x02) { 107 // Command station is in Emergency Stop Mode 108 power = IDLE; 109 } else if ((statusByte & 0x08) == 0x08) { 110 // Command station is in Service Mode, power to the 111 // track is off 112 power = OFF; 113 } else if ((statusByte & 0x40) == 0x40) { 114 // Command station is in Power Up Mode, and not yet on 115 power = OFF; 116 } else { 117 power = ON; 118 } 119 } 120 firePowerPropertyChange(old, power); 121 } 122 123 /** 124 * Listen for the messages to the LI100/LI101. 125 * 126 * @param l the message 127 */ 128 @Override 129 public void message(XNetMessage l) { 130 } 131 132 /** 133 * Handle a timeout notification. 134 */ 135 @Override 136 public void notifyTimeout(XNetMessage msg) { 137 log.debug("Notified of timeout on message{}", msg); 138 } 139 140 // Initialize logging information 141 private static final Logger log = LoggerFactory.getLogger(XNetPowerManager.class); 142 143}