#include "../monitoring/LimitViolationReporter.h" #include "../monitoring/MonitoringMessageContent.h" #include "ThermalModule.h" #include "AbstractTemperatureSensor.h" ThermalModule::ThermalModule(uint32_t moduleTemperaturePoolId, uint32_t currentStatePoolId, uint32_t targetStatePoolId, DataSet *dataSet, Parameters parameters, RedundantHeater::Parameters heaterParameters) : oldStrategy(ACTIVE_SINGLE), survivalTargetTemp(0), targetTemp(0), heating( false), parameters(parameters), moduleTemperature( moduleTemperaturePoolId, dataSet, PoolVariableIF::VAR_WRITE), currentState( currentStatePoolId, dataSet, PoolVariableIF::VAR_WRITE), targetState( targetStatePoolId, dataSet, PoolVariableIF::VAR_READ) { heater = new RedundantHeater(heaterParameters); } ThermalModule::ThermalModule(uint32_t moduleTemperaturePoolId, DataSet* dataSet) : oldStrategy(ACTIVE_SINGLE), survivalTargetTemp(0), targetTemp(0), heating( false), parameters( { 0, 0 }), moduleTemperature( moduleTemperaturePoolId, dataSet, PoolVariableIF::VAR_WRITE), heater( NULL), currentState(PoolVariableIF::INVALID, dataSet, PoolVariableIF::VAR_WRITE), targetState(PoolVariableIF::INVALID, dataSet, PoolVariableIF::VAR_READ) { } ThermalModule::~ThermalModule() { delete heater; } void ThermalModule::performOperation(uint8_t opCode) { if (heater != NULL) { heater->performOperation(0); } } void ThermalModule::performMode(Strategy strategy) { calculateTemperature(); bool safeOnly = (strategy == ACTIVE_SURVIVAL); ThermalComponentIF::HeaterRequest componentHeaterRequest = letComponentsPerformAndDeciceIfWeNeedToHeat(safeOnly); if (heater == NULL) { informComponentsAboutHeaterState(false, NONE); return; } bool heating = calculateModuleHeaterRequestAndSetModuleStatus(strategy); if (componentHeaterRequest != ThermalComponentIF::HEATER_DONT_CARE) { //Components overwrite the module request. heating = ((componentHeaterRequest == ThermalComponentIF::HEATER_REQUEST_ON) || (componentHeaterRequest == ThermalComponentIF::HEATER_REQUEST_EMERGENCY_ON)); } bool dual = (strategy == ACTIVE_DUAL); if (strategy == PASSIVE) { informComponentsAboutHeaterState(false, NONE); if (oldStrategy != PASSIVE) { heater->set(false, false, true); } } else { if (safeOnly) { informComponentsAboutHeaterState(heating, SAFE); } else { informComponentsAboutHeaterState(heating, ALL); } heater->set(heating, dual); } oldStrategy = strategy; } float ThermalModule::getTemperature() { return moduleTemperature; } void ThermalModule::registerSensor(AbstractTemperatureSensor * sensor) { sensors.push_back(sensor); } void ThermalModule::registerComponent(ThermalComponentIF* component, ThermalComponentIF::Priority priority) { components.push_back(ComponentData( { component, priority, ThermalComponentIF::HEATER_DONT_CARE })); } void ThermalModule::calculateTemperature() { uint32_t numberOfValidSensors = 0; moduleTemperature = 0; std::list::iterator iter = sensors.begin(); for (; iter != sensors.end(); iter++) { if ((*iter)->isValid()) { moduleTemperature = moduleTemperature + (*iter)->getTemperature(); numberOfValidSensors++; } } if (numberOfValidSensors != 0) { moduleTemperature = moduleTemperature / numberOfValidSensors; moduleTemperature.setValid(PoolVariableIF::VALID); } else { moduleTemperature = INVALID_TEMPERATURE; moduleTemperature.setValid(PoolVariableIF::INVALID); } } ThermalComponentIF* ThermalModule::findComponent(object_id_t objectId) { std::list::iterator iter = components.begin(); for (; iter != components.end(); iter++) { if (iter->component->getObjectId() == objectId) { return iter->component; } } return NULL; } ThermalComponentIF::HeaterRequest ThermalModule::letComponentsPerformAndDeciceIfWeNeedToHeat( bool safeOnly) { ThermalComponentIF::HeaterRequest heaterRequests[ThermalComponentIF::NUMBER_OF_PRIORITIES]; survivalTargetTemp = -999; targetTemp = -999; for (uint8_t i = 0; i < ThermalComponentIF::NUMBER_OF_PRIORITIES; i++) { heaterRequests[i] = ThermalComponentIF::HEATER_DONT_CARE; } std::list::iterator iter = components.begin(); for (; iter != components.end(); iter++) { updateTargetTemperatures(iter->component, iter->priority == ThermalComponentIF::SAFE); ThermalComponentIF::HeaterRequest request = iter->component->performOperation(0); iter->request = request; if (request != ThermalComponentIF::HEATER_DONT_CARE) { if (request < heaterRequests[iter->priority]) { heaterRequests[iter->priority] = request; } } } if (!safeOnly) { for (uint8_t i = ThermalComponentIF::NUMBER_OF_PRIORITIES - 1; i > 0; i--) { if (heaterRequests[i - 1] == ThermalComponentIF::HEATER_DONT_CARE) { heaterRequests[i - 1] = heaterRequests[i]; } } } return heaterRequests[0]; } void ThermalModule::informComponentsAboutHeaterState(bool heaterIsOn, Informee whomToInform) { std::list::iterator iter = components.begin(); for (; iter != components.end(); iter++) { switch (whomToInform) { case ALL: break; case SAFE: if (!(iter->priority == ThermalComponentIF::SAFE)) { iter->component->markStateIgnored(); continue; } break; case NONE: iter->component->markStateIgnored(); continue; } if (heaterIsOn) { if ((iter->request == ThermalComponentIF::HEATER_REQUEST_EMERGENCY_OFF) || (iter->request == ThermalComponentIF::HEATER_REQUEST_OFF)) { iter->component->markStateIgnored(); } } else { if ((iter->request == ThermalComponentIF::HEATER_REQUEST_EMERGENCY_ON) || (iter->request == ThermalComponentIF::HEATER_REQUEST_ON)) { iter->component->markStateIgnored(); } } } } void ThermalModule::initialize(PowerSwitchIF* powerSwitch) { if (heater != NULL) { heater->setPowerSwitcher(powerSwitch); } std::list::iterator iter = components.begin(); for (; iter != components.end(); iter++) { float componentLowerOpLimit = iter->component->getLowerOpLimit(); if (iter->priority == ThermalComponentIF::SAFE) { if (componentLowerOpLimit > survivalTargetTemp) { survivalTargetTemp = componentLowerOpLimit; } } else { if (componentLowerOpLimit > targetTemp) { targetTemp = componentLowerOpLimit; } } } if (survivalTargetTemp > targetTemp) { targetTemp = survivalTargetTemp; } } bool ThermalModule::calculateModuleHeaterRequestAndSetModuleStatus( Strategy strategy) { currentState.setValid(PoolVariableIF::VALID); if (moduleTemperature == INVALID_TEMPERATURE) { currentState = UNKNOWN; return false; } float limit = targetTemp; bool heaterRequest = false; if (strategy == ACTIVE_SURVIVAL) { limit = survivalTargetTemp; } if (moduleTemperature >= limit) { currentState = OPERATIONAL; } else { currentState = NON_OPERATIONAL; } limit += parameters.heaterOn; if (heating) { limit += parameters.hysteresis; } if (targetState == STATE_REQUEST_HEATING) { if (moduleTemperature < limit) { heaterRequest = true; } else { heaterRequest = false; } } heating = heaterRequest; return heaterRequest; } void ThermalModule::setHeating(bool on) { DataSet mySet; PoolVariable writableTargetState(targetState.getDataPoolId(), &mySet, PoolVariableIF::VAR_WRITE); if (on) { writableTargetState = STATE_REQUEST_HEATING; } else { writableTargetState = STATE_REQUEST_PASSIVE; } mySet.commit(PoolVariableIF::VALID); } void ThermalModule::updateTargetTemperatures(ThermalComponentIF* component, bool isSafe) { if (isSafe) { if (component->getLowerOpLimit() > survivalTargetTemp) { survivalTargetTemp = component->getLowerOpLimit(); } } else { if (component->getLowerOpLimit() > targetTemp) { targetTemp = component->getLowerOpLimit(); } } } void ThermalModule::setOutputInvalid() { moduleTemperature = INVALID_TEMPERATURE; moduleTemperature.setValid(PoolVariableIF::INVALID); currentState.setValid(PoolVariableIF::INVALID); std::list::iterator iter = components.begin(); for (; iter != components.end(); iter++) { iter->component->setOutputInvalid(); } if (heater != NULL) { heater->set(false,true); } }