v0.2.6 update

pull/34/head
Mason10198 3 years ago
parent 784763feb1
commit f173e89ef3

@ -31,7 +31,7 @@ import time
import wave import wave
import contextlib import contextlib
import math import math
from datetime import datetime, timezone from datetime import datetime, timezone, timedelta
from dateutil import parser from dateutil import parser
from pydub import AudioSegment from pydub import AudioSegment
from ruamel.yaml import YAML from ruamel.yaml import YAML
@ -360,6 +360,17 @@ def getAlerts(countyCodes):
return alerts return alerts
# Determing whether to use 'effective' or 'onset' time
timetype_mode = config.get("Alerting", {}).get("TimeType", "onset")
if timetype_mode == "effective":
logger.debug("getAlerts: Using effective time for alerting")
time_type_start = "effective"
time_type_end = "expires"
else:
logger.debug("getAlerts: Using onset time for alerting")
time_type_start = "onset"
time_type_end = "ends"
for countyCode in countyCodes: for countyCode in countyCodes:
url = "https://api.weather.gov/alerts/active?zone={}".format(countyCode) url = "https://api.weather.gov/alerts/active?zone={}".format(countyCode)
logger.debug("getAlerts: Checking for alerts in %s at URL: %s", countyCode, url) logger.debug("getAlerts: Checking for alerts in %s at URL: %s", countyCode, url)
@ -368,16 +379,16 @@ def getAlerts(countyCodes):
if response.status_code == 200: if response.status_code == 200:
alert_data = response.json() alert_data = response.json()
for feature in alert_data["features"]: for feature in alert_data["features"]:
onset = feature["properties"].get("onset") start = feature["properties"].get(time_type_start)
ends = feature["properties"].get("ends") end = feature["properties"].get(time_type_end)
if onset and ends: if start and end:
onset_time = parser.isoparse(onset) start_time = parser.isoparse(start)
ends_time = parser.isoparse(ends) end_time = parser.isoparse(end)
# Convert alert times to UTC # Convert alert times to UTC
onset_time_utc = onset_time.astimezone(timezone.utc) start_time_utc = start_time.astimezone(timezone.utc)
ends_time_utc = ends_time.astimezone(timezone.utc) end_time_utc = end_time.astimezone(timezone.utc)
if onset_time_utc <= current_time < ends_time_utc: event = feature["properties"]["event"]
event = feature["properties"]["event"] if start_time_utc <= current_time < end_time_utc:
description = feature["properties"].get("description", "") description = feature["properties"].get("description", "")
severity = feature["properties"].get("severity", None) severity = feature["properties"].get("severity", None)
# Check if alert has already been seen # Check if alert has already been seen
@ -407,12 +418,17 @@ def getAlerts(countyCodes):
alerts[(event, severity)] = description alerts[(event, severity)] = description
seen_alerts.add(event) seen_alerts.add(event)
else: else:
logger.debug("getAlerts: Skipping alert %s, not active.", event) time_difference = time_until(start_time_utc, current_time)
logger.debug(
"getAlerts: Skipping %s, not active for another %s.",
event,
time_difference,
)
logger.debug( logger.debug(
"Current time: %s | Alert onset: %s | Alert ends %s", "Current time: %s | Alert start: %s | Alert end %s",
current_time, current_time,
onset_time_utc, start_time_utc,
ends_time_utc, end_time_utc,
) )
else: else:
@ -439,6 +455,30 @@ def getAlerts(countyCodes):
return alerts return alerts
def time_until(start_time_utc, current_time):
"""
Calculate the time difference between two datetime objects and returns it
as a formatted string.
Args:
start_time_utc (datetime): The start time of the alert in UTC.
current_time (datetime): The current time in UTC.
Returns:
str: Formatted string displaying the time difference. If the alert has
not started yet, it returns a positive time difference. If the
alert has already started, it returns a negative time difference.
"""
delta = start_time_utc - current_time
sign = "-" if delta < timedelta(0) else ""
days, remainder = divmod(abs(delta.total_seconds()), 86400)
hours, remainder = divmod(remainder, 3600)
minutes, _ = divmod(remainder, 60)
return "{}{} days, {} hours, {} minutes".format(
sign, int(days), int(hours), int(minutes)
)
def sayAlert(alerts): def sayAlert(alerts):
""" """
Generate and broadcast severe weather alert sounds on Asterisk. Generate and broadcast severe weather alert sounds on Asterisk.
@ -1040,8 +1080,8 @@ def main():
# Initialize pushover message # Initialize pushover message
pushover_message = ( pushover_message = (
"Alerts Cleared\n" "Alerts Cleared\n"
if len(alerts) == 0 if not alerts
else "\n".join(str(key) for key in alerts.keys()) + "\n" else "\n".join(alert[0] for alert in alerts.keys()) + "\n"
) )
# Check if Courtesy Tones (CT) or ID needs to be changed # Check if Courtesy Tones (CT) or ID needs to be changed

@ -61,6 +61,23 @@ Alerting:
# Default is SkywarnPlus/SOUNDS. # Default is SkywarnPlus/SOUNDS.
#SoundsPath: #SoundsPath:
# 'TimeType' Configuration
#
# This setting determines the timing reference for issuing weather alerts.
# You can choose between "onset" and "effective" time.
#
# 'onset': Alerts are issued based on the predicted start time of the weather event.
# This means the system will only send out alerts when the events are imminent.
# For example, even though a "Heat Advisory" can be forecasted accurately a day or two in advance,
# the alert will only be sent close to the actual occurrence of the event.
#
# 'effective': Alerts are sent as soon as they are received, based on the effective time of the alert message.
# The "effective" time is when the alert message is considered to be in effect,
# which could be earlier than the actual onset of the event.
#
# By using 'onset', you can ensure that alerts are relevant and timely for the recipients.
TimeType: onset
################################################################################################################################ ################################################################################################################################
Blocking: Blocking:

Loading…
Cancel
Save

Powered by TurnKey Linux.