node-red-contrib-lgtv-notify 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@
7
7
  host: { value: '', required: true }
8
8
  },
9
9
  credentials: {
10
- clientKey: { type: 'text' }
10
+ clientKey: { type: 'password' }
11
11
  },
12
12
  label: function() {
13
13
  return this.name || this.host || 'LG TV';
@@ -30,6 +30,41 @@
30
30
  </div>
31
31
  </script>
32
32
 
33
+ <script type="text/html" data-help-name="lgtv-config">
34
+ <p>Configuration node for LG webOS TV connection.</p>
35
+
36
+ <h3>Properties</h3>
37
+ <dl class="message-properties">
38
+ <dt>Name <span class="property-type">string</span></dt>
39
+ <dd>A friendly name for this TV (e.g., "Living Room TV").</dd>
40
+ <dt>TV IP <span class="property-type">string</span></dt>
41
+ <dd>The IP address of your LG TV on the local network.</dd>
42
+ </dl>
43
+
44
+ <h3>Finding your TV's IP Address</h3>
45
+ <ol>
46
+ <li>On your TV, go to <strong>Settings > Network > Wi-Fi Connection</strong></li>
47
+ <li>Select your connected network</li>
48
+ <li>The IP address will be displayed (e.g., 192.168.1.100)</li>
49
+ </ol>
50
+
51
+ <h3>Pairing Process</h3>
52
+ <p>When you first deploy a flow using this TV configuration:</p>
53
+ <ol>
54
+ <li>A pairing prompt will appear on your TV screen</li>
55
+ <li>Use your TV remote to select "Accept"</li>
56
+ <li>The pairing key is saved automatically</li>
57
+ <li>Future connections will happen automatically</li>
58
+ </ol>
59
+
60
+ <h3>Requirements</h3>
61
+ <ul>
62
+ <li>TV must be powered on (not in standby mode)</li>
63
+ <li>"LG Connect Apps" must be enabled: Settings > General > External Device Manager > LG Connect Apps</li>
64
+ <li>TV and Node-RED server must be on the same network</li>
65
+ </ul>
66
+ </script>
67
+
33
68
  <!-- LG TV Notify Node -->
34
69
  <script type="text/javascript">
35
70
  RED.nodes.registerType('lgtv-notify', {
@@ -68,12 +103,12 @@
68
103
  </script>
69
104
 
70
105
  <script type="text/html" data-help-name="lgtv-notify">
71
- <p>Send toast notifications to an LG webOS TV.</p>
106
+ <p>Send toast notifications to an LG webOS Smart TV.</p>
72
107
 
73
108
  <h3>Inputs</h3>
74
109
  <dl class="message-properties">
75
110
  <dt>payload <span class="property-type">string</span></dt>
76
- <dd>The notification message to display on the TV.</dd>
111
+ <dd>The notification message to display on the TV (max 60 characters recommended).</dd>
77
112
  </dl>
78
113
 
79
114
  <h3>Outputs</h3>
@@ -82,15 +117,43 @@
82
117
  <dd>The original message.</dd>
83
118
  <dt>toastId <span class="property-type">string</span></dt>
84
119
  <dd>The ID of the created toast notification.</dd>
120
+ <dt>tvResponse <span class="property-type">object</span></dt>
121
+ <dd>The full response from the TV API.</dd>
85
122
  </dl>
86
123
 
87
124
  <h3>Details</h3>
88
- <p>This node sends a toast notification to an LG webOS Smart TV.</p>
89
- <p>The notification will appear in the top-right corner of the TV screen for approximately 5 seconds.</p>
90
- <p><strong>First use:</strong> When you first deploy, check your TV for a pairing prompt and accept it.</p>
125
+ <p>This node sends a toast notification to an LG webOS Smart TV. The notification appears in the top-right corner of the TV screen for approximately 5 seconds.</p>
126
+
127
+ <h4>First-time Setup</h4>
128
+ <ol>
129
+ <li>Configure the TV node with your TV's IP address</li>
130
+ <li>Deploy the flow</li>
131
+ <li><strong>Important:</strong> Accept the pairing prompt on your TV</li>
132
+ <li>The pairing key is saved automatically for future connections</li>
133
+ </ol>
134
+
135
+ <h4>Example Usage</h4>
136
+ <p>Send a simple notification:</p>
137
+ <pre>msg.payload = "Doorbell: Someone is at the door!";
138
+ return msg;</pre>
139
+
140
+ <h4>Requirements</h4>
141
+ <ul>
142
+ <li>LG webOS Smart TV (webOS 3.0 or newer, including 2025 models)</li>
143
+ <li>TV and Node-RED must be on the same network</li>
144
+ <li>"LG Connect Apps" must be enabled on the TV (Settings > General > External Device Manager)</li>
145
+ </ul>
146
+
147
+ <h4>Troubleshooting</h4>
148
+ <ul>
149
+ <li><strong>TV not connecting:</strong> Ensure TV is powered on (not standby), wait ~25 seconds after power-on</li>
150
+ <li><strong>No pairing prompt:</strong> Restart Node-RED and redeploy</li>
151
+ <li><strong>Notifications not showing:</strong> TV must be on and displaying content</li>
152
+ </ul>
91
153
 
92
154
  <h3>References</h3>
93
155
  <ul>
94
- <li><a href="https://github.com/rcaldeira/node-red-contrib-lgtv-notify">GitHub</a> - the node's repository</li>
156
+ <li><a href="https://github.com/Ricardo-Miguel-Caldeira/node-red-contrib-lgtv-notify">GitHub Repository</a></li>
157
+ <li><a href="https://www.npmjs.com/package/node-red-contrib-lgtv-notify">npm Package</a></li>
95
158
  </ul>
96
159
  </script>
@@ -40,6 +40,7 @@ module.exports = function(RED) {
40
40
 
41
41
  node.connection.on('error', (err) => {
42
42
  node.error(`Connection error: ${err.message}`);
43
+ node.warn(`Full error: ${JSON.stringify(err)}`);
43
44
  node.connected = false;
44
45
  node.connecting = false;
45
46
  });
@@ -56,7 +57,8 @@ module.exports = function(RED) {
56
57
  node.connection.on('connect', () => {
57
58
  node.connected = true;
58
59
  node.connecting = false;
59
- node.log(`Connected to ${node.host}`);
60
+ node.log(`Connected to TV at ${node.host}`);
61
+ node.warn(`Connection established - clientKey: ${node.connection.clientKey ? 'present' : 'missing'}`);
60
62
 
61
63
  // Save client key for future connections
62
64
  if (node.connection.clientKey && node.connection.clientKey !== node.clientKey) {
@@ -82,16 +84,26 @@ module.exports = function(RED) {
82
84
  };
83
85
 
84
86
  this.sendToast = function(message, callback) {
87
+ node.warn(`sendToast called - connected: ${node.connected}, message: "${message}"`);
88
+
85
89
  if (!node.connected) {
90
+ node.warn(`Not connected, queuing message. Queue size: ${node.queue.length + 1}`);
86
91
  node.queue.push({ message, callback });
87
92
  node.connect();
88
93
  return;
89
94
  }
90
95
 
96
+ node.warn(`Sending toast request to TV...`);
91
97
  node.connection.request(
92
98
  'ssap://system.notifications/createToast',
93
99
  { message: message },
94
100
  (err, res) => {
101
+ if (err) {
102
+ node.error(`Toast request failed: ${err.message || err}`);
103
+ node.warn(`Full error object: ${JSON.stringify(err)}`);
104
+ } else {
105
+ node.warn(`Toast response: ${JSON.stringify(res)}`);
106
+ }
95
107
  if (callback) callback(err, res);
96
108
  }
97
109
  );
@@ -127,16 +139,21 @@ module.exports = function(RED) {
127
139
  this.on('input', function(msg, send, done) {
128
140
  const message = msg.payload || config.message || 'Notification';
129
141
 
142
+ node.warn(`Input received - payload type: ${typeof msg.payload}, message to send: "${message}"`);
130
143
  node.status({ fill: 'yellow', shape: 'dot', text: 'sending...' });
131
144
 
132
145
  node.tv.sendToast(message, (err, res) => {
146
+ node.warn(`Callback received - err: ${err ? JSON.stringify(err) : 'null'}, res: ${JSON.stringify(res)}`);
147
+
133
148
  if (err) {
134
149
  node.status({ fill: 'red', shape: 'dot', text: 'error' });
150
+ node.error(`Failed to send toast: ${err.message || JSON.stringify(err)}`, msg);
135
151
  if (done) done(err);
136
- else node.error(err, msg);
137
152
  } else {
153
+ node.warn(`Toast sent successfully - toastId: ${res ? res.toastId : 'unknown'}`);
138
154
  node.status({ fill: 'green', shape: 'dot', text: 'sent' });
139
- msg.toastId = res.toastId;
155
+ msg.toastId = res ? res.toastId : null;
156
+ msg.tvResponse = res;
140
157
  send(msg);
141
158
  if (done) done();
142
159
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-lgtv-notify",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Send toast notifications to LG webOS TVs from Node-RED. Works with webOS 10+ (2025 TVs).",
5
5
  "keywords": [
6
6
  "node-red",
@@ -1,31 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(npm run build:*)",
5
- "mcp__plugin_playwright_playwright__browser_click",
6
- "mcp__plugin_playwright_playwright__browser_evaluate",
7
- "Bash(curl:*)",
8
- "Bash(timeout 5 npx ares-inspect:*)",
9
- "mcp__plugin_playwright_playwright__browser_console_messages",
10
- "Bash(timeout 8 npx ares-inspect:*)",
11
- "WebFetch(domain:webostv.developer.lge.com)",
12
- "WebFetch(domain:gist.github.com)",
13
- "WebFetch(domain:www.webosbrew.org)",
14
- "WebFetch(domain:www.webosose.org)",
15
- "Bash(npx ares-device-info:*)",
16
- "Bash(npx @�webos-tools/cli ares-device-info -d webostv)",
17
- "Bash(npx ares-shell -d webostv -r \"cat /var/run/nyx/os_info.json\")",
18
- "Bash(npx ares-shell:*)",
19
- "Bash(npx ares-device:*)",
20
- "WebFetch(domain:cani.rootmy.tv)",
21
- "WebFetch(domain:www.home-assistant.io)",
22
- "Bash(timeout 5 curl:*)",
23
- "Bash(timeout 3 bash -c 'echo > /dev/tcp/10.1.60.87/3000')",
24
- "Bash(timeout 3 bash -c 'echo > /dev/tcp/10.1.60.87/3001')",
25
- "Bash(timeout 15 node:*)",
26
- "Bash(timeout 35 node:*)",
27
- "Bash(npm whoami:*)",
28
- "Bash(npm publish)"
29
- ]
30
- }
31
- }
@@ -1,25 +0,0 @@
1
- name: Publish to npm
2
-
3
- on:
4
- release:
5
- types: [published]
6
- workflow_dispatch:
7
-
8
- jobs:
9
- publish:
10
- runs-on: ubuntu-latest
11
- steps:
12
- - uses: actions/checkout@v4
13
-
14
- - uses: actions/setup-node@v4
15
- with:
16
- node-version: '20'
17
- registry-url: 'https://registry.npmjs.org'
18
-
19
- - name: Install dependencies
20
- run: npm install --ignore-scripts
21
-
22
- - name: Publish to npm
23
- run: npm publish --access public
24
- env:
25
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/CLAUDE.md DELETED
@@ -1,99 +0,0 @@
1
- # YouTube Enhanced - webOS TV App
2
-
3
- Based on [youtube-webos](https://github.com/webosbrew/youtube-webos) with custom modifications for larger TVs.
4
-
5
- ## App Info
6
- - **App ID**: `com.mysmartv.youtube`
7
- - **Title**: YouTube Enhanced
8
- - **Features**: Ad blocking, SponsorBlock, smaller thumbnails (5 per row)
9
-
10
- ## Project Structure
11
- ```
12
- /home/rcaldeira/mySmartTV-Youtube/
13
- ├── assets/
14
- │ └── appinfo.json # App manifest (custom ID)
15
- ├── src/
16
- │ ├── index.html # Entry point
17
- │ ├── index.js # Redirects to youtube.com/tv
18
- │ ├── userScript.ts # Main injection script
19
- │ ├── thumbnail-size.css # Custom CSS for smaller thumbnails
20
- │ ├── adblock.js # Ad blocking
21
- │ ├── sponsorblock.js # SponsorBlock integration
22
- │ └── ... # Other modules
23
- ├── dist/ # Build output
24
- └── com.mysmartv.youtube_1.0.0_all.ipk
25
- ```
26
-
27
- ## Development Commands
28
-
29
- ### Build
30
- ```bash
31
- npm run build
32
- ```
33
-
34
- ### Package
35
- ```bash
36
- npx ares-package dist/ --outdir .
37
- ```
38
-
39
- ### Install to TV
40
- ```bash
41
- npx ares-install com.mysmartv.youtube_1.0.0_all.ipk -d webostv
42
- ```
43
-
44
- ### Launch
45
- ```bash
46
- npx ares-launch com.mysmartv.youtube -d webostv
47
- ```
48
-
49
- ### Full Deploy (one command)
50
- ```bash
51
- npm run build && npx ares-package dist/ --outdir . && npx ares-install com.mysmartv.youtube_1.0.0_all.ipk -d webostv && npx ares-launch com.mysmartv.youtube -d webostv
52
- ```
53
-
54
- ## Preview Method (Remote Debugging)
55
-
56
- ### 1. Start Inspector
57
- ```bash
58
- npx ares-inspect com.mysmartv.youtube -d webostv
59
- ```
60
-
61
- Output:
62
- ```
63
- Application Debugging - http://localhost:XXXXX
64
- ```
65
-
66
- ### 2. Open in Browser
67
- 1. Navigate to `http://localhost:XXXXX`
68
- 2. Click on "YouTube na TV" link
69
- 3. DevTools opens with live screencast of the TV
70
-
71
- ### 3. Take Screenshot with Playwright
72
- ```javascript
73
- await page.goto('http://localhost:XXXXX');
74
- await page.click('text=YouTube na TV');
75
- await page.waitForTimeout(3000);
76
- await page.screenshot({ path: 'tv-preview.png' });
77
- ```
78
-
79
- ## Custom Thumbnail CSS
80
-
81
- The `src/thumbnail-size.css` uses CSS transforms to scale down content:
82
- - Scales browse content to 85%
83
- - Scales individual tiles to 82%
84
- - Compacts sidebar to give more content space
85
- - Results in ~5 thumbnails per row on large TVs
86
-
87
- ## TV Device
88
- - **Name**: webostv
89
- - **IP**: 10.1.60.87:9922
90
-
91
- ### List Devices
92
- ```bash
93
- npx ares-setup-device --list
94
- ```
95
-
96
- ## Notes
97
- - App coexists with official YouTube (different app ID)
98
- - All youtube-webos features enabled (ad blocking, SponsorBlock)
99
- - CSS may need fine-tuning based on specific TV size