/* * 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.consumer; import java.util.Map; import org.apache.log4j.Logger; /** * * @author dgorst */ public class TransistorSwitchController implements DataModelConsumer { private static final Logger logger = Logger.getLogger(TransistorSwitchController.class); private final double armingHeight; private final double switchingHeight; static final int NUMBER_OF_READINGS_FOR_CONFIDENCE = 5; private int armingReadings = 0; private int switchingReadings = 0; private boolean armed; private final TransistorSwitch transistorSwitch; private final String heightKey; public TransistorSwitchController(TransistorSwitch transistorSwitch, double armingHeight, double switchingHeight, String heightKey) { this.transistorSwitch = transistorSwitch; this.armingHeight = armingHeight; this.switchingHeight = switchingHeight; this.heightKey = heightKey; } public boolean isArmed() { return armed; } @Override public void consumeDataModel(Map<String, Object> dataModel) { if (dataModel == null) { logger.warn("Could not consume null data model"); return; } Object heightValue = dataModel.get(heightKey); if (heightValue == null) { logger.warn("No data found against the " + heightKey + " key within the data model"); return; } if (heightValue instanceof Double) { processHeight((double) heightValue); } else { logger.warn("Object of wrong type passed for height. Object passed was: " + heightValue); } } /** * Once we go above a threshold height, arm the controller. Once we * subsequently go below a threshold, switch the transistorSwitch on. * * @param height Current height of the balloon */ public void processHeight(double height) { if (!armed) { armIfReady(height); } else { switchIfReady(height); } } /** * Calculate if we should arm the controller. For this, we require a number * of consecutive readings above the arming threshold. * * @param height */ private void armIfReady(double height) { if (height > armingHeight) { ++armingReadings; } else { armingReadings = 0; } if (armingReadings >= NUMBER_OF_READINGS_FOR_CONFIDENCE) { armed = true; logger.info("Transistor switch armed"); } } /** * Calculate if we should turn on the transistorSwitch. For this, we require * a number of consecutive readings below the switching threshold. * * @param height */ private void switchIfReady(double height) { if (height < switchingHeight) { ++switchingReadings; } else { switchingReadings = 0; } if (switchingReadings >= NUMBER_OF_READINGS_FOR_CONFIDENCE) { transistorSwitch.close(); logger.info("Transistor switch closed"); } } }