Control Panasonic TV with Node Red

Found other variations online, but not sure exactly how to verify them ?

url: http://192.168.1.98:55000/nrc/control_0
method: POST
headers:
content-type: application/xml
SOAPAction: '"urn:panasonic-com:service:p00NetworkControl:1#X_SendKey"'
payload: '<?xml version="1.0" encoding="utf-8"?> <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <s:Body> <u:X_SendKey xmlns:u="urn:panasonic-com:service:p00NetworkControl:1"> <X_KeyEvent>NRC_POWER-ONOFF</X_KeyEvent> </u:X_SendKey> </s:Body> </s:Envelope>'
content_type: 'text/xml'
verify_ssl: false

Another

OST /nrc/control_0 HTTP/1.1
User-Agent: Panasonic iOS VR-CP UPnP/2.0
Host: 10.0.1.15:55000
Content-Type: text/xml; charset="utf-8"
SOAPACTION: "urn:panasonic-com:service:p00NetworkControl:1#X_SendKey"
Content-Length: 334

<?xml version="1.0" encoding="utf-8"?>

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:X_SendKey xmlns:u="urn:panasonic-com:service:p00NetworkControl:1">
<X_KeyEvent>NRC_CH_DOWN-ONOFF</X_KeyEvent>
</u:X_SendKey>
</s:Body>
</s:Envelope>

Another

Accept: text/xml
Cache-Control: no-cache
Pragma: no-cache
SOAPACTION: "urn:panasonic-com:service:p00NetworkControl:1#X_SendKey"
Content-Length: 324
Content-Type: text/xml;charset="utf-8

<?xml version="1.0" encoding="utf-8"?>

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:X_SendKey xmlns:u="urn:panasonic-com:service:p00NetworkControl:1">
<X_KeyEvent>NRC_POWER-ONOFF</X_KeyEvent>
</u:X_SendKey>
</s:Body>
</s:Envelope>

And a Curl command too

execute "curl -s -i -H 'Accept: text/xml' -H 'Cache-Control: no-cache' -H 'Pragma: no-cache' -H 'SOAPACTION: 'urn:panasonic-com:service:p00NetworkControl:1#X_SendKey'' -H 'Content-Length: 200' -H 'Content-Type: text/xml;charset='utf-8'' -X POST --data '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body> <u:X_SendKey xmlns:u="urn:panasonic-com:service:p00NetworkControl:1"> <X_KeyEvent>NRC_POWER-ONOFF</X_KeyEvent></u:X_SendKey> </s:Body> </s:Envelope>' http://192.168.102.200:55000/nrc/control_0/?"

More than happy to give that a go, but how would I do that exactly ?

Write a sample script following the Readme from the library, see the link in the first post. Then set it up to run as script in your package.json file and execute it: https://docs.npmjs.com/cli/run-script

Sorry, where would I start with that - I've got very little experience of javascript?

In the past - when working with code, I've usually reworked something that already exists, that I know works, but this stumps me on what to do first ?

In that case I’d say wait a bit. JavaScript writing experience is definitely needed for that step. I’m going to look up some related details on that tv in a couple hours regarding authentication (as that’s likely causing the 403 error you’re seeing) but I think I need my laptop for that. Will post back later (could be tomorrow) with additional information

I have an older plasma panasonic and to my surprise it supports this api stuff.

on the commandline this works for me:

curl -s -i -H "Accept: text/xml" -H "Cache-Control: no-cache" -H "Pragma: no-cache" -H "SOAPACTION: \"urn:panasonic-com:service:p00NetworkControl:1#X_SendKey\"" -H "Content-Length: 200" -H "Content-Type: text/xml;charset=\"utf-8\"" -X POST --data "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body> <u:X_SendKey xmlns:u=\"urn:panasonic-com:service:p00NetworkControl:1\"> <X_KeyEvent>NRC_MENU-ONOFF</X_KeyEvent></u:X_SendKey> </s:Body> </s:Envelope>" http://10.0.0.246:55000/nrc/control_0/?

(change the ip address on the end)

I have tried to convert it into a function but somehow it is not parsed properly by the http request node. I will dig a little further.

Thanks for the continuing support @bakman2

When I try that curl command on my 55FZ952 - I get the following back

HTTP/1.1 500 Internal Server Error
CONTENT-LENGTH: 487
Content-Type: text/xml; charset="utf-8"
EXT:
SERVER: Panasonic-VIErA/1, UPnP/1.0, Panasonic MIL DLNA SERVER
CONNECTION: close

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
 <s:Body>
  <s:Fault>
   <faultcode>s:Client</faultcode>
   <faultstring>UPnPError</faultstring>
   <detail>
    <UPnPError xmlns="urn:schemas-upnp-org:control-1-0">
     <errorCode>401</errorCode>
     <errorDescription>Invalid action</errorDescription>
    </UPnPError>
   </detail>
  </s:Fault>
 </s:Body>
</s:Envelope>

Okay, humour me for a while. I can’t find the answer on google, but is this model from Panasonic’s Viera powered smart TV series, or is it running something else? I can’t find it in any of the Viera lists, nor can I find any references to Viera on this model. The thing is, this script, and the control for it, is specifically for Panasonic TVs in the Viera series.
But since in the previous message the headers show Panasonic/Viera as server, I’m expecting it to run Viera.

While searching, I found another usage with that library that sets up a local server to connect/control the TV. The point isn’t to have it replace your NR setup, just to see if things work in the first place. I also found a python library to connect with it that mentions that the newer models come with authentication and that you should request the TV for a key/password first. Considering the script posted in the first post is about 6 years old, and your TV is not, can you take a look at this link?


For the newest models, including one similar to yours there’s currently a connection/authentication issue, but reading that code it sounds doable to create a node for it.

Reading through the code a bit more, you need python 2 or 3, and to install the Crypto library. Can you check if it works? If so I think I can port that code to JavaScript/custom node, except I don’t have a Panasonic to test it with.

That a great find, and as my Panasonic model is an ‘ FZ ‘ which is specially mentioned , that makes sense why it has not been working for me..

Interestingly the volume command (via the old Viera node/module) does still work on these new TVs, it’s the only thing that does; - and based on what you found it seems they’ve restricted the use of the other controls/commands.

I’ve been trying to get this to work, but python is just not my thing; however on a positive note that issue you shared mentioned (@ ngws commented on 28 Mar ) having success with my make/model of tv, which is awesome.

I’m halfway porting the encryption to JavaScript. Javascript is not my best language, while Python I can do in my sleep. Most JavaScript I’ve written over the last years was all client-side, executing in the browser. Having to think of node just brings it as another challenge :slight_smile:

@nodecentral @bakman2 as you both have panasonic TVs, one with encryption and one without, can both of you do me a favour? I'm porting the python code, but I don't have any of the XML/SOAP inputs this is based on. So while writing xpath is normally a good challenge, doing so without having any XML to test it on to verify is a bridge too far when it comes to debugging if it is fully correct.

Can both of you please open the following page, regular web browser should do, and post me the output? Can via DM if preferred. http://<ip-of-tv>:55000/nrc/sdd_0.xml
For the encrypted version there should be a child tag to the root element ending on actionList, but I don't know if that's a local or namespaced name and it would make it a lot more readable knowing. Directly below that there's supposed a tag ending on name, but again that could be the last part of a longer tag, or just a namespaced tag. That ...name tag is supposed to have a child text element X_GetEncryptSessionId.
Knowing what that XML looks is for me the difference between an xpath like /actionList/name[text()="X_GetEncryptSessionId] or a monstrosity like /child::*[substring(local-name(), string-length(local-name()) - string-length("actionList") + 1)="actionList"]/child::*[substring(local-name(), string-length(local-name()) - string-length("name") + 1)="name" and text()="X_GetEncryptSessionId"].

Unless anyone has a decent XPath 2.0 or 2.1 library for Javascript (if so I'll worship you :pray:), that last horrifying thing will end up in the code :joy:

rename to xml
sdd_0.txt (6.9 KB)

Unless anyone has a decent XPath 2.0 or 2.1 library for Javascript (if so I'll worship you :pray:), that last horrifying thing will end up in the code :joy:

This is actually reasonably simple in node-red (xml > json) with jsonata.

Thank you so much, this shows exactly which part I'm missing :slight_smile:

Oh yes it is, and it's also pretty simply in xpath 2.1 :stuck_out_tongue: just a child::*[ends-with(local-name(), "actionList)] and so on. But much harder through just DOM parsing in XML with xpaths, and I'm trying to keep the dependencies for this thing as low as possible, as (compared to python) node based javascript feels like dependency hell enough on its own.

Even simpler with that xml file: //actionList/action/name[text()="X_GetEcryptSessionId"] should already do the trick :slight_smile:

I’m an iPad user so the response via the Safari browser is not formatted at all, if I try it via node Red I get a little more in the debug window, up to the character limit.

Thanks, this is perfect, shows I can do it the far easier way. I can use the same path to deal with both types of TVs without having to worry it will fail :slight_smile:

Hi @afelix

What can I do in node red to give you all the xml returned by my tv from that url ?

Send the debug to the console as well as the sidebar. It wont be truncated