001package jmri.jmrix.loconet; 002import java.util.TimerTask; 003 004/** 005 * Provides for LocoNet "Meters" discovery query at connection start-up. 006 * 007 * This class specifically deals with issues sometimes seen 008 * at JMRI LocoNet connection start-up. 009 * 010 * @author B. Milhaupt (C) 2020 011 */ 012public class LnMeterInitTask { 013 014 boolean _enabled = false; 015 private UpdateTask _intervalTask = null; 016 private final int _sleepInterval; 017 private final LnTrafficController tc; 018 019 /** 020 * Create a task to perform an initial query of LocoNet for devices 021 * which provide data for JMRI Meters. 022 * 023 * @param tc Traffic Controller used when sending query 024 * @param interval - delay between checks of connection's readiness 025 */ 026 public LnMeterInitTask(LnTrafficController tc, int interval) { 027 this.tc = tc; 028 _sleepInterval = interval; 029 } 030 031 /** 032 * Enable the task to begin 033 */ 034 protected void enable() { 035 if (!_enabled) { 036 _enabled = true; 037 if(_intervalTask != null) { 038 _intervalTask.enable(true); 039 } 040 } 041 } 042 043 /** 044 * Cancel the task (if it is not already canceled) 045 */ 046 protected void disable() { 047 if(_intervalTask != null) { 048 _intervalTask.enable(false); 049 } 050 } 051 052 /** 053 * Initializes timer for send of meters query. 054 * 055 * Cancels any existing task. Checks delay and 056 * exits if delay is negative. Establishes a 057 * new task only if delay is greater than 0. 058 */ 059 public void initTimer() { 060 if(_intervalTask != null) { 061 _intervalTask.cancel(); 062 _intervalTask = null; 063 } 064 if(_sleepInterval < 0){ 065 return; // don't start or restart the timer. 066 } 067 _intervalTask = new UpdateTask(); 068 log.debug("Starting Initialization Timer"); 069 jmri.util.TimerUtil.scheduleAtFixedRate(_intervalTask, 070 _sleepInterval, _sleepInterval); 071 } 072 073 /** 074 * Remove references to and from this object, so that it can eventually be 075 * garbage-collected. 076 */ 077 public void dispose(){ 078 if ((_intervalTask != null) && (_intervalTask.isEnabled())) { 079 _intervalTask.enable(false); 080 } 081 if (_intervalTask != null) { 082 _intervalTask = null; 083 } 084 } 085 086 /** 087 * Timer task for periodic updates 088 * 089 * Task to check status of the LocoNet connection, and, when it is 090 * ready, send a LocoNet query message. 091 */ 092 private class UpdateTask extends TimerTask { 093 094 private boolean _updateTaskIsEnabled; 095 096 public UpdateTask() { 097 super(); 098 this._updateTaskIsEnabled = false; 099 } 100 101 /** 102 * Enable or disable the update task 103 * @param val true to enable, false to disable 104 */ 105 public void enable(boolean val) { 106 if (!val) { 107 cancel(); 108 } 109 _updateTaskIsEnabled = val; 110 } 111 112 /** 113 * get the enable/disable state of the update task 114 * @return true if enabled, else false 115 */ 116 public boolean isEnabled() { 117 return _updateTaskIsEnabled; 118 } 119 120 @Override 121 public void run() { 122 if (!_updateTaskIsEnabled) { 123 log.debug("LnMeter initialization timer finds task not enabled."); 124 return; 125 } else if (!tc.status()) { 126 log.debug("LnMeter initialization timer finds connection not ready."); 127 return; 128 } 129 log.debug("LnMeter initialization timer is sending query."); 130 tc.sendLocoNetMessage(new LocoNetMessage( 131 new int[] {LnConstants.OPC_RQ_SL_DATA, 0x79, 0x01, 0x00})); 132 disable(); 133 } 134 } 135 136 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LnMeterInitTask.class); 137}