emontx: firmware flashing for the emonTx6 / emonPi3 over UART (design question before a PR) #3905
Unanswered
Frédéric Metrich (FredM67)
asked this question in
Component enhancements
Replies: 1 comment
|
🏷️ I've automatically added the |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Component name
emontx
Link to component documentation on our website
https://esphome.io/components/sensor/emontx/
Describe the enhancement
I would like your opinion on the design before I open a pull request.
Background
The emonTx6 and emonPi3 from OpenEnergyMonitor are standalone energy monitors built around a
SAMD21 microcontroller, with their own firmware (emon32-fw).
An ESP32 add-on board (emonWiFi) talks to them over UART. The
emontxcomponent, already inESPHome, reads their data and sends them commands. It also supports older models (emonTx4,
emonTx5) that run other firmware.
Each emonWiFi is dedicated to exactly one emonTx or emonPi, and one Home Assistant installation can
have several of them.
Firmware updates of the SAMD21 normally need a USB cable. With the SAM-BA bootloader over UART
(installed once by USB), the ESP32 can flash it instead. This works today in external components,
and a Home Assistant integration (HACS, ha-emon-config)
gives users a panel to configure the device and update its firmware.
What exists today
Two components, kept outside ESPHome (about 920 lines). Both have been tested on hardware,
including a full flash.
emontx_updater(ESP32 only):flash_emontx6(url)service withCustomAPIDevice::register_serviceesp_http_client, following GitHub's redirects by handoften not available on a fragmented heap. The current app image in that partition stays
intact, and the OTA update lock (esphome#20588) stops an ESPHome OTA from overwriting it
emontx, sends the firmware's "enter bootloader" commands, then writes the flash withSAM-BA word writes and NVM commands (as BOSSA does), in a FreeRTOS task. A flash takes about
45 s
esphome.emontx_flash_statusevents withfire_homeassistant_eventbootloader_timeout,verify_ssl,dry_runemontx_ha_bridge(all models):send_command(command)serviceesphome.emontx_rawevent, and every JSONframe as
esphome.emontx_jsonSetup for users today:
plus
http_request:, andcustom_services: trueandhomeassistant_services: trueunderapi:.Requirements
builds), and the switch back to the USB bootloader; progress and status messages; the checks
before entering the bootloader; the OTA lock; sending commands and receiving every line for the
configuration panel.
devices are not technical, so they should not have to copy YAML.
The Home Assistant panel can be rewritten as needed.
What we think may not fit upstream
CustomAPIDevice:register_serviceandfire_homeassistant_eventseem meant for externalcomponents and lambdas. No in-tree component uses them, and they require
custom_servicesandhomeassistant_servicesunderapi:.std::map<std::string, std::string>on the heap.http_requestand usesesp_http_clientdirectly. It also blocks themain loop for about 2.5 s.
Options for flashing
A. Keep the service and the events (
CustomAPIDevice)Setup stays exactly as today:
emontx_updater:. The panel does not change. The code would becleaned up (no heap-built event data where avoidable, download in the flash task).
B. Standard entities
An
updateplatform ofemontx, structured likeesp32_hosted/update:vcommand, already inemontx), latest release (from GitHub), Install button and progress bar, all native in HomeAssistant.
release. This covers older releases, custom builds and the USB bootloader switch.
The panel would follow these entities instead of the events. Ideally the platform creates both
extra entities by default, so the lines above stay the whole setup. We found no in-tree component
that creates entities the user did not list, hence question 2 below.
Options for sending commands and receiving lines
The panel sends commands (
l,k1 ...) and needs every line the device sends back. Reading theconfiguration is a burst of about 50 lines.
A. Keep the service and the events (
CustomAPIDevice)As today:
emontx_ha_bridge:, or the same feature as an option ofemontx.B. Entities
A text entity for the command and a text sensor for the last line. We see two problems: the
bursts would fill Home Assistant's history, and Home Assistant ignores a new state that is the same
as the previous one, so a repeated line would be lost.
C. A YAML package
The same service and events, built from
api: actions:,emontx.send_command, theon_datatrigger and
homeassistant.event. It only uses existing building blocks, but users would have toadd a
packages:entry that points to a file in another repository, which we would like to avoid.Questions
CustomAPIDeviceacceptable in an in-tree component for this use? If yes, option A forboth parts keeps everything as it is today.
its "Firmware URL" and "Flash status" entities by default?
task (about 45 s)?
dry_runstay? It is mostly useful while testing a new setup.In any case
http_requestif it handles the GitHub redirects with buffers small enough forthe ESP32-C3 (8 KB or more crashed its Wi-Fi driver during the download); otherwise keep
esp_http_clientand explain why. Run the download in the flash task.Next steps
The working version stays on its current branch. Once the design is agreed, the work is done on a
new branch based on
dev, tested on hardware with the updated Home Assistant panel, and submittedas one pull request per component.
Use cases
updating without a USB cable when the device is in a meter cabinet; installing a new release (for example v1.2.0 with automatic calibration) or going back to an older one; custom builds; switching back to the USB bootloader; configuring the device from the Home Assistant panel
Anything else?
OpenEnergyMonitor docs,
ha-emon-config repo
All reactions