Energy Consumption Dashboard
Monitor real-time power consumption of your home or workshop using a non-invasive current transformer. Data is logged to InfluxDB for historical analysis and displayed on live dashboard charts with configurable alerts.
Flow Architecture
[ADS1115] --> [Function: Calculate RMS & Power] --> [InfluxDB Write] --> [Chart: Real-time Line]
(1s poll, A0) (Vrms x Irms x PF) (energy_monitor db) (power over time)
|
v
[Switch: > Threshold] --> [Telegram: Alert]
(power > 3000W) ("High power usage!") What You'll Need
Hardware
- • Raspberry Pi (any model with I2C)
- • SCT-013-030 current transformer (30A version)
- • ADS1115 16-bit ADC module
- • 33Ω burden resistor (1% tolerance)
- • 10µF capacitor (optional, smoothing)
- • Jumper wires and breadboard
Software
- • EdgeFlow installed and running
- • InfluxDB 2.x installed
- • Grafana (optional, for advanced dashboards)
- • Telegram Bot (optional, for alerts)
Wiring Diagram
SCT-013 Current Transformer ADS1115 ADC Raspberry Pi
============================== =========== ============
Mains Wire (LIVE only) VDD ---- 3.3V (Pin 1)
| GND ---- GND (Pin 6)
| [Clamp around wire] SCL ---- GPIO3 (Pin 5)
| SDA ---- GPIO2 (Pin 3)
+--- Wire 1 --- Burden 33Ω ---+--- A0 (Analog Input)
| |
+--- Wire 2 ---+--- GND ------+
|
10µF Cap (optional)
|
GND
ADDR pin: GND = 0x48 (default)
VDD = 0x49
SDA = 0x4A
SCL = 0x4B Safety Warning
The SCT-013 is a non-invasive sensor that clamps around a wire without cutting it. Never open the clamp while it is around a live wire. Never connect the SCT-013 directly to mains voltage. Always use a burden resistor to avoid damage to the ADC.
Step-by-Step Setup
Wire the SCT-013 to the ADS1115
Clamp the SCT-013 around the LIVE mains wire (not neutral). Connect the output leads through the 33Ω burden resistor to the ADS1115 A0 input. The burden resistor converts the current output to a voltage the ADC can read. Add a 10µF capacitor across the burden resistor for signal smoothing.
Enable I2C on the Raspberry Pi
Enable the I2C interface and verify the ADS1115 is detected:
sudo raspi-config nonint do_i2c 0
sudo i2cdetect -y 1
# Should show device at address 0x48 Set up InfluxDB
Install InfluxDB and create the database and retention policy:
# Install InfluxDB 2.x
curl -sL https://repos.influxdata.com/influxdata-archive.key | sudo apt-key add -
sudo apt install influxdb2
# Create bucket via CLI
influx bucket create \
--name energy_monitor \
--retention 90d \
--org my-org
# Note your API token for EdgeFlow config Import the Flow
Copy the flow JSON below. In EdgeFlow, go to Menu → Import, paste the JSON, and click Import.
Configure and Deploy
Double-click each node to update configuration for your setup: adjust the mains voltage (230V or 120V), InfluxDB connection details, and optional Telegram bot credentials. Then click Deploy.
Set up Grafana (Optional)
Add InfluxDB as a data source in Grafana, then create a dashboard with panels for
real-time power (W), daily energy (kWh), and cost estimation. Use the
energy_monitor bucket and
power_readings measurement.
Power Calculation Formula
The SCT-013 outputs an AC signal proportional to the mains current. The function node samples multiple readings per cycle, calculates the RMS value, then multiplies by the mains voltage and power factor to get real power in watts.
Function Node: Calculate RMS and Power
// Calculate RMS current and power from ADS1115 voltage reading
// SCT-013-030: 30A range, 1V output at rated current
// Burden resistor: 33 ohms
var voltage = msg.payload; // Raw voltage from ADS1115
var MAINS_VOLTAGE = 230; // Change to 120 for US/Canada
var POWER_FACTOR = 0.95; // Typical residential PF
var CT_RATIO = 1800; // SCT-013-030 turns ratio
var BURDEN_R = 33; // Burden resistor in ohms
// Convert ADC voltage to current
// SCT output voltage = (I_primary / CT_RATIO) * BURDEN_R
// So: I_primary = (V_measured * CT_RATIO) / BURDEN_R
var current_rms = (voltage * CT_RATIO) / BURDEN_R;
// Calculate power
var power_watts = MAINS_VOLTAGE * current_rms * POWER_FACTOR;
// Accumulate energy (kWh)
var prev = context.get('energy_kwh') || 0;
var prev_time = context.get('last_time') || Date.now();
var elapsed_hours = (Date.now() - prev_time) / 3600000;
var energy_kwh = prev + (power_watts * elapsed_hours / 1000);
context.set('energy_kwh', energy_kwh);
context.set('last_time', Date.now());
msg.payload = {
current_rms: Math.round(current_rms * 100) / 100,
power_watts: Math.round(power_watts),
energy_kwh: Math.round(energy_kwh * 1000) / 1000,
voltage_mains: MAINS_VOLTAGE,
power_factor: POWER_FACTOR,
timestamp: Date.now()
};
return msg; Configuration Details
| Node | Property | Value | Notes |
|---|---|---|---|
| ads1x15 | chip | ADS1115 | 16-bit for better precision |
| ads1x15 | channel | A0 | Single-ended input |
| ads1x15 | gain | 1 (±4.096V) | Matches SCT-013 output range |
| ads1x15 | interval | 1000ms | 1 reading per second |
| influxdb | url | http://localhost:8086 | InfluxDB 2.x endpoint |
| influxdb | bucket | energy_monitor | 90-day retention |
| influxdb | measurement | power_readings | Time-series measurement name |
| switch | condition | power_watts > 3000 | Adjust threshold as needed |
Complete Flow JSON
Copy and import this flow into EdgeFlow via Menu → Import.
{
"name": "Energy Consumption Dashboard",
"nodes": [
{
"id": "ads1115_1",
"type": "ads1x15",
"name": "Current Sensor",
"chip": "1115",
"address": "0x48",
"channel": 0,
"gain": 1,
"interval": 1000,
"x": 120,
"y": 200
},
{
"id": "func_rms",
"type": "function",
"name": "Calculate RMS & Power",
"code": "var voltage = msg.payload;\nvar MAINS_VOLTAGE = 230;\nvar POWER_FACTOR = 0.95;\nvar CT_RATIO = 1800;\nvar BURDEN_R = 33;\nvar current_rms = (voltage * CT_RATIO) / BURDEN_R;\nvar power_watts = MAINS_VOLTAGE * current_rms * POWER_FACTOR;\nvar prev = context.get('energy_kwh') || 0;\nvar prev_time = context.get('last_time') || Date.now();\nvar elapsed_hours = (Date.now() - prev_time) / 3600000;\nvar energy_kwh = prev + (power_watts * elapsed_hours / 1000);\ncontext.set('energy_kwh', energy_kwh);\ncontext.set('last_time', Date.now());\nmsg.payload = { current_rms: Math.round(current_rms * 100) / 100, power_watts: Math.round(power_watts), energy_kwh: Math.round(energy_kwh * 1000) / 1000, voltage_mains: MAINS_VOLTAGE, power_factor: POWER_FACTOR, timestamp: Date.now() };\nreturn msg;",
"x": 360,
"y": 200
},
{
"id": "influx_write",
"type": "influxdb-out",
"name": "Log to InfluxDB",
"url": "http://localhost:8086",
"org": "my-org",
"bucket": "energy_monitor",
"measurement": "power_readings",
"token": "YOUR_INFLUXDB_TOKEN",
"x": 600,
"y": 160
},
{
"id": "chart_power",
"type": "chart",
"name": "Power Chart",
"chartType": "line",
"group": "Energy Dashboard",
"label": "Real-time Power (W)",
"yAxisLabel": "Watts",
"x": 820,
"y": 160
},
{
"id": "switch_alert",
"type": "switch",
"name": "High Power?",
"property": "payload.power_watts",
"rules": [
{ "type": "gt", "value": 3000 }
],
"x": 600,
"y": 280
},
{
"id": "func_alert_msg",
"type": "function",
"name": "Format Alert",
"code": "msg.payload = '⚠ High power usage detected!\nCurrent: ' + msg.payload.current_rms + ' A\nPower: ' + msg.payload.power_watts + ' W\nEnergy today: ' + msg.payload.energy_kwh + ' kWh';\nreturn msg;",
"x": 820,
"y": 280
},
{
"id": "telegram_alert",
"type": "telegram",
"name": "Send Alert",
"botToken": "YOUR_BOT_TOKEN",
"chatId": "YOUR_CHAT_ID",
"x": 1040,
"y": 280
}
],
"connections": [
{ "from": "ads1115_1", "to": "func_rms" },
{ "from": "func_rms", "to": "influx_write" },
{ "from": "influx_write", "to": "chart_power" },
{ "from": "func_rms", "to": "switch_alert" },
{ "from": "switch_alert", "to": "func_alert_msg", "port": 0 },
{ "from": "func_alert_msg", "to": "telegram_alert" }
]
} Expected Output
Each second, the function node outputs a message like this:
{
"payload": {
"current_rms": 4.82,
"power_watts": 1053,
"energy_kwh": 2.418,
"voltage_mains": 230,
"power_factor": 0.95,
"timestamp": 1707753600000
}
} Troubleshooting
ADS1115 not detected on I2C
Verify wiring: SDA to GPIO2 (Pin 3), SCL to GPIO3 (Pin 5). Check that I2C is enabled with
sudo raspi-config. Confirm the ADDR pin connection matches your expected address.
Readings are always zero
Ensure the SCT-013 is clamped around only one conductor (the live wire), not the entire cable. Check the burden resistor is connected properly. Verify the gain setting is not too low for the signal.
Noisy / fluctuating readings
Add the 10µF smoothing capacitor. Move wiring away from the mains cable. Consider averaging multiple samples in the function node. Use shielded cable for long wire runs from the CT to the ADC.
InfluxDB write errors
Verify the InfluxDB service is running. Check that the bucket name, org, and API token are correct in the node configuration. Ensure the InfluxDB URL is reachable from the Pi.