Holger Frey
6 years ago
4 changed files with 147 additions and 11 deletions
@ -1,3 +1,9 @@ |
|||||||
# s2watchdog |
# s2watchdog |
||||||
|
|
||||||
A simple watchdog script for the deep freezer alert system in our s2 scullery. |
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 @@ |
|||||||
def test(): |
''' Simple watchdog script for the deep freezer alert system |
||||||
print('TESTRUN') |
|
||||||
|
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