Skip to main content

Sonoff NSPanel in Home Assistant: eWeLink, ESPHome and NSPanel Easy

The Sonoff NSPanel EU represents a smart control panel with an integrated touch display at a very reasonable price.

Sonoff NSPanel EU, Gray

  • WiFi
  • Bluetooth

Specifications

  • Display: 3.5" Nextion Discovery NX4832F035, 480x320, capacitive touch
  • Buttons: 2x physical buttons below display
  • Relays: 2x relay for 240V (officially rated 2 A per channel)
  • Sensors: NTC temperature sensor
  • Connectivity: Wi-Fi 2.4GHz
  • Chip: ESP32-D0WD-V3, 4 MB flash
  • Dimensions: 8.6 x 8.6 x 4.2 cm
  • Color: Gray / White
Currently not available for purchase in this country

Out of the box, the device comes with firmware that uses the eWeLink cloud service. Adding the NSPanel is done through the eWeLink mobile app. After pairing, the panel shows a user interface as seen in the image above.

Download on Google PlayDownload on the App Store

With the stock firmware, you can control relays directly with the bottom buttons, view internal temperature from the panel's sensor, and see outdoor weather information, which updates quite sporadically (seemed like 4 times a day to me).

You can add control of other devices added to eWeLink, but you cannot control devices outside this cloud, which is the biggest drawback for me.

eWeLink can be further integrated with Google Assistant, Alexa, SmartThings, or Philips Hue - the basic foundation of today's systems. Additionally, there's a Home Assistant integration SonoffLAN, which you can install from HACS.

Open your Home Assistant instance and open a repository inside the Home Assistant Community Store.

Thanks to this integration, you'll have the ability to control both relays in Home Assistant, read temperature information, and see a few other details.

  • ✅ Control relays directly from the panel
  • ✅ Display temperature from internal sensor
  • ✅ View basic weather information
  • ✅ Add other eWeLink devices

What you CANNOT do

  • ❌ Control devices outside eWeLink cloud
  • ❌ Deep Home Assistant integration
  • ❌ Custom UI or scenes
  • ❌ Offline functionality during internet outage

Alternative Firmware

Since the NSPanel contains an ESP32 chip, several alternative firmware options have emerged that expand its capabilities and overcome the limitations of the original eWeLink firmware. Let's look at the most significant ones.

July 2026 update: development has moved to NSPanel Easy

Until now, this article taught you how to install NSPanel_HA_Blueprint. Its main developer has since moved development into his own project, NSPanel Easy, and the original repository now only receives critical fixes. I've therefore rewritten the guide around NSPanel Easy - and below I explain why this isn't a gamble on some unknown fork.

Already running the old project? How to move across without opening the panel is covered in migrating to NSPanel Easy.

Updated 27 July 2026. The installation procedure from 25 July still stands - the hardware, the serial flash and the bootloader mode don't change between the projects. See exactly what changed

NSPanelManager

url: github.com/NSPManager/NSPanelManager

Key Features

  • Allows loading entities from Home Assistant and OpenHAB, expanding smart home control possibilities.
  • Can function standalone without needing to connect to other systems.
  • Great emphasis on easy configuration through web interface, enabling intuitive panel function setup.
  • Support for connecting multiple NSPanels together for synchronized control.

Who is it for

  • Ideal for users who don't need complex integration with Home Assistant or other smart home systems.
  • Suitable for those who prefer simple solutions with basic customization options.

NSPanelManager

nspanel-lovelace-ui (Tasmota)

url: github.com/joBr99/nspanel-lovelace-ui

Key Features

  • Uses Tasmota as base firmware, ensuring stability and flexibility when communicating via MQTT.
  • Offers a user interface inspired by Home Assistant's Lovelace UI – allows displaying and controlling a wide range of devices (lights, sensors, thermostats, alarms).
  • Configuration is done via YAML files, providing a high degree of customization without needing to modify source code.
  • Localization support for over 30 languages ensures availability for users worldwide.

Who is it for

  • For advanced Home Assistant users who want to fully customize the appearance and functions of NSPanel.
  • Ideal for those with YAML configuration experience looking for a flexible solution.

nsppanel-lovelace-ui

NSPanel Easy (ESPHome)

url: github.com/edwardtfn/NSPanel-Easy · docs: edwardtfn.github.io/NSPanel-Easy

Key Features

  • Built on ESPHome, which is now part of the Home Assistant team – guarantees deep integration and long-term support.
  • Offers direct Home Assistant integration without needing external tools or services.
  • Simple setup via a Blueprint in Home Assistant – configuration happens directly in the system's user interface.
  • The panel's language is set with a single substitution in the ESPHome YAML, and only the strings for that one language get compiled into the firmware.
  • The firmware can upload the TFT to the display on its own once it detects a version mismatch at boot.
  • Boot memory is actively managed - API actions most people never call are not registered by default.
  • A Bluetooth Proxy for BLE sensors is technically possible, but I don't recommend it on this panel - I explain why under Advanced Features.

Who is it for

  • For Home Assistant users looking for easy setup and deep NSPanel integration into their system.
  • For anyone setting up an NSPanel from scratch today - this is where development continues.
  • For those running Blackymas/NSPanel_HA_Blueprint who want to stay with the project that still gets new features.

NSPanel Easy

NSPanel_HA_Blueprint - the original project, now in critical-fixes-only mode

url: github.com/Blackymas/NSPanel_HA_Blueprint

This is the project this article was built on for years, and I want to explain the situation properly - because at first glance it looks like "the author is sending me off to some random fork", and that's not what's happening.

NSPanel Easy was written by the very same person who wrote most of NSPanel_HA_Blueprint. In the Blackymas/NSPanel_HA_Blueprint repository, edwardtfn has 3,113 commits, while Blackymas has 494. He was the main developer, not an occasional contributor, and in January 2026 he moved development into his own repository, where he has control over the project's architecture.

He announced it himself in the original repo, in issue #3277 "Transitioning Development to NSPanel Easy" dated 17 April 2026:

I'll continue fixing showstoppers here — things like compilation failures from upstream ESPHome or Home Assistant changes that would completely break the build.

Please read that exactly as written: new features, ordinary bugs and enhancements go to NSPanel Easy, while the original repo only deals with things that would break the build outright. No formal end-of-support date has been announced, the project hasn't "died", and nobody said it ends on some given date. That said, the last commit to the code (as opposed to the README) is from 17 April 2026, and the last released version is v2026041 - exactly the one this article was pinned to until now.

What this means for you:

  • Running NSPanel_HA_Blueprint and it works? No need to rush. You'll still get critical fixes, and your panel won't stop working overnight.
  • Setting a panel up from scratch today? Go straight to NSPanel Easy so you don't have to do it twice.
  • Want new features, or chasing a bug? It gets fixed in NSPanel Easy, not here.

The migration is surprisingly gentle, by the way - it's an OTA update, you don't open the panel, and your automation settings carry over. The whole procedure is in a separate article, From NSPanel_HA_Blueprint to NSPanel Easy.

Which variant to choose?

Each of these firmware options has its advantages. If you're unsure, here's a quick summary:

  • NSPanelManager - simple installation, works even without Home Assistant
  • nspanel-lovelace-ui - maximum control via YAML, requires advanced knowledge
  • NSPanel Easy - best Home Assistant integration, and where the original NSPanel_HA_Blueprint development moved
  • NSPanel_HA_Blueprint - the original project NSPanel Easy is derived from; critical fixes only these days
My recommendation

In this article, we'll focus on NSPanel Easy (ESPHome), which I now consider the best solution for most Home Assistant users. It offers easy installation, deep integration, and above all it's where development moved from the original NSPanel_HA_Blueprint - same main developer, same configuration structure.

Until April 2026, the recommendation here was Blackymas/NSPanel_HA_Blueprint. If that's what you're running, your panel keeps working and there's nothing you have to do right now - just be aware that new things now land elsewhere.

Sonoff NSPanel EU, Gray

  • WiFi
  • Bluetooth
Currently not available for purchase in this country

Sonoff NSPanel EU, White

  • WiFi
  • Bluetooth
Currently not available for purchase in this country

CP2102 USB 2.0 to TTL UART Module

  • USB
Currently not available for purchase in this country

What's Inside - Hardware and GPIO Pinout

Before we get to flashing, it helps to know what's actually inside the panel. The following overview is based on the detailed teardown by blakadder and you'll appreciate it most if you want to write your own ESPHome or Tasmota configuration.

Heading straight for flashing?

If the hardware doesn't interest you, skip ahead to What You'll Need.

Main Components

  • ESP32-D0WD-V3 - dual-core chip with Wi-Fi and Bluetooth, 4 MB flash memory (GigaDevice on my unit, the teardown lists Winbond - it varies by production batch)
  • Nextion Discovery NX4832F035 - 3.5" display with 480x320 resolution and capacitive touch (CST340 controller)
  • STM32G031G8 - a separate microcontroller that handles the display graphics
  • NTC thermistor MF52A - 10 kΩ ±1%, B = 3950 - the panel's temperature sensor
  • 2x relay on a separate board
Why firmware is uploaded twice

The display has its own processor (STM32G031G8) and keeps the entire graphical interface in its own memory. The ESP32 only talks to it over a serial line, sending events like "a button was pressed" or "change this text". That's exactly why firmware is uploaded in two stages - once to the ESP32 (ESPHome) and once to the display (the .tft file).

Pinout and GPIO Mapping

FunctionGPIOBoard label
Button 1 (left)GPIO14K1
Button 2 (right)GPIO27K2
Relay 1GPIO22RY1
Relay 2GPIO19RY2
Relay 3GPIO23RY3 - unpopulated
Display - RX on the ESP32 sideGPIO17TF_RX
Display - TX on the ESP32 sideGPIO16TF_TX
Display resetGPIO4T_RST
Temperature sensorGPIO38NTC
Light sensorGPIO37ALS - unpopulated
BuzzerGPIO21BZ
Serial line (flashing)GPIO3 / GPIO1U0RXD / U0TXD

The TF_RX and TF_TX labels on the board are from the ESP32's point of view. In ESPHome that translates to tx_pin: 16, rx_pin: 17 and a baud rate of 115200.

When you'll actually need this table

If you're using a ready-made solution (NSPanel Easy or a Tasmota template), the project has the pins configured for you and you won't need this table. It's for those of you writing your own YAML configuration from scratch, or debugging why something isn't responding. Also keep in mind that GPIO5, GPIO9 and GPIO18 are occupied by the PSRAM - don't use them for your own peripherals.

How much PSRAM is in the panel

ESPHome prints it at boot: [C][psram:020]: Size: 2048 KB, so 2 MB, of which typically only a few percent gets used. The blakadder teardown says "16MB PSRAM" - most likely 16 Mbit, which is exactly 2 MB, so the two figures don't actually disagree.

Watch out for one trap: the compile output says SPI DRAM ... from 4194304 bytes, which is the size of the address window, not the chip. The runtime figure is the authoritative one.

More important than the size is one limitation: Wi-Fi buffers must be DMA-capable and on the ESP32 they cannot live in PSRAM. Free PSRAM therefore won't help you when the panel runs short of internal DRAM. I go through the practical consequences in When the NSPanel won't boot after an update.

40 kB of IRAM for free - but only if your own log says so

ESPHome may print this line at boot:

[W][app:198]: Bootloader supports SRAM1 as IRAM (+40KB). Set sram1_as_iram: true under esp32 > framework > advanced

If it does, one option in Step 2 buys you 40 kB of IRAM:

esp32:
framework:
advanced:
sram1_as_iram: true

It reclaims memory the bootloader had reserved as DRAM and hands it to the application as IRAM instead. It costs you nothing in free heap or DRAM, because that memory was never part of the heap in the first place. On top of that it widens the flash cache window for XIP, so there are fewer cache misses and all code running from flash - Wi-Fi, BLE and the API server included - performs better. It also helps against "IRAM overflow" compile errors (section '.iram0.text' will not fit in region 'iram0_0_seg'). Whether you need that second part at all is something to check in the summary at the end of the build - look for the IRAM line in it. My panel reports IRAM 84,263 B (48.98%), 87,769 B left out of 172,032 B, so it still has half the room to the ceiling, which leaves it only the wider flash cache window out of the whole benefit. This is valid only on the original ESP32 and only with the ESP-IDF framework - the NSPanel, with its ESP32-D0WD-V3 and esp-idf, meets both, and the default is false.

One thing must not get lost, though: this is IRAM, not DRAM. It does nothing for the internal-DRAM squeeze described just above and dissected in the post-mortem.

And the risk here is every bit as large as the benefit. The option requires a bootloader from ESP-IDF v5.1 or newer, and OTA updates do not touch the bootloader - only flashing over USB or the serial line rewrites it. With an older bootloader the device will not boot at all, and only a serial reflash brings it back. On a panel sealed into a wall that means taking it down and opening it up.

So stick to the rule that verifies itself: enable it only when that [W][app:198] line is actually in your own log. ESPHome prints it precisely when it detects a compatible bootloader on your device. If you don't see it there, leave sram1_as_iram alone.

The relays are 10 A parts, but load them with 2 A max

The relays on the board are physically rated for 10 A, yet Sonoff officially specifies the panel for 2 A per channel and 4 A in total. For LED lighting the limit is stricter still - 300 W per channel and 600 W in total (at 230 V). The reason most likely lies in the PCB design and heat dissipation inside a closed wall box. Stick to 2 A (roughly 460 W of resistive load at 230 V) and use a contactor or a separate relay for heavier appliances.

What's Missing in the NSPanel and Why Humidity Doesn't Work

When designing the panel, Sonoff clearly planned for more features than ended up in mass production:

  • The humidity reading is fabricated. The panel reports humidity in eWeLink, but there is no sensor in it at all - position H2 on the board was left empty and the firmware simply reports a hard-coded 50%. If that value struck you as suspiciously stable, now you know why.
  • The buzzer (BZ, GPIO21), on the other hand, is populated. Blakadder's teardown lists it as missing, but on regularly sold units you'll find it next to the B1 silkscreen (it's visible on the board photo further down). The Tasmota template accounts for it too, and in ESPHome you can drive it through the rtttl component - the panel can then beep on a button press or play a simple melody as a notification.
  • The third relay (RY3, GPIO23) is missing. The relay board has a prepared position for a third unit driven from GPIO23. It's most likely a leftover from an earlier revision of the design.
  • The ambient light sensor (ALS, GPIO37) only exists on paper. The pin carries that label on the board, but no light-sensitive component is fitted and neither the stock firmware, nor Tasmota, nor any of the ESPHome projects work with it. To dim the display according to ambient light, you'll need a different sensor in Home Assistant or the sun's position instead. A real light sensor only arrived with the higher-end NSPanel Pro, where Sonoff advertises it as one of the new features.
Soldering inside a 230 V device

Adding the third relay means working inside a device connected to 230 V mains and, of course, voiding your warranty. If you're not one hundred percent sure what you're doing, leave it alone. And if you do go for it, keep the panel disconnected from mains the entire time.

What You'll Need

Before we begin the installation, prepare the following:

Hardware

  • Sonoff NSPanel (obviously 😊)
  • USB-TTL adapter with CP2102 or CH340 chip (see below)
  • Jumper wires Female-to-Female type (minimum 5)
  • Nothing else - power comes straight from the adapter, no external supply needed

Software

  • Installed Home Assistant with ESPHome addon
  • Computer with web browser (Chrome or Edge - for Web Serial API)

Sonoff NSPanel EU, Gray

  • WiFi
  • Bluetooth
Currently not available for purchase in this country

CP2102 USB 2.0 to TTL UART Module

  • USB
Currently not available for purchase in this country

Dupont cables 10cm / 20cm / 30cm - male / female

Currently not available for purchase in this country
tip

If you don't have ESPHome installed yet, check out my article about ESPHome.

Safety First!

Before any manipulation with the panel, disconnect 230V power! We're working with 3.3V logic, but safety first.

Preparing NSPanel for Flashing

Before we upload the new firmware, we need to open the NSPanel and connect a USB-TTL adapter. Don't worry, it's not as complicated as it sounds.

Opening the Panel

  1. Unclip the panel from the mounting base
  2. Unscrew 2 screws at the bottom of the plastic cover
  3. Lift the plastic cover
  4. You'll find a 5-pin header for serial communication labeled 3V3, RX, TX, GND, IO0
The IO0 Pin

For the data transfer itself, 3 pins are sufficient (RX, TX, GND). You'll need the IO0 pin (GPIO0) to switch the chip into boot mode - connect it to GND and only then apply power (see the step below). NSPanel Manager's documentation confirms this too.

Take power from the +5V pin, not 3V3. Both work for the flash itself - flashing doesn't draw much current. The difference shows up afterwards: on +5V the panel boots normally once the firmware is written, whereas on 3V3 it will keep restarting, because that pin sits behind the adapter's tiny regulator and can't feed Wi-Fi starting up. You don't need an external supply for any of this.

Connecting to USB-TTL Adapter

Pinout NSPanel

Connect the cables as follows:

NSPanelUSB-TTL Adapter
TXRX
RXTX
GNDGND
5V+5V

Take power from the adapter's +5V pin. The 3V3 pin is also enough to flash, but the panel won't boot on it afterwards - see above.

Watch the Crossover!

TX from the panel goes to RX on the adapter and vice versa!

Mind the Display's Metal Shield

The display's metal shield sits right next to the serial header and the pins can easily short against it. If you solder a permanent header into the panel, cover its underside with electrical tape. With temporarily held DuPont connectors, at least make sure they don't touch the shield.

Entering Bootloader Mode

An ESP32 enters firmware download mode when GPIO0 is pulled to ground as power is applied. On the NSPanel board it's broken out as IO0, right there on the five-pin header.

  1. Disconnect the NSPanel from power (both 230 V and the USB-TTL adapter)
  2. Connect IO0 to GND - with a wire, a jumper, or simply hold it there
  3. Apply power (plug the USB-TTL adapter into your computer)
  4. You can then remove the short

The panel is now in bootloader mode and ready for firmware upload. You'll know it worked when esptool or the web flashing tool connects to it.

Correction: boot mode is entered via IO0, not the button

Many guides (and earlier versions of this article) claim it's enough to hold the left button below the display while powering up. Don't believe it. The NSPanel's buttons are on GPIO14 and GPIO27, so they have nothing to do with GPIO0 and won't put the chip into boot mode. I wasted plenty of time on this before reaching for IO0.

Corrected 25 July 2026, see the change log. NSPanel Manager's documentation confirms it too.

Installing ESPHome Firmware

Verified with these versions

Verified on 27 July 2026 with ESPHome 2026.7.2 (ESP-IDF v5.5.5) and NSPanel Easy v2026.7.1.

Let me be honest about one thing: I have this combination verified from a migration off Blackymas/NSPanel_HA_Blueprint, not from a clean from-scratch install on an untouched panel. The serial flash, the bootloader mode and the whole hardware part of the procedure don't change between the two projects, though - that part is verified from the original installation on 25 July 2026. What changes is the contents of the YAML configuration and the names of a few controls in Home Assistant.

NSPanel Easy polices its own minimum ESPHome version: it's declared in the firmware and checked at compile time, so too-old ESPHome gives you a clear error rather than something cryptic. For v2026.7.1 that minimum is 2026.5.0. The project's general rule is that it targets Home Assistant and ESPHome versions released no more than two months before the given NSPanel Easy release.

How much RAM the compile needs

The project recommends 4 GB of RAM for ESPHome running as a Home Assistant add-on - on a Raspberry Pi that means a Pi 4 with 4 GB as the minimum. A manual ESPHome installation on a computer gets by with 2 GB plus 500 MB of swap. With less, the compiler crashes. If your compile dies for no apparent reason, look here rather than in your configuration.

The order of steps matters here. Prepare the configuration first, flash second - otherwise you'd end up flashing the panel twice.

It's four steps plus reassembly:

  1. Create the device in ESPHome (don't install firmware yet)
  2. Paste the YAML configuration with the NSPanel Easy package
  3. Compile and download the .factory.bin
  4. Flash over the serial line
  5. Reassemble, connect to 230 V and add to Home Assistant

Step 1: Create the device in ESPHome

  1. In Home Assistant, open the ESPHome Device Builder add-on
  2. Click + New DeviceContinue
  3. Name the device, for example nspanel01
  4. Pick ESP32 and click Skip - we're not installing firmware yet
  5. Click the newly created device and choose Edit

Step 2: YAML configuration with the NSPanel Easy package

Delete the entire contents of the editor and paste this. This is the part most guides (including earlier versions of this one) leave out - and without it the panel will have no display controls and none of the Blueprint's entities:

api:
encryption:
key: !secret api_encryption_key

substitutions:
device_name: "nspanel01"
friendly_name: "NS Panel"
wifi_ssid: !secret wifi_ssid
wifi_password: !secret wifi_password
ota_password: !secret ota_password
language: en # language code - full list in the project docs
boot_sound: false
upload_tft_automatically: true

# Safe mode counter in RTC memory - a power cycle wipes it
safe_mode:
storage: rtc

packages:
remote_package:
url: https://github.com/edwardtfn/NSPanel-Easy
ref: v2026.7.1 # pinned tag, not 'latest'
refresh: never
files:
- nspanel_esphome.yaml
The language is set here now, not in the Blueprint

The language: substitution is new in NSPanel Easy - with NSPanel_HA_Blueprint you picked the language in the Blueprint. Only the strings for that one language get compiled into the firmware, which saves memory and lets the panel show correct text even while offline. Leave the substitution out and the panel falls back to English. The full list of codes is in the Localization docs.

After changing the language you have to recompile and flash - saving the file isn't enough.

Optional add-ons

This is the minimal working configuration. The project offers add-on modules on top of it, added as further entries under files:. Careful: the add-ons live in the esphome/ subfolder, while the base nspanel_esphome.yaml stays at the root - that's the single most common source of errors when coming from the older project.

files:
- nspanel_esphome.yaml # base package - NO esphome/ prefix
# Display as a light in HA (dimmable from automations)
- esphome/nspanel_esphome_addon_display_light.yaml
# Thermostat driving heating through a relay
# - esphome/nspanel_esphome_addon_climate_heat.yaml
# - esphome/nspanel_esphome_addon_climate_cool.yaml
# - esphome/nspanel_esphome_addon_climate_dual.yaml
# - esphome/nspanel_esphome_addon_cover.yaml

I use the first one myself. The climate add-ons additionally want the heater_relay: "1" and cooler_relay: "2" substitutions (which relay heats and which cools). The full list is in the project's documentation - but every add-on grows the firmware, so check your memory usage at compile time after adding one.

The !secret values must exist in your secrets.yaml (Secrets in the bottom left of ESPHome). Generate api_encryption_key from the ESPHome docs or any 32-byte base64 key generator.

Two things in that config the project docs don't mention

The api: encryption: block and safe_mode: storage: rtc are my own additions - you won't find them in the official template. The first encrypts communication with Home Assistant, the second saves you a serial cable should the panel ever latch into safe mode - I explain that further down under The NSPanel is black, not on Wi-Fi, and reflashing doesn't help. I'd keep both.

Conversely, ota_password in NSPanel Easy is separate and optional. With NSPanel_HA_Blueprint it was derived from the Wi-Fi password, so if you're migrating a panel wirelessly you need ota_password: ${wifi_password} there for that first OTA. On a clean install over serial you can pick whatever you like.

Why a pinned version instead of ref: latest

Here I deliberately depart from the official NSPanel Easy documentation, which recommends ref: latest with refresh: 300s. Let me explain why.

latest is a moving tag - it always points at the newest release. Together with refresh: 300s that means the package is re-fetched on every recompile, and if a new version has landed in the meantime, you get it without asking. That's exactly the pattern that once put my panel out of action for 42 hours (back then in the ref: main variant). The gap between "a new version exists" and "a new version is on my panel" should be your decision, not a matter of when you happened to click Install.

With ref: v2026.7.1 and refresh: never you update deliberately: you look at what's new and change one number. Current releases are on the releases page - the project ships frequently, and roughly monthly over the past few months. Since the new repository it uses the v2026.7.1 scheme (it used to be v2026041).

One more note on that scheme, because it's easy to misread: the last number isn't a patch level, it's the release's sequence within the month. So v2026.5.15 is the fifteenth May release, not "patch 15" of some 2026.5 version. That also shows just how often the project shipped early on - April 2026 saw 28 releases, June only two.

One exception: if you're migrating a panel off Blackymas/NSPanel_HA_Blueprint, the project's migration guide wants ref: latest for that first install during the migration. A specific tag can be used afterwards. On a clean from-scratch install you don't have this problem and can pin the version right away.

Hidden Wi-Fi network

If your SSID is hidden, add this as well, or the panel will take a long time to connect - or never will:

wifi:
fast_connect: true

Step 3: Compile and download the factory.bin

  1. Click Save, then Install
  2. Choose Manual download
  3. Let it compile - the first time takes up to ten minutes
  4. When prompted, download the .factory.bin (not the plain .bin, which is for OTA and won't boot from a serial flash)
Check your memory figures

The compile prints memory usage at the end. If you're above 90% Flash or have less than ~50 kB of free DRAM, you're on the edge and the next update may tip you over. The most common culprit is bluetooth_proxy - I explain why I don't recommend it on the panel further down.

Step 4: Flash over the serial line

The panel must be in bootloader mode and powered from the adapter's +5V pin. A flash from 3V3 would also succeed, but the panel wouldn't boot afterwards.

  1. In Chrome or Edge, open web.esphome.io
  2. Connect → pick your USB-TTL adapter
  3. Install → select the downloaded .factory.bin
  4. Let it upload, it takes about a minute

If you prefer the command line, use esptool:

esptool --port /dev/cu.usbserial-0001 --baud 460800 write-flash 0x0 nspanel01.factory.bin
The adapter doesn't show up

Check that the panel is in bootloader mode (IO0 to GND before applying power) and that TX and RX are crossed over. The browser must be Chrome or Edge, because of the Web Serial API.

Step 5: First boot

  1. Disconnect the USB-TTL adapter, every wire
  2. Reassemble the NSPanel
  3. Connect it to 230 V
  4. The panel boots and joins Wi-Fi

NSPanel after first boot

Never both at once

The panel on 230 V while the USB-TTL adapter is plugged into your computer is the combination that costs you the adapter, the USB port, or more. One at a time, always.

Integrating into Home Assistant

Automatic Detection

Home Assistant should find the NSPanel by itself after the first boot:

  1. Open SettingsDevices & Services
  2. nspanel01 should appear under Discovered
  3. Click Configure
  4. Paste the api_encryption_key from your secrets.yaml
  5. Confirm

Manual Addition

If automatic detection doesn't work:

  1. SettingsDevices & ServicesAdd Integration
  2. Search for ESPHome
  3. Enter the panel's IP address and port 6053
How to find the IP address

Quickest in your router's DHCP table. Alternatively in the panel's ESPHome log - the [C][wifi:1259]: IP Address: line.

The Blueprint entities are missing in Home Assistant

Check this, because every step that follows depends on it. The device page must show the diagnostic entities Version - ESPHome, Version - Blueprint and Version - TFT, plus the Display model and Update TFT display controls under Configuration.

If they're missing, the panel isn't running the NSPanel Easy configuration - most often because the generic "prepare for first use" firmware got flashed instead of the one from step 3. You can confirm it in the log, which must name the project:

[I][app:153]: Project edwardtfn.NSPanel-Easy version "2026.7.1"
The control got renamed

With NSPanel_HA_Blueprint the model selector was called Update TFT display - Model; in NSPanel Easy it's simply Display model. If you're following an older guide and looking for the old name, you won't find it - and nothing is actually wrong.

Uploading TFT Firmware for the Display

The NSPanel display (Nextion) has its own firmware that needs to be uploaded separately. In NSPanel Easy this process is significantly simpler - and on a first install you mostly don't have to deal with it at all.

Automatic Upload (Recommended)

With the upload_tft_automatically: true substitution from Step 2, the firmware uploads the TFT by itself: after boot it compares the TFT version in the display against what it expects, and starts the transfer when they don't match. All you need to do is select the right model and wait.

  1. Open your NSPanel's page in Home Assistant (Settings → Devices & Services → ESPHome)
  2. In the Configuration section, you'll find two controls:
    • "Display model" - expand and select your model. Note there are five options in that dropdown, not three:
      • NSpanel EU - for European model (the default)
      • NSpanel US - for American model (portrait)
      • NSpanel US Landscape - for American model in landscape orientation
      • NSpanel Blank - a minimal TFT showing a QR code, not meant for normal use; it's there to clear the display before uploading the real file (see troubleshooting)
      • NSpanel Easy EU (Under construction) - the new design still under development; don't pick it for normal use
    • "Update TFT display" - press this if you don't want to wait for the automatic upload
  3. ESPHome will automatically download the correct TFT file from GitHub and start uploading to the display
  4. A progress bar with a black background will appear on the display
  5. Transfer takes 10-20 minutes

The Display model selector does two jobs at once, by the way - besides picking the file, it also configures the panel's runtime behaviour (touch calibration, button layout, display orientation). So always keep it set to whatever you physically have on the wall.

Don't be fooled by the "NSpanel Easy EU" option

This is an easy trap to fall into precisely because you're installing NSPanel Easy: the dropdown holds an option literally named NSpanel Easy EU, and reaching for it feels like the obvious move. But it's a new display design still under development, not "the TFT for NSPanel Easy" - hence the "(Under construction)". It would upload nspanel_easy_landscape.tft, which is 3.3 MB against the 13 MB of a finished file, and the panel wouldn't be usable.

For a European panel, pick NSpanel EU even though you're installing NSPanel Easy.

The CJK variants are gone

With NSPanel_HA_Blueprint there were separate TFT files marked (CJK languages) for Chinese, Japanese and Korean. In NSPanel Easy those character sets are built into the standard TFT files and the separate variants have disappeared - just pick the model that matches your hardware, whatever language you use.

Automatic Download

ESPHome automatically selects the correct TFT file version based on your chosen model and downloads it directly from the project's repository. You don't need to download anything manually!

If Transfer Doesn't Start

On the very first boot it's normal for the log to repeat [W][nextion:xxx]: Not connected for a while - the firmware is probing for the right baud rate on the serial line to the display, and Sonoff's stock firmware uses a different one. This can take a couple of minutes.

After that, ESPHome will automatically retry several times with different parameters. If it still doesn't work — or if the transfer fails even from a local folder — there's a dedicated section walking through the causes.

Manual Upload (Only if Automatic Fails)

If automatic upload repeatedly fails, you can host the TFT yourself. NSPanel Easy offers two substitutions for that, and it matters a lot which one you pick:

  • nextion_update_base_url - overrides only the server address the files come from. Automatic model and version selection stays in effect, which is usually what you want for local hosting.
  • nextion_update_url - a full override. When set, it bypasses the model selector and the entire version logic, and that one URL is used as-is. Keeping a compatible, up-to-date file behind it is then your responsibility.

The full-override procedure:

  1. Download the correct TFT file from the hmi/ folder in the repository at the version tag you have pinned
    • For EU model: nspanel_landscape.tft
    • For US model (portrait): nspanel_portrait.tft
  2. Upload the file to a local HTTP server (e.g., to /config/www/ folder in Home Assistant)
  3. In your ESPHome configuration, add it to the substitutions: block (not at the root - it's a substitution):
    substitutions:
    # ... the other values from Step 2
    nextion_update_url: "http://homeassistant.local:8123/local/nspanel_landscape.tft"
  4. Compile, flash over OTA and press the "Update TFT display" button
There's no "Use nextion_update_url" option in the selector any more

With NSPanel_HA_Blueprint you activated nextion_update_url by picking a dedicated "Use nextion_update_url" option in the model selector. That option doesn't exist in NSPanel Easy - the substitution takes effect automatically as soon as it's non-empty. So leave the Display model selector on your actual model, because touch calibration and button layout are still driven by it.

And if you only used nextion_update_url to pick the model (which the old project allowed), remove it - the selector handles the model on its own now.

Configuration Using Blueprint

Now comes the best part - setting up what will be displayed on the panel!

Installing the Blueprint

In NSPanel Easy the Blueprint is called nspanel_easy_blueprint.yaml (it was nspanel_blueprint.yaml in the old project) and is imported from a different address.

  1. Open this link: NSPanel Easy Blueprint
  2. Or use the button:
Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.
Why latest is fine here after I warned you off it in Step 2

Did you spot it? That address contains refs/tags/latest - the very same moving tag I avoided for the ESPHome configuration. This isn't inconsistency; there's a real difference.

With the firmware, the problem is that the package is re-fetched on every recompile - so you get a new version as a side effect of clicking Install for some entirely unrelated reason. A Blueprint, by contrast, never updates itself. Re-importing it in Home Assistant is something you have to ask for explicitly, so it's always a deliberate step and a moving tag breaks nothing. It also matches how the project sets source_url inside the Blueprint itself.

A version mismatch won't stay hidden either: the firmware carries a min_blueprint_version (2026.5.15 in v2026.7.1) and checks the Blueprint version reported by Home Assistant at boot. If the Blueprint is too old, you'll hear about it - and you can see the state in the Version - Blueprint entity.

The language isn't set here any more

The most noticeable change against NSPanel_HA_Blueprint: there's no language option in the Blueprint. It's set with the language: substitution in the ESPHome YAML, see Step 2. The Localization section in the Blueprint is still there, but it now only deals with date, time and unit formats (temperature unit, decimal separator and compact unit display).

If your panel speaks English after the migration, this is why - and it isn't fixed in the Blueprint, but by recompiling the firmware.

Creating an Automation

  1. Go to SettingsAutomations & ScenesBlueprints
  2. Find NSPanel Easy Configuration and click it
  3. Fill in:
    • NSPanel device (REQUIRED): pick your panel's ESPHome device
    • Weather and temperature: the weather and temperature entities (the panel's internal sensor or an external one)
  4. Save it and give the automation a name so you can tell your panels apart later
One panel, one automation

Never assign the same panel to two automations. Home Assistant does nothing to stop you, but the panel then behaves unpredictably and it puts needless load on your Wi-Fi and on Home Assistant itself. With multiple panels, create a separate automation for each.

Adding Pages and Controls

The rest of the Blueprint is a long list of collapsed sections that configure the whole panel. The most important ones:

  • Home page - Entities states and Home page - Custom buttons - what's visible on the main screen
  • Button pages 01-04 - up to four pages of buttons; for each button you pick the entity, name, icon, colour, and optionally a confirmation dialog or a custom action
  • Entities pages 01-04 - up to four pages listing entities
  • Chips - small status icons in the top bar
  • Climate page, Water heater page, Utilities page, QR code
  • Hardware buttons - what the two physical buttons below the display should do
  • Screensaver, Media player, Notifications, Localization (date, time and unit formats), Advanced settings

It's all point-and-click in the user interface; you don't have to write any YAML.

NSPanel Pages

Automatic Type Detection

The Blueprint automatically detects the entity type (light, switch, cover) and displays the appropriate controls.

Advanced Features

Bluetooth Proxy - and why I don't recommend it

Technically the NSPanel can work as a Bluetooth proxy. Add bluetooth_proxy: to your configuration and BLE devices within range of the panel show up in Home Assistant.

This is a feature I changed my mind about after learning the hard way.

Bluetooth costs you half your free memory

I compiled the same configuration twice, the only difference being bluetooth_proxy:. The result:

with bluetooth_proxywithout
Flash1,529,391 B (83.3%)1,110,539 B (60.5%)
Total internal DRAM pool124,580 B180,736 B
Free internal DRAM55,228 B123,352 B

The middle row is the important one. The BLE controller carves its memory out of the total pool at link time - it isn't merely a matter of consumption. Free internal DRAM drops to less than half, and PSRAM won't save you because Wi-Fi buffers have to be DMA-capable.

My panel ran on those 55 kB for six months. Then one ESPHome update grew the firmware slightly, the headroom vanished, and the panel ended up black and unreachable. I walk through that whole diagnosis in When the NSPanel won't boot after an update.

The project documentation warns about this too, and quite precisely:

During Startup: If your device runs out of memory at startup, it may not load the firmware, resulting in a black screen and an unresponsive device.

The original project also removed the Bluetooth Proxy add-on as a breaking change (issue #2669) and its documentation page now contains a single sentence: "This add-on has been removed." The history of related problems is long - #2168 "Enabled active bluetooth proxy bricks devices", #1815 "TFT Update Fails if Bluetooth Proxy is enabled" and others.

NSPanel Easy actively manages boot memory - and it still changes nothing here

This one pleased me, because it independently confirms what I worked out during my own diagnosis. NSPanel Easy has a whole documentation section called Reducing Registered API Actions, and it contains this sentence:

Each API action registered by ESPHome consumes heap memory at boot. On memory-constrained configurations — such as those running Bluetooth Proxy — this can cause boot instability or crashes.

That's why the upload_tft and wake_up API actions are excluded by default - most people never call them from automations, and registering them eats heap at boot for nothing. You get them back with the include_action_upload_tft: true and include_action_wake_up: true substitutions.

It's the right move and it hands you back a few kilobytes. It doesn't change my recommendation, though, for a simple reason: the BLE controller carves its memory out of the total pool at link time, long before anything cares how many API actions are registered. You will not recover the 56 kB from the table above by registering zero API actions. Saving on the firmware side helps you alongside Bluetooth, not instead of it.

Recommendation: put the Bluetooth proxy on a separate ESP32. A board costing under four euros plugged into a USB charger has all its memory to itself, and you can flash ready-made firmware through the ESPHome web installer without writing any YAML. You also get to place the proxy where BLE coverage needs it, rather than where your wall switch happens to be. More detail in the Bluetooth Proxy article.

Custom TFT Design

If you enjoy customization, you can create your own display design:

  1. Download Nextion Editor
  2. Modify the HMI file according to your preferences
  3. Compile to TFT
  4. Upload to the panel
Advanced Users Only

Requires knowledge of the Nextion platform, not for beginners.

Monitoring Display Communication

On the board you'll find test pads labeled TF_RX and TF_TX. With a logic analyzer or a second USB-TTL adapter you can tap into the communication between the ESP32 and the display. This comes in handy when debugging your own TFT design and you need to see what commands the display actually receives.

Troubleshooting

I ran into a few problems during installation that may happen to you as well:

The compile fails with an error

A few error messages you may run into, and what usually sits behind them:

MessageCause
region 'dram0_0_seg' overflowed by N bytes
.dram0.bss will not fit in region
You don't fit in memory. Most often because of bluetooth_proxy - see the warning below. Strip components until it passes
Component not found: nextion_update_urlYou put it at the root of the configuration, but it's a substitution - it belongs in the substitutions: block
Couldn't find ID 'wifi_component' and similar unknown-ID errorsThe project package is missing, or you pulled it from a different version. Check the packages: block from Step 2
Errors that appeared "by themselves" after a recompileYou're pulling the package from a moving tag (ref: latest, or ref: main), so the version changed under you. Pin a specific tag as shown in Step 2
A file in packages: can't be found (404, Failed to load, an empty package)The classic when switching to NSPanel Easy: add-ons belong in the esphome/ subfolder, but the base nspanel_esphome.yaml belongs at the root. Check that you have esphome/nspanel_esphome_addon_...yaml with the prefix and nspanel_esphome.yaml without it
ESPHome version too old / a demand for a higher min_versionNSPanel Easy polices its minimum ESPHome version itself and tells you which one it wants. For v2026.7.1 it's 2026.5.0. Update the ESPHome add-on
Check your ESPHome version

NSPanel Easy has its minimum ESPHome version declared in the firmware and checked at compile time - for v2026.7.1 that's 2026.5.0, and anything older gives you a clear error rather than something cryptic. The project's general rule is that it targets Home Assistant and ESPHome versions released no more than two months before the given NSPanel Easy release.

Nobody polices an upper bound, though, so with an ESPHome much newer than what the firmware was tested against you can end up in a combination nobody has tried - which is exactly what's described here.

The NSPanel won't enter bootloader mode

  • Connect IO0 to GND and only then apply power. Holding the left button doesn't work - the buttons are on GPIO14 and GPIO27, not GPIO0
  • Make sure the short is in place throughout power-up, not applied afterwards
  • Try a different USB-TTL adapter or a different USB port

The NSPanel reboots every second in a boot loop and the log shows rst:0x1

The code rst:0x1 (POWERON_RESET) means the chip genuinely lost power, not that software crashed. A firmware crash would show rst:0xc (SW_CPU_RESET) and a Guru Meditation Error.

The most common cause is powering the panel from the 3V3 pin on the USB-TTL adapter. That pin comes from a tiny regulator on the adapter board good for maybe 50–100 mA. That's enough to flash - which is the treacherous part - but Wi-Fi starting up asks for many times that and the supply collapses, so the flash succeeds and the panel then restarts.

  • Move the power lead to the adapter's +5V pin, which comes essentially straight from USB VBUS
  • The panel converts those 5 V with its own regulator, which is rated for the job
  • On a 500 mA USB port it can be tight - a USB 3.0 port helps

I walked into this trap myself and it manufactured a false diagnosis - see the post-mortem.

The NSPanel is black, not on Wi-Fi, and reflashing doesn't help

Check the serial log for this:

[C][safe_mode:189]: Unsuccessful boot attempts: 10
[E][safe_mode:201]: Boot loop detected

The panel is stuck in safe mode, where ESPHome starts neither the display nor anything from the panel configuration - a black screen is expected in that state. And it's a trap, because on the ESP32 the failed-boot counter is stored in flash (NVS), so it survives a power cycle.

The insidious part is that factory.bin does not overwrite it. The NVS partition sits at 0x390000, the factory image is written from 0x0 and covers only the bootloader, the partition table and app0. Reflashing therefore leaves the counter alone.

The fix is to erase the entire flash:

esptool --port /dev/cu.usbserial-0001 erase-flash
esptool --port /dev/cu.usbserial-0001 --baud 460800 write-flash 0x0 nspanel01.factory.bin

Find your port per platform: on macOS /dev/cu.usbserial-* (not tty., which can block waiting for DCD and hang esptool), on Linux /dev/ttyUSB0, on Windows COM3. With an older esptool install, use esptool.py and erase_flash with an underscore.

Your Wi-Fi credentials are compiled into the firmware, so you lose nothing.

Why a factory image can't do this - and how I found out - is covered in the post-mortem.

So it doesn't happen again

Add this to your configuration:

safe_mode:
storage: rtc

The counter moves to RTC memory, which a power cycle wipes. Safe mode stays available as a safety net, but the panel can never latch into it permanently, and unplugging it replaces the whole serial-cable exercise.

The panel takes a long time to join Wi-Fi, or never joins

If you run a hidden SSID, look for these two lines in the log:

[W][wifi:1603]: 'my-iot-network' should be marked hidden
[W][wifi:1480]: No networks found

ESPHome can't find a hidden network by scanning and has to fall back to its hidden-network path. The fix is to skip scanning altogether:

wifi:
fast_connect: true

The panel then connects straight to the first configured network. For a fixed installation that will talk to the same AP for its whole life, you lose nothing. The link between a hidden SSID and an ESPHome crash is covered in the post-mortem.

Why not hidden: true

ESPHome does have a hidden option, but it is only valid inside networks:, not in the top-level wifi:. And with NSPanel Easy you can't set it (nor with NSPanel_HA_Blueprint, where this mechanism comes from) - ESPHome merges lists from packages by concatenation (old + new), so you'd end up with a second network entry with no SSID and the configuration would fail validation. Use fast_connect.

The NSPanel randomly reboots while flashing, or won't connect at all

  • The most common cause is a short against the display's metal shield right next to the serial header - check that no pin touches it and cover it with electrical tape if needed
  • Verify that TX and RX are crossed over (panel TX to adapter RX and vice versa)

The TFT upload won't start, won't finish, or fails even from a local folder

This is the single most common NSPanel problem, and surprisingly few things cause it. One important clue: if it fails even from a local folder, the problem isn't the download - and hunting for a different web server won't help.

Try the blank TFT file first

Most of these problems come down to the Nextion display's Active Reparse Mode. It's enabled on panels that ran the stock Sonoff firmware or nspanel-lovelace-ui, and in that mode the display rejects a normal upload regardless of where the file comes from.

Installing any TFT from this project disables it - but a regular file is over 13 MB, which the ESP32 struggles with. The project therefore ships nspanel_blank.tft, just under 700 kB, whose only purpose is to turn Reparse Mode off. In NSPanel Easy you don't have to download it anywhere - it's an option right in the model selector:

  1. In the Display model selector, pick NSpanel Blank
  2. Press Update TFT display and let it finish - it's a small file, so it won't take long
  3. Only then switch the selector to your real model (NSpanel EU) and upload the proper TFT

Alternatively you can grab nspanel_blank.tft from the hmi/ folder in the repository and host it locally.

Coming from nspanel-lovelace-ui

If your panel ran nspanel-lovelace-ui, without this intermediate step you won't be able to install anything at all. The project's documentation lists it as a requirement, not a tip.

If that doesn't help, work through this in order

What to checkWhy
Do you have bluetooth_proxy or esp32_ble_tracker in your config? Remove them temporarilyThe TFT upload needs a chunk of RAM and won't get it with BLE. See the memory warning and issue #1815
Hosting from /config/www/? Did you restart Home Assistant?Without a restart that folder isn't served at /local/. This is the most common reason "the local folder doesn't work"
Are you using http:// rather than https://?HTTPS is problematic for the ESP and transfers fail on it
Is there an IP address in the URL instead of homeassistant.local?DNS and mDNS are a frequent source of trouble. Use http://192.168.x.x:8123/local/…
Did you give the panel a manual IP? Add a DNS serverWithout DNS it can't download from GitHub. Either add DNS or host locally
Did you start the transfer too soon after boot?The display doesn't connect to ESPHome immediately. Wait up to two minutes for the boot script to finish
File size - download the .tft with the exact same URL to your computer and compare against GitHubIt's easy to end up saving an HTML page instead of the file. That "uploads" and then fails
Disconnect power, wait 30 seconds, power back onReturns both display and ESP to a clean state
Are you on the esp-idf framework?arduino has long been deprecated and unsupported (since v4.3.22 of the original project). NSPanel Easy builds on esp-idf and doesn't support any other framework - switching to arduino is technically still possible, but the docs themselves label it unmaintained. Its transfer engine behaves differently and HTTPS on it tends to be unstable
Stuck on a repeating [W][nextion:xxx]: Not connected?The firmware is probing for the display's baud rate, which takes a while on the first boot. If it never gets past that, add the include_button_scan_baud_rate: true substitution - you'll get a Scan baud rate diagnostic button in Home Assistant that walks through every supported rate and then starts the transfer at the one that works
The panel doesn't respond during a transfer

Once a transfer has started, the panel often ignores the Restart button in Home Assistant and the fifteen-second button hold. Disconnecting power helps, as does the hardware reset button in the small hole on the back of the panel - reachable with a pin.

"System data ERROR!" or "Model does not match" on the display

It looks alarming, sometimes even upside-down, but it only means the TFT file is incomplete or invalid. A successful upload fixes it; the panel isn't damaged. For "Model does not match", a reboot is sometimes enough to restore the previous TFT.

The TFT controls aren't in Home Assistant at all

That's a different problem - the panel isn't running the NSPanel Easy configuration. See its own section. If you do have the configuration and the controls are still missing, remove the ESPHome integration, restart Home Assistant and add the device again.

The NSPanel didn't show up in Home Assistant after flashing

  • Check that the ESPHome integration is active
  • Restart Home Assistant
  • Try adding it manually via IP address and port 6053

The NSPanel shows a white display and nothing appears

  • During the TFT upload this is normal, just be patient
  • If it takes longer than 20 minutes, try restarting the panel

Evaluation

After several months of using NSPanel with ESPHome, I can say I'm very satisfied. Installation does require some technical knowledge and patience, but the result is worth it.

✅ Main Advantages

  • Complete control - no cloud dependency
  • Deep integration - everything from Home Assistant at your fingertips
  • Active community - regular updates and support
  • Great price/performance ratio - an amazing solution for well under €70
  • No cloud - keeps working even if the eWeLink servers disappear

⚠️ What Could Be Better

  • Display quality - average viewing angles, slightly faded colors
  • More complex installation - not for complete beginners
  • TFT upload - sometimes it's a bit of a lottery

Recommendation

I recommend NSPanel with ESPHome if you:

  • ✅ Use Home Assistant
  • ✅ Have basic technical knowledge
  • ✅ Don't want cloud solutions
  • ✅ Appreciate good value for money

I don't recommend if you:

  • ❌ Are a complete beginner
  • ❌ Want a plug-and-play solution
  • ❌ Require a premium display
Final Note

If you're looking for an intelligent control panel with a good price-to-performance ratio and don't want to be dependent on the cloud, NSPanel with ESPHome is an excellent choice. Installation isn't trivial, but thanks to this guide, anyone with some technical knowledge should be able to handle it.

Sonoff NSPanel EU, Gray

  • WiFi
  • Bluetooth
Currently not available for purchase in this country

Sonoff NSPanel EU, White

  • WiFi
  • Bluetooth
Currently not available for purchase in this country

CP2102 USB 2.0 to TTL UART Module

  • USB
Currently not available for purchase in this country

Sources

Did this guide help you?

I write these guides in my spare time and keep them up to date. If one saved you time, you can chip in.

One-off, by card or Apple Pay. You can change the amount on the next page.

Would rather not send money? Buy the parts through my product links. The price is the same for you and it helps too.

Comments