001package jmri.jmrix.loconet.logixng;
002
003import jmri.jmrit.logixng.actions.*;
004
005import java.util.*;
006
007import jmri.*;
008import jmri.JmriException;
009import jmri.jmrit.logixng.*;
010import jmri.jmrix.loconet.*;
011
012/**
013 * Sets the speed to zero if the loco hasn't been used in a while.
014 *
015 * @author Daniel Bergqvist Copyright 2020
016 */
017public class SetSpeedZero extends AbstractDigitalAction {
018
019    private static final int NUM_LOCO_SLOTS_TO_CHECK = 119;
020
021    private LocoNetSystemConnectionMemo _memo;
022
023    public SetSpeedZero(String sys, String user, LocoNetSystemConnectionMemo memo) {
024        super(sys, user);
025        _memo = memo;
026    }
027
028    @Override
029    public Base getDeepCopy(Map<String, String> systemNames, Map<String, String> userNames) throws JmriException {
030        DigitalActionManager manager = InstanceManager.getDefault(DigitalActionManager.class);
031        String sysName = systemNames.get(getSystemName());
032        String userName = userNames.get(getSystemName());
033        if (sysName == null) sysName = manager.getAutoSystemName();
034        SetSpeedZero copy = new SetSpeedZero(sysName, userName, _memo);
035        return manager.registerAction(copy).deepCopyChildren(this, systemNames, userNames);
036    }
037
038    /** {@inheritDoc} */
039    @Override
040    public Category getCategory() {
041        return CategoryLocoNet.LOCONET;
042    }
043
044    public void setMemo(LocoNetSystemConnectionMemo memo) {
045        assertListenersAreNotRegistered(log, "setMemo");
046        _memo = memo;
047    }
048
049    public LocoNetSystemConnectionMemo getMemo() {
050        return _memo;
051    }
052
053    private void setSlotSpeedZero(LocoNetSlot slot) {
054        boolean inUse =
055                slot.slotStatus() == LnConstants.LOCO_IN_USE
056                || slot.slotStatus() == LnConstants.LOCO_COMMON;
057
058        boolean upLinkConsist =
059                slot.consistStatus() == LnConstants.CONSIST_MID
060                || slot.consistStatus() == LnConstants.CONSIST_SUB;
061
062        if (inUse && !upLinkConsist && slot.speed() != 0) {
063            LocoNetMessage msg = new LocoNetMessage(4);
064            msg.setOpCode(LnConstants.OPC_LOCO_SPD);
065            msg.setElement(1, slot.getSlot());
066            msg.setElement(2, 0);
067            _memo.getLnTrafficController().sendLocoNetMessage(msg);
068        }
069    }
070
071    /** {@inheritDoc} */
072    @Override
073    public void execute() {
074        for (int i=1; i <= NUM_LOCO_SLOTS_TO_CHECK; i++) {
075            setSlotSpeedZero(_memo.getSlotManager().slot(i));
076        }
077    }
078
079    @Override
080    public FemaleSocket getChild(int index) throws IllegalArgumentException, UnsupportedOperationException {
081        throw new UnsupportedOperationException("Not supported.");
082    }
083
084    @Override
085    public int getChildCount() {
086        return 0;
087    }
088
089    @Override
090    public String getShortDescription(Locale locale) {
091        return Bundle.getMessage(locale, "SetSpeedZero_Short");
092    }
093
094    @Override
095    public String getLongDescription(Locale locale) {
096        return Bundle.getMessage(locale, "SetSpeedZero_Long",
097                _memo != null ? _memo.getUserName() : Bundle.getMessage("MemoNotSet"));
098    }
099
100    /** {@inheritDoc} */
101    @Override
102    public void setup() {
103        // Do nothing
104    }
105
106    /** {@inheritDoc} */
107    @Override
108    public void registerListenersForThisClass() {
109        if (!_listenersAreRegistered) {
110            _listenersAreRegistered = true;
111        }
112    }
113
114    /** {@inheritDoc} */
115    @Override
116    public void unregisterListenersForThisClass() {
117        _listenersAreRegistered = false;
118    }
119
120    /** {@inheritDoc} */
121    @Override
122    public void disposeMe() {
123    }
124
125
126    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(SetSpeedZero.class);
127
128}