AlertScript: add ClearCommands

pull/140/head v0.5.2
Mason10198 2 years ago
parent fda0ee5ae0
commit 8e6ca6336c

@ -425,13 +425,17 @@ AlertScript:
# Examples:
#
# This entry will execute the bash command 'asterisk -rx "rpt fun 1999 *123*456*789"'
# when the alerts "Tornado Warning" AND "Tornado Watch" are detected.
# when the alerts "Tornado Warning" AND "Tornado Watch" are detected. It will execute the
# bash command 'asterisk -rx "rpt fun 1999 *987*654*321"' when there are no longer ANY alerts matching
# "Tornado Warning" OR "Tornado Watch".
#
- Type: DTMF
Nodes:
- 1999
Commands:
- "*123*456*789"
ClearCommands:
- "*987*654*321"
Triggers:
- Tornado Warning
- Tornado Watch
@ -491,6 +495,30 @@ AlertScript:
The `Match:` parameter tells `AlertScript` how to handle the triggers. If `Match: ANY`, then only 1 of the triggers needs to be matched for the command(s) to execute. If `Match: ALL`, then all of the triggers must be matched for the command(s) to execute. If `Match:` is not defined, then `ANY` is used by default.
## ClearCommands: Responding to Alert Clearance
With the introduction of `ClearCommands`, `AlertScript` now allows you to define actions that should be executed once a specific alert has been cleared. This can be particularly useful for scenarios where you want to notify users that a previously active alert is no longer in effect or to reset certain systems to their default state after an alert ends.
In the `config.yaml` file, under each mapping in the `AlertScript` section, you can specify the `ClearCommands` that should be executed when the corresponding alert(s) are cleared.
For example:
```yaml
- Type: DTMF
Nodes:
- 1999
Commands:
- "*123*456*789"
ClearCommands:
- "*987*654*321"
Triggers:
- Tornado Warning
- Tornado Watch
Match: ALL
```
In the above configuration, when the alerts "Tornado Warning" AND "Tornado Watch" are detected, the DTMF macro `*123*456*789` will be executed. However, when there are no longer ANY alerts matching "Tornado Warning" OR "Tornado Watch", the DTMF macro `*987*654*321` will be executed.
## The Power of YOU
`AlertScript` derives its power from its versatility and extensibility. By providing the capacity to directly interface with your node's functionality through DTMF commands or bash scripts, you can effectively program the node to do virtually anything in response to a specific weather alert.

@ -1234,18 +1234,16 @@ def alert_script(alerts):
state = load_state()
processed_alerts = set(
state["alertscript_alerts"]
) # Change this to a set for easier processing
) # Convert to a set for easier processing
active_alerts = set(
state.get("active_alerts", [])
) # Load active alerts from state, also as a set
# Extract only the alert names from the OrderedDict keys
alert_names = set([alert for alert in alerts.keys()]) # This should also be a set
alert_names = set([alert for alert in alerts.keys()])
# New alerts are those that are in the current alerts but were not active before
# Identify new alerts and cleared alerts
new_alerts = alert_names - active_alerts
# Alerts to be cleared are those that were previously active but are no longer present
cleared_alerts = active_alerts - alert_names
# Update the active alerts in the state
@ -1263,41 +1261,26 @@ def alert_script(alerts):
mappings = []
LOGGER.debug("Mappings: %s", mappings)
# Iterate over each mapping
# Process each mapping for new alerts
for mapping in mappings:
LOGGER.debug("Processing mapping: %s", mapping)
triggers = mapping.get("Triggers", [])
commands = mapping.get("Commands", [])
nodes = mapping.get("Nodes", [])
match_type = mapping.get("Match", "ANY").upper()
matched_alerts = []
for alert in new_alerts: # We only check the new alerts
for trigger in triggers:
if fnmatch.fnmatch(alert, trigger):
LOGGER.debug(
'Match found: Alert "%s" matches trigger "%s"', alert, trigger
)
matched_alerts.append(alert)
matched_alerts = [alert for alert in new_alerts if alert in triggers]
# Check if alerts matched the triggers as per the match type
# Check if new alerts matched the triggers as per the match type
if (
match_type == "ANY"
and matched_alerts
or match_type == "ALL"
and len(matched_alerts) == len(triggers)
):
LOGGER.debug(
'Alerts matched the triggers as per the match type "%s"', match_type
)
# Execute commands based on the Type of mapping
for alert in matched_alerts:
processed_alerts.add(alert)
if mapping.get("Type") == "BASH":
LOGGER.debug('Mapping type is "BASH"')
for cmd in commands:
cmd = cmd.format(
alert_title=alert
@ -1305,7 +1288,6 @@ def alert_script(alerts):
LOGGER.info("AlertScript: Executing BASH command: %s", cmd)
subprocess.run(cmd, shell=True)
elif mapping.get("Type") == "DTMF":
LOGGER.debug('Mapping type is "DTMF"')
for node in nodes:
for cmd in commands:
dtmf_cmd = 'asterisk -rx "rpt fun {} {}"'.format(node, cmd)
@ -1314,8 +1296,34 @@ def alert_script(alerts):
)
subprocess.run(dtmf_cmd, shell=True)
# Clear alerts that are no longer active
processed_alerts -= cleared_alerts
# Process each mapping for cleared alerts
for mapping in mappings:
clear_commands = mapping.get("ClearCommands", [])
triggers = mapping.get("Triggers", [])
match_type = mapping.get("Match", "ANY").upper()
matched_cleared_alerts = [
alert for alert in cleared_alerts if alert in triggers
]
# Check if cleared alerts matched the triggers as per the match type
if (
match_type == "ANY"
and matched_cleared_alerts
or match_type == "ALL"
and len(matched_cleared_alerts) == len(triggers)
):
for cmd in clear_commands:
if mapping.get("Type") == "BASH":
LOGGER.info("AlertScript: Executing BASH ClearCommand: %s", cmd)
subprocess.run(cmd, shell=True)
elif mapping.get("Type") == "DTMF":
for node in mapping.get("Nodes", []):
dtmf_cmd = 'asterisk -rx "rpt fun {} {}"'.format(node, cmd)
LOGGER.info(
"AlertScript: Executing DTMF ClearCommand: %s", dtmf_cmd
)
subprocess.run(dtmf_cmd, shell=True)
# Update the state with the alerts processed in this run
state["alertscript_alerts"] = list(

@ -303,17 +303,20 @@ AlertScript:
Mappings:
# Define the mapping of alerts to either DTMF commands or bash scripts here.
# Examples:
#
#Example 1:
# Example 1:
# This entry will execute the bash command 'asterisk -rx "rpt fun 1999 *123*456*789"'
# when the alerts "Tornado Warning" AND "Tornado Watch" are detected.
# when the alerts "Tornado Warning" AND "Tornado Watch" are detected. It will execute the
# bash command 'asterisk -rx "rpt fun 1999 *987*654*321"' when there are no longer ANY alerts matching
# "Tornado Warning" OR "Tornado Watch".
#
# - Type: DTMF
# Nodes:
# - 1999
# Commands:
# - "*123*456*789"
# ClearCommands:
# - "*987*654*321"
# Triggers:
# - Tornado Warning
# - Tornado Watch

Loading…
Cancel
Save

Powered by TurnKey Linux.