This repository contains the complete scheduling system and a simulator to test the system with many users and devices. The system consists of a Android frontend, written in Kotlin with Jetpack Compose as the GUI toolkit, and a CRUD REST API backend written in Rust with the Axum framework.
The purpose of the system is to schedule devices to run at times where they can make the most use of available renewable energy. The user registers their devices in the app and creates tasks for them. A task is a timespan of where the device can run and a duration of how long the device runs for. The task is then scheduled by the backend by creating an event that specifies the specific time the device should run. To do this an algorithm called the global scheduler is used to ensure optimal scheduling by taking into account tasks from all users.
The frontend allows the user to login, manage smart devices, and create tasks. A task is a time range that a device must be scheduled to run. The backend then schedules the task by using the global scheduler. The user is notified when their task has been scheduled, informing the user of the time the device will turn on.
Open the frontend/
project in Android Studio.
Here the app can be built.
The backend is a CRUD REST API written in Rust with the Axum framework.
It keeps track of accounts, authentication tokens, devices, tasks, and events in a sqlite database.
The database schema is defined in the migrations/
folder.
The backend has the following endpoints:
These endpoints return an authentication token on success. An authentication token is associated to an account.
accounts/register
register an accountaccounts/login
login to an account
An authentication token is needed to call the following endpoints. The endpoints only operate on the account's data, and cannot see or operate on other accounts' data.
devices/all
get all devicesdevices/create
create a devicedevices/delete
delete a devicetasks/all
get all taskstasks/create
create a tasktasks/delete
delete a taskevents/all
get all eventsevents/get
get the event associated with a task
Creating or deleting tasks signals to the backend that the scheduling algorithm needs to run. It waits for 5 minutes to collect more task creations/deletions and to not run the algorithm too often as it is expensive. The algorithm then runs and creates/updates events for all tasks in the system.
Many of these endpoints communicate with JSON.
This is done in rust by defining structs that specify the schema of the JSON input/output.
These structs are put into a seperate project (protocol
) so they can be reused in the simulator.
We use sqlx to communicate with the sqlite database. This provides compile time checked sql statements and type bindings to and from the database. It does however, require additional setup for the program to build.
First install the sqlx-cli tool:
cargo install sqlx-cli --no-default-features --features sqlite
Then create a .env file in the backend directory that contains the database file location:
DATABASE_URL=sqlite://dev.db
The database file can then be created and its schema setup with the following commands:
cargo sqlx db create
cargo sqlx migrate run
The backend can now be built:
cargo build
When you want to simulate, you have to recreate the database, to ensure that the database does not have any old data. Go to the backend directory and execute the following
.\make_new_db.bat
./make_new_db.sh
After that, the backend shall be executed in simulator mode
cargo run -- --simulator
Then open a new terminal in the simulator directory and modify the parameters in the compare function in simulator/src/compare_alforithms.rs
to match the simulation.
It is important that the available wattage match the tasks, so given n tasks the available watt per timeslot should be [1000; 2*505n], but you may round the calculated number up to a "nicer" number.
When the parameters are set, simply run the simulation
cargo run