Queue a stop/start sequence only when it fits whole

This commit is contained in:
J. Nick Koston
2026-10-16 13:39:46 -10:00
parent 2369ddea9e
commit 3f6eafc880
4 changed files with 26 additions and 0 deletions
@@ -29,6 +29,9 @@ class DfrobotSen0395SettingsAction final : public Action<Ts...>, public Parented
TEMPLATABLE_VALUE(float, det_max4)
void play(const Ts &...x) override {
// Worst case: stop, factory reset, six settings, save, start
if (!this->parent_->has_queue_room(10))
return;
this->parent_->enqueue(CommandType::COMMAND_TYPE_POWER, false);
if (this->factory_reset_.has_value() && this->factory_reset_.value(x...) == true) {
this->parent_->enqueue(CommandType::COMMAND_TYPE_FACTORY_RESET);
@@ -57,6 +57,13 @@ bool DfrobotSen0395Component::enqueue(CommandType type, uint8_t arg) {
return true;
}
bool DfrobotSen0395Component::has_queue_room(size_t count) const {
if (COMMAND_QUEUE_SIZE - this->cmd_queue_.size() >= count)
return true;
ESP_LOGE(TAG, "Command queue is full");
return false;
}
void DfrobotSen0395Component::enqueue_det_range_cfg(float min1, float max1, float min2, float max2, float min3,
float max3, float min4, float max4) {
// TODO: Print warning when values are rounded
@@ -89,6 +96,8 @@ void DfrobotSen0395Component::enqueue_set_latency(float delay_after_detection, f
void DfrobotSen0395Component::enqueue_saved_setting(CommandType type, bool value) {
const bool was_active = this->active_;
if (!this->has_queue_room(was_active ? 4 : 2))
return;
if (was_active)
this->enqueue(CommandType::COMMAND_TYPE_POWER, false);
this->enqueue(type, value);
@@ -97,6 +97,8 @@ class DfrobotSen0395Component final : public uart::UARTDevice, public Component
// Commands run one at a time from a queue, at least 1 s apart, so loop() never blocks
bool enqueue(CommandType type, uint8_t arg = 0);
/// True when count more commands fit; logs when they do not, so a stop/start sequence is never queued in part
bool has_queue_room(size_t count) const;
/// Queue a detection range config; segments are used up to the first one with a negative bound
void enqueue_det_range_cfg(float min1, float max1, float min2, float max2, float min3, float max3, float min4,
float max4);
@@ -142,4 +142,16 @@ TEST_F(SettingsActionTest, FloatTriggerUnpairedSegmentIsNotEvaluated) {
EXPECT_EQ(call_record().segment_calls[0], 0);
}
TEST_F(SettingsActionTest, QueuesNothingWithoutRoomForWholeSequence) {
for (int i = 0; i < 11; i++)
ASSERT_TRUE(this->radar_.enqueue(CommandType::COMMAND_TYPE_SAVE_CFG));
DfrobotSen0395SettingsAction<> action;
action.set_parent(&this->radar_);
action.play();
EXPECT_TRUE(this->radar_.has_queue_room(9));
this->radar_.enqueue_saved_setting(CommandType::COMMAND_TYPE_LED_MODE, true);
EXPECT_TRUE(this->radar_.has_queue_room(7));
EXPECT_FALSE(this->radar_.has_queue_room(8));
}
} // namespace esphome::dfrobot_sen0395::testing