Envertech Local keeps a persistent TCP connection to your Envertech inverter or gateway and turns the data into Home Assistant sensors: per-panel live values, system totals and daily, monthly and yearly energy. Everything is configured in the UI – no YAML required.
It is maintained by JimmyBones and uses the envertech-local protocol library.
✨ Features
- 🏠 100 % local: a persistent TCP connection to the inverter (default port
14889), polled every 5 seconds - 🔍 Automatic discovery of inverters on your network (UDP broadcast), with manual setup as a fallback
- ⚡ Per-panel live values: DC input voltage, power, energy, temperature, grid voltage and grid frequency
- 🏡 System totals: total power and lifetime energy
- 📅 Daily, monthly and yearly energy sensors that survive restarts
- 📈 Energy Dashboard ready: all energy sensors use
device_class: energyandstate_class: total_increasing - 🔁 Automatic reconnect with backoff (5 s up to 2 min) if the connection drops
- 🌍 Translations: English, German and Polish
- 🧩 Installable via HACS, with no YAML to write
📋 Requirements
- Home Assistant 2024.6.0 or newer
- An Envertech micro-inverter or gateway with a local TCP interface on port
14889, for example devices of the EMT series - Home Assistant must be able to reach the inverter on TCP port
14889 - For automatic discovery: UDP broadcasts must work – usually the same subnet/VLAN and
hostnetworking for Docker installs - Recommended: a fixed IP address (DHCP reservation) for the inverter in your router
📦 Installation
HACS (recommended)
The integration is not in the HACS default list yet (the inclusion request hacs/default#10850 is pending). Until then, add it as a custom repository:
- In Home Assistant, open HACS → ⋮ (top right) → Custom repositories.
- Add the repository URL below with type Integration.
- Search for Envertech API in HACS and click Download.
- Restart Home Assistant.
https://github.com/JImmyB0nes/Envertech_localJBCODE, 'text', 'Custom repository URL'); ?>
<h3>Manual installation</h3>
<ol>
<li>Download the <a href="<?= e($repo) ?>/releases/latest" target="_blank" rel="noopener">latest release</a>.</li>
<li>Copy <code>custom_components/envertech_local</code> into <code><config>/custom_components/</code> of your Home Assistant installation.</li>
<li><strong>Restart</strong> Home Assistant.</li>
</ol>
<h2>⚙️ Configuration</h2>
<p>The integration is set up entirely in the UI through a config flow:</p>
<ol>
<li>Go to <strong>Settings → Devices & services → Add integration</strong> and choose <strong>Envertech API</strong>.</li>
<li><strong>Discovery:</strong> the integration spends about 5 seconds searching your network for inverters. It sends UDP broadcasts on ports <code>48889</code> (Ethernet/LOCALCON) and <code>48899</code> (Wi-Fi). Every inverter found is listed as <code>IP — serial number</code>, except those already set up.</li>
<li>Pick your inverter and check the <strong>TCP port</strong> (default <code>14889</code>).</li>
<li>If nothing is found, choose <strong>Manual entry</strong> and enter the values from the table below.</li>
<li>Add one config entry for each inverter/gateway. The serial number is the unique ID, so an inverter can’t be added twice.</li>
</ol>
<div class="table-wrap"><table>
<thead><tr><th scope="col">Field (manual entry)</th><th scope="col">Description</th><th scope="col">Example / default</th></tr></thead>
<tbody>
<tr><td>IP address</td><td>IP address of the inverter/gateway</td><td><code>192.168.1.50</code></td></tr>
<tr><td>Serial number</td><td>The 8-character hex ID of the inverter</td><td><code>9A1B2C3D</code></td></tr>
<tr><td>TCP port</td><td>Local TCP port of the inverter</td><td><code>14889</code></td></tr>
</tbody>
</table></div>
<p>After setup, the inverter-wide sensors show up right away. Per-panel sensors are added automatically once the first data packet reports the panels. Until data arrives, sensors are <code>unavailable</code>.</p>
<h2>📊 Sensors</h2>
<p>The integration creates <strong>one device per config entry</strong> (<code>Envertech API <serial></code>, manufacturer <em>JimmyBones</em>, model <em>Microinverter</em>). The firmware version is shown as the device’s software version.</p>
<h3>Per panel / module</h3>
<p>These are created for every panel <code>n</code> (1, 2, …) that the inverter reports. The entity names are <code>P<n> …</code>, e.g. <code>sensor.p1_power</code>. With more than one inverter, Home Assistant adds a numeric suffix to entity IDs that would otherwise be identical.</p>
<div class="table-wrap project-table"><table>
<thead><tr><th scope="col">Sensor (entity name)</th><th scope="col">Key</th><th scope="col">Unit</th><th scope="col">Device / state class</th><th scope="col">Notes</th></tr></thead>
<tbody>
<tr><td>🔌 <code>P<n> Input Voltage</code></td><td><code>input_voltage</code></td><td>V</td><td>voltage / measurement</td><td>DC input voltage of the panel</td></tr>
<tr><td>⚡ <code>P<n> Power</code></td><td><code>power</code></td><td>W</td><td>power / measurement</td><td>Current power of the panel/module</td></tr>
<tr><td>🔋 <code>P<n> Energy</code></td><td><code>energy</code></td><td>kWh</td><td>energy / total_increasing</td><td>Lifetime energy of the module</td></tr>
<tr><td>🌡️ <code>P<n> Temperature</code></td><td><code>temperature</code></td><td>°C</td><td>temperature / measurement</td><td>Temperature reported by the micro-inverter module</td></tr>
<tr><td>🏭 <code>P<n> Grid Voltage</code></td><td><code>grid_voltage</code></td><td>V</td><td>voltage / measurement</td><td>AC grid voltage measured by the module</td></tr>
<tr><td>〰️ <code>P<n> Frequency</code></td><td><code>frequency</code></td><td>Hz</td><td>frequency / measurement</td><td>AC grid frequency</td></tr>
<tr><td>🆔 <code>P<n> Module Serial</code></td><td><code>mi_sn</code></td><td>–</td><td>–</td><td><em>Diagnostic</em> entity: serial number of the module</td></tr>
</tbody>
</table></div>
<p>Every per-panel sensor also has a <code>serial_number</code> attribute containing the module serial.</p>
<h3>Inverter / system</h3>
<p>These sensors belong to the device. Their names are translated (English, German, Polish). With Home Assistant set to English, the entity IDs look like <code>sensor.envertech_api_<serial>_total_power</code>.</p>
<div class="table-wrap project-table"><table>
<thead><tr><th scope="col">Sensor</th><th scope="col">Key</th><th scope="col">Unit</th><th scope="col">Device / state class</th><th scope="col">Notes</th></tr></thead>
<tbody>
<tr><td>⚡ Total power</td><td><code>total_power</code></td><td>W</td><td>power / measurement</td><td>Sum of all panel powers</td></tr>
<tr><td>🔋 Total energy</td><td><code>total_energy</code></td><td>kWh</td><td>energy / total_increasing</td><td>Sum of all panel lifetime energies</td></tr>
<tr><td>📅 Daily energy</td><td><code>energy_daily</code></td><td>kWh</td><td>energy / total_increasing</td><td>Energy since local midnight</td></tr>
<tr><td>🗓️ Monthly energy</td><td><code>energy_monthly</code></td><td>kWh</td><td>energy / total_increasing</td><td>Energy in the current month</td></tr>
<tr><td>📆 Yearly energy</td><td><code>energy_yearly</code></td><td>kWh</td><td>energy / total_increasing</td><td>Energy in the current year</td></tr>
<tr><td>🧠 Firmware version</td><td><code>firmware_version</code></td><td>–</td><td>–</td><td><em>Diagnostic</em> entity, format <code>x/y</code></td></tr>
</tbody>
</table></div>
<p>Numbers are rounded to 2 decimal places. The <strong>daily, monthly and yearly</strong> sensors are derived from <em>Total energy</em>: when a new period starts, they store the current total as an offset. They keep <code>offset</code>, <code>period_marker</code> and <code>last_reset</code> as attributes and restore them after a restart, so values don’t jump back to zero when Home Assistant restarts.</p>
<?php note('The integration does <strong>not</strong> provide per-panel current (A), per-panel AC power or MPPT-specific values, because the inverter’s local protocol doesn’t report them.', 'info'); ?>
<h2>📈 Energy Dashboard</h2>
<ol>
<li>Open <strong>Settings → Dashboards → Energy</strong>.</li>
<li>Under <strong>Solar panels</strong>, click <strong>Add solar production</strong>.</li>
<li>Select <code>sensor.envertech_api_<serial>_total_energy</code> (<em>Total energy</em>). For per-module statistics, add the individual <code>P<n> Energy</code> sensors instead.</li>
</ol>
<?php note('Use <em>Total energy</em> rather than the daily/monthly/yearly sensors – the Energy Dashboard does its own period calculations. The period sensors are meant for cards and automations.', 'tip'); ?>
<h2>🛠️ Troubleshooting</h2>
<details class="project-faq">
<summary>No values after a Home Assistant restart (only a reload helped)</summary>
<div class="project-faq-body">
<p>Versions <strong>≤ 1.1.1</strong> could end up without values after a restart: if the inverter wasn’t reachable within 60 seconds of startup (for example at night or because the network wasn’t up yet), the sensors were never created, and a dropped or silent TCP connection was never re-established.</p>
<p>This is fixed in <strong>1.1.2</strong>: the connection reconnects automatically with backoff (5 s up to 2 min), sensors are created immediately and stay <code>unavailable</code> until data arrives, and new panels are added as soon as they report. Update to the latest version; if it still happens, enable debug logging (see below) and open an issue.</p>
</div>
</details>
<details class="project-faq">
<summary>Sensors are <code>unavailable</code> at night</summary>
<div class="project-faq-body"><p>Micro-inverters are powered by the panels, so they switch off when there is no sunlight. The sensors become <code>unavailable</code> while the inverter is offline and recover on their own in the morning. The energy totals are unaffected.</p></div>
</details>
<details class="project-faq">
<summary>No inverter found during setup</summary>
<div class="project-faq-body">
<ul>
<li>Discovery relies on UDP broadcast, which doesn’t cross VLANs/subnets or Docker bridge networks. Use <strong>Manual entry</strong> instead.</li>
<li>Check that the inverter is powered (daylight!) and connected to your network.</li>
<li>Check that port <code>14889</code> is reachable:</li>
</ul>
<?php code_block(<<<'JBCODE'
nc -vz <inverter-ip> 14889