Main operations of web app

Entry point

This script runs the flask_controller application using a development server.

webapp.app.inject_constants()[source]

Allows Jinja to reference global python constants in HTML.

webapp.app.build_flask_app(use_local_db)[source]

Build and initialize the flask app.

All web routes

A collection of Flask routes

webapp.routes.register()[source]

Renders the register page

webapp.routes.login()[source]

If it’s a POST request, it will attempt to log the user in. Otherwise, it renders the login page.

webapp.routes.logout()[source]

Redirects to login page after logging out

webapp.routes.home()[source]

Renders the home page

webapp.routes.remote()[source]

Renders the remote page

webapp.routes.sensors()[source]

Renders the sensor dashboard page

webapp.routes.automode()[source]

Renders the autonomous page

webapp.routes.terminal()[source]

Renders the virtual terminal page

webapp.routes.settings_page()[source]

Renders the settings page

webapp.routes.about()[source]

Renders the about page

webapp.routes.shutdown_server()[source]

Shutdowns the webapp.

webapp.routes.restart()[source]

Restarts the robot (Only applicable if webserver runs off rasp pi)

webapp.routes.shutdown_robot()[source]

Shutsdown the robot (Only applicable if webserver runs off rasp pi)

webapp.routes.delete_user()[source]

Deletes the current user’s account.

webapp.routes.reset_password()[source]

Resets the current user’s password.

All socket channels

A collection of websocket routes

webapp.sockets.getHYPR()[source]

This function will try to determine the robot’s Heading, Yaw, Pitch, & Roll (HYPR) dependent on the specific data returned from the IMU device connected to the robot.

webapp.sockets.get_imu_data()[source]

Returns a 2d array containing the following

  • senses[0] = accel[x, y, z] for accelerometer data

  • senses[1] = gyro[x, y, z] for gyroscope data

  • senses[2] = mag[x, y, z] for magnetometer data

Note

Not all data may be aggregated depending on the IMU device connected to the robot.

webapp.sockets.handle_connect()[source]

This event fired when a websocket client establishes a connection to the server

webapp.sockets.handle_disconnect()[source]

This event fired when a websocket client breaks connection to the server

webapp.sockets.handle_webcam_init()[source]

Initialize the camera when the user goes to the remote control page.

webapp.sockets.handle_webcam_request()[source]

This event is to stream the webcam over websockets.

webapp.sockets.handle_webcam_cleanup()[source]

Cleanup the camera when the user leaves the remote control page.

webapp.sockets.build_wapypoints(waypoints, clear)[source]

Builds a list of waypoints based on the order they were created on the ‘automode.html’ page

Parameters
  • waypoints (list) – A list of GPS latitude & longitude pairs for the robot to travel to in sequence.

  • clear (bool) – A flag that will clear the existing list of GPS waypoints before appending to it.

webapp.sockets.handle_gps_request()[source]

This event fired when a websocket client’s response to the server about GPS coordinates.

webapp.sockets.handle_DoF_request()[source]

This event fired when a websocket client a response to the server about IMU device’s data.

webapp.sockets.handle_remoteOut(args)[source]

This event gets fired when the client sends data to the server about remote controls (via remote control page) specific to the robot’s drivetrain.

Parameters

args (list) – The list of motor inputs received from the remote control page.

webapp.sockets.on_terminal_input(data)[source]

Write to the child pty. The pty sees this as if you are typing in a real terminal.

webapp.sockets.on_terminal_resize(data)[source]

This event is fired when a websocket clients’ window gets resized.

webapp.sockets.on_terminal_connect()[source]

This event is fired when a new client has connected to the server’s terminal.

Supporting modules

Camera Manager

This module provides an abstraction for managing cameras.

class webapp.inputs.camera_manager.CameraManager[source]

This class is for abstracting the camera feed capabilities.

property initialized

Returns true if the camera is ready to be used

open_camera()[source]

Opens and initializes the camera

capture_image()[source]

Fetches an image from the camera feed and incodes it as a JPEG buffer

close_camera()[source]

Cleans up and closes the camera. Note that you cannot use the camera unless you re-initialize it with open_camera()

Virtual Terminal

This modules provides functionality for a pseudo SSH-like shell connection from the web app via websockets and Unix sockets. Windows not supported.

class webapp.utils.virtual_terminal.VTerminal(socketio_inst)[source]

This class is for abstracting the virtual terminal capabilities. Note that this does not work for windows.

property initialized

Check if the virtual terminal is initialized and ready to start doing I/O.

property running

Check if the virtual terminal is doing I/O as of now.

init_connect(term_cmd, init_rows=50, init_cols=50)[source]

Initiate the virtual terminal connection by creating a subprocess.

cleanup()[source]

Stop the background task and clean up after ourselves.

register_output_listener(listener)[source]

Add a virtual terminal output listener for processing output text.

remove_all_listeners()[source]

Remove all virtual terminal output listeners.

write_input(str_input)[source]

Write some text input into the virtual terminal.

resize_terminal(rows, cols)[source]

Resize the virtual terminal via the new numbers of rows and columns.

Fernet Vault

This module allows easy encryption/decryption of files via Fernet cryptography

class webapp.utils.file_encryption.FernetVault(key_file_path)[source]

A file vault that decrypts the contents of an encrypted file given a key file.

read_file(input_file)[source]

Read an encrypted file.

write_file(data, output_file)[source]

Write an encrypted file.

Super Logger

This module provides a easy-to-use class for logging any messages in a systematic manner, using the built-in ‘logging’ module and colorama for colored logging. May support connecting to online logging services such as sentry.io

This is how the different log level colors appear on the terminal/command prompt.

_images/logger_colors.png

Example:

logger = SuperLogger.instance()
logger.debug('CAMERA', 'Camera initialized')
logger.critical('CORE', 'The robot is feeling emotions!')
class webapp.utils.super_logger.SuperLogger(use_color=False)[source]

This class is for managing logging of messages that are scattered throughout the web app. It’s handled via a Logger instance, and it’s default log level is ‘INFO’.

Parameters

use_color (bool) – True enables the use specific colors for outputting text to the terminal. False makes the text colors behave as they would normally.

property use_color

If set to true, then enable colored logging support.

init_logger(_logger)[source]

Initialize the logger with an instance of a logging.Logger and sets the log level to INFO

property initialized

Return true only if SuperLogger.init_logger was successfully called.

set_log_level(level)[source]

Set the logger’s log level for which any levels below that will be ignored. For example, if the log level is set to ‘INFO’, all ‘DEBUG’ messages are ignored.

Here’s a list of the built-in log levels in descending order:

  • CRITICAL

  • ERROR

  • WARNING

  • INFO

  • DEBUG

  • NOTSET

Note that exceptions will always be logged regardless of the log level.

debug(tag, msg)[source]

Prints a message in the ‘debug’ channel. This should be used for detailed logging of the internals of a specific module or script such as the number of bytes sent via the camera module or how much time was taken to handle an HTTP request.

info(tag, msg)[source]

Prints a message in the ‘info’ channel. This should be used for general events or notes that the user should know but it isn’t a priority, such as what’s the port and host address of the Flask server or which web page did someone just access.

warning(tag, msg)[source]

Prints a message in the ‘warning’ channel. This should be used when an event in the web app has happened that the user should pay attention to, such as a missing config file or if a sensor isn’t configured correctly (that won’t greatly affect the performance of said sensor).

error(tag, msg)[source]

Prints a message in the ‘error’ channel. This should be used when an error has occurred that could make the web app unstable, such as a missing sensor attached, or if a 500 server error occurred internally.

critical(tag, msg)[source]

Prints a message in the ‘critical’ channel. This should be used when a critical event has occurred that user must pay attention to it, such as if the camera module or web app crashed.

User Management

A module to manage user accounts

class webapp.users.User(username, password)[source]

Bases: sqlalchemy.ext.declarative.api.Model

A User class for representing a user connected via an SQL database. See “Declaring Models” of the Flask-SQLAlchemy docs for more info on this class’ base object.

is_authenticated()[source]

Return true if the user is authenticated.

is_active()[source]

Return true if the user is activated.

is_anonymous()[source]

Return true if the user is anonymous.

get_id()[source]

This class attrubute holds the user account’s ID

webapp.users.load_user(user_id)[source]

A function wrapper to retreive a user account’s object

Configuration Management

A config file for controlling the global behavior of the web app.

webapp.config.DEBUG = False

A debug flag that controls flask’s debug mode.

webapp.config.LOCAL_DATABASE = False

If set to true, it will attempt to use the local database via SQLITE. You can initialize this database with python -m tools.init_test_db

webapp.config.LOG_LEVEL = 'DEBUG'

A flag for the default log level output for the global SuperLogger

Constants

webapp.constants.TECH_USED

A exhaustive list of all the technology used for this project.

webapp.constants.PAGES_CONFIG

A front-end configuration for the arrangement of the page tiles for the home page.

webapp.constants.SECRET_KEYFILE

Location of master secret keyfile for DB URI and Flask secret encryption.

webapp.constants.DB_CONFIG_FILE

Location of encrypted DB URI file.

webapp.constants.FLASK_SECRET_FILE

Location of encrypted flask secret file.

webapp.constants.ONE_YEAR

The time of one year in seconds.

webapp.constants.DB_URI

The database URI for facilitating user management.

webapp.constants.FLASK_SECRET

Used by Flask to securely sign cookies.

webapp.constants.LOCAL_DB_URI

Database URI used when using local database. See config.LOCAL_DATABASE for more info.

webapp.constants.STATIC_CACHE_CONFIG

Configuration for cache busting common static files.

Tools and scripts

Generate Secret Key

This script allows the admin to generate a new Fernet key file and re-encrypt any ‘.encrypted’ file, should the old key file be compromised.

Run it with python -m tools.gen_secret_key

Generate Flask secret

This script allows the admin to generate a new Fernet key file and re-encrypt any ‘.encrypted’ file, should the old key file be compromised.

Run it with python -m tools.gen_flask_secret

Decrypt contents of encrypted files

This script allows the admin to generate a new secret key, should the old one be compromised.

Run it with python -m tools.decrypt_contents

Initialize test database

This script allows you to create a local database with a default admin user.

Run it with python -m tools.init_test_db