Skip to main content
Intermediate Hardware Database Dashboard

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.

4
Nodes Used
~30min
Build Time
1s
Sample Rate
230V
Mains Voltage

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

1

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.

2

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
3

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
4

Import the Flow

Copy the flow JSON below. In EdgeFlow, go to Menu → Import, paste the JSON, and click Import.

5

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.

6

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

P = Vrms x Irms x PF
Where: P = Power (Watts), Vrms = Mains voltage (230V or 120V), Irms = RMS current from sensor, PF = Power Factor (0.95 typical)

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.

Next Steps