feat: -f/-v/-e flags, 5-field TSV with tags in field 2

This commit is contained in:
Lewis Wynne 2026-04-02 15:46:16 +01:00
parent 6b7fef5d2c
commit 2b36640567
9 changed files with 76 additions and 58 deletions

66
nag
View file

@ -304,16 +304,16 @@ do
-h|--help) -h|--help)
_SUBCOMMAND="help" _SUBCOMMAND="help"
;; ;;
-e|--edit) -e)
_SUBCOMMAND="edit" _SUBCOMMAND="edit"
;; ;;
--version) -v)
_SUBCOMMAND="version" _SUBCOMMAND="version"
;; ;;
--debug) --debug)
_USE_DEBUG=1 _USE_DEBUG=1
;; ;;
--yes) -f)
_YES=1 _YES=1
;; ;;
*) *)
@ -511,8 +511,8 @@ _next_id() {
# #
# Description: # Description:
# Extract a field from a TSV alarm line. # Extract a field from a TSV alarm line.
# Fields: 1=id, 2=timestamp, 3=rule, 4=message. # Fields: 1=id, 2=tags, 3=timestamp, 4=rule, 5=message.
# For field 4 (message), returns everything after the 3rd tab. # For field 5 (message), returns everything after the 4th tab.
_get_alarm_field() { _get_alarm_field() {
local _line="${1}" local _line="${1}"
local _field="${2}" local _field="${2}"
@ -522,7 +522,7 @@ _get_alarm_field() {
do do
_rest="${_rest#*$'\t'}" _rest="${_rest#*$'\t'}"
done done
if (( _field == 4 )) if (( _field == 5 ))
then then
printf "%s" "${_rest}" printf "%s" "${_rest}"
else else
@ -938,7 +938,7 @@ _parse_time() {
# Description: # Description:
# Check whether a systemd user timer for `nag check` is active. # Check whether a systemd user timer for `nag check` is active.
# If not, prompt the user to install one (or install automatically # If not, prompt the user to install one (or install automatically
# when --yes is set). Falls back to cron if systemd is unavailable. # when -f is set). Falls back to cron if systemd is unavailable.
_prompt_timer() { _prompt_timer() {
# Already running? # Already running?
if systemctl --user is-active nag.timer &>/dev/null if systemctl --user is-active nag.timer &>/dev/null
@ -1056,9 +1056,9 @@ Usage:
${_ME} version show version ${_ME} version show version
Options: Options:
-e, --edit Edit alarms file directly. -e Edit alarms file directly.
--yes Skip all prompts. -f Skip all prompts.
--version Show version. -v Show version.
Environment: Environment:
NAG_DIR Alarm storage directory (default: ~/.local/share/nag) NAG_DIR Alarm storage directory (default: ~/.local/share/nag)
@ -1072,7 +1072,7 @@ HEREDOC
describe "version" <<HEREDOC describe "version" <<HEREDOC
Usage: Usage:
${_ME} ( version | --version ) ${_ME} ( version | -v )
Description: Description:
Display the current program version. Display the current program version.
@ -1105,9 +1105,9 @@ list() {
return 0 return 0
fi fi
# Sort alarms by timestamp (field 2). # Sort alarms by timestamp (field 3).
local -a _sorted local -a _sorted
IFS=$'\n' _sorted=($(printf "%s\n" "${_ALARMS[@]}" | sort -t$'\t' -k2 -n)) IFS=$'\n' _sorted=($(printf "%s\n" "${_ALARMS[@]}" | sort -t$'\t' -k3 -n))
IFS=$'\n\t' IFS=$'\n\t'
local _today _today_epoch local _today _today_epoch
@ -1118,9 +1118,10 @@ list() {
for _line in "${_sorted[@]}" for _line in "${_sorted[@]}"
do do
[[ -n "${_line}" ]] || continue [[ -n "${_line}" ]] || continue
local _id _timestamp _rule _message _human_time _rule_display local _id _tags _timestamp _rule _message _human_time _rule_display _tag_display
_id="${_line%%$'\t'*}"; local _rest="${_line#*$'\t'}" _id="${_line%%$'\t'*}"; local _rest="${_line#*$'\t'}"
_tags="${_rest%%$'\t'*}"; _rest="${_rest#*$'\t'}"
_timestamp="${_rest%%$'\t'*}"; _rest="${_rest#*$'\t'}" _timestamp="${_rest%%$'\t'*}"; _rest="${_rest#*$'\t'}"
_rule="${_rest%%$'\t'*}" _rule="${_rest%%$'\t'*}"
_message="${_rest#*$'\t'}" _message="${_rest#*$'\t'}"
@ -1135,7 +1136,14 @@ list() {
_rule_display="" _rule_display=""
fi fi
printf "[%s] %s%s — %s\\n" "${_id}" "${_human_time}" "${_rule_display}" "${_message}" if [[ -n "${_tags}" ]]
then
_tag_display=" [${_tags//,/, }]"
else
_tag_display=""
fi
printf "[%s]%s %s%s — %s\\n" "${_id}" "${_tag_display}" "${_human_time}" "${_rule_display}" "${_message}"
done done
} }
@ -1215,11 +1223,12 @@ skip() {
for _line in "${_ALARMS[@]:-}" for _line in "${_ALARMS[@]:-}"
do do
[[ -n "${_line}" ]] || continue [[ -n "${_line}" ]] || continue
local _id _timestamp _rule _message local _id _tags _timestamp _rule _message
_id="$(_get_alarm_field "${_line}" 1)" _id="$(_get_alarm_field "${_line}" 1)"
_timestamp="$(_get_alarm_field "${_line}" 2)" _tags="$(_get_alarm_field "${_line}" 2)"
_rule="$(_get_alarm_field "${_line}" 3)" _timestamp="$(_get_alarm_field "${_line}" 3)"
_message="$(_get_alarm_field "${_line}" 4)" _rule="$(_get_alarm_field "${_line}" 4)"
_message="$(_get_alarm_field "${_line}" 5)"
if [[ "${_id}" == "${_target_id}" ]] if [[ "${_id}" == "${_target_id}" ]]
then then
@ -1228,7 +1237,7 @@ skip() {
then then
local _next_ts _human_time local _next_ts _human_time
_next_ts="$(_next_occurrence "${_rule}" "${_timestamp}")" _next_ts="$(_next_occurrence "${_rule}" "${_timestamp}")"
_new_alarms+=("$(printf "%s\t%s\t%s\t%s" "${_id}" "${_next_ts}" "${_rule}" "${_message}")") _new_alarms+=("$(printf "%s\t%s\t%s\t%s\t%s" "${_id}" "${_tags}" "${_next_ts}" "${_rule}" "${_message}")")
_format_time "${_next_ts}" _format_time "${_next_ts}"
_human_time="${REPLY}" _human_time="${REPLY}"
printf "Skipped. Next: %s\\n" "${_human_time}" printf "Skipped. Next: %s\\n" "${_human_time}"
@ -1284,11 +1293,12 @@ check() {
do do
[[ -n "${_line}" ]] || continue [[ -n "${_line}" ]] || continue
local _id _timestamp _rule _message local _id _tags _timestamp _rule _message
_id="$(_get_alarm_field "${_line}" 1)" _id="$(_get_alarm_field "${_line}" 1)"
_timestamp="$(_get_alarm_field "${_line}" 2)" _tags="$(_get_alarm_field "${_line}" 2)"
_rule="$(_get_alarm_field "${_line}" 3)" _timestamp="$(_get_alarm_field "${_line}" 3)"
_message="$(_get_alarm_field "${_line}" 4)" _rule="$(_get_alarm_field "${_line}" 4)"
_message="$(_get_alarm_field "${_line}" 5)"
if (( _timestamp <= _now )) if (( _timestamp <= _now ))
then then
@ -1317,7 +1327,7 @@ check() {
# Repeating: reschedule. # Repeating: reschedule.
local _next_ts local _next_ts
_next_ts="$(_next_occurrence "${_rule}" "${_timestamp}")" _next_ts="$(_next_occurrence "${_rule}" "${_timestamp}")"
_new_alarms+=("$(printf "%s\t%s\t%s\t%s" "${_id}" "${_next_ts}" "${_rule}" "${_message}")") _new_alarms+=("$(printf "%s\t%s\t%s\t%s\t%s" "${_id}" "${_tags}" "${_next_ts}" "${_rule}" "${_message}")")
fi fi
# One-shot: drop it (don't add to _new_alarms). # One-shot: drop it (don't add to _new_alarms).
else else
@ -1371,7 +1381,7 @@ at() {
# _next_id calls _read_alarms in a subshell, so _ALARMS isn't populated here. # _next_id calls _read_alarms in a subshell, so _ALARMS isn't populated here.
_read_alarms _read_alarms
_ALARMS+=("$(printf "%s\t%s\t\t%s" "${_id}" "${_timestamp}" "${_message}")") _ALARMS+=("$(printf "%s\t\t%s\t\t%s" "${_id}" "${_timestamp}" "${_message}")")
_write_alarms _write_alarms
_release_lock _release_lock
@ -1433,7 +1443,7 @@ every() {
# _next_id calls _read_alarms in a subshell, so _ALARMS isn't populated here. # _next_id calls _read_alarms in a subshell, so _ALARMS isn't populated here.
_read_alarms _read_alarms
_ALARMS+=("$(printf "%s\t%s\t%s\t%s" "${_id}" "${_timestamp}" "${_rules_str}" "${_message}")") _ALARMS+=("$(printf "%s\t\t%s\t%s\t%s" "${_id}" "${_timestamp}" "${_rules_str}" "${_message}")")
_write_alarms _write_alarms
_release_lock _release_lock
@ -1483,7 +1493,7 @@ unmute() {
describe "edit" <<HEREDOC describe "edit" <<HEREDOC
Usage: Usage:
${_ME} ( edit | -e | --edit ) ${_ME} ( edit | -e )
Description: Description:
Open the alarms file in \$EDITOR (falls back to \$VISUAL, then vi). Open the alarms file in \$EDITOR (falls back to \$VISUAL, then vi).

View file

@ -8,10 +8,10 @@ load test_helper
[[ "${output}" =~ "[1] Tomorrow, 3pm — take a break" ]] [[ "${output}" =~ "[1] Tomorrow, 3pm — take a break" ]]
[ -f "${NAG_DIR}/alarms" ] [ -f "${NAG_DIR}/alarms" ]
[ "$(wc -l < "${NAG_DIR}/alarms")" -eq 1 ] [ "$(wc -l < "${NAG_DIR}/alarms")" -eq 1 ]
# Verify TSV structure: id<TAB>timestamp<TAB><TAB>message # Verify TSV structure: id<TAB><empty-tags><TAB>timestamp<TAB><empty-rule><TAB>message
local _line local _line
_line="$(cat "${NAG_DIR}/alarms")" _line="$(cat "${NAG_DIR}/alarms")"
[[ "${_line}" =~ ^1$'\t'[0-9]+$'\t'$'\t'take\ a\ break$ ]] [[ "${_line}" =~ ^1$'\t'$'\t'[0-9]+$'\t'$'\t'take\ a\ break$ ]]
} }
@test "at is the implicit subcommand" { @test "at is the implicit subcommand" {
@ -68,13 +68,27 @@ load test_helper
run_nag at "${_last_month}" "annual thing" run_nag at "${_last_month}" "annual thing"
[ "${status}" -eq 0 ] [ "${status}" -eq 0 ]
local _ts local _ts
_ts="$(cut -f2 "${NAG_DIR}/alarms")" _ts="$(cut -f3 "${NAG_DIR}/alarms")"
local _ts_year _next_year local _ts_year _next_year
_ts_year="$(date -d "@${_ts}" +%Y)" _ts_year="$(date -d "@${_ts}" +%Y)"
_next_year="$(date -d "+1 year" +%Y)" _next_year="$(date -d "+1 year" +%Y)"
[ "${_ts_year}" = "${_next_year}" ] [ "${_ts_year}" = "${_next_year}" ]
} }
@test "-f flag suppresses prompts" {
run "${_NAG}" -f at "tomorrow 3pm" "flagged alarm"
[ "${status}" -eq 0 ]
[[ "${output}" =~ "flagged alarm" ]]
}
@test "at creates alarm with 5-field TSV (empty tags)" {
run_nag at "tomorrow 3pm" "tagged test"
[ "${status}" -eq 0 ]
local _line
_line="$(cat "${NAG_DIR}/alarms")"
[[ "${_line}" =~ ^1$'\t'$'\t'[0-9]+$'\t'$'\t'tagged\ test$ ]]
}
@test "at without message fails" { @test "at without message fails" {
run_nag at "tomorrow 3pm" run_nag at "tomorrow 3pm"
[ "${status}" -eq 1 ] [ "${status}" -eq 1 ]

View file

@ -4,7 +4,7 @@ load test_helper
@test "check fires expired one-shot and removes it" { @test "check fires expired one-shot and removes it" {
local _past_ts=$(( $(date +%s) - 60 )) local _past_ts=$(( $(date +%s) - 60 ))
write_alarm "$(printf "1\t%s\t\tpast alarm" "${_past_ts}")" write_alarm "$(printf "1\t\t%s\t\tpast alarm" "${_past_ts}")"
# Record what was fired. # Record what was fired.
local _fired="${NAG_DIR}/fired" local _fired="${NAG_DIR}/fired"
@ -27,7 +27,7 @@ SCRIPT
@test "check reschedules expired repeating alarm" { @test "check reschedules expired repeating alarm" {
local _past_ts=$(( $(date +%s) - 60 )) local _past_ts=$(( $(date +%s) - 60 ))
write_alarm "$(printf "1\t%s\tday\tdaily alarm" "${_past_ts}")" write_alarm "$(printf "1\t\t%s\tday\tdaily alarm" "${_past_ts}")"
run_nag check run_nag check
[ "${status}" -eq 0 ] [ "${status}" -eq 0 ]
@ -35,7 +35,7 @@ SCRIPT
# Alarm should still exist with a future timestamp. # Alarm should still exist with a future timestamp.
[ -s "${NAG_DIR}/alarms" ] [ -s "${NAG_DIR}/alarms" ]
local _new_ts local _new_ts
_new_ts="$(cut -f2 "${NAG_DIR}/alarms" | head -1)" _new_ts="$(cut -f3 "${NAG_DIR}/alarms" | head -1)"
local _now local _now
_now="$(date +%s)" _now="$(date +%s)"
(( _new_ts > _now )) (( _new_ts > _now ))
@ -43,7 +43,7 @@ SCRIPT
@test "check does not fire future alarms" { @test "check does not fire future alarms" {
local _future_ts=$(( $(date +%s) + 3600 )) local _future_ts=$(( $(date +%s) + 3600 ))
write_alarm "$(printf "1\t%s\t\tfuture alarm" "${_future_ts}")" write_alarm "$(printf "1\t\t%s\t\tfuture alarm" "${_future_ts}")"
run_nag check run_nag check
[ "${status}" -eq 0 ] [ "${status}" -eq 0 ]
@ -56,8 +56,8 @@ SCRIPT
@test "check fires all missed alarms" { @test "check fires all missed alarms" {
local _past1=$(( $(date +%s) - 120 )) local _past1=$(( $(date +%s) - 120 ))
local _past2=$(( $(date +%s) - 60 )) local _past2=$(( $(date +%s) - 60 ))
write_alarm "$(printf "1\t%s\t\tmissed one" "${_past1}")" write_alarm "$(printf "1\t\t%s\t\tmissed one" "${_past1}")"
write_alarm "$(printf "2\t%s\t\tmissed two" "${_past2}")" write_alarm "$(printf "2\t\t%s\t\tmissed two" "${_past2}")"
local _fired="${NAG_DIR}/fired" local _fired="${NAG_DIR}/fired"
export NAG_CMD="${NAG_DIR}/recorder" export NAG_CMD="${NAG_DIR}/recorder"
@ -80,7 +80,7 @@ SCRIPT
@test "check silently drops stale one-shot (older than 15 min)" { @test "check silently drops stale one-shot (older than 15 min)" {
local _stale_ts=$(( $(date +%s) - 1800 )) # 30 minutes ago local _stale_ts=$(( $(date +%s) - 1800 )) # 30 minutes ago
write_alarm "$(printf "1\t%s\t\tstale alarm" "${_stale_ts}")" write_alarm "$(printf "1\t\t%s\t\tstale alarm" "${_stale_ts}")"
local _fired="${NAG_DIR}/fired" local _fired="${NAG_DIR}/fired"
export NAG_CMD="${NAG_DIR}/recorder" export NAG_CMD="${NAG_DIR}/recorder"
@ -102,7 +102,7 @@ SCRIPT
@test "check silently reschedules stale repeating alarm" { @test "check silently reschedules stale repeating alarm" {
local _stale_ts=$(( $(date +%s) - 1800 )) # 30 minutes ago local _stale_ts=$(( $(date +%s) - 1800 )) # 30 minutes ago
write_alarm "$(printf "1\t%s\tday\tstale repeater" "${_stale_ts}")" write_alarm "$(printf "1\t\t%s\tday\tstale repeater" "${_stale_ts}")"
local _fired="${NAG_DIR}/fired" local _fired="${NAG_DIR}/fired"
export NAG_CMD="${NAG_DIR}/recorder" export NAG_CMD="${NAG_DIR}/recorder"
@ -121,6 +121,6 @@ SCRIPT
# Should be rescheduled to a future time. # Should be rescheduled to a future time.
[ -s "${NAG_DIR}/alarms" ] [ -s "${NAG_DIR}/alarms" ]
local _new_ts local _new_ts
_new_ts="$(cut -f2 "${NAG_DIR}/alarms" | head -1)" _new_ts="$(cut -f3 "${NAG_DIR}/alarms" | head -1)"
(( _new_ts > $(date +%s) )) (( _new_ts > $(date +%s) ))
} }

View file

@ -23,9 +23,3 @@ load test_helper
[[ "$output" == *"test alarm"* ]] [[ "$output" == *"test alarm"* ]]
} }
@test "--edit flag invokes edit" {
write_alarm "1 9999999999 test alarm"
EDITOR="cat" run_nag --edit
[[ "$status" -eq 0 ]]
[[ "$output" == *"test alarm"* ]]
}

View file

@ -10,7 +10,7 @@ load test_helper
[[ "${output}" =~ "standup meeting" ]] [[ "${output}" =~ "standup meeting" ]]
# Verify TSV has rule in field 3. # Verify TSV has rule in field 3.
local _rule local _rule
_rule="$(cut -f3 "${NAG_DIR}/alarms")" _rule="$(cut -f4 "${NAG_DIR}/alarms")"
[ "${_rule}" = "weekday" ] [ "${_rule}" = "weekday" ]
} }
@ -26,7 +26,7 @@ load test_helper
run_nag every weekend "tomorrow 3pm" relax run_nag every weekend "tomorrow 3pm" relax
[ "${status}" -eq 0 ] [ "${status}" -eq 0 ]
local _ts _dow local _ts _dow
_ts="$(cut -f2 "${NAG_DIR}/alarms")" _ts="$(cut -f3 "${NAG_DIR}/alarms")"
_dow="$(date -d "@${_ts}" +%u)" _dow="$(date -d "@${_ts}" +%u)"
# Day-of-week should be 6 (Sat) or 7 (Sun). # Day-of-week should be 6 (Sat) or 7 (Sun).
[[ "${_dow}" == "6" || "${_dow}" == "7" ]] [[ "${_dow}" == "6" || "${_dow}" == "7" ]]

View file

@ -32,7 +32,7 @@ load test_helper
run_nag help version run_nag help version
[ "${status}" -eq 0 ] [ "${status}" -eq 0 ]
[[ "${output}" =~ "Usage:" ]] [[ "${output}" =~ "Usage:" ]]
[[ "${output}" =~ "( version | --version )" ]] [[ "${output}" =~ "( version | -v )" ]]
} }
@test "help stop shows stop usage" { @test "help stop shows stop usage" {

View file

@ -70,7 +70,7 @@ load test_helper
@test "list shows Today for alarm due today" { @test "list shows Today for alarm due today" {
local _ts=$(( $(date -d "$(date +%Y-%m-%d)" +%s) + 82800 )) local _ts=$(( $(date -d "$(date +%Y-%m-%d)" +%s) + 82800 ))
write_alarm "$(printf '1\t%s\t\ttoday alarm' "${_ts}")" write_alarm "$(printf '1\t\t%s\t\ttoday alarm' "${_ts}")"
run_nag run_nag
[ "${status}" -eq 0 ] [ "${status}" -eq 0 ]
[[ "${output}" =~ "Today,".*"today alarm" ]] [[ "${output}" =~ "Today,".*"today alarm" ]]
@ -78,7 +78,7 @@ load test_helper
@test "list shows Tomorrow for alarm due tomorrow" { @test "list shows Tomorrow for alarm due tomorrow" {
local _ts=$(( $(date -d "$(date +%Y-%m-%d)" +%s) + 86400 + 43200 )) local _ts=$(( $(date -d "$(date +%Y-%m-%d)" +%s) + 86400 + 43200 ))
write_alarm "$(printf '1\t%s\t\ttomorrow alarm' "${_ts}")" write_alarm "$(printf '1\t\t%s\t\ttomorrow alarm' "${_ts}")"
run_nag run_nag
[ "${status}" -eq 0 ] [ "${status}" -eq 0 ]
[[ "${output}" =~ "Tomorrow,".*"tomorrow alarm" ]] [[ "${output}" =~ "Tomorrow,".*"tomorrow alarm" ]]
@ -87,7 +87,7 @@ load test_helper
@test "list shows This <day> for alarm 3 days away" { @test "list shows This <day> for alarm 3 days away" {
local _ts=$(( $(date -d "$(date +%Y-%m-%d)" +%s) + 86400 * 3 + 43200 )) local _ts=$(( $(date -d "$(date +%Y-%m-%d)" +%s) + 86400 * 3 + 43200 ))
local _day="$(date -d "@${_ts}" +%A)" local _day="$(date -d "@${_ts}" +%A)"
write_alarm "$(printf '1\t%s\t\tthis alarm' "${_ts}")" write_alarm "$(printf '1\t\t%s\t\tthis alarm' "${_ts}")"
run_nag run_nag
[ "${status}" -eq 0 ] [ "${status}" -eq 0 ]
[[ "${output}" =~ "This ${_day},".*"this alarm" ]] [[ "${output}" =~ "This ${_day},".*"this alarm" ]]
@ -96,7 +96,7 @@ load test_helper
@test "list shows Next <day> for alarm 10 days away" { @test "list shows Next <day> for alarm 10 days away" {
local _ts=$(( $(date -d "$(date +%Y-%m-%d)" +%s) + 86400 * 10 + 43200 )) local _ts=$(( $(date -d "$(date +%Y-%m-%d)" +%s) + 86400 * 10 + 43200 ))
local _day="$(date -d "@${_ts}" +%A)" local _day="$(date -d "@${_ts}" +%A)"
write_alarm "$(printf '1\t%s\t\tnext alarm' "${_ts}")" write_alarm "$(printf '1\t\t%s\t\tnext alarm' "${_ts}")"
run_nag run_nag
[ "${status}" -eq 0 ] [ "${status}" -eq 0 ]
[[ "${output}" =~ "Next ${_day},".*"next alarm" ]] [[ "${output}" =~ "Next ${_day},".*"next alarm" ]]
@ -105,7 +105,7 @@ load test_helper
@test "list shows date for alarm 30 days away" { @test "list shows date for alarm 30 days away" {
local _ts=$(( $(date -d "$(date +%Y-%m-%d)" +%s) + 86400 * 30 + 43200 )) local _ts=$(( $(date -d "$(date +%Y-%m-%d)" +%s) + 86400 * 30 + 43200 ))
local _date="$(date -d "@${_ts}" "+%a %b %-d")" local _date="$(date -d "@${_ts}" "+%a %b %-d")"
write_alarm "$(printf '1\t%s\t\tfar alarm' "${_ts}")" write_alarm "$(printf '1\t\t%s\t\tfar alarm' "${_ts}")"
run_nag run_nag
[ "${status}" -eq 0 ] [ "${status}" -eq 0 ]
[[ "${output}" =~ "${_date},".*"far alarm" ]] [[ "${output}" =~ "${_date},".*"far alarm" ]]

View file

@ -9,7 +9,7 @@ load test_helper
[[ "${output}" =~ "Skipped" ]] [[ "${output}" =~ "Skipped" ]]
[ -s "${NAG_DIR}/alarms" ] [ -s "${NAG_DIR}/alarms" ]
local _ts _now local _ts _now
_ts="$(cut -f2 "${NAG_DIR}/alarms")" _ts="$(cut -f3 "${NAG_DIR}/alarms")"
_now="$(date +%s)" _now="$(date +%s)"
(( _ts > _now )) (( _ts > _now ))
} }

View file

@ -15,7 +15,7 @@ teardown() {
} }
run_nag() { run_nag() {
run "${_NAG}" --yes "$@" run "${_NAG}" -f "$@"
} }
write_alarm() { write_alarm() {