Holger Frey
6 years ago
4 changed files with 147 additions and 11 deletions
@ -1,3 +1,9 @@
@@ -1,3 +1,9 @@
|
||||
# s2watchdog |
||||
|
||||
A simple watchdog script for the deep freezer alert system in our s2 scullery. |
||||
|
||||
The alert system of our deep freezer in the s2 scullery will send emails as |
||||
soon, as the temperature exceeds a certain level. |
||||
|
||||
This script will check regularly if the alert system itself is reachable and |
||||
send an email if the system is not available (network down or power failure). |
@ -1,2 +1,128 @@
@@ -1,2 +1,128 @@
|
||||
def test(): |
||||
print('TESTRUN') |
||||
''' Simple watchdog script for the deep freezer alert system |
||||
|
||||
The alert system of our deep freezer in the s2 scullery will send emails as |
||||
soon, as the temperature exceeds a certain level. |
||||
|
||||
This script will check regularly if the alert system itself is reachable and |
||||
send an email if the system is not available (network down or power failure). |
||||
''' |
||||
|
||||
import json |
||||
import requests |
||||
|
||||
from datetime import datetime |
||||
|
||||
from . import pysema |
||||
|
||||
|
||||
|
||||
# alert emails recipients, subject and message |
||||
EMAIL_RECIPIENTS = ['frey@imtek.de'] |
||||
EMAIL_SUBJECT = '[S2 Scullery]: Deep Freezer Alert System Is Offline' |
||||
EMAIL_BODY = [ |
||||
'The -80 alert system in the S2 scullery seems to be offline.', |
||||
'Maybe the network is down, there is a power outage or the system crashed.', |
||||
'', |
||||
'>>> Please have a look as soon as possible. <<<', |
||||
'', |
||||
'The system was last seen on {} (UTC)' |
||||
] |
||||
|
||||
# which url to check |
||||
ALERT_SYSTEM_URL = 'http://test.cpi.imtek.uni-freiburg.de' |
||||
|
||||
|
||||
# How many times can an error be ignored? |
||||
GRACE_PERIOD = 4 |
||||
|
||||
# where to store the data and default values |
||||
DATA_STORE_PATH = '/val/local/s2watchdog.json' |
||||
DEFAULTS = { |
||||
'emails_sent': 0, |
||||
'last_seen': 'Never', |
||||
'last_result': '', |
||||
'time_to_live': 0, |
||||
'url': ALERT_SYSTEM_URL, |
||||
} |
||||
|
||||
# how long (in seconds) to wait for a response from the alert system |
||||
TIMEOUT = 5 |
||||
|
||||
|
||||
|
||||
def load_data(path): |
||||
''' load and decode the saved data ''' |
||||
try: |
||||
with open(path, 'r') as file_handle: |
||||
data = json.load(file_handle) |
||||
|
||||
# ensure, that these two keys are integers: |
||||
for key in ['time_to_live', 'emails_sent']: |
||||
value = data.get(key, None) |
||||
if not isinstance(value, int): |
||||
data[key] = 0 |
||||
return data |
||||
except (FileNotFoundError, AttributeError): |
||||
return DEFAULTS |
||||
|
||||
|
||||
def save_data(path, data=None) |
||||
data = data or DEFAULTS |
||||
with open(path, 'w') as file_handle: |
||||
json.dump(data, file_handle) |
||||
|
||||
|
||||
def query_alert_system(url): |
||||
response = requests.get( |
||||
url, |
||||
allow_redirects=False, |
||||
timeout=TIMEOUT |
||||
) |
||||
response.raise_for_status() |
||||
return response.text |
||||
|
||||
|
||||
def send_alert_mail(data): |
||||
headers['Reply-To'] = EMAIL_RECIPIENTS |
||||
body = '\n'.join(EMAIL_BODY) |
||||
pysema.send( |
||||
EMAIL_RECIPIENTS, |
||||
EMAIL_SUBJECT, |
||||
body.format(data['last_seen']), |
||||
headers |
||||
) |
||||
|
||||
def run(): |
||||
data = load_data(DATA_STORE_PATH) |
||||
|
||||
# the url has changed, use the default values |
||||
if data['url'] != ALERT_SYSTEM_URL: |
||||
data = DEFAULTS |
||||
|
||||
try: |
||||
result = query_alert_system(ALERT_SYSTEM_URL) |
||||
if result != data['last_result']: |
||||
# the retrieved result was not cached somehow |
||||
# everything is all right! |
||||
# we'd return after the data is saved |
||||
data = { |
||||
'emails_sent': 0, |
||||
'last_seen': datetime.utcnow().isoformat(), |
||||
'last_result': result, |
||||
'time_to_live': GRACE_PERIOD, |
||||
'url': ALERT_SYSTEM_URL, |
||||
} |
||||
save_data(DATA_STORE_PATH, data) |
||||
return |
||||
except requests.exceptions.RequestException: |
||||
# the alarm system could not be reached. |
||||
# but maybe its in the grace period, so we pass here |
||||
pass |
||||
|
||||
ttl = data['time_to_live'] - 1 |
||||
if ttl <= 0: |
||||
data['email_sent'] = data['email_sent'] + 1 |
||||
data['time_to_live'] = GRACE_PERIOD * data['email_sent'] |
||||
save_data(DATA_STORE_PATH, data) |
||||
send_alert_mail(data) |
||||
|
||||
|
Loading…
Reference in new issue