001package jmri.jmrix.tams;
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 using binary P50x
011 * commands
012 *
013 * Based on work by Bob Jacobsen and Kevin Dickerson
014 *
015 * @author Jan Boen
016 * 
017 */
018public class TamsPowerManager extends AbstractPowerManager<TamsSystemConnectionMemo> implements TamsListener {
019    
020    //This dummy message is used in case we expect a reply from polling
021    static private TamsMessage myDummy() {
022        //log.debug("*** myDummy ***");
023        TamsMessage m = new TamsMessage(2);
024        m.setElement(0, TamsConstants.POLLMSG & TamsConstants.MASKFF);
025        m.setElement(1, TamsConstants.XSTATUS & TamsConstants.MASKFF);
026        m.setBinary(true);
027        m.setReplyOneByte(true);
028        m.setReplyType('P');
029        return m;
030    }
031    //A local TamsMessage is held at all time
032    //When no TamsMessage is being generated via the UI this dummy is used which means the TamsReply is a result of polling
033    TamsMessage tm = myDummy();
034    
035    public TamsPowerManager(TamsTrafficController ttc) {
036        super (ttc.adaptermemo);
037        log.debug("*** Tams PowerManager ***");
038        // connect to the TrafficManager
039        tc = ttc;
040        init();
041    }
042   
043    private void init() {
044        tc.addTamsListener(this);
045        tm = TamsMessage.getXStatus();
046        tc.sendTamsMessage(tm, this);
047        tc.addPollMessage(tm, this);
048        log.debug("TamsMessage added to pollqueue = {} {} and replyType = {}", jmri.util.StringUtil.appendTwoHexFromInt(tm.getElement(0) & 0xFF, ""), jmri.util.StringUtil.appendTwoHexFromInt(tm.getElement(1) & 0xFF, ""), tm.getReplyType());
049    }
050
051    TamsTrafficController tc;
052    Thread tamsPowerMonitorThread;
053
054    @Override
055    public void setPower(int v) throws JmriException {
056        log.debug("*** setPower ***");
057        int old = power;
058        power = UNKNOWN; // Until we get a reply from the CS
059        checkTC();
060        if (v == ON) {
061            // send message to turn on
062            tm = TamsMessage.setXPwrOn();
063            tc.sendTamsMessage(tm, null);//changed this to null in this method
064        } else if (v == OFF) {
065            // send message to turn off
066            tm = TamsMessage.setXPwrOff();
067            tc.sendTamsMessage(tm, null);
068        }
069        firePowerPropertyChange(old, power);
070    }
071
072    int lastRequest = 0;
073
074    // to free resources when no longer used
075    @Override
076    public void dispose() throws JmriException {
077        tm = TamsMessage.getXStatus();
078        tc.removePollMessage(tm, this);
079        tc = null;
080    }
081
082    private void checkTC() throws JmriException {
083        if (tc == null) {
084            throw new JmriException("attempt to use TamsPowerManager after dispose");
085        }
086    }
087
088    // to listen for status changes from Tams system
089    @Override
090    public void reply(TamsReply tr) {
091        int old = power;
092        if ((tc.replyType == 'P')){
093            log.debug("*** Tams Power Reply ***");
094            //log.debug("TamsMessage = " + jmri.util.StringUtil.appendTwoHexFromInt(tm.getElement(0) & 0xFF, "") + " " + jmri.util.StringUtil.appendTwoHexFromInt(tm.getElement(1) & 0xFF, "") + " and replyType = " + tm.getReplyType());
095            log.debug("TamsReply = {}", jmri.util.StringUtil.appendTwoHexFromInt(tr.getElement(0) & 0xFF, ""));
096            boolean valid = false;
097            if (tc.replyBinary) {//Reply related to Poll Message
098                log.debug("Reply to Poll Message");
099                //reply to power status check is either 0 for off or 8 for on
100                //if (tm.getElement(1) == TamsConstants.XSTATUS) {//power status check
101                    if ((tr.getElement(0) & TamsConstants.XPWRMASK) == 0x00) {
102                        log.debug("Power status = OFF");
103                        power = OFF;
104                        firePowerPropertyChange(old, power);
105                        valid = true;
106                    }
107                    if ((tr.getElement(0) & TamsConstants.XPWRMASK) == 0x08) {
108                        log.debug("Power status = ON");
109                        power = ON;
110                        firePowerPropertyChange(old, power);
111                        valid = true;
112                    }
113                //}
114            } else {//Reply related to UI message
115                log.debug("Reply to UI Message");
116                //reply to power on / power off is always 0x00 any other answer is not correct
117                if (tm.getElement(1) == TamsConstants.XPWROFF) {
118                    log.debug("Power set = OFF");
119                    power = OFF;
120                    firePowerPropertyChange(old, power);
121                    valid = true;
122                }
123                if (tm.getElement(1) == TamsConstants.XPWRON) {
124                    log.debug("Power set = ON");
125                    power = ON;
126                    firePowerPropertyChange(old, power);
127                    valid = true;
128                }
129            }
130            if (valid == false) {
131                power = UNKNOWN;
132                log.debug("Unknown reply in power manager {}", tr.toString());
133                firePowerPropertyChange(old, power);
134            }
135        tm = myDummy();
136        }
137    }
138
139    @Override
140    public void message(TamsMessage tm) {
141        // messages are ignored
142    }
143
144    private final static Logger log = LoggerFactory.getLogger(TamsPowerManager.class);
145}