Sending AgentURL to Device

I’m having an issue with sending my AgentURL to my device upon agent bootup.

Upon sending and I can print out the agenturl just fine. But once I assign it to say… a global variable and try to print it out later. It comes back null. Is there something stopping the agenturl being passed between the agent and device?

No. How are you doing it? Is it going out of scope on the device?

agent:

state.AgentUrl <- http.agenturl();
device.send(“myAgent”, state.AgentUrl);

device:

local myuniqueurl; //Global scope
agent.on(“myAgent”, function(data) {
myuniqueurl = data;
Device.AgentURL = data;
server.log("Data: " + data)
server.log("myuniqueurl: " + myuniqueurl);
server.log("Device.AgentURL: " + Device.AgentURL);
});


Above code works fine I get the agent url. But around a minute later when I enter a mainloop function the myuniqueurl goes null. So it’s never really going out of scope. It’s being assigned to a global variable.

The reason I’m doing this is because I want the user to be able to obtain the agent url over bluetooth so i can poll an agent api to see if the device is online yet from the agents pov.

Maybe there is a more intuitive way to do this. If so please share, although I have a simple algorithm to get the agent url to the device upon boot and it’s returning a null. My first thought was it was out of scope, but that is not the case.

Seems I was sending it too fast for the device and it was being over-written. I have it sending for 5 seconds now and i finally receive the value. I would recommend having the callback only send after the 5th call. But it’s just an example of how I finally got it to work. We should have a simple api for this already from the device side.

agent code:

function sendAgentToDevice() {
if(agentSendCount > 5) {
return;
}
device.send(“myAgent”, state.AgentUrl);
agentSendCount++;
imp.wakeup(1, sendAgentToDevice);
}
sendAgentToDevice();

device code:
agent.on(“myAgent”, function(data) {
server.log("Assigning Device.AgentURL: " + data);
Device.AgentURL = data;
});

Your mistake here is that you have this defined in a local context, not global.

If you change this to:

myuniqueurl <- null; // this is the *actual* global scope

… then it’ll work. If you define something as local at the “top” level, functions called from the same scope will have access to it, and generally retain a reference (I think I have that right)… but as soon as your code runs off the end of the script, the locals defined there will be garbage collected.

When you want to make something a global you need to insert it into the root table with “<-”. See https://developer.electricimp.com/squirrel/squirrelcrib#global-variables

In addition, you can use device.isconnected() on the agent to learn whether the agent knowns that the device is connected yet.

There are a couple of additional methods, device.onconnected() and device.ondisconnected() which allow you to register callback functions that will be triggered upon those events.

Personally, I have my device do an ‘I’m here’ agent.send() when it’s up and running and ready to receive data from the agent.

Usually if you get one of these scope issues wrong, you end up with “index not found” exceptions – rather than the variable existing but being null. Are you sure that the device isn’t restarting at all? (Following a server.sleepfor or imp.deepsleepfor, for instance, or even an uncaught Squirrel exception.) Device-side local and global variables do not survive a device restart.

Peter