Help with some JS code

Hey folks.

Need some help.

I have a "smart" TV (cough) but it is ONLY used for displaying.

It has 4 HDMI inputs.

I have an NVidia shield plugged into HDMI1.
I have an Amp with multiple HDMI inputs plugged into HDMI2.

HDMI2 is the usual input.
That has Foxtel plugged into it.
I use the Foxtel remote to control things. HDMI CEC.
I can detect if the TV is OFF/ON.

The shield is usually turned off.

NORMAL use the Foxtel is wateched mostly.
Now and then I turn on the shield to watch local stuff.

Problem
I can't really cheat to know when it is turned off as it still allows PING replies, so.....
I'm stuck with this point.

What happens.
I power on the shield and it starts returning PING values.
That indicates it is ON.
It also turns on the TV and it (The TV) adjusts its input to HDMI1.

I don't always turn off the Shield (power down) when not using it.
So, I turn on the Foxtel, and this is where things get complicated.

It sets itself to HDMI2 input, but doesn't get it exact.
I control the TV (Foxtel) also via HDMI CEC for channel changes, etc.
So the input selection needs to be correct. Not Generic.

To get around this I have a mode mode for the TV (flow context) to indicate the desired input.

Going to Shield input works fine. Going back to Foxtel mode doesn't.

To recap:
Normal mode (Foxtel) is active.
I turn on (power it on) the shield and the TV adjusts its input.
NR blocks any usual Foxtel/TV commands as they are channel changes.

It indicates it is set to SHIELD mode.

So I want to go back to Foxtel.
I pick up the Foxtel remote and Power it on.
The TV adjusts its input to the GENERIC HDMI input, but it isn't the exact one.

I don't think I can fix this EXACT problem as described.

But I'm wanting to get some code that - if the MODE is set to FOXTEL - tweaks what happens when the TV is powered on for the first time to set the correct input.

WHAT?
As in:
It is in SHIELD mode, but turned off.
I power on the TV but it is set to FOXTEL mode.
It sends some extra commands to tweak the input to the correct one.

Without posting the entire code - not fair to you - I just want some help with one bit of JS code in a function node.

//////////////////////////////////////////////////////////
//          2026 09 15                                  //
//          ==========                                  //
//                                                      //
//  Addition/modification to code.                      //
//  ------------------------------                      //
//                                                      //
//  Outputs:                                            //
//      1   -   Message to voice                        //
//      2   -   Output to input changer code            //
//                                                      //
//                                                      //
//  Variables:                                          //
//      `shield` - status of the shield.                //
//      `tvstate` - status of the tv.                   //
//      `tvmode` - mode set for tv input.               //
//      `flag` - used to stop resending of same message that day.   //
//                                                      //
//  Still to do:                                        //
//  Need code to detect tv input was on `shield` but    //
//  shield is off and tv is ON/`true` and send the      //
//  A.I.C. command to change input on TV.               //
//


//  get values needed.
const shield = flow.get("SHIELD")
const tvstate = flow.get("TVState")
const tvmode = flow.get("TV_MODE")
let flag = context.get("flag") || 0

//  store then in context only to help tracking.
context.set("shield",shield)
context.set("tvstate",tvstate)
context.set("tvmode",tvmode)

const msgA = "Warning.  Shield detected.  Mode set for Foxtel"
const msgB = "Please check TV is set to FOXTEL input and not just set to Onkyo"
const msgCC = "Change TV input"
const alert = "bellding.mp3"
//let mute = 0

//node.warn("Shield state " + shield)
//node.warn("TV state " + tv)
//node.warn("TV mode " + mode)


//  TV off
if (tvstate == false)
{
    //
    node.status({})
    context.set("flag",0)
    node.status({ fill: "red", shape: "dot", text: "OFF" });
    return
}
//  mode mismatch - first time
if (shield == "ON" && tvstate == true && tvmode == "FOXTEL" && flag == 0)
{
    //node.warn("HERE")
    //  This is maybe where the signal needs to go (output 2) to signal the TV input tweak?
    node.status({fill:"red"})
//    msg.payload = "Warning.  Shield detected.  Mode set for Foxtel"
    msg.payload = msgA
    msg.mute = 1
    msg.alert = alert
    node.status({ fill: "red", shape: "dot", text: "Mismatch" })
    context.set("flag",1)
    return msg
}
//  Shield - all good - first time
if (shield == "ON" && tvstate == true && tvmode == "SHIELD" && flag == 0) 
{
    //
    node.status({fill:"green", text: "Shield"})
    context.set("flag",0)
    return
}
//  Shield - all good - WHY NEEDED?
if (shield == "ON" && tvstate == true && tvmode == "SHIELD" && flag == 1) 
{
    //
    node.status({ fill: "green", text: "Shield" })
    context.set("flag", 0)
    return
}
//  Foxtel - all good - first time
if (shield == "OFF" && tvstate == true && tvmode == "FOXTEL" && flag == 0)
{
    //  This needs work to send message to adjust TV input
    //  msgCC needed in this part of the code sent out of second output
    //  and msgB is sent on first output
    node.status({fill:"yellow", text: "Foxtel"})
    return
}

Sorry for some of the commented lines. I'm still testing the waters. :wink:

I'm confused.

This NEARLY is what I want.
But it doesn't have the input for when I change the mode from SHIELD to FOXTEL.
(Isn't hard, but I'm just saying. This is where I'm at.)

Thoughts?

I've run it through AI and got this response and possible improvement...

Thanks Dave.

I wasn't wanting to go down the chatGPT rabbit hole - not that I haven't.
I just don't want to become dependant on it.

I really haven't worked out the exact workings of the big picture.

Note: exact.

It is a weird scenario which I can't fully understand just now.

It is annoying/painful that I can't detect the shield being OFF (as in software wise) and O F F (fully powered down.)

EDIT!

Sorry, I can. It either PINGS or it doesn't.

Likewise with the Foxtel, I don't get any signals from it saying it is ON or OFF.
And - alas - the TV doesn't tell me what it is seeing on its inputs.

The fixed / known things are:
If the shield is turned on (either from no power or from sleep mode) the TV is turned on and the correct input is selected.

If the shield has been USED and the input is set for it, and the Foxtel is turned on......
The TV needs a slight nudge to its selected input. But only for the FIRST time, as subsequent times the input will be correct.

But knowing exactly the microscopic details of that is .... impossible.
Other than the flow context of TV_STATE
Which I have to change manually.
And that opens a new can of worms in that if/when I do that.
Before the Foxtel is turned on or after.

Either way, the input on the TV needs to be tweaked.
But the handling of all that.......

Still fog for me.

Which is why I'm asking here.

Rather than brain rot myself with chatgtp..... human to human interaction and spit balling.
:wink:

What I posted is about .... 30% of the whole thing.
The TV_MODE is set else where.

Does that help or just make it more vague than it was?

You don't have to 'Brain Rot' yourself.

I get a flow and then understand how it works before I use it in my flows. It is surprising oaw you can save yourself effort in writing your own Functions when you understand what AI has given you!!

True.

I am - probably - being harsh on myself.

I'm - just now - talking to ChatGPT with the new code Dave posted.

I've found a couple of problems and am working on the solutions now.

Wow, this chatgpt is different to the one I use.

When I copy code, I get the leading ``` marks too.

(Strange)
(I deleted it to help it work here)

But the first line was

'''javascript
Ok, that isn't working.

But replace the ' with a ` and you get it.

the new code is:

//////////////////////////////////////////////////////////
//          2026 09 15                                  //
//          ==========                                  //
//                                                      //
//  TV / SHIELD / FOXTEL control                        //
//                                                      //
//  Outputs:                                            //
//      1 - Message to voice                            //
//      2 - Output to A.I.C. input changer              //
//                                                      //
//  IMPORTANT                                           //
//  TV_MODE is remembered while the TV is ON            //
//  before the TV is turned OFF                         //
//                                                      //
//  When the TV is turned ON again, the remembered      //
//  mode can be used to decide what action is needed    //
//                                                      //
//////////////////////////////////////////////////////////


// ------------------------------------------------------
// Get current values
// ------------------------------------------------------

const shield = flow.get("SHIELD")
const tvstate = flow.get("TVState")
const tvmode = flow.get("TV_MODE")


// ------------------------------------------------------
// Get values stored in context
// ------------------------------------------------------

// Flag used to prevent sending the same A.I.C. command
// repeatedly
let flag = context.get("flag") || 0

// Remember the TV_MODE from the previous TV ON state
let previousTVMode = context.get("previousTVMode") || null

// Remember the previous TV state
let previousTVState = context.get("previousTVState")


// ------------------------------------------------------
// Store current values for tracking
// ------------------------------------------------------

context.set("shield", shield)
context.set("tvstate", tvstate)
context.set("tvmode", tvmode)


// ------------------------------------------------------
// Messages
// ------------------------------------------------------

const msgA = "Warning. Shield detected. Mode set for Foxtel"
const msgB = "Please check TV is set to FOXTEL input and not just set to Onkyo"
const msgCC = "Change TV input"
const alert = "bellding.mp3"


// ------------------------------------------------------
// Detect TV ON -> OFF
//
// Before the TV goes OFF, remember the current TV_MODE
//
// This is important because TV_MODE may change, disappear,
// or become unreliable while the TV is OFF
// ------------------------------------------------------

if (
    previousTVState === true &&
    tvstate === false
)
{
    // Only remember the mode if it is a valid known mode
    if (
        tvmode === "SHIELD" ||
        tvmode === "FOXTEL"
    )
    {
        context.set("previousTVMode", tvmode)

        previousTVMode = tvmode
    }

    node.status({
        fill: "red",
        shape: "dot",
        text: "TV OFF"
    })

    // A new TV ON cycle can have a new A.I.C. event
    context.set("flag", 0)

    // Store current state
    context.set("previousTVState", tvstate)

    return [null, null]
}


// ------------------------------------------------------
// TV OFF
//
// Nothing else happens while the TV remains OFF
//
// IMPORTANT:
// Do NOT overwrite previousTVMode here
// ------------------------------------------------------

if (tvstate !== true)
{
    node.status({
        fill: "red",
        shape: "dot",
        text: "TV OFF"
    })

    context.set("previousTVState", tvstate)

    return [null, null]
}


// ------------------------------------------------------
// TV has just changed from OFF -> ON
//
// This is where we use the TV_MODE remembered from the
// previous ON state.
//
// Example:
//
//     TV was ON
//     TV_MODE = SHIELD
//     TV turned OFF
//     SHIELD turned OFF
//     TV turned ON
//
// previousTVMode will still be "SHIELD"
//
// This allows us to act on what the TV WAS using,
// rather than relying on the current TV_MODE
// ------------------------------------------------------

if (
    previousTVState === false &&
    tvstate === true
)
{
    node.status({
        fill: "blue",
        shape: "dot",
        text: "TV ON"
    })


    // --------------------------------------------------
    // TV was previously using SHIELD
    //
    // If SHIELD is now OFF, send the A.I.C. command
    //
    // This is the important condition
    // --------------------------------------------------

    if (
        previousTVMode === "SHIELD" &&
        shield === "OFF" &&
        flag === 0
    )
    {
        const aicMsg = {
            payload: msgCC
        }

        context.set("flag", 1)

        context.set("previousTVState", tvstate)

        return [null, aicMsg]
    }
}


// ------------------------------------------------------
// SHIELD ON + TV ON + TV MODE = FOXTEL
//
// Shield has been detected but TV is still on FOXTEL.
//
// Voice warning only.
//
// NO A.I.C. command here.
// ------------------------------------------------------

if (
    shield === "ON" &&
    tvstate === true &&
    tvmode === "FOXTEL" &&
    flag === 0
)
{
    const voiceMsg = {
        payload: msgA,
        mute: 1,
        alert: alert
    }

    context.set("flag", 1)

    node.status({
        fill: "red",
        shape: "dot",
        text: "Shield / FOXTEL mismatch"
    })

    context.set("previousTVState", tvstate)

    return [voiceMsg, null]
}


// ------------------------------------------------------
// SHIELD ON + TV ON + TV MODE = SHIELD
//
// Everything is correct
// ------------------------------------------------------

if (
    shield === "ON" &&
    tvstate === true &&
    tvmode === "SHIELD"
)
{
    context.set("flag", 0)

    node.status({
        fill: "green",
        shape: "dot",
        text: "Shield"
    })

    // Remember the current valid mode
    context.set("previousTVMode", tvmode)

    context.set("previousTVState", tvstate)

    return [null, null]
}


// ------------------------------------------------------
// SHIELD OFF + TV ON + TV MODE = FOXTEL
//
// Everything is correct
// ------------------------------------------------------

if (
    shield === "OFF" &&
    tvstate === true &&
    tvmode === "FOXTEL"
)
{
    context.set("flag", 0)

    node.status({
        fill: "yellow",
        shape: "dot",
        text: "Foxtel"
    })

    // Remember the current valid mode
    context.set("previousTVMode", tvmode)

    context.set("previousTVState", tvstate)

    return [null, null]
}


// ------------------------------------------------------
// TV is ON
//
// If TV_MODE is known, remember it.
//
// This catches normal changes while the TV remains ON.
// ------------------------------------------------------

if (
    tvstate === true &&
    (
        tvmode === "SHIELD" ||
        tvmode === "FOXTEL"
    )
)
{
    context.set("previousTVMode", tvmode)
}


// ------------------------------------------------------
// Store current TV state
// ------------------------------------------------------

context.set("previousTVState", tvstate)

return [null, null]

I'm working through it now.

You'll have to top and tail the code by removing...
```javascript at the top
and
``` at the bottom of the listing.

Strange, as I have never had to do that before myself.

Make sure you at least have a good idea of what the code is doing. I find my Debug Nodes and msg.test(x) get a hammering while understanding!

Good Luck.

Sorry for going slightly off-topic, but this sentence made me smile....

I have to admit, “I don't want to become dependent on ChatGPT” sounds wonderfully old-school.

A bit like saying: “I prefer to solve problems myself”… and then opening a forum thread to ask other people how to solve the problem.

Apparently the important thing is that ChatGPT reaches you through at least one human intermediary. :grinning_face_with_smiling_eyes: