Skip to main content

IoTaWatt

IoTaWatt is an open-source WiFi energy monitor (ESP8266 + ADS1115 ADC) with up to 14 CT channels plus a voltage reference channel. The driver polls the device's local HTTP API and publishes the live readings to GEM zones you map to its inputs and named outputs — one zone per channel, which you create.

Prerequisites​

  • IoTaWatt firmware 02_07_05 or newer (the /status JSON shape stabilized at this revision).
  • Device on the same LAN as GEM with a static or reserved IP.
  • The voltage reference channel calibrated against an actual outlet. Without a calibrated voltage reference, every power reading will be wrong (most commonly: 0 W everywhere).
  • One CT clamp per measured circuit, properly oriented (arrow toward the load).

Setup​

  1. Find the IoTaWatt IP from your router or the device's captive-portal-style setup page. Confirm http://<ip>/status returns JSON in a browser.
  2. On the Devices page choose System → Devices → Add Device and pick the driver iotawatt.
    • ip — the LAN address.
    • port — 80 unless you changed it in IoTaWatt's WiFi config.
    • username / password — only if you set an admin password on the IoTaWatt under Configuration → Device → Admin Password. Most installs run open on a trusted VLAN. The driver sends HTTP basic credentials first; if the IoTaWatt refuses them with a 401 it retries the same request once with HTTP digest authentication and, when that is accepted, keeps using digest until the device is next reconnected. (Digest support was added without testing against a password-protected unit.)
  3. Run the get_inputs command. The response is the list of physical CT channels you configured in IoTaWatt — each has a name, Watts, Vrms, Hz, pf, Irms.
  4. Run get_outputs. These are the named expressions you defined in IoTaWatt (e.g. Main = input_1 + input_2).
  5. Create the zones yourself — the driver does not auto-create them. Unlike some metered integrations (SPAN, WattBox), IoTaWatt does not discover channels into zones or build a subsystem for you; it only publishes readings to zones that already exist. Add one zone per input or output you want to track, under Zones, each bound to this IoTaWatt device:
    • Subsystem — a default GEM install ships a Power subsystem (power); use it. (The driver hints energy, so the zone editor only pre-selects a subsystem if one named energy already exists — the stock install has none, so choose Power yourself, or create an energy subsystem under Subsystems if you'd rather keep IoTaWatt channels separate.)
    • Address — the channel name exactly as IoTaWatt reports it; the match is case-sensitive. Copy it from the get_inputs / get_outputs output.
      • Bare name (e.g. Main) — the driver looks for a matching input first, then an output.
      • input:Main or output:Main — explicit prefix; use it when the same name exists on both an input and an output.
  6. Adjust status_interval if needed. IoTaWatt comfortably serves 1 s polling; 5-10 s is plenty for dashboards and reduces ESP8266 load. Values below 1000 are raised to 1000; a blank, unparseable, zero, negative or oversized value uses the 10 s default.

Attribute Reference​

Device attributes​

AttributeRequiredTypeDefaultNotes
ipyesstring—LAN IP / hostname of the IoTaWatt.
portnoint80HTTP port.
usernamenostring—HTTP basic auth username. Set only if a password is configured. Usually admin.
passwordnostring (secure)—HTTP basic auth password.
status_intervalnoint (ms)10000Poll frequency for /status.

Zone attributes​

AttributeNotes
addressIoTaWatt channel name. input:Name or output:Name for disambiguation.
channel_kindAuto-set to input or output on first poll.

Zone state attributes (published by the polling loop)​

AttributeTypeUnit
wattsfloatW (signed; negative = wrong-side CT)
voltsfloatV (RMS)
hzfloatHz
pffloatpower factor (0..1)
ampsfloatA (RMS)
watt_hoursfloatWh (running total since IoTaWatt reboot)

Commands​

NameArgsNotes
get_status—Raw /status?stats=yes&inputs=yes&outputs=yes&device=yes JSON.
get_inputs—Physical CT channels. Use this to seed input zones.
get_outputs—Named expressions. Use this to seed output zones.
get_channeladdressOne channel by name (or input:Name / output:Name).
queryselect, begin, endHistorical query. select is the IoTaWatt series expression (e.g. Main.watts) — the driver automatically prepends a local-ISO timestamp column, so pass just the data series. begin / end are IoTaWatt time strings (s-1h, s, y, etc.). Returns the parsed series JSON.

Known Limitations​

  • watt_hours on /status is a running counter since the last IoTaWatt reboot. For daily / monthly totals, use the query command against IoTaWatt's historical series (it stores .log files locally).
  • Read-only — IoTaWatt has no relay outputs and the driver intentionally does not expose /edit (config-write) endpoints.
  • A CT clamped on the wrong side of the breaker reads negative watts. The driver passes the sign through unchanged so the integrator can spot it; correct it by flipping the clamp or inverting that input in IoTaWatt config (Configuration → Inputs → Reverse).
  • The voltage reference is just another input channel — named Voltage by default, often renamed. The driver gives it no special treatment: map a zone to it by name like any other channel and its volts / Hz readings land on that zone.
  • Each quantity is accepted under both the lowercase and the capitalized IoTaWatt spelling (watts/Watts, volts/Vrms, hz/Hz, pf/Pf, amps/Irms). A reading the firmware renders as a string is compared as a number, so it is written once and not on every poll; a channel the firmware reports as empty or null is left alone rather than recorded as 0.
  • If the IoTaWatt cannot be reached when the device connects, the driver retries after 30 s, doubling the wait up to 5 minutes, until it answers. A 401 at connect is not retried — correct the credentials and the device reconnects.
  • After three failed polls in a row the poll interval doubles each time, up to 5 minutes (or status_interval if that is longer). The first good poll returns to the configured interval. The device is marked connected only by a status reply that parses as JSON; a 401 or other HTTP error marks it disconnected.
  • mDNS discovery (_iotawatt._tcp) is supported by the firmware but not yet auto-discovered by GEM.
  • IoTaWatt does not yet feed the generic energy dashboards — the Power Flow and Top Circuits widgets (see Power Management). Those widgets light up automatically only for integrations that have been tagged for them, and IoTaWatt has not been tagged yet. The readings still land on each zone, so you can put them on zone tiles or a custom widget, chart them under History, and use them in triggers and reports.

Troubleshooting​

SymptomLikely cause / fix
Connection state stays falsehttp://<ip>/status returns 401? Set username / password on the device. If the page won't load at all, check IP and that the IoTaWatt is online (web UI at /). A reply that is not JSON (a login page, a different device at that address) does not count as connected.
Readings update only every few minutesThe IoTaWatt failed three polls in a row and polling backed off. Check the network path; polling returns to status_interval on the first good reply.
get_inputs returns emptyFirmware older than 02_07_05 — upgrade.
A zone never updates / shows no readingsIts Address must match an IoTaWatt input or output name exactly (case-sensitive), and the zone must be bound to this IoTaWatt device. Re-run get_inputs / get_outputs, copy the name verbatim, or prefix it with input: / output:.
Every channel reads 0 WVoltage reference is uncalibrated or wrong channel. In IoTaWatt → Configuration → Inputs, set the voltage channel to a CT clamped on an outlet whose voltage you can verify (~120 V NA / 230 V EU).
One channel reads negativeCT is reversed. Flip the clamp on the breaker or check the Reverse box on that input in IoTaWatt config.
Polling falls behind / 5xxLower status_interval. The ESP8266 has limited concurrency — 1s polling from multiple consumers (GEM + dashboard) can saturate it.