# Control Panasonic TV with Node Red

**URL:** https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923
**Category:** General
**Created:** [4 July 2019 18:00 UTC](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923 "2019-07-04T18:00:45Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![nodecentral](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nodecentral/32/10432_2.png) [@nodecentral](https://discourse.nodered.org/u/nodecentral)
#### Post date: [4 July 2019 18:00 UTC](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923/1 "2019-07-04T18:00:45Z")

</div>

Hi

I’ve come across some javascript code to control a Panasonic tv, please could someone help me to work this into a flow ?

```auto
  var VieraJS = require("viera.js-g30r93g");
  var viera = new VieraJS("ipAddress");
  
  viera.sendRequest("Command", "X_SendKey", "<X_KeyEvent>NRC_" + command.toUpperCase() + "-ONOFF</X_KeyEvent>");
  
  viera.sendCommand("Power");
  viera.sendCommand("Up");
  viera.sendCommand("Menu");
  
  viera.sendHDMICommand(1);
  viera.sendHDMICommand(2);
  
  viera.sendAppCommand("0010000200000001"); // Netflix
  viera.sendAppCommand("0010000100170001"); // Amazon Prime Video
  viera.sendAppCommand("0070000200170001"); // YouTube
  
  viera.getMute((status) => {
    console.log("Mute: " + status);
  });
  viera.getVolume((volume) => {
    console.log("Volume: " + volume);
  });
  
  viera.setMute(true);
  viera.setVolume(30);

```

Huge credit to the creator if I can get this to work, [https://github.com/g30r93g/viera.js](https://github.com/g30r93g/viera.js)

---

<div class="post-metadata">

### Author: ![nodecentral](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nodecentral/32/10432_2.png) [@nodecentral](https://discourse.nodered.org/u/nodecentral)
#### Post date: [5 July 2019 07:44 UTC](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923/2 "2019-07-05T07:44:20Z")

</div>

Based on the limited coding knowledge, if the code is calling something (like a function). I need to have that defined somewhere.

The github link, shows the supporting files/information, and what looks to be the key file Viera.js - do I bring that file in via an import of something, or do I copy and paste the content into the same or a different function node ?

---

<div class="post-metadata">

### Author: ![nodecentral](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nodecentral/32/10432_2.png) [@nodecentral](https://discourse.nodered.org/u/nodecentral)
#### Post date: [5 July 2019 07:50 UTC](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923/3 "2019-07-05T07:50:16Z")

</div>

This part of Viera.js looks to be for the verification of the IP address - which I potentially don’t need.

```auto
var Viera = function(ipAddress) {
        // Check if ipAddress is valid IP address
        var ipRegExp = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/;

        if (ipRegExp.test(ipAddress)) {
            this.ipAddress = ipAddress;
        } else {
            throw new TypeError('You entered invalid IP address!');
        }
    };

```

---

<div class="post-metadata">

### Author: ![nodecentral](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nodecentral/32/10432_2.png) [@nodecentral](https://discourse.nodered.org/u/nodecentral)
#### Post date: [5 July 2019 07:51 UTC](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923/4 "2019-07-05T07:51:51Z")

</div>

This seems to be the meat of what I likely need.

```auto
    /**
     * Create and send request to the TV
     *
     * @param {String} type Type of your request                        
     * @param {String} action The xml action type to perform
     * @param {String} command The command from codes.txt you want to perform
     * @param {Array} options Options array (mostly for callback)
     */
     Viera.prototype.sendRequest = function(type, action, command, options) {
        var url, urn;
        if (type === 'command') {
            url = '/nrc/control_0';
            urn = 'panasonic-com:service:p00NetworkControl:1';
        } else if (type === 'render') {
            url = '/dmr/control_0';
            urn = 'schemas-upnp-org:service:RenderingControl:1';
        }

        var body = '<?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:'+action+' xmlns:u="urn:'+urn+'"> \
                      '+command+' \
                     </u:'+action+'> \
                    </s:Body> \
                    </s:Envelope>';

        var postRequest = {
            host: this.ipAddress,
            path: url,
            port: 55000,
            method: "POST",
            headers: {
                'Content-Length': body.length,
                'Content-Type': 'text/xml; charset="utf-8"',
                'SOAPACTION': '"urn:'+urn+'#'+action+'"'
            }
        };

        var self = this;
        if (options !== undefined) {
            self.callback = options.callback;
        } else {
            self.callback = function () {};
        }

        var req = http.request(postRequest, (res) => {
            res.setEncoding('utf8');
            res.on('data', self.callback);
        });

        req.on('error', (e) =>{
            console.log('error: ' + e.message);
            console.log(e);
        });

        req.write(body);
        req.end();

        return this;
    };

```

---

<div class="post-metadata">

### Author: ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)
#### Post date: [5 July 2019 07:53 UTC](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923/5 "2019-07-05T07:53:46Z")

</div>

In `settings.js` under `functionGlobalContext` you could add this library to make it available for functions.

Looking at the library, it basically creates and sends an SOAP (XML) envelope to the TV, which you could (re)create yourself and use a http post to send the file directly.

---

<div class="post-metadata">

### Author: ![nodecentral](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nodecentral/32/10432_2.png) [@nodecentral](https://discourse.nodered.org/u/nodecentral)
#### Post date: [5 July 2019 07:55 UTC](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923/6 "2019-07-05T07:55:29Z")

</div>

Hi @bakman2

Thanks so much for responding, although you’re going to have to help a novice programmer like me out..

What section or code or file, constitutes being a ‘library’?

And then what would I do within a flow exactly to make use of it ?

---

<div class="post-metadata">

### Author: ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)
#### Post date: [5 July 2019 07:56 UTC](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923/7 "2019-07-05T07:56:55Z")

</div>

I will create an example (can't test it myself).

---

<div class="post-metadata">

### Author: ![nodecentral](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nodecentral/32/10432_2.png) [@nodecentral](https://discourse.nodered.org/u/nodecentral)
#### Post date: [5 July 2019 07:57 UTC](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923/8 "2019-07-05T07:57:23Z")

</div>

Awesome, thanks !

---

<div class="post-metadata">

### Author: ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)
#### Post date: [5 July 2019 08:14 UTC](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923/9 "2019-07-05T08:14:19Z")

</div>

This is the idea of the viera.js "library"

```auto
[{"id":"41273357.16c744","type":"inject","z":"7be082eb.bb1594","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":264,"wires":[["7afa94be.f2855c"]]},{"id":"7afa94be.f2855c","type":"function","z":"7be082eb.bb1594","name":"set xml","func":"xml = '<?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:schemas-upnp-org:service:RenderingControl:1\"><X_KeyEvent>NRC_POWER-ONOFF</X_KeyEvent></u:X_SendKey></s:Body></s:Envelope>'\nheaders = {\n'Content-Type': 'text/xml; charset=\"utf-8\"',\n'SOAPACTION': '\"urn:X_SendKey#NRC_POWER-ONOFF'\n}\n\nreturn {headers:headers,payload:xml}","outputs":1,"noerr":0,"x":324,"y":264,"wires":[["e5c86241.c123e8","416522f5.a46944"]]},{"id":"61a769eb.a47a88","type":"http request","z":"7be082eb.bb1594","name":"","method":"POST","ret":"txt","paytoqs":false,"url":"http://tv-ipaddress:55000/nrc/control_0","tls":"","proxy":"","authType":"basic","x":642,"y":374,"wires":[["9362629d.fb97f8"]]},{"id":"416522f5.a46944","type":"debug","z":"7be082eb.bb1594","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":622,"y":264,"wires":[]},{"id":"e5c86241.c123e8","type":"xml","z":"7be082eb.bb1594","name":"","property":"payload","attr":"","chr":"","x":468,"y":308,"wires":[["416522f5.a46944","61a769eb.a47a88"]]},{"id":"9362629d.fb97f8","type":"debug","z":"7be082eb.bb1594","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":794,"y":374,"wires":[]}]

```

Change the http request node:

`http://tv-ipaddress:55000/nrc/control_0` replace `tv-ipaddress` with your tv's ip adress.

As I cannot test it, can't guarantee that it works. But look at all the outputs in the debug window and see what is being send. The viera.js library generates "dynamic" xml output based on the commands. In this example I used the POWER command. All the commands could be dynamic in node-red as well by using a switch node or something.

---

<div class="post-metadata">

### Author: ![nodecentral](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nodecentral/32/10432_2.png) [@nodecentral](https://discourse.nodered.org/u/nodecentral)
#### Post date: [5 July 2019 13:46 UTC](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923/10 "2019-07-05T13:46:16Z")

</div>

Thanks, i have tried the flow, but it does not seem to work, returning what I assume is a 400 'bad request' error ?

To help troubleshoot, here's the first debug output, on the message sent

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/f/f29ca89ab112978aef8fa0c15673ec24031f2b29.png)

Here's the second

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/7/731b9884225721b6ab6ddce90a5962e383038eb9.png)

And here is the response back.

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/0/0f282bd46279ebf95f69833152ec4b879d1cc9b3.png)

Any ideas ?

---

<div class="post-metadata">

### Author: ![nodecentral](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nodecentral/32/10432_2.png) [@nodecentral](https://discourse.nodered.org/u/nodecentral)
#### Post date: [5 July 2019 13:48 UTC](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923/11 "2019-07-05T13:48:34Z")

</div>

Checking that URL

[http://192.168.102.200:55000/nrc/control\_0](http://192.168.102.200:55000/nrc/control_0)

I get the following message

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/1/12ffb2fe7bb10f29db8afb0ba172d8e5f026f49c.png)

---

<div class="post-metadata">

### Author: ![nodecentral](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nodecentral/32/10432_2.png) [@nodecentral](https://discourse.nodered.org/u/nodecentral)
#### Post date: [5 July 2019 13:58 UTC](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923/12 "2019-07-05T13:58:11Z")

</div>

FYI - I'm currently focussing on this section, to see if we maybe have the wrong one. As 'Power' would be a command ?

```auto
        var url, urn;
        if (type === 'command') {
            url = '/nrc/control_0';
            urn = 'panasonic-com:service:p00NetworkControl:1';
        } else if (type === 'render') {
            url = '/dmr/control_0';
            urn = 'schemas-upnp-org:service:RenderingControl:1';

```

---

<div class="post-metadata">

### Author: ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)
#### Post date: [5 July 2019 14:01 UTC](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923/13 "2019-07-05T14:01:39Z")

</div>

The access denied is likely, because that page expects a POST request. But looking at the headers, I made a typo.

Could you replace the function node with this:

```auto
xml = '<?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="panasonic-com:service:p00NetworkControl:1"><X_KeyEvent>NRC_POWER-ONOFF</X_KeyEvent></u:X_SendKey></s:Body></s:Envelope>'
headers = {
'Content-Type': "text/xml; charset=utf-8",
'SOAPACTION': 'urn:X_SendKey#NRC_POWER-ONOFF'
}

return {headers:headers,payload:xml}

```

It is not the "wrong" one. In the viera.js library there is a codes.txt file containing the available commands.

The function they use is for dynamically generating the xml.

---

<div class="post-metadata">

### Author: ![nodecentral](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nodecentral/32/10432_2.png) [@nodecentral](https://discourse.nodered.org/u/nodecentral)
#### Post date: [5 July 2019 14:01 UTC](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923/14 "2019-07-05T14:01:50Z")

</div>

Nope, no joy there, same 400 error .😢

Here's the payload..

> payload: "\<?xml version="1.0" encoding="utf-8"?\>\<s:Envelope xmlns:s="[http://schemas.xmlsoap.org/soap/envelope/](http://schemas.xmlsoap.org/soap/envelope/)" s:encodingStyle="[http://schemas.xmlsoap.org/soap/encoding/](http://schemas.xmlsoap.org/soap/encoding/)"\>\<s:Body\>\<u:X\_SendKey xmlns:u="urn:schemas-upnp-org:service:RenderingControl:1"\>\<X\_KeyEvent\>NRC\_POWER-ONOFF\</X\_KeyEvent\>\</u:X\_SendKey\>\</s:Body\>\</s:Envelope\>"

---

<div class="post-metadata">

### Author: ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)
#### Post date: [5 July 2019 14:04 UTC](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923/15 "2019-07-05T14:04:25Z")

</div>

I edited it again, more typos. try again.

---

<div class="post-metadata">

### Author: ![nodecentral](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nodecentral/32/10432_2.png) [@nodecentral](https://discourse.nodered.org/u/nodecentral)
#### Post date: [5 July 2019 14:06 UTC](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923/16 "2019-07-05T14:06:50Z")

</div>

Nope, still the same 400 error

Here's the payload generated..

> payload: "\<?xml version="1.0" encoding="utf-8"?\>\<s:Envelope xmlns:s="[http://schemas.xmlsoap.org/soap/envelope/](http://schemas.xmlsoap.org/soap/envelope/)" s:encodingStyle="[http://schemas.xmlsoap.org/soap/encoding/](http://schemas.xmlsoap.org/soap/encoding/)"\>\<s:Body\>\<u:X\_SendKey xmlns:u="panasonic-com:service:p00NetworkControl:1"\>\<X\_KeyEvent\>NRC\_POWER-ONOFF\</X\_KeyEvent\>\</u:X\_SendKey\>\</s:Body\>\</s:Envelope\>"

---

<div class="post-metadata">

### Author: ![nodecentral](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nodecentral/32/10432_2.png) [@nodecentral](https://discourse.nodered.org/u/nodecentral)
#### Post date: [5 July 2019 14:10 UTC](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923/17 "2019-07-05T14:10:47Z")

</div>

added "urn" to the bigining of the xmlns to see it that might be it, nope 400 error again..

> payload: "\<?xml version="1.0" encoding="utf-8"?\>\<s:Envelope xmlns:s="[http://schemas.xmlsoap.org/soap/envelope/](http://schemas.xmlsoap.org/soap/envelope/)" s:encodingStyle="[http://schemas.xmlsoap.org/soap/encoding/](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\>"

---

<div class="post-metadata">

### Author: ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)
#### Post date: [5 July 2019 14:12 UTC](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923/18 "2019-07-05T14:12:38Z")

</div>

New flow:

```auto
[{"id":"1640edf4.88503a","type":"inject","z":"99f892ff.d32518","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":192,"y":176,"wires":[["ffca154d.4d456"]]},{"id":"ffca154d.4d456","type":"function","z":"99f892ff.d32518","name":"set xml","func":"msg.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=\"panasonic-com:service:p00NetworkControl:1\"><X_KeyEvent>NRC_POWER-ONOFF</X_KeyEvent></u:X_SendKey></s:Body></s:Envelope>'\nmsg.headers = {\n'content-type':'application/xml',\n'SOAPACTION': 'urn:X_SendKey#NRC_POWER-ONOFF'\n}\n\nreturn {headers:msg.headers,payload:msg.payload}","outputs":1,"noerr":0,"x":346,"y":176,"wires":[["1e44c35b.7dde4d","35dd0944.9cff66"]]},{"id":"35dd0944.9cff66","type":"http request","z":"99f892ff.d32518","name":"","method":"POST","ret":"txt","paytoqs":false,"url":"http://tv-ipaddress:55000/nrc/control_0","tls":"","proxy":"","authType":"basic","x":532,"y":220,"wires":[["162310d1.73a797"]]},{"id":"1e44c35b.7dde4d","type":"debug","z":"99f892ff.d32518","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":512,"y":154,"wires":[]},{"id":"162310d1.73a797","type":"debug","z":"99f892ff.d32518","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":666,"y":220,"wires":[]}]

```

If it doesn't work, I don't know how to help further.

---

<div class="post-metadata">

### Author: ![nodecentral](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nodecentral/32/10432_2.png) [@nodecentral](https://discourse.nodered.org/u/nodecentral)
#### Post date: [5 July 2019 14:20 UTC](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923/19 "2019-07-05T14:20:53Z")

</div>

Sadly no, same 400 message again...

---

<div class="post-metadata">

### Author: ![afelix](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/afelix/32/9743_2.png) [@afelix](https://discourse.nodered.org/u/afelix)
#### Post date: [5 July 2019 14:30 UTC](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923/20 "2019-07-05T14:30:38Z")

</div>

Have you tried the JavaScript library from the first post directly, without the “via node-red” part? If that one doesn’t work too, the problem isn’t in your flow.

[Next page](https://discourse.nodered.org/t/control-panasonic-tv-with-node-red/12923.md?page=2)
