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 subscribe_sensor_data():
    """ Function used to subscribe to topic destination where sensor readings
    are being published.
    """

    # MQTT client publisher
    mqtt_subscriber = MQTTSubscriber()

    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("subscribing to sensor TOPIC destination...")

            mqtt_subscriber.subscribe_temperature()

        except (Exception) as err:
            sys.stderr.write(str(err))
            logging.exception("Error subscribing to 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 mqttsubscriber daemon: [{0}]</p>"
                          .format(err), sys.stderr)

        time.sleep(sleep_timeout)

    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