polymech - fw latest | web ui
60
.gitignore
vendored
@ -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
@ -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
@ -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
|
||||
- [ ]
|
||||
|
||||
13
cassandra-rc2/.config/dotnet-tools.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"csharpier": {
|
||||
"version": "1.0.3",
|
||||
"commands": [
|
||||
"csharpier"
|
||||
],
|
||||
"rollForward": false
|
||||
}
|
||||
}
|
||||
}
|
||||
27
cassandra-rc2/.cursor/rules/PressCylinder.mdc
Normal 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)`.
|
||||
|
||||
5
cassandra-rc2/.cursor/rules/comments.mdc
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
description:
|
||||
globs:
|
||||
alwaysApply: false
|
||||
---
|
||||
38
cassandra-rc2/.cursor/rules/loadcell-component.mdc
Normal 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
@ -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
@ -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
|
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 376 KiB After Width: | Height: | Size: 376 KiB |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 2.0 MiB After Width: | Height: | Size: 2.0 MiB |
|
Before Width: | Height: | Size: 2.0 MiB After Width: | Height: | Size: 2.0 MiB |
|
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 168 KiB |
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 764 KiB After Width: | Height: | Size: 764 KiB |
|
Before Width: | Height: | Size: 308 KiB After Width: | Height: | Size: 308 KiB |
|
Before Width: | Height: | Size: 340 KiB After Width: | Height: | Size: 340 KiB |
|
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |