Files
scalesApp/SETUP.md
T
gitea 122480cd46 Add the A4 report designer and fix band layout
Brings in the A4 (millimetre) report designer alongside the existing
matrix editor, migrates the frontend from react-scripts to Vite/Vitest,
and fixes four defects found while using the A4 band tools.

Layout — layout.js now implements the standard banded-report model:
everything prints where it was drawn, and a band growing per data row is
the only thing that moves anything. Previously `paginate` re-flowed every
band from the top margin, so a band placed halfway down the page
previewed at the top, and `header` was treated as a page header and
hoisted above the statics drawn before it. A header is a COLUMN header:
it prints in place and repeats only on a continuation page. Statics now
take part too — one drawn below a band keeps its drawn gap as that band
grows, and follows onto the next page rather than vanishing when pushed
past the bottom margin. The displacement is keyed on the band's design
bottom, not on an instance's laid-out y: every row of a band shares one
design position, so keying on the instance measured the gap from row 1
and let the static overlap rows 2..n.

Band children — a child's x is relative to its band, as its y already
was. layout() emitted it raw, so a field printed measured from the paper
edge instead of the band's left margin. Instances now carry bandX.

Band placement — a band's x comes from the page margins, so creation
takes only the click's Y (the factory's x was being overwritten by the
spread order) and dragging is locked to the vertical axis. Bands render
as a strip, with top/bottom rules only, matching the matrix editor.
fromApiReport reflows on load so reports saved with a stray x straighten
themselves. Matrix bands are constrained to vertical too.

Drag lifecycle — useElementDrag re-subscribed its document listeners on
every render during a drag, because the effect depended on an unmemoized
onDrag. Each re-subscribe removed the mouseup listener before adding the
next, measured as add/remove/add/remove/add across two mousemoves, and a
release landing in that gap was lost: the element kept following the
cursor until the next click. Snapping made it routine, since a held
guide stops x/y changing and leaves the guide overlay's render sitting
between the move and the release. onDrag and dragData now go through
refs so the effect depends on [isDragging] alone.

Note: the matrix editor has no test coverage, so its band constraint is
verified by reading only. The A4 suite is 201 passing tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-20 12:52:20 +03:00

307 lines
7.4 KiB
Markdown

# ScalesApp - Complete Setup & Installation Guide
A three-tier application for reading serial COM port data, storing it in a Django backend, and displaying it in a React frontend.
## Project Structure
```
ScalesApp/
├── frontend/ # React web application
│ ├── src/
│ ├── public/
│ ├── package.json
│ └── .env.example
├── backend/ # Django REST API
│ ├── api/ # Main API app
│ ├── manage.py
│ ├── settings.py
│ ├── requirements.txt
│ └── .env.example
├── serial_bridge/ # Python serial reader (system tray)
│ ├── app.py
│ ├── serial_reader.py
│ ├── tray_icon.py
│ ├── requirements.txt
│ ├── serial_bridge.spec
│ └── .env.example
└── README.md
```
## Prerequisites
- **Python 3.8+** (for Django and Serial Bridge)
- **Node.js 16+** (for React)
- **Windows OS** (Serial Bridge uses Windows-specific system tray)
- A COM port device (scales or serial reader)
## Step-by-Step Installation
### 1. Backend (Django) Setup
#### a. Create virtual environment
```bash
cd backend
python -m venv venv
venv\Scripts\activate
```
#### b. Install dependencies
```bash
pip install -r requirements.txt
```
#### c. Setup environment variables
```bash
copy .env.example .env
# Edit .env file with your settings
```
#### d. Initialize database
```bash
python manage.py migrate
```
#### e. Create admin user (optional)
```bash
python manage.py createsuperuser
```
#### f. Run the backend server
```bash
python manage.py runserver
```
The API will be available at `http://localhost:8000`
**Available API Endpoints:**
- `GET /api/readings/` - List all readings
- `POST /api/readings/` - Create a new reading
- `GET /api/readings/latest/` - Get the latest reading
- `GET /api/readings/by_port/?port=COM1` - Get readings from specific port
### 2. Frontend (React) Setup
#### a. Install dependencies
```bash
cd frontend
npm install
```
#### b. Setup environment variables
```bash
copy .env.example .env
# Ensure VITE_API_URL=http://localhost:8000
```
#### c. Start development server
```bash
npm start
```
The frontend will open at `http://localhost:3000`
**Features:**
- Real-time data display from COM ports
- Port selector for filtering
- Recent readings table
- Auto-refresh every 2 seconds
### 3. Serial Bridge (Python) Setup
#### a. Create virtual environment
```bash
cd serial_bridge
python -m venv venv
venv\Scripts\activate
```
#### b. Install dependencies
```bash
pip install -r requirements.txt
```
#### c. Setup environment variables
```bash
copy .env.example .env
# Edit .env with your COM port and backend URL
```
Key settings:
- `COM_PORT=COM1` (change to your port)
- `BAUD_RATE=9600` (adjust based on your device)
- `BACKEND_URL=http://localhost:8000`
#### d. Run the application
```bash
python app.py
```
The app will:
- Appear in system tray
- Start reading from COM port
- Automatically post data to Django backend
- Retry failed posts
- Log to `serial_bridge.log`
### 4. Running All Services (Development)
Open 3 terminal windows and run:
```bash
# Terminal 1: Backend
cd backend
venv\Scripts\activate
python manage.py runserver
# Terminal 2: Frontend
cd frontend
npm start
# Terminal 3: Serial Bridge
cd serial_bridge
venv\Scripts\activate
python app.py
```
## Building Serial Bridge as EXE
To create a standalone Windows executable that runs in the system tray:
```bash
cd serial_bridge
# Install PyInstaller
pip install pyinstaller
# Build the executable
pyinstaller serial_bridge.spec
```
The executable will be created at `serial_bridge\dist\ScalesApp\ScalesApp.exe`
You can:
- Run it directly
- Add it to Startup folder (`C:\Users\<User>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup`)
- Create a Windows Task Scheduler entry to run at startup
## Data Flow
```
┌──────────────────┐
│ Physical Device │
│ (Scales/COM) │
└────────┬─────────┘
│
│ Serial data
▼
┌──────────────────────────────┐
│ Serial Bridge (Python) │
│ - Reads COM port │
│ - System tray app │
│ - Retry logic │
└────────┬─────────────────────┘
│
│ HTTP POST /api/readings/
▼
┌──────────────────────────────┐
│ Django Backend │
│ - REST API │
│ - Database storage │
│ - CORS enabled │
└────────┬─────────────────────┘
│
│ REST API GET /api/readings/
▼
┌──────────────────────────────┐
│ React Frontend │
│ - Real-time display │
│ - Port selector │
│ - Auto-refresh │
└──────────────────────────────┘
```
## Configuration Files
### Backend (backend/.env)
```env
SECRET_KEY=your-secret-key-here
DEBUG=True
ALLOWED_HOSTS=localhost,127.0.0.1
DATABASE_URL=sqlite:///db.sqlite3
```
### Frontend (frontend/.env)
```env
VITE_API_URL=http://localhost:8000
```
### Serial Bridge (serial_bridge/.env)
```env
COM_PORT=COM1
BAUD_RATE=9600
BACKEND_URL=http://localhost:8000
AUTO_CONNECT=True
DEBUG=False
```
## Troubleshooting
### Backend Issues
- **Port already in use**: Change port: `python manage.py runserver 8001`
- **CORS errors**: Check `ALLOWED_HOSTS` and `CORS_ALLOWED_ORIGINS` in settings.py
- **Database errors**: Run migrations: `python manage.py migrate`
### Frontend Issues
- **Cannot connect to backend**: Ensure Django is running and `VITE_API_URL` is correct
- **Port 3000 in use**: Kill process: `netstat -ano | findstr :3000`
### Serial Bridge Issues
- **COM port not found**: List available ports with: `python -m serial.tools.list_ports`
- **Backend not reachable**: Check `BACKEND_URL` and ensure Django server is running
- **No tray icon**: Run as administrator, check Windows system tray settings
- **Data not posting**: Check `serial_bridge.log` for errors
## Production Deployment
### Backend
```bash
# Use production settings
export DJANGO_SETTINGS_MODULE=scalesapp.settings
python manage.py collectstatic
# Use Gunicorn
pip install gunicorn
gunicorn scalesapp.wsgi -b 0.0.0.0:8000
```
### Frontend
```bash
npm run build
# Serve dist folder with nginx or similar
```
### Serial Bridge
Create Windows Service or Scheduled Task to run the EXE at startup.
## Next Steps
1. ✅ Test all three components locally
2. ✅ Verify data flow from COM → Backend → Frontend
3. ✅ Customize React components if needed
4. ✅ Build Serial Bridge as EXE
5. ✅ Deploy to production servers
6. ✅ Setup monitoring and logging
## Additional Resources
- [Django REST Framework Docs](https://www.django-rest-framework.org/)
- [React Docs](https://react.dev/)
- [PySerial Docs](https://pyserial.readthedocs.io/)
- [Pystray Docs](https://github.com/moses-palmer/pystray)
## Support
For issues, check the logs:
- Backend: Django console output
- Frontend: Browser console (F12)
- Serial Bridge: `serial_bridge.log` file