Nodejs react-switch to send command to Chirpstack

Good day all I am new to using Chirpstack and HTML I am needing help. I am trying to build a nodejs website application to be able to view the devices and send on/off commands to devices that have digital outputs with toggle switches on the nodejs webpage I am building. So I have managed to get toggle switches where I need them and the state of the toggle changes when i use the milesight toolbox app to change the state. but now I am struggling to figure out how do I get the toggle switch to send the command to Chirpstack.

this is the base64 command layout
gpio_out_1 on ‘{“devEui”:“24e124445d354713”,“confirmed”:true,“fPort”:85,“data”:“BwEB”}’ gpio_out_1 off ‘{“devEui”:“24e124445d354713”,“confirmed”:true,“fPort”:85,“data”:“BwEA”}’ gpio_out_2 on ‘{“devEui”:“24e124445d354713”,“confirmed”:true,“fPort”:85,“data”:“CAEB”}’ gpio_out_2 off ‘{“devEui”:“24e124445d354713”,“confirmed”:true,“fPort”:85,“data”:“CAEA”}’

this is what shows in Chirpstack when i change the state of the output with the toolbox

Screenshot 2025-04-14 113649

Screenshot 2025-04-14 113743

Screenshot 2025-04-14 113804

Screenshot 2025-04-14 113823

You will want to use Chirpstack’s gRPC api and the enqueueDownlink function.

Thanks, but i am trying to use the mqtt method
here is the downlink section in my mqtt.js

function sendRawHexCommand(devEui, hexData, fPort = 85, confirmed = false) {
    const downlinkTopic = DOWNLINK_TOPIC_TEMPLATE.replace('{devEui}', devEui);
    
    const payload = {
        devEui: devEui,
        confirmed: confirmed,
        fPort: fPort,
        data: hexData // Send raw hex string directly
    };

    client.publish(downlinkTopic, JSON.stringify(payload), (err) => {
        if (err) {
            console.error('MQTT Publish Error:', err);
            return false;
        }
        console.log('Raw hex command sent:', {
            devEui,
            hexData,
            topic: downlinkTopic
        });
        return true;
    });
}

the section in my DeviceContext.jsx

  // Control output function
  const controlOutput = useCallback(async (deviceId, payload) => {
    try {
        // For GPIO output commands
        if (payload.data && typeof payload.data === 'string') {
            await sendRawHexCommand( // Make sure this matches your exported function name
                deviceId,
                payload.data,
                payload.fPort || 85,
                payload.confirmed || true
            );
        } else {
            throw new Error('Invalid payload format - hex data required');
        }
    } catch (err) {
        console.error('Downlink failed:', {
            deviceId,
            payload,
            error: err.message
        });
        throw new Error(`Command failed: ${err.message}`); // More descriptive error
    }
}, []);

then the GeneratorController.jsx

  const handleToggleOutput = async (deviceId, outputName) => {
    setError(null);
    setLoadingOutput(outputName);
    
    // Get current value BEFORE the try block
    const currentValue = getDeviceData(deviceId)[outputName];
    const newValue = currentValue === "on" ? "off" : "on";
    
    try {
        // Update local state immediately - use functional update
        setLocalDeviceState(prev => {
            const newState = {...prev};
            newState[deviceId] = {
                ...(newState[deviceId] || {}), // Ensure device exists
                [outputName]: newValue
            };
            return newState;
        });

        // Create the payload
        const payload = {
            devEui: deviceId,
            confirmed: true,
            fPort: 85,
            data: outputName === 'gpio_out_1' 
                ? (newValue === 'on' ? '070100' : '070101')
                : (newValue === 'on' ? '080100' : '080101')
        };
        
        await controlOutput(deviceId, payload);
        
    } catch (err) {
        setError(`Failed to toggle ${outputName}. Please try again.`);
        console.error('Toggle failed:', {
            deviceId,
            outputName,
            currentValue, // Now accessible
            error: err.message
        });
        
        // Revert local state safely
        setLocalDeviceState(prev => {
            const newState = {...prev};
            if (newState[deviceId]) {
                newState[deviceId] = {
                    ...newState[deviceId],
                    [outputName]: currentValue // Use the captured value
                };
            }
            return newState;
        });
    } finally {
        setLoadingOutput(null);
    }
};

the error when i inspect my webpage is this

DeviceContext.jsx:51 Downlink failed: 
Object
deviceId
: 
"24e124445d354713"
error
: 
"sendRawHexCommand is not defined"
payload
: 
confirmed
: 
false
data
: 
"070101"
devEui
: 
"24e124445d354713"
fPort
: 
85
[[Prototype]]
: 
Object
[[Prototype]]
: 
Object

GeneratorController.jsx:65 Toggle failed: 
Object
currentValue
: 
"on"
deviceId
: 
"24e124445d354713"
error
: 
"Command failed: sendRawHexCommand is not defined"
outputName
: 
"gpio_out_1"

and on Chirpstack events for the device I am trying to control there is no events coming though not even errors.

Not sure if I am missing something