summaryrefslogtreecommitdiff
path: root/maintenance/health_monitor.py
blob: 95b7a8ea50b579d9db42ff20a9650ffa68726357 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import os, serial, smtplib
from time import sleep
from sbhs_server.credentials import ADMIN_EMAIL
from sbhs_server.helpers import mailer 

#Setting default device parameters
MAX_PORTS = 256
MIN_TEMP = 10
MAX_TEMP = 70

def write_to_port(s, com, arg):
    """ Sets fan/heater value based on input command code and entered parameter.
        Inputs: s:serial port object, com: number that distinguishes commands, arg: value to be set for that parameter.
    """
    s.write(chr(int(com)))
    sleep(0.5)
    s.write(chr(int(arg)))
    sleep(0.5)

def read_from_port(s, com):
    """ Reads mid/temperature based on input command code.
        Inputs: s:serial port object, com: number that distinguishes commands.
        Output: result: temperature if com=255, mid if com=252, and -1 in case of invalid command code.
    """
    s.write(chr(int(com)))
    sleep(0.5)
    if com == 255:
        result = ord(s.read(1)) + (0.1 * ord(s.read(1)))
    elif com == 252:
        result = ord(s.read(1))
    else:
        result = -1
    sleep(0.5)
    return result

def create_message(check_mids, defective_ports):
    """ Creates message to be sent to the admin for monitoring ports and devices.
        Inputs: check_mids: list of mids for devices to be checked, defective_ports: list of defective ports.
        Output: msg: message with list of mids of devices to be checked and defective ports that is to be mailed to the admin.
    """
    msg = ''
    if len(check_mids) != 0:
        msg += 'Please check the following machine ids :\n'
        for i,mid in enumerate(check_mids):
            msg = msg + str(i) + '. ' + str(mid) + '\n'
    if len(defective_ports) != 0:
        msg = msg + '\nPlease check the following ports :\n'
        for port in defective_ports:
            msg = msg + str(port) + '\n'
    return msg

def main():
    """ Attempts to open serial port object on existing USB paths, and then read the mid of the device using read_from port() function.
        Sets fan and heater value to 100 and 0 respectively using write_to_port() function,
        and reads the temperature of the same device using read_from port() function.
        if the serial port opens but the mid returned is less than zero
            append it to the list of defective ports.
        if an exception occurs while reading or writing but the port opens successfully and returns a valid mid
            then add it to the list of offline mids.
        if the ports opens successfully, returns a valid mid and temperature, and encounters no exceptions
            then add it to the list of present_online_mids
        The difference between the sets of online_mids and present_online_mids gives the list of mids of devices to be checked.
        Calls the create_message function and mails the returned message to the admin.
    """
    present_online_mids, offline_mids, defective_ports = [], [], []
    for i in range(0,MAX_PORTS):
        path = '/dev/ttyUSB' + str(i)
        if os.path.exists(path):
            try:
                s = serial.Serial(port=path, baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=2)
                if not s.is_open:
                    s.open()
                assert s.is_open
                mid = read_from_port(s, 252) # get machine id
                assert mid > 0
                write_to_port(s, 253, 100) # set fan speed
                write_to_port(s, 254, 0) # set heater value
                current_temp = read_from_port(s, 255) # get current temperature
                assert current_temp >= MIN_TEMP and current_temp <= MAX_TEMP
                present_online_mids.append(mid)
            except:
                if s.is_open:
                    if mid > 0:
                        offline_mids.append(mid)
                    else:
                        defective_ports.append(path)
            if s.is_open:
                s.close()
    check_mids = list(set(online_mids).difference(set(present_online_mids)))
    msg = create_message(check_mids, defective_ports)
    if len(msg) == 0:
        msg = "Nothing out of order was detected on the server. :)"
    #thread.start_new_thread(mailer.email, (ADMIN_EMAIL, "Health report of SBHS Server", msg))
    mailer.email(ADMIN_EMAIL, "Health report of SBHS Server", msg)
    #print msg

if __name__ == "__main__":
    main()