Sonoff NSPanel by ITead - Smart Scene Wall Switch based on ESP32 and custom Nextion Touch Screen Panel Display (non-Pro variant)

Here is my NSPanel. Graphics are not ready, but all works.

What do you think?

4 Likes

looking great… nice work…
i only hope that the Nextion Editor is going to be much easier to work with

I’ve just changed my sleep method to use the built in sleep instead of the button or the screensaver page. The big button was a pain when editing and the screensaver page only works if you have one page as far as I can see. If you’re on a different page, it’s always going to go back to the home screen. Not a big problem but I didn’t want to build in an issue.

So, I used the sleep method. It works fine apart form one thing. I have a motion sensor that switches the screen back on. In Node-RED, I have an nspanel_send_command with:

{"cmd":"click wake_button,0"}

That obviously won’t work now as the screen is asleep and won’t accept the command, and there is no button to click.

Does anyone know a way round this?

what if you would make a black screen as sleep screen, and whenever the Motion triggers you got the desired page, would that be a work around?!

Or maybe dim it to 0% and wake it up to full brightness in a lambda:

  • lambda: ‘id(disp1).set_backlight_brightness(x/100);’
    Something like this.

Or send a command sleep ==0 is wake up

  • lambda: ‘id(disp1).send_command_printf("%s", cmd.c_str());’

My take on the NSPanel plus me asking for some help…
I’ve tried to create something with the main purpose of easy control of lights in all rooms but with the possibility to go deeper into each room to control basically everything. Plus dynamic pages that pop up on special events: Knock on door, coffee brew, deactivate alarm…

Help is about the fact that I can’t add any more components to the code because that causes the ESP to not boot up. The code compiles and gets uploaded but it then just gets stuck with a flashing first page. Very annoying since I’ve come so far with the project. Flash memory is about 65% use but it feels like it has to much to initiate at boot up so it just gives up. Anyone has any ideas of what the root cause could be?

Code is uploaded on Github:
https://github.com/lillaeriika/NSPanel

7 Likes

Yes, I have also found it easiest just to use the built-in Nextion sleep command following the details on the topic in in the Nextion Instruction Set and the Nextion Sunday Blog series.

Some tips I’ve found on getting sleeping & waking to work properly:

  • Read the Nextion Instruction Set descriptions for System Variables ussp, thsp (currently not working on NSPanels), thup and usup, in particular taking note of setting thup=1 (to wake on touch) and usup=0 (to NOT wake on serial coms).
  • Even when the Nextion is in sleep mode with usup=0, it will wake by sending sleep=0ÿÿÿ (the ESPHome send_command() adds the ÿÿÿ termination to all Nextion Instructions for you). You just have to make sure you send that instruction first BEFORE you send the next commands you want to send, and include a short delay (to allow the Nextion to wake up).
  • There doesn’t seem to be a Nextion Event that you can use to reset things as the device wakes up. I’ve found it helps to set everything to be prepared for waking up (such as higher screen brightness etc.) immediately before calling sleep=1 in my Nextion Event code.
  • It helps if you have your own controlled way of putting the Nextion to sleep (rather than its internal time out settings or just sending sleep=1 from HA/ESPH) so as to ensure you have set it up to wake up in a controlled manner (given the previous point). (thsp isn’t working on NSPanels at the moment, but I don’t think I use it even it were - controlled sleeping is a better option.)

I have my own NSPanels working very well with sleeping (to black screen), progressive screen dimming while there is inaction, waking from sleep, and control of variable-speed update loops if you want to check out my HA Community posting or my code files on GitHub.

(edit)… and here is a motion automation to wake up the NSP from usup=0 sleep (I’ve edited in the notes about termination and the need for a delay I originally forgot to mention above):

# Wake NSP on motion
- alias: "Motion wake NSP1"
  trigger:
    - platform: state
      entity_id: binary_sensor.lounge_motion
      to: "on"
  condition:  # << Useful if you have a way to check the NSP isn't already in use
    - condition: state
      entity_id: sensor.nsp1_trigger
      state: "0.00"  # << indicates sleeping for Nextion Handler
  action:
    - service: esphome.nsp1_send_command
      data:
        cmd: sleep=0  #<< the ESPHome 'send_command()' will add the required termination string (0xFF, 0xFF, 0xFF = ÿÿÿ")
    - delay: 0.5  # <<<< note short delay to allow Nextion to wake up
    - service: esphome.nsp1_send_command
      data:
        cmd: page 0
1 Like

… and here is the Nextion Sunday Blog that covered sleeping that I referred to above (it took a bit of Googling to find it again)

and the Nextion Instruction Set is here - see notes on System Variables nos. 7, 8, 9 and particularly 17.

The EU model does not fit in the default 60mm flush-mounted box.

So i designed and 3D printed a surface mount enclosure what will fit on the 60mm flush-mounted box.

https://www.thingiverse.com/thing:5256325

2 Likes

Help is about the fact that I can’t add any more components to the code because that causes the ESP to not boot up.

I couldn’t find the HMI file on the GitHub link you posted (only the TFT) - did I miss something?
Without that the first suggestion would be to check the number of components you have (given it seemed you are dynamically cramming a lot of components into one page?), and if it exceeds the 250 limitation noted in the Nextion documentation:

There is a hard limit of 250 components allowed per page…

Why not make the box tilted if you 3d printed it?
Just having it 10-15% angle would make a more pleasant I believe.

Sorry I forgot to upload the HMI file. It’s up there now. It’s actually not that many buttons on the first page. It’s basically just what you see. Maybe 15 buttons. I dynamically change the value of the buttons though so there is a lot of code in the yaml file that executes on button presses or if a light is changed.

I don’t think the HMI file is the issue. I think it is quite small to what it could be. It’s as soon as i add code or components to the YAML file that the ESP stops booting. As I said when I go over the “limit” for what it can handle during boot it sometimes starts working if i just remove logging and try to reboot again. So I have a very strong feeling that the ESP has too much to handle in the yaml file during boot. Is there any way to sequence the boot process so it doesn’t try to do everything at the same time? Is there any settings connected to the boot process that could help me? I don’t know, I’m just guessing.

Edit: I’ve done some more investigation. Working theory right now is that I was using retained messages on my MQTT channels in Openhab. I thought that would be a good idea so a newly started panel would get the latest value on all components. But thinking about it I don’t think the ESP likes receiving data from 20 mqtt topics on boot plus a lot of code that is supposed to execute for each received message. At the same time it is trying to initialize every ESP component as well. Looks like I can add some more stuff for the moment at least.

1 Like

I’m having a real issue just getting the built-in sleep working. I’ve gone back to the simplest configuration I can imagine: 2 pages, each with different background colours so easily distinguishable, with a button on each which goes to the other page. I’ve tried to make the second page the start up page and the display to sleep after 15 seconds. This configuration works in the Nextion debugger prefectly but:

  • The start page is always the first (albeit with a cycle from the last to the first when I reload the tft file)
  • I sit and wait and wait but the screen never sleeps

My Program.s is trivial:

thsp=15  //Sleep after this many secs without touch
thup=1     //Enables(1) touch to wake device
ussp=15  //Sleep after this many secs without serial port activity
usup=0     //Disable(0) wake on serial data - NB*** will still wake if command string "sleep=1ÿÿÿ" is sent over serial
page Last   //Power on start page (255 = last page)

My nspanel.yaml is bare bones:

# Set some variables for convenience
substitutions:
  node_name: nspanel
  device_name: NSPanel

# Note: this may not be needed if the pull request has been merged.
# Check https://github.com/esphome/esphome/pull/2956 for current status.
external_components:
  - source: github://pr#2956
    components: [nextion]
    refresh: 1h

esphome:
  name: $node_name
  comment: $device_name

esp32:
  board: esp32dev

# Enable logging
logger:
  baud_rate: 0
  level: DEBUG
  logs:
    sensor: WARN
    resistance: WARN
    text_sensor: WARN
    ntc: WARN

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    password: !secret wifi_password

captive_portal:

# Enable wireless updates
ota:

# Enable Home Assistant API
api:
  services:
    # Service to upload the tft file
    - service: upload_tft
      then:
        - lambda: 'id(disp1)->upload_tft();'

switch:
  # Pin 4 always needs to be on to power up the display
  - platform: gpio
    id: screen_power
    entity_category: config
    pin:
      number: 4
      inverted: true
    restore_mode: ALWAYS_ON

# Configure UART for communicating with the screen
uart:
  id: tf_uart
  tx_pin: 16
  rx_pin: 17
  baud_rate: 115200

# Configure the screen itself
display:
  - platform: nextion
    id: disp1
    uart_id: tf_uart
    tft_url: http://192.168.x.y:8123/local/tft/nspanel.tft

Anyone else having a similar issue? Am I missing something?

Try a more controlled approach to sleeping (& waking) by setting sleep=1 in a timer (that will ultimately control a lot of the sequencing and scheduling of your code on the page - I call mine UPDATE_LOOP).
Start simply by adding a timer to your page and set its attributes (in the panel with the table of attributes for the selected component) e.g.,:
UPDATE_LOOP.tim 15000 (ms = the 15 secs you’re trying just to get going).
UPDATE_LOOP.en 1 (to make sure the timer is enabled and will start when you open the page).
Then in the ‘Event’ panel for the timer enter:
sleep=1
Check that this very basic set up works first (in the simulator, then on the physical device), and that it wakes up again on touch (with your thsp=1 setting) but does not wake from serial communications (with your usup=0, unless you send sleep=0).

If that all works properly, then add a variable with a counter to your loop, and only put the device to sleep when the counter crosses a trigger value.
Then you can start managing this timer control loop with events that change the counter and change the looping interval (*.tim) (and you can add more things into the loop that happen conditionally such as sleeping, dimming, getting data updates, managing the rate of data flow, applying data updates to UI attributes etc. as your project needs).

I’m sure there are other approaches, but this one is working well for me. (I found that if I didn’t control how the Nextion was put to sleep that I couldn’t control how it woke up again, which was giving me unpredictable and laggy responses after waking again).

1 Like

Thanks. I’m only just starting with Nextion so lots to learn (eg I was unaware of the sleep statement). I did want to use the built-in sleep settings but I’ve given up (for now).

I’ve got something working which seems to do what I want. When the timer expires, it takes the nspanel to a blank page with nothing on it. In this way, when it’s woken up by a touch event nothing is activated but it goes to the “home” page. The sequence is roughly as so:

  • I have a timer on my front page that when it expires sets sleep=1,page Blank and my timer’s .en attribute to 0.
  • On the blank page I have a TouchCap which:
    – for the touch press event wakes the screen with sleep=0
    – for the touch release event simply redirects to page Home
  • The Home page Postinitialize event sets my timer’s .en attribute to 1.

There are probably better ways of doing this so any recommendations welcome.

I’ve a couple of issues I’m wondering how to resolve:

  • Is there any way of setting the .tim attribute using a variable so I can change it universally (I’m anticipating having the same timer on every page and I don’t want to have to edit each one when I change it)?
  • I’m using the nspanel physical buttons to switch on/off some lights. At the moment these work with the display blank. I’d prefer that, if the screen is blank, pressing either of these buttons would activate the screen (as I have a visual indicator of the state of the lights) and then another press is needed to switch the light on/off. If the screen is active, then only a single press should be needed.

I followed your approach and interestingly, when sending the display to sleep with usup=0, I need to send sleep=0 in order to wake it (sleep=0ÿÿÿ doesn’t work).

Thank you for all the pointers btw!

I need to send sleep=0 in order to wake it (sleep=0ÿÿÿ doesn’t work).

Yes, if you are sending instructions via ESPHome’s Nextion send_command() or send_command_printf(), then it already adds the termination string required by the Nextion (hex: “0xFF, 0xFF, 0xFF” = print(“ÿÿÿ”)), so don’t add it again (as per the HA automation YAML example above - now edited to make that clearer). That goes for ALL Nextion Instructions being sent from ESPHome or Home Assistant, not just sleep.

I fear that I may have broken my NSPanel. I tried to implement a custom UI via ESPHome but now the screen is blank apart from the words System Data ERROR! Has anyone had any experience with this?

This should not be a problem, you should still be able to flash an UI / tft file.

System data Error - Unofficial Nextion/TJC User Forum

I tried flashing directly to the Screen from Nextion Editor and was not successful. I have not been able to resolve this yet and since there is no SD card access not sure how to fix yet. Mine does not connect to the Wifi. Might be bricked

It was the same for me as well. ESPHome always failed with the upload. It was not able to upload the TFT file to the display.
I had to change to Tasmota, which was able to do the upload.