Get device ID on agent without passing?

Hey guys,

I’m using the Agent more or less as a proxy to allow devices to talk to my servers elsewhere. Every API call needs to include a device id so that I can associate the call with a particular user/device.

So the agent.send()/device.on() pattern works okay, but the one problem is I can’t seem to pull the device’s id from the agent side. That means that even for calls with one parameter I have to pass a hash map with device id & param.

For example, if all I really want to send the agent is:

local somedata = "hi";

I end up having to write and send:

local somedata = "hi"; local senddata = { id = hardware.getdeviceid(), mydata = somedata }

The agent surely has to already know the device id to establish a session (the url is generated from it). Is there no way to grab it agent-side? Would make things a lot less verbose for me…

You can use server.save() to store it in non-volatile memory on the agent side.

At start up, the agent can check nvm with server.load, if the deviceId is already there, it uses it. If not, it queries the device for it and stashes it for later.

FWIW, I use the tail end of the agent’s URL as my key to know which site (device) I’m dealing with.

It’s pretty simple:
local urlTail = split(http.agenturl(), "/").top();

I’ve started using agentID for everything like @ctmorrisonhvacsp. AgentID is unique to an account + model + device, which means if/when I give devices to other people, I don’t need to worry about as many security things :slight_smile:

Here is some somewhat complex, but very reliable code to do what @coverdriven is talking about :slight_smile:

device code
`function sendDeviceID() {
agent.send(“deviceID”, hardware.getdeviceid());
}

agent.on(“getDeviceID”, function(nullData) { sendDeviceID(); });
`

agent code
`deviceID <- null;

function loadDeviceID () {
local data = server.load();
if (“deviceID” in data) {
deviceID = data.deviceID;
} else {
device.send(“getDeviceID”, null);
}
}

function saveDeviceID(id) {
local data = server.load();
if (!(“deviceID” in data)) {
data[“deviceID”] <- null;
}

data.deviceID = id;
server.save(data);

}

agent.on(“deviceID”, saveDeviceID);

loadDeviceID();`

Thanks for the tips guys!

From what I’ve read, it sounds like the agent URL can change based on software updates (which are likely to happen at some point). For my application, it’s important to know the answer to the question “is this api call from the same device that called last time?” So while I’ll need to store the agent URL, using it as the sole identifier would be problematic.

As for the server.save() solution, it sounds like that’s useful for stashing settings that can’t survive reboots, but for device id I can just fetch it again from the device if it’s not set in the local instance context. So basically the same pattern @beardedinventor suggests, but just omitting the server.save/server.load part would work fine.

That raises another question for me–is there some documentation on the server instance lifecycle? Based on the answers, I assume these per-device server instances get suspended after some period of inactivity from an individual device. What is that timeout or condition?

Thanks!

No, the agent URL will not change. There was a one-off change at one point in the past (to ensure that all URLs used consistent characters in them).

It is not problematic to use this as an identifier.

Note that agents can restart at any time due to maintenance/load balancing/etc. If this happens, and the device is offline at the time, then you wouldn’t have access to the device ID. This is why we suggest you use server.save.

Agents are not guaranteed to continue to run >30 days after the last time the imp was seen. Agents can also be stopped at production re-deploys (if a customer updates their code) until a device comes online again, though that’s a bug that will be addressed.

What’s the reliability of the server.save() table not getting reset? I don’t count on it lasting forever but I don’t know what the expectations should be around it.

You can rely on that table, it’s persistent, replicated, etc. It will last the lifetime of the agent.

Thanks Hugo, I was finding bits and pieces of information about how the URL is generated. Very helpful to know that it’s stable.