# TischlerCtrl - Sensor Data Collection System A Node.js server that collects sensor data from multiple agents via WebSocket, stores it in SQLite with automatic data summarization and retention policies. ## Architecture ``` ┌─────────────────────────────────────────────────────────────┐ │ Central Server (Node.js) │ │ ┌─────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ │ WebSocket │ │ SQLite DB │ │ Aggregation & │ │ │ │ Server │──│ sensor_data │ │ Cleanup Jobs │ │ │ │ :8080 │ │ sensor_10m │ │ (10m, 1h) │ │ │ └─────────────┘ │ sensor_1h │ └──────────────────┘ │ └────────┬─────────┴──────────────────────────────────────────┘ │ ┌────┴────┬──────────────┐ │ │ │ ┌───▼───┐ ┌───▼───┐ ┌─────▼─────┐ │ AC │ │ Tapo │ │ CLI │ │Infinity│ │ Agent │ │ Agent │ │ Agent │ │(Rust) │ │ (bash) │ └───────┘ └───────┘ └───────────┘ ``` ## Quick Start ### 1. Start the Server ```bash cd server cp .env.example .env npm install npm start ``` ### 2. Generate API Keys ```bash cd server node src/cli/generate-key.js "ac-infinity-agent" "ac:" node src/cli/generate-key.js "tapo-agent" "tapo:" node src/cli/generate-key.js "custom" "custom:" ``` ### 3. Configure and Start AC Infinity Agent ```bash cd agents/ac-infinity cp .env.example .env # Edit .env with your AC Infinity credentials and API key npm install npm start ``` ### 4. Build and Deploy Tapo Agent (Rust) ```bash cd agents/tapo cp config.toml.example config.toml # Edit config.toml with your Tapo devices and API key # Build for local machine cargo build --release # Or cross-compile for Raspberry Pi (requires cross) # cargo install cross # cross build --release --target armv7-unknown-linux-gnueabihf # Run ./target/release/tapo-agent # Or: RUST_LOG=info ./target/release/tapo-agent ``` ### 5. Use CLI Agent ```bash # Install websocat (one-time) cargo install websocat # Or: sudo apt install websocat # Send data export SENSOR_API_KEY="your-custom-api-key" export SENSOR_SERVER="ws://localhost:8080" ./agents/cli/sensor-send mydevice temperature 24.5 ``` ## Data Retention Policy | Resolution | Retention | Source | |------------|-----------|--------| | Raw (1 min) | 7 days | `sensor_data` | | 10 minutes | 30 days | `sensor_data_10m` | | 1 hour | Forever | `sensor_data_1h` | Data is averaged when aggregating to higher resolutions. ## WebSocket Protocol ### Authentication ```json → {"type": "auth", "apiKey": "your-api-key"} ← {"type": "auth", "success": true, "devicePrefix": "ac:"} ``` ### Send Data ```json → {"type": "data", "readings": [ {"device": "ctrl1", "channel": "temperature", "value": 24.5}, {"device": "ctrl1", "channel": "humidity", "value": 65.0} ]} ← {"type": "ack", "count": 2} ``` ## Project Structure ``` tischlerctrl/ ├── server/ # Central data collection server │ ├── src/ │ │ ├── index.js # Entry point │ │ ├── config.js # Configuration │ │ ├── db/ # Database schema & queries │ │ ├── websocket/ # WebSocket server │ │ ├── jobs/ # Aggregation & cleanup jobs │ │ └── cli/ # CLI tools (generate-key) │ └── data/ # SQLite database files │ ├── agents/ │ ├── ac-infinity/ # Node.js AC Infinity agent │ ├── tapo/ # Rust Tapo smart plug agent │ └── cli/ # Bash CLI tool │ └── README.md ``` ## License MIT