Sonoff NSPanel Setup

On the stock screen, or on my customer nxpanel screen firmware?

on your customer nxpanel screen firmware
I don’t see anything published when i press the button

You cannot get water out of a stone.

But would be great :smiley:

Mike has progress day by day so beta version would come soon I guess

no they don’t ,it wasn’t quite there on that yet.

i think next version should be a semi working. it will have no ‘play/demo’ buttons, it will have real one built from your backend.

the panel will send a message like

{ "page": { "format": f, "pid": page_id: "type": "refresh" } }

Your system will need to watch for these and send a reply back

f will the source page;

11 - 2 Button
12 - 3 Button
13 - 4 Button
14 - 6 Button
15 - 8 Button

you can prob ignore that tho.

the page_id is your unique room/view number. Example, 101 for Lounge. you the return what button config you want for that. you’ll need to send back buttons to match the format.

{ "refresh" : { "pid": 101, "name": "Lounge", "buttons": [
  { "bid": 1, "label": "Light", "type": 1, "state": n, "icon": 1 },
  { "bid": 2, "label": "Hall", "type": 10, "state": 14, "next": 201, "icon": 7 },
  { "bid": 3, "label": "Fan", "type": 1, "state": n, "icon": 3 } ] } }

type would be

00 - Unused
01 - Toggle
02 - Push
03 - Dimmer 
04 - Dimmer RGB
10 - Page Link

state would be 0/1 for toggles, or the page type if link to other buttons page, there it’s type 10 (Page Link), next would be the page id to pull back the config for that page, and so on.

A refresh message would be to build the whole page, if the nxpanel sent a “sync” one, you just need to return the states of things.

Anyway. just to give you a heads up

To start with you’ll need to send the json back via your scripts. but later I thank it will be possible to add your items to specifc groups which will cause the json to be send automatic, but that’s later… you should be able to get a working version by sending it youself tho for now

pressing a button will send

{ "button": { "pid": id, "bid": n, "state": s } }

It’s almost compete. I hope to have a working version of a beta release at the weekend.

For now here is an almost compete version in which you can actually configure your setup!! :slight_smile:

You need a thing channel and a rule;

  - id: nxpanel_command
    channelTypeUID: mqtt:string
    label: NxPanel Command
    description: ""
    configuration:
      commandTopic: cmnd/nspanel/nxpanel
  - id: nxpanel_page_trigger
    channelTypeUID: mqtt:trigger
    label: NxPanel Page Trigger
    description: ""
    configuration:
      stateTopic: tele/nspanel/RESULT

import org.slf4j.LoggerFactory

def logger = LoggerFactory.getLogger("org.openhab.core.automation.nspanel")

/*
 * Utility functions
 */

def makeButton(bid,label,type,icon=null,state=null,next=null) {
  var str = ""<<((bid==1)?"":",")
  str<<'{"bid":'<<bid<<',"label":"'<<label<<'","type":'<<type
  if (next!=null) {
    str<<',"next":'<<next
  }
  if (state!=null) {
    str<<',"state":'<<state
  }
  if (icon!=null) {
    str<<',"icon":'<<icon
  }
  str<<'}'
  return str
}

def makePage(pid,name,format) {
  var str = new StringBuilder('{"refresh":')
  str<<'{"pid":'<<pid<<',"name":"'<<name<<'","format":'<<format<<',buttons:['
  return str
}

def str = event.getEvent()
if (str.indexOf('{"page":')!=0) {
  logger.info("ignore: "+str)
  return
}

/*
 * Get data from the page message
 * (would be good to use JsonSluper here but currently can't access)
 */

var i = str.indexOf("\"id\"")
var i2 = str.indexOf(",",i+6)
var id = str.substring(i+6,i2)
i = str.indexOf("\"format\"")
i2 = str.indexOf(",",i+10)
var format = str.substring(i+10,i2)

// check if a full refresh or just a status update
var refresh = str.indexOf("refresh")>0

var json

switch (id) {
  
  /*
   * MakePage has these params;
   *  pid - you unique id for the page (max 99)
   *  name - 25 chars of description
   *  format - The style of page (will be set from what calls it, but this is to validate)
   *   1  - home
   *   2  - 2 buttons
   *   3  - 3 buttons
   *   4  - 4 buttons
   *   5  - 6 buttons
   *   6  - 8 buttons
   *   7  - dimmer Brightness
   *   8  - dimmer Color
   *   9  - Thermostat
   *   10 - Alert 1
   *   11 - Alert 2
   *   12 - Alarm
   *   13 - Media Player
   *   14 - Media Playlist
   *   15 - Status Panel
   *
   * 10 is the root button page from the home screen
   * it's set to be an 8 button panel for now, but you'll be able to change
   *   
   * MakeButton has these params;
   *  bid - number of button (1-8), keep in correct order, can leave blank
   *  label - the label under the button (8 chars max)
   *  type:
   *   0  - Unused
   *   1  - Toggle
   *   2  - Push
   *   3  - Dimmer (press on/off, long press for advanced)
   *   4  - Dimmer RGB (press on/off, long press for advanced)
   *   10 - Page Link
   *  icon: (can add more on request!)
   *   0  - Blank
   *   1  - Bulb
   *   2  - Dimmer 1
   *   3  - Dimmer 2
   *   4  - Vaccum
   *   5  - Bed
   *   6  - House
   *   7  - Sofa
   *   8  - Bell
   *   9  - Heat
   *   10 - Curtains
   *   11 - Music
   *   12 - Binary
   *  state - button 0=off, 1=on (for toggles), or page format for links (type 10)
   *  next  - id of next page from the section below
   *    
   */
  
  case "10" :
    movie = ir.getItem("movie_room_lights").state==ON?1:0
    if (refresh) {
      json = makePage(10,'Lounge',format)
      json<<makeButton(1,"Movie",1,1,movie)
      json<<makeButton(2,"Cabin",1,1,0)
      json<<makeButton(3,"Hall",2,6)
      json<<makeButton(4,"Bedroom",10,5,5,11)
      json<<makeButton(5,"Temp",10,9,9,12)
      json<<makeButton(6,"Light",1,3)
      json<<"]}}"
      print json
      print json.length()
      events.sendCommand("nxpanel_command",json.toString())
    }
    break
  case "11" :
    if (refresh) {
      json = makePage(10,'Hall',format)
      json<<makeButton(1,"A",1,4)
      json<<makeButton(2,"B",1,5)
      json<<makeButton(3,"C",1,6)
      json<<makeButton(4,"D",2,7)
      json<<makeButton(5,"E",2,8)
      json<<makeButton(6,"F",2,9)
      json<<"]}}"
      print json
      print json.length()
      events.sendCommand("nxpanel_command",json.toString())
    }
    break
  case "12" :
    if (refresh) {
      // TODO
    }
    break
}

The above is just a little 2 page example to get the idea.

Make sure you are on latest nxpanel.be & nxpanel.tft

How do you think that is?

NxPanel Specific Thread moved here;

i just want to ask something before i order one for my livingroom.Flashing tasmota and using the stock firmware can i use all the features with mqtt and openhab?What are the limitations and what can i do using stock?For example i want to use the 2 buttons as switches and 2 virtual buttons for 2 scenes plus the thermostat readings maybe control my wleds color …that kind of stuff.Do i have to flash Nxpanel for that or i can do using stock?

you can do some stuff with stock and control it to a degree. it was my first way, but it’s not great and pretty limited. and having the buttons only say ‘outlet’ when you go into the sub pages is useless. so you will be able do those things, but it will be a time consuming fight, I think. But you could.

Once you get tasoma on it’s a 5 min easy job to switch from stock to nxPanel and back. So i’d suggest having a play with each for a while, the see which suit your needs best.

But I don’t think you can go wrong getting one, for the price, it’s a very cool thing!

1 Like

thnx mate i got one in my hands today,flashed and using the nspanel.be…reading your stuff and blakadder’s ,trying to understand the protocol and make my own changes.My goal is to make a widget screen with 3 toggles and a color and to make thermostat screen to show and command my nest thermostat.Any tips are very welcome.

Yes, use NxPanel it will do that for you and save you a load of work! :slight_smile:

Describe it clearer. You want 2 on/off toggles, for what? lights?

What do you mean to ‘make a color’?

for a thermostat, you mean on/of and set a temperature?

1 Like

yes toggles for lights and a color widget to control my wled strip.As for the nest termostat yes i want set temperature and to show me the current temperature of the Nest.

v1.0.0-beta5

Some small fixes around sync refreshing

IMPORTANT To keep things in order I renamed the id field that is sent to the rule to be pid as below;


var i = str.indexOf("\"pid\"")
var i2 = str.indexOf(",",i+7)
var id = str.substring(i+7,i2)
i = str.indexOf("\"format\"")
i2 = str.indexOf(",",i+10)
var format = str.substring(i+10,i2)

You’ll need to change that, and the 6 to 7 in the substring as it’s a char longer now.

i have created a widget for my spotlights working really well,toggle it and i get

{"NSPanel":{"ctype":"group","id":"1","params":{"switch":"on","switches":[{"switch":"on","outlet":0}]}}}

or

{"NSPanel":{"ctype":"group","id":"1","params":{"switch":"off","switches":[{"switch":"off","outlet":0}]}}}

being the coding noob i am just need an example how to create a channel to read and command the state of this widget …

Looks like you are using the stock firmware not nxpanel. support for stock will be limited here, as I think most in this thread are using nxpanel now. You’d be able to call your spotlights “Spotlights” and not “outlet1” if your did :slight_smile:

But, in the channel you need to chain together two expression plugins in the input mapping field of the channel. The REGEX(text) one to filter those messages that only relate to the switch you are dealing with (as it will get all messages). and chain that with the JSON one so you can do NSPanel.params.switch to get at the value you are after. If you search you should find examples of chaining REGEX to get at values in JSON.

But, i’d suggest looking at NxPanel on the device before you spend a lot of time on a dead horse.

Hi Michael,
Thanks for posting this, and especially your nspanel code on Github.
I’m doing much the same as you: porting old ESP32 and Nextion code to an NSpanel.
Nothing would work until I read the above, and looked at your code.
Fancy swapping pins 16 and 17, AND needing pin4 low.

i have found a weird bug(?) …using the original blakadder’s nspanel.be .When i change the thermostat’s setting for example from 19 to 20 i get at mqtt

{"NSPanel":{"ATCMode":0,"ATCExpect0":20}}

and everything is working ok parsing and transforming reading the number setpoint in openhab
but when i set to 21 and only then i get

{"NSPanel":{"ATCMode":0,"ATCExpect0":21}B}}

that “B” at the end is cause error

[WARN ] [t.generic.ChannelStateTransformation] - Executing the JSONPATH-transformation failed: An error occurred while transforming JSON expression.

This is only happening with “21” value…
my openhab incoming Value Transformation is

REGEX:(.*ATCExpect0.*)∩JSONPATH:$.NSPanel.ATCExpect0

Anyone knows why this is happening?

Yes. I remember seeing that too. But I didn’t really use stock long enough to dig too much, I don’t see anything like that nxpanel, so I’m seeing it’s some bug or corruption in the Nextion part, also sending data to the nextion has CRC checking to see if corruption over serial happened, there is no such thing coming back. so there is alwasy a risk of getting interferecing over serial causing weird stuff. But I don’t think this error is that, as it’s always a B near end of message.

can i change my transformation to something else to workaround it?

could try chaining a regex expression before that to do a substiution?

s/}B}/}}/

As in here

seems cant make it work around… i ve tried transformation chains like

REGEX:(.*ATCExpect0.*)∩REGEX:(s/}B}/}}/)∩JSONPATH:$.NSPanel.ATCExpect0

but nothing seems to work ,i posted the bug at blakadder/nspanel github issues.