001package jmri.jmrix.zimo;
002
003import static jmri.jmrix.zimo.Mx1Message.ACKREP1;
004
005import jmri.JmriException;
006import jmri.managers.AbstractPowerManager;
007
008/**
009 * PowerManager implementation for controlling layout power.
010 *
011 * @author Bob Jacobsen Copyright (C) 2001
012  *
013 * Adapted by Sip Bosch for use with zimo Mx-1
014 *
015 */
016public class Mx1PowerManager extends AbstractPowerManager<Mx1SystemConnectionMemo> implements Mx1Listener {
017
018    Mx1TrafficController tc = null;
019
020    public Mx1PowerManager(Mx1SystemConnectionMemo memo) {
021        super(memo);
022        // connect to the TrafficManager
023        this.tc = memo.getMx1TrafficController();
024        tc.addMx1Listener(~0, this);
025    }
026
027    @Override
028    public void setPower(int v) throws JmriException {
029        int old = power;
030        power = UNKNOWN;
031        if (tc.getProtocol() == Mx1Packetizer.ASCII) {
032            checkTC();
033            if (v == ON) {
034                // send GPON
035                Mx1Message m = new Mx1Message(3);
036                m.setElement(0, 0x53);
037                m.setElement(1, 0x45);
038                tc.sendMx1Message(m, this);
039            } else if (v == OFF) {
040                // send GPOFF
041                Mx1Message m = new Mx1Message(3);
042                m.setElement(0, 0x53);
043                m.setElement(1, 0x41);
044                tc.sendMx1Message(m, this);
045            }
046            // request status
047            Mx1Message m = new Mx1Message(2);
048            m.setElement(0, 0x5A);
049            tc.sendMx1Message(m, this);
050        } else {
051            if (v == ON) {
052                tc.sendMx1Message(Mx1Message.setPowerOn(), this);
053            } else if (v == OFF) {
054                tc.sendMx1Message(Mx1Message.setPowerOff(), this);
055            }
056            if (memo.getConnectionType() == Mx1SystemConnectionMemo.MXULF) {
057                //MXULF doesn't return the correct status of the track power, so we have to assume it has been set                
058                power = v;
059            } else {
060                tc.sendMx1Message(Mx1Message.getTrackStatus(), this);
061            }
062        }
063        firePowerPropertyChange(old, power);
064    }
065
066    // to free resources when no longer used
067    @Override
068    public void dispose() throws JmriException {
069        tc.removeMx1Listener(~0, this);
070        tc = null;
071    }
072
073    private void checkTC() throws JmriException {
074        if (tc == null) {
075            throw new JmriException("attempt to use PowerManager after dispose");
076        }
077    }
078
079    // to listen for status changes from net
080    @Override
081    public void message(Mx1Message m) {
082        if (tc.getProtocol() == Mx1Packetizer.ASCII) {
083            int old = power;
084            if (m.getElement(0) == 0x5a) {
085                if ((m.getElement(2) & 0x02) == 0x02) {
086                    power = ON;
087                } else {
088                    power = OFF;
089                }
090            } else if (m.getMessageType() == ACKREP1 && m.getPrimaryMessage() == Mx1Message.TRACKCTL) {
091                if ((m.getElement(4) & 0x02) == 0x02) {
092                    power = OFF;
093                } else {
094                    power = ON;
095                }
096            }
097            firePowerPropertyChange(old, power);
098        }
099    }
100
101}
102
103
104