Public Access
Rules can be limited to schedule blocks
Each rule has the blocks it acts in (none: always; without a running schedule always). Stored as a block mask (schedule format 2, version 1 records are converted), in JSON as the blocks' start times. Version 2.7.1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
87e242bf89
commit
53e9057d02
11 files changed
+166
-19
No files matched your search
@@ -60,6 +60,8 @@ const char *validateSchedule(const PageSchedule &s)
|
||||
return "Rule times must be 1 to 3600 seconds";
|
||||
if (r.interval < RULE_INTERVAL_MIN || r.interval > RULE_INTERVAL_MAX)
|
||||
return "Rules are read every 2 to 600 seconds";
|
||||
if (r.blocks >> s.block_count)
|
||||
return "A rule is set for a block that doesn't exist";
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -79,6 +81,11 @@ static bool number(const char *text, double &value)
|
||||
return end != text && *end == '\0';
|
||||
}
|
||||
|
||||
bool ruleInBlock(const TriggerRule &rule, int block)
|
||||
{
|
||||
return rule.blocks == 0 || block < 0 || (rule.blocks >> block) & 1;
|
||||
}
|
||||
|
||||
bool ruleMatches(const TriggerRule &rule, const char *value)
|
||||
{
|
||||
if (value == nullptr)
|
||||
|
||||
@@ -63,6 +63,7 @@ struct TriggerRule
|
||||
TriggerMode mode = TriggerMode::WhileTrue;
|
||||
uint16_t seconds = 30; // AddToRotation: time in the rotation; ForSeconds: how long
|
||||
uint16_t interval = 10; // read the entity this often (s)
|
||||
uint8_t blocks = 0; // bit i: active during block i; 0: always (also without a schedule)
|
||||
};
|
||||
|
||||
struct PageSchedule
|
||||
@@ -78,6 +79,9 @@ struct PageSchedule
|
||||
// the pages exist.
|
||||
const char *validateSchedule(const PageSchedule &schedule);
|
||||
|
||||
// Whether a rule acts during this block (-1: no schedule runs, then always)
|
||||
bool ruleInBlock(const TriggerRule &rule, int block);
|
||||
|
||||
// Whether a rule's condition is true for this value (nullptr: not known, never true)
|
||||
bool ruleMatches(const TriggerRule &rule, const char *value);
|
||||
|
||||
|
||||
@@ -104,8 +104,9 @@ PageChoice PageSelector::update(int minute, uint32_t now)
|
||||
const TriggerRule &r = _schedule->rules[i];
|
||||
if (r.mode == TriggerMode::ForSeconds && _rule_timer[i] && now - _rule_since[i] >= r.seconds * 1000UL)
|
||||
_rule_timer[i] = false;
|
||||
bool takes_over = (r.mode == TriggerMode::WhileTrue && _rule_active[i]) ||
|
||||
(r.mode == TriggerMode::ForSeconds && _rule_timer[i]);
|
||||
bool takes_over = ((r.mode == TriggerMode::WhileTrue && _rule_active[i]) ||
|
||||
(r.mode == TriggerMode::ForSeconds && _rule_timer[i])) &&
|
||||
ruleInBlock(r, _block);
|
||||
if (takes_over)
|
||||
{
|
||||
choice.page = r.page;
|
||||
@@ -137,7 +138,7 @@ PageChoice PageSelector::update(int minute, uint32_t now)
|
||||
for (int i = 0; i < rule_count; i++)
|
||||
{
|
||||
const TriggerRule &r = _schedule->rules[i];
|
||||
if (r.mode == TriggerMode::AddToRotation && _rule_active[i])
|
||||
if (r.mode == TriggerMode::AddToRotation && _rule_active[i] && ruleInBlock(r, _block))
|
||||
items[count++] = {r.page, r.seconds * 1000UL, ShowReason::Rotation, i};
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
#include "logic/page_schedule.h"
|
||||
|
||||
// Decides which page or bitmap is shown, from (highest priority first):
|
||||
// 1. take-over rules (TriggerMode::WhileTrue / ForSeconds), in their order
|
||||
// 1. take-over rules (TriggerMode::WhileTrue / ForSeconds), in their order; a rule can be
|
||||
// limited to some schedule blocks (TriggerRule::blocks)
|
||||
// 2. a manual pick (web UI, Home Assistant "Mode"), until the next schedule block starts
|
||||
// 3. the schedule: the pages of the current block rotate, plus the pages of active
|
||||
// AddToRotation rules
|
||||
|
||||
Reference in new issue
Block a user