polymech - fw latest | web ui

This commit is contained in:
lovebird 2026-04-18 10:31:24 +02:00
parent a105c5ee85
commit ab2ff368a6
2972 changed files with 441416 additions and 372 deletions

60
.gitignore vendored
View File

@ -1,39 +1,21 @@
# PlatformIO
.pio
.cache/
# Build artifacts
*.elf
*.bin
*.map
# Secrets
src/config_secrets.h
# Doxygen Output
docs/doxygen/
firmware-docs
# Python build artifacts
scripts/__pycache__/
*.pyc
# Node.js
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.vscode/
.idea/
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
tests/reports/
src/firmware.ino.cpp
data/
dist
build
# build output
dist/
# generated types
.astro/
# dependencies
node_modules/
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store

10
.gitmodules vendored Normal file
View File

@ -0,0 +1,10 @@
[submodule "elena-rc2/lib/polymech-base"]
path = elena-rc2/lib/polymech-base
url = https://git.polymech.io/polymech/firmware-base.git
[submodule "cassandra-rc2/components/espsoftwareserial"]
path = cassandra-rc2/components/espsoftwareserial
url = https://github.com/plerup/espsoftwareserial.git
[submodule "cassandra-rc2/components/Vector"]
path = cassandra-rc2/components/Vector
url = https://github.com/janelia-arduino/Vector.git

119
README.md
View File

@ -1,114 +1,17 @@
# Polymech Cassandra Firmware
## Firmware ports of OSR-Plastic
This repository contains the firmware for the Polymech Cassandra project, running on an ESP32-S3.
## Overview
The firmware manages various hardware components and provides multiple interfaces for control and monitoring:
* **Serial Interface:** For debugging, testing, and direct command execution.
* **Modbus TCP Server:** Allows interaction with components using the Modbus protocol over WiFi.
* **REST API & Web UI:** Provides a web-based interface (status page, API documentation) and a RESTful API for interacting with the system over WiFi.
## Architecture
The firmware is built upon a component-based architecture:
* **`App` / `PHApp`:** The main application class (`src/PHApp.h`).
* **`Component`:** Base class (`src/Component.h`) for all functional units.
* **`Bridge`:** (`src/Bridge.h`) Facilitates serial command dispatch.
* **`SerialMessage`:** (`src/SerialMessage.h`) Handles serial communication.
* **`ModbusManager`:** (`src/ModbusManager.h`) Manages the Modbus TCP server.
* **`RESTServer`:** (`src/RestServer.h`) Implements the web server and REST API.
* **Details:** See [docs/components.md](./docs/components.md) for how components are structured, configured, and added.
## Interfaces
### 1. Serial Communication
A command-line interface is available over the USB serial port used for programming and monitoring.
* **Purpose:** Debugging, direct method calls on components.
* **Command Format:** `<<component_id;call_type;flags;payload:arg1:arg2...>>`
* **Examples & Details:** See [docs/serial.md](./docs/serial.md)
* **Sending Commands:** Use `npm run send -- "<command_string>"` or a standard serial terminal.
### 2. Modbus TCP
The device runs a Modbus TCP server (slave/responder) on port 502.
* **Implementation:** Managed by `ModbusManager` using the `eModbus` library.
* **Component Interaction:** Components supporting Modbus (like `Relay` or `PHApp` itself) implement `readNetworkValue` and `writeNetworkValue` methods. They are registered with the `ModbusManager` along with their corresponding Modbus addresses.
* **Configuration:** Modbus addresses are defined in `src/config-modbus.h`.
* **Design Details:** See [docs/design-network.md](./docs/design-network.md)
* **Testing:** Use the `python scripts/modbus_*.py` scripts directly (npm script argument passing has issues):
```bash
# Read Coil 51
python scripts/modbus_read_coils.py --address 51 --ip-address <DEVICE_IP>
# Write Coil 51 ON
python scripts/modbus_write_coil.py --address 51 --value 1 --ip-address <DEVICE_IP>
# Read Register 20
python scripts/modbus_read_registers.py --address 20 --ip-address <DEVICE_IP>
# Write Register 20
python scripts/modbus_write_register.py --address 20 --value 123 --ip-address <DEVICE_IP>
```
### 3. Web Interface & REST API
A web server runs on port 80, providing:
* **Status Page:** `http://<DEVICE_IP>/`
* **Swagger UI:** `http://<DEVICE_IP>/api-docs` (Interactive API documentation)
* **REST API:** `http://<DEVICE_IP>/api/v1/...`
* **Working Endpoints:**
* `GET /api/v1/system/info`: Device status.
* `GET /api/v1/coils`: List of registered coils.
* `GET /api/v1/registers`: List of registered registers.
* `GET /api/v1/coils?address=<addr>`: Read a specific registered coil.
* `GET /api/v1/registers?address=<addr>`: Read a specific registered register.
* `POST /api/v1/relay/test`: Trigger internal relay test.
* **Non-Functional Endpoints (Known Issue):**
* `POST /coils/{address}`: Returns 404.
* `POST /registers/{address}`: Returns 404.
* **Details & Examples:** See [docs/web.md](./docs/web.md)
* **Testing:** Use `npm run test-api-ip` (note that some tests related to POST endpoints will fail).
## Building and Development
See [firmware/.cursor/rules](./.cursor/rules) for a summary of common workflow commands.
**Key `npm` Scripts:**
* `npm run build`: Compile the firmware.
* `npm run upload`: Upload the firmware to the device.
* `npm run clean`: Clean build artifacts.
* `npm run monitor`: Open the serial monitor.
* `npm run build-web`: Generate web assets (from `swagger.yaml`, `front/`) and build firmware.
* `npm run send -- "<command>"`: Send a serial command.
* `npm run test-api-ip`: Run the REST API test script against the device IP.
* *(Modbus tests need direct python execution, see Modbus section above)*
## Configuration
* **Hardware Pins, Features:** `src/config.h`, `src/config_adv.h`
* **WiFi Credentials:** `src/config_secrets.h` (ensure this file exists and is populated)
* **Modbus Addresses:** `src/config-modbus.h`
* **Component IDs:** `src/enums.h` (enum `COMPONENT_KEY`)
## Todos
### Web
* [x] pid stats
* [ ] prof enabled
* [ ] warmup toggle
* [-] press prof - remaining ( parent )
* [ ] auto - interlock ( rs 485 connect ) => modes
* [ ] press : sp ( ui - mobile)
* [ ] partitions : settings not applied
### FW
* [x] press - profile ( check abort => vis error )
* [x] sp drag / lag
- [ ] pid stats
- [ ] prof enabled
- [ ] warmup toggle
- [ ] sp drag / lag
- [ ] press prof - remaining ( parent )
- [ ] auto - interlock ( rs 485 connect ) => modes
- [ ] press : sp ( ui - mobile)
- [ ] press - profile ( check abort => vis error )
- [ ] partitions : settings not applied
- [ ]

View File

@ -0,0 +1,13 @@
{
"version": 1,
"isRoot": true,
"tools": {
"csharpier": {
"version": "1.0.3",
"commands": [
"csharpier"
],
"rollForward": false
}
}
}

View File

@ -0,0 +1,27 @@
---
description:
globs:
alwaysApply: false
---
# PressCylinder Component
The `PressCylinder` is a component that orchestrates a `[Solenoid.h](mdc:cassandra-rc2/lib/polymech-base/src/components/Solenoid.h)` and a `[Loadcell.h](mdc:cassandra-rc2/lib/polymech-base/src/components/Loadcell.h)` to achieve a target pressure.
## Files
- Header: `[PressCylinder.h](mdc:cassandra-rc2/lib/polymech-base/src/components/PressCylinder.h)`
- Implementation: `[PressCylinder.cpp](mdc:cassandra-rc2/lib/polymech-base/src/components/PressCylinder.cpp)`
## Dependencies
- It controls a `[Solenoid.h](mdc:cassandra-rc2/lib/polymech-base/src/components/Solenoid.h)`.
- It reads pressure values from a `[Loadcell.h](mdc:cassandra-rc2/lib/polymech-base/src/components/Loadcell.h)`.
- It can optionally be controlled by a `[Joystick.h](mdc:cassandra-rc2/lib/polymech-base/src/components/Joystick.h)` for manual operation.
## Functionality
The component has two primary modes:
1. **Auto Mode**: Automatically opens/closes the solenoid to reach a Modbus-defined pressure setpoint (`targetSP`), based on the current value from the loadcell.
2. **Manual Mode**: Allows for direct control of the solenoid using the joystick (`UP` opens the solenoid).
## Configuration
- The component is enabled by the `ENABLE_PRESS_CYLINDER` flag in `[config.h](mdc:cassandra-rc2/src/config.h)`.
- It is instantiated and its dependencies are injected within `[PHApp.cpp](mdc:cassandra-rc2/src/PHApp.cpp)`.

View File

@ -0,0 +1,5 @@
---
description:
globs:
alwaysApply: false
---

View File

@ -0,0 +1,38 @@
---
description:
globs:
alwaysApply: false
---
# Loadcell Component Integration
This document outlines the structure and integration of the `Loadcell` component, which is designed to interface with an RS485 load cell.
## Key Files
- **Header File**: Defines the class structure, Modbus registers, and public methods.
- `lib/polymech-base/src/components/Loadcell.h`
- **Implementation File**: Contains the logic for setup, main loop, and Modbus communication.
- `lib/polymech-base/src/components/Loadcell.cpp`
## Enabling the Component
To enable or disable the `Loadcell` component, you must define or comment out the `ENABLE_LOADCELL` macro in the main configuration file:
- `src/config.h`
## Feature Inclusion
The component's header is conditionally included in the project through the `features.h` file. This ensures that the `Loadcell` is only compiled when its feature flag is enabled.
- `src/features.h`
## Device Registration
The `Loadcell` is registered as a slave device on the RS485 bus. The instantiation and registration logic can be found in the `registerApplicationDevices` function:
- `src/RS485Devices.cpp`
## Data Handling
The Process Value (PV) from the load cell is managed by a `ValueWrapper`. This allows for efficient, event-driven updates throughout the system. The `ValueWrapper` is initialized in the constructor of `Loadcell.cpp`.

39
cassandra-rc2/.gitignore vendored Normal file
View File

@ -0,0 +1,39 @@
# PlatformIO
.pio
.cache/
# Build artifacts
*.elf
*.bin
*.map
# Secrets
src/config_secrets.h
# Doxygen Output
docs/doxygen/
firmware-docs
# Python build artifacts
scripts/__pycache__/
*.pyc
# Node.js
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.vscode/
.idea/
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
tests/reports/
src/firmware.ino.cpp
data/
dist
build

114
cassandra-rc2/README.md Normal file
View File

@ -0,0 +1,114 @@
# Polymech Cassandra Firmware
This repository contains the firmware for the Polymech Cassandra project, running on an ESP32-S3.
## Overview
The firmware manages various hardware components and provides multiple interfaces for control and monitoring:
* **Serial Interface:** For debugging, testing, and direct command execution.
* **Modbus TCP Server:** Allows interaction with components using the Modbus protocol over WiFi.
* **REST API & Web UI:** Provides a web-based interface (status page, API documentation) and a RESTful API for interacting with the system over WiFi.
## Architecture
The firmware is built upon a component-based architecture:
* **`App` / `PHApp`:** The main application class (`src/PHApp.h`).
* **`Component`:** Base class (`src/Component.h`) for all functional units.
* **`Bridge`:** (`src/Bridge.h`) Facilitates serial command dispatch.
* **`SerialMessage`:** (`src/SerialMessage.h`) Handles serial communication.
* **`ModbusManager`:** (`src/ModbusManager.h`) Manages the Modbus TCP server.
* **`RESTServer`:** (`src/RestServer.h`) Implements the web server and REST API.
* **Details:** See [docs/components.md](./docs/components.md) for how components are structured, configured, and added.
## Interfaces
### 1. Serial Communication
A command-line interface is available over the USB serial port used for programming and monitoring.
* **Purpose:** Debugging, direct method calls on components.
* **Command Format:** `<<component_id;call_type;flags;payload:arg1:arg2...>>`
* **Examples & Details:** See [docs/serial.md](./docs/serial.md)
* **Sending Commands:** Use `npm run send -- "<command_string>"` or a standard serial terminal.
### 2. Modbus TCP
The device runs a Modbus TCP server (slave/responder) on port 502.
* **Implementation:** Managed by `ModbusManager` using the `eModbus` library.
* **Component Interaction:** Components supporting Modbus (like `Relay` or `PHApp` itself) implement `readNetworkValue` and `writeNetworkValue` methods. They are registered with the `ModbusManager` along with their corresponding Modbus addresses.
* **Configuration:** Modbus addresses are defined in `src/config-modbus.h`.
* **Design Details:** See [docs/design-network.md](./docs/design-network.md)
* **Testing:** Use the `python scripts/modbus_*.py` scripts directly (npm script argument passing has issues):
```bash
# Read Coil 51
python scripts/modbus_read_coils.py --address 51 --ip-address <DEVICE_IP>
# Write Coil 51 ON
python scripts/modbus_write_coil.py --address 51 --value 1 --ip-address <DEVICE_IP>
# Read Register 20
python scripts/modbus_read_registers.py --address 20 --ip-address <DEVICE_IP>
# Write Register 20
python scripts/modbus_write_register.py --address 20 --value 123 --ip-address <DEVICE_IP>
```
### 3. Web Interface & REST API
A web server runs on port 80, providing:
* **Status Page:** `http://<DEVICE_IP>/`
* **Swagger UI:** `http://<DEVICE_IP>/api-docs` (Interactive API documentation)
* **REST API:** `http://<DEVICE_IP>/api/v1/...`
* **Working Endpoints:**
* `GET /api/v1/system/info`: Device status.
* `GET /api/v1/coils`: List of registered coils.
* `GET /api/v1/registers`: List of registered registers.
* `GET /api/v1/coils?address=<addr>`: Read a specific registered coil.
* `GET /api/v1/registers?address=<addr>`: Read a specific registered register.
* `POST /api/v1/relay/test`: Trigger internal relay test.
* **Non-Functional Endpoints (Known Issue):**
* `POST /coils/{address}`: Returns 404.
* `POST /registers/{address}`: Returns 404.
* **Details & Examples:** See [docs/web.md](./docs/web.md)
* **Testing:** Use `npm run test-api-ip` (note that some tests related to POST endpoints will fail).
## Building and Development
See [firmware/.cursor/rules](./.cursor/rules) for a summary of common workflow commands.
**Key `npm` Scripts:**
* `npm run build`: Compile the firmware.
* `npm run upload`: Upload the firmware to the device.
* `npm run clean`: Clean build artifacts.
* `npm run monitor`: Open the serial monitor.
* `npm run build-web`: Generate web assets (from `swagger.yaml`, `front/`) and build firmware.
* `npm run send -- "<command>"`: Send a serial command.
* `npm run test-api-ip`: Run the REST API test script against the device IP.
* *(Modbus tests need direct python execution, see Modbus section above)*
## Configuration
* **Hardware Pins, Features:** `src/config.h`, `src/config_adv.h`
* **WiFi Credentials:** `src/config_secrets.h` (ensure this file exists and is populated)
* **Modbus Addresses:** `src/config-modbus.h`
* **Component IDs:** `src/enums.h` (enum `COMPONENT_KEY`)
## Todos
### Web
* [x] pid stats
* [ ] prof enabled
* [ ] warmup toggle
* [-] press prof - remaining ( parent )
* [ ] auto - interlock ( rs 485 connect ) => modes
* [ ] press : sp ( ui - mobile)
* [ ] partitions : settings not applied
### FW
* [x] press - profile ( check abort => vis error )
* [x] sp drag / lag

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 376 KiB

After

Width:  |  Height:  |  Size: 376 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

View File

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

View File

Before

Width:  |  Height:  |  Size: 168 KiB

After

Width:  |  Height:  |  Size: 168 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

Before

Width:  |  Height:  |  Size: 764 KiB

After

Width:  |  Height:  |  Size: 764 KiB

View File

Before

Width:  |  Height:  |  Size: 308 KiB

After

Width:  |  Height:  |  Size: 308 KiB

View File

Before

Width:  |  Height:  |  Size: 340 KiB

After

Width:  |  Height:  |  Size: 340 KiB

View File

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Some files were not shown because too many files have changed in this diff Show More