def __basicAuthentication():
    """This is a private helper method used by the http_basic_authenticate.
    """
    auth = request.authorization
    logging.debug("Authenticating HTTP Basic Authentication "
                  "using Authorization [{0}]"
                  .format(auth))

    valid_username = ini_config.get("Sensor", "SENSOR_REST_API_USERNAME")
    valid_password = ini_config.get("Sensor", "SENSOR_REST_API_PASSWORD")

    if not auth:
        logging.debug("HTTP Basic Authentication header not found.")
        return False
    elif (auth.username != valid_username):
        logging.debug("user [{0}] is not valid. Authentication failed"
                       .format(auth.username))
        return False
    elif (auth.password != valid_password):
        logging.debug("Password not valid. user [{0}] failed authentication."
                       .format(auth.username))
        return False


    logging.debug("user [{0}] has been authenticated."
                   .format(auth.username))
    return True
Beispiel #2
0
    def subscribe_temperature():
        """
        Subscribe to temperature sensor data.

        Parameters
        ----------

        Returns
        -------

        """

        # The callback for when the client receives a CONNACK response from
        # the server.
        def on_connect(client, userdata, flags, rc):
            print("Connected with result code " + str(rc))

            topic = ini_config.get("MQTT", "MQTT_TOPIC")

            # Subscribing in on_connect() means that if we lose the connection
            # and reconnect then subscriptions will be renewed.
            mqttc.subscribe(topic, qos=0)

        # The callback for when a PUBLISH message is received from the server.
        def on_message(client, userdata, msg):
            print(msg.topic + " " + str(msg.payload))

        mqtt_id = ini_config.get("MQTT", "MQTT_CLIENT_ID")
        user = ini_config.get("MQTT", "MQTT_USERNAME")
        pw = ini_config.get("MQTT", "MQTT_PASSWORD")
        host = ini_config.get("MQTT", "MQTT_HOST")
        port = ini_config.getint("MQTT", "MQTT_PORT")

        mqttc = mqtt.Client(client_id=mqtt_id,
                             clean_session=True,
                             protocol=mqtt.MQTTv31)

        mqttc.on_connect = on_connect
        mqttc.on_message = on_message
        mqttc.username_pw_set(user, password=pw)

        logging.debug("Connecting to MQTT Broker: "
                      "host [{0}], port [{1}], user [{2}]"
                      .format(host, port, user))

        mqttc.connect(host, port)

        # Blocking call that processes network traffic, dispatches callbacks
        # and handles reconnecting.
        # Other loop*() functions are available that give a threaded interface
        # and a manual interface.
        mqttc.loop_forever()

        return
    def del_readings(serial):
        """
        Deletes all measurement data for the given serial

        Parameters
        ----------
        serial: str (required)
            sensor unique serial number

        Returns
        -------
            nothing.
        """

        logging.debug("Deleting all measurements in SQLite database for "
                      "serial [{0}]".format(serial))

        sql_db = ini_config.get("SqlLite", "SQLITE_DB")
        conn = sqlite3.connect(sql_db)
        logging.debug("Connected to SQLite DB [{0}]".format(sql_db))

        c = conn.cursor()
        c.execute("DELETE FROM readings WHERE serial = '{0}' "
                   .format(serial))

        conn.commit()
        logging.debug("Measurements have been deleted from SQLite database")
        conn.close()

        logging.debug("Disconnected from SQLite DB [{0}]".format(sql_db))

        return
def read_publish_sensor_data():
    """ Function used to read sensor data and publish the readings to a topic
    served by an MQTT server.
    """

    # MQTT client publisher
    mqtt_publisher = MQTTPublisher()

    sensor_serial = ini_config.get("Sensor", "SENSOR_TEMPERATURE_SERIAL")
    sleep_timeout = ini_config.getint("Sensor", "SENSOR_SLEEP_TIME")

    # start daemon forever loop
    while True:

        try:
            # read and publish sensor reading to topic in MQTT server
            logging.debug("publishing sensor serial [{0}] data".format(sensor_serial))

            mqtt_publisher.publish_temperature(sensor_serial)

        except (Exception) as err:
            sys.stderr.write(str(err))
            logging.exception("Error reading/publishing sensor data. [{0}]".format(err))

        except:  # catch *all* other exceptions
            err = sys.exc_info()[0]
            logging.exception("Error occurred in mqtt daemon: [{0}]".format(err))

            write_to_file("<p>Error in mqttpublisher daemon: [{0}]</p>".format(err), sys.stderr)

        time.sleep(sleep_timeout)

    return
    def del_sensor(serial):
        """
        Deletes sensor data for the given serial

        Parameters
        ----------
        serial: str (required)
            sensor unique serial number

        Returns
        -------
            nothing.
        """

        mongodb_name = ini_config.get("MongoDB", "MONGO_DB")
        db = MongoDB.database(mongodb_name)

        coll = db["sensors"]

        logging.debug("Deleting sensor with serial [{0}] from MongoDB DB.".format(serial))

        result = coll.delete_many({"serial": serial})

        logging.debug("[{0}] sensors have been deleted from MongoDB database".format(result.deleted_count))

        db.client.close()

        logging.debug("Disconnected from MongoDB")

        return
    def del_readings(serial):
        """
        Deletes all measurement data for the given serial

        Parameters
        ----------
        serial: str (required)
            sensor unique serial number

        Returns
        -------
            nothing.
        """

        mongodb_name = ini_config.get("MongoDB", "MONGO_DB")
        db = MongoDB.database(mongodb_name)

        coll = db["readings"]

        logging.debug(
            "Deleting all readings in the MongoDB collection [{0}] " "for sensor serial [{1}].".format(coll, serial)
        )

        result = coll.delete_many({"serial": serial})

        logging.debug("[{0}] sensor readings have been deleted from " "MongoDB database".format(result.deleted_count))

        db.client.close()

        logging.debug("Disconnected from MongoDB")

        return
    def add_sensor(serial, geolocation, location, address, state, name, sensor_type, description):
        """
        Adds given sensor data to sensor database

        Parameters
        ----------
        serial:  str (required)
            sensor unique serial number.
        geolocation:  str (optional)
            GEO Location: LATITUDE, LONGITUDE 
        location: str (optional)
            ENGINE, HOME, PATIO, ...
        address: str (optional)
            Address where sensor is located
        state: str (required)
            UP, DOWN, ...
        name: str (required)
            name to help identify this sensor
        sensor_type: str (required)
            HUMIDITY, PRESSURE, TEMPERATURE, VELOCITY,  ...
        description: str(optional)
            helps describe this sensor

        Returns
        -------
            nothing.
        """

        mongodb_name = ini_config.get("MongoDB", "MONGO_DB")
        db = MongoDB.database(mongodb_name)

        coll = db["sensors"]

        logging.debug(
            "Adding following sensor to MongoDB database: "
            "serial [{0}], state [{1}], name [{2}], type [{3}]".format(serial, state, name, sensor_type)
        )

        result = coll.insert_one(
            {
                "_id": serial,
                "serial": serial,
                "geolocation": geolocation,
                "location": location,
                "address": address,
                "state": state,
                "name": name,
                "type": sensor_type,
                "description": description,
            }
        )

        logging.debug("Sensor with id [{0}] has been inserted " "into MongoDB database".format(result.inserted_id))

        db.client.close()

        logging.debug("Disconnected from MongoDB")

        return
Beispiel #8
0
        def on_connect(client, userdata, flags, rc):
            print("Connected with result code " + str(rc))

            topic = ini_config.get("MQTT", "MQTT_TOPIC")

            # Subscribing in on_connect() means that if we lose the connection
            # and reconnect then subscriptions will be renewed.
            mqttc.subscribe(topic, qos=0)
def teardown_request(exception):

    sql_enabled = ini_config.getboolean("SqlLite", "SQLITE_DB_ENABLE")
    sql_db = ini_config.get("SqlLite", "SQLITE_DB")

    # disconnect DB connection only if DB is enabled
    if sql_enabled and hasattr(g, 'db'):
        g.db.close()
        logging.debug("Disconnected from DB [{0}]".format(sql_db))

    return
    def add_sensor(serial, geolocation, location, address, state, name,
                    sensor_type, description):
        """
        Adds given sensor data to sensor database

        Parameters
        ----------
        serial:  str (required)
            sensor unique serial number.
        geolocation:  str (optional)
            GEO Location: LATITUDE, LONGITUDE 
        location: str (optional)
            ENGINE, HOME, PATIO, ...
        address: str (optional)
            Address where sensor is located
        state: str (required)
            UP, DOWN, ...
        name: str (required)
            name to help identify this sensor
        sensor_type: str (required)
            HUMIDITY, PRESSURE, TEMPERATURE, VELOCITY,  ...
        description: str(optional)
            helps describe this sensor

        Returns
        -------
            nothing.
        """

        logging.debug("Inserting sensor in SQLite database: "
                      "serial [{0}], state [{1}], name [{2}], type [{3}]"
                      .format(serial, state, name, sensor_type))

        sql_db = ini_config.get("SqlLite", "SQLITE_DB")
        conn = sqlite3.connect(sql_db)
        logging.debug("Connected to SQLite DB [{0}]".format(sql_db))

        c = conn.cursor()

        c.execute("INSERT INTO sensor ( serial, geolocation, location, "
                    " address, state, name, type, description ) "
                  "VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
                  (serial, geolocation, location, address, state, name,
                    sensor_type, description))

        conn.commit()
        logging.debug("sensor has been committed in database")
        conn.close()

        logging.debug("Disconnected from SQLite DB [{0}]".format(sql_db))

        return
    def get_readings(serial, current_datetime, past_datetime):
        """
        Returns .....

        Parameters
        ----------
        serial: str (required)
            sensor unique serial number
        current_datetime: str (required)
            a valid UTC timestamp
        past_datetime: str (required)
            a valid UTC timestamp

        Returns
        -------
        dict:
            A sensor dictionary containing column names as keys, and
            corresponding values.
        """

        mongodb_name = ini_config.get("MongoDB", "MONGO_DB")
        db = MongoDB.database(mongodb_name)

        coll = db["readings"]

        logging.debug(
            "Retrieving readings for sensor with serial [{0}] "
            "between [{1}] and [{2}] from MongoDB database.".format(serial, past_datetime, current_datetime)
        )

        cursor = coll.find({"serial": serial, "utc": {"$lt": current_datetime}, "utc": {"$gt": past_datetime}}).sort(
            "utc", pymongo.ASCENDING
        )

        data = None

        if cursor.count() > 0:
            data = list(cursor)

        logging.debug("Readings [{0}] retrieved from MongoDB for sensor with " "serial [{1}]".format(data, serial))

        db.client.close()

        logging.debug("Disconnected from MongoDB")

        if data is not None:
            # convert any MongoDB ObjectId and others (ie Binary, Code, etc)
            # to a string equivalent such as "$oid." and revert back to dict.
            data = json.loads(json_util.dumps(data))

        return data
Beispiel #12
0
def setup_routes():
    """Sets up the routes for the REST resources
    """
    # The Flask RESTful API object
    api = FlaskRESTfulAPI(current_app)

    # rest_apis: REST APIs that should be enabled.
    restful_apis = ini_config.get("REST", "RESTFUL_APIS")
    rest_api_list = restful_apis.upper().split(",")
    rest_apis = [str(value).strip() for value in rest_api_list]

    # Temperature API
    if "TEMPERATURE" in rest_apis:
        api.add_resource(RESTTemperatureResource, "/temperature/<string:to_unit>")
        logging.info("temperature REST API is enabled")

    # Weight API
    if "WEIGHT" in rest_apis:
        api.add_resource(RESTWeightResource, "/weight/<string:to_unit>")
        logging.info("weight REST API is enabled")

    # Length API
    if "LENGTH" in rest_apis:
        api.add_resource(RESTLengthResource, "/length/<string:to_unit>")
        logging.info("length REST API is enabled")

    # PRODUCT_INFO
    if "PRODUCT_INFO" in rest_apis:
        api.add_resource(RESTProductInfoResource, "/information/product")
        logging.info("Product Info REST API is enabled")

    # IoT - Sensor Temperature API
    if "SENSOR_TEMPERATURE" in rest_apis:
        api.add_resource(RESTSensorTemperatureResource, "/temperature/sensors/<string:serial>")
        logging.info("Sensor Temperature REST API is enabled")

    # IoT - Sensor Information API
    if "SENSOR_INFO" in rest_apis:
        api.add_resource(RESTSensorInfoResource, "/information/sensors", "/information/sensors/<string:serial>")
        logging.info("Sensor Information REST API is enabled")

    # IoT - Sensor Temperature Analytics API
    if "SENSOR_TEMPERATURE_ANALYTICS" in rest_apis:
        api.add_resource(RESTSensorTemperatureAnalyticsResource, "/analytics/temperature/sensors/<string:serial>")
        logging.info("Sensor Temperature Analytics REST API is enabled")

    # URL API
    if "URL" in rest_apis:
        api.add_resource(RESTUrlResource, "/resource")
        logging.info("URL REST API is enabled")
    def get_sensor(serial):
        """
        Returns a tuple corresponding to the sensor table in the database
        for the given sensor serial.

        Parameters
        ----------
        serial: str (required)
            sensor unique serial number

        Returns
        -------
        dict:
            A sensor dictionary containing column names as keys, and
            corresponding values.
        """

        mongodb_name = ini_config.get("MongoDB", "MONGO_DB")
        db = MongoDB.database(mongodb_name)

        coll = db["sensors"]

        logging.debug("Retrieving sensor with serial [{0}] " "from MongoDB database.".format(serial))

        cursor = coll.find({"serial": serial})

        # at most we are only allowed to have one sensor per serial
        if cursor.count() > 1:
            db.client.close()
            raise RuntimeError(
                "More than one sensor found in MongoDB [{0}] " "for sensor serial [{1}]".format(db, serial)
            )

        data = None
        for document in cursor:
            data = document

        logging.debug("[{0}] sensors have been retrieved from MongoDB DB".format(data))

        db.client.close()

        logging.debug("Disconnected from MongoDB")

        if data is not None:
            # convert any MongoDB ObjectId and others (ie Binary, Code, etc)
            # to a string equivalent such as "$oid." and revert back to dict.
            data = json.loads(json_util.dumps(data))

        return data
    def get_readings(serial, current_datetime, past_datetime):
        """
        Returns .....

        Parameters
        ----------
        serial: str (required)
            sensor unique serial number
        current_datetime: str (required)
            a valid UTC timestamp
        past_datetime: str (required)
            a valid UTC timestamp

        Returns
        -------
        dict:
            A sensor dictionary containing column names as keys, and
            corresponding values.
        """

        logging.debug("Retrieving readings from sensor with serial [{0}] "
                       "between [{1}] and [{2}] from SQLite database."
                      .format(serial, past_datetime, current_datetime))

        sql = ("SELECT utc, serial, unit, value FROM readings WHERE serial = '{0}' "
               "AND utc BETWEEN '{1}' AND '{2}' "
               "ORDER BY utc ASC"
               .format(serial, past_datetime, current_datetime))

        sql_db = ini_config.get("SqlLite", "SQLITE_DB")
        conn = sqlite3.connect(sql_db)
        logging.debug("Connected to SQLite DB [{0}]".format(sql_db))

        c = conn.cursor()
        c.row_factory = dict_factory
        cursor = c.execute(sql)
        data = cursor.fetchall()

        conn.commit()
        conn.close()

        logging.debug("Disconnected from SQLite DB [{0}]".format(sql_db))

        return data
    def add_reading(unit, value, utc, serial):
        """
        Adds given measurement data to sensor database

        Parameters
        ----------
        unit:  str (required)
            degF, degC, degF.
        value:  float (required)
            a float number
        utc: str (required)
            UTC timestamp of the reading
        serial: str (required)
            sensor unique serial number

        Returns
        -------
            nothing.
        """

        mongodb_name = ini_config.get("MongoDB", "MONGO_DB")
        db = MongoDB.database(mongodb_name)

        coll = db["readings"]

        result = coll.insert_one({"unit": unit, "value": value, "utc": utc, "serial": serial})

        logging.debug(
            "Sensor reading with id [{0}] has been inserted " "into MongoDB database".format(result.inserted_id)
        )

        db.client.close()

        logging.debug("Disconnected from MongoDB")

        return
    def get_sensor(serial):
        """
        Returns a tuble corresponding to the sensor table in the database
        for the given sensor serial.

        Parameters
        ----------
        serial: str (required)
            sensor unique serial number

        Returns
        -------
        dict:
            A sensor dictionary containing column names as keys, and
            corresponding values.
        """

        logging.debug("Retrieving sensor with serial [{0}] from database."
                      .format(serial))

        sql_db = ini_config.get("SqlLite", "SQLITE_DB")
        conn = sqlite3.connect(sql_db)
        logging.debug("Connected to SQLite DB [{0}]".format(sql_db))

        c = conn.cursor()
        c.row_factory = dict_factory
        cursor = c.execute(("SELECT * FROM sensor WHERE serial = '{0}'"
                             .format(serial)))
        data = cursor.fetchone()

        conn.commit()
        conn.close()

        logging.debug("Disconnected from SQLite DB [{0}]".format(sql_db))

        return data
    def add_reading(unit, value, utc, serial):
        """
        Adds given measurement data to sensor database

        Parameters
        ----------
        unit:  str (required)
            degF, degC, degF.
        value:  float (required)
            a float number
        utc: str (required)
            UTC timestamp of the reading
        serial: str (required)
            sensor unique serial number

        Returns
        -------
            nothing.
        """
      
        sql_db = ini_config.get("SqlLite", "SQLITE_DB")
        conn = sqlite3.connect(sql_db)
        logging.debug("Connected to SQLite DB [{0}]".format(sql_db))

        c = conn.cursor()
        c.execute("INSERT INTO readings (id, unit, value, utc, serial) "
                  "VALUES (?,?,?,?,?)",
                  (None, unit, value, utc, serial))

        conn.commit()
        logging.debug("Measurement has been committed in SQLite database")
        conn.close()

        logging.debug("Disconnected from SQLite DB [{0}]".format(sql_db))

        return
import logging

from flask import Flask

from rgapps.config import ini_config
from rgapps.http.routes import setup_routes


__author__ = "Rubens S. Gomes <*****@*****.**>"
__copyright__ = "Copyright (c) 2015 Rubens S. Gomes"
__license__ = "All Rights Reserved"
__maintainer__ = "Rubens Gomes"
__email__ = "*****@*****.**"
__status__ = "Experimental"

instance_path = ini_config.get("Flask", "INSTANCE_PATH")

logging.info("creating Flask app ...")
app = Flask(__name__,
            instance_path=instance_path,
            instance_relative_config=True)

is_debug = ini_config.getboolean("Flask", "DEBUG")
is_testing = ini_config.getboolean("Flask", "TESTING")
is_json_sort_keys = ini_config.getboolean("Flask", "JSON_SORT_KEYS")
max_content_length = ini_config.getint("Flask", "MAX_CONTENT_LENGTH")

app.config.update(DEBUG=is_debug,
                   TESTING=is_testing,
                   JSON_SORT_KEYS=is_json_sort_keys,
                   MAX_CONTENT_LENGTH=max_content_length)
Beispiel #19
0
    def publish_temperature(serial):
        """
        Publishes the given temperature sensor data to MQTT
        message broker.

        Parameters
        ----------
        serial:  str (required)
            sensor serial number

        Returns
        -------

        """

        # test serial
        if is_blank(serial):
            raise IllegalArgumentException("serial is required")

        mqtt_id = ini_config.get("MQTT", "MQTT_CLIENT_ID")
        user = ini_config.get("MQTT", "MQTT_USERNAME")
        pw = ini_config.get("MQTT", "MQTT_PASSWORD")
        host = ini_config.get("MQTT", "MQTT_HOST")
        port = ini_config.getint("MQTT", "MQTT_PORT")
        topic = ini_config.get("MQTT", "MQTT_TOPIC")


        mqttc = mqtt.Client(client_id=mqtt_id,
                             clean_session=True,
                             protocol=mqtt.MQTTv31)
        mqttc.username_pw_set(user, password=pw)

        sensor_temperature = DS18B20Sensor(serial)
        readings = sensor_temperature.get_measurement()

        message = OrderedDict()
        message["value"] = readings.get_value()
        message["unit"] = readings.get_unit()
        message["utc"] = readings.get_utc()

        json_message = json.dumps(message, indent=2, sort_keys=True)

        auth = OrderedDict()
        auth["username"] = user
        auth["password"] = pw

        logging.debug("Publishing to MQTT Broker: "
                      "host [{0}], port [{1}], client id [{2}], "
                      "user [{3}], sensor serial [{4}]"
                      .format(host, port, mqtt_id, user, serial))

        publish.single(topic,
                        payload=json_message, qos=0,
                        retain=False,
                        hostname=host,
                        port=port,
                        client_id=mqtt_id,
                        keepalive=20,
                        auth=auth)

        logging.debug("Message [{0}] was published correctly: "
                      "host [{1}], port [{2}], client id [{3}], "
                      "user [{4}], sensor serial [{5}]"
                      .format(message, host, port, mqtt_id, user, serial))

        return
Beispiel #20
0
 def test_send_text(self):
     logging.debug("testing sms send_text")
     phone = ini_config.get("SMS", "TESTING_PHONE")
     SMS.send_text(phone, "TESTING message")
     return
def read_store_readings ():
    """ Function used to read and store sensor readings
    """
    logging.debug("inside read_store_readings...")

    if globalFlaskApp is None:
        logging.error("Flask has not been initialized!")
        raise EnvironmentError("Flask has not been initialized")

    # error flag used to send email only once if error occurs.
    error_flag = False

    headers = {'content-type': 'application/json'}

    sensor_url = ini_config.get("Sensor", "SENSOR_TEMPERATURE_URL")
    sensor_serial = ini_config.get("Sensor", "SENSOR_TEMPERATURE_SERIAL")

    rest_url = (sensor_url + "/" + sensor_serial)
    logging.debug("sensor REST URL is [{0}]".format(rest_url))

    rest_user = ini_config.get("Sensor", "SENSOR_REST_API_USERNAME")
    rest_pw = ini_config.get("Sensor", "SENSOR_REST_API_PASSWORD")
    req_timeout = ini_config.getint("Sensor", "SENSOR_REQUEST_TIMEOUT")
    sleep_timeout = ini_config.getint("Sensor", "SENSOR_SLEEP_TIME")
    recipient = ini_config.get("Email", "RECIPIENT_EMAIL")

    with globalFlaskApp.app_context():

        logging.debug("starting forever loop within Flask app context")

        # start daemon forever loop
        while True:

            try:
                # collect data from sensor using RESTFul API
                logging.debug("Sending request to [{0}] with user [{1}]"
                               .format(rest_url, rest_user))

                r = requests.get(rest_url,
                                 verify=False,
                                 auth=(rest_user, rest_pw),
                                 headers=headers,
                                 timeout=req_timeout)

                # if code gets here no exception has occurred. reset flag.
                error_flag = False

                if (r.status_code != 200):
                    logging.error("Response status code [{0}] : [{1}]"
                                   .format(r.status_code, r.text))
                else:
                    output = r.json()
                    sensor = output[SENSOR_KEY]
                    readings = output[DATA_KEY]

                    logging.debug("Adding sensor record with unit [{0}], "
                                   "value [{1}], utc [{2}], serial [{3}] to "
                                   "database."
                                   .format(readings["unit"],
                                           readings["value"],
                                           readings["utc"],
                                           sensor["serial"]))

                    SensorDAO.add_reading(readings["unit"],
                                          readings["value"],
                                          readings["utc"],
                                          sensor["serial"])

            # python 3.4: ConnectionRefusedError
            except (ConnectionError, Timeout) as err:  # e.g., server is down.
                sys.stderr.write(str(err))

                logging.exception("Connection Error with URL [{0}], "
                                   "user [{1}] in runserver daemon: [{2}]"
                                   .format(rest_url, rest_user, err))

                if not error_flag :  # only send email once.
                    subject = "sensorserver: Connection/Timeout Error"
                    logging.info("Sending email to [{0}] with subject [{1}]"
                                  .format(recipient, subject))
                    message = ("Connection/Timeout Error to URL [{0}]: [{1}]"
                               .format(rest_url, err))
                    try:
                        EMail.send_email(recipient, subject, message)
                        logging.info("email to [{0}] with subject [{1}] sent."
                                      .format(recipient, subject))
                    except Exception as mail_err:
                        logging.error("Error [{0}] sending email."
                                       .format(mail_err))

                error_flag = True

            except (HTTPError, RequestException) as err:
                sys.stderr.write(str(err))

                logging.exception("HTTP/Request Error to URL [{0}] in "
                                   "runserver daemon: [{1}]"
                                   .format(rest_url, err))

                if not error_flag :  # only send email once.
                    subject = "sensorserver: HTTP Error"
                    logging.info("Sending email to [{0}] with subject [{1}]"
                                  .format(recipient, subject))
                    message = ("HTTP/Request to URL [{0}] Error: [{1}]"
                               .format(rest_url, err))

                    try:
                        EMail.send_email(recipient, subject, message)
                        logging.info(
                            "email to [{0}] with subject [{1}] was sent."
                            .format(recipient, subject))
                    except Exception as mail_err:
                        logging.error("Error [{0}] sending email."
                                       .format(mail_err))

                error_flag = True

            except (EnvironmentError, Exception) as err:
                sys.stderr.write(str(err))

                logging.exception("Error in runserver daemon: [{0}]"
                                   .format(err))

                if not error_flag :  # only send email once.
                    subject = "sensorserver: Environment Error"
                    logging.info("Sending email to [{0}] with subject [{1}]"
                                  .format(recipient, subject))
                    message = "EXITING APPLICATION. Error: [{0}]".format(err)

                    try:
                        EMail.send_email(recipient, subject, message)
                        logging.info(
                            "email to [{0}] with subject [{1}] was sent."
                            .format(recipient, subject))
                    except Exception as mail_err:
                        logging.error("Error [{0}] sending email."
                                       .format(mail_err))

                error_flag = True

            except:  # catch *all* other exceptions
                err = sys.exc_info()[0]
                logging.exception("Error occurred in runserver daemon: [{0}]"
                                   .format(err))

                write_to_file("<p>Error in runsensor daemon: [{0}]</p>"
                              .format(err), sys.stderr)
                exit(1)


            time.sleep(sleep_timeout)

    return
def run():
    """ daemon run function.

    This function should be called to start the system.
    """

    instance_path = ini_config.get("Flask", "INSTANCE_PATH")

    # app: Flask application object
    logging.debug("initializing the Flask app")
    global globalFlaskApp
    globalFlaskApp = Flask(__name__,
                            instance_path=instance_path,
                            instance_relative_config=True)

    is_debug = ini_config.getboolean("Flask", "DEBUG")
    is_testing = ini_config.getboolean("Flask", "TESTING")
    is_json_sort_keys = ini_config.getboolean("Flask", "JSON_SORT_KEYS")
    max_content_length = ini_config.getint("Flask", "MAX_CONTENT_LENGTH")

    globalFlaskApp.config.update(DEBUG=is_debug,
                                  TESTING=is_testing,
                                  JSON_SORT_KEYS=is_json_sort_keys,
                                  MAX_CONTENT_LENGTH=max_content_length)


    with globalFlaskApp.app_context():

        logging.info("Starting application ...")

        from rgapps.utils.utility import get_log_file_handles
        logger_fds = get_log_file_handles(logging.getLogger())
        logging.debug("Logger file handles fileno [{0}]"
                       .format(logger_fds))

        system = platform.system()

        if system == "Linux":
            logging.info("Server running on Linux.")

            pid_file = ini_config.get("Sensor", "SENSOR_PID_FILE")
            working_dir = ini_config.get("Logging", "WORKING_DIR")

            logging.debug("Instantiating daemon with pid_file [{0}] "
                           "and working_dir [{1}]"
                           .format(pid_file, working_dir))

            import daemon.pidfile

            daemon_context = daemon.DaemonContext(
                working_directory=working_dir,
                umask=0o002,
                pidfile=daemon.pidfile.PIDLockFile(pid_file))

            logging.debug("Setting up daemon signal map")
            daemon_context.signal_map = { signal.SIGTERM: program_cleanup }
            logging.debug("daemon signal map has been setup")

            if (logger_fds):
                logging.debug("setting files_preserve for the log file "
                               "descriptor [{0}]"
                               .format(logger_fds))
                daemon_context.files_preserve = logger_fds

            logging.debug("Starting daemon by opening its context.")
            daemon_context.open()

            logging.info("Calling read_store_readings....")
            read_store_readings()

            logging.debug("Closing the daemon context.")
            daemon_context.close()

        else:
            logging.info("Server running on Windows system ...")
            read_store_readings()

    return
def before_request():
    """
    Handler to be run at the beginning of every single request to
    ensure that the income request is compliant to the existing
    REST API.  For example, it checks to ensure that the ACCEPT
    HTTP Header contains the Content Type support by the REST API.
    """
    url = request.url
    logging.debug("Requested URL [{0}]".format(url))

    accept = request.headers.get('Accept')
    logging.debug("HTTP Request Header Accept [{0}]".format(accept))

    accept_language = request.headers.get('Accept-Language')
    logging.debug("HTTP Request Header Accept-Language [{0}]"
                             .format(accept_language))

    content_length = request.headers.get('Content-Length')
    logging.debug("HTTP Request Content-Length [{0}]"
                             .format(content_length))

    ip = request.remote_addr
    logging.debug("Client IP Address [{0}]".format(ip))

    user_agent = request.headers.get('User-Agent')
    logging.debug("HTTP Client User-Agent [{0}]"
                             .format(user_agent))

    date = request.headers.get("Date")
    logging.debug("HTTP Request date [{0}]".format(date))

    json_weigth = request.accept_mimetypes["application/json"]
    logging.debug("application/json accept weight [{0}]"
                             .format(json_weigth))

    if json_weigth <= 0:
        # The incoming HTTP Accept header specifies a media type that is
        # not supported by this application REST API.  Currently, only
        # the JSON media type is accepted.
        msg = "HTTP Request Header Accept [{0}] not supported".format(accept)
        logging.warn(msg)
        raise NotAcceptable(msg)

    method = request.method

    if method != 'GET':
        # At this time only 'GET' methods are accepted
        msg = "HTTP Method [{0}] not supported".format(accept)
        logging.warn(msg)
        raise MethodNotAllowed(msg)

    # acquire DB connection only if DB is enabled
    is_sql_enabled = ini_config.getboolean("SqlLite", "SQLITE_DB_ENABLE")
    sql_db = ini_config.get("SqlLite", "SQLITE_DB")
    if is_sql_enabled :
        db = getattr(g, 'db', None)
        if db is None:
            g.db = sqlite3.connect(sql_db)
            logging.debug("Connected to DB [{0}]".format(sql_db))

    return
    def send_email(recipient, subject, message):
        """Sends given message using Gmail credentials defined in the
        configuration file.

        Parameters
        ----------
        recipient:  str (required)
            recipient email address
        subject:  str (optional)
            email subject
        message: str (optional)
            message to send

        Returns
        -------
            nothing.

        Raises
        ------
        SMTPHeloError:
            The server didn't reply properly to the helo greeting.
        SMTPAuthenticationError:
            The server didn't accept the username/password combination.
        SMTPException:
            No suitable authentication method was found.
        SMTPRecipientsRefused:
          The server rejected ALL recipients (no mail was sent).
        SMTPSenderRefused:
            The server didn't accept the from_addr.
        SMTPDataError:
            The server replied with an unexpected error code (other than a
            refusal of a recipient).
        """

        if is_blank (recipient):
            raise IllegalArgumentException("recipient is required.")

        # ensure valid GMail Account
        gmail_account = ini_config.get("Email", "GMAIL_ACCOUNT")
        is_valid = validate_email(gmail_account)

        if(not is_valid):
            raise IllegalArgumentException(
                "GMail Account [{0}] is not valid email address"
                .format(gmail_account))

        gmail_user = ini_config.get("Email", "GMAIL_ACCOUNT")
        gmail_password = ini_config.get("Email", "GMAIL_PASSWORD")

        logging.debug("Sending email using Gmail account [{0}]  "
                      "to recipient [{1}]"
                      .format(gmail_user, recipient))

        is_valid = validate_email(recipient)

        if(not is_valid):
            raise IllegalArgumentException(
                "Recipient [{0}] is not valid email address"
                .format(recipient))

        msg = MIMEMultipart()
        msg['From'] = gmail_user
        msg['To'] = recipient
        msg['Subject'] = subject
        msg.attach(MIMEText(message))

        logging.debug("Sending email to [{0}] using Gmail account [{1}]"
                      .format(recipient, gmail_user))

        mail_server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
        mail_server.login(gmail_user, gmail_password)
        failed_recipients = mail_server.sendmail(
            gmail_user, recipient, msg.as_string())

        if failed_recipients:
            logging.warn("Email failed to following recipients [{0}]"
                         .format(failed_recipients))

        mail_server.close()

        return