001package jmri.jmrix.dccpp; 002 003import jmri.JmriException; 004import jmri.managers.AbstractPowerManager; 005 006/** 007 * DCCppPowerManager.java 008 * 009 * PowerManager implementation for controlling layout power 010 * 011 * @author Bob Jacobsen Copyright (C) 2001 012 * @author Paul Bender Copyright (C) 2003-2010 013 * @author Mark Underwood Copyright (C) 2015 014 * 015 * Based on XNetPowerManager by Bob Jacobsen and Paul Bender 016 */ 017public class DCCppPowerManager extends AbstractPowerManager<DCCppSystemConnectionMemo> implements DCCppListener { 018 019 private DCCppTrafficController tc = null; 020 021 /** 022 * Create a new DCCppPowerManager. 023 * Adds listener to connection. 024 * Requests power update from layout. 025 * @param memo the Connection. 026 */ 027 public DCCppPowerManager(DCCppSystemConnectionMemo memo) { 028 super(memo); 029 // connect to the TrafficManager 030 tc = memo.getDCCppTrafficController(); 031 tc.addDCCppListener(DCCppInterface.CS_INFO, this); 032 DCCppPowerManager.this.requestUpdateFromLayout(); 033 } 034 035 /** 036 * Set the Power status. 037 * After sending to the layout, requests power status update. 038 * {@inheritDoc } 039 */ 040 @Override 041 public void setPower(int v) throws JmriException { 042 int old = power; 043 power = UNKNOWN; 044 checkTC(); 045 if (v == ON) { 046 // send TRACK_POWER_ON 047 tc.sendDCCppMessage(DCCppMessage.makeTrackPowerOnMsg(), this); 048 } else if (v == OFF) { 049 // send TRACK_POWER_OFF 050 tc.sendDCCppMessage(DCCppMessage.makeTrackPowerOffMsg(), this); 051 } 052 firePowerPropertyChange(old, power); 053 // Newer( > v5.5 / v5.6 ?? ) versions of DCC-EX only broadcast power state changes, 054 // so we request confirmation of power status. 055 requestUpdateFromLayout(); 056 } 057 058 // to free resources when no longer used 059 @Override 060 public void dispose() throws JmriException { 061 tc.removeDCCppListener(DCCppInterface.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 // listen for power and status messages 072 @Override 073 public void message(DCCppReply m) { 074 if (m.isPowerReply()) { 075 log.debug("Power Reply message received: {}", m); 076 int old = power; 077 if (m.getPowerBool()) { 078 power = ON; 079 } else { 080 power = OFF; 081 } 082 firePowerPropertyChange(old, power); 083 084 // if status reply 's', then update the command station info (version, etc.) 085 } else if (m.isStatusReply()) { 086 log.debug("Version Info Received: {}", m); 087 tc.getCommandStation().setCommandStationInfo(m); 088 089 // store trackmanager mode by index (0-7 for A-H) 090 } else if (m.isTrackManagerReply()) { 091 log.debug("Track Manager Reply Received: {}", m); 092 int trackNum = m.getTrackManagerLetter() - 'A'; //get track number from track letter 093 tc.getCommandStation().setTrackMode(trackNum, m.getTrackManagerMode()); 094 } 095 } 096 097 // listen for the messages to the CommandStation 098 @Override 099 public void message(DCCppMessage l) { 100 } 101 102 // Handle message timeout notification 103 // If the message still has retries available, reduce retries and send it back to the traffic controller. 104 @Override 105 public void notifyTimeout(DCCppMessage msg) { 106 log.debug("Notified of timeout on message '{}' , {} retries available.", msg, msg.getRetries()); 107 if (msg.getRetries() > 0) { 108 msg.setRetries(msg.getRetries() - 1); 109 tc.sendDCCppMessage(msg, this); 110 } 111 } 112 113 /** 114 * Request the current command station status and 115 * request the trackmanager configuration. 116 * {@inheritDoc } 117 */ 118 @Override 119 public void requestUpdateFromLayout() { 120 // Request the current command station status. 121 tc.sendDCCppMessage(DCCppMessage.makeCSStatusMsg(), this); 122 // Request the trackmanager configuration. 123 tc.sendDCCppMessage(DCCppMessage.makeTrackManagerRequestMsg(), this); 124 } 125 126 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DCCppPowerManager.class); 127 128}