Add {clock} field for notification timestamps; fix offline preview path and validator allowlist
This commit is contained in:
@@ -166,6 +166,12 @@ def stamp():
|
|||||||
return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
|
||||||
|
|
||||||
|
def clock_stamp():
|
||||||
|
now = datetime.now()
|
||||||
|
hour12 = now.hour % 12 or 12
|
||||||
|
return f"{hour12}:{now.minute:02d} {now.strftime('%p')}"
|
||||||
|
|
||||||
|
|
||||||
class Reporter:
|
class Reporter:
|
||||||
def __init__(self, log_path=None, quiet=False):
|
def __init__(self, log_path=None, quiet=False):
|
||||||
self.quiet = quiet
|
self.quiet = quiet
|
||||||
@@ -355,6 +361,7 @@ class Engine:
|
|||||||
"target_host": self.target.host,
|
"target_host": self.target.host,
|
||||||
"target_channel": self.target.channel,
|
"target_channel": self.target.channel,
|
||||||
"time": stamp(),
|
"time": stamp(),
|
||||||
|
"clock": clock_stamp(),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return context
|
return context
|
||||||
|
|||||||
+6
-6
@@ -43,7 +43,7 @@ ACTIONS = {"target.on", "target.off", "none"}
|
|||||||
DURATION_PATTERN = re.compile(r"^\s*(\d+(?:\.\d+)?)\s*([smh]?)\s*$", re.IGNORECASE)
|
DURATION_PATTERN = re.compile(r"^\s*(\d+(?:\.\d+)?)\s*([smh]?)\s*$", re.IGNORECASE)
|
||||||
|
|
||||||
DEFAULT_NOTIFY_TEMPLATE = (
|
DEFAULT_NOTIFY_TEMPLATE = (
|
||||||
"{source_name} battery {battery_soc}%, solar {pv_total}W. "
|
"{clock} {source_name} battery {battery_soc}%, solar {pv_total}W. "
|
||||||
"{target_name} turned {action}."
|
"{target_name} turned {action}."
|
||||||
)
|
)
|
||||||
DEFAULT_NOTIFY_THROTTLE = 300
|
DEFAULT_NOTIFY_THROTTLE = 300
|
||||||
@@ -197,14 +197,14 @@ class NotificationSettings:
|
|||||||
self.stale_template = str(
|
self.stale_template = str(
|
||||||
raw.get("stale_template")
|
raw.get("stale_template")
|
||||||
or (
|
or (
|
||||||
"{source_name}: telemetry lost ({reason}). Last seen battery "
|
"{clock} {source_name}: telemetry lost ({reason}). Last seen "
|
||||||
"{battery_soc}% at {last_seen}. {target_name} was turned {action} "
|
"battery {battery_soc}% at {last_seen}. {target_name} was "
|
||||||
"as a precaution."
|
"turned {action} as a precaution."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.recovered_template = str(
|
self.recovered_template = str(
|
||||||
raw.get("recovered_template")
|
raw.get("recovered_template")
|
||||||
or "{source_name}: telemetry is back after {outage}. Rules resumed."
|
or "{clock} {source_name}: telemetry is back after {outage}. Rules resumed."
|
||||||
)
|
)
|
||||||
self.title = str(raw.get("title") or "{profile}")
|
self.title = str(raw.get("title") or "{profile}")
|
||||||
self.throttle = parse_duration(
|
self.throttle = parse_duration(
|
||||||
@@ -537,7 +537,7 @@ def validate(profile):
|
|||||||
context_names = {
|
context_names = {
|
||||||
"profile", "rule", "action", "action_word", "source_name", "source_model",
|
"profile", "rule", "action", "action_word", "source_name", "source_model",
|
||||||
"source_serial", "target_name", "target_model", "target_host",
|
"source_serial", "target_name", "target_model", "target_host",
|
||||||
"target_channel", "condition", "time", "reason", "event",
|
"target_channel", "condition", "time", "clock", "reason", "event",
|
||||||
}
|
}
|
||||||
for template in templates_to_check:
|
for template in templates_to_check:
|
||||||
for field in notify_module.template_fields(template):
|
for field in notify_module.template_fields(template):
|
||||||
|
|||||||
Reference in New Issue
Block a user