001package jmri.jmrix.can.cbus.node;
002
003import jmri.jmrix.can.CanListener;
004import jmri.jmrix.can.CanMessage;
005import jmri.jmrix.can.CanSystemConnectionMemo;
006import jmri.jmrix.can.CanReply;
007import jmri.jmrix.can.TrafficController;
008import java.util.TimerTask;
009import jmri.util.TimerUtil;
010
011// import org.slf4j.Logger;
012// import org.slf4j.LoggerFactory;
013
014
015// intention is that once instance of this class active at any point, 
016// managed via the CbusNodeTableModel
017
018// if the network is quiet, ie no messages in the last XX ms, this
019// will trigger a fetch for any unknown node parameters, node variables, or node event variables
020
021public class CbusNodeTrickleFetch implements CanListener {
022    
023    private final CbusBasicNodeTableFetch nodeModel;
024    private final TrafficController tc;
025    private TimerTask trickleTimer;
026    private final long trickleTimeoutValue;
027    private boolean networkActive;
028    
029    public CbusNodeTrickleFetch(CanSystemConnectionMemo memo, CbusBasicNodeTableFetch model, long timeoutValue) {
030        
031        nodeModel = model;
032        trickleTimeoutValue = timeoutValue;
033        tc = memo.getTrafficController();
034        networkActive = false;
035        // start timer
036        if ( timeoutValue > 0L ) {
037            // connect to the CanInterface
038            addTc(tc);
039            startTrickleTimer();
040        }
041    }
042
043    /**
044     * Set up the Timer, and start it.
045     */
046    private void startTrickleTimer() {
047        if (trickleTimer == null) {
048            trickleTimer = new TimerTask(){
049                    @Override
050                    public void run() {
051                        seeIfCanBusy();
052                    }
053                };
054        }
055        TimerUtil.schedule(trickleTimer, trickleTimeoutValue, trickleTimeoutValue);
056    }
057    
058    private void stopTrickleTimer(){
059        if (trickleTimer != null ) {
060            trickleTimer.cancel();
061            trickleTimer = null;
062        }
063    }
064
065    private void seeIfCanBusy() {
066        if ( !networkActive ) {   
067            // log.debug("Quiet Network");
068            nodeModel.sendNextBackgroundFetch();
069        } else {
070            // log.debug("Busy Network");
071            networkActive = false;
072        }
073    }
074    
075    /**
076     * {@inheritDoc}
077     */
078    @Override
079    public void message(CanMessage m) { // outgoing cbus message
080        networkActive = true;
081    }
082    
083    /**
084     * {@inheritDoc}
085     */
086    @Override
087    public void reply(CanReply m) { // incoming cbus message
088        networkActive = true;
089    }
090    
091    public void dispose(){
092        stopTrickleTimer();
093        removeTc(tc);
094    }
095
096    // private final static Logger log = LoggerFactory.getLogger(CbusNodeTrickleFetch.class);
097
098}