Combine two separate functions into one

Hi so basically I two when separate functions which when on their own work as intended but I need them to work together but unsure as to how to combine them. Tried several ways but none worked.
First function is to return pin values to a web page, second is to listen for web page and activate pins depending on user parameters.

Code as follows:

// Log the URLs we need

server.log("Internal Lights OFF : " + http.agenturl() + "?led=0");
server.log("Internal Lights ON : " + http.agenturl() + "?led=1");
server.log("Internal LUX : " + http.agenturl() + "?led=2");
server.log("External LUX : " + http.agenturl() + "?led=3");
server.log("Heater : " + http.agenturl() + "?led=4");
server.log("Internal Temp : " + http.agenturl() + "?led=5");
server.log("External Temp : " + http.agenturl() + "?led=6");

_pin2 <- "";
_pin5 <- "";
_pin8 <- "";
_pin9 <- "";

function respondImpValues(request,response){

local pinTable = {
"pin2": ""+_pin2+"",
"pin5": ""+_pin5+"", // e.g.: "pin5" : "48491"
"pin8": ""+_pin8+"",
"pin9": ""+_pin9+"",

local jvars = http.jsonencode(pinTable);
response.header("Access-Control-Allow-Origin", "*");

device.on("impValues", function(iv) {
_pin2 = iv.pin2;
_pin5 = iv.pin5;
_pin8 = iv.pin8;
_pin9 = iv.pin9;


function requestHandler(request, response)
response.header("Access-Control-Allow-Origin", "*");

// check if the user sent led as a query parameter
if ("led" in request.query)
// if they did
if (request.query.led == "0" || request.query.led == "1" ||
request.query.led == "2" || request.query.led == "3" ||
request.query.led == "4" || request.query.led == "5" ||
request.query.led == "6")
// convert the led query parameter to an integer
local ledState = request.query.led.tointeger();

// send "led" message to device, and send ledState as the data
device.send("led", ledState);
// send a response back saying everything was OK.
response.send(200, "OK");
catch (ex)
response.send(500, "Internal Server Error: " + ex);

How can I merge the two functions, any advice? The main barrier is the because of the response.send I believe.


  • edited March 9
    Basically, you can only have one HTTP request handler. In this case, your single function checks for the presence of 'led' in request.query and if it's there, it runs the block of code in your second function. If there is no 'led', you just return jvars, as per the first block of code. Something like:
    function requestHandler(request, response) {
    try {
    if ("led" in request.query) {
    . . .
    device.send("led", ledState);
    response.send(200, "OK");
    } else {
    . . .
    response.send(200, jvars);
    } catch (ex) {
    response.send(500, "Error" + ex);
    The crucial point is not to call 'response' more than once, but you can use it in different ways.

    What I would say, though, is that if you are doing this kind of thing with complex controls (lights, temperature, heater etc). you should consider building a more structured API for your control app to interact with. You can do this very easily with the Rocky library. Better still, you can then combine that API with a web UI, both served by your agent.

    You can find some sample code for this here, and I've just built a full application you can get source code for here.
  • I would recommend you apply Key-Value pairings. At the moment you have just one "key" namely "led" which represents multiple things. This typically makes coding more complicated. Thus suggest using multiple keys such as "led", "lux" and "temp" and then attach values to each. This then allows you to send one http GET request using all key-value pairings, such as for example:

    http.agenturl() + "?led=0&lux=95&temp=32"

    Then on the other side you will get a "request.query" table. Simply use the "foreach" statement to scroll through and extract out each key-value pairing.
  • Thanks got it working with a solution similar to smittytones suggestion. One problem is when I then build and run it is that the log gets spammed with
    "UTC+0 [Agent] ERROR: no handler for agent.send()"

    But only until I send it a URL ending in "?led=" then it stops, why is this? Whats the fix?
  • Looks like your device code is sending a messaghe that the agent has no responder (device.on()) for
  • That could happen if your call to `device.on` somehow ended up inside your request-handler function, instead of being at the top level where it belongs.

    If that's not it, we'd need to see the whole code to diagnose...

Sign In or Register to comment.