4f52064b3d6f7de51396bb5951a6ff0fd660d262
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
cd server
cp .env.example .env
npm install
npm start
2. Generate API Keys
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
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)
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
# 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
→ {"type": "auth", "apiKey": "your-api-key"}
← {"type": "auth", "success": true, "devicePrefix": "ac:"}
Send Data
→ {"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
Description
Languages
Rust
57.8%
JavaScript
23.6%
Python
17.4%
Shell
1.2%