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

I took over an existing yalm project, thanks to the answer I finally managed to start my configuration, and by quietly copying and modifying the yalm with the hmi I can gradually make my interface now.

Currently I am stuck on the correspondence of the ids between the yalm, and the ids of the images of the hmi on nextion. Notament for the weather icons, no id used in the yalm file correspond with the id in the hmi project, and I do not understand how to get the right icon under an if condition.

This is the sort of thing I use (note the substitutions as Nextion will change IDs so I try to use these to make updating them easier):

# Set some variables for convenience
substitutions:
  node_name: nspanel
  device_name: NSPanel
  TV_on_icon: '0'
  TV_off_icon: '1'
  FloorLight_on_icon: '12'
  FloorLight_off_icon: '11'
  Heating_on_icon: '13'
  Heating_off_icon: '14'
  HallLight_page_id: '3'
  PorchLight_page_id: '5'
  Boiler_entity_id: switch.tz3000_blah_on_off
  Boiler_on_icon: '13'
  Boiler_off_icon: '14'

then later

# Boiler setup
  - platform: homeassistant
    id: Boiler
    entity_id: $Boiler_entity_id
    on_value:
      then:
        - wait_until:
            switch.is_on: nextion_init
        - lambda: |-
            int BGimg = $Boiler_on_icon;
            if (id(Boiler).state == "off") {
              BGimg=$Boiler_off_icon;
            }
            id(disp1).send_command_printf("Home.HWBoost.pic=%i", BGimg);
1 Like

look under the weather section in marcfagers yaml. you see where it has “symbol” in the weather section?? this is referencing the pictures id’s in the nextion editor. whichever symbol number you have there will be the symbol that is displayed. I’m not at my pc right now but hopefully this helps.

pedroKTFC has brought them out as substitutes in his answer so all images are easier to change in one location without needing to scroll through 1000s of lines of code(unfortunately these yaml files can get messy). notice at the bottom of the weather section the “if statements” that there is the command to update the screen with whatever image. the same as pedroKTFC posted, although he’s showing another component instead of the weather. (his boiler…) he is calling for image id number 14 for when its in the off state and image 13 when its in the on state.

id(disp1).send_command_printf("Home.HWBoost.pic=%i

this line is saying your updating disp1 at a page called Home and picture components called HWBoost, the “.pic” is the image field in the tft files picture component, finally the %i is an int… look through the marcfager files and see how everything in the yaml corresponds to the tft.

2 Likes

From what I understood it is indeed the order of the images so id is indeed equal to id of hmi, but when the files are modified then the order changes, and it quickly becomes a mess. I don’t understand how the substitution works, it’s interesting I’ll try to understand how you do it.

In any case here is the progress of this night. I designed the weather icons, and used several functions and everything works well, thank you for the advice!

2 Likes

I indeed took the code from “GitHub - marcfager/nspanel-mf: Custom HMI controlled by ESPHome for the Sonoff NSPanel. Includes media player card and home screen with weather data and clock. More to come.” I did not manage to fully understand the ifs, I am just learning python and I master it well this section on python, but I still do not master the different conditions under yalm. I was not able to write or modify 2 conditions in case of “on” and “off” with 2 image conditions.

The section where I ask myself the most questions is on the sliders. I saw that it was 3 parts of images which are superimposed to make a slider.

yes the order of images you import into the nextion editor is the ID, i know if you delete one then the editor auto alters your image id’s in the components .pic attributes but it won’t obviously alter anything in the yaml. i just add a new one each time then delete the old and move the new into the same location (within the imported images, nextion editor bottom left). that or add a new one and change its id in yaml and nextion editor to suit. The substitutes are like fixed variables :thinking::joy:… in other words if you have them for names or id’s and use the $somename in your code multiple times. you can then just change the substitute for something other than “somename” like to “anothername” by just doing the one edit in substitutes. hope that makes sense :joy: (obviously they aren’t variables because you can’t alter the values programmatically)

yes I fully understand. It seems logical, I would code the same way under python. instead of modifying everything, a single variable contains the value of the id of nextion and the yalm refers to a library of variables, it allows you to change only one id rather than the whole yalm. Where it is absolutely necessary to respect the order of the ids under nextions, it is also what I did, but I prefer the variable technique. just better work.

Im struggling to update a .var variable from a HA sensor attribute.

Code looks like this:

  - platform: homeassistant
    id: alarm_delay
    entity_id: alarm_control_panel.alarmo
    attribute: delay
    accuracy_decimals: 0
    on_value:    
      then:
        - wait_until:
            switch.is_on: nextion_init
        - lambda: id(disp1).send_command_printf("Alarm.TimerCounter.val", "%s", id(alarm_delay).state);     
        - lambda: id(disp1).send_command_printf("Alarm.alarmtimer.en=1");

But it gives the following error message:

/config/esphome/ns-panel.yaml: In lambda function:
/config/esphome/ns-panel.yaml:869:84: warning: too many arguments for format [-Wformat-extra-args]
         - lambda: id(disp1).send_command_printf("Alarm.TimerCounter.val", "%s", id(alarm_delay).state); 

I cannot figured out the correct lambda syntax…
Does anyone have a clue?

- lambda: 'id(disp1).send_command_printf("Home.brightness.val=%i", int(x));'

does the above help? is the value an int? this is how masto or marcfager has it in the number component for passing the brightness to a variable in the HMI.

Salvation !
Almost everything is working for me now. I am currently looking to change the text when a button state changes so print on a button on or off when it is activated or not. I thought so headed for :

        - lambda: 'id(disp1).send_command_printf("Lumieres.spot_led_hmi.txt=%s", "ON" );' 

Only for the moment it does not work. Advices ?

I think you can do something like this, where targetTemp is the objname of the Nextion object. This has the advantage it’s independent of id so won’t change as you add remove other objects. I don’t know if this can be done for other attributes as that would remove that id dependence.

              - lambda: 'id(disp1).set_component_text_printf("targetTemp", "Off");'

1 Like

    # THERMOSTAT UP BUTTON INCREASES CLIMATE TARGET TEMPERATURE IN HA.
  - platform: nextion
    name: $device_name Target Up
    page_id: 7
    component_id: 12
    on_click:
      - homeassistant.service:
          service: climate.set_temperature
          data_template:
            entity_id: climate.lounge
            temperature: ! "return id(target_temperature).state + 1;"

edit: removed other code as it’s not needed for this function :man_facepalming:

Thanks for that!!! After ticking on press everything started working.



Nspanel as a remote control for my wee boy! Just in case someone is looking for new ideas.

binary_sensor:
  - platform: nextion
    name: $device_name Fireman Sam
    page_id: 4
    component_id: 4   
  - platform: nextion
    name: $device_name Pocoyo
    page_id: 3
    component_id: 7 
  - platform: nextion
    name: $device_name Peppa
    page_id: 3
    component_id: 4     
  - platform: nextion
    name: $device_name Paw Patrol
    page_id: 3
    component_id: 5       
  - platform: nextion
    name: $device_name Boss baby
    page_id: 3
    component_id: 6      
  - platform: nextion
    name: $device_name Simon
    page_id: 4
    component_id: 5   
  - platform: nextion
    name: $device_name Thomas
    page_id: 4
    component_id: 6  
  - platform: nextion
    name: $device_name Ricky zoom
    page_id: 4
    component_id: 7  
  - platform: nextion
    name: $device_name PJ Mask
    page_id: 5
    component_id: 4  
  - platform: nextion
    name: $device_name Pokemon
    page_id: 5
    component_id: 5 
  - platform: nextion
    name: $device_name Bheem
    page_id: 5
    component_id: 6

  

And then with an automation for each one, the television plays what you want to watch.

- id: 1645739815peppa607
  alias: NS_Peppa pig
  description: ''
  trigger:
  - type: turned_on
    platform: device
    device_id: XXXXXXXXXXXXXXXXXXXXXX
    entity_id: binary_sensor.nspanel_salon_peppa
    domain: binary_sensor
  condition:
  - condition: state
    entity_id: input_select.horario_infantil_tv
    state: SI
  action:
  - service: androidtv.adb_command
    data:
      command: am start -n com.netflix.ninja/.MainActivity -a android.intent.action.VIEW
        -e amzn_deeplink_data 80025802
    target:
      entity_id: media_player.YOURTELEVISION
  mode: single

80025802 equals Peppa pig
70287547 Fireman Sam
80235785 Pocoyo
etc… you can find those numbers opening netflix on a browser

Hope it helps!! :slight_smile:

3 Likes

Thank you for the help, little by little I’m moving forward and once the solution is found, it’s easy to make basic templates.

I still have a small problem, more recalcitrant than the others.
I want to retrieve the % lighting of a dimmer under tasmota (sonoff D1)
Only impossible to recover the data.

here is the yalm configuration of the button under home functional assistant:

here is my yalm configuration for the nspanel :

  # Grab current brightness from Home Assistant
  - platform: homeassistant
    id: brightness
    entity_id: light.dimmer_cuisine
    internal: true
    on_value:
      then:
        - wait_until:
            switch.is_on: nextion_init
      # https://www.codetable.net/hex/b0
        - lambda: 'id(disp1).set_component_text_printf("Lumieres.m1pourcent", "%.1f", id(brightness).state);'

I don’t get the value but in the esphome logs I still have this error:

it is however exactly the same yalm configuration as for the temperature and therefore I do not understand why it does not work. And I know even less how to fix the error. I’ve only been doing trial and error since yesterday by recovering bits of code on various projects.

thank you again for the help, I would really like this project to be completed to make it my first shared project on github!

it works thank you! Any idea what I could do to not print anything when the switch is off? everything works now, but I can’t get anything to print. I have to put for example “-”

secondary info?? shouldn’t that be “attr” ??
leve the text field blank in the hmi. and in the yaml if statement print “” if button state is off.

La solution viens en partie de la configuration de @masto

 - platform: homeassistant
    id: brightness_dimmer_cuisine
    entity_id: light.dimmer_cuisine
    attribute: brightness
    on_value:
      then:
        - wait_until:
            switch.is_on: nextion_init_slow
        - lambda: 'id(disp1).send_command_printf("Lumieres.spot_led_hmi.pco=%i", 27501);'
        - lambda: 'id(disp1).set_component_text_printf("Lumieres.spot_led_hmi", "%.0f%s", id(brightness_dimmer_cuisine).state/255*100, "%");'

I had to figure out how print works and remove decimals with %.0f

As the sensor has a scale of 0 to 255 I wrote the calculation to bring it back to 100% to my surprise everything works fine.

It’s an effect an attribute!

Coming back to the condition I am trying to use lambda and the if condition, but I can’t write it properly.

I can’t really find the documentation because I don’t have a sufficient level of mastery to still understand them. It’s only my basics of python that serve me and of course on this forum!

I currently have this partially working. The problem is that the status does not get updated until the dimmer changes value. Looks like I need a loop?

  - platform: homeassistant
    id: brightness_dimmer_cuisine
    entity_id: light.dimmer_cuisine
    attribute: brightness
    on_value:
      then:
        - wait_until:
            switch.is_on: nextion_init_slow
        - lambda: |- 
            if (id(relay_1).state) {
              id(disp1).set_component_text_printf("Lumieres.spot_led_hmi", "%.0f%s", id(brightness_dimmer_cuisine).state/255*100, "%");
            } else {
              id(disp1).set_component_text_printf("Lumieres.spot_led_hmi", "%s", "x");
            }

OK, I finally found the solution.

I had to do it in 2 places, one so that the value of the dimmer is permanently updated if the button is on:

  - platform: homeassistant
    id: brightness_dimmer_cuisine
    entity_id: light.dimmer_cuisine
    attribute: brightness
    on_value:
      then:
        - lambda: |- 
            if (id(relay_1).state) {
              id(disp1).set_component_text_printf("Lumieres.spot_led_hmi", "%.0f%s", id(brightness_dimmer_cuisine).state/255*100, "%");
            } else {
              id(disp1).set_component_text_printf("Lumieres.spot_led_hmi", "%s", ".");
            }

Then this which allows to change if the value must be displayed or not on the other hand I am obliged to write “.” if I want to change this value, otherwise I stay on the last value of the dimmer:

  - platform: homeassistant
    id: brightness_dimmer_cuisine_update_value
    entity_id: switch.spots_led
    on_value:
      then:
        - lambda: |- 
            if (id(relay_1).state) {
              id(disp1).set_component_text_printf("Lumieres.spot_led_hmi", "%.0f%s", id(brightness_dimmer_cuisine).state/255*100, "%");
            } else {
              id(disp1).set_component_text_printf("Lumieres.spot_led_hmi", "%s", ".");
            }
            }

I would like to try a cleaner code, and especially remove the “.” but it doesn’t matter if this value should stay with a font color I can make it not visible

I hope this would help other people