Exemplo n.º 1
0
    def __init__(self):
        self.logger = self.logSetup()

        alerts = Alerts(self.logger)
        alerts.alertInfo('Raspberry Pi: Running HappyFish.py')

        self.mqtt_email = os.environ["MQTT_EMAIL"]
        self.mqtt_password = os.environ["MQTT_PASSWORD"]

        self.logger.info('='*50)
        self.logger.info('Running main script')

        self.settings = Settings(self.logger, False)

        self.electronics = Electronics(self.logger, self.settings)

        self.logger.info('Updating the pwm modules for the first time')
        self.result = self.electronics.updateModule()

        self.reconnect_count = 0
        self.reconnect_delay = 60

        if self.result == True:
            self.logger.info('PWM modules updated. Electronics working as intended')
        else:
            self.logger.critical('Failed to light up the lab room. Check pwm modules')
            self.logger.critical('Terminating script. Please check hardware')
            alerts = Alerts(self.logger)
            alerts.alertCritical('Raspberry Pi: PWM Module cannot be opened')
            exit()

        self.connection = Connection(self.logger, self.settings, self.mqtt_email, self.mqtt_password)
        self.connection.start(self)
        self.reconnecting = False
Exemplo n.º 2
0
def test_delete(fb):
    id = "test@test"
    type = "temperature"
    bound = 80
    direction = "gt"

    # Delete everything
    fb.delete(dummy_database, None)

    # Add previous data
    fb.post(dummy_database, {
        "id": id,
        "type": type,
        "bound": bound,
        "direction": direction
    })

    alerts = Alerts(lambda x: x, dummy_database)

    # Delete alert
    alerts.delete_alert(id, type, bound, direction)
    assert len(alerts.alerts) == 0

    # Try deleting alert again
    alerts.delete_alert(id, type, bound, direction)
    assert len(alerts.alerts) == 0
Exemplo n.º 3
0
    def getBrightnessPercentage(self):

        raw_stage = self.getStageInfo()

        current_stage = raw_stage[0]
        seconds = raw_stage[1]

        if current_stage != self.stage:
            self.logger.info('Scheduled stage changed from \'' + self.stage +
                             '\' to \'' + current_stage + '\'')
            alerts = Alerts(self.logger)
            alerts.alertInfo('Scheduled stage changed from \'' + self.stage +
                             '\' to \'' + current_stage + '\'')
            self.stage = current_stage

        if self.stage == Stages.pre_sun_rise or self.stage == Stages.post_sun_set:
            return 0.0

        if self.stage == Stages.sun_rise:
            return float(seconds - self.sunrise_start) / float(
                self.duration_seconds)

        if self.stage == Stages.sun_set:
            return 1 - (float(seconds - self.sunset_start) /
                        float(self.duration_seconds))

        return 1.0
Exemplo n.º 4
0
def test_alerts(fb):
    id = "test@test"
    type = "temperature"
    bound = 80
    direction = "gt"

    # Delete everything
    fb.delete(dummy_database, None)

    alerts = Alerts(lambda x: x, dummy_database)
    assert len(alerts.alerts) == 0

    alerts.add_alert(id, type, bound, direction)
    assert len(alerts.alerts) == 1
    assert alerts.alerts.ix[0].id == id
    assert alerts.alerts.ix[0].type == type
    assert alerts.alerts.ix[0].bound == bound
    assert alerts.alerts.ix[
        0].direction == operator.gt if direction == 'gt' else operator.lt

    a = alerts.get_alerts()
    assert (len(a['alerts']) == 1)
    assert a['alerts'][0]['id'] == id
    assert a['alerts'][0]['type'] == type
    assert a['alerts'][0]['bound'] == bound
    assert a['alerts'][0]['direction'] == direction
Exemplo n.º 5
0
def test_add(fb):
    id = "test@test"
    type = "temperature"
    bound = 80
    direction = "gt"

    # Delete everything
    fb.delete(dummy_database, None)

    # Create new alerts
    alerts = Alerts(lambda x: x, dummy_database)
    assert len(alerts.alerts) == 0

    # Add one alert
    alerts.add_alert(id, type, bound, direction)

    assert len(alerts.alerts) == 1
    assert alerts.alerts.ix[0].id == id
    assert alerts.alerts.ix[0].type == type
    assert alerts.alerts.ix[0].bound == bound
    assert alerts.alerts.ix[
        0].direction == operator.gt if direction == 'gt' else operator.lt

    # Try adding again
    alerts.add_alert(id, type, bound, direction)

    # Nothing should have changed
    assert len(alerts.alerts) == 1
    assert alerts.alerts.ix[0].id == id
    assert alerts.alerts.ix[0].type == type
    assert alerts.alerts.ix[0].bound == bound
    assert alerts.alerts.ix[
        0].direction == operator.gt if direction == 'gt' else operator.lt
Exemplo n.º 6
0
 def on_disconnect(self, client, userdata, flags, rc=0):
     self.logger.critical('Connection disconnected, return code: ' +
                          str(rc))
     self.happyfish.reconnect_delay = self.happyfish.reconnect_delay * 2
     self.connection_closed = True
     self.time_ended = time()
     alerts = Alerts(self.logger)
     alerts.alertCritical(f'RPi disconnected from the MQTT server. RC {rc}')
Exemplo n.º 7
0
 def on_connect(self, client, userdata, flags, rc):
     self.is_connecting = False
     if rc == 0:
         self.established_connection = True
         self.logger.info('Connected with MQTT broker, result code: ' +
                          str(rc))
         self.happyfish.reconnect_delay = 60
         alerts = Alerts(self.logger)
         alerts.alertInfo('Raspberry Pi connected to MQTT successfully')
     else:
         self.established_connection = False
         self.failed_connection = True
         self.logger.critical('Bad connection, result code: ' + str(rc))
         self.happyfish.reconnect_delay = self.happyfish.reconnect_delay * 2
         alerts = Alerts(self.logger)
         alerts.alertCritical(
             f'Raspberry Pi could NOT connect to MQTT. Bad Connection. RC {rc}'
         )
Exemplo n.º 8
0
    def start(self):
        try:
            self.logger.info('Running main loop')
            while True:
                sleep(0.5)

                self.electronics.updateModule()

                if not self.reconnecting and self.connection.connection_closed and self.reconnect_count < 15:
                    self.logger.critical(f'Connection appears to be closed... Ending connection and will reconnect after {self.reconnect_delay/60} min(s)')
                    alerts = Alerts(self.logger)
                    alerts.alertCritical(f'Connection appears to be closed. Reconnecting again in {self.reconnect_delay/60} min(s). Reconnect count is {self.reconnect_count}')
                    self.connection.end()
                    self.reconnecting = True
                    self.timer = Timer(self.reconnect_delay, self.reconnect, args=None, kwargs=None)
                    self.timer.start()

        except KeyboardInterrupt:
            self.logger.critical('Script manually terminated')

        self.connection.end()

        self.settings.printConfig()

        self.logger.info('Script ended. Shutting down the lights')
        self.settings.turnAllOff()
        self.result = self.electronics.updateModule()

        if self.result == True:
            self.logger.info('Successfully turned off all the lights')
        else:
            self.logger.critical('Failed to turn off the lights. Unable to communicate with pwm module')

        alerts = Alerts(self.logger)
        alerts.alertCritical('HappyFish script got terminated... Unknown reason')

        self.ended = True
Exemplo n.º 9
0
    def __init__(self):
        ''' Constructs the GUI '''

        self.window = tk.Tk()
        self.window.title("Crypto Parking")
        self.window.attributes("-fullscreen", True)

        # Bind global keyboard commands
        self.window.bind("<Escape>", self.quit)

        self.window.config(bg=const.COLOR_BG)
        self.main_frame = MainFrame(self.window)
        self.main_frame.pack(side="top", fill="both", expand=True)

        # Call admin for help button
        self.call_admin_btn_img = ImageTk.PhotoImage(
            file="./assets/call_admin_btn.png")
        self.call_admin_btn = tk.Button(self.frame,
                                        width=175,
                                        height=35,
                                        highlightthickness=0,
                                        highlightbackground=const.COLOR_BG,
                                        bd=-2,
                                        bg=const.COLOR_BG,
                                        command=self.call_admin,
                                        image=self.call_admin_btn_img)
        self.call_admin_btn.pack()

        # Call admin for help button (pressed)
        self.help_otw_btn_img = ImageTk.PhotoImage(
            file="./assets/help_otw.png")
        self.help_otw_btn = tk.Button(self.frame,
                                      width=175,
                                      height=35,
                                      highlightthickness=0,
                                      highlightbackground=const.COLOR_BG,
                                      bd=-2,
                                      bg=const.COLOR_BG,
                                      image=self.help_otw_btn_img)

        # Instantiate alert sender module
        self.alert_sender = Alerts()

        #===========================================================================
        # CODE USED FOR TESTING
        # Dummy buttons simulate input
        '''self.frame = tk.Frame(
Exemplo n.º 10
0
def ia_process():
    # Génération du token    
    env_var.Generation_Token()
    env_var.Generation_Temperature_Moyenne()
    
    # Récupération des capteurs => /getSensors
    sensorsDataResponse = requests.get("https://eclisson.duckdns.org/ConnectedCity/getSensors", headers=env_var.HEADERS)
    sensorsData = json.loads(sensorsDataResponse.text)
    # Pour chaque capteur dans la base de données
    for sensor in sensorsData:
        print("Sensor ID : " + sensor["sensorID"][0])

        # Récupération des executions des capteurs => /getSensors/:id => 062336c2-d39b-42cf-a8bb-1d05de74bd7e
        rawDataResponse = requests.get("https://eclisson.duckdns.org/ConnectedCity/getRawData/"+sensor["sensorID"][0], headers=env_var.HEADERS)
        # Vérifie qu'il y a des executions pour ce capteur
        if rawDataResponse.text != "[]":
            rawData = json.loads(rawDataResponse.text)
            rawList = sorted(rawData, key=lambda item: item['time'], reverse=True)

            # Récupération de la dernière exécution du capteur
            lastExecution = rawList[0]
            # s, ms = divmod(int(lastExecution["time"]), 1000)

            # Vérification des différentes alertes
            pm25Alert = pm25_execution_process(lastExecution["PM25"])
            temperatureAlert = temperature_execution_process(lastExecution["temp"])
            co2Alert = co2_execution_process(lastExecution["C02"])
            humidityAlert = humidity_execution_process(lastExecution["humidity"])

            # Récupération des anciennes alertes pour le capteur en question
            AlertClass = Alerts()
            alertDataResponse = requests.get("https://eclisson.duckdns.org/ConnectedCity/getAlerts/"+sensor["sensorID"][0], headers=env_var.HEADERS)
            if alertDataResponse.text != "[]":
                # S'il y a déjà des alertes en base pour ce capteur, alors on compare les anciennes alertes avec les nouvelles
                print("Update des alertes en base de données")
                alertData = json.loads(alertDataResponse.text)
                AlertClass.updateAlerts(sensor, alertData[0], co2Alert, pm25Alert, humidityAlert, temperatureAlert)

            elif alertDataResponse.text == "[]":
                print("Insertion des alertes en base de données")
                # S'il n'y a aucune alerte référencée en base de données pour ce capteur, alors on insère en BDD les alertes détectées
                AlertClass.insertAlerts(sensor, co2Alert, pm25Alert, humidityAlert, temperatureAlert)
    s.enter(600, 1, ia_process, ())
Exemplo n.º 11
0
def test_clear(fb):
    id = "test@test"
    type = "temperature"
    bound = 80
    direction = "gt"

    # Delete everything
    fb.delete(dummy_database, None)

    alerts = Alerts(lambda x: x, dummy_database)
    assert len(alerts.alerts) == 0

    alerts.add_alert(id, type, bound, direction)
    assert len(alerts.alerts) == 1
    assert alerts.alerts.ix[0].id == id
    assert alerts.alerts.ix[0].type == type
    assert alerts.alerts.ix[0].bound == bound
    assert alerts.alerts.ix[
        0].direction == operator.gt if direction == 'gt' else operator.lt

    alerts.clear_alerts()
    assert len(alerts.alerts) == 0
Exemplo n.º 12
0
def test_previous_data(fb):
    id = "test@test"
    type = "temperature"
    bound = 80
    direction = "gt"

    # Add previous data
    fb.post(dummy_database, {
        "id": id,
        "type": type,
        "bound": bound,
        "direction": direction
    })

    alerts = Alerts(lambda x: x, dummy_database)

    assert alerts.alerts is not None
    assert len(alerts.alerts) == 1
    assert alerts.alerts.ix[0].id == id
    assert alerts.alerts.ix[0].type == type
    assert alerts.alerts.ix[0].bound == bound
    assert alerts.alerts.ix[
        0].direction == operator.gt if direction == 'gt' else operator.lt
Exemplo n.º 13
0
 def alerts_btn(self):
     root2 = Toplevel(self.master)
     myGui = Alerts(root2)
Exemplo n.º 14
0
            temp_c = temp_output
            particle_output = part.readline().strip()
            temp_hz, moist_hz = particle_output.split(', ')
            if temp_c and temp_hz and moist_hz:
                row = (dt, float(temp_c), float(temp_hz), float(moist_hz))
                print "%s, %f, %f, %f" % row
                output_data.append(row)
                if float(temp_c) < 23.0:
                    dump_the_pandas_data(output_data)
                    print "Completed Calibration"
                    return start

        except ValueError:
            pass
        except KeyboardInterrupt as e:
            print "Error:", e
            return start
        except Exception as e:
            dump_the_pandas_data(output_data)
            return start


if __name__ == '__main__':
    start = read_from_serial()
    elapsed = datetime.now() - start
    alert = Alerts(api_keys=settings.pushover_keys)
    msg = "Calibration program done. Time to complete: " + str(elapsed)
    print(msg)
    alert.send_pushover(msg)
    exit()
Exemplo n.º 15
0
    send_email(to=to, subject=subject, message=message)


logger = logging.getLogger('alerts')
logger.setLevel(logging.INFO)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
logger.addHandler(ch)

# Set up web server
app = Flask(__name__)
CORS(app)
data, get_more_data = get_data()

# Set up alerts
alerts = Alerts(triggered_alerts)
threading.Thread(target=alerts.run).start()


@app.route("/sensor/status")
def status():
    data = get_more_data()
    response = {"last_reading": data.ix[-1].name.value // 10**6}

    return jsonify(**response)


@app.route("/sensor/summary")
def summary():
    data = get_more_data()
Exemplo n.º 16
0
def main():
    """
  - Parse user-specified data from YaML
  - Check to see that the needed graphics are available. If not, get them.
  - Get the radar imagery, complete with warnings graphics
  - Get today's hazardous weather outlook statement and parse it
  - Check for FTM outage notifications
  - Get, parse, and write out current weather conditions to specified locations.
  - TODO: should run the getweather.sh shell script, that overlays/composites
    the weather graphics. At present, that shell script calls this script
    and runs the overlays with -bash-.
  - Check for and acquire current multi-band GOES-x imagery of a given resolution.
  """
    if os.path.exists('weatherwidget.log'):
        os.remove('weatherwidget.log')
    logging.basicConfig(
        filename='weatherwidget.log',
        level=logging.DEBUG,
        format='%(asctime)s %(levelname)s %(threadName)-10s %(message)s',
    )

    data = wf.load_settings_and_defaults(SETTINGS_DIR, 'settings.yml',
                                         'defaults.yml')
    if not data:
        logging.error('Unable to load settings files. These are required.')
        sys.exit(
            'settings files are required and could not be loaded successfully.'
        )

    logging.info('Checking for radar outage.')
    wf.outage_check(data)

    logging.info('Retrieving current weather observations.')
    right_now = Observation(data)
    right_now.get_current_conditions()
    right_now.get_backup_obs(use_json=False)
    right_now.merge_good_observations()
    logging.debug('Merged current conditions: %s', right_now.con1.obs)
    sum_con = right_now.conditions_summary()

    if right_now.con1.obs and sum_con:
        text_conditions, nice_con = right_now.format_current_conditions()
        logging.debug('Current conditions from primary source: %s', nice_con)
        wf.write_json(some_dict=nice_con,
                      outputdir=data['output_dir'],
                      filename='current_conditions.json')
    else:
        logging.error(
            'Something went wrong getting the current conditions. Halting.')
        return 1

    wf.write_text(os.path.join(data['output_dir'], 'current_conditions.txt'),
                  text_conditions)

    # Get radar image:
    current_radar = Radar(data)
    current_radar.check_assets()
    current_radar.get_radar()
    current_radar.get_warnings_box()
    if current_radar.problem:
        logging.error('Unable to retrieve weather radar image. Halting now.')

    # Hazardous Weather Outlook and alerts:
    today_alerts = Alerts(data)
    today_alerts.get_alerts()

    # Get hydrograph image.
    if wf.get_hydrograph(abbr=data['river_gauge_abbr'],
                         hydro_url=data['defaults']['water_url'],
                         outputdir=data['output_dir']).ok:
        logging.info('Requesting hydrograph for station %s, gauge "%s".',
                     data['radar_station'], data['river_gauge_abbr'])
    else:
        logging.error('Failed to get hydrograph information.')
        return 1

    forecast_obj = Forecast(data=data)
    logging.debug('Getting the forecasts.')
    forecast_obj.get_forecast()
    forecastdict = forecast_obj.parse_forecast()
    if forecastdict is None:
        logging.error('Unable to parse forecast!')
        return 1
    forecast_obj.write_forecast(outputdir=data['output_dir'])
    logging.debug('Getting area forecast discussion.')
    forecast_obj.get_afd()

    logging.debug('Getting zone forecast.')
    zoneforecast = ZoneForecast(data)
    zoneforecast.get()

    wf.write_json(some_dict=forecastdict,
                  outputdir=data['output_dir'],
                  filename='forecast.json')
    wsvg.make_forecast_icons(forecastdict, outputdir=data['output_dir'])

    # Satellite imagery:
    current_image = Imagery(band='GEOCOLOR', data=data)
    current_image.get_all()

    logging.info('Finished program run.')

    return 0
Exemplo n.º 17
0
def test_init(fb):
    # Delete everything
    fb.delete(dummy_database, None)

    alerts = Alerts(lambda x: x, dummy_database)
    assert len(alerts.alerts) == 0