Bluetooth Mesh

Last Updated on : 2024-04-04 16:26:49download

Bluetooth mesh enables Bluetooth devices to communicate with each other over a mesh network. This topic describes the API methods and examples of Bluetooth mesh capabilities provided by the Commercial Lighting App SDK.

Concepts

The Bluetooth Special Interest Group (SIG) provides Bluetooth mesh technologies to enable mesh networking. Bluetooth mesh is also known as Bluetooth SIG mesh. This mesh networking standard allows for many-to-many communication over Bluetooth radio. The standard must be followed to implement Bluetooth mesh networking and device updates.

Glossary

Term Description
Product category and type Each Bluetooth mesh device corresponds to a product that belongs to a product category and a product type. The SDK provides pcc to specify a product category and type to specify a product type.
Mesh group localId The 2-byte localId uniquely identifies a mesh group in a mesh network. To control a group, send commands to its localId in the mesh network.
Mesh nodeId The 2-byte nodeId uniquely identifies a mesh device in a mesh network. To control a device, send commands to its nodeId in the mesh network.
Local connection Connect to a paired device over Bluetooth for control.
Gateway connection Connect to a paired device through a gateway within the acceptable range for control.

Synchronous operations

Any operations performed on a device or group will be executed locally and then synchronized to the cloud. When issuing a command, the app needs to send the command to both the device and the cloud for synchronization.

Device classification rules (categories and types)

  • The device category is defined with a combination of device type, product category, and product type, stored in the little-endian format.

    • Device type:
      • Standard: 1
      • Raw: 2
    • Bluetooth mesh products are classified into the following product categories:
      • Lighting (01): smart lights ranging from cool white lights (C) to white and colored lights (RGBCW)
      • Electrical (02): one to six-outlet sockets
      • Remote control (05): one to six-button remote controls
    • Product types of a category:
      • Smart lights ranging from cool white lights (C) to white and colored lights (RGBCW) (01–05)
      • One to six-outlet power strips (01–06)
      • One to six-button remote controls (01–06)
  • Example:

    Product Category value Description
    Standard white and colored light (RGBCW) 1510 1015 in the little-endian format:
    • 1: standard device
    • 01: light
    • 5: white and colored light (RGBCW)
    Standard 4-outlet power strip 2410 1024 in the little-endian format:
    • 1: standard device
    • 02: socket
    • 4: 4-outlet power strip
    Raw type of device xx20 20xx in the little-endian format: 2 represents a device of raw type.

Preparation

  • System requirements: Android 4.3 or later

  • Manifest permissions:

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
    
  • Bluetooth permission precheck: It is performed before Bluetooth scanning and connection. Otherwise, the app cannot use Bluetooth as expected.

    • Before scanning and connection, the app checks if it is allowed to access location services.
    • Check if the phone’s Bluetooth is turned on.

    The Commercial Lighting App SDK does not provide the logic for precheck. You can implement it on your own.

Pairing

In a pairing process, the Bluetooth mesh device joins the target mesh network after data exchange.

Scan for sub-devices

Scan for Bluetooth mesh devices ready for pairing. When a device is discovered, it can be paired.

API description

// Start scanning
void startSearch();
// Stop scanning
void stopSearch();

Example

IThingBlueMeshSearchListener iThingBlueMeshSearchListener=new IThingBlueMeshSearchListener() {
    @Override
    public void onSearched(SearchDeviceBean deviceBean) {

    }

    @Override
    public void onSearchFinish() {

    }
};
// The UUID of the Bluetooth mesh device to be paired.
UUID[] MESH_PROVISIONING_UUID = {UUID.fromString("00001827-0000-1000-8000-00805f9b34fb")};
SearchBuilder searchBuilder = new SearchBuilder()
                                .setServiceUUIDs(MESH_PROVISIONING_UUID)    // The UUID of the Bluetooth mesh device. It is a fixed value.
                .setTimeOut(100)        // The scan timeout, in seconds.
                .setThingBlueMeshSearchListener(iThingBlueMeshSearchListener).build();

IThingBlueMeshSearch mMeshSearch = ThingOSMesh.activator().newThingBlueMeshSearch(searchBuilder);

// Start scanning
mMeshSearch.startSearch();

// Stop scanning
mMeshSearch.stopSearch();

Get device information

Request the name and icon of the discovered device.

API description

void getActivatorDeviceInfo(String productId, String uuid, String mac, IThingDataCallback<ConfigProductInfoBean> callback);

Parameter description

Parameter Type Description
productId String SearchDeviceBean.productId. byte[] must be converted into String before this parameter is set.
uuid String The device UUID. The value is null for a Bluetooth mesh device.
mac String SearchDeviceBean.productId

Example

ThingOSActivator.deviceActivator().getActivatorDeviceInfo(
    // btye[] to String
    new String(bean.getProductId(), StandardCharsets.UTF_8),
    // uuid
    null,
    // mac
    scanDeviceBean.getMacAdress(),
    // callback
    new IThingDataCallback<ConfigProductInfoBean>() {
        @Override
        public void onSuccess(ConfigProductInfoBean result) {

        }

        @Override
        public void onError(String errorCode, String errorMessage) {

        }
});

Callback description

ConfigProductInfoBean

Property Type Description
name String The product name. Its value is set in the cloud. Typically, the name is specified when the product is created.
icon String The icon of the product.

Pair Bluetooth mesh sub-device

Sub-devices can be paired with the app over Bluetooth or through a gateway.

API description

// Start pairing
void startActivator();
// Stop pairing
void stopActivator();

Example

ThingSigMeshActivatorBuilder ThingSigMeshActivatorBuilder = new ThingSigMeshActivatorBuilder()
            .setSearchDeviceBeans(mSearchDeviceBeanList)
            .setSigMeshBean(sigMeshBean) // Basic information about Bluetooth mesh
            .setHomeId(gid)// Required parameter. The gid of the area to which the target device belongs.
            .setTimeOut(100) // Timeout
            .setThingBlueMeshActivatorListener(new IThingBlueMeshActivatorListener() {
     @Override
     public void onSuccess(String mac, DeviceBean deviceBean) {
         L.d(TAG, "subDevBean onSuccess: " + deviceBean.getName());
     }
     @Override
     public void onError(String mac, String errorCode, String errorMsg) {
         L.d(TAG, "config mesh error" + errorCode + " " + errorMsg);
     }
     @Override
     public void onFinish() {
      L.d(TAG, "config mesh onFinish");
     });

IThingBlueMeshActivator iThingBlueMeshActivator = ThingOSMesh.activator().newSigActivator()(ThingSigMeshActivatorBuilder);

// Start pairing
iThingBlueMeshActivator.startActivator();

// Stop pairing
iThingBlueMeshActivator.stopActivator();

Set the homeIdto the relation ID of the area to which the device belongs. See Get Area Relation ID.

Parameter description

Parameter Description
mSearchDeviceBeanList The collection of devices to be paired, returned by startSearch.
timeout The pairing timeout, defaulting to 100, in seconds. The value can be increased to pair a large number of devices.
sigMeshBean SigMeshBean

Response parameters

Parameter Description
DeviceBean The type of device data. For more information, see DeviceBean.
errorCode For more information, see Pairing Error Codes.

Pair Bluetooth mesh gateway

A Bluetooth mesh gateway is a combo device.

  • It is paired over Wi-Fi. For more information, see Wi-Fi EZ Mode.

Pair Bluetooth mesh sub-device through gateway

Pair a Bluetooth mesh sub-device through a gateway in the same way as Zigbee sub-devices. For more information, see Sub-Device Pairing.

Pairing error codes

Error code Error message
21002 Invite failure.
21004 Provision failure.
21006 Failed to send a public key.
21008 Conform failure.
210010 Random conform failure.
210014 Failed to send data.
210016 Composition data failure.
210018 Failed to add appkey.
210020 Failed to bind a model.
210022 Publication model failure.
210024 Network transmit failure.
210026 Cloud registration failure.
210027 The maximum number of device addresses has been reached.
210034 Notify failure.
20021 Pairing timeout.

Device

The IThingBlueMeshDevice class provides operations to manage Bluetooth mesh groups.

Query device instance

Example

IThingBlueMeshPlugin plugin = PluginManager.service(IThingBlueMeshPlugin.class);
IThingBlueMeshDevice mThingBlueMeshDevice = plugin.newSigMeshDeviceInstance("meshIdxxxx");

Query Bluetooth mesh connection status

Example

DeviceBean deviceBean = ThingOSDevice.getDeviceBean(mDevId);
DeviceBean gwBean = ThingOSDevice.getDeviceBean(deviceBean.getParentId());

// Online status (local network and gateway)
boolean online = deviceBean.getIsOnline()
// The online status on the local Bluetooth network.
boolean localOnline = deviceBean.getIsLocalOnline()
// The online status through gateway (both the gateway and sub-device are online)
boolean wifiOnline = deviceBean.isCloudOnline() && gwBean.getIsOnline()

Check device type

Example

DeviceBean deviceBean = ThingOSDevice..getDeviceBean(mDevId);
// Check if this is a Bluetooth mesh device (sub-device connected to gateway)
if(deviceBean.isSigMesh()){
    // This device is sig mesh device"
}

// Check if this is a Bluetooth mesh gateway.
if(deviceBean.isSigMeshWifi()){
    // This device is sig mesh Wi-Fi device
}

Rename Bluetooth mesh sub-device

API description

void renameMeshSubDev(String devId, String name, IResultCallback callback);

Parameter description

Parameter Description
devId The device ID.
name The new name of the device.
callback The callback.

Example

IThingBlueMeshPlugin plugin = PluginManager.service(IThingBlueMeshPlugin.class);
IThingBlueMeshDevice mThingBlueMeshDevice = plugin.newSigMeshDeviceInstance("meshIdxxxx");

mThingBlueMeshDevice.renameMeshSubDev("devIdxxxx","New name", new IResultCallback() {
     @Override
     public void onError(String code, String errorMsg) {
        // Rename failed.
     }

     @Override
     public void onSuccess() {
        // Rename succeeded.
     }
});

Query Bluetooth mesh sub-device status

Request the current status of Bluetooth mesh sub-devices. The result is returned by the method onDpUpdate of IMeshDevListener.

API description

void querySubDevStatusByLocal(String pcc, final String nodeId, final IResultCallback callback);

Parameter description

Parameter Description
pcc The category and type of the device.
nodeId The nodeId of the device.
callback The callback.

Example

IThingBlueMeshPlugin plugin = PluginManager.service(IThingBlueMeshPlugin.class);
IThingBlueMeshDevice mThingBlueMeshDevice = plugin.newSigMeshDeviceInstance("meshIdxxxx");

mThingBlueMeshDevice.querySubDevStatusByLocal(devBean.getCategory(), devBean.getNodeId(), new IResultCallback() {
    @Override
    public void onError(String code, String errorMsg) {
        // Query failed.
    }
    @Override
    public void onSuccess() {
        // Query succeeded. See the callback for IMeshDevListener.
    }
});

Configure online profile

The SDK provides the following online profiles that define the online status of Bluetooth mesh devices after they are paired:

  • Online profile 1: By default, all sub-devices go online after they are connected to a Bluetooth mesh network.
  • Online profile 2: Check the online status of all sub-devices after they are connected to a Bluetooth mesh network.

The following example shows how to configure the online profile for paired Bluetooth mesh devices.

Example

// Use the profile of requesting the online status of all sub-devices in the Bluetooth mesh network.
SigMeshConfiguration.OnlineMode onlineMode = SigMeshConfiguration.OnlineMode.RESPONSE_ONLINE;
ISigMeshControl sigMeshControl = ThingOSMesh.getSigMeshControl(mMeshId);
if (sigMeshControl != null){
    SigMeshConfiguration sigMeshConfiguration = sigMeshControl.getSigMeshConfiguration();
    if (sigMeshConfiguration != null){
        sigMeshConfiguration.setOnlineMode(onlineMode);
    }
}

Online profile

SigMeshConfiguration.OnlineMode

Enum value Description
DEFAULT By default, all Bluetooth mesh sub-devices go online after they are paired.
RESPONSE_ONLINE Check the online status of all sub-devices after they are connected to a Bluetooth mesh network.

Query online status

Method 1: Follow the online profile for Bluetooth mesh sub-devices

Checks whether sub-devices are online or offline after they are connected to a Bluetooth mesh network based on the specified online profile. The value of OnlineMode determines the types of sub-devices to be queried:

  • If OnlineMode is RESPONSE_ONLINE, the online status of all sub-devices is returned automatically.
  • If OnlineMode is DEFAULT, the status of offline sub-devices is returned automatically.

API description

ISigMeshControl sigMeshControl = ThingOSMesh.getSigMeshControl(mMeshId);
if (sigMeshControl != null){
    sigMeshControl.queryAllOnLineStatusByLocal(new IResultCallback() {
        @Override
        public void onError(String code, String error) {
             // Failed to deliver the query command.
        }

        @Override
        public void onSuccess() {
            // The query command is delivered successfully.
        }
    });
}

Method 2: Customize online profile

API description

ISigMeshControl sigMeshControl = ThingOSMesh.getSigMeshControl(mMeshId);
int queryStrategy = 0;
// The query profile. 0: Query all sub-devices in the Bluetooth mesh network. 1: Query the offline devices only.
if (sigMeshControl != null){
    sigMeshControl.queryMeshDeviceOnlineStatusByLocal(queryStrategy, new IResultCallback() {
        @Override
        public void onError(String code, String error) {
             // Failed to deliver the query command.
        }

        @Override
        public void onSuccess() {
            // The query command is delivered successfully.
        }
    });
}

Parameter description

Enum value Description
queryStrategy Specifies the types of devices to be queried in the online profile:
  • 0: The online or offline status of all Bluetooth mesh sub-devices.
  • 1: Only the offline Bluetooth mesh sub-devices.

Remove Bluetooth mesh sub-device

API description

void removeMeshSubDev(String devId, IResultCallback callback);

Parameter description

Parameter Description
devId The device ID.
pcc The category and type of the device.
callback The callback.

Example

IThingBlueMeshPlugin plugin = PluginManager.service(IThingBlueMeshPlugin.class);
IThingBlueMeshDevice mThingBlueMeshDevice = plugin.newSigMeshDeviceInstance("meshIdxxxx");
mThingBlueMeshDevice.removeMeshSubDev(devBean.getDevId(), devBean.getCategory(), new IResultCallback() {
    @Override
    public void onError(String code, String errorMsg) {

    }
    @Override
    public void onSuccess() {

    }
});

Control

Smart devices are managed with DPs. Bluetooth mesh devices are also controlled by device DPs. The IThingBlueMeshDevice class provides operations to manage Bluetooth mesh devices.

Command format

Send a command in the following format:

{
    "(dpId1)":(dpValue1),
    "(dpId2)":(dpValue2)
}

For more information, see Data Points.

Send control commands

API description

void publishDps(String nodeId, String pcc, String dps, IResultCallback callback);

Parameter description

Parameter Description
nodeId The local ID of the sub-device.
pcc The product category and type of the sub-device.
dps The list of DPs. For more information, see Data Points.
callback The callback.

Example

String dps = {"1":false};

IThingBlueMeshPlugin plugin = PluginManager.service(IThingBlueMeshPlugin.class);
IThingBlueMeshDevice mThingBlueMeshDevice = plugin.newSigMeshDeviceInstance("meshIdxxxx");

mThingSigMeshDevice.publishDps(devBean.getNodeId(), devBean.getCategory(), dps, new IResultCallback() {
    @Override
    public void onError(String s, String s1) {
        // Failed to send DPs.
    }

    @Override
    public void onSuccess() {
        // DPs are sent successfully.
    }
});

Listener for device control

Device information on a Bluetooth mesh network, such as DP data, status changes, device name, and device removal, is synchronized to IMeshDevListener in real time.

Example

mThingSigMeshDevice.registerMeshDevListener(new IMeshDevListener() {
    /**
    * Update data
    * @param nodeId    Update the nodeId of the device.
    * @param dps        DP data.
    * @param isFromLocal   The data source. true: local Bluetooth network. false: cloud
    */
    @Override
    public void onDpUpdate(String nodeId, String dps,boolean isFromLocal) {
        // You can locate the corresponding DeviceBean by node.
        DeviceBean deviceBean = mThingBlueMeshDevice.getMeshSubDevBeanByNodeId(nodeId);
    }
    /**
    * Report device status
    * @param online    Online device list
    * @param offline   Offline device list
    */
    @Override
    public void onStatusChanged(List<String> online, List<String> offline,String gwId) {

    }

    /**
    * Network status changes
    * @param devId
    * @param status
    */
    @Override
    public void onNetworkStatusChanged(String devId, boolean status) {

    }
    /**
    * Report data of raw type
    * @param bytes
    */
    @Override
    public void onRawDataUpdate(byte[] bytes) {

    }
    /**
    * Modify device information, such as name.
    * @param bytes
    */
    @Override
    public void onDevInfoUpdate(String devId) {

    }
    /**
    * Remove device
    * @param devId
    */
    @Override
    public void onRemoved(String devId) {

    }
});

Update

Bluetooth mesh sub-devices can be updated over the air.

Bluetooth LE mesh devices need to wake up before updates. The wake-up method varies depending on the device.

Get firmware update information

API description

void requestUpgradeInfo(String devId, IRequestUpgradeInfoCallback callback);

Parameter description

Parameter Description
devId The ID of the target device.
callback The callback.

Example

IThingBlueMeshPlugin iThingBlueMeshPlugin = PluginManager.service(IThingBlueMeshPlugin.class);
iThingBlueMeshPlugin.getMeshInstance().requestUpgradeInfo(mDevID, new IRequestUpgradeInfoCallback() {
    @Override
    public void onSuccess(ArrayList<BLEUpgradeBean> bleUpgradeBeans) {

    }

    @Override
    public void onError(String errorCode, String errorMsg) {

    }
});

BLEUpgradeBean returns the firmware update information as described in the following table.

Field Type Description
upgradeStatus int The update status.
  • 0: No update available
  • 1: An update available
  • 2: Updating
version String The latest version.
currentVersion String The current version.
timeout int The specified timeout, in seconds.
upgradeType int
  • 0: Update notification
  • 2: Forced update
  • 3: Check for update
type int The source of the firmware.
  • 0: Wi-Fi module
  • 1: Bluetooth module
  • 2: GPRS module
  • 3: Zigbee module
  • 9: MCU
typeDesc String The description of the update.
lastUpgradeTime long The last update time, in milliseconds.
url String The URL to download the update. This parameter has a value when type is 1 or 9.
fileSize long The size of the update.
md5 String The MD5 hash value of the update.

Update Bluetooth mesh sub-device

API description

void startOta();

Example

private MeshUpgradeListener mListener = new MeshUpgradeListener() {
    @Override
    public void onUpgrade(int percent) {
        // The update progress.
    }

    @Override
    public void onSendSuccess() {
        // The firmware update is sent successfully.
    }

    @Override
    public void onUpgradeSuccess() {
        // Update succeeded.
        mMeshOta.onDestroy();
    }

    @Override
    public void onFail(String errorCode, String errorMsg) {
        // Update failed.
        mMeshOta.onDestroy();
    }
};

// Query the byte stream of the specified file.
byte data[] = getFromFile(path);

ThingBlueMeshOtaBuilder build = new ThingBlueMeshOtaBuilder()
        .setData(data)
        .setMeshId(mDevBean.getMeshId())
        .setMac(mDevBean.getMac())
        .setProductKey(mDevBean.getProductId())
        .setNodeId(mDevBean.getNodeId())
        .setDevId(mDevID)
        .setVersion("version")
        .setThingBlueMeshActivatorListener(mListener)
        .bulid();
IThingBlueMeshOta mMeshOta = ThingOSMesh.newOTA(build);

// Start update
mMeshOta.startOta();

Request parameters

ThingBlueMeshOtaBuilder

Parameter Type Description
data byte[] The byte stream of the target firmware.
meshId String The meshId of the Bluetooth mesh device.
mac String The MAC address of the device.
productkey String The product ID (PID) of the device.
mNodeId String The nodeId of the device.
devId String The device ID.
version String The version number of the target firmware.

Update Bluetooth mesh gateway

Update a Bluetooth mesh gateway the same way you would update a Wi-Fi device.

Example

private IOtaListener iOtaListener = new IOtaListener() {
    @Override
    public void onSuccess(int otaType) {
        // Update succeeded.
    }

    @Override
    public void onFailure(int otaType, String code, String error) {
        // Update failed.
    }

    @Override
    public void onProgress(int otaType, final int progress) {
        // The update progress.
    }
};
IThingOtaPlugin otaPlugin = PluginManager.service(IThingOtaPlugin.class));
IThingOta iThingOta = otaPlugin.newOTAInstance(devId);
iThingOta.setOtaListener(mOtaListener);
// Start update
iThingOta.startOta();

// Destroy update
iThingOta.onDestroy();