Troubleshooting Guide
Something not working? Start at the top of this page and work down — the first section covers the great majority of problems people actually hit.
Start with these four
Section titled “Start with these four”1. No panels showing up at all.
Nine times out of ten this is the wiring. Check that A goes to A, B goes to B,
and that you actually connected the ground wire — RS485 won’t read reliably
without it. Then confirm your setup file says baud_rate: 38400.
See Wiring.
2. Some panels showing, but not all.
Give it 10–15 minutes. Panels take turns reporting on the shared cable, so they
trickle in rather than all appearing at once. If you’re still short after that,
check number_of_devices in your config is at least as large as your panel count.
3. Panels showing as “Module 4F2A” instead of names. That’s expected on a fresh install — the device knows a panel is there but nobody’s told it what to call it. See Putting names on the panels.
4. It worked, then went unstable or unreachable. Usually a board without PSRAM, which this project requires. Use one that has it, such as the AtomS3R.
Still stuck? The rest of this page is organised by symptom.
Quick reference
Section titled “Quick reference”| Symptom | Solution |
|---|---|
| No devices discovered | Check UART wiring, verify 38400 baud (Wiring) |
| No devices discovered on a LilyGO T-CAN485 | Drive GPIO16, 17 and 19 high — the transceiver is unpowered without them (below) |
| High packet loss | Add CONFIG_UART_ISR_IN_IRAM: "y" (UART Optimization) |
| Memory exhaustion | Use an ESP32-S3 with PSRAM — it’s required |
| CCA sync fails (local HTTP) | Verify CCA IP, check network connectivity |
| CCA sync returns 401 / “HTTP locked” | Tigo firmware 4.0.4+ closed local HTTP — use cca_source: ble or cloud_import: true |
| BLE CCA won’t connect | Close the Tigo phone app (one BLE central at a time) |
| Tigo cloud import fails | Recheck credentials; needs cloud_import: true; token may have expired |
| History reads back empty after reboot | Erase the tsdb partition once (history storage) |
| Web UI not loading | Confirm tigo_server configured, check ESP32 IP |
Device Discovery Issues
Section titled “Device Discovery Issues”No Devices Found
Section titled “No Devices Found”Symptoms: No “Frame received” or “New device discovered” log messages.
Solutions:
- Verify UART wiring (TX→RX, RX→TX) — see the Wiring Guide
- Confirm baud rate is 38400
- Check Tigo system is powered and communicating
- Look for any “Frame” messages in ESPHome logs
No Devices Found on a LilyGO T-CAN485
Section titled “No Devices Found on a LilyGO T-CAN485”Symptoms: Nothing received at all — the log shows no frames, and a UART debug
block shows only >>> (transmit) lines with no <<< (receive) lines. An ESP32
loopback or TX test still passes, because it never leaves the chip.
Cause: the board’s RS485 front end needs three GPIOs held high, and the
one people miss is GPIO16. It is not an enable — it is 5V_EN, the ME2107 boost
that supplies the MAX13487E transceiver. Left floating, the transceiver has no
power and the receiver is deaf no matter how correct the wiring and baud rate are.
Solution: drive all three, and leave them on:
switch: - platform: gpio id: rs485_power_5v pin: GPIO16 # 5V boost that feeds the transceiver internal: true restore_mode: ALWAYS_ON - platform: gpio id: rs485_auto_direction pin: GPIO17 # /RE high => AutoDirection controls the receiver internal: true restore_mode: ALWAYS_ON - platform: gpio id: rs485_chip_enable pin: GPIO19 # SHDN high => normal operation (low = whole chip off) internal: true restore_mode: ALWAYS_ONSimpler still, include the shipping board file as a package and let it supply the
front end for you — boards/esp32-lilygo-t-can485.yaml, as
boards/example-t-can485.yaml does. The config builder
also emits all three when you pick this board.
While you are in there: do not add a test writer that transmits bytes on this
UART. tigo_monitor is receive-only, and the MAX13487E has no driver-enable pin —
AutoDirection turns the driver on by itself whenever it sees activity, so those
test bytes go straight onto your live CCA↔TAP bus.
Devices Found But No Barcodes
Section titled “Devices Found But No Barcodes”Symptoms: Devices show as “Module XXXX” instead of barcode.
Explanation: Frame 27 (16-char barcode) may not transmit immediately. This is normal.
Solutions:
- Wait longer (barcodes come from periodic Frame 27)
- Devices work without barcodes
- Use CCA sync to get panel names
UART Communication
Section titled “UART Communication”“Packet missed!” Errors
Section titled ““Packet missed!” Errors”Cause: UART interrupt not in IRAM, causing missed frames.
Solution: Add to ESP-IDF config:
esp32: framework: type: esp-idf sdkconfig_options: CONFIG_UART_ISR_IN_IRAM: "y"Expected miss rate: 0.02-0.04% is excellent for multi-drop RS485. For the deep dive, see UART Optimization.
High Frame Loss Rate
Section titled “High Frame Loss Rate”Solutions:
- Ensure
CONFIG_UART_ISR_IN_IRAM: "y"is set - Size the RX buffer correctly (see below)
- Check for electrical interference on RS485 line
- Verify proper termination on RS485 bus
See UART Optimization for the full tuning guide.
RX Buffer Sizing
Section titled “RX Buffer Sizing”rx_buffer_size: and CONFIG_UART_RX_BUFFER_SIZE are not alternatives — set both to the same value. The sdkconfig option sizes the ESP-IDF driver’s ring buffer; the uart: option must match it so ESPHome doesn’t fight the driver. Every shipping board YAML sets them together:
esp32: framework: type: esp-idf sdkconfig_options: CONFIG_UART_RX_BUFFER_SIZE: "4096"
uart: id: tigo_uart rx_pin: GPIO5 tx_pin: GPIO6 baud_rate: 38400 rx_buffer_size: 4096 # match CONFIG_UART_RX_BUFFER_SIZE2-8 KB is plenty on an ESP32-S3 at 38400 baud. This buffer comes from internal (DMA-capable) RAM, never PSRAM, so an oversized value wastes scarce internal heap — a 32 KB buffer silently spends a sixth of the usable internal RAM. See UART Optimization.
Memory Issues
Section titled “Memory Issues”Socket Creation Failures
Section titled “Socket Creation Failures”Symptoms:
Failed to create socketin logs- Web interface crashes
- System instability
Cause: Internal RAM exhaustion without PSRAM.
Solutions:
- Immediate: Reboot ESP32
- Permanent: Upgrade to ESP32-S3 with PSRAM (e.g., M5Stack AtomS3R)
Memory Limits
Section titled “Memory Limits”PSRAM is required — but only by tigo_server, not by tigo_monitor.
A config with tigo_server: and no psram: block is now rejected at validation
time rather than compiling into a device that runs out of heap hours later. The
web server builds whole HTML pages and JSON responses in memory; without
psram: ESPHome never sets CONFIG_SPIRAM, so those allocations land on the
~130KB internal heap and fragment it to OOM under dashboard polling.
If your board has no PSRAM, drop tigo_server: and run sensors-only to Home
Assistant over the native API — boards/esp32-lilygo-t-can485.yaml is a worked
example. Panel discovery there uses the Generate YAML Config button instead
of the web UI.
ESP32 Internal Temperature Reads Nothing
Section titled “ESP32 Internal Temperature Reads Nothing”/api/status returns "internal_temp": null and the Diagnostics view shows no die temperature.
Most ESP32s have a single temperature peripheral, and it installs exactly once. Three things break it:
- Range must fit one hardware range.
temperature_sensor_install()needs the requested range to sit inside a single entry of the chip’s range table — on the ESP32-S3 that is{50..125, 20..100, -10..80, -30..50, -40..20}. A request spanning two entries (e.g.-10..110) matches none, fails withESP_ERR_INVALID_ARG(“Out of testing range”), and the sensor never installs. Fixed in 2.0.0-beta.4, which requests-10..80. The configured range is only a starting hint — the driver follows the hardware onto another range at read time, so a hot die still reads correctly. - Another component owns the peripheral. If you also run ESPHome’s
internal_temperatureplatform, its install and ours race and the loser reads nothing. Wire the existing sensor intotigo_serverinstead of letting both try:
sensor: - platform: internal_temperature id: die_temp name: "ESP32 Temperature"
tigo_server: internal_temperature_id: die_temp- The chip has no such peripheral at all. The classic ESP32 (including the WROVER modules with PSRAM) has none — only the S2/S3/C-series and P4 do. There is nothing to configure here; the field is simply absent. The boot log says
No die temperature sensor on this chip - Diagnostics will omit it.
Look for Failed to install temperature sensor: <err> in the boot log to tell the first two apart.
PSRAM Not Detected After Enabling
Section titled “PSRAM Not Detected After Enabling”Symptoms:
- ESP32 crashes and rolls back to previous firmware
- Logs show
OTA rollback detected! Rolled back from partition 'app1' - PSRAM not recognized despite
esptool.pyconfirming it exists
Cause: ESPHome does not rebuild the bootloader when changing PSRAM configuration. The old bootloader doesn’t initialize PSRAM, causing boot failure.
Solution:
- Clean ESPHome build files:
esphome clean <yaml> - Erase flash completely:
esptool.py erase_flash - Flash again:
esphome run <yaml>
This forces a fresh bootloader build with PSRAM support enabled.
CCA Integration
Section titled “CCA Integration”CCA sync only fills in friendly panel/string/inverter names. Your local RS485 monitoring — power, voltage, temperature, energy — works fine without it.
Sync Not Working (local HTTP)
Section titled “Sync Not Working (local HTTP)”Checklist:
- CCA IP address correct?
- ESP32 can reach CCA on network?
- CCA responding? (Test:
http://cca-ip/in browser) - Check logs for “CCA Sync complete” or error messages
CCA Sync Returns 401 / “HTTP Locked” (Tigo firmware 4.0.4+)
Section titled “CCA Sync Returns 401 / “HTTP Locked” (Tigo firmware 4.0.4+)”Symptoms: Sync fails with a 401 or an “HTTP locked” message. The CCA web page also refuses local logins.
Cause: Newer Tigo CCA firmware (4.0.4 and up, including 4.0.5-ct) closes the local HTTP API. This is a Tigo change, not a bug in this component. Your local RS485 monitoring is unaffected — only friendly-name import from the CCA is blocked.
Fix — pick one:
- Read the CCA over Bluetooth. Set
cca_source: bleand add able_client_id;tigo_servertalks the CCA’smobile_apiover BLE instead of HTTP. See CCA over Bluetooth. - Recover the layout from Tigo’s cloud. Set
cloud_import: trueand sign in on the Tigo Cloud page to pull panel names + string/MPPT/inverter layout. See Tigo cloud import. - Enter friendly names manually from the Tools view — no CCA connection required.
BLE CCA Won’t Connect / Search Finds Nothing
Section titled “BLE CCA Won’t Connect / Search Finds Nothing”Symptoms: The CCA Info CCA Connection search returns nothing, or the BLE link never connects.
Solutions:
- Close the Tigo phone app. The CCA allows only one BLE central at a time — if the app is connected, the ESP32 can’t be.
- The CCA advertises on the
04:C0:5BTigo MAC prefix; the search card filters for it. If nothing shows, move the ESP32 closer or confirm the CCA has BLE enabled. - Connection is on demand — the link opens for each read (~10 s round trip) and drops afterward, so a brief delay is normal; it isn’t held open at boot.
- Confirm
esp32_bleandesp32_ble_trackerare configured andble_client_idpoints at able_client:block. See CCA over Bluetooth.
Tigo Cloud Import Fails / Login Rejected
Section titled “Tigo Cloud Import Fails / Login Rejected”Symptoms: Cloud sign-in on the Tigo Cloud page is rejected, or layout import returns nothing.
Solutions:
- Recheck your Tigo account credentials (the same login the Tigo mobile app uses). Only the resulting bearer token is stored on-device — never your password.
- The stored token expires; if import stops working after it worked before, sign in again to refresh it.
- Confirm
cloud_import: trueis set — without it the Tigo Cloud page and cloud client aren’t compiled in. See Tigo cloud import.
Barcode Mismatch
Section titled “Barcode Mismatch”Cause: CCA barcodes may differ slightly from UART Frame 27 barcodes.
Solution: Component uses fuzzy matching (last 6 chars, 1-char tolerance). If still not matching, check logs for discovered barcodes and CCA barcodes.
Web Interface
Section titled “Web Interface”Not Accessible
Section titled “Not Accessible”Checklist:
tigo_servercomponent configured?- Correct ESP32 IP? (Check ESPHome logs)
- Port 80 not blocked?
- Try direct IP:
http://x.x.x.x/
Slow or Unresponsive
Section titled “Slow or Unresponsive”Solutions:
- Use ESP32-S3 with PSRAM
- Reduce
number_of_devicesif set too high - Check heap memory on
/statuspage
Energy Data
Section titled “Energy Data”Energy Total Resets on Reboot
Section titled “Energy Total Resets on Reboot”This is about the running energy counter (total kWh), which is separate from the on-flash History database — see History Reads Back Empty below for that.
Normal behavior: The component saves the energy total to NVS hourly to reduce flash wear.
Maximum data loss: 1 hour of energy accumulation on an unexpected reboot.
Logs to verify:
Restored total energy: X.XX kWhEnergy data saved at hour boundary
Energy Not Accumulating
Section titled “Energy Not Accumulating”Checklist:
- Sensors publishing? (Check HA entities)
- Night mode active? (Check binary sensor)
- Power readings valid? (Non-zero during daylight)
On-Flash History (TSDB)
Section titled “On-Flash History (TSDB)”The History view is backed by an on-flash time-series database (esp_tsdb) stored on a LittleFS partition. This is separate from the hourly energy total above — it keeps per-snapshot rollups and per-panel power that survive reboots and OTA updates.
History Reads Back Empty / “0 records” After Reboot
Section titled “History Reads Back Empty / “0 records” After Reboot”Symptoms: The History view or /api/tsdb/stats shows 0 records after every reboot, even though data accumulates while the device is up.
Cause: A too-small LittleFS partition left no copy-on-write headroom, so the database couldn’t commit and read back empty after a restart. This was a real bug, fixed by right-sizing the partition.
Solutions:
- Update to the current firmware (the partition layout is corrected).
- Existing installs may need to erase the tsdb partition once so LittleFS reformats it at the new size. After that, history persists across reboots.
- Confirm your config pins the forked
esp_tsdbby commit SHA rather than a registry version, and uses the custom partition table. Saving history to flash has the current pin.
See Saving history to flash for the schema, sizing, and partition setup.
Diagnostics Shows 0 KB for Every Database Size
Section titled “Diagnostics Shows 0 KB for Every Database Size”/api/tsdb/stats reports size_bytes: 0 for every database (the Diagnostics table’s size column reads 0.0).
esp_tsdb gets the file size from stat(), and ESP-IDF leaves CONFIG_VFS_SUPPORT_DIR off by default — that compiles the VFS directory syscalls out of the build, so stat() fails for every path at runtime. fopen/fread/fwrite are unaffected (they live under VFS_SUPPORT_IO), which is why the databases themselves work fine and only the size column is dead.
Add to your esp32: framework: sdkconfig_options::
CONFIG_VFS_SUPPORT_DIR: "y"Costs about 5.7 KB of flash. The shipped boards/*.yaml already set it. It also un-breaks esp_tsdb’s corruption-recovery unlink() calls, which silently no-op without it.
A Database Row Says “stats unavailable”
Section titled “A Database Row Says “stats unavailable””The Diagnostics table shows — for a database’s counters and stats unavailable (ESP_ERR_TIMEOUT) in the range column, and the log has E TSDB_CORE: tsdb_get_stats_h: lock timeout.
Not an error condition. tsdb_get_stats_h() takes the per-database mutex with a 5-second timeout, and the writer task holds that mutex across tsdb_sync_h()’s fclose/fopen. A stats poll that lands on a flush gives up and the row is rendered as unreadable rather than dropped. It resolves on the next refresh.
History View Empty / No /api/history Endpoints
Section titled “History View Empty / No /api/history Endpoints”Cause: esp_tsdb is opt-in — without the extra components and custom partition table it isn’t compiled in.
Solution: Add the esp_tsdb + littlefs components and the custom partition table as shown in Saving history to flash. The rest of the component works fine without it; you just lose the History view and the /api/history/* and /api/tsdb/stats endpoints.
Night Mode
Section titled “Night Mode”Normal behavior: After 60 minutes without data:
- Publishes zeros every 10 minutes
- Prevents stale data in Home Assistant
- Temperatures show as unavailable
Customize timeout:
tigo_monitor: night_mode_timeout: 90 # Minutes (1-1440)Compilation Errors
Section titled “Compilation Errors”fatal error: esphome/components/sensor/sensor.h: No such file or directory
Section titled “fatal error: esphome/components/sensor/sensor.h: No such file or directory”Cause: ESPHome only copies a component’s sources into the build when that component is declared in your YAML. The tigo_monitor C++ code includes sensor/sensor.h, text_sensor/text_sensor.h, and binary_sensor/binary_sensor.h unconditionally, so all three have to be present.
Solution: Update the component — tigo_monitor now AUTO_LOADs all three, so nothing is needed in your YAML.
If you are pinned to an older version, add stub sections (empty is enough):
sensor:
text_sensor:
binary_sensor:Note the error names whichever header the compiler reached first, so you may see text_sensor.h or binary_sensor.h instead of sensor.h. On older versions, fix all three at once — adding them one at a time just moves the error to the next line.
“has no member” Error
Section titled ““has no member” Error”Cause: Method renamed during refactoring.
Solution: Update to latest component version, or check for stale method names.
external_components Not Loading
Section titled “external_components Not Loading”Cause: The shorthand github:// format may not resolve correctly depending on ESPHome version.
Solution: Use the expanded format:
external_components: - source: type: git url: https://github.com/RAR/esphome-tigomonitor components: [ tigo_monitor, tigo_server ] refresh: 0sFor a specific release:
external_components: - source: type: git url: https://github.com/RAR/esphome-tigomonitor ref: v1.3.1 components: [ tigo_monitor, tigo_server ] refresh: 0sESP-IDF Errors
Section titled “ESP-IDF Errors”Solutions:
- Use ESPHome 2026.5.0+
- Set
framework: type: esp-idf, version: recommended - Try clean compile:
esphome clean <yaml> && esphome compile <yaml>
fatal error: esp_bt_defs.h: No such file or directory (BLE build on ESP-IDF 6.0.x)
Section titled “fatal error: esp_bt_defs.h: No such file or directory (BLE build on ESP-IDF 6.0.x)”Symptom: esp32_ble_tracker.h:22:10: fatal error: esp_bt_defs.h: No such file or directory
while compiling ble_client / esp32_ble_tracker — only on BLE builds
(cca_source: ble/auto, or any config with esp32_ble_tracker).
Cause: an explicit version: "6.0.x" framework pin. ESPHome 2026.x maps that
to the pioarduino prep_IDF6 platform, a moving branch that now delivers
ESP-IDF 6.0.2. IDF 6.0.2 relocated the Bluedroid public headers to
components/bt/host/bluedroid/api/include/api/ and no longer puts them on the
global include path, while ESPHome’s esp32_ble_tracker.h still does
#include <esp_bt_defs.h> without declaring bt as a component requirement — so
every BLE source fails to compile. This is an upstream ESPHome × IDF-6
incompatibility, not a TigoMonitor issue, and it is independent of the ESPHome
release (recommended is IDF 5.5.4 on both 2026.6.5 and 2026.7.0).
Solution: don’t pin IDF 6 for BLE builds — use the recommended toolchain:
esp32: framework: type: esp-idf version: recommended # IDF 5.5.4 — builds cca_source: ble cleanlyIDF 6 is not required for BLE. If you specifically need IDF 6 and BLE, it is
blocked until ESPHome adds bt to the BLE component’s REQUIRES upstream; stay
on recommended in the meantime. (The non-BLE IDF-6 build path is unaffected —
see boards/test-idf6-tigomonitor.yaml.)
Reset Commands
Section titled “Reset Commands”Reset Node Table
Section titled “Reset Node Table”Clears all device mappings:
button: - platform: tigo_monitor name: "Reset Node Table" tigo_monitor_id: tigo_hub button_type: reset_node_tableForce CCA Re-sync
Section titled “Force CCA Re-sync”button: - platform: tigo_monitor name: "Sync from CCA" tigo_monitor_id: tigo_hub button_type: sync_from_ccaLog Messages Reference
Section titled “Log Messages Reference”| Message | Meaning |
|---|---|
Frame 27 received |
Long address discovery (16-char barcode) |
New device discovered |
First power data from device |
Assigned sensor index X |
Device mapped to sensor slot |
Energy data saved at hour boundary |
Hourly persistence complete |
No Frame 27 long address available |
Device found, waiting for barcode |
node table is full |
Increase number_of_devices |
Maximum number of devices reached |
At configured limit |
CCA Sync complete |
Successfully synced with CCA |
Packet missed! |
UART frame loss (add ISR to IRAM) |
Getting Help
Section titled “Getting Help”- Check ESPHome logs for error messages
- Review the Diagnostics view for memory info
- Search existing GitHub issues
- Open a new issue with:
- ESPHome version
- Hardware (board, PSRAM)
- Relevant log output
- Configuration (sanitized)
See also: Wiring · UART Optimization · Configuration · ← Back to README