Skip to main content

imp.setcountry(regionCode)

Specifies the imp’s WiFi regulatory territory at blessing

Availability

Device
Available for use in Factory Firmware only

Parameters

Name Type Description
regionCode Integer A constant specifying the device’s usage region

Returns

Nothing

Description

This method allows you to specify geographical regions in which an imp-based connected product is expected to operate. This primarily affects the number of channels within the 2.4GHz band (and, for the imp005 and imp006 with suitable WiFi module, the 5GHz band) that the device is permitted to use by the region’s regulatory bodies.

It is the responsibility of you the product vendor to enable the channel set which is applicable (and legal for) the region in which the device will be sold. Before choosing a region code to be used for a country-specific product, you must ensure that the product meets all the regulatory needs of that territory.

Region Imp Type regionCode Notes
US/Canada* imp001, 002, 003, 004m 0x00005355 2.4GHz channels 1-11
imp005 US: 0x00115858 2.4GHz channels 1-11, 5GHz channels 36-165
Canada: 0x03B64143 2.4GHz channels 1-11, 5GHz channels 36-112, 116, 132-165
The Canada channel set is smaller than the US set for 5GHz due to local regulations but otherwise the same
Europe imp001, 002, 003, 004m 0x00004247 This enables 2.4GHz channels 1-13, which are generally legal across the EU
imp005 0x037F3045 This enables 2.4GHz channels 1-13 and 5GHz channels 36-136 in steps of 4, which are generally legal across the EU. Please see our test reports that can help guide your CE self-certification process. Power levels are generally lower than the US due to the EN300-328 PSD limits
Japan imp001, 002, 003, 004m 0x00004247 This enables 2.4GHz channels 1-13
imp005 0x03B8504A This enables 2.4GHz channels 1-13 and 5GHz channels 36-136 in steps of 4
Other Countries imp001, 002, 003, 004m 0x00004247 Most countries follow either US or European standards. A compliance test house can advise you on the exact details and certifications required for each country; please contact Electric Imp Customer Support if you have questions about country codes
imp005 0x03D75658

*These codes correspond to the FCC/IC modular approval, and must be used to reuse those certifications.

This method is only available for use within factory firmware in order to set a production device’s region code after the device has been blessed. Attempting to use this method in development code or application firmware will result in a Squirrel error.

If a new country code is set when the imp is already connected to a WiFi network, the new code will only take effect when the imp next connects to a WiFi network. This disconnection and reconnection is typical behavior: the imp disconnects from the factory network, is powered down and then reconnects to the end-user’s network (enforcing the new country code) after BlinkUp™.

Using values other than those listed here is not supported — Squirrel will throw an error if you try to set an invalid code (ie. one not listed above). If you require other channel sets and/or region codes, please contact Electric Imp Customer Support.

Module-specific Information

imp005

The settings applied via imp.setcountry() will only take effect after an imp restart, eg. by calling imp.reset() or physically power-cycling the device (other imps will continue to enable the new settings on the next connection attempt).

impC001

The impC001 does not currently implement imp.setcountry().

Example Code

The following example shows the use of the imp.setcountry() method call in typical factory firmware. The method is called in the device under test (DUT) code flow in the post-bless callback, provided blessing has been successful. The code calls the function getRegionCode() to get the integer value to be passed into imp.setcountry(). getRegionCode() takes a two-character string which identifies the desired country or region; it uses imp.info() to determine the DUT’s imp type and apply the appropriate code.

// ------------------------------------------------------------------------------
// File: factory.firmware.device.nut
// Version: 1.1.6
//
// Copyright 2015-18 Electric Imp
//
// SPDX-License-Identifier: MIT
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
// EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// ------------------------------------------------------------------------------
// ***************************************
// ***** SETUP *****
// ***************************************
// IMPORTS
// Load the Factory Tools Library, which simplifies detecting Fixture or DUT
#require "FactoryTools.lib.nut:2.2.0"
// Load the CFAx33KL Library, which abstracts the LCD/Keypad used on the impFactory
#require "CFAx33KL.device.lib.nut:2.0.0"
// Load the Button library to provide debouncing on the footswitch (if installed) and green button
#require "Button.class.nut:1.2.0"
// CONSTANTS
// Enter your factory WiFi credentials as the values of these constants
const SSID = "SSID";
const PASSWORD = "PASSWORD";
// Set the target WiFi Region code (see 'getRegionCode()', below, for values)
const WIFI_REGION = "US";
// Sets how long to wait (seconds) after triggering BlinkUp before allowing another
const BLINKUP_TIME = 10;
// GLOBALS
// Flag used to prevent new BlinkUp triggers while BlinkUp is running
local sendingBlinkUp = false;
local blinkUpCount = 0;
// ***************************************
// ***** FACTORY FIXTURE FUNCTIONS *****
// ***************************************
function blinkupTriggered() {
// Trigger only when BlinkUp is not already running
if (!sendingBlinkUp) {
sendingBlinkUp = true;
imp.wakeup(BLINKUP_TIME, function() {
sendingBlinkUp = false;
});
// Configure factory BlinkUp
// NOTE Depending on which LED you connect to your impFactory, you may need
// to remove the 'BLINKUP_ACTIVEHIGH' option (default is BLINKUP_ACTIVELOW)
local optionFlags = BLINKUP_FAST | BLINKUP_ACTIVEHIGH;
// Send factory BlinkUp
server.factoryblinkup(SSID, PASSWORD, blinkupPin, optionFlags);
// Signal the agent that BlinkUp has been performed
agent.send("blinkup.sent", true);
// Update the fixture display
blinkUpCount++;
lcd.setLine2(format("BlinkUp #%07i ", blinkUpCount));
}
}
function configureFactoryFixture() {
// Assign pins
greenBtn <- Button(hardware.pinC, DIGITAL_IN, Button.NORMALLY_HIGH, null, blinkupTriggered.bindenv(this));
footSwitch <- Button(hardware.pinH, DIGITAL_IN, Button.NORMALLY_HIGH, null, blinkupTriggered.bindenv(this));
ledGreen <- hardware.pinE;
ledRed <- hardware.pinF;
blinkupPin <- hardware.pinM;
// Initialize front panel LEDs to Off
ledRed.configure(DIGITAL_OUT, 0);
ledGreen.configure(DIGITAL_OUT, 0);
// Print a message on the LCD and store it as default
lcd <- CFAx33KL(hardware.uart2);
lcd.clearAll();
lcd.setLine1("Electric Imp");
lcd.setLine2("impFactory");
lcd.setBrightness(100);
lcd.storeCurrentStateAsBootState();
}
// ***************************************
// ** DEVICE UNDER TEST (DUT) FUNCTIONS **
// ***************************************
function blessDeviceUnderTest() {
// Run any tests you require for you DUT
local testSuccess = myTestFunction();
// Attempt to bless this device, and send the result to the Factory Test Results Webhook
server.bless(testSuccess, function(blessSuccess) {
// Send identifying info and result to the test results webhook
agent.send("test.result", { "device_id": hardware.getdeviceid(),
"success": (blessSuccess ? "SUCCEEDED" : "FAILED") });
// Clear the WiFi credentials and reboot if blessing completes successfully
if (blessSuccess) {
imp.clearconfiguration();
imp.setcountry(getRegionCode(WIFI_REGION));
// The imp will go idle at this point, allowing impOS to install
// application code and restart the Squirrel VM if the Production Device Group’s
// devices are set to receive application code immediately after blessing
// If you are installing your application upon device activation (first
// end-user BlinkUp), you can power down the device at this point
}
});
}
function getRegionCode(location = "US") {
// Pass in the region ID, eg. "UK", "US", to receive the code for that region
local type = imp.info().type;
local returnCode = 0;
// Region codes data organized by territory code
// Each region has two values: the first for imp001 through imp004m, the second for imp005
// NOTE select "OT" for all regions than those listed (US, Canada, Europe/UK, Japan)
local codes = { "US" : [0x00005355, 0x00115858],
"CA" : [0x00005355, 0x03B64143],
"EU" : [0x00004247, 0x037F3045],
"JA" : [0x00004247, 0x03B8504A],
"OT" : [0x00004247, 0x03D75658] }
if (location in codes) {
returnCode = codes[location];
returnCode = returnCode[(type == "imp005" ? 1 : 0)];
} else {
server.error("Invalid region ID supplied - choosing US");
returnCode = codes.US[(type == "imp005" ? 1 : 0)];
}
server.log(format("Region code chosen: 0x%08X", returnCode));
return returnCode;
}
// ***************************************
// ***** YOUR HARDWARE TEST CODE *****
// ***************************************
function myTestFunction() {
// Run your tests here
// Returning false will prevent blessing and pass a "FAILED" to the test results webhook
return true;
}
// ***************************************
// ***** RUNTIME START *****
// ***************************************
// Use the Factory Tools library's isFactoryImp() call asynchronously in order to be sure
// the impFactory is online and has received device status data from the server
FactoryTools.isFactoryImp(function(isImpFactory) {
if (isImpFactory) {
// Device is an impFactory unit
configureFactoryFixture();
} else {
// The next call need not be asynchronous since we can be sure
// at this point (we're executing in a callback) that the status
// data has now been received by the device (whatever it is)
if (FactoryTools.isDeviceUnderTest()) {
// Device is a production unit - test it
blessDeviceUnderTest();
} else {
throw "This firmware is not running in the factory environment";
}
}
});