A deterministic, configurable IoT simulator for grid-connected solar PV plants that generates realistic telemetry data, computes daily/weekly digests, and anchors digest hashes to the blockchain for carbon credit verification.
- Realistic Solar Simulation: Generates time-series telemetry with day/night cycles, weather variation, degradation, and outages
- Deterministic Generation: Seeded RNG ensures reproducible results for demos and testing
- Daily Digests: Computes Merkle-rooted digests with kWh โ tCO2e avoided calculations
- Blockchain Anchoring: Optional anchoring of digest hashes via registry-adapter-api
- REST APIs: Complete API for sites, telemetry, and digest management
- Live Dashboard: Real-time visualization of solar plant performance
- Docker Ready: Containerized deployment with docker-compose
- CLI Tools: Scripts for seeding, backfilling, and anchoring
- Node.js 20+
- Docker & Docker Compose (optional)
- Clone and install dependencies:
git clone <repository-url>
cd iot-solar-sim
npm install- Set up environment:
cp env.example .env
# Edit .env with your configuration- Initialize database:
npm run db:migrate
npm run db:generate- Seed with sample data:
npm run seed- Start the server:
npm run devThe API will be available at http://localhost:4200 and the dashboard at http://localhost:4200/dashboard.
# Build and start all services
docker-compose up -d
# View logs
docker-compose logs -f iot-solar-sim
# Stop services
docker-compose down- PV Simulation Model: Calculates irradiance, temperature, and power based on solar geometry and weather
- Telemetry Generator: Creates deterministic time-series data with configurable intervals
- Aggregation Service: Builds hourly summaries and daily digests
- Digest Generator: Creates Merkle-rooted JSON/CSV artifacts
- Anchor Client: Communicates with registry-adapter-api for blockchain anchoring
- REST API: Fastify-based HTTP API with health checks and metrics
- Dashboard UI: Real-time web interface for monitoring
Solar Site Config โ PV Model โ Telemetry Generator โ Database
โ
Blockchain โ Registry Adapter โ Anchor Client โ Daily Digest โ Aggregation
| Variable | Default | Description |
|---|---|---|
PORT |
4200 | API server port |
DATABASE_URL |
file:./sim.db |
SQLite database path |
SIM_SEED |
42 | RNG seed for deterministic generation |
INTERVAL_SECONDS |
60 | Live simulation interval |
DEFAULT_INTERVAL_MINUTES |
5 | Default telemetry interval |
ANCHOR_ENABLED |
true | Enable blockchain anchoring |
ADAPTER_API_URL |
http://localhost:4100 |
Registry adapter API URL |
SITE_IDS |
PRJ001,PRJ002 |
Comma-separated site IDs |
BASELINE_FACTOR_KG_PER_KWH_IN |
0.708 | India emission factor |
BASELINE_FACTOR_KG_PER_KWH_DEFAULT |
0.82 | Default emission factor |
Sites are configured via JSON files in src/config/sites/:
{
"siteId": "PRJ001",
"name": "Solar Farm C",
"country": "IN",
"timezone": "Asia/Kolkata",
"lat": 18.52,
"lon": 73.85,
"capacityDcKW": 12000,
"capacityAcKW": 10000,
"tiltDeg": 20,
"azimuthDeg": 180,
"modules": 22000,
"inverterEff": 0.972,
"degradationPctPerYear": 0.5,
"baselineKgPerKwh": 0.708,
"outageWindows": [
{
"start": "03:00",
"end": "03:30",
"days": "SUN"
}
],
"curtailmentPct": 0.03
}GET /health- System health checkGET /metrics- Basic metrics (sites, telemetry count, digests)
GET /sites- List all sitesGET /sites/:id- Get site details
GET /sites/:id/telemetry?from=&to=&interval=- Get telemetry dataPOST /sites/:id/generate?day=&interval=- Generate telemetry for a day
GET /sites/:id/daily?from=&to=- Get daily digestsPOST /sites/:id/anchor?day=- Anchor a digest to blockchain
GET /sites/:id/preview/today- Get today's summary data
GET /dashboard- Web dashboard interfaceGET /api/dashboard- Dashboard API data
npm run seedCreates sample sites and generates yesterday's data with anchored digest.
npm run backfill -- --site PRJ001 --from 2025-01-01 --to 2025-01-31 --interval 5mGenerates historical telemetry and digests for a date range.
npm run anchor -- --site PRJ001 --day 2025-10-20Anchors a specific day's digest to the blockchain.
npm run live -- --site PRJ001 --interval 60s --duration 120Runs live simulation for specified duration.
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run specific test file
npm test -- pv-simulation.test.ts- Unit Tests: PV model, RNG, hashing, CO2 conversion
- Integration Tests: API endpoints, database operations
- Property Tests: Energy monotonicity, power clipping, outage effects
- Database connectivity
- Registry adapter API status
- System metrics
- Site count
- Telemetry record count
- Daily digest count
- Anchor success/failure rates
Structured logging with Pino:
- Request/response logging
- Error tracking
- Performance metrics
- Audit trail for anchoring
- No PII: Only plant IDs and hashes stored
- Rate Limiting: API rate limits (100 req/min)
- CORS: Disabled by default
- HMAC Signing: Optional for adapter API calls
- Input Validation: Zod schema validation
Default emission factors by country:
- India: 0.708 kg CO2e/kWh
- USA: 0.386 kg CO2e/kWh
- EU: 0.255 kg CO2e/kWh
- China: 0.581 kg CO2e/kWh
Daily digests include:
- Site ID and date
- Total energy (kWh)
- Avoided CO2 emissions (tCO2e)
- Merkle root hash
- Row count and metadata
- Generate daily digest with Merkle root
- POST to registry-adapter-api
/v1/anchor - Receive transaction hash and block number
- Store anchor information in database
# docker-compose.yml
version: '3.8'
services:
iot-solar-sim:
build: .
ports:
- "4200:4200"
environment:
- NODE_ENV=production
- DATABASE_URL=file:./data/sim.db
- ANCHOR_ENABLED=true
volumes:
- ./data:/app/data
depends_on:
- registry-adapter-apiSet these in your .env file or Docker environment:
BLOCKCHAIN_RPC_URL: Ethereum RPC endpointPRIVATE_KEY: Wallet private key for anchoringCONTRACT_ADDRESS: EvidenceAnchor contract address
iot-solar-sim/
โโโ src/
โ โโโ config/ # Configuration and site configs
โ โโโ model/ # PV simulation model
โ โโโ ingest/ # Telemetry generation
โ โโโ aggregate/ # Aggregation and digest generation
โ โโโ anchor/ # Blockchain anchoring client
โ โโโ api/ # REST API server
โ โโโ ui/ # Dashboard UI
โ โโโ util/ # Utilities (RNG, hashing, time)
โ โโโ test/ # Test files
โโโ scripts/ # CLI scripts
โโโ prisma/ # Database schema
โโโ docker/ # Docker configuration
- Create site config JSON in
src/config/sites/ - Add site ID to
SITE_IDSenvironment variable - Run
npm run seedto create site in database
The PV simulation model can be extended to support:
- Different module types
- Tracking systems
- Shading effects
- More sophisticated weather models
Add country-specific emission factors in src/config/index.ts:
export const EMISSION_FACTORS = {
// ... existing factors
NEW_COUNTRY: 0.500,
} as const;- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
MIT License - see LICENSE file for details.
For issues and questions:
- Check the documentation
- Review existing issues
- Create a new issue with detailed information
- MQTT telemetry streaming
- Multi-site aggregation
- Advanced weather integration
- Performance optimization
- Additional blockchain networks
- Mobile dashboard
- Alert system
- Data export tools