Example #1
0
def settings_users():
    """ Display user settings """
    if not flaskutils.user_has_permission('view_settings'):
        return redirect(url_for('general_routes.home'))

    users = User.query.all()
    user_roles = Role.query.all()
    form_add_user = flaskforms.UserAdd()
    form_mod_user = flaskforms.UserMod()
    form_user_roles = flaskforms.UserRoles()

    if request.method == 'POST':
        if not flaskutils.user_has_permission('edit_users'):
            return redirect(url_for('general_routes.home'))

        if form_add_user.add_user.data:
            flaskutils.user_add(form_add_user)
        elif form_mod_user.delete.data:
            if flaskutils.user_del(form_mod_user) == 'logout':
                return redirect('/logout')
        elif form_mod_user.save.data:
            if flaskutils.user_mod(form_mod_user) == 'logout':
                return redirect('/logout')
        elif (form_user_roles.add_role.data or form_user_roles.save_role.data
              or form_user_roles.delete_role.data):
            flaskutils.user_roles(form_user_roles)
        return redirect(url_for('settings_routes.settings_users'))

    return render_template('settings/users.html',
                           themes=THEMES,
                           users=users,
                           user_roles=user_roles,
                           form_add_user=form_add_user,
                           form_mod_user=form_mod_user,
                           form_user_roles=form_user_roles)
Example #2
0
def admin_backup():
    """ Load the backup management page """
    if not flaskutils.user_has_permission('edit_settings'):
        return redirect(url_for('general_routes.home'))

    form_backup = flaskforms.Backup()

    backup_dirs = []
    if not os.path.isdir('/var/Mycodo-backups'):
        flash("Error: Backup directory doesn't exist.", "error")
    else:
        backup_dirs = sorted(next(os.walk('/var/Mycodo-backups'))[1])
        backup_dirs.reverse()

    backup_dirs_filtered = []
    for each_dir in backup_dirs:
        if each_dir.startswith("Mycodo-backup-"):
            backup_dirs_filtered.append(each_dir)

    if request.method == 'POST':
        form_name = request.form['form-name']
        if form_name == 'restore':
            if form_backup.restore.data:
                flash("Restore functionality is not currently enabled.",
                      "error")
                # formUpdate.restore.data
                # restore_command = '{path}/mycodo/scripts/mycodo_wrapper ' \
                #                   'restore >> /var/log/mycodo/mycodorestore.log 2>&1'.format(
                #                     path=INSTALL_DIRECTORY)
                # subprocess.Popen(restore_command, shell=True)

    return render_template('admin/backup.html',
                           form_backup=form_backup,
                           backup_dirs=backup_dirs_filtered)
Example #3
0
def page_usage():
    """ Display relay usage (duration and energy usage/cost) """
    if not flaskutils.user_has_permission('view_stats'):
        return redirect(url_for('general_routes.home'))

    misc = Misc.query.first()
    relay = Relay.query.all()

    relay_stats = return_relay_usage(misc, relay)

    day = misc.relay_usage_dayofmonth
    if 4 <= day <= 20 or 24 <= day <= 30:
        date_suffix = 'th'
    else:
        date_suffix = ['st', 'nd', 'rd'][day % 10 - 1]

    display_order = csv_to_list_of_int(DisplayOrder.query.first().relay)

    return render_template('pages/usage.html',
                           date_suffix=date_suffix,
                           display_order=display_order,
                           misc=misc,
                           relay=relay,
                           relay_stats=relay_stats,
                           timestamp=time.strftime("%c"))
Example #4
0
def computer_command(action):
    """Execute one of several commands as root"""
    if not flaskutils.user_has_permission('edit_settings'):
        return redirect(url_for('general_routes.home'))

    try:
        if action not in ['restart', 'shutdown']:
            flash("Unrecognized command: {action}".format(action=action),
                  "success")
            return redirect('/settings')
        cmd = '{path}/mycodo/scripts/mycodo_wrapper {action} 2>&1'.format(
            path=INSTALL_DIRECTORY, action=action)
        subprocess.Popen(cmd, shell=True)
        if action == 'restart':
            flash(gettext(u"System rebooting in 10 seconds"), "success")
        elif action == 'shutdown':
            flash(gettext(u"System shutting down in 10 seconds"), "success")
        return redirect('/settings')
    except Exception as e:
        logger.error("System command '{cmd}' raised and error: "
                     "{err}".format(cmd=action, err=e))
        flash(
            "System command '{cmd}' raised and error: "
            "{err}".format(cmd=action, err=e), "error")
        return redirect(url_for('general_routes.home'))
Example #5
0
def settings_camera():
    """ Display camera settings """
    if not flaskutils.user_has_permission('view_settings'):
        return redirect(url_for('general_routes.home'))

    form_camera = flaskforms.SettingsCamera()

    camera = Camera.query.all()
    relay = Relay.query.all()

    camera_libraries = []
    camera_types = []
    for camera_type, library in CAMERAS.items():
        camera_libraries.append(library)
        camera_types.append(camera_type)

    opencv_devices = count_cameras_opencv()

    pi_camera_enabled = False
    try:
        if 'start_x=1' in open('/boot/config.txt').read():
            pi_camera_enabled = True
    except IOError as e:
        logger.error("Camera IOError raised in '/settings/camera' endpoint: "
                     "{err}".format(err=e))

    if request.method == 'POST':
        if not flaskutils.user_has_permission('edit_settings'):
            return redirect(url_for('general_routes.home'))

        if form_camera.camera_add.data:
            flaskutils.camera_add(form_camera)
        elif form_camera.camera_mod.data:
            flaskutils.camera_mod(form_camera)
        elif form_camera.camera_del.data:
            flaskutils.camera_del(form_camera)
        return redirect(url_for('settings_routes.settings_camera'))

    return render_template('settings/camera.html',
                           camera=camera,
                           camera_libraries=camera_libraries,
                           camera_types=camera_types,
                           form_camera=form_camera,
                           opencv_devices=opencv_devices,
                           pi_camera_enabled=pi_camera_enabled,
                           relay=relay)
Example #6
0
def page_pid():
    """ Display PID settings """
    pids = PID.query.all()
    relay = Relay.query.all()
    sensor = Sensor.query.all()

    display_order = csv_to_list_of_int(DisplayOrder.query.first().pid)

    form_add_pid = flaskforms.PIDAdd()
    form_mod_pid = flaskforms.PIDMod()

    method = Method.query.all()

    if request.method == 'POST':
        if not flaskutils.user_has_permission('edit_controllers'):
            return redirect(url_for('general_routes.home'))

        form_name = request.form['form-name']
        if form_name == 'addPID':
            flaskutils.pid_add(form_add_pid)
        elif form_name == 'modPID':
            if form_mod_pid.delete.data:
                flaskutils.pid_del(
                    form_mod_pid.pid_id.data)
            elif form_mod_pid.reorder_up.data:
                flaskutils.pid_reorder(
                    form_mod_pid.pid_id.data, display_order, 'up')
            elif form_mod_pid.reorder_down.data:
                flaskutils.pid_reorder(
                    form_mod_pid.pid_id.data, display_order, 'down')
            elif form_mod_pid.activate.data:
                flaskutils.pid_activate(
                    form_mod_pid.pid_id.data)
            elif form_mod_pid.deactivate.data:
                flaskutils.pid_deactivate(
                    form_mod_pid.pid_id.data)
            elif form_mod_pid.hold.data:
                flaskutils.pid_manipulate(
                    form_mod_pid.pid_id.data, 'Hold')
            elif form_mod_pid.pause.data:
                flaskutils.pid_manipulate(
                    form_mod_pid.pid_id.data, 'Pause')
            elif form_mod_pid.resume.data:
                flaskutils.pid_manipulate(
                    form_mod_pid.pid_id.data, 'Resume')
            else:
                flaskutils.pid_mod(form_mod_pid)

        return redirect('/pid')

    return render_template('pages/pid.html',
                           method=method,
                           pids=pids,
                           relay=relay,
                           sensor=sensor,
                           displayOrder=display_order,
                           form_add_pid=form_add_pid,
                           form_mod_pid=form_mod_pid)
Example #7
0
def admin_backup():
    """ Load the backup management page """
    if not flaskutils.user_has_permission('edit_settings'):
        return redirect(url_for('general_routes.home'))

    form_backup = flaskforms.Backup()

    backup_dirs_tmp = []
    if not os.path.isdir('/var/Mycodo-backups'):
        flash("Error: Backup directory doesn't exist.", "error")
    else:
        backup_dirs_tmp = sorted(next(os.walk(BACKUP_PATH))[1])
        backup_dirs_tmp.reverse()

    backup_dirs = []
    full_paths = []
    for each_dir in backup_dirs_tmp:
        if each_dir.startswith("Mycodo-backup-"):
            backup_dirs.append(each_dir)
            full_paths.append(os.path.join(BACKUP_PATH, each_dir))

    if request.method == 'POST':
        if form_backup.backup.data:
            cmd = '{pth}/mycodo/scripts/mycodo_wrapper backup-create ' \
                  ' >> {log} 2>&1'.format(pth=INSTALL_DIRECTORY,
                                          log=BACKUP_LOG_FILE)
            subprocess.Popen(cmd, shell=True)
            flash(gettext(u"Backup in progress. It should complete within a "
                          u"few seconds to a few minutes. The backup will "
                          u"appear on this page after it completes."),
                  "success")
        elif form_backup.delete.data:
            cmd = '{pth}/mycodo/scripts/mycodo_wrapper backup-delete {dir}' \
                  ' 2>&1'.format(pth=INSTALL_DIRECTORY,
                                 dir=form_backup.selected_dir.data)
            subprocess.Popen(cmd, shell=True)
            flash(gettext(u"Deletion of backup in progress. It should "
                          u"complete within a few seconds to a few minutes. "
                          u"The backup will disappear on this page after it "
                          u"completes."),
                  "success")
        elif form_backup.restore.data:
            cmd = '{pth}/mycodo/scripts/mycodo_wrapper backup-restore ' \
                  '{backup} >> {log} 2>&1'.format(
                    pth=INSTALL_DIRECTORY,
                    backup=form_backup.full_path.data,
                    log=RESTORE_LOG_FILE)

            subprocess.Popen(cmd, shell=True)
            flash(gettext(u"Restore in progress. It should complete within a "
                          u"few seconds to a few minutes."),
                  "success")

    return render_template('admin/backup.html',
                           form_backup=form_backup,
                           backup_dirs=backup_dirs,
                           full_paths=full_paths)
Example #8
0
def admin_statistics():
    """ Display collected statistics """
    if not flaskutils.user_has_permission('view_stats'):
        return redirect(url_for('general_routes.home'))

    try:
        statistics = return_stat_file_dict(STATS_CSV)
    except IOError:
        statistics = {}
    return render_template('admin/statistics.html', statistics=statistics)
Example #9
0
def page_usage_reports():
    """ Display relay usage (duration and energy usage/cost) """
    if not flaskutils.user_has_permission('view_stats'):
        return redirect(url_for('general_routes.home'))

    report_location = os.path.normpath(USAGE_REPORTS_PATH)
    reports = [0, 0]

    return render_template('pages/usage_reports.html',
                           report_location=report_location,
                           reports=reports)
Example #10
0
def settings_alerts():
    """ Display alert settings """
    if not flaskutils.user_has_permission('view_settings'):
        return redirect(url_for('general_routes.home'))

    smtp = SMTP.query.first()
    form_email_alert = flaskforms.EmailAlert()

    if request.method == 'POST':
        if not flaskutils.user_has_permission('edit_settings'):
            return redirect(url_for('general_routes.home'))

        form_name = request.form['form-name']
        if form_name == 'EmailAlert':
            flaskutils.settings_alert_mod(form_email_alert)
        return redirect(url_for('settings_routes.settings_alerts'))

    return render_template('settings/alerts.html',
                           smtp=smtp,
                           form_email_alert=form_email_alert)
Example #11
0
def calibration_select():
    """
    Landing page to initially select the device to calibrate
    """
    if not flaskutils.user_has_permission('edit_controllers'):
        return redirect(url_for('general_routes.home'))
    form_calibration = flaskforms.Calibration()
    if form_calibration.submit.data:
        route = 'calibration_routes.{page}'.format(
            page=form_calibration.selection.data)
        return redirect(url_for(route))
    return render_template('tools/calibration.html',
                           form_calibration=form_calibration)
Example #12
0
def settings_general():
    """ Display general settings """
    if not flaskutils.user_has_permission('view_settings'):
        return redirect(url_for('general_routes.home'))

    misc = Misc.query.first()
    form_settings_general = flaskforms.SettingsGeneral()

    languages_sorted = sorted(LANGUAGES.items(), key=operator.itemgetter(1))

    if request.method == 'POST':
        if not flaskutils.user_has_permission('edit_settings'):
            return redirect(url_for('general_routes.home'))

        form_name = request.form['form-name']
        if form_name == 'General':
            flaskutils.settings_general_mod(form_settings_general)
        return redirect(url_for('settings_routes.settings_general'))

    return render_template('settings/general.html',
                           misc=misc,
                           languages=languages_sorted,
                           form_settings_general=form_settings_general)
Example #13
0
def page_lcd():
    """ Display LCD output settings """
    lcd = LCD.query.all()
    pid = PID.query.all()
    relay = Relay.query.all()
    sensor = Sensor.query.all()

    display_order = csv_to_list_of_int(DisplayOrder.query.first().lcd)

    form_add_lcd = flaskforms.LCDAdd()
    form_mod_lcd = flaskforms.LCDMod()

    if request.method == 'POST':
        if not flaskutils.user_has_permission('edit_controllers'):
            return redirect(url_for('general_routes.home'))

        if form_add_lcd.add.data:
            flaskutils.lcd_add(form_add_lcd.quantity.data)
        elif form_mod_lcd.save.data:
            flaskutils.lcd_mod(form_mod_lcd)
        elif form_mod_lcd.delete.data:
            flaskutils.lcd_del(form_mod_lcd.lcd_id.data)
        elif form_mod_lcd.reorder_up.data:
            flaskutils.lcd_reorder(form_mod_lcd.lcd_id.data, display_order,
                                   'up')
        elif form_mod_lcd.reorder_down.data:
            flaskutils.lcd_reorder(form_mod_lcd.lcd_id.data, display_order,
                                   'down')
        elif form_mod_lcd.activate.data:
            flaskutils.lcd_activate(form_mod_lcd.lcd_id.data)
        elif form_mod_lcd.deactivate.data:
            flaskutils.lcd_deactivate(form_mod_lcd.lcd_id.data)
        elif form_mod_lcd.reset_flashing.data:
            flaskutils.lcd_reset_flashing(form_mod_lcd.lcd_id.data)
        return redirect('/lcd')

    return render_template('pages/lcd.html',
                           lcd=lcd,
                           measurements=MEASUREMENTS,
                           pid=pid,
                           relay=relay,
                           sensor=sensor,
                           displayOrder=display_order,
                           form_add_lcd=form_add_lcd,
                           form_mod_lcd=form_mod_lcd)
Example #14
0
def calibration_atlas_ph_measure(sensor_id):
    """
    Acquire a measurement from the Atlas Scientific pH sensor and return it
    Used during calibration to display the current pH to the user
    """
    if not flaskutils.user_has_permission('edit_controllers'):
        return redirect(url_for('page_routes.page_atlas_ph_calibrate'))

    selected_sensor = Sensor.query.filter_by(unique_id=sensor_id).first()

    ph = None
    error = None

    if selected_sensor.interface == 'UART':
        ph_sensor_uart = AtlasScientificUART(
            selected_sensor.device_loc, baudrate=selected_sensor.baud_rate)
        lines = ph_sensor_uart.query('R')
        logger.debug("All Lines: {lines}".format(lines=lines))

        if 'check probe' in lines:
            error = '"check probe" returned from sensor'
        elif not lines:
            error = 'Nothing returned from sensor'
        elif str_is_float(lines[0]):
            ph = lines[0]
            logger.debug('Value[0] is float: {val}'.format(val=ph))
        else:
            error = 'Value[0] is not float or "check probe": {val}'.format(
                val=lines[0])
    elif selected_sensor.interface == 'I2C':
        ph_sensor_i2c = AtlasScientificI2C(
            i2c_address=selected_sensor.i2c_address,
            i2c_bus=selected_sensor.i2c_bus)
        ph_status, ph_str = ph_sensor_i2c.query('R')
        if ph_status == 'error':
            error = "Sensor read unsuccessful: {err}".format(err=ph_str)
        elif ph_status == 'success':
            ph = ph_str

    if error:
        logger.error(error)
        return error, 204
    else:
        return ph
Example #15
0
def page_logview():
    """ Display the last (n) lines from a log file """
    if not flaskutils.user_has_permission('view_logs'):
        return redirect(url_for('general_routes.home'))

    form_log_view = flaskforms.LogView()
    log_output = None
    lines = 30
    logfile = ''
    if request.method == 'POST':
        if form_log_view.lines.data:
            lines = form_log_view.lines.data

        if form_log_view.loglogin.data:
            logfile = LOGIN_LOG_FILE
        elif form_log_view.loghttp.data:
            logfile = HTTP_LOG_FILE
        elif form_log_view.logdaemon.data:
            logfile = DAEMON_LOG_FILE
        elif form_log_view.logkeepup.data:
            logfile = KEEPUP_LOG_FILE
        elif form_log_view.logbackup.data:
            logfile = BACKUP_LOG_FILE
        elif form_log_view.logrestore.data:
            logfile = RESTORE_LOG_FILE
        elif form_log_view.logupgrade.data:
            logfile = UPGRADE_LOG_FILE

        # Get contents from file
        if os.path.isfile(logfile):
            command = 'tail -n {lines} {log}'.format(lines=lines, log=logfile)
            log = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
            (log_output, _) = log.communicate()
            log.wait()
            log_output = unicode(log_output, 'utf-8')
        else:
            log_output = 404

    return render_template('tools/logview.html',
                           form_log_view=form_log_view,
                           lines=lines,
                           logfile=logfile,
                           log_output=log_output)
Example #16
0
def page_timer():
    """ Display Timer settings """
    timer = Timer.query.all()
    relay = Relay.query.all()
    relay_choices = flaskutils.choices_id_name(relay)

    display_order = csv_to_list_of_int(DisplayOrder.query.first().timer)

    form_timer = flaskforms.Timer()

    if request.method == 'POST':
        if not flaskutils.user_has_permission('edit_controllers'):
            return redirect(url_for('general_routes.home'))

        form_name = request.form['form-name']
        if form_name == 'addTimer':
            flaskutils.timer_add(form_timer,
                                 request.form['timer_type'],
                                 display_order)
        elif form_name == 'modTimer':
            if form_timer.timerDel.data:
                flaskutils.timer_del(form_timer)
            elif form_timer.orderTimerUp.data:
                flaskutils.timer_reorder(form_timer.timer_id.data,
                                         display_order, 'up')
            elif form_timer.orderTimerDown.data:
                flaskutils.timer_reorder(form_timer.timer_id.data,
                                         display_order, 'down')
            elif form_timer.activate.data:
                flaskutils.timer_activate(form_timer)
            elif form_timer.deactivate.data:
                flaskutils.timer_deactivate(form_timer)
            elif form_timer.timerMod.data:
                flaskutils.timer_mod(form_timer)
        return redirect('/timer')

    return render_template('pages/timer.html',
                           timer=timer,
                           displayOrder=display_order,
                           relay_choices=relay_choices,
                           form_timer=form_timer)
Example #17
0
def method_delete(method_id):
    """Delete a method"""
    action = '{action} {controller}'.format(action=gettext(u"Delete"),
                                            controller=gettext(u"Method"))

    if not flaskutils.user_has_permission('edit_settings'):
        return redirect(url_for('method_routes.method_list'))

    try:
        MethodData.query.filter(
            MethodData.method_id == int(method_id)).delete()
        Method.query.filter(Method.id == int(method_id)).delete()
        display_order = csv_to_list_of_int(DisplayOrder.query.first().method)
        display_order.remove(int(method_id))
        DisplayOrder.query.first().method = list_to_csv(display_order)
        db.session.commit()
        flash("Success: {action}".format(action=action), "success")
    except Exception as except_msg:
        flash("Error: {action}: {err}".format(action=action, err=except_msg),
              "error")
    return redirect(url_for('method_routes.method_list'))
Example #18
0
def remote_admin(page):
    """Return pages for remote administration"""
    if not flaskutils.user_has_permission('edit_settings'):
        return redirect(url_for('general_routes.home'))

    remote_hosts = Remote.query.all()
    display_order_unsplit = DisplayOrder.query.first().remote_host
    if display_order_unsplit:
        display_order = display_order_unsplit.split(",")
    else:
        display_order = []

    if page == 'setup':
        form_setup = flaskforms.RemoteSetup()
        host_auth = {}
        for each_host in remote_hosts:
            host_auth[each_host.host] = flaskutils.auth_credentials(
                each_host.host, each_host.username, each_host.password_hash)

        if request.method == 'POST':
            form_name = request.form['form-name']
            if form_name == 'setup':
                if form_setup.add.data:
                    flaskutils.remote_host_add(form_setup=form_setup,
                                               display_order=display_order)
            if form_name == 'mod_remote':
                if form_setup.delete.data:
                    flaskutils.remote_host_del(form_setup=form_setup)
            return redirect('/remote/setup')

        return render_template('remote/setup.html',
                               form_setup=form_setup,
                               display_order=display_order,
                               remote_hosts=remote_hosts,
                               host_auth=host_auth)
    else:
        return render_template('404.html'), 404
Example #19
0
def page_camera():
    """
    Page to start/stop video stream or time-lapse, or capture a still image.
    Displays most recent still image and time-lapse image.
    """
    if not flaskutils.user_has_permission('view_camera'):
        return redirect(url_for('general_routes.home'))

    form_camera = flaskforms.Camera()
    camera = Camera.query.all()

    # Check if a video stream is active
    for each_camera in camera:
        if each_camera.stream_started and not CameraStream().is_running():
            each_camera.stream_started = False
            db.session.commit()

    if request.method == 'POST':
        if not flaskutils.user_has_permission('edit_settings'):
            return redirect(url_for('page_routes.page_camera'))

        control = DaemonControl()
        mod_camera = Camera.query.filter(
            Camera.id == form_camera.camera_id.data).first()
        if form_camera.capture_still.data:
            if mod_camera.stream_started:
                flash(
                    gettext(
                        u"Cannot capture still image if stream is active."))
                return redirect('/camera')
            if CameraStream().is_running():
                CameraStream().terminate_controller()  # Stop camera stream
                time.sleep(2)
            camera_record('photo', mod_camera)
        elif form_camera.start_timelapse.data:
            if mod_camera.stream_started:
                flash(gettext(u"Cannot start time-lapse if stream is active."))
                return redirect('/camera')
            now = time.time()
            mod_camera.timelapse_started = True
            mod_camera.timelapse_start_time = now
            mod_camera.timelapse_end_time = now + float(
                form_camera.timelapse_runtime_sec.data)
            mod_camera.timelapse_interval = form_camera.timelapse_interval.data
            mod_camera.timelapse_next_capture = now
            mod_camera.timelapse_capture_number = 0
            db.session.commit()
            control.refresh_daemon_camera_settings()
        elif form_camera.pause_timelapse.data:
            mod_camera.timelapse_paused = True
            db.session.commit()
            control.refresh_daemon_camera_settings()
        elif form_camera.resume_timelapse.data:
            mod_camera.timelapse_paused = False
            db.session.commit()
            control.refresh_daemon_camera_settings()
        elif form_camera.stop_timelapse.data:
            mod_camera.timelapse_started = False
            mod_camera.timelapse_start_time = None
            mod_camera.timelapse_end_time = None
            mod_camera.timelapse_interval = None
            mod_camera.timelapse_next_capture = None
            mod_camera.timelapse_capture_number = None
            db.session.commit()
            control.refresh_daemon_camera_settings()
        elif form_camera.start_stream.data:
            if mod_camera.timelapse_started:
                flash(gettext(u"Cannot start stream if time-lapse is active."))
                return redirect('/camera')
            elif CameraStream().is_running():
                flash(
                    gettext(
                        u"Cannot start stream. The stream is already running.")
                )
                return redirect('/camera')
            elif (not (mod_camera.camera_type == 'Raspberry Pi'
                       and mod_camera.library == 'picamera')):
                flash(
                    gettext(u"Streaming is only supported with the Raspberry"
                            u" Pi camera using the picamera library."))
                return redirect('/camera')
            elif Camera.query.filter_by(stream_started=True).count():
                flash(
                    gettext(u"Cannot start stream if another stream is "
                            u"already in progress."))
                return redirect('/camera')
            else:
                mod_camera.stream_started = True
                db.session.commit()
        elif form_camera.stop_stream.data:
            if CameraStream().is_running():
                CameraStream().terminate_controller()
            mod_camera.stream_started = False
            db.session.commit()
        return redirect('/camera')

    # Get the full path and timestamps of latest still and time-lapse images
    latest_img_still_ts = {}
    latest_img_still = {}
    latest_img_tl_ts = {}
    latest_img_tl = {}
    for each_camera in camera:
        camera_path = os.path.join(
            PATH_CAMERAS, '{id}-{uid}'.format(id=each_camera.id,
                                              uid=each_camera.unique_id))
        try:
            latest_still_img_full_path = max(glob.iglob(
                '{path}/still/Still-{cam_id}-*.jpg'.format(
                    path=camera_path, cam_id=each_camera.id)),
                                             key=os.path.getmtime)
        except ValueError:
            latest_still_img_full_path = None
        if latest_still_img_full_path:
            ts = os.path.getmtime(latest_still_img_full_path)
            latest_img_still_ts[
                each_camera.id] = datetime.datetime.fromtimestamp(ts).strftime(
                    "%Y-%m-%d %H:%M:%S")
            latest_img_still[each_camera.id] = os.path.basename(
                latest_still_img_full_path)
        else:
            latest_img_still[each_camera.id] = None

        try:
            latest_time_lapse_img_full_path = max(glob.iglob(
                '{path}/timelapse/Timelapse-{cam_id}-*.jpg'.format(
                    path=camera_path, cam_id=each_camera.id)),
                                                  key=os.path.getmtime)
        except ValueError:
            latest_time_lapse_img_full_path = None
        if latest_time_lapse_img_full_path:
            ts = os.path.getmtime(latest_time_lapse_img_full_path)
            latest_img_tl_ts[each_camera.id] = datetime.datetime.fromtimestamp(
                ts).strftime("%Y-%m-%d %H:%M:%S")
            latest_img_tl[each_camera.id] = os.path.basename(
                latest_time_lapse_img_full_path)
        else:
            latest_img_tl[each_camera.id] = None

    time_now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')

    return render_template('pages/camera.html',
                           camera=camera,
                           form_camera=form_camera,
                           latest_img_still=latest_img_still,
                           latest_img_still_ts=latest_img_still_ts,
                           latest_img_tl=latest_img_tl,
                           latest_img_tl_ts=latest_img_tl_ts,
                           time_now=time_now)
Example #20
0
def page_input():
    """ Display sensor settings """
    # TCA9548A I2C multiplexer
    multiplexer_addresses = [
        '0x70', '0x71', '0x72', '0x73', '0x74', '0x75', '0x76', '0x77'
    ]
    multiplexer_channels = list(range(0, 9))

    camera = Camera.query.all()
    lcd = LCD.query.all()
    pid = PID.query.all()
    relay = Relay.query.all()
    sensor = Sensor.query.all()
    user = User.query.all()

    conditional = Conditional.query.filter(
        Conditional.conditional_type == 'sensor').all()
    conditional_actions = ConditionalActions.query.all()

    display_order = csv_to_list_of_int(DisplayOrder.query.first().sensor)

    form_add_sensor = flaskforms.SensorAdd()
    form_mod_sensor = flaskforms.SensorMod()

    form_conditional = flaskforms.Conditional()
    form_conditional_actions = flaskforms.ConditionalActions()

    # If DS18B20 sensors added, compile a list of detected sensors
    ds18b20_sensors = []
    if Sensor.query.filter(Sensor.device == 'DS18B20').count():
        try:
            for each_sensor in W1ThermSensor.get_available_sensors():
                ds18b20_sensors.append(each_sensor.id)
        except OSError:
            flash("Unable to detect sensors in '/sys/bus/w1/devices'", "error")

    # Create list of file names from the input_options directory
    # Used in generating the correct options for each sensor/device
    sensor_templates = []
    sensor_path = os.path.join(
        INSTALL_DIRECTORY, 'mycodo/mycodo_flask/templates/pages/input_options')
    for (_, _, file_names) in os.walk(sensor_path):
        sensor_templates.extend(file_names)
        break

    if request.method == 'POST':
        if not flaskutils.user_has_permission('edit_controllers'):
            return redirect(url_for('page_routes.page_input'))

        if form_add_sensor.sensorAddSubmit.data:
            flaskutils.sensor_add(form_add_sensor)
        elif form_mod_sensor.modSensorSubmit.data:
            flaskutils.sensor_mod(form_mod_sensor)
        elif form_mod_sensor.delSensorSubmit.data:
            flaskutils.sensor_del(form_mod_sensor)
        elif form_mod_sensor.orderSensorUp.data:
            flaskutils.sensor_reorder(form_mod_sensor.modSensor_id.data,
                                      display_order, 'up')
        elif form_mod_sensor.orderSensorDown.data:
            flaskutils.sensor_reorder(form_mod_sensor.modSensor_id.data,
                                      display_order, 'down')
        elif form_mod_sensor.activateSensorSubmit.data:
            flaskutils.sensor_activate(form_mod_sensor)
        elif form_mod_sensor.deactivateSensorSubmit.data:
            flaskutils.sensor_deactivate(form_mod_sensor)

        elif form_conditional.deactivate_cond.data:
            flaskutils.conditional_deactivate(form_conditional)
        elif form_conditional.activate_cond.data:
            flaskutils.conditional_activate(form_conditional)
        elif form_mod_sensor.sensorCondAddSubmit.data:
            flaskutils.conditional_add(
                'sensor', 1, sensor_id=form_mod_sensor.modSensor_id.data)
        elif form_conditional.delete_cond.data:
            flaskutils.conditional_mod(form_conditional, 'delete')
        elif form_conditional.save_cond.data:
            flaskutils.conditional_mod(form_conditional, 'modify')
        elif form_conditional_actions.add_action.data:
            flaskutils.conditional_action_add(form_conditional_actions)
        elif form_conditional_actions.save_action.data:
            flaskutils.conditional_action_mod(form_conditional_actions,
                                              'modify')
        elif form_conditional_actions.delete_action.data:
            flaskutils.conditional_action_mod(form_conditional_actions,
                                              'delete')
        return redirect(url_for('page_routes.page_input'))

    return render_template('pages/input.html',
                           camera=camera,
                           conditional=conditional,
                           conditional_actions=conditional_actions,
                           conditional_actions_list=CONDITIONAL_ACTIONS,
                           displayOrder=display_order,
                           ds18b20_sensors=ds18b20_sensors,
                           form_add_sensor=form_add_sensor,
                           form_conditional=form_conditional,
                           form_conditional_actions=form_conditional_actions,
                           form_mod_sensor=form_mod_sensor,
                           lcd=lcd,
                           measurements=MEASUREMENTS,
                           multiplexer_addresses=multiplexer_addresses,
                           multiplexer_channels=multiplexer_channels,
                           pid=pid,
                           relay=relay,
                           sensor=sensor,
                           sensor_templates=sensor_templates,
                           units=MEASUREMENT_UNITS,
                           user=user)
Example #21
0
def page_output():
    """ Display relay status and config """
    camera = Camera.query.all()
    lcd = LCD.query.all()
    relay = Relay.query.all()
    user = User.query.all()

    conditional = Conditional.query.filter(
        Conditional.conditional_type == 'relay').all()
    conditional_actions = ConditionalActions.query.all()

    display_order = csv_to_list_of_int(DisplayOrder.query.first().relay)

    form_add_relay = flaskforms.RelayAdd()
    form_mod_relay = flaskforms.RelayMod()

    form_conditional = flaskforms.Conditional()
    form_conditional_actions = flaskforms.ConditionalActions()

    # Create list of file names from the output_options directory
    # Used in generating the correct options for each relay/device
    relay_templates = []
    relay_path = os.path.join(
        INSTALL_DIRECTORY,
        'mycodo/mycodo_flask/templates/pages/output_options')
    for (_, _, file_names) in os.walk(relay_path):
        relay_templates.extend(file_names)
        break

    if request.method == 'POST':
        if not flaskutils.user_has_permission('edit_controllers'):
            return redirect(url_for('page_routes.page_output'))

        if form_add_relay.relay_add.data:
            flaskutils.relay_add(form_add_relay)
        elif form_mod_relay.save.data:
            flaskutils.relay_mod(form_mod_relay)
        elif (form_mod_relay.turn_on.data or form_mod_relay.turn_off.data
              or form_mod_relay.on_submit.data):
            flaskutils.relay_on_off(form_mod_relay)
        elif form_mod_relay.delete.data:
            flaskutils.relay_del(form_mod_relay)
        elif form_mod_relay.order_up.data:
            flaskutils.relay_reorder(form_mod_relay.relay_id.data,
                                     display_order, 'up')
        elif form_mod_relay.order_down.data:
            flaskutils.relay_reorder(form_mod_relay.relay_id.data,
                                     display_order, 'down')
        elif form_conditional.add_cond.data:
            flaskutils.conditional_add(form_conditional.conditional_type.data,
                                       form_conditional.quantity.data)
        elif form_conditional.delete_cond.data:
            flaskutils.conditional_mod(form_conditional, 'delete')
        elif form_conditional.save_cond.data:
            flaskutils.conditional_mod(form_conditional, 'modify')
        elif form_conditional.activate_cond.data:
            flaskutils.conditional_activate(form_conditional)
        elif form_conditional.deactivate_cond.data:
            flaskutils.conditional_deactivate(form_conditional)
        elif form_conditional_actions.add_action.data:
            flaskutils.conditional_action_add(form_conditional_actions)
        elif form_conditional_actions.save_action.data:
            flaskutils.conditional_action_mod(form_conditional_actions,
                                              'modify')
        elif form_conditional_actions.delete_action.data:
            flaskutils.conditional_action_mod(form_conditional_actions,
                                              'delete')
        return redirect(url_for('page_routes.page_output'))

    return render_template('pages/output.html',
                           camera=camera,
                           conditional=conditional,
                           conditional_actions=conditional_actions,
                           conditional_actions_list=CONDITIONAL_ACTIONS,
                           displayOrder=display_order,
                           form_conditional=form_conditional,
                           form_conditional_actions=form_conditional_actions,
                           form_add_relay=form_add_relay,
                           form_mod_relay=form_mod_relay,
                           lcd=lcd,
                           relay=relay,
                           relay_templates=relay_templates,
                           user=user)
Example #22
0
def page_pid():
    """ Display PID settings """
    pids = PID.query.all()
    relay = Relay.query.all()
    sensor = Sensor.query.all()

    display_order = csv_to_list_of_int(DisplayOrder.query.first().pid)

    form_add_pid = flaskforms.PIDAdd()
    form_mod_pid_base = flaskforms.PIDModBase()
    form_mod_pid_relay = flaskforms.PIDModRelay()
    form_mod_pid_pwm = flaskforms.PIDModPWM()

    method = Method.query.all()

    # Create list of file names from the pid_options directory
    # Used in generating the correct options for each PID
    pid_templates = []
    pid_path = os.path.join(INSTALL_DIRECTORY,
                            'mycodo/mycodo_flask/templates/pages/pid_options')
    for (_, _, file_names) in os.walk(pid_path):
        pid_templates.extend(file_names)
        break

    if request.method == 'POST':
        if not flaskutils.user_has_permission('edit_controllers'):
            return redirect(url_for('general_routes.home'))

        form_name = request.form['form-name']
        if form_name == 'addPID':
            flaskutils.pid_add(form_add_pid)
        elif form_name == 'modPID':
            if form_mod_pid_base.save.data:
                flaskutils.pid_mod(form_mod_pid_base, form_mod_pid_pwm,
                                   form_mod_pid_relay)
            elif form_mod_pid_base.delete.data:
                flaskutils.pid_del(form_mod_pid_base.pid_id.data)
            elif form_mod_pid_base.reorder_up.data:
                flaskutils.pid_reorder(form_mod_pid_base.pid_id.data,
                                       display_order, 'up')
            elif form_mod_pid_base.reorder_down.data:
                flaskutils.pid_reorder(form_mod_pid_base.pid_id.data,
                                       display_order, 'down')
            elif form_mod_pid_base.activate.data:
                flaskutils.pid_activate(form_mod_pid_base.pid_id.data)
            elif form_mod_pid_base.deactivate.data:
                flaskutils.pid_deactivate(form_mod_pid_base.pid_id.data)
            elif form_mod_pid_base.hold.data:
                flaskutils.pid_manipulate(form_mod_pid_base.pid_id.data,
                                          'Hold')
            elif form_mod_pid_base.pause.data:
                flaskutils.pid_manipulate(form_mod_pid_base.pid_id.data,
                                          'Pause')
            elif form_mod_pid_base.resume.data:
                flaskutils.pid_manipulate(form_mod_pid_base.pid_id.data,
                                          'Resume')

        return redirect('/pid')

    return render_template('pages/pid.html',
                           method=method,
                           pids=pids,
                           pid_templates=pid_templates,
                           relay=relay,
                           sensor=sensor,
                           displayOrder=display_order,
                           form_add_pid=form_add_pid,
                           form_mod_pid_base=form_mod_pid_base,
                           form_mod_pid_pwm=form_mod_pid_pwm,
                           form_mod_pid_relay=form_mod_pid_relay)
Example #23
0
def calibration_atlas_ph():
    """
    Step-by-step tool for calibrating the Atlas Scientific pH sensor
    """
    if not flaskutils.user_has_permission('edit_controllers'):
        return redirect(url_for('general_routes.home'))

    form_ph_calibrate = flaskforms.CalibrationAtlasph()
    sensor = Sensor.query.filter_by(device='ATLAS_PH_UART').all()
    stage = 0
    next_stage = None
    selected_sensor = None
    sensor_device_name = None
    complete_with_error = None

    if form_ph_calibrate.hidden_next_stage.data is not None:
        next_stage = int(form_ph_calibrate.hidden_next_stage.data)

    # Clear Calibration memory
    if form_ph_calibrate.clear_calibration.data:
        selected_sensor = Sensor.query.filter_by(
            unique_id=form_ph_calibrate.selected_sensor_id.data).first()
        atlas_command = AtlasScientificCommand(selected_sensor)
        status, message = atlas_command.calibrate('clear_calibration')
        if status:
            flash(message, "error")
        else:
            flash(message, "success")
    # Begin calibration from Selected sensor
    elif form_ph_calibrate.go_from_first_stage.data:
        stage = 1
        selected_sensor = Sensor.query.filter_by(
            unique_id=form_ph_calibrate.selected_sensor_id.data).first()
        if not selected_sensor:
            flash(
                'Sensor not found: {}'.format(
                    form_ph_calibrate.selected_sensor_id.data), 'error')
        else:
            for each_sensor in SENSORS:
                if selected_sensor.device == each_sensor[0]:
                    sensor_device_name = each_sensor[1]
    # Continue calibration from selected sensor
    elif (form_ph_calibrate.go_to_next_stage.data
          or form_ph_calibrate.go_to_last_stage.data or next_stage > 1):
        selected_sensor = Sensor.query.filter_by(
            unique_id=form_ph_calibrate.hidden_sensor_id.data).first()
        for each_sensor in SENSORS:
            if selected_sensor.device == each_sensor[0]:
                sensor_device_name = each_sensor[1]

    if next_stage == 2:
        if form_ph_calibrate.temperature.data is None:
            flash(
                gettext(
                    u"A valid temperature is required: %(temp)s is invalid.",
                    temp=form_ph_calibrate.temperature.data), "error")
            stage = 1
        else:
            temp = '{temp:.2f}'.format(temp=form_ph_calibrate.temperature.data)
            stage, complete_with_error = dual_commands_to_sensor(
                selected_sensor, 'temperature', temp, 'continuous', 1)
    elif next_stage == 3:
        stage, complete_with_error = dual_commands_to_sensor(
            selected_sensor, 'mid', '7.0', 'continuous', 2)
    elif next_stage == 4:
        stage, complete_with_error = dual_commands_to_sensor(
            selected_sensor, 'low', '4.0', 'continuous', 3)
    elif next_stage == 5:
        stage, complete_with_error = dual_commands_to_sensor(
            selected_sensor, 'high', '10.0', 'end', 4)

    return render_template('tools/calibration_atlas_ph.html',
                           complete_with_error=complete_with_error,
                           form_ph_calibrate=form_ph_calibrate,
                           sensor=sensor,
                           sensor_device_name=sensor_device_name,
                           selected_sensor=selected_sensor,
                           stage=stage)
Example #24
0
def page_relay():
    """ Display relay status and config """
    camera = Camera.query.all()
    lcd = LCD.query.all()
    relay = Relay.query.all()
    user = User.query.all()

    conditional = Conditional.query.filter(
        Conditional.conditional_type == 'relay').all()
    conditional_actions = ConditionalActions.query.all()

    display_order = csv_to_list_of_int(DisplayOrder.query.first().relay)

    form_add_relay = flaskforms.RelayAdd()
    form_mod_relay = flaskforms.RelayMod()

    form_conditional = flaskforms.Conditional()
    form_conditional_actions = flaskforms.ConditionalActions()

    if request.method == 'POST':
        if not flaskutils.user_has_permission('edit_controllers'):
            return redirect(url_for('general_routes.page_relay'))

        if form_add_relay.relay_add.data:
            flaskutils.relay_add(form_add_relay)
        elif form_mod_relay.save.data:
            flaskutils.relay_mod(form_mod_relay)
        elif (form_mod_relay.turn_on.data or
                form_mod_relay.turn_off.data or
                form_mod_relay.sec_on_submit.data):
            flaskutils.relay_on_off(form_mod_relay)
        elif form_mod_relay.delete.data:
            flaskutils.relay_del(form_mod_relay)
        elif form_mod_relay.order_up.data:
            flaskutils.relay_reorder(form_mod_relay.relay_id.data,
                                     display_order, 'up')
        elif form_mod_relay.order_down.data:
            flaskutils.relay_reorder(form_mod_relay.relay_id.data,
                                     display_order, 'down')
        elif form_conditional.add_cond.data:
            flaskutils.conditional_add(form_conditional.conditional_type.data,
                                       form_conditional.quantity.data)
        elif form_conditional.delete_cond.data:
            flaskutils.conditional_mod(form_conditional, 'delete')
        elif form_conditional.save_cond.data:
            flaskutils.conditional_mod(form_conditional, 'modify')
        elif form_conditional.activate_cond.data:
            flaskutils.conditional_activate(form_conditional)
        elif form_conditional.deactivate_cond.data:
            flaskutils.conditional_deactivate(form_conditional)
        elif form_conditional_actions.add_action.data:
            flaskutils.conditional_action_add(form_conditional_actions)
        elif form_conditional_actions.save_action.data:
            flaskutils.conditional_action_mod(form_conditional_actions,
                                              'modify')
        elif form_conditional_actions.delete_action.data:
            flaskutils.conditional_action_mod(form_conditional_actions,
                                              'delete')
        return redirect('/relay')

    return render_template('pages/relay.html',
                           camera=camera,
                           conditional=conditional,
                           conditional_actions=conditional_actions,
                           conditional_actions_list=CONDITIONAL_ACTIONS,
                           displayOrder=display_order,
                           form_conditional=form_conditional,
                           form_conditional_actions=form_conditional_actions,
                           form_add_relay=form_add_relay,
                           form_mod_relay=form_mod_relay,
                           lcd=lcd,
                           relay=relay,
                           user=user)
Example #25
0
def admin_upgrade():
    """ Display any available upgrades and option to upgrade """
    if not flaskutils.user_has_permission('edit_settings'):
        return redirect(url_for('general_routes.home'))

    if not internet():
        flash(
            gettext(u"Upgrade functionality is disabled because an internet "
                    u"connection was unable to be detected"), "error")
        return render_template('admin/upgrade.html', is_internet=False)

    # Read from the upgrade status file created by the upgrade script
    # to indicate if the upgrade is running.
    try:
        with open(INSTALL_DIRECTORY + '/.upgrade') as f:
            upgrade = int(f.read(1))
    except IOError:
        try:
            with open(INSTALL_DIRECTORY + '/.upgrade', 'w') as f:
                f.write('0')
        finally:
            upgrade = 0

    if upgrade:
        if upgrade == 1:
            flash(
                gettext(u"An upgrade is currently in progress. Please wait "
                        u"for it to finish"), "error")
        elif upgrade == 2:
            flash(
                gettext(u"There was an error encountered during the upgrade "
                        u"process. Check the upgrade log for details."),
                "error")
        return render_template('admin/upgrade.html', upgrade=upgrade)

    form_backup = flaskforms.Backup()
    form_upgrade = flaskforms.Upgrade()

    is_internet = True
    upgrade_available = False

    # Check for any new Mycodo releases on github
    releases = []
    try:
        maj_version = int(MYCODO_VERSION.split('.')[0])
        releases = github_releases(maj_version)
    except Exception:
        flash(
            gettext(u"Could not determine local mycodo version or "
                    u"online release versions"), "error")
    if len(releases):
        latest_release = releases[0]
        current_releases = []
        releases_behind = None
        for index, each_release in enumerate(releases):
            if parse_version(each_release) >= parse_version(MYCODO_VERSION):
                current_releases.append(each_release)
            if parse_version(each_release) == parse_version(MYCODO_VERSION):
                releases_behind = index
        if parse_version(releases[0]) > parse_version(MYCODO_VERSION):
            upgrade_available = True
    else:
        current_releases = []
        latest_release = '0.0.0'
        releases_behind = 0

    if request.method == 'POST':
        if form_upgrade.upgrade.data and upgrade_available:
            subprocess.Popen('{path}/mycodo/scripts/mycodo_wrapper upgrade >>'
                             ' /var/log/mycodo/mycodoupgrade.log 2>&1'.format(
                                 path=INSTALL_DIRECTORY),
                             shell=True)
            upgrade = 1
            flash(
                gettext(u"The upgrade has started. The daemon will be "
                        u"stopped during the upgrade."), "success")
        else:
            flash(
                gettext(u"You cannot upgrade if an upgrade is not available"),
                "error")

    return render_template('admin/upgrade.html',
                           form_backup=form_backup,
                           form_upgrade=form_upgrade,
                           current_release=MYCODO_VERSION,
                           current_releases=current_releases,
                           latest_release=latest_release,
                           releases_behind=releases_behind,
                           upgrade_available=upgrade_available,
                           upgrade=upgrade,
                           is_internet=is_internet)
Example #26
0
def page_info():
    """ Display page with system information from command line tools """
    if not flaskutils.user_has_permission('view_stats'):
        return redirect(url_for('general_routes.home'))

    uptime = subprocess.Popen("uptime", stdout=subprocess.PIPE, shell=True)
    (uptime_output, _) = uptime.communicate()
    uptime.wait()

    uname = subprocess.Popen("uname -a", stdout=subprocess.PIPE, shell=True)
    (uname_output, _) = uname.communicate()
    uname.wait()

    gpio = subprocess.Popen("gpio readall", stdout=subprocess.PIPE, shell=True)
    (gpio_output, _) = gpio.communicate()
    gpio.wait()

    df = subprocess.Popen("df -h", stdout=subprocess.PIPE, shell=True)
    (df_output, _) = df.communicate()
    df.wait()

    free = subprocess.Popen("free -h", stdout=subprocess.PIPE, shell=True)
    (free_output, _) = free.communicate()
    free.wait()

    ifconfig = subprocess.Popen("ifconfig -a",
                                stdout=subprocess.PIPE,
                                shell=True)
    (ifconfig_output, _) = ifconfig.communicate()
    ifconfig.wait()

    daemon_pid = None
    if os.path.exists(DAEMON_PID_FILE):
        with open(DAEMON_PID_FILE, 'r') as pid_file:
            daemon_pid = int(pid_file.read())

    database_version = []
    for each_ver in AlembicVersion.query.all():
        database_version.append(each_ver.version_num)

    virtualenv_flask = False
    if hasattr(sys, 'real_prefix'):
        virtualenv_flask = True

    virtualenv_daemon = False
    pstree_output = None
    top_output = None
    daemon_up = daemon_active()
    if daemon_up:
        control = DaemonControl()
        ram_use_daemon = control.ram_use()
        virtualenv_daemon = control.is_in_virtualenv()

        pstree = subprocess.Popen("pstree -p {pid}".format(pid=daemon_pid),
                                  stdout=subprocess.PIPE,
                                  shell=True)
        (pstree_output, _) = pstree.communicate()
        pstree.wait()

        top = subprocess.Popen("top -bH -n 1 -p {pid}".format(pid=daemon_pid),
                               stdout=subprocess.PIPE,
                               shell=True)
        (top_output, _) = top.communicate()
        top.wait()
    else:
        ram_use_daemon = 0

    ram_use_flask = resource.getrusage(
        resource.RUSAGE_SELF).ru_maxrss / float(1000)

    return render_template('pages/info.html',
                           daemon_pid=daemon_pid,
                           daemon_up=daemon_up,
                           gpio_readall=gpio_output,
                           database_version=database_version,
                           df=df_output,
                           free=free_output,
                           ifconfig=ifconfig_output,
                           pstree=pstree_output,
                           ram_use_daemon=ram_use_daemon,
                           ram_use_flask=ram_use_flask,
                           top=top_output,
                           uname=uname_output,
                           uptime=uptime_output,
                           virtualenv_daemon=virtualenv_daemon,
                           virtualenv_flask=virtualenv_flask)
Example #27
0
def page_graph():
    """
    Generate custom graphs to display sensor data retrieved from influxdb.
    """
    # Create form objects
    form_mod_graph = flaskforms.GraphMod()
    form_del_graph = flaskforms.GraphDel()
    form_order_graph = flaskforms.GraphOrder()
    form_add_graph = flaskforms.GraphAdd()

    # Retrieve the order to display graphs
    display_order = csv_to_list_of_int(DisplayOrder.query.first().graph)

    # Retrieve tables from SQL database
    graph = Graph.query.all()
    pid = PID.query.all()
    relay = Relay.query.all()
    sensor = Sensor.query.all()

    # Retrieve all choices to populate form drop-down menu
    pid_choices = flaskutils.choices_pids(pid)
    output_choices = flaskutils.choices_outputs(relay)
    sensor_choices = flaskutils.choices_sensors(sensor)

    # Add multi-select values as form choices, for validation
    form_mod_graph.pid_ids.choices = []
    form_mod_graph.relay_ids.choices = []
    form_mod_graph.sensor_ids.choices = []
    for key, value in pid_choices.items():
        form_mod_graph.pid_ids.choices.append((key, value))
    for key, value in output_choices.items():
        form_mod_graph.relay_ids.choices.append((key, value))
    for key, value in sensor_choices.items():
        form_mod_graph.sensor_ids.choices.append((key, value))

    # Generate dictionary of custom colors for each graph
    dict_colors = dict_custom_colors()

    # Detect which form on the page was submitted
    if request.method == 'POST':
        if not flaskutils.user_has_permission('edit_controllers'):
            return redirect(url_for('general_routes.home'))

        form_name = request.form['form-name']
        if form_name == 'modGraph':
            flaskutils.graph_mod(form_mod_graph, request.form)
        elif form_name == 'delGraph':
            flaskutils.graph_del(form_del_graph)
        elif form_order_graph.orderGraphUp.data:
            flaskutils.graph_reorder(form_order_graph.orderGraph_id.data,
                                     display_order, 'up')
        elif form_order_graph.orderGraphDown.data:
            flaskutils.graph_reorder(form_order_graph.orderGraph_id.data,
                                     display_order, 'down')
        elif form_name == 'addGraph':
            flaskutils.graph_add(form_add_graph, display_order)
        return redirect('/graph')

    return render_template('pages/graph.html',
                           graph=graph,
                           pid=pid,
                           relay=relay,
                           sensor=sensor,
                           pid_choices=pid_choices,
                           output_choices=output_choices,
                           sensor_choices=sensor_choices,
                           dict_colors=dict_colors,
                           measurement_units=MEASUREMENT_UNITS,
                           displayOrder=display_order,
                           form_mod_graph=form_mod_graph,
                           form_del_graph=form_del_graph,
                           form_order_graph=form_order_graph,
                           form_add_graph=form_add_graph)
Example #28
0
def method_builder(method_id):
    """
    Page to edit the details of each method
    This includes the (time, setpoint) data sets
    """
    if not flaskutils.user_has_permission('edit_controllers'):
        return redirect(url_for('method_routes.method_list'))

    relay = Relay.query.all()

    form_create_method = flaskforms.MethodCreate()
    form_add_method = flaskforms.MethodAdd()
    form_mod_method = flaskforms.MethodMod()

    # Used in software tests to verify function is executing as admin
    if method_id == '-1':
        return 'admin logged in'
    # Create new method
    elif method_id == '0':
        form_fail = flaskutils.method_create(form_create_method)
        new_method = Method.query.order_by(Method.id.desc()).first()
        if not form_fail:
            return redirect(
                '/method-build/{method_id}'.format(method_id=new_method.id))
        else:
            return redirect('/method')
    elif int(method_id) < 0:
        flash("Invalid method ID", "error")
        return redirect('/method')

    # First method column with general information about method
    method = Method.query.filter(Method.id == int(method_id)).first()

    if method.method_type in [
            'Date', 'Duration', 'Daily', 'DailySine', 'DailyBezier'
    ]:

        # Retrieve the order to display method data lines
        display_order = csv_to_list_of_int(method.method_order)

        method_data = MethodData.query.filter(
            MethodData.method_id == method.id)
        setpoint_method_data = MethodData.query.filter(
            MethodData.setpoint_start != None)
        sine_method_data = MethodData.query.filter(
            MethodData.amplitude != None)
        bezier_method_data = MethodData.query.filter(MethodData.x0 != None)
        if display_order is not None:
            last_setpoint_method = setpoint_method_data.filter(
                MethodData.id == display_order[-1]).first()
            last_sine_method = sine_method_data.filter(
                MethodData.id == display_order[-1]).first()
            last_bezier_method = bezier_method_data.filter(
                MethodData.id == display_order[-1]).first()
        else:
            last_setpoint_method = None
            last_sine_method = None
            last_bezier_method = None

        last_end_time = ''
        last_setpoint = ''
        if method.method_type in ['Daily', 'Date', 'Duration']:
            method_data = method_data.all()

            # Get last entry end time and setpoint to populate the form
            if last_setpoint_method is None:
                last_end_time = ''
                last_setpoint = ''
            else:
                last_end_time = last_setpoint_method.time_end
                if last_setpoint_method.setpoint_end is not None:
                    last_setpoint = last_setpoint_method.setpoint_end
                else:
                    last_setpoint = last_setpoint_method.setpoint_start

        if request.method == 'POST':
            form_name = request.form['form-name']
            if form_name == 'addMethod':
                form_fail = flaskutils.method_add(form_add_method)
            elif form_name in ['modMethod', 'renameMethod']:
                form_fail = flaskutils.method_mod(form_mod_method)
            if (form_name in ['addMethod', 'modMethod', 'renameMethod']
                    and not form_fail):
                return redirect(
                    '/method-build/{method_id}'.format(method_id=method.id))

        if not method_data:
            method_data = []

        return render_template('pages/method-build.html',
                               method=method,
                               relay=relay,
                               method_data=method_data,
                               method_id=method_id,
                               last_end_time=last_end_time,
                               last_bezier_method=last_bezier_method,
                               last_sine_method=last_sine_method,
                               last_setpoint_method=last_setpoint_method,
                               last_setpoint=last_setpoint,
                               form_create_method=form_create_method,
                               form_add_method=form_add_method,
                               form_mod_method=form_mod_method)

    return redirect('/method')