Skip to content

Commit

Permalink
Changes to only read data from the weather service when we need to.
Browse files Browse the repository at this point in the history
  • Loading branch information
jmurph committed Nov 23, 2011
1 parent df1faf4 commit 084d64e
Show file tree
Hide file tree
Showing 9 changed files with 407 additions and 406 deletions.
365 changes: 175 additions & 190 deletions src/main/java/com/controlj/addon/weather/EquipmentHandler.java

Large diffs are not rendered by default.

256 changes: 77 additions & 179 deletions src/main/java/com/controlj/addon/weather/ScheduledWeatherLookup.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@
import com.controlj.addon.weather.config.ConfigData;
import com.controlj.addon.weather.config.ConfigDataFactory;
import com.controlj.addon.weather.config.WeatherConfigEntry;
import com.controlj.addon.weather.data.ForecastSource;
import com.controlj.addon.weather.data.ConditionsSource;
import com.controlj.addon.weather.service.WeatherService;
import com.controlj.addon.weather.service.WeatherServiceException;
import com.controlj.addon.weather.util.Logging;

import javax.servlet.ServletContextEvent;
Expand All @@ -44,181 +40,83 @@
* pages. This class implements ServletContextListener so that it can be started up when the
* web server starts.
*/
public class ScheduledWeatherLookup implements ServletContextListener
{
private static AtomicReference<ScheduledWeatherLookup> ref = new AtomicReference<ScheduledWeatherLookup>();
private ScheduledExecutorService scheduledExecutorService;
private ScheduledFuture<?> conditionsUpdateFuture;
private ScheduledFuture<?> forecastsUpdateFuture;

/**
* Starts the scheduled update of weather information when the context starts.
*/
@Override public synchronized void contextInitialized(ServletContextEvent sce)
{
ref.set(this);
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
rescheduleUpdates(1);
}

/**
* Stops the scheduled update of weather information when the context is destroyed. This happens when
* the server is shutting down, or if this add-on is disabled.
*/
@Override public synchronized void contextDestroyed(ServletContextEvent sce)
{
scheduledExecutorService.shutdownNow();
}

/**
* Stops any running updates and reschedules them based on the current saved configuration data.
* The updates have an initial delay as specified.
*/
private synchronized void rescheduleUpdates(int initialDelay)
{
if (conditionsUpdateFuture != null)
conditionsUpdateFuture.cancel(false);
if (forecastsUpdateFuture != null)
forecastsUpdateFuture.cancel(false);

Logging.println("Starting scheduled update of weather information:");

int conditionsRefresh = ConfigDataFactory.loadConfigData().getConditionsRefreshInMinutes();
Logging.println(" current conditions updated at a fixed rate of every "+conditionsRefresh+" minutes");
conditionsUpdateFuture = scheduledExecutorService.scheduleAtFixedRate(new ConditionsUpdate(), initialDelay*60, conditionsRefresh*60, TimeUnit.SECONDS);

int forecastsRefresh = ConfigDataFactory.loadConfigData().getForecastsRefreshInMinutes();
Logging.println(" forecasts updated at a fixed rate of every "+forecastsRefresh+" minutes");
forecastsUpdateFuture = scheduledExecutorService.scheduleAtFixedRate(new ForecastsUpdate(), initialDelay*60, forecastsRefresh*60, TimeUnit.SECONDS);
}

/**
* Stops any running updates and reschedules them based on the current saved configuration data. Used when
* the UI changes the refresh rate.
*/
public static void rescheduleUpdates()
{
ref.get().rescheduleUpdates(0);
}

/**
* Reads weather conditions data from the WeatherService, inserts it into the associated control program
* for the given entry (if any) and saves this data for later use by a view page.
* @param configData the config data. Used to get the selected weather service.
* @param entry the config entry for which this update is occurring.
* @return the conditions data read from the weather service.
* @throws WeatherServiceException if the data could not be read from the weather service.
*/
public static ConditionsSource updateConditionsData(ConfigData configData, WeatherConfigEntry entry) throws WeatherServiceException
{
ConditionsSource conditionsSource = null;
try
{
WeatherService weatherService = configData.getWeatherService();
conditionsSource = weatherService.getConditionsSource(configData.getServiceConfigData(),
entry.getStationSource(), entry.getServiceEntryData());

String errorMessage = null;
try
{
EquipmentHandler equipmentHandler = new EquipmentHandler(configData.getSystemConn(), "ABSPATH:1:"+entry.getCpPath());
equipmentHandler.writeConditionsData(conditionsSource);
}
catch (EquipmentWriteException e)
{
Logging.println("Error writing current conditions to CP "+entry.getCpPath(), e);
errorMessage = "Error writing data";
}

RuntimeInformation.getSingleton().updateConditionsData(entry, conditionsSource, errorMessage);
return conditionsSource;
}
catch (WeatherServiceException e)
{
Logging.println("Error reading forecast data", e);
RuntimeInformation.getSingleton().updateConditionsData(entry, null, "Error reading data");
throw e;
}
}

/**
* Reads weather forecast data from the WeatherService, inserts it into the associated control program
* for the given entry (if any) and saves this data for later use by a view page.
* @param configData the config data. Used to get the selected weather service.
* @param entry the config entry for which this update is occurring.
* @return the forecast data read from the weather service.
* @throws WeatherServiceException if the data could not be read from the weather service.
*/
public static ForecastSource[] updateForecastsData(ConfigData configData, WeatherConfigEntry entry) throws WeatherServiceException
{
try
{
WeatherService weatherService = configData.getWeatherService();
ForecastSource[] forecastSources = weatherService.getForecastSources(configData.getServiceConfigData(),
entry.getStationSource(), entry.getServiceEntryData());

String errorMessage = null;
try
{
EquipmentHandler equipmentHandler = new EquipmentHandler(configData.getSystemConn(), "ABSPATH:1:"+entry.getCpPath());
equipmentHandler.writeForecastData(forecastSources);

// periodically push this just so that it's kept up to date in the module (in case the equipment is reset to definition
// defaults or recreated or something)
equipmentHandler.writeStationData(entry.getStationSource());
}
catch (EquipmentWriteException e)
{
Logging.println("Error writing forecast data to CP "+entry.getCpPath(), e);
errorMessage = "Error writing data";
}

RuntimeInformation.getSingleton().updateForecastData(entry, forecastSources, errorMessage);
return forecastSources;
}
catch (WeatherServiceException e)
{
Logging.println("Error reading forecast data", e);
RuntimeInformation.getSingleton().updateForecastData(entry, null, "Error reading data");
throw e;
}
}

private static class ConditionsUpdate implements Runnable
{
@Override public void run()
{
ConfigData configData = ConfigDataFactory.loadConfigData();
for (WeatherConfigEntry entry : configData.getList())
{
try
{
updateConditionsData(configData, entry);
}
catch (Exception e)
{
Logging.println("Error writing conditions data for entry "+entry, e);
}
}
}
}

private static class ForecastsUpdate implements Runnable
{
@Override public void run()
{
ConfigData configData = ConfigDataFactory.loadConfigData();
for (WeatherConfigEntry entry : configData.getList())
{
try
{
updateForecastsData(configData, entry);
public class ScheduledWeatherLookup implements ServletContextListener {
private static final AtomicReference<ScheduledWeatherLookup> ref = new AtomicReference<ScheduledWeatherLookup>();
private ScheduledExecutorService scheduledExecutorService;
private ScheduledFuture<?> conditionsUpdateFuture;
private ScheduledFuture<?> forecastsUpdateFuture;

/**
* Starts the scheduled update of weather information when the context starts.
*/
@Override public synchronized void contextInitialized(ServletContextEvent sce) {
ref.set(this);
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
rescheduleUpdates(1);
}

/**
* Stops the scheduled update of weather information when the context is destroyed. This happens when
* the server is shutting down, or if this add-on is disabled.
*/
@Override public synchronized void contextDestroyed(ServletContextEvent sce) {
scheduledExecutorService.shutdownNow();
}

public static void rescheduleUpdates() {
ref.get().rescheduleUpdates(1);
}

/**
* Stops any running updates and reschedules them based on the current saved configuration data.
* The updates have an initial delay as specified.
*/
private synchronized void rescheduleUpdates(int initialDelay) {
if (conditionsUpdateFuture != null)
conditionsUpdateFuture.cancel(false);
if (forecastsUpdateFuture != null)
forecastsUpdateFuture.cancel(false);

Logging.println("Starting scheduled update of weather information:");

int conditionsRefresh = ConfigDataFactory.loadConfigData().getConditionsRefreshInMinutes();
Logging.println(" current conditions updated at a fixed rate of every " + conditionsRefresh + " minutes");
conditionsUpdateFuture = scheduledExecutorService.scheduleAtFixedRate(new ConditionsUpdate(), initialDelay * 60, conditionsRefresh * 60, TimeUnit.SECONDS);

int forecastsRefresh = ConfigDataFactory.loadConfigData().getForecastsRefreshInMinutes();
Logging.println(" forecasts updated at a fixed rate of every " + forecastsRefresh + " minutes");
forecastsUpdateFuture = scheduledExecutorService.scheduleAtFixedRate(new ForecastsUpdate(), initialDelay * 60, forecastsRefresh * 60, TimeUnit.SECONDS);
}

private static class ConditionsUpdate implements Runnable {
@Override public void run() {
ConfigData configData = ConfigDataFactory.loadConfigData();
WeatherLookup weatherLookup = new WeatherLookup(configData);
for (WeatherConfigEntry entry : configData.getList()) {
try {
EquipmentHandler handler = new EquipmentHandler(configData.getSystemConn(), entry.getCpPath());
if (handler.hasFieldsToWrite())
weatherLookup.lookupConditionsData(entry, true);
} catch (Exception e) {
Logging.println("Error writing conditions data for entry " + entry, e);
}
}
catch (Exception e)
{
Logging.println("Error writing forecasts data for entry "+entry, e);
}
}

private static class ForecastsUpdate implements Runnable {
@Override public void run() {
ConfigData configData = ConfigDataFactory.loadConfigData();
WeatherLookup weatherLookup = new WeatherLookup(configData);
for (WeatherConfigEntry entry : configData.getList()) {
try {
EquipmentHandler handler = new EquipmentHandler(configData.getSystemConn(), entry.getCpPath());
if (handler.hasFieldsToWrite())
weatherLookup.lookupForecastsData(entry, true);
} catch (Exception e) {
Logging.println("Error writing forecasts data for entry " + entry, e);
}
}
}
}
}
}
}
}
Loading

0 comments on commit 084d64e

Please sign in to comment.