/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package project.latex.balloon; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; import project.latex.balloon.consumer.DataModelConsumer; import project.latex.balloon.sensor.CameraSensorController; import project.latex.balloon.sensor.SensorController; import project.latex.balloon.sensor.SensorReadFailedException; import project.latex.balloon.ssdv.SsdvController; import project.latex.balloon.writer.DataWriter; /** * * @author Dan */ public class BalloonController { private static final Logger logger = Logger.getLogger(BalloonController.class); private final String payloadName = "$$latex"; // Sensors to determine the current state of the balloon private List<SensorController> sensors; private List<DataModelConsumer> dataModelConsumers; private List<DataWriter> dataWriters; // Camera private CameraSensorController cameraSensor; private SentenceIdGenerator sentenceIdGenerator; private ControllerRunner controllerRunner; // Ssdv private SsdvController ssdvController; // Required properties private String timeKey; private String dateKey; private String payloadNameKey; private String sentenceIdKey; /** * @param args the command line arguments */ public static void main(String[] args) { PropertyConfigurator.configure("logger.properties"); logger.info("Project Latex Balloon Controller, version 0.1"); String configFile = args[0]; ApplicationContext context = new FileSystemXmlApplicationContext(configFile); BalloonController balloonController = (BalloonController) context.getBean("balloonController"); logger.info("Balloon created"); balloonController.run(); } public String getPayloadName() { return payloadName; } public List<SensorController> getSensors() { return sensors; } public List<DataWriter> getDataWriters() { return dataWriters; } public List<DataModelConsumer> getDataModelConsumers() { return dataModelConsumers; } public CameraSensorController getCameraSensor() { return cameraSensor; } public SsdvController getSsdvController() { return ssdvController; } public SentenceIdGenerator getSentenceIdGenerator() { return sentenceIdGenerator; } public void setSensors(List<SensorController> sensors) { this.sensors = sensors; } public void setDataModelConsumers(List<DataModelConsumer> dataModelConsumers) { this.dataModelConsumers = dataModelConsumers; } public void setDataWriters(List<DataWriter> dataWriters) { this.dataWriters = dataWriters; } public void setCameraSensor(CameraSensorController cameraSensor) { this.cameraSensor = cameraSensor; } public void setSsdvController(SsdvController ssdvController) { this.ssdvController = ssdvController; } public void setSentenceIdGenerator(SentenceIdGenerator sentenceIdGenerator) { this.sentenceIdGenerator = sentenceIdGenerator; } public void setTimeKey(String timeKey) { this.timeKey = timeKey; } public void setDateKey(String dateKey) { this.dateKey = dateKey; } public void setPayloadNameKey(String payloadNameKey) { this.payloadNameKey = payloadNameKey; } public void setSentenceIdKey(String sentenceIdKey) { this.sentenceIdKey = sentenceIdKey; } public void setControllerRunner(ControllerRunner controllerRunner) { this.controllerRunner = controllerRunner; } void run() { if (controllerRunner == null) { throw new IllegalArgumentException("Cannot run with null ControllerRunner"); } if (timeKey == null) { throw new IllegalArgumentException("Null time key specified"); } if (dateKey == null) { throw new IllegalArgumentException("Null date key specified"); } if (payloadNameKey == null) { throw new IllegalArgumentException("Null payload name key specified"); } if (sentenceIdKey == null) { throw new IllegalArgumentException("Null sentence id key specified"); } while (controllerRunner.shouldKeepRunning()) { switch (controllerRunner.getCurrentRunLoop()) { case SensorDataRunLoop: processSensorData(); break; case SsdvRunLoop: if (ssdvController != null) { ssdvController.sendNextPacket(); } controllerRunner.controllerFinishedRunLoop(null); } } } private void processSensorData() { // Build up a model of the current balloon state from the sensors Map<String, Object> data = new HashMap<>(); // Add entries for date and time. If the GPS module is running, that will // override these values when we read data from it. // For now we put the date into the same timeFormat as the Icarus test data, // as this means we don't need to change the receiver to be able to handle both // sets of data Date now = new Date(); DateFormat timeFormat = new SimpleDateFormat("HH:mm:ss"); data.put(timeKey, timeFormat.format(now)); DateFormat dateFormat = new SimpleDateFormat("ddMMYY"); data.put(dateKey, dateFormat.format(now)); data.put(payloadNameKey, this.payloadName); data.put(sentenceIdKey, this.sentenceIdGenerator.generateId()); // Get readings from each of our sensors. for (SensorController controller : this.sensors) { try { Map<String, Object> sensorData = controller.getCurrentData(); for (String key : sensorData.keySet()) { data.put(key, sensorData.get(key)); } } catch (SensorReadFailedException ex) { logger.error(ex); } } // Allow our consumers to consume the data model for (DataModelConsumer dataModelConsumer : this.dataModelConsumers) { dataModelConsumer.consumeDataModel(data); } // Write the model for (DataWriter dataWriter : this.dataWriters) { try { dataWriter.writeData(data); } // If we get some kind of exception, let's catch it here rather than just crashing the app catch (Exception e) { logger.error(e); } } // Handle any new camera images which are available if (this.cameraSensor != null) { cameraSensor.handleNewImages(); } controllerRunner.controllerFinishedRunLoop(data); } }