NxPanel - Replacement Firmware for Sonoff NSPanel

Oh, and I believe I found a bug on the color dimmer page. Every time I send a refresh command, like:

‘{“refresh”: {“pid”: 30, “name”: “LEDs”, “power”: 1,“hsbcolor”: “100,100,100”}’;

the page responds with:

“{“dimmer”:{“pid”:30,“power”:1,“hsbcolor”:“100,100,100”}}”

this is causing a loop, since I change the screen to reflect my leds state, but than it triggers a button push, that updates the screen, that triggers a button, and so on… The standard dimmer does not behave like this. When refreshed, that is no response

When the screen has dimmed because of the settings and you send a {“dim”: {“normal”: 100)}} you get a grey screen, which will only change to the normal display when you tap it.
I want to turn on the display, when the panel receives a e.g. a warnings message.

I have gotten so far the trigger works, but no green light and like nothing happens really.


UID: mqtt:topic:e4db36b9fe:1e8dcbf0b7
label: Nxpanel
thingTypeUID: mqtt:topic
configuration: {}
bridgeUID: mqtt:broker:e4db36b9fe
channels:
  - id: nxpanel_command
    channelTypeUID: mqtt:string
    label: NxPanel Command
    description: null
    configuration:
      commandTopic: cmnd/nspanel/nxpanel
  - id: nxpanel_page_trigger
    channelTypeUID: mqtt:trigger
    label: NxPanel Page Trigger
    description: null
    configuration:
      stateTopic: tele/tasmota_7C0BEC/RESULT

I used the script nothing edited just to see something.

I have flashed my NSpanel to Tamota and managed to load nxpanel (so I see the same images as shown on one of the pages here.) besides the main screen (with time and date) the temperature show 0 degrees C and half sun. On another screen I also see 8 empty buttons and I can enter a settings screen (down swipe) that shows version 1.07, Sleep Time, Dim Level and normal level (and some tickboxes). Those settings doesn’t seem to do anything (At least I can’t notice any behavior change?).

Where do I have to change settings in order to get something shown on my NSpanel? I have to point my NSpanel to a MQTT broker? Haven’t found a manual that explains me what to do? Is this information somewhere hidden in the 244 reactions in this topic?

2 Likes

you need to change your cmnd

commandTopic: cmnd/nspanel/nxpanel
to

commandTopic: cmnd/tasmota_7C0BEC/nxpanel

Yes still same thing, also changed the script Mqtt broker.


UID: mqtt:topic:e4db36b9fe:1e8dcbf0b7
label: Nxpanel
thingTypeUID: mqtt:topic
configuration: {}
bridgeUID: mqtt:broker:e4db36b9fe
channels:
  - id: nxpanel_command
    channelTypeUID: mqtt:string
    label: NxPanel Command
    description: null
    configuration:
      commandTopic: cmnd/tasmota_7C0BEC/nxpanel
  - id: nxpanel_page_trigger
    channelTypeUID: mqtt:trigger
    label: NxPanel Page Trigger
    description: null
    configuration:
      stateTopic: tele/tasmota_7C0BEC/RESULT


configuration: {}
triggers:
  - id: "1"
    configuration:
      channelUID: mqtt:topic:e4db36b9fe:1e8dcbf0b7:nxpanel_page_trigger
    type: core.ChannelEventTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/x-groovy
      script: >-
        import org.slf4j.LoggerFactory


        def PAGE_HOME            = 1

        def PAGE_2_BUTTON        = 2

        def PAGE_3_BUTTON        = 3

        def PAGE_4_BUTTON        = 4

        def PAGE_6_BUTTON        = 5

        def PAGE_8_BUTTON        = 6

        def PAGE_DIMMER          = 7

        def PAGE_DIMMER_COLOR    = 8

        def PAGE_THERMOSTAT      = 9

        def PAGE_ALERT_1         = 10

        def PAGE_ALERT_2         = 11

        def PAGE_ALARM           = 12

        def PAGE_MEDIA           = 13

        def PAGE_PLAYLIST        = 14

        def PAGE_STATUS          = 15


        def BUTTON_UNUSED        = 0

        def BUTTON_TOGGLE        = 1

        def BUTTON_PUSH          = 2

        def BUTTON_DIMMER        = 3

        def BUTTON_DIMMER_COLOR  = 4

        def BUTTON_PAGE          = 10


        def ICON_BLANK           = 0 

        def ICON_BULB            = 1 

        def ICON_DIMMER          = 2 

        def ICON_DIMMER_COLOR    = 3

        def ICON_VACUUM          = 4 

        def ICON_BED             = 5 

        def ICON_HOUSE           = 6 

        def ICON_SOFA            = 7 

        def ICON_BELL            = 8 

        def ICON_HEAT            = 9

        def ICON_CURTAINS        = 10 

        def ICON_MUSIC           = 11

        def ICON_BINARY          = 12 

        def ICON_FAN             = 13

        def ICON_SWITCH          = 14

        def ICON_TALK            = 15

        def ICON_INFO            = 16


        def NONE                 = 0


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


        def mqtt = actions.get("mqtt","mqtt:broker:e4db36b9fe")


        def str = event.getEvent()


        logger.info("Demo page rules called")


        if (str.indexOf('{"page":')!=0) {
          return
        }


        /*
         * Utility functions - start
         */

        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) {
          var str = new StringBuilder('{"refresh":')
          str<<'{"pid":'<<pid<<',"name":"'<<name<<'",'
          return str
        }


        def makeEmptySync(pid) {
          var str = new StringBuilder('{"sync":')
          str<<'{"pid":'<<pid<<'}}'
          return str
        }


        def makeEmptyRefresh(pid) {
          var str = new StringBuilder('{"refresh":')
          str<<'{"pid":'<<pid<<'}}'
          return str
        }


        def makeSyncButtonStart(pid,bid,state) {
          var str = new StringBuilder('{"sync":')
          str<<'{"pid":'<<pid
          str<<',buttons:[{"bid":'<<bid<<',"state":'<<state<<'}'
          return str
        }


        def addSyncButton(bid,state) {
          var str = ',{"bid":'<<bid<<',"state":'<<state<<'}'
          return str
        }


        /*
         * Utility functions - end
         */

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

        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)


        // check if a full refresh or just a status update

        var refresh = str.indexOf("refresh")>0


        var json


        def PANEL_MAIN          = 10

        def PANEL_BEDROOM_1     = 11

        def PANEL_BEDROOM_2     = 12

        def PANEL_LOUNGE        = 13

        def PANEL_CABIN         = 14

        def PANEL_CABIN_THERMO  = 15

        def PANEL_CABIN_LIGHTS  = 16

        def PANEL_LOUNGE_FAN    = 17

        def PANEL_LOUNGE_LIGHT  = 18

        def PANEL_STATUS        = 19

        def PANEL_MUSIC         = 20


        def TOPIC = "cmnd/nspanel/nxpanel"


        logger.info("updating page ... "+id)


        switch (id as int) {  
          
          case PANEL_MAIN :
            logger.info("main panel")
            // set these from your own items
            movie_state = 1
            lounge_state = 0
            cabin_state = 0
            hall_light_state = 1
            if (refresh) {
              json = makePage(id,'Lounge')
              json<<format<<'buttons:['
              json<<makeButton(1,"Movie",BUTTON_TOGGLE,ICON_BULB,movie_state)
              json<<makeButton(2,"Lounge",BUTTON_TOGGLE,ICON_BULB,lounge_state)
              json<<makeButton(3,"Hall",BUTTON_PUSH,ICON_HOUSE)
              json<<makeButton(4,"Bedroom",BUTTON_PAGE,ICON_BED,PAGE_6_BUTTON,PANEL_BEDROOM_1)
              json<<makeButton(5,"Temp",BUTTON_PAGE,ICON_HEAT,PAGE_THERMOSTAT,PANEL_CABIN_THERMO)
              json<<makeButton(6,"Light",BUTTON_DIMMER,ICON_DIMMER,hall_light_state,PANEL_LOUNGE_LIGHT)
              json<<makeButton(7,"Dimmer",BUTTON_DIMMER_COLOR,ICON_DIMMER_COLOR,cabin_state,PANEL_CABIN_LIGHTS)
              json<<makeButton(8,"Status",BUTTON_PAGE,ICON_INFO,PAGE_STATUS,PANEL_STATUS)
              json<<"]}}"
            } else {
              json = makeSyncButtonStart(id,1,movie_state)
              json<<addSyncButton(2,lounge_state)
              json<<"]}}"
            }
            mqtt.publishMQTT(TOPIC, json.toString())
            break
          case PANEL_BEDROOM_1 :
            // set these from your own items
            fan_state = 1
            if (refresh) {
              json = makePage(id,'Bedroom 1')
              json<<format<<'buttons:['
              json<<makeButton(1,"A",BUTTON_PUSH,ICON_HOUSE)
              json<<makeButton(2,"Fan",BUTTON_DIMMER,ICON_FAN,fan_state,PANEL_LOUNGE_FAN)
              json<<makeButton(3,"C",BUTTON_PUSH,ICON_SOFA)
              json<<makeButton(4,"Music",BUTTON_PAGE,ICON_MUSIC,PAGE_MEDIA,PANEL_MUSIC)
              json<<makeButton(5,"D",BUTTON_PUSH,ICON_TALK)
              json<<makeButton(6,"Alarm",BUTTON_PAGE,ICON_BELL,PAGE_ALARM,NONE)
              json<<"]}}"
            } else {
              json = makeEmptySync(id)
            }
            mqtt.publishMQTT(TOPIC, json.toString())
            break
          case PANEL_BEDROOM_2 :
            json = makeEmptySync(id)
            mqtt.publishMQTT(TOPIC, json.toString())
            break
          case PANEL_LOUNGE :
            json = makeEmptySync(id)
            mqtt.publishMQTT(TOPIC, json.toString())
            break
          case PANEL_CABIN :
            json = makePage(id,'Cabin')
            json<<"}}"
            mqtt.publishMQTT(TOPIC, json.toString())
            break
          case PANEL_CABIN_THERMO :
            // set these from your own items
            var heater = 1
            var auto = 0
            var temp = 15
            var set = 21
            json = makePage(id,'Cabin')
            json<<format<<',"therm":{'
            json<<'"set":'<<set<<',"temp":'<<temp<<',"heat":'<<heater<<',"state":'<<auto<<'"'
            json<<"}}"
            mqtt.publishMQTT(TOPIC, json.toString())
            break
          case PANEL_CABIN_LIGHTS :
            json = makePage(id,'Cabin Lights')
            json<<'"power":'<<ON<<',"hsbcolor":'<<'"10,100,50"'
            json<<"}}"
            mqtt.publishMQTT(TOPIC, json.toString())
            break
          case PANEL_LOUNGE_FAN :
            // set these from your own items
            fan_state = ON
            fan_setting = 3
            json = makePage(id,'Lounge Fan')
            json<<'"power":'<<fan_state<<',"min":'<<1<<',"max":'<<4<<',"icon":'<<ICON_FAN<<',"dimmer":'<<fan_setting
            json<<"}}"
            mqtt.publishMQTT(TOPIC, json.toString())
            break
          case PANEL_LOUNGE_LIGHT :
            json = makePage(id,'Lounge Light')
            json<<'"power":'<<ON<<',"dimmer":'<<30
            json<<"}}"
            mqtt.publishMQTT(TOPIC, json.toString())
            break
          case PANEL_STATUS :
            json = makePage(id,'System Status')
            json<<'"status":['
            json<<'{"id":'<<1<<',"text":'<<'"Gate":'<<',"value":'<<'"Open"'<<',"color":'<<2<<'}'
            json<<','
            json<<'{"id":'<<2<<',"text":'<<'"Window":'<<',"value":'<<',"Shut"'<<',"color":'<<3<<'}'
            json<<','
            json<<'{"id":'<<5<<',"text":'<<'"Room Temp":'<<',"value":'<<',"20°C"'<<'}'
            json<<']}}'
            mqtt.publishMQTT(TOPIC, json.toString())
            break
          case PANEL_MUSIC :
            json = makePage(id,'Sonos Player')
            // set these from your own items
            json<<'"artist":'<<'"New Order"'<<',"album":'<<'"Movement"'<<',"track":'<<'"Power Play"'<<',"volume":'<<70
            json<<"}}"
            mqtt.publishMQTT(TOPIC, json.toString())
            break    
          default :
            logger.info("unknown page!")
            break

        }


        logger.info("rule done")
    type: script.ScriptAction

Hello,

I just installed the custom firmware and I want to go back to the default tft one.
so I ran

FlashNextion http://cdn.discordapp.com/attachments/538814618106331139/925351768852951050/ns-panel.tft

but whenever I do this I get the message
“Model does not match”
image

Is there a way to find the firmware for my model?

Hi and thanks for the tremendous effort to make this work, really impressed - Thanks firstly to @m-home to make the integration with OpenHAB happen in the first place (well let’s not forget blackadder!) but also to all others contributing with comments and improvements.
I have my NSPanel flashed and got the start panel working the way I like, next up is doing the menus.

What I noted during my work is that a lot of the information I needed to get running is spread around, both in this thread, but also in the initial thread. As I’m lazy and do forget stuff I once learned, I’ve been putting my config work into a documentation. It’s still far from ready but when it is I will share as my contribution. But one question to @m-home, do you also have something documented (whatever quality) so I don’t invent the wheel?

4 Likes

Hi Alf, I’m still not getting anywhere, so love to see your documentation that is hopefully a bit more structured than the way its currently presented (due to the nature a forum works). I’m not running OpenHab but got MQTT broker running now, so should be able to get/set some manual commands on the NxPanel, but no progress yet, as having no idea to start with this.

2 Likes

Have the same issue ::confused:

1 Like

Can you share the project files? I’d like to modify the look a little bit.

1 Like

Hi Alf, I would love to see your documentation as well. I am driving myself crazy bouncing around the forum replies trying to see if I had tried various fixes in my troubleshooting.

2 Likes

First version of the documentation done. Still work in progress but thought it would be valuable to share “as is” as it at least covers and brings you past where most people get stuck (just as me) -
that is to get NSPanel to “talk” to OpenHAB. For quick answer, check picture in chapter 6, page 8 second doc.).
(Documentation exceeded 1Mb ulpoad limit, so needed to split onto two docs…)
Cheers…
OpenHAB3 and Sonoff NSPanel v1 part 1.pdf (672.9 KB)
OpenHAB3 and Sonoff NSPanel v1 part 2.pdf (1007.4 KB)

2 Likes

Hi Alf, thank you for all of your hard work putting it all in a nice document :ok_hand:. What is it about " chapter Fel! Hittar inte referenskälla…" in the documents? I dont use OpenHab but still good to know how this works. I can install Groovy and MQTT on my rpi, but still need some other tool to send the commands from Groovy I guess.

Thanks for the good documents,

I have connections now, but how do I send weather information? Etc front page

Hi,

Look like I broke the screen. I m seeing System Data ERROR! on screen. the nexpanel.be hung at 97% and now screen is stuck on error screen.

I m able to access tasmota etc. Any pointers, how to fix this? I m new to displays.

tasmota version I have used is : 11.0.0.4

It stops randomly above 90% and is in wrong orientation. Is this anything to do with size available for flash ? it hangs around same size

Thank you in advance!

Sorry. Been caught up in day work and not had time to look here, and on needed holiday to the 12th now, when back I’ll catch up with all bugs and issue and do a new release first week back.

Here comes version 2 of the setup documentation, now everything in one document:

NSPanel - Setup instructions for OpenHAB

See version 2 just posted :blush:.I also fixed some errors I found in the first version, key thing I learned is that you don’t need a “NXPanel Command” channel. Doc and pictures updated accordingly.

Hi,

Not sure if there is any issue in latest version but today I tried nxpanel-1.0.7.tft and it worked.

thanks