NxPanel - Replacement Firmware for Sonoff NSPanel

I’ll go ahead and update my comment to include a demo as well and add some of the enums

1 Like

Version 1.0.4

  • Pressing bell, just clears bell. Long press, clears bell & notifications
  • Fix - State of hard switches kept after a reboot
  • Fix - Media message was wrong

I removed my ON/OFF constants as they clashes with one auto imported into script for state!

I send the command “InstallNxPanel” to the unit
the unit showing flashing
And that’s the version I get
it is OK?

{“init”: {“nx-panel”: “1.0.0”, “berry”: “berry: 1.1.2” }}

make sure you tick auto update and also test updates in the config panel then try again
it will ask you to update you nxpanel.be file too (as I see it’s 1.1.2) , so you might want to do that first

Did the sync operation for the button change?

case PANEL_MAIN :
logger.info(“main panel”)
// set these from your own items
movie_state = ir.getItem(“MyRoom_Power”).state==ON?1:0
if (refresh) {
json = makePage(id,‘Lounge’)
json<<format<<‘buttons:[’
json<<makeButton(1,“Movie”,BUTTON_TOGGLE,ICON_BULB,movie_state)
json<<“]}}”
} else {
json = makeSyncButtonStart(id,1,movie_state)
json<<addSyncButton(2,movie_state)
json<<“]}}”

I took format out, bc it wasn’t really needed. it shouldn’t be an issue if you leave it though. nothing major was changed.

is sometthing not working?

This one in post 2 should work without change as a template.

the sync not working igot

Cmnd ‘NXPANEL’, Idx 1, Len 69, Data ‘{“sync”:{“pid”:10,buttons:[{“bid”:1,“state”:0},{“bid”:2,“state”:0}]}}’

but my state light is on

Hi,

I can’t flash a .tft file. I always get a message:

Model does not match
Device Model
NX4832F035_011C

The progress bar shows up a short time but then a blank screen with this message appears. It stays there until I reboot the device. I can’t find any error message in the log file.

What can be wrong?

Are you sure you are using the latest Tasmota for the NSPanel?

I canceled these lines and it works

//def ON = 1
//def OFF = 0
//def NONE = 0

I messaged above about those. I took then out the template too. There are already ON OFF ones in scope from State. it doesn’t give you any warning you are using ones already there!!

|Program Version|11.0.0.2(tasmota)||—|—|
|Build Date & Time|2022-02-20T16:33:58|
|Core/SDK Version|2_0_2_1/v4.4|

Console:
23:45:03.653 CMD: Grp 0, Cmd ‘FLASHNEXTION’, Idx 1, Len 41, Pld -99, Data ‘http://nxpanel.xxxxxxxx.be/ns-panel.tft
23:45:03.671 MQT: stat/nspanel/RESULT = {“FlashNextion”:“Done”}
23:45:03.771 FLH: host: nxpanel.xxxxxxxxxx.be, port: 80, get: /ns-panel.tft
23:45:03.845 FLH: Connected:true
23:45:03.954 FLH: Retry 1
23:45:04.011 BRY: GC from 43467 to 21328 bytes, objects freed 431/355 (in 21 ms) - slots from 840/854 to 261/641
23:45:04.178 BRY: GC from 42680 to 21309 bytes, objects freed 350/355 (in 44 ms) - slots from 377/641 to 260/610
23:45:04.238 FLH: Size found in header, skip count
23:45:04.242 FLH: Flash file size: 162
23:45:04.247 NXP: Nextion command sent = bytes(‘4452414B4A485355594447424E434A48474A4B534842444EFFFFFF’)
23:45:04.255 NXP: Nextion command sent = bytes(‘7265636D6F643D30FFFFFF’)
23:45:04.259 NXP: Nextion command sent = bytes(‘7265636D6F643D30FFFFFF’)
23:45:04.265 NXP: Nextion command sent = bytes(‘636F6E6E656374FFFFFF’)
23:45:04.278 NXP: Received Raw = bytes(‘636F6D6F6B20322C33303631342D302C4E5834383332463033355F303131432C…’)
23:45:04.282 FLH: Send (High Speed) flash start
23:45:04.288 NXP: Nextion command sent = bytes(‘77686D692D77726973203136322C3131353230302C72657330FFFFFF’)
23:45:04.676 NXP: Received Raw = bytes(‘05’)
23:45:04.681 FLH: Read block
23:45:04.684 FLH: Buff size 162
23:45:04.689 FLH: Writing 162
23:45:04.702 MQT: tele/nspanel/RESULT = {“Flashing”:{“complete”: 0}}
23:45:04.738 FLH: Total 162
23:45:04.742 FLH: Flashing complete

Try to revert back to stock nspanel driver. The flash file size seems strange to me…

What is this?

That’s not a URL for anyhting?

Can you reboot the device and post the logs right from the beginning of the logs after boot (with weblog 4 on), until the point it does look like it’s working.
after typing

installnxpanel

You should have this at the start

I don’t think you’ve installed a correct tasmota.

Hi Mike back from holiday and ready to have another go at this. The flashing is a great improvement and the linking of items directly to buttons is much easier.

I’m now trying to setup the Music page - I can sync items fine but on the initial setup of the page I am not clear how to code this.

Managed to figure it out by trial and error -

 

case PANEL_MUSIC :
    logger.info("music panel")
    def artist_state = ir.getItem("Sonos_CurrentArtist").state.toString()
    def album = ir.getItem("Sonos_CurrentAlbum").state.toString()
    def track = ir.getItem("Sonos_CurrentTitle").state.toString()
    def volume = ir.getItem("Sonos_Volume").state.intValue()
    json = makePage(id,'Sonos Player')
    // set these from your own items
    json<<'"artist": "'<<artist_state<<'","album": "'<<album<<'","track":"'<<track<<'","volume":'<<volume
    json<<"}}"
    mqtt.publishMQTT(TOPIC, json.toString())
    break

the xxxxxxxxx is just to mask the real url… I installed Tasmota version 11.0.0.1 and the following info in console:
00:00:00.003 HDW: ESP32-D0WD-V3 (PSRAM)
00:00:00.003 HDW: FoundPSRAM=1 CanUsePSRAM=1
00:00:00.168 UFS: FlashFS mounted with 220 kB free
00:00:00.301 CFG: Loaded from File, Count 288
00:00:00.317 QPC: Count 1
00:00:00.319 CFG: CR 424/699, Busy 0
00:00:00.327 CFG: CR 424/699, Busy 0
00:00:00.330 ROT: Mode 1
00:00:00.332 BRY: GC from 1479 to 1479 bytes, objects freed 0/1 (in 1 ms) - slots from 6/46 to 6/46
00:00:00.343 BRY: GC from 3625 to 2993 bytes, objects freed 5/21 (in 1 ms) - slots from 35/61 to 24/61
00:00:00.039 CFG: No ‘*.autoconf’ file found
00:00:00.045 BRY: GC from 5042 to 4129 bytes, objects freed 5/41 (in 1 ms) - slots from 63/91 to 37/91
00:00:00.045 BRY: Berry initialized, RAM used=4129 bytes
00:00:00.076 BRY: No ‘preinit.be’
00:00:00.080 SRC: Restart
00:00:00.086 Project tasmota - NSPANEL Version 11.0.0.1(tasmota)-2_0_2_1(2022-02-18T15:35:14)
00:00:02.228 BRY: GC from 8352 to 7125 bytes, objects freed 18/103 (in 1 ms) - slots from 134/152 to 105/152
00:00:02.275 BRY: GC from 14259 to 13151 bytes, objects freed 18/187 (in 1 ms) - slots from 191/213 to 158/213
00:00:02.351 BRY: GC from 26329 to 23613 bytes, objects freed 46/359 (in 2 ms) - slots from 361/380 to 275/380
00:00:02.360 NXP: Initializing Driver
00:00:02.366 NXP: Nextion command sent = bytes(‘4452414B4A485355594447424E434A48474A4B534842444EFFFFFF’)
00:00:02.369 NXP: Nextion command sent = bytes(‘72657374FFFFFF’)
00:00:02.376 SRC: Berry
00:00:02.378 CMD: Grp 0, Cmd ‘RULE’, Idx 3, Len 1, Pld 1, Data ‘1’
00:00:02.381 RSL: RESULT = {“Rule3”:{“State”:“ON”,“Once”:“OFF”,“StopOnError”:“OFF”,“Length”:0,“Free”:511,“Rules”:""}}
00:00:02.388 BRY: Stack resized from 800 to 976 bytes
00:00:02.406 SRC: Berry
00:00:02.408 CMD: Grp 0, Cmd ‘STATE’, Idx 1, Len 0, Pld -99, Data ‘’
00:00:02.414 BRY: GC from 30572 to 20205 bytes, objects freed 61/348 (in 3 ms) - slots from 414/442 to 252/442
00:00:02.417 RSL: RESULT = {“Time”:“1970-01-01T00:00:02”,“Uptime”:“0T00:00:00”,“UptimeSec”:0,“Heap”:204,“SleepMode”:“Dynamic”,“Sleep”:0,“LoadAvg”:0,“MqttCount”:0,“Berry”:{“HeapUsed”:19,“Objects”:348},“POWER1”:“OFF”,“POWER2”:“OFF”}
00:00:02.452 BRY: Successfully loaded ‘autoexec.be’
00:00:02.502 NXP: Received Raw = bytes(‘1AFFFFFF’)
00:00:02.508 RSL: RESULT = {“nextion”:“bytes(‘1A’)”}
00:00:03.464 NXP: Received Raw = bytes(‘000000FFFFFF88FFFFFF’)
00:00:03.469 NXP: Screen Initialized
00:00:03.473 NXP: Nextion command sent = bytes(‘62657272792E7478743D22312E312E3322FFFFFF’)
00:00:03.476 NXP: Nextion command sent = bytes(‘636C69636B20696E69745F626E2C31FFFFFF’)
00:00:03.480 NXP: Nextion command sent = bytes(‘7265636D6F643D31FFFFFF’)
00:00:03.533 NXP: Switch state updated with { “switches”: { “switch1”: 0 , “switch2”: 0 } }
00:00:03.571 NXP: payload sent = bytes(‘5053002F007B20227377697463686573223A207B202273776974636831223A20…’)
00:00:03.699 BRY: GC from 40437 to 20219 bytes, objects freed 413/341 (in 12 ms) - slots from 906/928 to 254/533
00:00:03.717 NXP: Restoring: {“config”: {“wp”: 0, “dn”: 100, “st”: 30, “sm”: 0, “ah”: 0, “v”: “1.0.0”, “at”: 0, “ar”: 0, “au”: 0, “dl”: 10}}
00:00:03.800 BRY: GC from 40492 to 21100 bytes, objects freed 255/346 (in 10 ms) - slots from 590/626 to 254/564
00:00:03.820 NXP: payload sent = bytes(‘5053006F007B22636F6E666967223A207B227770223A20302C2022646E223A20…’)
00:00:03.822 NXP: Triggering update check
00:00:03.838 NXP: payload sent = bytes(‘5053000E007B22636F6E666967223A2022227D4570’)
00:00:03.843 WIF: Checking connection…
00:00:03.845 WIF: Attempting connection…
00:00:04.344 WIF: Connecting to AP1 APTON-NOACCESS Channel 11 BSSId 88:DC:96:28:D4:F8 in mode 11n as nspanel-4368…
00:00:04.861 NXP: Received Raw = bytes(‘02FFFFFF7B22636F6E666967223A7B2276223A22312E302E30222C226175223A…’)
00:00:05.000 RSL: RESULT = {“nextion”:“bytes(‘02FFFFFF7B22636F6E666967223A7B2276223A22312E302E30222C226175223A…’)”}
00:00:05.046 RSL: RESULT = {“config”:{“v”:“1.0.0”,“au”:0,“at”:0,“sm”:0,“st”:30,“wp”:0,“ar”:0,“ah”:0,“dl”:10,“dn”:100}}
00:00:05.074 NXP: persist msg: {‘config’: {‘ar’: 0, ‘dn’: 100, ‘st’: 30, ‘dl’: 10, ‘wp’: 0, ‘v’: ‘1.0.0’, ‘at’: 0, ‘au’: 0, ‘ah’: 0, ‘sm’: 0}}
00:00:05.171 NXP: persist saved
00:00:05.174 NXP: No auto update active
00:00:06.492 WIF: Checking connection…
00:00:06.494 WIF: Connected
00:00:06.545 NTP: Synch time…
00:00:06.605 RTC: UTC 2022-02-21T13:14:18, DST 2022-03-27T02:00:00, STD 2022-10-30T03:00:00
14:14:18.000 NTP: Synched
14:14:18.033 BRY: GC from 42224 to 20589 bytes, objects freed 393/347 (in 13 ms) - slots from 832/853 to 254/578
14:14:18.148 HTP: Web server active on nspanel-4368 with IP address 192.168.10.97
14:14:19.743 MQT: Attempting connection…
14:14:19.979 MQT: Connected
14:14:19.989 MQT: tele/nspanel/LWT = Online (retained)
14:14:20.003 MQT: cmnd/nspanel/POWER =
14:14:20.006 MQT: Subscribe to cmnd/nspanel/#
14:14:20.010 MQT: Subscribe to cmnd/tasmotas/#
14:14:20.013 MQT: Subscribe to cmnd/DVES_79D110_fb/#
14:14:20.017 MQT: Unsubscribe from homeassistant/status
14:14:20.025 MQT: tele/nspanel/INFO1 = {“Info1”:{“Module”:“NSPanel”,“Version”:“11.0.0.1(tasmota)”,“FallbackTopic”:“cmnd/DVES_79D110_fb/”,“GroupTopic”:“cmnd/tasmotas/”}}
14:14:20.078 MQT: tele/nspanel/INFO2 = {“Info2”:{“WebServerMode”:“Admin”,“Hostname”:“nspanel-4368”,“IPAddress”:“192.168.10.97”}}
14:14:20.116 MQT: tele/nspanel/INFO3 = {“Info3”:{“RestartReason”:“Vbat power on reset”,“BootCount”:137}}
14:14:20.158 MQT: stat/nspanel/RESULT = {“POWER1”:“OFF”}
14:14:20.164 MQT: stat/nspanel/POWER1 = OFF
14:14:20.172 MQT: stat/nspanel/RESULT = {“POWER2”:“OFF”}
14:14:20.178 MQT: stat/nspanel/POWER2 = OFF
14:14:20.197 TFS: File ‘autoexec.bat’ not found
14:14:22.042 NXP: Received Raw = bytes(‘7B22696E6974223A207B226E782D70616E656C223A2022312E302E30222C2022…’)
14:14:22.066 MQT: tele/nspanel/RESULT = {“init”: {“nx-panel”: “1.0.0”, “berry”: “1.1.3” }}
14:14:22.551 QPC: Reset
14:14:24.471 BRY: GC from 41186 to 20940 bytes, objects freed 489/356 (in 13 ms) - slots from 1072/1092 to 268/578
14:14:24.540 APP: Boot Count 137
14:14:24.551 BRY: GC from 20975 to 20617 bytes, objects freed 7/348 (in 4 ms) - slots from 270/578 to 256/563
14:14:24.567 MQT: tele/nspanel/STATE = {“Time”:“2022-02-21T14:14:24”,“Uptime”:“0T00:00:10”,“UptimeSec”:10,“Heap”:167,“SleepMode”:“Dynamic”,“Sleep”:0,“LoadAvg”:550,“MqttCount”:1,“Berry”:{“HeapUsed”:20,“Objects”:348},“POWER1”:“OFF”,“POWER2”:“OFF”,“Wifi”:{“AP”:1,“SSId”:“APTON-NOACCESS”,“BSSId”:“88:DC:96:28:D4:F8”,“Channel”:11,“Mode”:“11n”,“RSSI”:80,“Signal”:-60,“LinkCount”:1,“Downtime”:“0T00:00:03”}}
14:14:24.652 MQT: tele/nspanel/SENSOR = {“Time”:“2022-02-21T14:14:24”,“ANALOG”:{“Temperature1”:27.1},“ESP32”:{“Temperature”:53.3},“TempUnit”:“C”}
14:14:25.631 CFG: Saved, Count 289, Bytes 4096
14:14:29.568 MQT: tasmota/discovery/44179379D110/config = {“ip”:“192.168.10.97”,“dn”:“NSPANEL”,“fn”:[“NSPANEL”,"",null,null,null,null,null,null],“hn”:“nspanel-4368”,“mac”:“44179379D110”,“md”:“NSPanel”,“ty”:0,“if”:0,“ofln”:“Offline”,“onln”:“Online”,“state”:[“OFF”,“ON”,“TOGGLE”,“HOLD”],“sw”:“11.0.0.1”,“t”:“nspanel”,“ft”:"%prefix%/%topic%/",“tp”:[“cmnd”,“stat”,“tele”],“rl”:[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],“swc”:[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],“swn”:[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],“btn”:[0,0,0,0,0,0,0,0],“so”:{“4”:0,“11”:0,“13”:0,“17”:0,“20”:0,“30”:0,“68”:0,“73”:0,“82”:0,“114”:0,“117”:0},“lk”:0,“lt_st”:0,“sho”:[0,0,0,0],“ver”:1} (retained)
14:14:29.599 MQT: tasmota/discovery/44179379D110/sensors = {“sn”:{“Time”:“2022-02-21T14:14:29”,“ANALOG”:{“Temperature1”:27.1},“ESP32”:{“Temperature”:53.3},“TempUnit”:“C”},“ver”:1} (retained)
14:14:40.264 WIF: Checking connection…
14:14:48.386 BRY: GC from 41242 to 20915 bytes, objects freed 501/357 (in 12 ms) - slots from 1100/1122 to 267/609
14:15:00.263 WIF: Checking connection…
14:15:15.563 BRY: GC from 41842 to 20887 bytes, objects freed 552/356 (in 13 ms) - slots from 1157/1167 to 267/594
14:15:15.574 NXP: Time and date synced with { “clock”: { “date”:21,“month”:2,“year”:2022,“weekday”:1,“hour”:14,“min”:15 } }
14:15:15.637 NXP: payload sent = bytes(‘5053004F007B2022636C6F636B223A207B202264617465223A32312C226D6F6E…’)
14:15:20.264 WIF: Checking connection…
14:15:28.090 BRY: GC from 41791 to 20722 bytes, objects freed 463/350 (in 14 ms) - slots from 991/1020 to 258/624
14:15:40.263 WIF: Checking connection…
14:15:58.683 BRY: GC from 41468 to 20742 bytes, objects freed 545/351 (in 13 ms) - slots from 1140/1152 to 259/609
14:16:00.264 WIF: Checking connection…
14:16:00.557 NXP: Time and date synced with { “clock”: { “date”:21,“month”:2,“year”:2022,“weekday”:1,“hour”:14,“min”:16 } }
14:16:00.622 NXP: payload sent = bytes(‘5053004F007B2022636C6F636B223A207B202264617465223A32312C226D6F6E…’)
14:16:07.687 BRY: GC from 41501 to 20746 bytes, objects freed 457/351 (in 13 ms) - slots from 982/1020 to 259/640
14:16:20.264 WIF: Checking connection…
14:16:38.280 BRY: GC from 41516 to 21018 bytes, objects freed 542/358 (in 14 ms) - slots from 1143/1152 to 269/655
14:16:40.263 WIF: Checking connection…
14:17:00.285 WIF: Checking connection…
14:17:00.570 BRY: GC from 42056 to 21319 bytes, objects freed 539/361 (in 13 ms) - slots from 1148/1152 to 271/609
14:17:00.576 NXP: Time and date synced with { “clock”: { “date”:21,“month”:2,“year”:2022,“weekday”:1,“hour”:14,“min”:17 } }
14:17:00.642 NXP: payload sent = bytes(‘5053004F007B2022636C6F636B223A207B202264617465223A32312C226D6F6E…’)
14:17:17.987 BRY: GC from 42642 to 20961 bytes, objects freed 488/358 (in 14 ms) - slots from 1033/1065 to 270/640
14:17:20.263 WIF: Checking connection…
14:17:40.263 WIF: Checking connection…
14:17:43.584 CMD: FlashNextion http://nxpanel.pitconsult.be/nspanel.tft
14:17:43.588 SRC: WebConsole from 192.168.10.41
14:17:43.591 CMD: Grp 0, Cmd ‘FLASHNEXTION’, Idx 1, Len 40, Pld -99, Data ‘http://nxpanel.xxxxxxxxxxxxxx.be/nspanel.tft
14:17:43.610 MQT: stat/nspanel/RESULT = {“FlashNextion”:“Done”}
14:17:43.785 BRY: GC from 41961 to 20891 bytes, objects freed 547/354 (in 13 ms) - slots from 1151/1152 to 260/563
14:17:43.793 FLH: host: nxpanel.xxxxxxxxxx.be, port: 80, get: /nspanel.tft
14:17:43.874 FLH: Connected:true
14:17:43.983 FLH: Retry 1
14:17:44.107 BRY: GC from 41803 to 21379 bytes, objects freed 326/356 (in 33 ms) - slots from 372/563 to 261/563
14:17:44.189 FLH: Size found in header, skip count
14:17:44.192 FLH: Flash file size: 162
14:17:44.198 NXP: Nextion command sent = bytes(‘4452414B4A485355594447424E434A48474A4B534842444EFFFFFF’)
14:17:44.204 NXP: Nextion command sent = bytes(‘7265636D6F643D30FFFFFF’)
14:17:44.211 NXP: Nextion command sent = bytes(‘7265636D6F643D30FFFFFF’)
14:17:44.218 NXP: Nextion command sent = bytes(‘636F6E6E656374FFFFFF’)
14:17:44.234 NXP: Received Raw = bytes(‘636F6D6F6B20322C33303631342D302C4E5834383332463033355F303131432C…’)
14:17:44.240 FLH: Send (High Speed) flash start
14:17:44.247 NXP: Nextion command sent = bytes(‘77686D692D77726973203136322C3131353230302C72657330FFFFFF’)
14:17:44.630 NXP: Received Raw = bytes(‘05’)
14:17:44.635 FLH: Read block
14:17:44.673 BRY: GC from 42807 to 20847 bytes, objects freed 325/348 (in 33 ms) - slots from 367/563 to 256/563
14:17:44.676 FLH: Buff size 162
14:17:44.680 FLH: Writing 162
14:17:44.693 MQT: tele/nspanel/RESULT = {“Flashing”:{“complete”: 0}}
14:17:44.726 FLH: Total 162
14:17:44.729 FLH: Flashing complete
14:18:00.515 WIF: Checking connection…

The issue seems to be with your web server serving the page if you look at your message it says the content-length is 162

14:17:43.785 BRY: GC from 41961 to 20891 bytes, objects freed 547/354 (in 13 ms) - slots from 1151/1152 to 260/563
14:17:43.793 FLH: host: [nxpanel.xxxxxxxxxx.be](http://nxpanel.xxxxxxxxxx.be/), port: 80, get: /nspanel.tft
14:17:43.874 FLH: Connected:true
14:17:43.983 FLH: Retry 1
14:17:44.107 BRY: GC from 41803 to 21379 bytes, objects freed 326/356 (in 33 ms) - slots from 372/563 to 261/563
14:17:44.189 FLH: Size found in header, skip count
14:17:44.192 FLH: Flash file size: 162
14:17:44.198 NXP: Nextion command sent = bytes(‘4452414B4A485355594447424E434A48474A4B534842444EFFFFFF’)

That should be the length of the file, which is a lot more than that, so I don’t think your web server is returning the correct stream for the URL.

Rather than trying to serve the file from your own web server why don’t you just try typing;

installnxpanel

That will download it from mine, which I know works.

Short of that, you’ll need to adress why your webserver in not returning the right thing.
you could uncomment this line in the berry file;
image.png

Which would show you what your headers are, might give you a clue.

I was going to say what you had looks right to me! :slight_smile: Then I read above and you said you sorted it! lol

Looks good, you can also send another sync message as the track changes, which (if that screen is showing) will the change it realtime.

I’ve got a rule that does the sync so that is working fine. I am not clear on how to do the play and pause though. The volume was easy because it had a specific sync so I could link it just like a switch:

{"sync":{"pid":20,"volume":49}}

  - id: nx_panel_sonos_volume
    channelTypeUID: mqtt:dimmer
    label: Sonos volume
    description: null
    configuration:
      postCommand: true
      min: 0
      formatBeforePublish: "'{\"sync\":{\"pid\":20,\"volume\":%d}}'"
      max: 100
      commandTopic: cmnd/nspanel/nxpanel
      transformationPattern: REGEX:(.*\"volume\":.*)∩JSONPATH:$.media.volume
      stateTopic: tele/nspanel/RESULT

For the play/pause button it is sending 2 commands so linking to a single item is not possible afaik. Is there anyway to have a simple button or sync for this? The current setup seems to send volume with everything.

{"media":{"action":"play","volume":29}}

the volume one is fine

for play, it’d create a trigger channel with a REGEX of

.*\"pid\":20.*play.*

drop the 20 bit now, as it’s missing from the message, that’s a bug, I should send that!!
since you could have a different one in each room. so from now, just the play, but it shoudl have pid in, when fix it, as all the outgoing commands nxpanel sends should.

then you can have a rule which is of the format;
when trigger channel then do command (play on sonos)

same for stop/pause next or whatever

sound right?