# Extracting a value from a http request

**URL:** <https://discourse.nodered.org/t/extracting-a-value-from-a-http-request/98270>\
**Category:** General\
**Created:** [23 July 2025 12:18 UTC](https://discourse.nodered.org/t/extracting-a-value-from-a-http-request/98270 "2025-07-23T12:18:02Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mikee1234K](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/mikee1234k/32/70283_2.png) [@Mikee1234K](https://discourse.nodered.org/u/Mikee1234K)\
**Post date:** [23 July 2025 12:18 UTC](https://discourse.nodered.org/t/extracting-a-value-from-a-http-request/98270/1 "2025-07-23T12:18:02Z")

</div>

I am trying to extract a value (string) obtained by a http request. This is the payload I am receiving (partially)

```auto
<?xml version="1.0" ?>
<command_result>
<param name="protocol_version" value="6"/>
<param name="phv_md5" value="D41D8CD98F00B204E9800998ECF8427E"/>
<param name="android_app_active" value="0"/>
<param name="android_md5" value="8607D73529871E25EB08F15E8B88BDF8"/>
<param name="player_state" value="navigator"/>
<param name="playback_volume" value="80"/>
<param name="playback_mute" value="0"/>

```

I am trying to extract the player state (that will then show me how to extract other values I might need)

---

<div class="post-metadata">

**Author:** ![dynamicdave](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dynamicdave/32/96_2.png) [@dynamicdave](https://discourse.nodered.org/u/dynamicdave)\
**Post date:** [23 July 2025 12:21 UTC](https://discourse.nodered.org/t/extracting-a-value-from-a-http-request/98270/2 "2025-07-23T12:21:33Z")

</div>

If the XML string is in `msg.payload`, first use an "xml" node to convert XML to a JavaScript object.

Then in a function node:

```auto
let params = msg.payload.command_result.param;

let playerState = params.find(p => p.$.name === "player_state").$.value;

msg.payload = playerState;
return msg;

```

---

<div class="post-metadata">

**Author:** ![Mikee1234K](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/mikee1234k/32/70283_2.png) [@Mikee1234K](https://discourse.nodered.org/u/Mikee1234K)\
**Post date:** [24 July 2025 06:16 UTC](https://discourse.nodered.org/t/extracting-a-value-from-a-http-request/98270/3 "2025-07-24T06:16:39Z")

</div>

> [@dynamicdave](#):
>
> ```auto
> let params = msg.payload.command_result.param;
> 
> let playerState = params.find(p => p.$.name === "player_state").$.value;
> 
> msg.payload = playerState;
> return msg;
> 
> ```

That works well. But I am now trying to expand the function node to extract 2 values, and send them to 2 different outputs. One for player state, the other for playback state.  
I get an error from the function node: TypeError: Cannot read properties of undefined (reading '$')  
Ideally I wanted the output as a object, and in payload. If thats not possible it could be in payload.status  
This is my function node

```auto
let params = msg.payload.command_result.param;

let playerState = params.find(p => p.$.name === "player_state").$.value;
let playbackState = params.find(p => p.$.name === "playback_state").$.value;

var msg1 = { payload: {status: playerState }};
var msg2 = { payload: {status: playbackState }};
return [msg1,msg2]

```

---

<div class="post-metadata">

**Author:** ![dynamicdave](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dynamicdave/32/96_2.png) [@dynamicdave](https://discourse.nodered.org/u/dynamicdave)\
**Post date:** [24 July 2025 06:53 UTC](https://discourse.nodered.org/t/extracting-a-value-from-a-http-request/98270/4 "2025-07-24T06:53:17Z")

</div>

> [@Mikee1234K](#):
>
> TypeError: Cannot read properties of undefined (reading '$')

The error you're getting means that  
`params.find(p => p.$.name === "player_state")`  
or  
`params.find(p => p.$.name === "playback_state")`  
is returning undefined — in other words, it didn't find a matching element, and then you're trying to access undefined.$.value.

**I assume you did insert an XML node in your NR flow before the function node?**

**Possible steps to tryout...**

You need to:

1. Ensure the `.find(...)` call actually finds an element.
2. Add checks before accessing properties.

Try this JS in the function node.

```auto
let params = msg.payload.command_result.param;

// Find player_state and playback_state objects safely
let playerStateObj = params.find(p => p.$ && p.$.name === "player_state");
let playbackStateObj = params.find(p => p.$ && p.$.name === "playback_state");

// Extract values safely
let playerState = playerStateObj?.$?.value || "unknown";
let playbackState = playbackStateObj?.$?.value || "unknown";

var msg1 = { payload: { status: playerState }};
var msg2 = { payload: { status: playbackState }};

return [msg1, msg2];

```

**It would help if you can share the NR flow you have created and a sample XML string.**

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [24 July 2025 07:47 UTC](https://discourse.nodered.org/t/extracting-a-value-from-a-http-request/98270/5 "2025-07-24T07:47:21Z")

</div>

Using your demo data from post 1, there is no `playback_state` so without error checking or error handling, you will see that.

If I add that entry into the test data, it works with this:

```auto
const param = msg.payload.command_result.param
const player_state = param?.find(e => e.$.name === "player_state")
const playback_state = param?.find(e => e.$.name === "playback_state")

if (!player_state || !player_state.$) {
    throw new Error('player_state not found')
}
if (!playback_state || !playback_state.$) {
    throw new Error('playback_state not found')
}

const msg1 = { topic: "player", payload: { status: player_state.$.value }};
const msg2 = { topic: "playback", payload: { status: playback_state.$.value }};

return [msg1, msg2];

```

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/4/a/4a0f84f15ab7e1d7fc5c719f918fcca970fce47d.png)

#### Test flow

```auto
[{"id":"4ad53da770f3dd0b","type":"group","z":"7a7a72bd5ef89e06","style":{"stroke":"#999999","stroke-opacity":"1","fill":"none","fill-opacity":"1","label":true,"label-position":"nw","color":"#a4a4a4"},"nodes":["ed635d75dbfbadce","07412dcdd28bea9f","5c297e6faa3bf049","89c2bff228087709","e1a5554947e128b7","06c46dbadab39a09","ed96549876a942c7","9cb41e9bf2af8433","5b60ae43c433be62","6212f5a283e0a2d6","183feac69cb0b228"],"x":514,"y":119,"w":732,"h":322},{"id":"ed635d75dbfbadce","type":"inject","z":"7a7a72bd5ef89e06","g":"4ad53da770f3dd0b","name":"good data","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":620,"y":160,"wires":[["07412dcdd28bea9f"]]},{"id":"07412dcdd28bea9f","type":"template","z":"7a7a72bd5ef89e06","g":"4ad53da770f3dd0b","name":"test data","field":"payload","fieldType":"msg","format":"html","syntax":"mustache","template":"<?xml version=\"1.0\" ?>\n<command_result>\n <param name=\"protocol_version\" value=\"6\" />\n <param name=\"phv_md5\" value=\"D41D8CD98F00B204E9800998ECF8427E\" />\n <param name=\"android_app_active\" value=\"0\" />\n <param name=\"android_md5\" value=\"8607D73529871E25EB08F15E8B88BDF8\" />\n <param name=\"player_state\" value=\"navigator\" />\n <param name=\"playback_state\" value=\"paused\" />\n <param name=\"playback_volume\" value=\"80\" />\n <param name=\"playback_mute\" value=\"0\" />\n</command_result>","output":"str","x":770,"y":160,"wires":[["5c297e6faa3bf049"]]},{"id":"5c297e6faa3bf049","type":"xml","z":"7a7a72bd5ef89e06","g":"4ad53da770f3dd0b","name":"","property":"payload","attr":"","chr":"","x":950,"y":160,"wires":[["89c2bff228087709","e1a5554947e128b7"]]},{"id":"89c2bff228087709","type":"debug","z":"7a7a72bd5ef89e06","g":"4ad53da770f3dd0b","name":"debug 1","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1140,"y":160,"wires":[]},{"id":"e1a5554947e128b7","type":"function","z":"7a7a72bd5ef89e06","g":"4ad53da770f3dd0b","name":"get player and playback state","func":"const param = msg.payload.command_result.param\nconst player_state = param?.find(e => e.$.name === \"player_state\")\nconst playback_state = param?.find(e => e.$.name === \"playback_state\")\n\nif (!player_state || !player_state.$) {\n throw new Error('player_state not found')\n}\nif (!playback_state || !playback_state.$) {\n throw new Error('playback_state not found')\n}\n\nconst msg1 = { topic: \"player\", payload: { status: player_state.$.value }};\nconst msg2 = { topic: \"playback\", payload: { status: playback_state.$.value }};\n\nreturn [msg1, msg2];","outputs":2,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":920,"y":280,"wires":[["06c46dbadab39a09"],["183feac69cb0b228"]]},{"id":"06c46dbadab39a09","type":"debug","z":"7a7a72bd5ef89e06","g":"4ad53da770f3dd0b","name":"player","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":1130,"y":240,"wires":[]},{"id":"ed96549876a942c7","type":"inject","z":"7a7a72bd5ef89e06","g":"4ad53da770f3dd0b","name":"bad data","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":620,"y":200,"wires":[["9cb41e9bf2af8433"]]},{"id":"9cb41e9bf2af8433","type":"template","z":"7a7a72bd5ef89e06","g":"4ad53da770f3dd0b","name":"test data","field":"payload","fieldType":"msg","format":"html","syntax":"mustache","template":"<?xml version=\"1.0\" ?>\n<command_result>\n\n</command_result>","output":"str","x":770,"y":200,"wires":[["5c297e6faa3bf049"]]},{"id":"5b60ae43c433be62","type":"catch","z":"7a7a72bd5ef89e06","g":"4ad53da770f3dd0b","name":"","scope":"group","uncaught":false,"x":630,"y":400,"wires":[["6212f5a283e0a2d6"]]},{"id":"6212f5a283e0a2d6","type":"debug","z":"7a7a72bd5ef89e06","g":"4ad53da770f3dd0b","name":"error","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1130,"y":400,"wires":[]},{"id":"183feac69cb0b228","type":"debug","z":"7a7a72bd5ef89e06","g":"4ad53da770f3dd0b","name":"playback","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":1140,"y":320,"wires":[]}]

```

---

<div class="post-metadata">

**Author:** ![Mikee1234K](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/mikee1234k/32/70283_2.png) [@Mikee1234K](https://discourse.nodered.org/u/Mikee1234K)\
**Post date:** [24 July 2025 08:08 UTC](https://discourse.nodered.org/t/extracting-a-value-from-a-http-request/98270/6 "2025-07-24T08:08:59Z")

</div>

I am not getting errors now with the updated function. I think it might be throwing a error when the player is on standby, as then there is no playback state.

This is a sample of the xml when the player is on standby

```auto
<?xml version="1.0" ?>
<command_result>
<param name="protocol_version" value="6"/>
<param name="phv_md5" value="D41D8CD98F00B204E9800998ECF8427E"/>
<param name="android_app_active" value="0"/>
<param name="android_md5" value="8607D73529871E25EB08F15E8B88BDF8"/>
<param name="player_state" value="navigator"/>
<param name="playback_volume" value="80"/>
<param name="playback_mute" value="0"/>
<param name="md5" value="F4BEE7914810BB1A60A53F349AFC8076"/>
<param name="product_id" value="tv188b"/>
<param name="serial_number" value="***"/>
<param name="firmware_version" value="250622_1149_r22"/>
<param name="commercial_serial_number" value="***"/>
<param name="app_version" value="1.0.1-13-250622_1149"/>
<param name="product_name" value="Pro 8K Plus"/>
</command_result>

```

This is one when playing

```auto
<param name="protocol_version" value="6"/>
<param name="phv_md5" value="D41D8CD98F00B204E9800998ECF8427E"/>
<param name="android_app_active" value="0"/>
<param name="android_md5" value="8607D73529871E25EB08F15E8B88BDF8"/>
<param name="player_state" value="file_playback"/>
<param name="playback_state" value="playing"/>
<param name="previous_playback_state" value="buffering"/>
<param name="last_playback_event" value="no_event"/>
<param name="playback_url" value="/tmp/mnt/smb/2/Videos/Unbroken (2014)/Unbroken-(2014)-1080p-Atmos-8bit.mkv"/>
<param name="playback_speed" value="256"/>
<param name="playback_duration" value="8248"/>
<param name="playback_position" value="497"/>
<param name="playback_position_version" value="134"/>
<param name="playback_repeat" value="0"/>
<param name="playback_shuffle" value="0"/>
<param name="playback_current_bitrate" value="28061000"/>
<param name="playback_is_buffering" value="0"/>
<param name="playback_volume" value="80"/>
<param name="playback_mute" value="0"/>
<param name="playback_video_width" value="1920"/>
<param name="playback_video_height" value="1080"/>
<param name="audio_track" value="0"/>
<param name="subtitles_track" value="-1"/>
<param name="playback_window_fullscreen" value="0"/>
<param name="playback_window_rect_x" value="0"/>
<param name="playback_window_rect_y" value="0"/>
<param name="playback_window_rect_width" value="0"/>
<param name="playback_window_rect_height" value="0"/>
<param name="playback_clip_rect_x" value="0"/>
<param name="playback_clip_rect_y" value="0"/>
<param name="playback_clip_rect_width" value="0"/>
<param name="playback_clip_rect_height" value="0"/>
<param name="playback_video_source_rect_x" value="0"/>
<param name="playback_video_source_rect_y" value="0"/>
<param name="playback_video_source_rect_width" value="0"/>
<param name="playback_video_source_rect_height" value="0"/>
<param name="osd_width" value="0"/>
<param name="osd_height" value="0"/>
<param name="video_enabled" value="0"/>
<param name="video_on_top" value="0"/>
<param name="video_zoom" value="normal"/>
<param name="is_video" value="1"/>
<param name="pause_is_available" value="0"/>
<param name="teletext_available" value="0"/>
<param name="teletext_enabled" value="0"/>
<param name="teletext_mix_mode" value="0"/>
<param name="teletext_page_number" value="0"/>
<param name="scrambling_detected" value="0"/>
<param name="hangup_watchdog_activations" value="0"/>
<param name="hls_first_sequence" value="0"/>
<param name="segment_length" value="0"/>
<param name="item_id" value="0"/>
<param name="audio_track.0.lang" value="eng"/>
<param name="audio_track.0.pid" value="1"/>
<param name="audio_track.0.codec" value="TrueHD"/>
<param name="audio_track.0.type" value="normal"/>
<param name="subtitles_track.0.lang" value="eng"/>
<param name="subtitles_track.0.pid" value="2"/>
<param name="subtitles_track.0.codec" value="PGS"/>
<param name="subtitles_track.0.type" value="normal"/>
<param name="subtitles_track.0.offset_ms" value="0"/>
<param name="subtitles_track.1.lang" value="fre"/>
<param name="subtitles_track.1.pid" value="3"/>
<param name="subtitles_track.1.codec" value="PGS"/>
<param name="subtitles_track.1.type" value="normal"/>
<param name="subtitles_track.1.offset_ms" value="0"/>
<param name="pltv_enabled" value="0"/>
<param name="playback_caption" value="Unbroken (1 of 20)"/>
<param name="playback_extra_caption" value="Chapter 01"/>
<param name="md5" value="9E41BD80B32849C6E536C5A3A65D4A8F"/>
<param name="product_id" value="tv188b"/>
<param name="serial_number" value="***"/>
<param name="firmware_version" value="250622_1149_r22"/>
<param name="commercial_serial_number" value="***"/>
<param name="app_version" value="1.0.1-13-250622_1149"/>
<param name="product_name" value="Pro 8K Plus"/>

```

This is my current flow. The change node for the player state and following nodes should really be processed in the function node too, but not sure yet of how to do that

```auto
[
    {
        "id": "0ef1f12f95a3d503",
        "type": "http request",
        "z": "51ebdd733328bee0",
        "name": "",
        "method": "GET",
        "ret": "txt",
        "paytoqs": "ignore",
        "url": "http://192.168.0.177/cgi-bin/do?cmd=status",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [],
        "x": 270,
        "y": 4000,
        "wires": [
            [
                "e873c1cbc9d093f5"
            ]
        ]
    },
    {
        "id": "8a1213070c83837a",
        "type": "inject",
        "z": "51ebdd733328bee0",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 100,
        "y": 4000,
        "wires": [
            [
                "0ef1f12f95a3d503"
            ]
        ]
    },
    {
        "id": "63813081fdd613b9",
        "type": "debug",
        "z": "51ebdd733328bee0",
        "name": "debug 180",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 890,
        "y": 4000,
        "wires": []
    },
    {
        "id": "e873c1cbc9d093f5",
        "type": "xml",
        "z": "51ebdd733328bee0",
        "name": "",
        "property": "payload",
        "attr": "",
        "chr": "",
        "x": 430,
        "y": 4000,
        "wires": [
            [
                "d4e24881c6f41e4a"
            ]
        ]
    },
    {
        "id": "d4e24881c6f41e4a",
        "type": "function",
        "z": "51ebdd733328bee0",
        "name": "function 33",
        "func": "let params = msg.payload.command_result.param;\n\n// Find player_state and playback_state objects safely\nlet playerStateObj = params.find(p => p.$ && p.$.name === \"player_state\");\nlet playbackStateObj = params.find(p => p.$ && p.$.name === \"playback_state\");\n\n// Extract values safely\nlet playerState = playerStateObj?.$?.value || \"unknown\";\nlet playbackState = playbackStateObj?.$?.value || \"unknown\";\n\nvar msg1 = { payload: { status: playerState } };\nvar msg2 = { payload: { status: playbackState } };\n\nreturn [msg1, msg2];\n",
        "outputs": 2,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 190,
        "y": 4200,
        "wires": [
            [
                "63813081fdd613b9",
                "9e084cb49ada6936",
                "af5cc1acf96817f0"
            ],
            [
                "701b0538133c89d3"
            ]
        ]
    },
    {
        "id": "9e084cb49ada6936",
        "type": "change",
        "z": "51ebdd733328bee0",
        "name": "update Dune Player State",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "update",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "payload.value",
                "pt": "msg",
                "to": "payload.value",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 230,
        "y": 4100,
        "wires": [
            []
        ]
    },
    {
        "id": "4596367cf960dbef",
        "type": "hs-device",
        "z": "51ebdd733328bee0",
        "name": "AV Lounge Dune Player State",
        "device": "4461",
        "server": "e2626888dadf1c4f",
        "feature": 0,
        "reportonstartup": false,
        "x": 850,
        "y": 4200,
        "wires": [
            []
        ]
    },
    {
        "id": "701b0538133c89d3",
        "type": "change",
        "z": "51ebdd733328bee0",
        "name": "update Dune Playback State",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "update",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "payload.value",
                "pt": "msg",
                "to": "payload.value",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 240,
        "y": 4320,
        "wires": [
            [
                "cef5da6143b81564"
            ]
        ]
    },
    {
        "id": "cef5da6143b81564",
        "type": "hs-device",
        "z": "51ebdd733328bee0",
        "name": "AV Lounge Dune Playback State",
        "device": "4459",
        "server": "e2626888dadf1c4f",
        "feature": 0,
        "reportonstartup": false,
        "x": 550,
        "y": 4320,
        "wires": [
            []
        ]
    },
    {
        "id": "c069fe5f0c2da476",
        "type": "debug",
        "z": "51ebdd733328bee0",
        "name": "debug 182",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 890,
        "y": 4040,
        "wires": []
    },
    {
        "id": "af5cc1acf96817f0",
        "type": "switch",
        "z": "51ebdd733328bee0",
        "name": "",
        "property": "payload.status",
        "propertyType": "msg",
        "rules": [
            {
                "t": "cont",
                "v": "standby",
                "vt": "str"
            },
            {
                "t": "cont",
                "v": "navigator",
                "vt": "str"
            },
            {
                "t": "cont",
                "v": "file_playback",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 3,
        "x": 430,
        "y": 4180,
        "wires": [
            [
                "1d9791817b0b3d3a"
            ],
            [
                "e8cac50b776cbef1"
            ],
            [
                "c34cb02cf6c4a18f"
            ]
        ]
    },
    {
        "id": "1d9791817b0b3d3a",
        "type": "change",
        "z": "51ebdd733328bee0",
        "name": "Standby",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "{\"value\":\"0\"}",
                "tot": "json"
            },
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "control",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 600,
        "y": 4160,
        "wires": [
            [
                "4596367cf960dbef",
                "c069fe5f0c2da476"
            ]
        ]
    },
    {
        "id": "e8cac50b776cbef1",
        "type": "change",
        "z": "51ebdd733328bee0",
        "name": "Navigator",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "{\"value\":\"1\"}",
                "tot": "json"
            },
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "control",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 600,
        "y": 4200,
        "wires": [
            [
                "4596367cf960dbef"
            ]
        ]
    },
    {
        "id": "c34cb02cf6c4a18f",
        "type": "change",
        "z": "51ebdd733328bee0",
        "name": "File playback",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "{\"value\":\"2\"}",
                "tot": "json"
            },
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "control",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 610,
        "y": 4240,
        "wires": [
            [
                "4596367cf960dbef"
            ]
        ]
    },
    {
        "id": "e2626888dadf1c4f",
        "type": "hs-server",
        "name": "new HS4",
        "host": "192.168.0.7",
        "port": "81"
    }
]

```

---

<div class="post-metadata">

**Author:** ![dynamicdave](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dynamicdave/32/96_2.png) [@dynamicdave](https://discourse.nodered.org/u/dynamicdave)\
**Post date:** [24 July 2025 10:18 UTC](https://discourse.nodered.org/t/extracting-a-value-from-a-http-request/98270/7 "2025-07-24T10:18:44Z")

</div>

Here's a quickly cleaned-up and merged version of the last NR flow you posted.

Key changes...

- Merged multiple `change` nodes into a single `function`
- Combined player state mapping into one logic block
- Output messages include proper `topic` and `payload.value` formatting for HomeSeer
- Optional: keeps a single `debug` for clarity  
 ![Thurs_NR_clean_up](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/8/2/8261a53e6cc9be32624824361d4e4fb8fe1fb074.png)

```auto
[{"id":"ebf08de78ddb1c68","type":"tab","label":"Flow 14","disabled":false,"info":"","env":[]},{"id":"inject_get_status","type":"inject","z":"ebf08de78ddb1c68","name":"Trigger","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":170,"y":260,"wires":[["http_get_status"]]},{"id":"http_get_status","type":"http request","z":"ebf08de78ddb1c68","name":"GET Dune Status","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://192.168.0.177/cgi-bin/do?cmd=status","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":350,"y":260,"wires":[["xml_parse"]]},{"id":"xml_parse","type":"xml","z":"ebf08de78ddb1c68","name":"Parse XML","property":"payload","attr":"","chr":"","x":550,"y":260,"wires":[["extract_states"]]},{"id":"extract_states","type":"function","z":"ebf08de78ddb1c68","name":"Extract States","func":"// Extract from XML\nlet params = msg.payload.command_result.param;\n\nlet playerStateObj = params.find(p => p.$?.name === \"player_state\");\nlet playbackStateObj = params.find(p => p.$?.name === \"playback_state\");\n\nlet playerState = playerStateObj?.$?.value || \"unknown\";\nlet playbackState = playbackStateObj?.$?.value || \"unknown\";\n\nreturn [\n { payload: { value: playerState }, topic: \"update\", status: playerState },\n { payload: { value: playbackState }, topic: \"update\" }\n];","outputs":2,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":740,"y":260,"wires":[["map_player_state","debug_output"],["hs_playback_state"]]},{"id":"map_player_state","type":"function","z":"ebf08de78ddb1c68","name":"Map Player State","func":"let state = msg.status;\nlet value;\n\nif (state.includes(\"standby\")) {\n value = \"0\";\n} else if (state.includes(\"navigator\")) {\n value = \"1\";\n} else if (state.includes(\"file_playback\")) {\n value = \"2\";\n} else {\n return null;\n}\n\nmsg.payload = { value };\nmsg.topic = \"control\";\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":970,"y":180,"wires":[["hs_player_state"]]},{"id":"hs_player_state","type":"hs-device","z":"ebf08de78ddb1c68","name":"AV Lounge Dune Player State","device":"4461","server":"hs4_server","feature":0,"reportonstartup":false,"x":1190,"y":180,"wires":[]},{"id":"hs_playback_state","type":"hs-device","z":"ebf08de78ddb1c68","name":"AV Lounge Dune Playback State","device":"4459","server":"hs4_server","feature":0,"reportonstartup":false,"x":970,"y":300,"wires":[]},{"id":"debug_output","type":"debug","z":"ebf08de78ddb1c68","name":"Debug Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":960,"y":240,"wires":[]}]

```

**Note:** I haven't got the HomeSeer (hs) nodes, so they are showing as 'unknown'.

---

<div class="post-metadata">

**Author:** ![Mikee1234K](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/mikee1234k/32/70283_2.png) [@Mikee1234K](https://discourse.nodered.org/u/Mikee1234K)\
**Post date:** [24 July 2025 10:39 UTC](https://discourse.nodered.org/t/extracting-a-value-from-a-http-request/98270/8 "2025-07-24T10:39:50Z")

</div>

Yes that works perfectly now. How would I change the function node 'extract states', if I only wanted a output if playerstate or playbck state changes ? The reason is I want to change my lights, but do not want to send a command if the lights are already set to that mode

---

<div class="post-metadata">

**Author:** ![Mikee1234K](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/mikee1234k/32/70283_2.png) [@Mikee1234K](https://discourse.nodered.org/u/Mikee1234K)\
**Post date:** [24 July 2025 12:42 UTC](https://discourse.nodered.org/t/extracting-a-value-from-a-http-request/98270/9 "2025-07-24T12:42:35Z")

</div>

I have found a solution to only output when there is a change. Thanks all for the help, much appreciated !

---

<div class="post-metadata">

**Author:** ![dynamicdave](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dynamicdave/32/96_2.png) [@dynamicdave](https://discourse.nodered.org/u/dynamicdave)\
**Post date:** [24 July 2025 12:46 UTC](https://discourse.nodered.org/t/extracting-a-value-from-a-http-request/98270/10 "2025-07-24T12:46:53Z")

</div>

To **only output from the `extract_states` function node if `player_state` or `playback_state` has changed** , you can **store the previous values in `context`** and compare them with the current ones. If neither has changed, return `null`.

Here’s the **modified `extract_states` function** with that logic:

```auto
let params = msg.payload.command_result.param;

let playerStateObj = params.find(p => p.$?.name === "player_state");
let playbackStateObj = params.find(p => p.$?.name === "playback_state");

let playerState = playerStateObj?.$?.value || "unknown";
let playbackState = playbackStateObj?.$?.value || "unknown";

// Get previous states from context
let prevPlayerState = context.get("playerState");
let prevPlaybackState = context.get("playbackState");

// Check if either value has changed
let changedPlayer = playerState !== prevPlayerState;
let changedPlayback = playbackState !== prevPlaybackState;

// Store current states for next time
context.set("playerState", playerState);
context.set("playbackState", playbackState);

// Only output if something changed
if (changedPlayer || changedPlayback) {
    return [
        changedPlayer ? { payload: { value: playerState }, topic: "update", status: playerState } : null,
        changedPlayback ? { payload: { value: playbackState }, topic: "update" } : null
    ];
} else {
    return [null, null];
}

```

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [22 October 2025 12:47 UTC](https://discourse.nodered.org/t/extracting-a-value-from-a-http-request/98270/11 "2025-10-22T12:47:53Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
