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

Thought I’d share what I have added from @marcfager files. 20220109_024035_1_1

8 Likes

OK so I received the NS panel today and as expected the existing integration picks up and can control the 2 physical switches with no flashing needed. So far the only way I have been able to trigger a HA automation is by using a Sonoff switch or plug with nothing connected to it. The panel toggles that and then the HA automation runs based on the switch/plug state change. Works great but not ideal as you need a spare physical switch for each widget/automation, but it does work for anyone that doesn’t want to flash it just yet.

My NSPanel project deployed!

What code did you use?

I don’t use temperature but show CO2 and it updates when the HA entity updates.

Beautiful!! any chance you could share your files?? I simply love it.

  # Grab current temperature from Home Assistant
  - platform: homeassistant
    id: outside_temperature
    entity_id: sensor.garden_sensor_temperature
    attribute: temperature
    on_value:
      # Push it to the display
      then:
        - lambda: 'id(disp1).set_component_text_printf("tempoutside", "%.1f ""\xb0""C", id(outside_temperature).state);'

This is what I have now and that seems to be updating. This was already in there to update the current temp as measure by the panel but I’m not bothered by that at the moment so I just changed it to suit.

1 Like

It is a lot of work but it is comming along nicely :slight_smile:
Still need to create the weather screen but the icon on the main changes with the actual weather.
Also the home status icon is changing when the home status changes
Also need to make the page for the curtains
The announce screen you can push the button if the soup is ready and it announce over the google home speakers in the house,







The code can be found here on Github

12 Likes

Very nice work on all those buttons!

Have anybody set a slider? ex for led strip with brithness?

1 Like

Really useful!

Couple of questions…

1. If I run your HMI file through the debugger in the Nextion Editor, I can’t see how the buttons have “states” if they’re turned on and off. How are you handling that?

Sussed that one. Need to send the component ID on touch AND release.

  1. Extending Q1, what happens to a button if you change something outside your NSPanel? For example, if you set the home status to away through Home Assistant, how are you telling your panel to light up the image of the car?

So far, so good. This is my home screen. At the moment, it just controls three input_booleans, one for each mode the house might be in, in home assistant which are used for conditions in Node-RED. E.g. If motion is detected in the bedroom, switch the lights on unless “Night mode” is on. In HA, I have it so that only one of these can be on at any one time.

So I have the buttons on here controlling the input_booleans in HA fine. But if one gets changed in any other way then I can’t work out how to update the button states in Nextion.

  1. In the hmi editor you have the touch event and touch release event and you need to tick the box then it will send a command to esphome and this you can use.
    You need to make sure the page_id and component_id for your button
  - platform: nextion
    name: $device_name Thermostat up
    page_id: 6
    component_id: 9

This is done in the yaml code on the esp module.
If the status changes you call for another picture to be shown in that place

      int status_home=26; //home button on page home status
      if (id(home_status).state == "Thuis") {
        status_home=27;
      } else if (id(home_status).state == "Weg") {
        status_home=26;
      } else if (id(home_status).state == "Vakantie") {
        status_home=26;
      } else if (id(home_status).state == "Slapen") {
        status_home=26;
      }
      id(disp1).send_command_printf("home_status.home.pic=%i", status_home);
      id(disp1).send_command_printf("home_status.home.pic2=%i", status_home);
      
      int status_away=28; //away button on page home status
      if (id(home_status).state == "Thuis") {
        status_away=28;
      } else if (id(home_status).state == "Weg") {
        status_away=29;
      } else if (id(home_status).state == "Vakantie") {
        status_away=28;
      } else if (id(home_status).state == "Slapen") {
        status_away=28;
      }
      id(disp1).send_command_printf("home_status.away.pic=%i", status_away);     
      id(disp1).send_command_printf("home_status.away.pic2=%i", status_away);    
      
      int status_sleep=30; //sleep button on page home status
      if (id(home_status).state == "Thuis") {
        status_sleep=30;
      } else if (id(home_status).state == "Weg") {
        status_sleep=30;
      } else if (id(home_status).state == "Vakantie") {
        status_sleep=30;
      } else if (id(home_status).state == "Slapen") {
        status_sleep=31;
      }
      id(disp1).send_command_printf("home_status.slapen.pic=%i", status_sleep);      
      id(disp1).send_command_printf("home_status.slapen.pic2=%i", status_sleep); 
      
      int status_vacation=32; //vacation button on page home status
      if (id(home_status).state == "Thuis") {
        status_vacation=32;
      } else if (id(home_status).state == "Weg") {
        status_vacation=32;
      } else if (id(home_status).state == "Vakantie") {
        status_vacation=33;
      } else if (id(home_status).state == "Slapen") {
        status_vacation=32;
      }
      id(disp1).send_command_printf("home_status.vacation.pic=%i", status_vacation);       
      id(disp1).send_command_printf("home_status.vacation.pic2=%i", status_vacation);
2 Likes

Thank you! I think your reply crossed with my edit. I’ll give that a try for Q2 now.

This feels like a hacking session or design sprint at work :slight_smile:

I did see you did find the answer for the first question :+1:
I have been working on this all day good thing it was raining all day

1 Like

Yaml, HMI, tft and images available here

edit: update yaml to include @crlogic work on syncing states on display with home assistant

I think you could save a lot of time and effort. Might be too late. I’m using just 2 images of 480px x 320px for my panel. One has everything off, one has everything on.

Set the STA to “crop image”. When you set picc and picc2 on a button that is, say 100px x 100px then it will only visually change the 100 x 100 section like using the crop image. It would save you having to slice all your screens into little buttons and your code will always be the same. I’m just testing the theory so I could be wrong. That’s how it seems to be working for me though.

Off
Off

On
On


To read the input_booleans I use for the"house mode" in HA. I have 3 for day, evening and night which just change the behaviour of a load of Node-RED flows. Returns “on” of “off”:

#This is the first icon for sunrise
  - platform: homeassistant
    id: day_mode
    entity_id: input_boolean.day_mode

Then, under the display section:

# This section looks at the text sensor above (day_mode) and sets the images used for a button with the STA set to "crop image"  
    lambda: |-
      int status_day=0;
      if (id(day_mode).state == "off") {
        status_day=0;
      } else if (id(day_mode).state == "on") {
        status_day=1;
      }
      id(disp1).send_command_printf("page0.b0.picc=%i", status_day);
      id(disp1).send_command_printf("page0.b0.picc2=%i", status_day);

So, b0 is the button with the STA set to “crop image”. It’s 100px x 100px. I’m just using the 2 images above. off is image id 0. on is image id 1. When the state of an input_boolean changes to on, for example, the display just shows the 100px x 100px section from the “on” image making it look like only that image has changed.

I might be teaching everyone to suck eggs with this but, if I write it down, It’ll stick in my head. I’ve tested it on my live box and it seems to work. I’m loathe to do too much as it’s the middle of the night, If I mess up and the bedroom lights go on my other half will be in here VERY quickly to let me know :grinning_face_with_smiling_eyes:

1 Like

Has anyone gotten pages to work?

I have three pages defined in the Nextion Editor with page pagename defined in the “Touch Press Event”. This works in the debug simulator of the editor (gif below), but does nothing when uploaded to the NSPanel.
Nextion Pages

So I went looking through the docs and found it.goto_page("pagename");

Adding this to the yaml kinda works; it just goes to a phantom page, not the pages I defined. And only if I use a number, not a name.

  - platform: nextion
    name: $device_name page0_goto_alarm
    id: page0_goto_alarm
    page_id: 0
    component_id: 13
    internal: true
    on_press:
      then:
           # lambda: id(disp1).goto_page("pagealarm"); # does nothing
           lambda: id(disp1).goto_page("1"); # goes to phantom page

Here is the phantom page;
[edit] link https://photos.app.goo.gl/CWyp2HCRReHWZF16A

[edit] if you have read this far, disregard everything. I’m blind. Upload your tft to the correct path people. Or waste hours like me!

Hi Christopher,
I have received 2 weeks back several EU version of the NSPanels, as part of the kickstarter project.
I have followed in detail your [great] video, but I unfortunately cannot upload the TFT file into the NS-Panel…I am turning all possibilities since this morning and getting exhausted. The GPIO 16 and 17 (UART) seem to not connect the panel. Do you see anything wrong I could have done?
on 20:39:34 on this log, I am calling the upload_tft function.
The Nextion screen refuses to upload the new TFT from the internal UART of the Nspanel.

Esphome log extract is hereby:

20:39:27][D][text_sensor:067]: 'weather_symbol': Sending state 'rainy'
[20:39:27][W][nextion:078]: Nextion is not connected! 
[20:39:27][W][nextion:078]: Nextion is not connected! 
[20:39:28][W][nextion:078]: Nextion is not connected! 
[20:39:28][W][nextion:078]: Nextion is not connected! 
[20:39:29][W][nextion:078]: Nextion is not connected! 
[20:39:29][W][nextion:078]: Nextion is not connected! 
[20:39:30][W][nextion:078]: Nextion is not connected! 
[20:39:30][W][nextion:078]: Nextion is not connected! 
[20:39:31][W][nextion:078]: Nextion is not connected! 
[20:39:32][W][nextion:078]: Nextion is not connected! 
[20:39:32][W][nextion:078]: Nextion is not connected! 
[20:39:33][W][nextion:078]: Nextion is not connected! 
[20:39:33][W][nextion:078]: Nextion is not connected! 
[20:39:34][D][nextion_upload:169]: Connected
[20:39:34][D][nextion_upload:175]: Requesting URL: http://10.0.0.120:8123/local/hmi.tft
[20:39:34][D][nextion_upload:209]: Updating Nextion ...
[20:39:34][D][nextion_upload:235]: Waiting for upgrade response
[20:39:34][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:34][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:34][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:34][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:35][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:35][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:35][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:35][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:35][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:35][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:35][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:35][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:35][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:36][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:36][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:36][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:36][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:36][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:36][E][uart:015]: Reading from UART timed out at byte 0!
[20:39:36][D][nextion_upload:239]: Upgrade response is  19
[20:39:36][D][nextion_upload:242]: Available 0 : 0x00
[20:39:36][D][nextion_upload:242]: Available 1 : 0x00
[20:39:36][D][nextion_upload:242]: Available 2 : 0x00
[20:39:36][D][nextion_upload:242]: Available 3 : 0x00
[20:39:36][D][nextion_upload:242]: Available 4 : 0x00
[20:39:36][D][nextion_upload:242]: Available 5 : 0x00
[20:39:36][D][nextion_upload:242]: Available 6 : 0x00
[20:39:36][D][nextion_upload:242]: Available 7 : 0x00
[20:39:36][D][nextion_upload:242]: Available 8 : 0x00
[20:39:36][D][nextion_upload:242]: Available 9 : 0x00
[20:39:36][D][nextion_upload:242]: Available 10 : 0x00
[20:39:36][D][nextion_upload:242]: Available 11 : 0x00
[20:39:36][D][nextion_upload:242]: Available 12 : 0x00
[20:39:36][D][nextion_upload:242]: Available 13 : 0x00
[20:39:36][D][nextion_upload:242]: Available 14 : 0x00
[20:39:36][D][nextion_upload:242]: Available 15 : 0x00
[20:39:36][D][nextion_upload:242]: Available 16 : 0x00
[20:39:36][D][nextion_upload:242]: Available 17 : 0x00
[20:39:36][D][nextion_upload:242]: Available 18 : 0x00
[20:39:36][D][nextion_upload:248]: preparation for tft update failed 0 ""
[20:39:36][D][nextion_upload:324]: Restarting Nextion
[20:39:38][D][nextion_upload:327]: Restarting esphome
INFO nspanel.local: Error while reading incoming messages: Error while reading data: [Errno 104] Connection reset by peer
INFO Disconnected from ESPHome API for nspanel.local
WARNING Disconnected from API
INFO nspanel.local: Ping Failed: Error while reading data: [Errno 104] Connection reset by peer
INFO Successfully connected to nspanel.local
[20:39:44][W][nextion:078]: Nextion is not connected! 
[20:39:44][W][nextion:078]: Nextion is not connected!  

Any idea of what I could have done wrong is welcome.

Best, Felix

Any chance you can post your YAML config somewhere? My guess is that you’re not importing the external component (e.g. here) needed to get the display out of Sonoff’s proprietary mode.