refactor(simulator.v2): Improve the simulator structure with better organisation
- Dominant language
- G-code
- Stars
- 1
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
# Tasks
### Documentation Tasks - Planning Actions
- [x] Define this GitHub Issue structure
- [x] Analyze the original simulator architecture (v1), explain its structure and flaws, and propose improvements
- [x] Complete previous unfinished test code
- [x] Complete v1 to v2 migration plan
- Need to migrate remaining v1 endpoints (Materials, PrintJob, System, History, Camera, AirManager, Ambient_temperature) to v2 architecture. Currently, v2 has only migrated printer and authenticationendpoints.
- [x] Materials
- [x] Network
- [x] PrintJob
- [x] System
- [x] History
- [x] Camera
- [x] AirManager
- [x] Ambient_temperature
- [ ] Add comprehensive documentation (architecture diagram, API usage guide)
- [ ] Class diagram
- [ ] Architecture diagram
- [ ] Sequence diagram
- [ ] API usage guide
- [ ] Developer reading guide
- [ ] Continue executing related parent Issues
- [ ] Plan future roadmap
### Code Tasks - Specific Migration Actions
- [x] **FastAPI Program Entry**: Swagger documentation and welcome page
- [x] **Identify v1 and real 3D printer endpoints**: Check v1’s endpoints/*.py and list all routes
- [x] **Create Pydantic schemas**: Define schemas in app/api/schemas/
- [ ] **Update domain models**: Add corresponding models in app/domain/models/
- [ ] **Create repositories and services**
- [ ] In-memory storage
- [ ] **Implement API endpoints**
- [ ] **Update SwaggerAPI**: Register new routers in swagger_api.py
- [ ] **Test migration**
- [ ] Unit tests
- [ ] Integration tests
### Future Plans - Analysis Roadmap
- [ ] Consider proposed improvements (state machine, API controls, testing, etc.)
- **State Management**: How to implement a complete state machine?
- **Real-time Data**: Is WebSocket needed for real-time data push?
- **Edge Cases**: Should edge cases be considered?
- [ ] Plan for scalability (database support)
- [ ] In-memory storage
- [ ] Database support
# Introduction
### 1. Original Simulator Overview (v1)
#### a. Original Project Structure
```
(CS3300-Project) cs1-17-silver13:v1 jjzf1$ tree
.
├── frontend
└── backend
└── app
├── api # API routing layer
│ └── v1
│ ├── base_api.py # Base API class (used by swagger_api.py)
│ ├── endpoints
│ │ ├── printer.py
│ │ ├── authentication.py
│ │ ├── materials.py
│ │ ├── print_job.py
│ │ ├── system.py
│ │ ├── history.py
│ │ ├── camera.py
│ │ ├── air_manager.py
│ │ ├── ambient_temperature.py
│ └── swagger_api.py # Aggregates all endpoint routes
├── generators # Data generation layer
│ └── *_gen.py # Stateless data generators for each module
├── services # Service layer
│ └── *_service.py # Service logic for each module
└── main.py # FastAPI entrypoint
```
#### b. Original Functional Structure Description
The v1 system is divided into three layers:
- **API Routing Layer**: Handles user requests, route aggregation, and service calls.
- swagger_api.py: Aggregates all routes.
- base_api.py: Provides a common API base class.
- endpoints/*.py: Defines module-specific routes (e.g., printer.py, materials.py).
- **Service Layer**: Responds to API calls and fetches data from generators, acting as a dispatcher without state control.
- **Data Generation Layer**: Generates random data (e.g., printer_data_gen.py) to simulate device behavior.
#### c. v1 Flaws
- **Uncontrolled Random Data**: Generators produce inconsistent data, lacking state persistence, making it impossible to simulate continuous device behavior (e.g., printer status transitions).
- **No Entity Models**: Generators return raw data without class encapsulation, reducing realism.
- **Unclear Service Responsibilities**: Services merely forward calls without managing state or logic.
- **Blurry Module Boundaries**: Data generation and service logic are entangled, hindering maintainability.
- **Limited API Control**: Lacks fine-grained control (e.g., start/pause printing), limiting frontend usability.
#### d. v1 Workflow (Sequence Diagram)
The following sequence diagram illustrates the workflow for a GET /api/v1/printer request in v1, with layers annotated:
```mermaid
sequenceDiagram
actor User
participant Frontend
participant APIRouter as "API (printer.py) [API Layer]"
participant Service as "PrinterService [Service Layer]"
participant Generator as "PrinterDataGen [Data Generation Layer]"
User->>Frontend: Initiate GET /api/v1/printer
Frontend->>APIRouter: HTTP GET /api/v1/printer
APIRouter->>Service: Call get_printer()
Service->>Generator: Call generate_printer_data()
Generator-->>Service: Return random data
Service-->>APIRouter: Return data
APIRouter-->>Frontend: Return JSON response
Frontend-->>User: Display printer data
```
**Notes**:
- **Layers**: The API layer (printer.py) receives requests, the service layer (PrinterService) calls the data generation layer (PrinterDataGen).
- **Flaws**: The generator produces random, stateless data, leading to inconsistent responses; no domain models or Pydantic schemas are involved, lacking data validation and structuring.
### 2. Current Simulator Structure (v2)
#### a. Current Project Structure
```
(CS3300-Project) cs1-17-silver13:v2 jjzf1$ tree
.
├── frontend
└── backend
└── app
├── api # API routing layer
│ ├── endpoints # Route endpoints
│ │ ├── authentication.py
│ │ └── printer.py
│ ├── schemas # Pydantic schema definitions
│ │ ├── auth_schemas.py
│ │ └── printer_schemas.py
│ └── swagger_api.py # Route aggregation and documentation
├── infrastructure # Infrastructure layer
│ ├── simulators # Stateful hardware simulators
│ │ └── print_head.py # Simulates print head with internal state
│ └── repositories # State persistence interfaces
│ ├── authentication_repo.py # User state manager
│ └── printer_repo.py # Printer task & state manager
├── domain # Domain model layer
│ └── models # Core business models
│ ├── authentication_models.py
│ └── printer_models.py
├── services # Service layer
│ ├── auth_service.py
│ └── printer_service.py
├── tests # Tests
│ ├── unit # Unit tests
│ │ ├── service
│ │ │ └── test.py
│ │ └── domain
│ │ └── test.py
│ └── integration # Integration tests
│ └── api
│ └── test_printer.py
└── main.py # FastAPI entrypoint
```
#### b. Functional Structure Description
- **API Routing Layer (**api**)**:
- Handles user requests, route aggregation, and service calls.
- swagger_api.py: Aggregates endpoint routes.
- endpoints/*.py: Defines module-specific routes (currently only printer.py and authentication.py).
- schemas/*.py: Uses Pydantic for request/response validation and documentation.
- **Infrastructure Layer (**infrastructure**)**:
- simulators/*.py: Stateful hardware simulation (e.g., print_head.py).
- repositories/*.py: Manages state persistence (currently in-memory, future-ready for DB).
- **Domain Model Layer (**domain**)**:
- models/*.py: Defines core entities (e.g., Printer, Head, Extruder) using dataclasses.
- **Service Layer (**services**)**:
- Manages business logic and state transitions, bridging API and infrastructure.
- **Test Layer (**tests**)**:
- Includes unit and integration tests for reliability.
#### c. v2 Workflow (Sequence Diagram)
The following sequence diagram illustrates the workflow for a GET /api/v1/printer request in v2, including Model and Schemas, with layers annotated:
```mermaid
sequenceDiagram
actor User
participant Frontend
participant APIRouter as "API (printer.py) [API Layer]"
participant Schema as "PrinterSchemas [API Layer]"
participant Service as "PrinterService [Service Layer]"
participant Repository as "PrinterRepository [Infrastructure Layer]"
participant Model as "PrinterModel [Domain Layer]"
participant Simulator as "PrintHeadSimulator [Infrastructure Layer]"
User->>Frontend: Initiate GET /api/v1/printer
Frontend->>APIRouter: HTTP GET /api/v1/printer
APIRouter->>Schema: Validate request (Pydantic)
APIRouter->>Service: Call get_printer()
Service->>Repository: Call get()
Repository->>Model: Construct PrinterModel
Model-->>Repository: Return Printer object
Repository-->>Service: Return Printer object
Service->>Simulator: Call get_dynamic_data() (e.g., temperature)
Simulator-->>Service: Return simulated data
Service->>Schema: Convert to PrinterResponse
Schema-->>APIRouter: Return validated response
APIRouter-->>Frontend: Return JSON response
Frontend-->>User: Display printer data
```
**Notes**:
- **Layers**:
- **API Layer**: printer.py handles routing, PrinterSchemas (Pydantic) validates requests/responses.
- **Service Layer**: PrinterService coordinates logic.
- **Infrastructure Layer**: PrinterRepository manages state, PrintHeadSimulator provides dynamic data.
- **Domain Layer**: PrinterModel defines structured entities.
- **Improvements**: Compared to v1, v2 uses PrinterModel for data structuring, PrinterSchemas for validation, PrinterRepository for state persistence, and PrintHeadSimulator for dynamic behavior.
#### d. v2 Improvements Over v1
- **State Management**:
- Simulators are stateful, simulating hardware behavior over time.
- Repositories maintain persistent state, ensuring consistent device behavior.
- **Clear Responsibility Separation**:
- API: Handles requests and validation.
- Service: Manages business logic.
- Infrastructure: Simulates hardware and stores state.
- Domain: Encapsulates core entities.
- **Improved Interfaces**:
- Pydantic schemas ensure type safety and automatic documentation generation.
- Enhanced maintainability and reliability.
# Features Under Design/Refactoring
### 1. Enhanced State Management
- Design a complete state machine for printer status transitions (e.g., idle → printing → paused → completed → error).
- Primarily used to simulate the data generation process for a task from creation to completion.
### 2. Extended API Control
- Add fine-grained control endpoints:
- Submit print jobs to start printer operations.
- Implement WebSocket endpoint for real-time status updates.
### 3. Testing Infrastructure
- Achieve 80%+ code coverage with unit and integration tests.
- Evaluate whether edge cases need testing.
### 4. Simulator Realism
- Parse G-code files to enhance PrintHeadSimulator for dynamic behavior (e.g., temperature changes, material consumption).
- Add periodic updates to track time_spent_hot, material_extruded, etc.
### 5. Scalability
- Plan migration to database storage (e.g., SQLite/PostgreSQL via SQLAlchemy).
# Related Issues
- [ ] TBD: Implement user authentication flow (/auth/request, /auth/check)
- [ ] TBD: Enhance frontend to display real-time printer status (requires WebSocket support)
- [ ] TBD: Add support for print job management (e.g., queue, cancel, progress tracking)
# Resources & References
- **FastAPI Documentation**: https://fastapi.tiangolo.com/
- **Pydantic Documentation**: https://docs.pydantic.dev/
- **State Machine Design**: https://martinfowler.com/articles/2017-state-machine.html
- **FastAPI WebSocket**: https://fastapi.tiangolo.com/advanced/websockets/
- **SQLAlchemy Database**: https://docs.sqlalchemy.org/en/20/
- **Pytest Testing**: https://docs.pytest.org/en/stable/
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.