示例#1
0
 def after_handle(self):
     cost = datetime.datetime.now().timestamp() - self.start_handle_time
     app_log.info("{} {} {} ({}) {}ms".format(self.request.method.upper(),
                                              self.status_code,
                                              self.request.path,
                                              self.request.client_ip,
                                              round(cost * 1000, 1)))
示例#2
0
def restartNotifyServer():
    # disconnectAllPVs()
    # clearGlobalDicts()
    # getListOfPVNames()
    # initAlarmDict()
    print("Notify server restarted...")
    app_log.info("Notify server restarted...")
示例#3
0
def notifyWhatsApp(timestamp, mobile, userNotifyDict):
    # This function must return True as an acknowledgedment to the notification
    # server that the notification method executed successfully

    app_log.info(mobile)
    # app_log.info(str(userNotifyDict))

    return False
示例#4
0
 def start_server(self, host, port, router):
     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     sock.bind((host, port))
     sock.listen()
     sock.setblocking(False)
     sel.register(sock, selectors.EVENT_READ, self._on_new_connect)
     self.router = router
     app_log.info("Start listen on {}:{}".format(host, port))
示例#5
0
def startNotifyServer():
    # initPreSuffix()
    # getListOfPVNames()
    # initAlarmDict()

    # debug prints
    # print(alarmDict)

    print("Notify server running...")
    app_log.info("Notify server running...")
示例#6
0
def notifyEmail(timestamp, email, userNotifyDict):
    # This function must return True as an acknowledgedment to the notification
    # server that the notification method executed successfully

    timestamp = datetime.fromisoformat(timestamp)

    app_log.info("###-EMAIL NOTIFY-###")
    app_log.info(timestamp.strftime('%a, %d %b %Y at %H:%M:%S UTC'))
    app_log.info(email)
    # app_log.info(str(userNotifyDict))

    try:
        msg = MIMEMultipart()
        msg['From'] = SMTP_SENDER
        msg['To'] = email
        # Time zone localisation
        if (localtz):
            str_time = timestamp.astimezone(localtz).strftime(
                '%a, %d %b %Y at %H:%M:%S')
        else:
            str_time = timestamp.strftime(
                '%a, %d %b %Y at %H:%M:%S') + " (UTC)"
        # Time zone localisation
        msg['Subject'] = "Alarm Notification: " + str_time
        email_body = composeEmailBody(userNotifyDict)
        msg.attach(MIMEText(email_body, 'html', 'utf-8'))

        try:
            with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as server:
                if (AH_DEBUG):
                    server.set_debuglevel(2)
                # identify ourselves, prompting server for supported features
                server.ehlo()
                # If we can encrypt this session, do it
                if server.has_extn('STARTTLS'):
                    server.starttls()
                    server.ehlo()  # re-identify ourselves over TLS connection
                if (smtpAuth):
                    server.login(SMTP_USER, SMTP_PASS)
                server.sendmail(msg['From'], msg['To'], msg.as_string())
                server.quit()
            print("Successfully sent email to", email)
            app_log.info("Successfully sent email to " + email)
            return True
        except Exception as e:
            app_log.error("Exception raised: " + str(e))
            app_log.error("Exception type: " + str(type(e)))
            app_log.error("Exception args: " + str(e.args))
            print("Failed to send email to", email, ". Verify SMTP settings.")
            app_log.error("Failed to send email to " + email +
                          ". Verify SMTP settings.")
            return False
    except Exception as e:
        app_log.error("Exception raised: " + str(e))
        app_log.error("Exception type: " + str(type(e)))
        app_log.error("Exception args: " + str(e.args))
        print("Failed to send email to", email, ". Verify SMTP settings.")
        app_log.error("Failed to send email to " + email +
                      ". Verify SMTP settings.")
        return False
示例#7
0
 def _on_response(self, request, sock, mask):
     sel.unregister(sock)
     try:
         data = sock.recv(1024)
     except Exception as e:
         request["fut"].throw(type(e), e.args[1], e.__traceback__)
     else:
         request["fut"].send(data)
     finally:
         sock.close()
     cost = time.time() - request["start_time"]
     app_log.info("HTTP {} http://{}:{}{} {}ms".format(
         request["method"],
         request["host"],
         request["port"],
         request["path"],
         round(cost * 1000, 1),
     ))
def initAlarmDatabase():
    ALARM_DATABASE = os.getenv('ALARM_DATABASE', 'localhost')
    ALARM_DATABASE_REPLICA_SET_NAME = os.getenv(
        'ALARM_DATABASE_REPLICA_SET_NAME', 'devrs')
    MONGO_INITDB_ALARM_DATABASE = os.getenv('MONGO_INITDB_ALARM_DATABASE',
                                            'demoAlarmDatabase')
    try:
        MONGO_ROOT_USERNAME = os.environ['MONGO_ROOT_USERNAME']
        MONGO_ROOT_PASSWORD = os.environ['MONGO_ROOT_PASSWORD']
        MONGO_ROOT_USERNAME = urllib.parse.quote_plus(MONGO_ROOT_USERNAME)
        MONGO_ROOT_PASSWORD = urllib.parse.quote_plus(MONGO_ROOT_PASSWORD)
        mongoAuth = True
    except:
        mongoAuth = False
    if (mongoAuth):
        client = MongoClient(
            'mongodb://%s:%s@%s' %
            (MONGO_ROOT_USERNAME, MONGO_ROOT_PASSWORD, ALARM_DATABASE),
            replicaSet=ALARM_DATABASE_REPLICA_SET_NAME,
            readPreference='secondaryPreferred')
    else:
        client = MongoClient('mongodb://%s' % (ALARM_DATABASE),
                             replicaSet=ALARM_DATABASE_REPLICA_SET_NAME,
                             readPreference='secondaryPreferred')

    global alarmDB
    alarmDB = client[MONGO_INITDB_ALARM_DATABASE]

    while (len(alarmDB.list_collection_names()) != 5):
        app_log.info(
            'Waiting for Pymongo to connect to all collections in alarm database'
        )
        sleep(1.0)
    app_log.info('Pymongo connected to all collections in alarm database')
    app_log.info(str(alarmDB.list_collection_names()))
    while (len(list(alarmDB['glob'].find({}))) == 0):
        app_log.info('Alarm database ' + MONGO_INITDB_ALARM_DATABASE +
                     ' still being instantiated')
        sleep(1.0)
    app_log.info('Alarm database ' + MONGO_INITDB_ALARM_DATABASE +
                 ' instantiated')
示例#9
0
def notifyValid(notifySetup):
    now = datetime.now(utc)
    if (notifySetup["notify"]):
        app_log.info("Must notify")
        if (notifySetup["allDay"]):
            app_log.info("All day")
        else:
            app_log.info("Time restricted")
            formatTime = "%H:%M"
            fromTime = datetime.fromisoformat(
                notifySetup["fromTime"]).astimezone(utc).strftime(formatTime)
            toTime = datetime.fromisoformat(
                notifySetup["toTime"]).astimezone(utc).strftime(formatTime)
            nowTime = now.strftime(formatTime)
            app_log.info('fromTime UTC ' + str(fromTime))
            app_log.info('toTime UTC ' + str(toTime))
            app_log.info('nowTime UTC ' + str(nowTime))
            if (time_is_between(nowTime, fromTime, toTime)):
                app_log.info("Current time between fromTime and toTime")
            else:
                app_log.info("Current time NOT between fromTime and toTime")
                app_log.info("!!Don't notify!!")
                return False
        if (notifySetup["weekly"]):
            formatTime = "%A"
            dayToday = now.strftime(formatTime)
            app_log.info("Notify weekly")
            daysToNotify = []
            for key, value in notifySetup["days"].items():
                if (value):
                    daysToNotify.append(key)
            app_log.info("Notify on " + " ".join(daysToNotify))
            app_log.info("Today is " + dayToday)
            if (dayToday in daysToNotify):
                app_log.info("Notify today")
            else:
                app_log.info("Don't notify today")
                app_log.info("!!Don't notify!!")
                return False
        else:
            formatTime = "%d %B %Y"
            fromDate = datetime.fromisoformat(
                notifySetup["fromDate"]).astimezone(utc)
            toDate = datetime.fromisoformat(
                notifySetup["toDate"]).astimezone(utc)
            app_log.info("Notify date range")
            app_log.info('fromDate ' + fromDate.strftime(formatTime))
            app_log.info('toDate ' + toDate.strftime(formatTime))
            app_log.info("Today" + now.strftime(formatTime))
            if (date_is_between(now, fromDate, toDate)):
                app_log.info("Notify today")
            else:
                app_log.info("Don't notify today")
                app_log.info("!!Don't notify!!")
                return False

        return True
    else:
        app_log.info("!!Don't notify!!")
        return False
示例#10
0
def notify(notifyBuffer):
    for user in dbGetCollection("users").find():
        if (user["adminDB_en"] and user["isAHUser"]):
            app_log.info("User " + user["name"] + " is a valid alarm user")
            notifyEmailDict = {}
            notifySMSDict = {}
            notifyWhatsAppDict = {}
            notifySignalDict = {}
            name = user["name"]
            email = user["email"]
            mobile = user["mobile"]
            for notifyPV in user["notifyPVs"]:
                for area in notifyBuffer:
                    for pvname in notifyBuffer[area]:
                        app_log.info('##-START NOTIFY DEBUG-##')
                        app_log.info(name)
                        app_log.info(area)
                        app_log.info(pvname)
                        message = notifyBuffer[area][pvname]
                        minorAlarm = False
                        majorAlarm = False
                        invalidAlarm = False
                        disconnAlarm = False
                        for entry in message:
                            minorAlarm = minorAlarm or ("MINOR_ALARM"
                                                        in entry["entry"])
                            majorAlarm = majorAlarm or ("MAJOR_ALARM"
                                                        in entry["entry"])
                            invalidAlarm = invalidAlarm or ("INVALID_ALARM"
                                                            in entry["entry"])
                            disconnAlarm = disconnAlarm or ("DISCONNECTED"
                                                            in entry["entry"])
                        app_log.info("minorAlarm " + str(minorAlarm))
                        app_log.info("majorAlarm " + str(majorAlarm))
                        app_log.info("invalidAlarm " + str(invalidAlarm))
                        app_log.info("disconnAlarm " + str(disconnAlarm))
                        if (js_regex.compile(
                                notifyPV["regEx"]).search(pvname)):
                            # Passes regEx check
                            app_log.info("Pass regEx " + notifyPV["regEx"])
                            notify = False
                            notifyAlarmType = False
                            notifyOnEmail = False
                            notifyOnSMS = False
                            notifyOnWhatsApp = False
                            notifyOnSignal = False
                            if (user["global"]):
                                app_log.info("Using global profile")
                                notify = notifyValid(user["globalSetup"])
                                notifyOnEmail = user["globalSetup"]["email"]
                                notifyOnSMS = user["globalSetup"]["sms"]
                                notifyOnWhatsApp = user["globalSetup"][
                                    "whatsapp"]
                                # Backwards compatible
                                notifyOnSignal = user["globalSetup"][
                                    "signal"] if (
                                        "signal"
                                        in user["globalSetup"]) else False
                                notifyMinorAlarm = user["globalSetup"][
                                    "alarmMinor"] if (
                                        "alarmMinor"
                                        in user["globalSetup"]) else True
                                notifyMajorAlarm = user["globalSetup"][
                                    "alarmMajor"] if (
                                        "alarmMajor"
                                        in user["globalSetup"]) else True
                                notifyInvalidAlarm = user["globalSetup"][
                                    "alarmInvalid"] if (
                                        "alarmInvalid"
                                        in user["globalSetup"]) else True
                                notifyDisconnAlarm = user["globalSetup"][
                                    "alarmDisconn"] if (
                                        "alarmDisconn"
                                        in user["globalSetup"]) else True
                                #
                            else:
                                app_log.info("Using unique profile")
                                notify = notifyValid(notifyPV["notifySetup"])
                                notifyOnEmail = notifyPV["notifySetup"][
                                    "email"]
                                notifyOnSMS = notifyPV["notifySetup"]["sms"]
                                notifyOnWhatsApp = notifyPV["notifySetup"][
                                    "whatsapp"]
                                # Backwards compatible
                                notifyOnSignal = notifyPV["notifySetup"][
                                    "signal"] if (
                                        "signal"
                                        in notifyPV["notifySetup"]) else False
                                notifyMinorAlarm = notifyPV["notifySetup"][
                                    "alarmMinor"] if (
                                        "alarmMinor"
                                        in notifyPV["notifySetup"]) else True
                                notifyMajorAlarm = notifyPV["notifySetup"][
                                    "alarmMajor"] if (
                                        "alarmMajor"
                                        in notifyPV["notifySetup"]) else True
                                notifyInvalidAlarm = notifyPV["notifySetup"][
                                    "alarmInvalid"] if (
                                        "alarmInvalid"
                                        in notifyPV["notifySetup"]) else True
                                notifyDisconnAlarm = notifyPV["notifySetup"][
                                    "alarmDisconn"] if (
                                        "alarmDisconn"
                                        in notifyPV["notifySetup"]) else True
                                #
                            app_log.info("notifyMinorAlarm " +
                                         str(notifyMinorAlarm))
                            app_log.info("notifyMajorAlarm " +
                                         str(notifyMajorAlarm))
                            app_log.info("notifyInvalidAlarm " +
                                         str(notifyInvalidAlarm))
                            app_log.info("notifyDisconnAlarm " +
                                         str(notifyDisconnAlarm))
                            if (minorAlarm and notifyMinorAlarm):
                                notifyAlarmType = True
                            elif (majorAlarm and notifyMajorAlarm):
                                notifyAlarmType = True
                            elif (invalidAlarm and notifyInvalidAlarm):
                                notifyAlarmType = True
                            elif (disconnAlarm and notifyDisconnAlarm):
                                notifyAlarmType = True
                            if (notify and notifyAlarmType):
                                # Passes notifyValid check
                                app_log.info(
                                    "Pass notifyValid and alarm type checks")
                                if (notifyOnEmail):
                                    # Notify via email
                                    app_log.info("Notify via email")
                                    if (area not in notifyEmailDict):
                                        notifyEmailDict[area] = {}
                                    notifyEmailDict[area][pvname] = message
                                if (notifyOnSMS):
                                    # Notify via sms
                                    app_log.info("Notify via sms")
                                    if (area not in notifySMSDict):
                                        notifySMSDict[area] = {}
                                    notifySMSDict[area][pvname] = message
                                if (notifyOnWhatsApp):
                                    # Notify via whatsapp
                                    app_log.info("Notify via whatsapp")
                                    if (area not in notifyWhatsAppDict):
                                        notifyWhatsAppDict[area] = {}
                                    notifyWhatsAppDict[area][pvname] = message
                                if (notifyOnSignal):
                                    # Notify via signal
                                    app_log.info("Notify via Signal")
                                    if (area not in notifySignalDict):
                                        notifySignalDict[area] = {}
                                    notifySignalDict[area][pvname] = message
                            else:
                                app_log.info(
                                    "Fail notifyValid or alarm type check")
                        else:
                            app_log.info("Fail regEx " + notifyPV["regEx"])
                        app_log.info('###-END NOTIFY DEBUG-###')
            timestamp = datetime.now(utc).isoformat()
            if (notifyEmailDict):
                if (notifyEmail(timestamp, email, notifyEmailDict)):
                    timestamp = datetime.now(utc).isoformat()
                    entry = {
                        "timestamp": timestamp,
                        "entry": " ".join([name, "notified on email"])
                    }
                else:
                    timestamp = datetime.now(utc).isoformat()
                    entry = {
                        "timestamp": timestamp,
                        "entry":
                        " ".join(["FAILED to notify", name, "on email!"])
                    }
                for area in notifyEmailDict:
                    for pvname in notifyEmailDict[area]:
                        dbUpdateHistory(area, entry, pvname)

            if (notifySMSDict):
                if (notifySMS(timestamp, mobile, notifySMSDict)):
                    timestamp = datetime.now(utc).isoformat()
                    entry = {
                        "timestamp": timestamp,
                        "entry": " ".join([name, "notified on SMS"])
                    }
                else:
                    timestamp = datetime.now(utc).isoformat()
                    entry = {
                        "timestamp": timestamp,
                        "entry":
                        " ".join(["FAILED to notify", name, "on SMS!"])
                    }
                for area in notifySMSDict:
                    for pvname in notifySMSDict[area]:
                        dbUpdateHistory(area, entry, pvname)

            if (notifyWhatsAppDict):
                if (notifyWhatsApp(timestamp, mobile, notifyWhatsAppDict)):
                    timestamp = datetime.now(utc).isoformat()
                    entry = {
                        "timestamp": timestamp,
                        "entry": " ".join([name, "notified on WhatsApp"])
                    }
                else:
                    timestamp = datetime.now(utc).isoformat()
                    entry = {
                        "timestamp":
                        timestamp,
                        "entry":
                        " ".join(["FAILED to notify", name, "on WhatsApp!"])
                    }
                for area in notifyWhatsAppDict:
                    for pvname in notifyWhatsAppDict[area]:
                        dbUpdateHistory(area, entry, pvname)

            if (notifySignalDict):
                notifySignal(timestamp, mobile, name, notifySignalDict)
        else:
            app_log.info("User " + user["name"] + " is NOT a valid alarm user")
示例#11
0
from notificationMethods.notifyEmail import notifyEmail
from notificationMethods.notifySMS import notifySMS
from notificationMethods.notifyWhatsApp import notifyWhatsApp
from notificationMethods.notifySignal import notifySignal

from log import app_log

try:
    AH_DEBUG = bool(os.environ['AH_DEBUG'])
except:
    AH_DEBUG = False

try:
    timezone(os.environ['AH_TZ'])
    print('Local timezone for alarm handler set to', os.environ['AH_TZ'])
    app_log.info('Local timezone for alarm handler set to ' +
                 os.environ['AH_TZ'])
except:
    print('[Warning]', 'Local timezone for alarm handler not set!')
    app_log.warning('Local timezone for alarm handler not set!')

pvNameList = []
alarmDict = {}


def initPreSuffix():
    # Prefix and suffix for alarmIOC pvs
    global alarmIOCPVPrefix
    global alarmIOCPVSuffix
    doc = dbFindOne("config")
    alarmIOCPVPrefix = doc["alarmIOCPVPrefix"]
    alarmIOCPVSuffix = doc["alarmIOCPVSuffix"]
def worker():
    while True:
        item = q.get()

        timestamp = item['timestamp']
        mobile = item['mobile']
        name = item['name']
        userNotifyDict = item['userNotifyDict']

        timestamp = datetime.fromisoformat(timestamp)

        app_log.info("###-SIGNAL NOTIFY-###")
        app_log.info(timestamp.strftime('%a, %d %b %Y at %H:%M:%S UTC'))
        app_log.info(mobile)
        # app_log.info(str(userNotifyDict))

        if (SIGNAL_CLI_REST_ENDPOINT != ''):
            try:
                # Time zone localisation
                if (localtz):
                    str_time = timestamp.astimezone(localtz).strftime(
                        '%a, %d %b %Y at %H:%M:%S')
                else:
                    str_time = timestamp.strftime(
                        '%a, %d %b %Y at %H:%M:%S') + " (UTC)"
                # Time zone localisation
                message = "You have new alarm notifications"
                message = message.replace(" ", "\ ")
                message.encode('unicode_escape')
                html = composeEmailBody(userNotifyDict, str_time)

                imgkit.from_string(html, 'alarms.jpg')

                with open("alarms.jpg", "rb") as image_file:
                    encoded_image = base64.b64encode(image_file.read())

                data = {
                    "text":
                    message,
                    "receivers": [mobile],
                    "group":
                    False,
                    "groupId":
                    "",
                    "attachments": [{
                        "url": "",
                        "filename": "alarms.jpg",
                        "content": encoded_image.decode()
                    }]
                }

                try:
                    r = requests.post(SIGNAL_CLI_REST_ENDPOINT, json=data)
                    app_log.info("Signal rest API response: [" +
                                 str(r.status_code) + "] " + r.reason)
                    if (r.ok):
                        timestamp = datetime.now(utc).isoformat()
                        entry = {
                            "timestamp": timestamp,
                            "entry": " ".join([name, "notified on Signal"])
                        }
                except Exception as e:
                    app_log.error("Exception raised: " + str(e))
                    app_log.error("Exception type: " + str(type(e)))
                    app_log.error("Exception args: " + str(e.args))
                    print("Failed to send Signal message to", mobile,
                          ". Verify Signal settings.")
                    app_log.error("Failed to send Signal message to " +
                                  mobile + ". Verify Signal settings.")
                    timestamp = datetime.now(utc).isoformat()
                    entry = {
                        "timestamp": timestamp,
                        "entry":
                        " ".join(["FAILED to notify", name, "on Signal!"])
                    }
            except Exception as e:
                app_log.error("Exception raised: " + str(e))
                app_log.error("Exception type: " + str(type(e)))
                app_log.error("Exception args: " + str(e.args))
                print("Failed to send Signal message to", mobile,
                      ". Verify Signal settings.")
                app_log.error("Failed to send Signal message to " + mobile +
                              ". Verify Signal settings.")
                timestamp = datetime.now(utc).isoformat()
                entry = {
                    "timestamp": timestamp,
                    "entry": " ".join(["FAILED to notify", name, "on Signal!"])
                }
        else:
            print("Failed to send Signal message to", mobile,
                  ". Verify Signal settings.")
            app_log.error("Failed to send Signal message to " + mobile +
                          ". Verify Signal settings.")
            timestamp = datetime.now(utc).isoformat()
            entry = {
                "timestamp": timestamp,
                "entry": " ".join(["FAILED to notify", name, "on Signal!"])
            }

        for area in userNotifyDict:
            for pvname in userNotifyDict[area]:
                dbUpdateHistory(area, entry, pvname)
        q.task_done()
try:
    SIGNAL_CLI_REST_API_PORT = os.environ['SIGNAL_CLI_REST_API_PORT']
except:
    print("SIGNAL_CLI_REST_API_PORT not defined, defaulting to port 8000")
    app_log.warning(
        "SIGNAL_CLI_REST_API_PORT not defined, defaulting to port 8000")
    SIGNAL_CLI_REST_API_PORT = str(8000)

try:
    SIGNAL_ACC_NUMBER = os.environ['SIGNAL_ACC_NUMBER']
    SIGNAL_ACC_NUMBER = SIGNAL_ACC_NUMBER.replace('+', '%2B')
    SIGNAL_CLI_REST_ENDPOINT = 'http://127.0.0.1:' + \
        SIGNAL_CLI_REST_API_PORT+'/messages/'+SIGNAL_ACC_NUMBER
    print(SIGNAL_CLI_REST_ENDPOINT)
    app_log.info(SIGNAL_CLI_REST_ENDPOINT)
except:
    print("Signal account number not configured!")
    print("Signal notifications will not be sent")
    app_log.warning("Signal account number not configured!")
    app_log.warning("Signal notifications will not be sent")
    SIGNAL_CLI_REST_ENDPOINT = ''

q = queue.Queue()


def composeEmailBody(userNotifyDict, sent_time):
    body = ""
    for area in userNotifyDict:
        if ("=" in area):
            displayArea = area.replace("=", " > ")
示例#14
0
    AH_DEBUG = bool(os.environ['AH_DEBUG'])
except:
    AH_DEBUG = False

try:
    AH_TZ = os.environ['AH_TZ']
    localtz = timezone(AH_TZ)
except:
    localtz = None

try:
    SMTP_HOST = os.environ['SMTP_HOST']
    SMTP_PORT = os.environ['SMTP_PORT']
    SMTP_SENDER = os.environ['SMTP_SENDER']
    print("Email SMTP settings configured")
    app_log.info("Email SMTP settings configured")
except:
    SMTP_HOST = ''
    SMTP_PORT = ''
    SMTP_SENDER = ''
    print("Email SMTP settings not configured!")
    print("Email notifications will not be sent")
    app_log.warning("Email SMTP settings not configured!")
    app_log.warning("Email notifications will not be sent")

try:
    SMTP_USER = os.environ['SMTP_USER']
    SMTP_PASS = os.environ['SMTP_PASS']
    smtpAuth = True
    print("SMTP user/password set, login required")
    app_log.info("SMTP user/password set, login required")