Newer
Older
TestStandRepository / Software / Monitoring / Monitoring.py
"""
Author: Federica Lionetto
Date: March 30th, 2015

Description:
Monitoring of the environmental variables.
Temperature, relative humidity, and dew point are measured at regular time intervals and are saved into one or several text files.
When the maximum number of measurements per text file is reached, a new text file is opened.
The text files are saved in "/disk/data1/hep/LHCbUT/TestStand/Data/<sensor>/Monitoring according to the name "Monitoring-<date>-<n>.dat", with <n> determined according to the number of rows and the maximum number of rows.
If the difference between the measured temperature and the dew point is less than 2 degrees Celsius, a warning e-mail is sent to someone nearby the lab.
If it is less than 1 degree Celsius, an emergency e-mail is sent (and the cooling system is switched off remotely, this one still to be implemented).

Parameters:
- <sensor>, the type of sensor;
- <date>, the date according to the yyyymmdd format.

How to run it:
python Monitoring --s <sensor> --d <date>

For example:
python Monitoring --s Hans320 --d 20150330
"""

import argparse
import math
import os
import re
import serial
import sys
import time

sys.path.insert(0,'../Tools')
from SendEmail import *

parser = argparse.ArgumentParser(description='Define the parameters of the monitoring of the environmental variables.')

parser.add_argument('--s',help='type of sensor',required=True)
parser.add_argument('--d',type=int,help='date according to the yyyymmdd format',required=True)

args = parser.parse_args()

# Configuration.

# Type of sensor.
sensor = args.s
# Date according to the yyyymmdd format.
yyyymmdd = args.d

# Header to be written in the output text file.
header = 'Date&Time T (C) RH (%) DP (C)\n'
# Maximum number of output text files.
nFiles = 0
maxNFiles = 100
# Maximum size of the output text file (number of rows). Once this is reached, a new output text file will be created.
nRows = 0
maxNRows = 500

# Sleep time between two consecutive measurements (s).
wait = 60

# Variables to be monitored.
reading = []
T = -1.
RH = -1.
DP = -1.

# Connection to Sensirion sensor.
# It should be ttyS4 or ttyS5.
ser = serial.Serial()
ser.port = '/dev/ttyS5'
ser.baudrate = 9600
ser.bytesize = serial.EIGHTBITS
ser.parity = serial.PARITY_NONE
ser.stopbits = serial.STOPBITS_ONE
ser.timeout = 1

ser.open()
print "================================================================================================"
print "Serial port connected to Sensirion sensor: "
print ser.portstr
print "================================================================================================"

if (ser.isOpen()) :
    print "================================================================================================"
    print "Serial port listening."
    print "================================================================================================"

    ser.write('MOD=H\r')
    while True :
        trash = ser.read(1)
        if (trash == '\r') :
            break

    # Loop until the user presses Ctrl+C...
    try :
        while True :
            # Sleep between two consecutive measurements.
            time.sleep(wait)
            # Read current time.
            currentTime = time.ctime()
            # Reset.
            reading = []
            T = -1.
            RH = -1.
            DP = -1.
            # Measure.
            ser.write('GET\r')
            while True :
                trash = ser.read(1)
                if (trash == '\r') :
                    break
    
            while True :
                byte = ser.read(1)
                if (byte != '\r') :
                    reading.append(byte)
                else :
                    trash = ser.read(1)
                    break
            # print reading
        
            # Manipulate the list and extract the desired information.
            reading.remove('\n')
            # print reading
            s = ''.join(reading)
            # print s
            l = re.findall(r"[-+]?\d*\.\d+",s)
            # Relative humidity (RH).
            RH = float(l[0])
            # Temperature (T).
            T = float(l[1])
            # Dew point (DP).
            H = (math.log10(RH)-2)/0.4343 + (17.62*T)/(243.12+T)
            DP = 243.12*H/(17.62-H)

            # If the difference between the measured temperature and the dew point is less than 2 degrees Celsius, a warning e-mail is sent to someone nearby the lab.
            #If it is less than 1 degree Celsius, an emergency e-mail is sent (and the cooling system is switched off remotely, this one still to be implemented).
            warningDeltaT = 2.
            emergencyDeltaT = 1.
            # Send email.
            sender = 'federica.lionetto@cern.ch'
            receiver = 'federica.lionetto@cern.ch'
            warningMessage = 'Condensation warning! \n The measured temperature is less than two degrees Celsius far from the dew point. Consider switching off the cooling system to avoid condensation on cold surfaces and damage to detector and electronics...'
            warningSubject = 'Condensation warning'
            emergencyMessage = 'Condensation emergency! \n Switch off the cooling system immediately!'
            emergencySubject = 'Condensation emergency'

            if (T-DP<warningDeltaT) :
                send_email(sender,receiver,warningMessage,warningSubject)
            elif (T-DP<emergencyDeltaT) :
                send_email(sender,receiver,emergencyMessage,emergencySubject)

            # Write row in the output text file.
            if (nRows%maxNRows==0) :
                # Close previous output text file, if exists.
                if (nFiles > 0) :
                    file.close()
                if (nFiles == maxNFiles) :
                    print "================================================================================================"
                    print "Maximum number of output text files reached."
                    print "Terminating monitoring."
                    print "================================================================================================"
                    sys.exit(0)
                # Create and open output text file.
                # Filename (complete path or not) given through a parser.
                path = "/disk/data1/hep/LHCbUT/TestStand/Data/"+sensor+"/Monitoring"
                if not os.path.exists(path) :
                    os.makedirs(path)
                filename = path+"/Monitoring-"+str(yyyymmdd)+"-"+str(int(nRows/maxNRows))+".dat"
                print "================================================================================================"
                print "Opening new output text file: "
                print filename
                print "================================================================================================"

                file = open(filename,"w")
                file.write(header)
                nFiles = nFiles+1

            row = currentTime + " " + "%.2f" % T + " " + "%.2f" % RH + " " + "%.2f" % DP + "\n"
            print row
            file.write(row)
            file.flush()
            nRows = nRows+1
    except KeyboardInterrupt :
        sys.exit(0)

    # Close output text file.
    file.close()
    ser.close()