Skip to main content

Examples Of Using Agents In Factory Firmware

Factory Label Printer

You decide your product should ship with its MAC address and other unit-specific information printed on a sticky label which can be attached to the product packaging or to the base of the unit itself. How do you get the unique data from each Device Under Test (DUT) back to your factory BlinkUp™ fixture for printing? Factory agents allow you to do this.

The diagram below shows the flow of information from DUT to DUT’s agent, DUT agent to fixture’s agent, and fixture’s agent to fixture:


Once the DUT has been tested and blessed, the device-side factory firmware can call the imp API method agent.send() to transmit its data to its own agent:

local deviceData = {};
local netData =;
local network = netData.interface[("active" in netData ? : 0)];
deviceData.mac <- network.mac; <- hardware.getdeviceid();
agent.send("", deviceData);

The above code should be added to the portion of your factory firmware that manages the DUT. The agent that makes use of the information it has been sent might contain the following code:

device.on("", function(deviceData) {
  // Get the URL of the BlinkUp fixture that configured the DUT
  local fixtureAgentURL = imp.configparams.factory_fixture_url;

  if (fixtureAgentURL != null) {
    // Relay the DUT’s data (MAC, deviceID) to the factory BlinkUp fixture via HTTP
    local header = { "content-type" : "application/json" };
    local body = http.jsonencode(deviceData);
    local request =, header, body);

    // Wait for a response before proceeding, ie. pause operation until
    // fixture confirms receipt. We need label printing and DUT’s position
    // on the assembly line to stay in sync
    local response = request.sendsync();

    if (response.statuscode != 200) {
      // Issue a simple error here; real firmware would need a more advanced solution
      server.error("Problem contacting fixture");
    } else {
      // Device can now be blessed while the label is printing...
  } else {
    server.error("Posting code called in BlinkUp fixture flow not DUT flow");

The factory BlinkUp fixture’s agent URL can be obtained from the imp.configparams property, factory_fixture_url, as the code above demonstrates. Again, this code is intended for the DUT’s agent, not the BlinkUp fixture’s agent. Just as your device code needs to detect which category of device it is running on and adopt an appropriate code flow, so too does your agent code. This is particularly important here as imp.configparams’s factory_fixture_url is not available to the fixture itself.

The code branch that covers BlinkUp fixture agent operation needs code of its own: an HTTP request handler function to receive and process the data sent by each DUT’s agent:

http.onrequest(function(request, response) {
  try {
    // Look for a POST request from a device
    if (request.method == "POST") {
      if (request.body) {
        // Make sure the request has a non-null body
        try {
          local data = http.jsondecode(request.body);

          // Send the device’s data to the BlinkUp fixture
          device.send("", data);

          // Confirm successful receipt
          response.send(200, "OK");
        } catch (error) {
          response.send(400, "Could not process JSON");
  } catch (error) {
    response.send(500, "Transmission failed - please try again");

Finally, in the BlinkUp fixture’s factory firmware device code:

agent.on("", function(deviceData) {

The factory manager needs to organize this set-up so that each label is attached to the correct unit, and that blessing and printing move in step with the assembly flow. The function printLabel(), which we have not included here for clarity’s sake, will need to extract the mac and id values from deviceData table, and insert them into a template which will then be sent as data to the printer via serial or USB.

We have shown here the use of simple textual data, but the factory BlinkUp fixture’s agent might also transmit the DUT information to a remote server running a QR-code generation program. The agent requests the QR code, which is returned to it as a small bitmap graphic. This is then sent to the BlinkUp fixture to be added to the printed label.

There is an example of this in the Dev Center’s Sample Code section.

Downloading Device Resources

If you expect to ship your product with data stored on board — perhaps samples of audio tones or voice recordings transmitted to the user for guidance and feedback, or graphics that will be displayed on the product’s LCD — you can use factory agents to download these resources before blessing and place them in the DUT’s SPI flash storage. This saves the need to directly program this content into flash at an earlier stage in the assembly process, and gives you greater control over the content itself. For example, if you need to change an audio sample slightly, you can do so on the server your factory agent reaches out to; you don’t need to bundle up a new flash image and send it to the factory, which might be on a different continent and run by a contractor. This way you can guarantee that the update is applied to the production line as soon as it is ready.

Similarly, if your product contains a microphone, you might choose to take an audio sample as part of the DUT testing phase and use the factory agent to send the sample back to base. Here it can be analyzed and, if necessary, suitable calibration settings returned to the device and stored in the on-board flash.

Production BlinkUp

Many products will be configured for end-use in the field. After all, the manufacturer doesn’t know what a given end-user’s network access information will be. However, in a small number of cases — for example, devices being prepared for a specific customer — this information is known in advance, and the manufacturer would like to pre-configure production devices ahead of shipment so they are ready to use upon installation. Again, factory agents make this possible.

Electric Imp has a REST API which can be used to acquire device enrollment credentials from the Electric Imp impCloud™. These credentials can then be applied to a device using the factory API method imp.setenroltokens(). WiFi credentials can be set using imp.setwificonfiguration().

This done, when the device first connects to the specified WiFi network, it will immediately attempt to enroll itself into the Electric Imp impCloud without the need for an end-user BlinkUp: the end-user simply has to turn the device on.