Filter results by

libzigbee API Programming

The libartik-sdk-zigbee library that comes in the ARTIK SDK is written in C, C++, and JavaScript. It provides generic ZigBee coordinator/router capabilities. You use the ARTIK IDE to build applications for it on your development PC.

Here we discuss the alternative libzigbee library for advanced users. Written in straight C for more compact code, it implements specific functionality for ZigBee device-side hardware. Typically you will use the gcc compiler on your ARTIK board to build your application.

This guide familiarizes you with libzigbee by walking you through development of a basic ZigBee application with two options – "Remote Control" and "Light Sensor" – where the Light Sensor reports its measured value to the Remote Control.

Support for the following devices is currently included in the libzigbee library.

  • On/Off Switch, Level Control Switch
  • On/Off Light, Dimmable Light
  • Light Sensor
  • Remote Control
  • Occupancy Sensor
  • Temperature Sensor
  • IAS Control and Indication Equipment
  • Thermostat (controller and humidity sensor)

More devices will be added as requested.

Preparation

Before you get started developing libzigbee applications, prepare your development environment and run the test programs to get familiar with them.

If your module image is configured to use Thread or Edge Node Manager, disable the Thread daemon before proceeding.
systemctl stop artik-ip-driver systemctl restart zigbee-daemon

These instructions are for 32-bit Ubuntu platforms (ARTIK 530).

  1. Check that you are using the latest ARTIK image version.
  2. Download the set of files to your development PC, then uncompress and copy them to your ARTIK root.

    ARTIK 530 (32-bit)

  3. On your ARTIK board, start as always with a general update.
    apt update
    apt upgrade
    apt install build-essential
  4. libzigbee uses glib. Install the development package on your ARTIK board to create/build your own applications.
    apt-get install libglib2.0-dev
  5. If you have installed a prior version of libzigbee, remove it now to prevent conflicts.
    dpkg --purge --force-all libzigbee:armhf libzigbee-dev:armhf zigbeed:armhf
  6. Install the 32-bit deb packages.
    dpkg -i libzigbee*.deb
    dpkg -i zigbeed*.deb

These instructions are for 64-bit Ubuntu platforms (ARTIK 710).

  1. Check that you are using the latest ARTIK image version.
  2. Download the set of files to your development PC, then uncompress and copy them to your ARTIK root.

    ARTIK 710 (64-bit)

  3. On your ARTIK board, start as always with a general update.
    apt update
    apt upgrade
    apt install build-essential
  4. libzigbee uses glib. Install the development package on your ARTIK board to create/build your own applications.
    apt-get install libglib2.0-dev
  5. If you have installed a prior version of libzigbee, remove it now to prevent conflicts.
    dpkg --purge --force-all libzigbee:arm64 libzigbee-dev:arm64 zigbeed:arm64
  6. Install the 64-bit deb packages.
    dpkg -i libzigbee*.deb
    dpkg -i zigbeed*.deb

These instructions are for Fedora 24 platforms.

  1. Check that you are using the latest ARTIK image version.
  2. Download the set of files to your development PC, then uncompress and copy them to your ARTIK root.

    ARTIK 520/530/710     

  3. On your ARTIK board, start as always with a general update.
    dnf upgrade
  4. libzigbee uses glib. Install the development package on your ARTIK board to create/build your own applications.
    dnf install glib2-devel
  5. Install the rpm packages.
    rpm -Uvh --force libzigbee*.rpm
    rpm -Uvh --force zigbeed*.rpm

Once you have the packages installed, you'll want to build the utility programs.

First, go to the directory where the sample code has been installed.

cd /usr/share/zigbee_test/

Now you can compile the sample applications using the following commands.

gcc zigbee_test.c zigbee_test_common.c \
-o zigbee-test `pkg-config --cflags --libs zigbee`

gcc general_testing_remote_control.c \
-o remote-control `pkg-config --cflags --libs zigbee`

gcc general_testing_light_sensor.c \
-o light-sensor `pkg-config --cflags --libs zigbee`

gcc sample_IAS_CIE_ONOFF_SWITCH.c \
-o ias-test `pkg-config --cflags --libs zigbee`


Using the example programs

Remote Control and Light Sensor demo. You'll need two ARTIK Linux boards. Run the Target (./remote-control) on the first, then run the Initiator (./light-sensor) on the other, to start sending/receiving reports.

ZigBee Test. You'll need one ARTIK Linux board plus other devices of your choice to join the network. Run the ./zigbee-test program. To test against the A030 Z3 Light project, for example, you would want to be an on-off switch:
1. Start as 'new' if asked
2. Select on-Off switch
3. Accept default endpoint
4. Choose [0] [Enter] to go to main page
5. Leave network
6. Form network
7. Apply power to your Z3Light board and it will join automatically
8. Choose Discover devices
9. Go to the Testing page
10. Use Auto test or On-Off Switch test to try out your Z3Light.

Note that this version of zigbee-test is not the same as the pre-built one that comes with the ZigBee API (in the /usr/bin directory). Call it in the /usr/share/zigbee-test directory where you built it.

IAS-CIE On/Off Test. See how easy and compact a libzigbee application can be. You'll need one ARTIK Linux board, one IAS CIE device (such as an Iris door contact sensor), and the A030 Z3 Light project. Refer to the Sensor bound to light section for details.

Creating Devices

Creating a ZigBee target device requires two steps: giving it an endpoint handle for reference, and then initializing it.

Create endpoint handle

Call API zigbee_set_local_endpoint to set the local endpoint information. One device (target) can include multiple endpoints (id: 1~239).

zigbee_error ret = EZ_ERROR;
zigbee_local_endpoint_info endpoint_info;

memset(&endpoint_info, 0, sizeof(zigbee_local_endpoint_info));

endpoint_info.endpoints[endpoint_info.count].profile = ZIGBEE_PROFILE_HA;
endpoint_info.endpoints[endpoint_info.count].endpoint_id = ENDPOINT_REMOTE_CONTROL;
endpoint_info.endpoints[endpoint_info.count].device_id = DEVICE_REMOTE_CONTROL;
endpoint_info.count++;

/* DEVICE_IAS_CIE endpoint below is to communicate with products that require IAS Zone client cluster */
endpoint_info.endpoints[endpoint_info.count].profile = ZIGBEE_PROFILE_HA;
endpoint_info.endpoints[endpoint_info.count].endpoint_id = ENDPOINT_IAS_CIE;
endpoint_info.endpoints[endpoint_info.count].device_id = DEVICE_IAS_CIE;
endpoint_info.count++;

ret = zigbee_set_local_endpoint(&endpoint_info);
if (EZ_OK != ret)
  fprintf(stderr, "Set local endpoint error %d\n", ret);

return ret;

Initialize device

Before using a device, you need to initialize it. Use API zigbee_initialize to initialize the device and set the user callback, which type is ZigBee response callback function. The first parameter is response callback, it can receive response information such as command results.

zigbee_error ret = EZ_ERROR;

static void _on_callback(void *user_data, zigbee_response_type response_type, void *payload)
{
  switch (response_type) {
    case ZIGBEE_RESPONSE_NOTIFICATION:
      ...
      break;
    case ZIGBEE_RESPONSE_NETWORK_NOTIFICATION:
      ...
      break;
    case ZIGBEE_RESPONSE_DEVICE_DISCOVER:
      ...
      break;
    case .../* there are many response types */
            /* you can check the enum zigbee_response_type*/
      ...
      break;
    default:
      break;
  }
}

/* Initialize device */
ret = zigbee_initialize(_on_callback, NULL);
if (EZ_OK != ret)
  goto free_quit;

Handling Network Operations

A ZigBee network has four basic operations: Form, Permit Join, Join, and Leave. Users can additionally choose between the form/join approach and EZ-Mode commissioning, which is just a way to automate the form/join process. To implement all these operations, you need the following seven APIs.

API NameAPI Description
zigbee_network_start
Start network operation after re-starting the application (deprecated)
zigbee_network_form
Form a new network as a coordinator
zigbee_network_join
Join to the existing network formed by other coordinator
zigbee_network_leave
Leave from the joined network
zigbee_network_permitjoin
Allow other devices joining in the formed network in certain duration of time
zigbee_device_discover
Request device/service discovery
zigbee_ezmode_commissioning
Start/Stop EZ-Mode commissioning on some endpoint as target/initiator

Here are the details for putting together a ZigBee network.

Form and Join Network

CoordinatorRouter

Call zigbee_network_start to initialize network operation

Network start

zigbee_error ret = EZ_ERROR;

ret = zigbee_network_start(state);
if (EZ_OK != ret)
	printf("network_start error %d\n", ret);

Source code same as coordinator

Call zigbee_network_form to form a network.

Network form

zigbee_error ret = EZ_ERROR;

ret = zigbee_network_form();
if (ret == S_OK)
    printf("Wait for response\n");
else
    printf("Network form failed: %d\n", ret);

After doing so, the coordinator device callback will receive
"ZIGBEE_RESPONSE_NETWORK
_NOTIFICATION" with signal
ZIGBEE_NETWORK_FIND_FORM.

Call zigbee_network_permitjoin to allow other devices to join in the network.

Permit Join

#define EASY_PJOIN_DURATION			0x3C   /* permit join duration time */
static void _on_callback(void *user_data,
             zigbee_response_type response_type,
             void *payload)
{
    switch (response_type) {
        case ZIGBEE_RESPONSE_NETWORK_NOTIFICATION:
            network_notification = *((zigbee_network_notification *) payload);
            switch (network_notification) {
                case ZIGBEE_NETWORK_FIND_FORM:
                    showln("NETWORK_NOTIFICATION: FIND FORM SUCCESS");
          ret = zigbee_network_permitjoin(EASY_PJOIN_DURATION);
          if (ret != EZ_OK)
            fprintf(stderr, "zigbee_network_permitjoin failed:%s\n", zigbee_error_msg(ret));
          break;
                ...
                default:
            }
        ...
        default:
    }
}

Once joining is permitted, call zigbee_network_join to join in the network.

Join

zigbee_error ret = EZ_ERROR;

ret = zigbee_network_join();
if (ret == S_OK)
    printf("Wait for response\n");
else
    printf("Network join failed: %d\n", ret);

Device Discovery

CoordinatorRouter

After router joins the network, the coordinator device will receive
ZIGBEE_RESPONSE_NETWORK
_NOTIFICATION
” with signal
ZIGBEE_NETWORK_JOIN.

Coordinator needs to call zigbee_device_discover to update devices and fetch the remote devices information.

Discover - coordinator

void _on_callback(void *user_data,
                  zigbee_response_type response_type,
                  void *payload)
{
  switch (response_type) {
    case ZIGBEE_RESPONSE_NETWORK_NOTIFICATION:
      network_notification = *((zigbee_network_notification *) payload);
      switch (network_notification) {
        case ZIGBEE_NETWORK_JOIN:
          showln("NETWORK_NOTIFICATION: JOIN");
          if (!conducted_by_commissioning) {
            showln("Device discovering ...");
            ret = zigbee_device_discover();
            if (ret != EZ_OK)
              fprintf(stderr, "Device discover failed:%s\n", zigbee_error_msg(ret));
          }
          break;
        ...
        default:
       }
     ...
  default:
  }
}

After router calls zigbee_network_join, the router callback will receive
“ZIGBEE_RESPONSE_NETWORK
_NOTIFICATION” with signal
ZIGBEE_NETWORK_FIND_JOIN.

Router needs to call zigbee_device_discover to update devices and fetch the remote devices information.

Discover - router

void _on_callback(void *user_data,
                  zigbee_response_type response_type,
                  void *payload)
{
    switch (response_type) {
        case ZIGBEE_RESPONSE_NETWORK_NOTIFICATION:
            network_notification = *((zigbee_network_notification *) payload);
            switch (network_notification) {
                case ZIGBEE_NETWORK_FIND_JOIN:
                    if (!conducted_by_commissioning) {
						showln("Device discovering ...");
						ret = zigbee_device_discover();
						if (ret != EZ_OK)
							fprintf(stderr, "Device discover failed:%s\n", zigbee_error_msg(ret));
					}
					break;
                ...
                default:
            }
        ...
        default:
    }
}

The discovery response will be received after zigbee_device_discover.

Discovery response

static void _on_callback(void *user_data,
						 zigbee_response_type response_type,
						 void *payload)
{
    switch (response_type) {
        case ZIGBEE_RESPONSE_DEVICE_DISCOVER:
            device_discovery = (zigbee_device_discovery *) payload;
			switch (device_discovery->status) {
			case ZIGBEE_DEVICE_DISCOVERY_START:
				showln("Device discovery start");
				break;
			case ZIGBEE_DEVICE_DISCOVERY_FOUND:
				showln("Device discovery found:");
				show_device(&(device_discovery->device));
				break;
			case ZIGBEE_DEVICE_DISCOVERY_IN_PROGRESS:
				showln("Device discovery in progress");
				showln("Done");
				break;
			case ZIGBEE_DEVICE_DISCOVERY_DONE:
				showln("Done");
				break;
			case ZIGBEE_DEVICE_DISCOVERY_NO_DEVICE:
				showln("Device discovery no device");
				showln("Done");
				break;
			case ZIGBEE_DEVICE_DISCOVERY_ERROR:
				showln("Device discovery error");
				break;
			case ZIGBEE_DEVICE_DISCOVERY_CHANGED:
				showln("Device discovery changed:");
				show_device(&(device_discovery->device));
				break;
			case ZIGBEE_DEVICE_DISCOVERY_LOST:
				showln("Device discovery lost:");
				show_device(&(device_discovery->device));
				break;
			default:
				showln("Discovery device unknown result");
				showln("Done");
				break;
			}
			break;
        ...
        default:
    }
}

Source code same as coordinator

Leave Network

CoordinatorRouter

If device wants to leave current network, it only needs to call zigbee_network_leave

Leave

zigbee_error ret = EZ_ERROR;
 
ret = zigbee_network_leave();
if (ret != EZ_OK)
	printf("Network leave failed: %d\n", ret);

If device wants to leave current network, it only needs to call zigbee_network_leave

Source code same as coordinator.

If router leaves network, the coordinator device will receive
"ZIGBEE_RESPONSE_NETWORK
_NOTIFICATION" with signal
ZIGBEE_NETWORK_LEAVE.

Callback

void _on_callback(void *user_data,
                  zigbee_response_type response_type,
                  void *payload)
{
  switch (response_type) {
    case ZIGBEE_RESPONSE_NETWORK_NOTIFICATION:
      network_notification = *((zigbee_network_notification *) payload);
      switch (network_notification) {
        case ZIGBEE_NETWORK_LEAVE:
          printf("NETWORK_NOTIFICATION: LEAVE\n");
          break;
        ...
        default:
      }
    ...
    default:
  }
}
The router cannot receive any notification after it leaves the network.

The following sequence shows you how to use EZ-Mode commissioning.

EZ-Mode Commissioning Start by Target

A target devices starts the EZ-Mode commissioning process as follows.

...
ret = zigbee_ezmode_commissioning(endpoint_id, false, true); 
...

After target start, device will receive "ZIGBEE_RESPONSE_COMMISSIONING_STATUS" response with signals
COMMISSIONING_NETWORK_STEERING_FORM
COMMISSIONING_NETWORK_STEERING_SUCCESS
COMMISSIONING_TARGET_SUCCESS

Commissioning - Target

static void _on_commissioning_status(zigbee_commissioning_state commissioning_state)
{
  switch (commissioning_state) {
    case COMMISSIONING_ERROR:
      printf("Commissioning: error\n");
      _loop_quit();
      break;
    case COMMISSIONING_ERR_IN_PROGRESS:
      printf("Commissioning: error in progress, please wait\n");
      break;
    case COMMISSIONING_NETWORK_STEERING_FORM:
      printf("Commissioning: network steering form\n");
      break;
    case COMMISSIONING_NETWORK_STEERING_SUCCESS:
      printf("Commissioning: network steering success\n");
      break;
    case COMMISSIONING_NETWORK_STEERING_FAILED:
      printf("Commissioning: network steering failed\n");
      _loop_quit();
      break;
    case COMMISSIONING_WAIT_NETWORK_STEERING:
      printf("Commissioning: wait for network steering\n");
      break;
    case COMMISSIONING_TARGET_SUCCESS:
      printf("Commissioning: target success, Please run initiator\n");
      _device_discover();
      break;
    case COMMISSIONING_TARGET_FAILED:
      printf("Commissioning: target failed\n");
      _loop_quit();
      break;
    case COMMISSIONING_TARGET_STOP:
      printf("Commissioning: target stopped\n");
      break;
    default:
      printf("Commissioning: Other status\n");
      _loop_quit();
      break;
  }
}
 
static void _on_callback(void *user_data, zigbee_response_type response_type, void *payload)
{
  switch (response_type) {
    case ZIGBEE_RESPONSE_COMMISSIONING_STATUS:
      _on_commissioning_status(*(zigbee_commissioning_state *)payload);
      break;
    ...
    default:
      break;
  }
}

After the commissioning process, device needs to call the discovery API to update devices.

EZ-Mode Commissioning Start by Initiator

After the target device receives COMMISSIONING_TARGET_SUCCESS, the initiator device can start EZ-Mode commissioning as follows.

...
ret = zigbee_ezmode_commissioning(endpoint_id, true, true);
...

After initiator start, the device will receive
"ZIGBEE_RESPONSE_COMMISSIONING_STATUS" with signal
COMMISSIONING_NETWORK_STEERING_SUCCESS.

Then the initiator device will receive these responses:
"ZIGBEE_RESPONSE_COMMISSIONING_TARGET_INFO"
and
"ZIGBEE_RESPONSE_COMMISSIONING_BOUND_INFO"

Finally, the initiator device receives the COMMISSIONING_INITIATOR_SUCCESS signal indicating that the commissioning process has finished.

Commissioning - Initiator

static void _on_commissioning_status(zigbee_commissioning_state commissioning_state)
{
  switch (commissioning_state) {
    case COMMISSIONING_ERROR:
      printf("Commissioning: error\n");
      _loop_quit();
      break;
    case COMMISSIONING_ERR_IN_PROGRESS:
      printf("Commissioning: error in progress, please wait\n");
      break;
    case COMMISSIONING_NETWORK_STEERING_FORM:
      printf("Commissioning: network steering form\n");
      break;
    case COMMISSIONING_NETWORK_STEERING_SUCCESS:
      printf("Commissioning: network steering success\n");
      break;
    case COMMISSIONING_NETWORK_STEERING_FAILED:
      printf("Commissioning: network steering failed\n");
      _loop_quit();
      break;
    case COMMISSIONING_WAIT_NETWORK_STEERING:
      printf("Commissioning: wait for network steering\n");
      break;
    case COMMISSIONING_INITIATOR_SUCCESS:
      printf("Commissioning: initiator success\n");
      _show_operations();
      break;
    case COMMISSIONING_INITIATOR_FAILED:
      printf("Commissioning: initiator failed\n");
      printf("Please run target first, application exit\n");
      _loop_quit();
      break;
    case COMMISSIONING_INITIATOR_STOP:
      printf("Commissioning: initiator stopped\n");
      break;
    default:
      printf("Commissioning: Other status\n");
      _loop_quit();
      break;
  }
}
 
static void _on_callback(void *user_data, zigbee_response_type response_type, void *payload)
{
  switch (response_type) {
    case ZIGBEE_RESPONSE_COMMISSIONING_STATUS:
      _on_commissioning_status(*(zigbee_commissioning_state *)payload);
      break;
    ...
    default:
      break;
  }
}

After the EZ-Mode commissioning process, the device needs to call the discovery API to update devices.

Implementing Reporting

After joining the ZigBee network, two or more paired devices can communicate with each other. The following example shows you how to develop an application with a reporting feature. This simple example is based on two devices: Remote Control (as Target) and Light Sensor (as Initiator)

Create handle for Remote Control device

static int _create_REMOTE_CONTROL_device(void)
{
  int ret = EZ_OK;
  zigbee_local_endpoint_info endpoint_info;

  memset(&endpoint_info, 0, sizeof(zigbee_local_endpoint_info));
  endpoint_info.endpoints[endpoint_info.count].profile = ZIGBEE_PROFILE_HA;
  endpoint_info.endpoints[endpoint_info.count].endpoint_id = ENDPOINT_REMOTE_CONTROL;
  endpoint_info.endpoints[endpoint_info.count].device_id = DEVICE_REMOTE_CONTROL;
  endpoint_info.count++;

  ret = zigbee_set_local_endpoint(&endpoint_info);
  if (EZ_OK != ret)
    printf("Set local endpoint error %d", ret);

  return ret;
}

Create handle for Light Sensor device

static int _create_LIGHT_SENSOR_device(void)
{
  int ret = EZ_OK;
  zigbee_local_endpoint_info endpoint_info;
  memset(&endpoint_info, 0, sizeof(zigbee_local_endpoint_info));
  endpoint_info.endpoints[endpoint_info.count].profile = ZIGBEE_PROFILE_HA;
  endpoint_info.endpoints[endpoint_info.count].endpoint_id = ENDPOINT_LIGHT_SENSOR;
  endpoint_info.endpoints[endpoint_info.count].device_id = DEVICE_LIGHT_SENSOR;
  endpoint_info.count++;
  ret = zigbee_set_local_endpoint(&endpoint_info);
  if (EZ_OK != ret)
    printf("Set local endpoint error %d", ret);
  return ret;
}

Use EZ-Mode Commissioning

To enable reporting, you'll need to use EZ-Mode commissioning to bind devices. You can start with no network and go straight to EZ-Mode commissioning, or you can form a network first and still use EZ-Mode commissioning. Refer to the Home Automation Public Application Profile chapter 8, Home Automation Commissioning, for more details.

When making the call, change the zigbee_ezmode_commissioning parameter endpoint_id to ENDPOINT_REMOTE_CONTROL or ENDPOINT_LIGHT_SENSOR, and change the second parameter to true for the initiator or false for the target.

Request Reporting

An API call is provided to request the Light Sensor to report measured luminance values periodically. You'll find it used in the sample code.

zigbee_request_reporting(ZCL_ILLUM_MEASUREMENT_CLUSTER_ID, 
    endpoint, ZIGBEE_REPORTING_MEASURED_ILLUMINANCE, min_interval,
    max_interval, threshold, ENDPOINT_REMOTE_CONTROL);

After requesting "reporting configure", the remote control device can get notification whenever the attribute value in the light sensor device is changed through the callback function.

Handling Optional Attributes

libzigbee does not provide specific API calls for optional attributes. However, you can use the zigbee_general_ API calls for reading/writing optional attributes. These work both locally and remotely, with the following requirements.

  • To read/write attributes on the local device, the current endpoint must contain the specified server cluster.

  • To read/write attributes on the remote device, the remote endpoint must contain the specified server cluster.

We'll provide examples below for reading and writing the optional, but commonly used, "manufacturer name" attribute. You can also refer to the zigbee_test.c program to perform these accesses.

Read/Write Local Attribute

Start with an endpoint in the local device containing the Basic server cluster. Now call
zigbee_general_read_local_attribute()
and
zigbee_general_write_local_attribute()
to read and write the manufacturer name attribute.


char value[MAX_ATTRIBUTE_SIZE];
unsigned int value_length = 0;
zigbee_attribute_data_type value_type = ZIGBEE_UNKNOWN_ATTRIBUTE_TYPE;
char *manufacturer_name = NULL;
zigbee_error ret = EZ_OK;
 
manufacturer_name = "artik_manufacturer_name";
ret = zigbee_general_write_local_attribute(ZCL_BASIC_CLUSTER_ID, ZCL_MANUFACTURER_NAME_ATTRIBUTE_ID,
        manufacturer_name, strlen(manufacturer_name), ZIGBEE_CHAR_STRING_ATTRIBUTE_TYPE, local_endpoint);
if (EZ_OK != ret) {
    fprintf(stdout, "Basic: write local manufacturer name %s failed: %d\n", manufacturer_name, ret);
    return;
} else {
    fprintf(stdout, "Basic: write local manufacturer name %s success\n", manufacturer_name);
}
 
ret = zigbee_general_read_local_attribute(ZCL_BASIC_CLUSTER_ID, ZCL_MANUFACTURER_NAME_ATTRIBUTE_ID, value,
        &value_length, &value_type, local_endpoint);
if (EZ_OK != ret) {
    fprintf(stdout, "Basic: read local manufacturer name failed: %d\n", ret);
} else {
    fprintf(stdout, "Basic: read local manufacturer name %s value length %d value type 0x%02X\n", value,
            value_length, value_type);
}

Sample console output would be as shown.


Basic: write local manufacturer name artik_manufacturer_name success
Basic: read local manufacturer name artik_manufacturer_name value length 23 value type 0x42

Read Remote Attribute

Start with at least two ZigBee devices in the same network, one with the Basic cluster enabled as client and at least one with the Basic cluster enabled as server. From the client, call
zigbee_general_read_remote_attribute()
to read the manufacturer name attribute from a remote device.


zigbee_endpoint_list endpoint_list;
struct zigbee_sending_info sending_info;
char value[MAX_ATTRIBUTE_SIZE];
unsigned int value_length = 0;
zigbee_attribute_data_type value_type = ZIGBEE_UNKNOWN_ATTRIBUTE_TYPE;
zigbee_error ret = EZ_OK;
 
ret = zigbee_device_find_by_cluster(&endpoint_list, ZCL_BASIC_CLUSTER_ID, 1);
if (EZ_OK != ret) {
    fprintf(stdout, "Basic: Find endpoint by cluster failed: %d\n", ret);
    return;
}
 
sending_info.type = ZIGBEE_SENDING_BY_ENDPOINT;
memcpy(&sending_info.data.dest_endpoint, &endpoint_list.endpoint[0], sizeof(zigbee_endpoint));
ret = zigbee_general_read_remote_attribute(&sending_info, ZCL_BASIC_CLUSTER_ID,
        ZCL_MANUFACTURER_NAME_ATTRIBUTE_ID, value, &value_length, &value_type, local_endpoint);
if (EZ_OK != ret) {
    fprintf(stdout, "Basic: read remote manufacturer name failed: %d\n", ret);
} else {
    fprintf(stdout, "Basic: read remote manufacturer name %s value length %d value type 0x%02X\n", value,
            value_length, value_type);
}

Sample console output would be as shown.

Basic: read remote manufacturer name artik_manufacturer_name value length 23 value type 0x42

Write Remote Attribute

Most attributes are read-only for the remote device. Before writing a remote attribute, check whether the attribute is read-only or not per the ZigBee Cluster Library Specification (manufacturer name, for example, is read-only). If writable, follow the same scheme as above.

IAS Zone Devices

libzigbee is constantly being improved to interoperate with ZigBee products available in the marketplace. Some popular ones go by the Iris® brand name. We provide related information below, based on our testing.

If there is a specific product for which you need additional information, contact us through the Forums and use 'libzigbee' in the subject line.

libzigbee supports IAS Control and Indication Equipment (CIE) reports. The Iris motion and contact sensors are examples of IAS Zone devices. Unlike other attribute reporting, IAS Zone devices report attribute changes through the "Zone Status Change Notification" command from the IAS Zone node to an IAS CIE node.

Sensor

For the example below, you'll need an Iris (or comparable) motion or contact sensor along with your ARTIK board with libzigbee installed and using the zigbee-test program you compiled initially.

Prerequisite. You'll need to start with the sensor reset, unconnected to any network. Follow the manufacturer's instructions for doing so (hold the reset button depressed while inserting the battery to get a red LED, similar to the Smart Button example.

  1. Go to the test directory.
    cd /usr/share/zigbee_test/

  2. Run
    zigbee-test

  3. On the first screen, add a new device: Type 1 [Enter].

  4. On the next screen, add IAS CIE support by typing [9] [Enter], and [Enter] again.

  5. Type 0 [Enter] to finish adding device endpoints.

  6. Set up and join the network on the main screen:

    1. Type 7 [Enter] to leave the network, and wait for Done.

    2. Type 1 [Enter] to form a new network, then wait for FIND FORM SUCCESS. You are now in the permit joining phase.

    3. Within the join time, insert the battery on the sensor and wait for it to join the network (LED blue to green).

	NETWORK_NOTIFICATION: FIND FORM SUCCESS
	[testzigbee] callback end
	In callback, response type : 3307
	NETWORK_NOTIFICATION: JOIN
	[testzigbee] callback end
	In callback, response type : 3407
	[testzigbee] callback end

Now, when you make a motion in front of the motion sensor, or move the magnet on the contact sensor, and observe the screen, you should see output like this.

In callback, response type : 3322
IAS Zone status 0x0025 source node 0x744D zone id 0x00 delay 3
 - ALARM1 : opened or alarmed
 - ALARM2 : closed or not alarmed
 - TAMPER : Tampered
 - BATTERY : Battery OK
 - SUPERVISION_REPORTS : Does not report
 - RESTORE_REPORTS : Reports restore
 - TROUBLE : OK
 - AC : AC/Mains OK
 - TEST : Sensor is in operation mode
 - BATTERY_DEFECT : Sensor battery is func-tioning normally
[testzigbee] callback end

Sensor bound to light

You can use the IAS-CIE On/Off Test to do the same thing as you did with zigbee-test, as well as bind with a light, without typing in any commands.

  1. Go to the test directory.
    cd /usr/share/zigbee_test/

  2. Run the IAS-CIE On/Off Test demonstration program.
    ./ias-test

  3. Join your A030 Z3 Light.

  4. Join your sensor as you did previously.

Wait several seconds and then try activating the sensor. You should see the Z3 Light LED toggle on and off.

This example program is meant as an easy starting point for your IAS Zone device projects, so take advantage of it!

Last updated on: