Sonoff NSPanel Setup

I thought I’d start a new thread on the best ways to get this working with openhab.

I current have it working for me, replacing all the sources on the home screen with better feeds from openhab. and the thermostat working. Ive used normal config in the main UI in 3.2 and a few groovy scripts.

Basically, I’ve flashed tasmota and use mqtt to link to openhab.

This guide gets you started;

I run this script from openhab to set the buttons up;

import org.slf4j.LoggerFactory

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

logger.info("NS init ...")
Thread.sleep(5000)
mqtt = actions.get("mqtt","mqtt:broker:mqtt_broker")

//mqtt.publishMQTT("cmnd/nspanel/nspsend","{\"index\":1,\"type\":\"delete\"}")
mqtt.publishMQTT("cmnd/nspanel/nspsend","{\"HMI_resources\":[{\"index\":1,\"ctype\":\"device\",\"id\":\"2\",\"uiid\":52}]}")
mqtt.publishMQTT("cmnd/nspanel/nspsend","{\"HMI_resources\":[{\"index\":2,\"ctype\":\"device\",\"id\":\"2\",\"uiid\":1}]}")
mqtt.publishMQTT("cmnd/nspanel/nspsend","{\"HMI_resources\":[{\"index\":3,\"ctype\":\"device\",\"id\":\"3\",\"uiid\":1}]}")
mqtt.publishMQTT("cmnd/nspanel/nspsend","{\"HMI_resources\":[{\"index\":4,\"ctype\":\"device\",\"id\":\"4\",\"uiid\":1}]}")
mqtt.publishMQTT("cmnd/nspanel/nspsend","{\"HMI_resources\":[{\"index\":5,\"ctype\":\"device\",\"id\":\"5\",\"uiid\":1}]}")
mqtt.publishMQTT("cmnd/nspanel/nspsend","{\"HMI_resources\":[{\"index\":6,\"ctype\":\"device\",\"id\":\"6\",\"uiid\":1}]}")
mqtt.publishMQTT("cmnd/nspanel/nspsend","{\"HMI_resources\":[{\"index\":7,\"ctype\":\"device\",\"id\":\"7\",\"uiid\":1}]}")
mqtt.publishMQTT("cmnd/nspanel/nspsend","{\"HMI_resources\":[{\"index\":8,\"ctype\":\"device\",\"id\":\"8\",\"uiid\":1}]}")

mqtt.publishMQTT("cmnd/nspanel/nspsend","{\"relation\":[{\"id\":\"1\",\"online\":true,\"name\":\"Cabin\",\"params\":{\"ltype\":\"white\"},\"white\":{\"br\":50}}]}")
mqtt.publishMQTT("cmnd/nspanel/nspsend","{\"relation\":[{\"id\":\"2\",\"online\":true,\"name\":\"Cabin\",\"params\":{\"switch\":\"off\"}}]}")
mqtt.publishMQTT("cmnd/nspanel/nspsend","{\"relation\":[{\"id\":\"3\",\"online\":true,\"name\":\"Balcony\",\"params\":{\"switch\":\"off\"}}]}")
mqtt.publishMQTT("cmnd/nspanel/nspsend","{\"relation\":[{\"id\":\"4\",\"online\":true,\"name\":\"Decking\",\"params\":{\"switch\":\"off\"}}]}")
mqtt.publishMQTT("cmnd/nspanel/nspsend","{\"relation\":[{\"id\":\"5\",\"online\":true,\"name\":\"Movie\",\"params\":{\"switch\":\"off\"}}]}")
mqtt.publishMQTT("cmnd/nspanel/nspsend","{\"relation\":[{\"id\":\"6\",\"online\":true,\"name\":\"Garage\",\"params\":{\"switch\":\"off\"}}]}")
mqtt.publishMQTT("cmnd/nspanel/nspsend","{\"relation\":[{\"id\":\"7\",\"online\":true,\"name\":\"Master\",\"params\":{\"switch\":\"off\"}}]}")
mqtt.publishMQTT("cmnd/nspanel/nspsend","{\"relation\":[{\"id\":\"8\",\"online\":true,\"name\":\"Lounge\",\"params\":{\"switch\":\"off\"}}]}")

There is an nspanel.be file mentioned in the above install. I commented out a couple of lines that update the screen with rubbish data and added an extra MQT message so I know when the screen has been initialised, so I can add my buttons back, when it restarts.

These were my changes to nspanel.be
image
image


image

This basically stops the items on the screem being updated by anything other that changes you make. Before this you’d set them temp to what you wanted and a few mins later it would be overrriden by the one on the device, which is very wrong. mine is +6 or more high. I think the unit itself gives off internal heat, which makes it useless.

The UI button behave a bit odd. when you press one to ON, it visually moves to ON, send an MTQ message out saying it’s ON, then visually jumps back to OFF!!? if you want it so stay visually ON you need to send a command back to the device to change it ON. Then it stays ON. This seems to be the case for all (except the very first button for some stange reason, which keeps it’s state)

I’ll post these when I get some more time

NxPanel

Latest Version here;

Current Pages;

2 Likes

These are my channels;

label: NS Panel
thingTypeUID: mqtt:topic
configuration: {}
bridgeUID: mqtt:broker:mqtt_broker
location: Lower Hall
channels:
  - id: ns_temperature
    channelTypeUID: mqtt:string
    label: NS Temperature
    description: ""
    configuration:
      formatBeforePublish: '{"temperature":%s,"humidity":0,"tempUnit":0}'
      commandTopic: cmnd/nspanel/nspsend
  - id: ns_switch_2
    channelTypeUID: mqtt:switch
    label: NS Panel Switch 2
    description: ""
    configuration:
      stateTopic: stat/nspanel/POWER2
  - id: nspsend_command
    channelTypeUID: mqtt:string
    label: NSPSend Command
    description: ""
    configuration:
      commandTopic: cmnd/nspanel/nspsend
  - id: ns_thermostat_switch
    channelTypeUID: mqtt:switch
    label: NS Thermostat Switch
    description: ""
    configuration:
      commandTopic: cmnd/nspanel/nspsend
      formatBeforePublish: '{"ATCEnable":%s}'
      off: "0"
      on: "1"
  - id: ns_thermostat_switch_listener
    channelTypeUID: mqtt:switch
    label: NS Thermostat Switch Listener
    description: ""
    configuration:
      transformationPattern: REGEX:(.*ATCEnable.*)∩JSONPATH:$.NSPanel.ATCEnable
      stateTopic: tele/nspanel/RESULT
      off: "0"
      on: "1"
  - id: ns_thermostat_set_temp
    channelTypeUID: mqtt:number
    label: NS Thermostat Set Temp
    description: ""
    configuration:
      formatBeforePublish: '{"ATCMode":0,"ATCExpect0":%d}'
      commandTopic: cmnd/nspanel/nspsend
  - id: ns_thermostat_set_temp_listener
    channelTypeUID: mqtt:number
    label: NS Thermostat Set Temp Listener
    description: ""
    configuration:
      formatBeforePublish: "%s"
      stateTopic: tele/nspanel/RESULT
      transformationPattern: REGEX:(.*ATCExpect0.*)∩JSONPATH:$.NSPanel.ATCExpect0
  - id: ns_thermostat_heat_ind
    channelTypeUID: mqtt:string
    label: NS Thermostat Heat Indicator
    description: ""
    configuration:
      formatBeforePublish: '{"HMI_ATCDevice":{"ctype":"device","id":"themostat","outlet":0,"etype":"%s"}}'
      commandTopic: cmnd/nspanel/nspsend
  - id: ns_button
    channelTypeUID: mqtt:string
    label: NS Button Listener
    description: ""
    configuration:
      stateTopic: tele/nspanel/RESULT
      transformationPattern: REGEX:(.*"id".*"params".*"switches".*"outlet".*)
  - id: ns_init
    channelTypeUID: mqtt:string
    label: NS Initialization
    description: ""
    configuration:
      stateTopic: tele/nspanel/RESULT
      transformationPattern: REGEX:(^Initialized$)

I work these with some rules;

For the buttons I have two rules to link the openhab item buttons to the buttons on the panel. I only use 8 top level buttons on the panel becuase I can name those. if you use the subgroup buttons they are called, outlet1, outlet2 and so on. I dont think that’s any good, so won’t be using it.

For the rules to work I create to item group called “NS Button Group” and add the buttons in openhab that I want mirrored on the Panel to the group, then I have this rule;

import org.slf4j.LoggerFactory

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

Properties p1 = new Properties()
p1.load(new FileReader("../conf/transform/ns-button.map"))
Properties p2 = new Properties();
for (Map.Entry<Object, Object> e: p1.entrySet()) {
  p2.setProperty((String)e.getValue(), (String)e.getKey());
}
id = p2.getProperty(event.itemName)
state = ir.getItem(event.itemName).state.toString().toLowerCase();

logger.info(String.format("OH id=%s, state=%s, item=%s",id,state,event.itemName))

events.sendCommand("nspsend_command",
  String.format("{\"relation\":[{\"id\":\"%s\",\"params\":{\"switch\":\"%s\"}}]}",
  id,state))

it depends on a config file that tells the system what panel button equates to which openhab button;

openhab/conf/transform/ns-button.map

2=cabin_lights
3=balcony_lights
4=DeckingLights_DeckingLights
5=movie_room_lights
6=garage_lights
7=master_bedroom
8=LoungeLights_LoungeLights

I have another rule which is linked to the channel item that picks up buttons on the panel;

import org.slf4j.LoggerFactory

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

/*
def jsonSlurper = new JsonSlurper()
def json = jsonSlurper.parseText(ir.getItem(event.itemName).state.toString())
id = json.NSPanel.id
state = json.NSPanel.params.switch
*/

def str = ir.getItem(event.itemName).state.toString();
var i = str.indexOf("\"id\"")
id = str.substring(i+6,i+7)
i = str.indexOf("\"switch\"")
i2 = str.indexOf("\"",i+10)
state = str.substring(i+10,i2)

Properties p1 = new Properties()
p1.load(new FileReader("../conf/transform/ns-button.map"))

item = p1.getProperty(id)

logger.info(String.format("NS id=%s, state=%s, item=%s",id,state,item))

events.sendCommand("nspsend_command",
  String.format("{\"relation\":[{\"id\":\"%s\",\"params\":{\"switch\":\"%s\"}}]}",
  id,state))
events.sendCommand(item,state.toUpperCase())


This should get things basically working and in sync! :slight_smile:

1 Like

For the temps and weather, I use openweather and push those items to the screen and i push the room temp from another sensor in the room which give a correct reading.

This needs another map file which maps openweather icons to those on the unit;
openhab/conf/transform/weather-icons.map

01=1
02=2
03=7
04=7
09=12
10=12
11=15
13=22
50=11

I then use this rule;

events.sendCommand("ns_temperature",""+ir.getItem("CabinDevices_CabinRoomTemperature").state.intValue())

Properties map = new Properties()
File file = new File("../conf/transform/weather-icons.map")
map.load(new FileReader(file))

def weather = map.getProperty(ir.getItem("weather_icon_id").state.toString().substring(0,2))
def outdoorTemp = ir.getItem("outdoor_temp").state.intValue()
def apparentTemp = ir.getItem("apparent_temperature").state.intValue()

def json = String.format(
  "{\"HMI_weather\":%s,\"HMI_outdoorTemp\":{\"current\":%d,\"range\":\"%d,%d\"}}",
  weather, outdoorTemp, apparentTemp, apparentTemp)

events.sendCommand("nspsend_command",json)


Hope this is of use to someone

1 Like

Thanks, I’ll read it all carefully tomorrow!

Next thing I’d like to look at is custom screens!

But I’ve not found any info yet on how to do this in the context of Tasmota.

I think the process would be this though;

  1. Upload a new TTF file to the screen. this seem to be a single file that has all new screen bundled in. On next reboot the screen sees the file, unpacks in and install it.
  2. Write another .be file for your custom screens. This would handle the conversion of commands sent to Tasmota to commands the screen would understand.

The part I don’t know is how to get the new TTF file to the screen and importantly, put the original TFF back after I’ve tinkered, so can continue using as is, until I’ve happy. I’m hoping that this can be done while tasmota is on and that hardward flashing is not needed. my box is already on the wall!! :slight_smile:

1 Like

Awesome Work @m-home ! Thank you for sharing…
Hope I’ll find some spare time in the next days to flash both of my nspanels and Start using your examples…

Looks like you have done great job (thx for moving from tasmota github topic).
Seems fantastic to replace values with our own, but before improving weather I am trying to undestand regular outlet switch updating.
Could you explain what is “ns_init” trigger on your setup? where you take it from?

When you reboot, it looses your buttons. So it was to re-add them when it boots. It was to detect the reboot from a mqtt message and run the script in OH to add them back. I added an extra mqtt message in the nspanel,be, so my trigger knew when to add them back. Use this for now but I’m going to change it shortly. I think it’s better to actually edit the nspanel.be file directly and set the buttons as you like there, and ignore the init way Im doing now. it’s pretty easy, right as the start of the nspanel.be there is an array of the 8 buttons just change them to suit you. Currently, there is no name in the array tho, so for now use the rule way, it works. I’ll let you know the edit to the .be for the other when ive done it

You need to make sure you add this extra mqtt message tho
image
2nd last line. becuase the rule need to know it can add them back at this point

1 Like

@m-home Well done for writing this up! I have been using the NSPanel with Openhab for a few weeks and have found it to be quite good. I just have it running one screen to run 8 different scenarios, the other screens are still there of course but I don’t use them.

The limitation of the secondary buttons being called Outlet is a shame.

I also find that if you have it on sleep you end up accidently pressing a button when you wake it up. I’ve got it in our bedroom so it was too bright to leave on all the time.

I guess the question will be whether Tasmota can be configured to allow more customisations or do we have to use esphome which takes it to another level Flash NSPanel with ESPHome

If you look he has also done a second video that overcomes the screen diming issue. He is using Home assistant but I am sure Openhab could be used as well.

I have now implemented custom screen uploading with the Tasmota version. Very early version hot off the press, but seems to work just fine.

I flashed a demo TFT then flashed the stock firmware back, without any issues.

Please look here for now;

3 Likes

Wow it looks great!
Hopefully it could be some day like below but with tasmota (dont want to start additionally learning of esphome )

2 Likes

Brilliant work everyone involve in this…
I have flashed tasmota (from ESPHome), and using the m-home java uploader - i flashed my custom tft.
and instead using the “send component ID” which doesnt indicate dual-button state.
i can add print command in nextion editor to send what i want…

on tasmota console pressing this button i get
10:53:48.884 RSL: RESULT = {“NSPanel”:{“Nextion”:“b”}}
10:53:49.583 RSL: RESULT = {“NSPanel”:{“Nextion”:“3”}}

  1. can i add MQTT rules in tasmota based on that ?
  2. the tasmota seems to chop the strings for some reason (tried also printh)

or im getting this all wrong and i have to use component ID somehow ?

Probably my error. I was focussing on getting the firmware upload working, not the replies back from the screen. I’ll have a look shortly and put a fix in if wrong.

FIXED!

Please get the latest nextion.be file here;

Please read the notes at bottom for Data Exchange.

Also, any issues with this, please log on git if you can.

Brilliant! Works like a charm
thanks @m-home!

That looks exactly what I want to do with mine. I was already looking into esphome, but if I can avoid it, even better.

One thing that I am missing in the Data Exchange section is - how to send the data from OH to the panel to update the custom fields on the display. An example for that would be great.

You can just issues command to the screen.

For example, if you page called ‘home’ in your display and that has a text field on call ‘temp’ you can do this by sending a message to the nspanel via mqtt

Nextion page home
Nextion temp.txt=“25c”

Guys do you mind to upload some screenshots of NSPanel after mod?
I am lost with understanding what we are looking for here - is it visualisation of screens or communication and feeding NSPanel with our values ?

Would be possible to remove thermostat screen when useless?

This is what I am currently working on. I managed to get writes working from Tasmota and I get button press events. So now I just need to finish the design. For some reason the actual viewing area is smaller than the screen, which I didn’t know.

1 Like

Do you have a HMI template for the Euro Version of the screen?
I only find the description of the US version.
Some samples would make life easer :wink:
I try to stay on tasmota, as I want to work only with MQTT.
Currently I´m little stuck.
I flashed the firmware and write the sample TFT file, all working good so far.