001/**
002 * DCCppPowerManager.java
003 *
004 * PowerManager implementation for controlling layout power
005 *
006 * @author Bob Jacobsen Copyright (C) 2001
007 * @author Paul Bender Copyright (C) 2003-2010
008 * @author Mark Underwood Copyright (C) 2015
009  *
010 * Based on XNetPowerManager by Bob Jacobsen and Paul Bender
011 */
012package jmri.jmrix.dccpp;
013
014import jmri.JmriException;
015import jmri.managers.AbstractPowerManager;
016
017import org.slf4j.Logger;
018import org.slf4j.LoggerFactory;
019
020public class DCCppPowerManager extends AbstractPowerManager<DCCppSystemConnectionMemo> implements DCCppListener {
021
022    DCCppTrafficController tc = null;
023
024    public DCCppPowerManager(DCCppSystemConnectionMemo memo) {
025        super(memo);
026        // connect to the TrafficManager
027        tc = memo.getDCCppTrafficController();
028        tc.addDCCppListener(DCCppInterface.CS_INFO, this);
029        // request the current command station status
030        tc.sendDCCppMessage(DCCppMessage.makeCSStatusMsg(), this);
031    }
032
033    @Override
034    public void setPower(int v) throws JmriException {
035        int old = power;
036        power = UNKNOWN;
037        checkTC();
038        if (v == ON) {
039            // send TRACK_POWER_ON
040            tc.sendDCCppMessage(DCCppMessage.makeTrackPowerOnMsg(), this);
041        } else if (v == OFF) {
042            // send TRACK_POWER_OFF
043            tc.sendDCCppMessage(DCCppMessage.makeTrackPowerOffMsg(), this);
044        }
045        firePowerPropertyChange(old, power);
046    }
047
048    // to free resources when no longer used
049    @Override
050    public void dispose() throws JmriException {
051        tc.removeDCCppListener(DCCppInterface.CS_INFO, this);
052        tc = null;
053    }
054
055    private void checkTC() throws JmriException {
056        if (tc == null) {
057            throw new JmriException("attempt to use PowerManager after dispose");
058        }
059    }
060
061    // listen for power and status messages
062    @Override
063    public void message(DCCppReply m) {
064        if (m.isPowerReply()) {
065            log.debug("Power Reply message received: {}", m);
066            int old = power;
067            if (m.getPowerBool()) {
068                power = ON;
069            } else {
070                power = OFF;
071            }
072            firePowerPropertyChange(old, power);
073        // if status reply 's', then update the command station info (version, etc.)
074        } else if (m.isStatusReply()) {
075            log.debug("Version Info Received: {}", m);
076            tc.getCommandStation().setCommandStationInfo(m);
077        }
078    }
079
080    // listen for the messages to the CommandStation
081    @Override
082    public void message(DCCppMessage l) {
083    }
084
085    // Handle message timeout notification
086    // If the message still has retries available, reduce retries and send it back to the traffic controller.
087    @Override
088    public void notifyTimeout(DCCppMessage msg) {
089        log.debug("Notified of timeout on message '{}' , {} retries available.", msg, msg.getRetries());
090        if (msg.getRetries() > 0) {
091            msg.setRetries(msg.getRetries() - 1);
092            tc.sendDCCppMessage(msg, this);
093        }        
094    }
095
096    // Initialize logging information
097    private final static Logger log = LoggerFactory.getLogger(DCCppPowerManager.class);
098
099}
100
101
102