Commit 0669d4f
Feature: Support lilygo t can485 board (without PSRAM) (#44)
* fix(monitor): emit platform: tigo_monitor in generated sensor YAML
The "Generate YAML Config" button printed `- platform: tigo_server` for
every discovered device, but the sensor platform lives in
components/tigo_monitor/sensor.py and is named `tigo_monitor`. Pasting
the output verbatim failed config validation.
Barely noticeable on boards with the web UI, where the node table is a
page you can read. On a board without one, that button is the only
panel-discovery workflow there is, so its output has to paste in clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(monitor): skip the PSRAM probe when CONFIG_SPIRAM is unset
psram_malloc() called heap_caps_malloc(MALLOC_CAP_SPIRAM) on every
allocation and fell back to the internal heap when it failed. On a build
with no PSRAM that attempt can never succeed, so it ran on every single
allocation all day, and logged a "PSRAM unavailable" warning for anything
over 1KB.
Guard it on the IDF's CONFIG_SPIRAM, which is set only when PSRAM is
actually configured, and include sdkconfig.h explicitly so a silently
missing header cannot compile PSRAM out on boards that do have it. No
behaviour change where PSRAM exists.
Also reword the setup() logging: "No PSRAM detected" is no longer a
warning, because a sensors-only build without tigo_server is a supported
configuration, and the pre-allocated 16KB serial buffer is not a "PSRAM
buffer" on such a board.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* feat(boards): add LilyGO T-CAN485 for sensors-only builds
The T-CAN485 is a plain ESP32 with 4MB flash and no PSRAM. It cannot have
any: the board wires GPIO16/17 to its RS485 front end, which is exactly
where a WROVER's PSRAM would sit. It does carry an isolated MAX13487E
transceiver on GPIO21/22, which makes it a natural fit for a
Home-Assistant-only install.
PSRAM was never a requirement of tigo_monitor itself. The device and node
tables run roughly 600 bytes per optimizer, so 20 of them cost ~12KB of
the ~180-200KB an ESP32 has free once WiFi is up. It is tigo_server that
needs PSRAM, and it stays out of these configs.
esp32-lilygo-t-can485.yaml drives the three transceiver enable lines high
at boot (5V_EN, /RE, SHDN) as the MAX13487E datasheet requires, and
example-t-can485.yaml is ready to flash. Verified with esphome compile:
53% of a 1.75MB OTA slot, 15% static RAM, no warnings.
Note the MAX13487E has no DE pin, so unlike the MAX485 wiring in the docs
there is no way to strap this board driver-off in hardware. Read-only
rests on tigo_monitor having no UART write calls; the board file documents
that and how to harden it further.
This does not reopen the Config Builder to PSRAM-less boards. The builder
emits configs containing tigo_server, so its guard is unchanged and still
enforced by test.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* feat(boards): free 40KB IRAM and drop pre-3.1 workarounds on T-CAN485
Two ESP32-classic-only framework options for the T-CAN485:
sram1_as_iram hands the SRAM1 region — previously reserved as bootloader
DRAM — to IRAM, worth +40KB. That pairs directly with
CONFIG_UART_ISR_IN_IRAM, which spends IRAM to keep the UART ISR off flash
so Tigo frames are not dropped while flash is busy. This is where that
budget comes from.
minimum_chip_revision: '3.1' drops the IDF's workaround code for older
silicon bugs. Flash falls from 973,263 to 969,243 bytes; still 52.8% of
the 1.75MB OTA slot.
Both fail closed rather than degrading, so both are documented in the
board file and in boards/README.md:
- sram1_as_iram needs an ESP-IDF v5.1+ bootloader. A USB flash updates
the bootloader automatically, an OTA does not, so this board must be
flashed over USB the first time or it will not boot.
- the bootloader hard-checks the minimum revision; a chip older than
v3.1 halts at boot. The boot log prints the actual revision, and the
value needs lowering if it reports less.
Verified with esphome compile: CONFIG_ESP32_REV_MIN_FULL=301 and
CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM=y in the generated
sdkconfig, no warnings.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(monitor): AUTO_LOAD sensor, text_sensor and binary_sensor
tigo_monitor.h includes sensor.h, text_sensor.h and binary_sensor.h
unconditionally, unlike time/button which sit behind USE_TIME/USE_BUTTON.
ESPHome only copies a component's sources into the build when that
component appears in the config, so any hand-written YAML that did not
declare all three died at compile time:
tigo_monitor.h:8:10: fatal error:
esphome/components/text_sensor/text_sensor.h: No such file or directory
The fix was an empty `text_sensor:` stanza you had to already know to
write, and it was easy to miss because the error names only whichever
header the compiler reached first — adding one at a time just moves the
failure to the next line.
AUTO_LOAD pulls the three in whenever tigo_monitor is used, which is what
it is for. This loads ESPHome's core sensor/text_sensor/binary_sensor
components, not this package's same-named platform files; those still
load only when a `- platform: tigo_monitor` entry asks for them.
Verified by compiling a config with no text_sensor:/binary_sensor: keys —
it failed on the include before, and builds after. A config that does
declare them is unaffected: example-t-can485.yaml still produces a
byte-identical 969,243-byte image.
Also drops the now-obsolete instructions from the troubleshooting guide
and CLAUDE.md, and corrects the "required" comments on the test targets.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* docs(boards): wire CCA panel-name sync into the T-CAN485 example
The example shipped without any mention of cca_ip, which made it look as
though panel names needed the web server. They do not: cca_ip is already a
tigo_monitor option, and sync_from_cca() -> query_cca_config() ->
match_cca_to_uart() all live in tigo_monitor with no tigo_server
dependency. The HTTP read buffer goes through psram_malloc() and is 4KB,
with the response accumulator capped at 64KB, so it is comfortable on the
internal heap of a board with no PSRAM.
Adds the "Sync from CCA" button and a commented cca_ip block documenting
the endpoint (GET /cgi-bin/summary_config, Basic Tigo:$olar) and a curl
one-liner to verify it answers before enabling.
Also records what the BLE CCA bridge actually does, since the naming
invites the opposite assumption: it only issues DEVICE_PING and
DEVICE_INFO for the CCA Info page. match_cca_to_uart() has exactly one
caller, the HTTP handler, so BLE never contributes panel layout.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* tweaking
* Change upstream repo
* fix(t-can485): require chip rev 3.0, not 3.1, or ECO3 boards bootloop
minimum_chip_revision: '3.1' excluded every ESP32 ECO3 part — the common
revision — from a board config named after hardware people already own.
ESPHome sets CONFIG_ESP32_REV_MIN_* for the chosen revision and clears
the rest, so this is a hard floor enforced by the bootloader: it fails at
boot, not at build, and presents as an unexplained bootloop.
It bought nothing. Every revision-gated conditional in IDF 5.5.5 tests
CONFIG_ESP32_REV_MIN_FULL >= 300, which 3.0 satisfies; nothing in the
tree tests >= 301, and REV_MIN_3 and REV_MIN_3_1 select an identical
option set. Verified by building both: byte-for-byte identical output,
RAM 47792 and flash 856267 either way, with
CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM=y unaffected — the SRAM1
option depends only on !ESP32_TRAX and never on chip revision.
Also document in boards/README.md that the first flash must be over USB
(sram1_as_iram needs a v5.1+ bootloader and OTA does not update it; the
board file said so already, the board comparison table did not), and
soften the device-count claim to what was actually measured — 18 tested,
40 expected — noting the real ceiling on a PSRAM-less board is heap
fragmentation across many small per-device allocations, not total bytes.
Claude-Session: https://claude.ai/code/session_01RgSnMCa3JQigphGnPbazdw
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Andrew Rankin <andrew@eiknet.com>1 parent d790870 commit 0669d4f
11 files changed
Lines changed: 521 additions & 19 deletions
File tree
- boards
- components/tigo_monitor
- site/src/content/docs/guides
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
| |||
20 | 21 | | |
21 | 22 | | |
22 | 23 | | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
23 | 27 | | |
24 | 28 | | |
25 | 29 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
62 | 62 | | |
63 | 63 | | |
64 | 64 | | |
| 65 | + | |
| 66 | + | |
65 | 67 | | |
66 | 68 | | |
67 | 69 | | |
| |||
77 | 79 | | |
78 | 80 | | |
79 | 81 | | |
80 | | - | |
| 82 | + | |
81 | 83 | | |
82 | 84 | | |
83 | 85 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
6 | 10 | | |
7 | 11 | | |
8 | 12 | | |
| |||
26 | 30 | | |
27 | 31 | | |
28 | 32 | | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
29 | 69 | | |
30 | 70 | | |
31 | 71 | | |
| |||
47 | 87 | | |
48 | 88 | | |
49 | 89 | | |
50 | | - | |
| 90 | + | |
51 | 91 | | |
52 | 92 | | |
53 | 93 | | |
54 | 94 | | |
55 | | - | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
56 | 98 | | |
57 | 99 | | |
58 | 100 | | |
59 | 101 | | |
60 | 102 | | |
61 | | - | |
| 103 | + | |
62 | 104 | | |
63 | 105 | | |
64 | 106 | | |
| |||
0 commit comments