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

I’m tearing my (little remaining!) hair out trying to get values displayed on a thermostat page I’m building (based on one from a link many posts above I’ve since forgotten, sorry). I have a home page with a link to my thermostat page which has various values including target and actual temperatures. When I tap this link, it goes to the thermostat page but only shows the Nextion construction page without the temperatures filled in. I’ve tried various methods I can think of to trigger a script to update these values all to no avail. I thought by having a “hidden” button (2x2, bottom right out of sight) that I could emulate by click id,event (in my case, click 17,1) in the page preinitialize or postinitialize events. But I don’t see anything back in my yamal.

Unfortunately, I’m not very familiar with Nextion nor yaml. Any suggestions for where I’m going wrong? Thanks

hello PedroKTFC

I did it like this:

1 - create a sensor (inside esphome) that collects the heating value at that moment:

example:

#DINING ROOM TEMPERATURE

  • platform: home assistant
    id: dining_temperature
    entity_id: sensor.temperature_dining_room_heating

Create the button you have on the nextion screen and tell it that when you RELEASE (it didn’t work for me when pressed) write the value of the previous sensor in the text field:

  • platform: nextion
    name: NS-CO - Time Button
    page_id: 0
    component_id: 4
    on_release:
    then:
    - wait_until:
    switch.is_on: nextion_init
    - lambda: id(disp1).set_component_text_printf(“time.t1”, “%.1f”, id(dining_temperature).state);

time = (page)
t1= (text)
“%.1f” = make it float
id(dining_temperature).state = state of the previously created sensor
page ID = page where the button is
component_id: id of the button you press to go to the page
the sensor id: it is the id in home assistant

don’t forget, in nextion editor, on the button you use to go to the page “click” on “send id”

I’m sorry but I’m new to forums and I don’t know how to put the code in “squares” like my peers

I hope it helps you

1 Like

I don’t know how to put the code in “squares” like my peers

To format a block as code on the forums you can use one of these options:

  • mark the code block with three backticks ``` (just left of the 1 key on US keyboard layout) before AND after the relevant text; or
  • select the text and then use the </> icon (near the middle of the top row of icons in the editor) to mark it as a code block (it will insert the backticks for you, same as above); or
  • indent each line by 4 spaces.

There is a helpful page on formatting posts on the HA forums.

Hi everyone
I need a original tft file for US version of NS Panel. Is anybody have a link to it? Try to find on discord but only EU version is come up
Thank you in advance

Thanks but this is only updating a single field. I want to update all the fields on my page as they aren’t set on its display.

What I’ve done (for now) is have a timer that goes off every second and calls a script to update the fields in the page (see below). For multiple pages I’ll need a script for each page. The code I’m using is below:

time:
  ## Time component that fetches time from Home Assistant and updates the display once a second
  - platform: homeassistant
    id: homeassistant_time
    on_time:
      - seconds: /1 
        then:
          - script.execute: refresh
#          - logger.log: "**** On time run"
          - lambda: 'id(disp1).set_component_text_printf("time", "%02i:%02i", id(homeassistant_time).now().hour, id(homeassistant_time).now().minute);'
          - lambda: 'id(disp1).set_component_text_printf("date", "%i/%02i/%02i", id(homeassistant_time).now().day_of_month, id(homeassistant_time).now().month, id(homeassistant_time).now().year);'

Hopefully I can replace this once I have found out how to detect a page’s display. And If I can work out which page is on display, I can run only the script relevant for that display. Moreover, if I can work out if my display dim=0, I can skip all scripts until dim>0!

1 Like

You can use this to detect the current page (the variable dp is the displayed page in nextion):

sensor:
  - platform: nextion
    id: disp1_current_page
    variable_name: dp
    update_interval: 1s

I believe the same would work for the dim variable as well.

2 Likes

hello PedroKTFC

yes, it was just an example field… if you have 10 fields, then multiply that code by 10, (that’s how I do it)

1 Like

Thanks for the suggestion but I can’t see how to use the variable dp. I’m just trying to log the page as an initial trial but I never get the a page number. My “code” is:

  - platform: nextion
    id: disp1_current_page
    variable_name: dp
    update_interval: 1s
    on_value:
      then:
        - logger.log: 
            format: "**** GAPS **** Sensor current page %i"
            args: ['dp']

What Am I doing wrong?

Hi all,

I have the NS-panel working fine, but what I want to do, is to let the buzzer play something when the doorbell button is pushed. I have noticed I can send a json command to the NS-panel…but I have no idea what I should do there :slight_smile:

dp is the variable inside Nextion, not in ESPHome
I did not test this, but it should would similar to this:

sensor:
  - platform: nextion
    id: disp1_current_page
    variable_name: dp
    update_interval: 1s
    on_value:
      if:
        condition: 
          lambda: 'return id(disp1_current_page).state == "0";'
        then:
          - update thing for page 0
      if:
        condition: 
          lambda: 'return id(disp1_current_page).state == "1";'
        then:
          - update thing for page 1

Thanks denes44. Although that wasn’t quite correct, it put me on the right track. The following is the syntax that seems to work:

  - platform: nextion
    id: disp1_current_page
    variable_name: dp
    update_interval: 1s
    on_value:
      if:
        condition: 
          lambda: 'return x == 4;'
        then:
          - logger.log: "**** GAPS **** Sensor current page 4"
          - script.execute: refresh
        else:
          if:
            condition: 
              lambda: 'return x == 0;'
            then:
              - logger.log: "**** GAPS **** Sensor current page 0"

Simply changing your ==“4” to ==4 worked but I then got errors in my logs. Using x solved that for some reason. This will actually do in my case as I “park” at an empty page (id=2) when the screen blanks so updates will then stop.

Can you point me at documentation that explains this and will help me in the future? I prefer to have a better understanding so I can resolve future issues myself.
Thanks again.

Yes, it’s easier to use ‘x’. Inside the definition of a component, you can use the variable x inside lambdas to access the value of the component.

You can check here which automation you can use for number components, and read here about all the things you can use inside automations.
And this is the instruction set of the Nextion displays, you can see here which variables are available.

1 Like

I have the same problem. My NSpanel now is showing “System Data Error!”. This happened after a tft upload through home assistant. Is there any idea on how to recover. I tried using masto’s basic configration with no success. I have not tried flashing tasmota. Is there any other solution I could try?

Any suggestions about this? I would use this as a ringer for my doorbell

If you flashed with ESPHome look for the service play_rtttl in the developer. This sends a command to play sounds using the onboard buzzer.

I have flashed with ESPHome, but can’t find play_rtttl in the developer :slight_smile:

Just thought I’d update on my “long press” approach I talked about a little earlier in case it’s useful to anyone. Quick bit of background. I have two cases where I want to use a long press:

  1. I have hot water tank that is controlled by a ZigBee switch. I want to be able to switch it on and off from my NSPanel. As I don’t want it inadvertently controlled, a long press should switch it on and a double-tap switch it off (on my phone the HA app has a dialogue for this where it asks “Are you sure” with an OK or Cancel).
  2. For my ZigBee lights I want to be switch them on and off using a normal tap while a long press should bring up a page that allows the user to change the brightness and/or colour temperature.

My solution for the hot water is two-fold. The simple part is in my nspanel yaml:

  - platform: nextion
    name: $device_name Hot water boost
    page_id: 0
    component_id: 2
    on_multi_click:
      - timing:
          - ON for at least 2s
        then:
          - rtttl.play: "twobits:d=4,o=0,b=6000:a0"
    on_double_click:
      then:
        - homeassistant.service:
            service: switch.turn_off
            data:
              entity_id: $Boiler_entity_id

Note the use of the on_multi_click instruction to simply check for a long press. For my hot water I actually use Node Red to turn the switch on as I want it to be a boost that automatically switches off after 30 minutes. Hence all the long press in the yaml here does is bleep after 2 seconds.

For the ZigBee lights the on_multi_click goes to the right page for each light while an on_click toggles their state.

As it happens for my ZigBee lights I actually use the physical switches on the nspanel as they are used a lot so I want it to be as quick and easy for someone to switch them on and off.

1 Like

It was the same for me after I wanted to upload a TFT with ESPHome, while the display had the original stock TFT.
I did the first TFT upload with tasmota, then changed to ESPHome, and everything is working now wonderfully.

Does your esphome yaml code have api: and services: defined if not I would look at some of the example code provided by @chrismasto or @marcfarger on their githubs. Both available in this thread and show how to correctly call the service with the ringtone string that will play the onboard buzzer.

Updated with example from @marcfarger code on his github: This wil create a service on HA that can be called:

api:

  services:
    # Service to play a rtttl tone
    - service: play_rtttl
      variables:
        song_str: string
      then:
        - rtttl.play:
            rtttl: !lambda 'return song_str;'

Call the service with the data being the rtttl ringtone string. Again I would recommend you take a look at the yaml from @marcfarger which has more information than I have given.

I think you have to use an action in Esphome to play rtttl,.look in the esphome docs it has an example