added auto-shutdown for faulty heaters
This commit is contained in:
parent
21ba8c95ff
commit
e81ddaa1a5
@ -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},
|
||||||
|
@ -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,29 +117,35 @@ 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);
|
||||||
HasHealthIF::HealthState health = heater.healthDevice->getHealth();
|
|
||||||
if (health == HasHealthIF::FAULTY or health == HasHealthIF::PERMANENT_FAULTY or
|
auto actionRaw = data[1];
|
||||||
health == HasHealthIF::NEEDS_RECOVERY) {
|
if (actionRaw != 0 and actionRaw != 1) {
|
||||||
return HasHealthIF::OBJECT_NOT_HEALTHY;
|
|
||||||
}
|
|
||||||
CmdSourceParam cmdSource = CmdSourceParam::EXTERNAL;
|
|
||||||
uint8_t cmdSourceRaw = data[2];
|
|
||||||
if(cmdSourceRaw > 1) {
|
|
||||||
return HasActionsIF::INVALID_PARAMETERS;
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
}
|
}
|
||||||
cmdSource = static_cast<CmdSourceParam>(data[2]);
|
auto action = static_cast<SwitchAction>(data[1]);
|
||||||
if(health == HasHealthIF::EXTERNAL_CONTROL and cmdSource == CmdSourceParam::INTERNAL) {
|
// Always accepts OFF commands
|
||||||
return HasHealthIF::IS_EXTERNALLY_CONTROLLED;
|
if (action == SwitchAction::SET_SWITCH_ON) {
|
||||||
|
HasHealthIF::HealthState health = heater.healthDevice->getHealth();
|
||||||
|
if (health == HasHealthIF::FAULTY or health == HasHealthIF::PERMANENT_FAULTY or
|
||||||
|
health == HasHealthIF::NEEDS_RECOVERY) {
|
||||||
|
return HasHealthIF::OBJECT_NOT_HEALTHY;
|
||||||
|
}
|
||||||
|
CmdSourceParam cmdSource = CmdSourceParam::EXTERNAL;
|
||||||
|
uint8_t cmdSourceRaw = data[2];
|
||||||
|
if (cmdSourceRaw > 1) {
|
||||||
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
|
}
|
||||||
|
cmdSource = static_cast<CmdSourceParam>(data[2]);
|
||||||
|
if (health == HasHealthIF::EXTERNAL_CONTROL and cmdSource == CmdSourceParam::INTERNAL) {
|
||||||
|
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 {
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user