Browse Source

first rough version

master
Holger Frey 6 years ago
parent
commit
888ad107c2
  1. 6
      README.md
  2. 130
      s2watchdog/__init__.py
  3. 9
      s2watchdog/pysema.py
  4. 11
      setup.py

6
README.md

@ -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).

130
s2watchdog/__init__.py

@ -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)

9
s2watchdog/pysema.py

@ -21,12 +21,12 @@ class SendMailException(Exception):
pass pass
def send(to=None, subject='', message='', **headers): def send(to=None, subject='', message='', headers=None):
msg = create_message(to, subject, message, **headers) msg = create_message(to, subject, message, headers)
send_message(msg) send_message(msg)
def create_message(to=None, subject='', message='', **headers): def create_message(to=None, subject='', message='', headers=None):
if isinstance(to, str): if isinstance(to, str):
recipients = to recipients = to
elif isinstance(to, (list, set, tuple)): elif isinstance(to, (list, set, tuple)):
@ -34,6 +34,9 @@ def create_message(to=None, subject='', message='', **headers):
else: else:
raise SendMailException('No recipients given') raise SendMailException('No recipients given')
if not isinstance(headers, dict):
headers = {}
# ensure that the 'from' keyword (if given) is uppercase # ensure that the 'from' keyword (if given) is uppercase
sender_mail = headers.pop('from', None) sender_mail = headers.pop('from', None)
if sender_mail is not None: if sender_mail is not None:

11
setup.py

@ -7,7 +7,8 @@ with open(os.path.join(here, 'README.md')) as f:
README = f.read() README = f.read()
requires = [ requires = [
] 'requests'
]
setup( setup(
name='s2watchdog', name='s2watchdog',
@ -29,7 +30,7 @@ setup(
install_requires=requires, install_requires=requires,
entry_points={ entry_points={
'console_scripts': [ 'console_scripts': [
's2watchdog = s2watchdog:test', 's2watchdog = s2watchdog:run',
], ],
}, },
) )

Loading…
Cancel
Save