Skip to content

Commit

Permalink
fix: python decorator
Browse files Browse the repository at this point in the history
  • Loading branch information
Crispy-rw committed Jun 5, 2023
1 parent 2bc40f7 commit 68571cb
Show file tree
Hide file tree
Showing 12 changed files with 212 additions and 60 deletions.
113 changes: 113 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
## Design and implement a system that will track the assets in motion. Battery Swap, telematics onboard.
### How would you organize the data? What technologies would you use? Where would you see key risks?

To track assets in motion, including battery swaps and telematics onboard, the data can be organized as follows:

1. **Asset in motion Data**: This includes information about each asset, such as asset ID, type, current location, status, and associated battery details.
2. **Battery Data**: This includes battery information, such as battery ID, current charge level, health status, and history of swaps.
3. **Driver Data**: This includes driver details, such as driver ID, name, contact information, and driving history.
4. **Station Data**: This includes information about the battery swap stations, including station ID, location, available batteries, and swap history.

Technologies that was used to implement this system include:
- Backend Framework: Flask (Python) for developing the RESTful API and handling request/response logic.
- Relational Database: MySQL for storing and managing asset in motion, battery data, driver, and station data.
- frontend framework: ReactJs is a popular framework used to build modern SPAs

Key Risks:
- **Data Accuracy and Consistency**: Ensuring accurate and consistent real-time tracking data is crucial to maintain the reliability of the system.
- **Data Security**: Safeguarding sensitive asset information and implementing secure communication between devices, backend, and frontend components.
- **Scalability and Performance**: As the number of assets and data volume increases, the system should handle scalability and performance requirements effectively.

## How would you calculate the distance travelled by each driver? Total energy consumed by each driver. Total energy theoretically consumed by each driver.

To calculate the distance travelled by each driver and the total energy consumed by each driver, the following approach can be taken:

1. **Distance Calculation**:
- Utilize the GPS coordinates captured by the telematics devices on an asset.
- Apply distance calculation algorithms to calculate the distance between each set of consecutive GPS coordinates.
- Sum up the distances to calculate the total distance travelled by each driver.

2. **Energy Consumption Calculation**:
- Leverage the battery data and telematics data.
- Calculate the energy consumption based on factors such as vehicle speed, acceleration, and deceleration.
- Use energy consumption models specific to the vehicle type and battery characteristics.
- Sum up the energy consumption values to calculate the total energy consumed by each driver.

3. **Theoretical Energy Consumption Calculation**:
- Determine the theoretical energy consumption for each driver based on various factors, such as motocycle type, battery capacity, distance travelled, and energy efficiency.


## What's a good way to predict and optimize for how many batteries should be at a given station?

To predict and optimize the number of batteries at a given station, the following approach can be considered:

- Analyze historical data on battery swaps, station usage, and demands.
- Use statistical analysis techniques to identify peak demand periods and popular swap times
- Consider factors such as time of day, day of the week, seasonality, and any other relevant variables that affect battery demand.
- Incorporate external factors like events, holidays, and special occasions that may impact battery usage.

## Project Setup

To run the project using Docker, follow these steps:

### Prerequisites

Make sure you have the following installed on your system:
- Docker: [Download and install Docker](https://www.docker.com/get-started)

### 1. Clone the Repository

Clone the project repository from GitHub:

```bash
git clone https://github.com/Crispy-rw/energize-swap
```

### 2. Build the Docker Images

Navigate to the project's root directory:

```bash
cd energize-swap
```

Build the Docker images for the backend and frontend services:

```bash
docker-compose build
```

### 3. Start the Containers

Start the Docker containers using Docker Compose:

```bash
docker-compose up
```

This will start the backend, frontend, and database services defined in the `docker-compose.yml` file.

### 4. Access the Application

Once the containers are up and running, you can access the application in your web browser:

- Backend API: `http://localhost:5000/`
- Frontend: `http://localhost:5173/`

### 5. Stop the Containers

To stop the Docker containers, press `Ctrl + C` in the terminal where the containers are running.

Alternatively, you can run the following command in the project's root directory:

```bash
docker-compose down
```

This will stop and remove the containers, networks, and volumes created by Docker Compose.

That's it! You now have the project running using Docker.

Note: Make sure to customize the Docker Compose configuration (`docker-compose.yml`) according to your project's needs, such as environment variables, volumes, or additional services.

Please let me know if you need further assistance!
4 changes: 0 additions & 4 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,4 @@ RUN pip install --upgrade pip && pip install -r requirements.txt

COPY . /app

ADD entrypoint.sh /entrypoint.sh

RUN ["chmod", "+x", "/entrypoint.sh"]

CMD /wait && flask db reset && flask run --host=0.0.0.0
37 changes: 17 additions & 20 deletions backend/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
---
title: Energize Swap Backend API
---

# Energize Swap Backend API

Expand Down Expand Up @@ -34,22 +31,22 @@ The API will be accessible at `http://localhost:5000`.

## API ENDPOINTS

| Ressource URL | Methods | Description | Authentication required |
| -------------------------------- | ------- | ----------------------------------------------- | ----------------------- |
| /api/v1/batteries | GET | Get a list of all batteries | Yes |
| /api/v1/batteries/addbattery | POST | Create a new battery | Yes |
| /api/v1/drivers | GET | GET a list of drivers | Yes |
| /api/v1/drivers/addriver | POST | Create a new driver | Yes |
| /api/v1/stations | GET | Get a list of stations | No |
| /api/v1/stations/addstation | POST | Create a new Station | Yes |
| /api/v1/stations/batteries | GET | Get all batteries of a specific stations | Yes |
| /api/v1/swaps | GET | Get a list of all battery exchange | Yes |
| /api/v1/swaps/addswap | POST | Create a new battery exchange | Yes |
| /api/v1/swaps/stopswap/<swap_id> | PUT | Modify/Edit a specific swap to finish it | Yes |
| /api/v1/swaps/totalswappedbattery| GET | Get a list of total battery exchanged | Yes |
| /api/v1/swaps/<swap_id> | GET | Get information of one battery exchange | Yes |
| /api/v1/movements/<serial_number>| POST | Update the movement of an active battery | Yes |
| /api/v1/login | POST | Authentication | No |
| Ressource URL | Methods | Description | Authentication required | Role |
| -------------------------------- | ------- | ----------------------------------------------- | ----------------------- | ---------------|
| /api/v1/batteries | GET | Get a list of all batteries | Yes | Admin |
| /api/v1/batteries/addbattery | POST | Create a new battery | Yes | Admin |
| /api/v1/drivers | GET | GET a list of drivers | Yes | Admin |
| /api/v1/drivers/addriver | POST | Create a new driver | Yes | Admin |
| /api/v1/stations | GET | Get a list of stations | No | Admin |
| /api/v1/stations/addstation | POST | Create a new Station | Yes | Admin |
| /api/v1/stations/batteries | GET | Get all batteries of a specific stations | Yes | Manager |
| /api/v1/swaps | GET | Get a list of all battery exchange | Yes | Admin, Manager |
| /api/v1/swaps/addswap | POST | Create a new battery exchange | Yes | Manager |
| /api/v1/swaps/stopswap/<swap_id> | PUT | Modify/Edit a specific swap to finish it | Yes | Manager |
| /api/v1/swaps/totalswappedbattery| GET | Get a list of total battery exchanged | Yes | Manager, Admin |
| /api/v1/swaps/<swap_id> | GET | Get information of one battery exchange | Yes | Manager |
| /api/v1/movements/<serial_number>| POST | Update the movement of an active battery | Yes | Driver |
| /api/v1/login | POST | Authentication | No | |

## Deployment

Expand All @@ -75,4 +72,4 @@ The Energize Swap Backend API is released under the [MIT License](https://openso

This project was developed as part of the Energize Swap initiative to promote electric vehicle adoption and provide efficient battery swapping services. We would like to thank all the contributors and supporters who have made this project possible.

For any inquiries or further information, please contact [Project Team Email].
For any inquiries or further information, please contact [[email protected]].
18 changes: 12 additions & 6 deletions backend/api/v1/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@

# Assuming RADIUS is a global constant
def toRad(degrees):
# Converts degrees to radians
'''
Converts degrees to radians
'''
return degrees * math.pi / 180

def getDistance(from_, to):
# Calculates the distance between two points on a sphere
'''
Calculates the distance between two points on a sphere
'''
fromLat = from_[0]
fromLon = from_[1]
toLat = to[0]
Expand All @@ -29,7 +33,9 @@ def getDistance(from_, to):
return RADIUS * c

def measurePath(points):
# Measures the total distance of a path given by a list of points
'''
Measures the total distance of a path given by a list of points
'''
lastPoint = None
distance = 0
for point in points:
Expand All @@ -41,15 +47,15 @@ def measurePath(points):

def token_info(token):
'''
Check token if token is valid this returns ID aapended to it
Check token if token is valid this returns infor apended to it
'''
try:

claims = jwt.decode(token.split(' ')[1], 'test')
claims.validate()
except ExpiredTokenError as e:
except ExpiredTokenError:
return False
except Exception as e: # noqa: E722
except Exception: # noqa: E722
return False
return claims

Expand Down
9 changes: 9 additions & 0 deletions backend/api/v1/views/batteries.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@
from api.v1.views import app_views
from api.v1.models.battery import Battery
from api.v1.inputs.inputs import REGISTER_BATTERY_RULES, validate
from api.v1 import auth


@app_views.route('batteries/addbattery', methods=['POST'], strict_slashes=False)
@auth
def create_battery():
'''
Create a new battery
'''
try:
sent_data = request.get_json()

Expand Down Expand Up @@ -34,7 +39,11 @@ def create_battery():


@app_views.route("/batteries", methods=["GET"], strict_slashes=False)
@auth
def get_all_batteries():
'''
Get all batteries with their information
'''
try:
batteries = Battery.query.all()
return jsonify({
Expand Down
19 changes: 13 additions & 6 deletions backend/api/v1/views/drivers.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@

@app_views.route("/login", methods=["POST"], strict_slashes=False)
def login():
'''
User authentication
'''
sent_data = request.get_json(force=True)

valid = validate(sent_data, LOGIN_RULES)
Expand Down Expand Up @@ -68,9 +71,12 @@ def login():
return jsonify({"error": "Invalid email or password"}), 401


@auth
@app_views.route("drivers/addriver", methods=["POST"], strict_slashes=False)
@auth
def create_driver():
'''
Create a new driver
'''
try:
sent_data = request.get_json(force=True)

Expand Down Expand Up @@ -118,17 +124,18 @@ def create_driver():
}), 400


@auth
@app_views.route("/drivers", methods=["GET"], strict_slashes=False)
@auth
def get_drivers():
'''
Get all drivers information
'''
try:
return jsonify(
{
return jsonify({
"status": "Ok",
"message": "All Drivers informations",
"data": [driver.serialize_one for driver in Driver.query.all()],
}
)
})
except Exception as e:
return jsonify({
'status': "Error",
Expand Down
5 changes: 5 additions & 0 deletions backend/api/v1/views/movements.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@
from sqlalchemy import and_

from api.v1.inputs.inputs import REGISTER_MOVEMENT_RULE, validate
from api.v1 import auth


@app_views.route('movements/<serial_number>', methods=['POST'], strict_slashes=False)
@auth
def update_movement(serial_number):
'''
Update the movement of a swapped battery
'''
try:
sent_data = request.get_json()

Expand Down
14 changes: 13 additions & 1 deletion backend/api/v1/views/stations.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@


@app_views.route('stations/addstation', methods=['POST'], strict_slashes=False)
@auth
def create_station():
'''
Create a new station
'''
try:
sent_data = request.get_json(force=True)

Expand All @@ -38,9 +42,12 @@ def create_station():



@auth

@app_views.route("/stations", methods=["GET"], strict_slashes=False)
def get_stations():
'''
Get all stations
'''
try:
data = []
for station in Station.query.all():
Expand All @@ -59,8 +66,13 @@ def get_stations():
'message': "Erro" + e,
}), 400


@app_views.route("/stations/batteries", methods=["GET"], strict_slashes=False)
@auth
def get_batteries_per_station():
'''
Get all batteries of a specific station
'''
try:
user_info = token_info(request.headers.get("Authorization"))

Expand Down
Loading

0 comments on commit 68571cb

Please sign in to comment.