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
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
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
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
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
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}')
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}' )
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
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(
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, ())
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
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
def alerts_btn(self): root2 = Toplevel(self.master) myGui = Alerts(root2)
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()
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()
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
def test_init(fb): # Delete everything fb.delete(dummy_database, None) alerts = Alerts(lambda x: x, dummy_database) assert len(alerts.alerts) == 0