added auto-shutdown for faulty heaters

This commit is contained in:
Robin Müller 2022-05-12 20:44:36 +02:00
parent 21ba8c95ff
commit e81ddaa1a5
No known key found for this signature in database
GPG Key ID: 11D4952C8CCEF814
3 changed files with 51 additions and 33 deletions

View File

@ -526,7 +526,8 @@ void ObjectFactory::createHeaterComponents(GpioIF* gpioIF, PowerSwitchIF* pwrSwi
gpioIF->addGpios(heaterGpiosCookie); gpioIF->addGpios(heaterGpiosCookie);
HeaterHelper helper({{ HeaterHelper helper({{
{new HealthDevice(objects::HEATER_0_PLOC_PROC_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_0}, {new HealthDevice(objects::HEATER_0_PLOC_PROC_BRD, MessageQueueIF::NO_QUEUE),
gpioIds::HEATER_0},
{new HealthDevice(objects::HEATER_1_PCDU_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_1}, {new HealthDevice(objects::HEATER_1_PCDU_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_1},
{new HealthDevice(objects::HEATER_2_ACS_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_2}, {new HealthDevice(objects::HEATER_2_ACS_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_2},
{new HealthDevice(objects::HEATER_3_OBC_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_3}, {new HealthDevice(objects::HEATER_3_OBC_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_3},

View File

@ -43,10 +43,10 @@ HeaterHandler::~HeaterHandler() {}
ReturnValue_t HeaterHandler::performOperation(uint8_t operationCode) { ReturnValue_t HeaterHandler::performOperation(uint8_t operationCode) {
try { try {
readCommandQueue(); readCommandQueue();
handleActiveCommands();
for (const auto& heater : helper.heaters) { for (const auto& heater : helper.heaters) {
heater.first->performOperation(0); heater.first->performOperation(0);
} }
handleSwitchHandling();
} catch (const std::out_of_range& e) { } catch (const std::out_of_range& e) {
sif::warning << "HeaterHandler::performOperation: " sif::warning << "HeaterHandler::performOperation: "
"Out of range error | " "Out of range error | "
@ -117,6 +117,14 @@ ReturnValue_t HeaterHandler::executeAction(ActionId_t actionId, MessageQueueId_t
return HasActionsIF::INVALID_PARAMETERS; return HasActionsIF::INVALID_PARAMETERS;
} }
auto& heater = heaterVec.at(switchNr); auto& heater = heaterVec.at(switchNr);
auto actionRaw = data[1];
if (actionRaw != 0 and actionRaw != 1) {
return HasActionsIF::INVALID_PARAMETERS;
}
auto action = static_cast<SwitchAction>(data[1]);
// Always accepts OFF commands
if (action == SwitchAction::SET_SWITCH_ON) {
HasHealthIF::HealthState health = heater.healthDevice->getHealth(); HasHealthIF::HealthState health = heater.healthDevice->getHealth();
if (health == HasHealthIF::FAULTY or health == HasHealthIF::PERMANENT_FAULTY or if (health == HasHealthIF::FAULTY or health == HasHealthIF::PERMANENT_FAULTY or
health == HasHealthIF::NEEDS_RECOVERY) { health == HasHealthIF::NEEDS_RECOVERY) {
@ -131,15 +139,13 @@ ReturnValue_t HeaterHandler::executeAction(ActionId_t actionId, MessageQueueId_t
if (health == HasHealthIF::EXTERNAL_CONTROL and cmdSource == CmdSourceParam::INTERNAL) { if (health == HasHealthIF::EXTERNAL_CONTROL and cmdSource == CmdSourceParam::INTERNAL) {
return HasHealthIF::IS_EXTERNALLY_CONTROLLED; return HasHealthIF::IS_EXTERNALLY_CONTROLLED;
} }
if (heater.active) { }
if (heater.cmdActive) {
return COMMAND_ALREADY_WAITING; return COMMAND_ALREADY_WAITING;
} }
auto action = data[1]; heater.action = action;
if (action != 0 and action != 1) { heater.cmdActive = true;
return HasActionsIF::INVALID_PARAMETERS;
}
heater.action = static_cast<SwitchAction>(data[1]);
heater.active = true;
heater.replyQueue = commandedBy; heater.replyQueue = commandedBy;
return RETURN_OK; return RETURN_OK;
} }
@ -179,9 +185,21 @@ ReturnValue_t HeaterHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t o
return result; return result;
} }
void HeaterHandler::handleActiveCommands() { void HeaterHandler::handleSwitchHandling() {
for (uint8_t idx = 0; idx < heater::NUMBER_OF_SWITCHES; idx++) { for (uint8_t idx = 0; idx < heater::NUMBER_OF_SWITCHES; idx++) {
if (heaterVec[idx].active) { auto health = heaterVec[idx].healthDevice->getHealth();
if (heaterVec[idx].switchState == SwitchState::ON) {
// If a heater is still on but the device was marked faulty by the operator, the SW
// will shut down the heater
if (health == HasHealthIF::FAULTY or health == HasHealthIF::PERMANENT_FAULTY) {
heaterVec[idx].cmdActive = true;
heaterVec[idx].action = SET_SWITCH_OFF;
triggerEvent(FAULTY_HEATER_WAS_ON, idx, 0);
handleSwitchOffCommand(static_cast<heater::Switchers>(idx));
continue;
}
}
if (heaterVec[idx].cmdActive) {
switch (heaterVec[idx].action) { switch (heaterVec[idx].action) {
case SET_SWITCH_ON: case SET_SWITCH_ON:
handleSwitchOnCommand(static_cast<heater::Switchers>(idx)); handleSwitchOnCommand(static_cast<heater::Switchers>(idx));
@ -207,7 +225,7 @@ void HeaterHandler::handleSwitchOnCommand(heater::Switchers heaterIdx) {
triggerEvent(MAIN_SWITCH_TIMEOUT); triggerEvent(MAIN_SWITCH_TIMEOUT);
sif::error << "HeaterHandler::handleSwitchOnCommand: Main switch setting on timeout" sif::error << "HeaterHandler::handleSwitchOnCommand: Main switch setting on timeout"
<< std::endl; << std::endl;
heater.active = false; heater.cmdActive = false;
heater.waitMainSwitchOn = false; heater.waitMainSwitchOn = false;
if (heater.replyQueue != commandQueue->getId()) { if (heater.replyQueue != commandQueue->getId()) {
actionHelper.finish(false, heater.replyQueue, heater.action, MAIN_SWITCH_SET_TIMEOUT); actionHelper.finish(false, heater.replyQueue, heater.action, MAIN_SWITCH_SET_TIMEOUT);
@ -241,7 +259,7 @@ void HeaterHandler::handleSwitchOnCommand(heater::Switchers heaterIdx) {
actionHelper.finish(false, heater.replyQueue, heater.action, result); actionHelper.finish(false, heater.replyQueue, heater.action, result);
} }
} }
heater.active = false; heater.cmdActive = false;
heater.waitMainSwitchOn = false; heater.waitMainSwitchOn = false;
} else if (mainSwitchState == PowerSwitchIF::SWITCH_OFF && heater.waitMainSwitchOn) { } else if (mainSwitchState == PowerSwitchIF::SWITCH_OFF && heater.waitMainSwitchOn) {
// Just waiting for the main switch being set on // Just waiting for the main switch being set on
@ -251,12 +269,12 @@ void HeaterHandler::handleSwitchOnCommand(heater::Switchers heaterIdx) {
heater.mainSwitchCountdown.setTimeout(mainLineSwitcher->getSwitchDelayMs()); heater.mainSwitchCountdown.setTimeout(mainLineSwitcher->getSwitchDelayMs());
heater.waitMainSwitchOn = true; heater.waitMainSwitchOn = true;
} else { } else {
sif::debug << "HeaterHandler::handleActiveCommands: Failed to get state of" sif::debug << "HeaterHandler::handleSwitchHandling: Failed to get state of"
<< " main line switch" << std::endl; << " main line switch" << std::endl;
if (heater.replyQueue != commandQueue->getId()) { if (heater.replyQueue != commandQueue->getId()) {
actionHelper.finish(false, heater.replyQueue, heater.action, mainSwitchState); actionHelper.finish(false, heater.replyQueue, heater.action, mainSwitchState);
} }
heater.active = false; heater.cmdActive = false;
} }
} }
@ -295,7 +313,7 @@ void HeaterHandler::handleSwitchOffCommand(heater::Switchers heaterIdx) {
actionHelper.finish(false, heater.replyQueue, heater.action, result); actionHelper.finish(false, heater.replyQueue, heater.action, result);
} }
} }
heater.active = false; heater.cmdActive = false;
} }
HeaterHandler::SwitchState HeaterHandler::checkSwitchState(heater::Switchers switchNr) const { HeaterHandler::SwitchState HeaterHandler::checkSwitchState(heater::Switchers switchNr) const {

View File

@ -46,10 +46,7 @@ class HeaterHandler : public ExecutableObjectIF,
static const ReturnValue_t MAIN_SWITCH_SET_TIMEOUT = MAKE_RETURN_CODE(0xA4); static const ReturnValue_t MAIN_SWITCH_SET_TIMEOUT = MAKE_RETURN_CODE(0xA4);
static const ReturnValue_t COMMAND_ALREADY_WAITING = MAKE_RETURN_CODE(0xA5); static const ReturnValue_t COMMAND_ALREADY_WAITING = MAKE_RETURN_CODE(0xA5);
enum CmdSourceParam: uint8_t { enum CmdSourceParam : uint8_t { INTERNAL = 0, EXTERNAL = 1 };
INTERNAL = 0,
EXTERNAL = 1
};
/** Device command IDs */ /** Device command IDs */
static const DeviceCommandId_t SWITCH_HEATER = 0x0; static const DeviceCommandId_t SWITCH_HEATER = 0x0;
@ -85,6 +82,8 @@ class HeaterHandler : public ExecutableObjectIF,
static constexpr Event SWITCH_ALREADY_ON = MAKE_EVENT(4, severity::LOW); static constexpr Event SWITCH_ALREADY_ON = MAKE_EVENT(4, severity::LOW);
static constexpr Event SWITCH_ALREADY_OFF = MAKE_EVENT(5, severity::LOW); static constexpr Event SWITCH_ALREADY_OFF = MAKE_EVENT(5, severity::LOW);
static constexpr Event MAIN_SWITCH_TIMEOUT = MAKE_EVENT(6, severity::MEDIUM); static constexpr Event MAIN_SWITCH_TIMEOUT = MAKE_EVENT(6, severity::MEDIUM);
//! A faulty heater was one. The SW will autonomously attempt to shut it down. P1: Heater Index
static constexpr Event FAULTY_HEATER_WAS_ON = event::makeEvent(SUBSYSTEM_ID, 7, severity::LOW);
static const MessageQueueId_t NO_COMMANDER = 0; static const MessageQueueId_t NO_COMMANDER = 0;
@ -108,7 +107,7 @@ class HeaterHandler : public ExecutableObjectIF,
gpioId_t gpioId = gpio::NO_GPIO; gpioId_t gpioId = gpio::NO_GPIO;
SwitchAction action = SwitchAction::NONE; SwitchAction action = SwitchAction::NONE;
MessageQueueId_t replyQueue = MessageQueueIF::NO_QUEUE; MessageQueueId_t replyQueue = MessageQueueIF::NO_QUEUE;
bool active = false; bool cmdActive = false;
SwitchState switchState = SwitchState::OFF; SwitchState switchState = SwitchState::OFF;
bool waitMainSwitchOn = false; bool waitMainSwitchOn = false;
Countdown mainSwitchCountdown; Countdown mainSwitchCountdown;
@ -153,7 +152,7 @@ class HeaterHandler : public ExecutableObjectIF,
/** /**
* @brief This function runs commands waiting for execution. * @brief This function runs commands waiting for execution.
*/ */
void handleActiveCommands(); void handleSwitchHandling();
ReturnValue_t initializeHeaterMap(); ReturnValue_t initializeHeaterMap();