原文:https://docs.edgexfoundry.org/Ch-GettingStartedSDK.html

EdgeX Device Service SDK 能够帮助开发者为EdgeX快速地创建一个新设备连接器,因为它提供了设备服务共用的脚手架(scaffolding)。脚手架提供了服务供给(provisioning)的模式,包括了接收和响应命令的公共代码模板,并且提供了获取从传感器到EdgeX Core Data的数据(通常作为数据注入 data ingestion)的公共代码。使用SDK, 开发者只需要关注通过设备协议与设备进行通信的代码。

接下来,我们会创建一个简单的设备服务来生产随机数,而不是从真实的传感器获取。通过这种方式,你并不需要跟实际设备打交道,就可以探索实现设备服务所需的脚手架和其他必要的相关工作。

安装依赖库

如果要使用EdgeX C SDK来构建设备服务,你需要安装下面的库

libmicrohttpd
libcurl
libyaml
libcbor

在Ubuntu上运行下面命令:

sudo apt install libcurl4-openssl-dev libmicrohttpd-dev libyaml-dev libcbor-dev

2. 获取EdgeX Device SDK C

接下来下载并编译C版本的EdgeX Device SDK, 要注意使用与EdgeX匹配的SDK版本。当前edinburgh版本是EdgeX的稳定版本, 所以我们使用edinburgh分支的C SDK.

首先,从Github克隆device-sdk-c的edinburgh分支:

git clone -b edinburgh https://github.com/edgexfoundry/device-sdk-c.git
cd ./device-sdk-c

接下来,编译device-sdk-c:

./scripts/build.sh

可能会碰到以下两个问题

  • 问题1:./scripts/build.sh: 77: ./scripts/build.sh: cmake: not found 解决方法:安装cmake

sudo apt-get install build-essential cmake

  • 问题2: UUID library or header not found 解决方法:安装uuid开发库

sudo apt-get install uuid-dev

3. 创建新设备服务项目

我们从C SDK里的例子模板开始,修改它的功能让它生成随机整数。

首先,创建目录example-device-c,并把例子代码拷贝进去:

mkdir -p ../example-device-c/res
cp ./src/c/examples/template.c ../example-device-c
cd ../example-device-c

4. 构建设备服务

现在,你可以使用前一步里编辑过的C SDK来构建你的设备服务

告诉编译器C SDK文件位置:

export CSDK_DIR=../device-sdk-c/build/release/_CPack_Packages/Linux/TGZ/csdk-1.0.0

注意: 实际的CSDK_DIR路径可能会随着SDK的版本变化而不同,比如我当前用的就是csdk-1.0.3

重新编译设备服务,生成可执行文件:

gcc -I$CSDK_DIR/include -L$CSDK_DIR/lib -o device-example-c template.c -lcsdk

5. 自定义你的设备服务

至此,你已经成功地编译了C SDK里设备服务例子,为了让它支持生成随机数的功能,你需要修改文件template.c里的方法template_get_handler,如下:

for (uint32_t i = 0; i < nreadings; i++)
{
  const edgex_nvpairs * current = requests[i].attributes;
  while (current!=NULL)
  {
    if (strcmp (current->name, "type") ==0 )
    {
      /* Set the resulting reading type as Uint64 */
      readings[i].type = Uint64;
      if (strcmp (current->value, "random") ==0 )
      {
        /* Set the reading as a random value between 0 and 100 */
        readings[i].value.ui64_result = rand() % 100;
      }
    }
    current = current->next;
  }
}
return true;

6. 创建设备文件 Device Profile

设备文件是YAML文件,它描述了EdgeX的一个设备类。包括:这类设备的整体特点,提供的数据,支持的命令等。

设备服务通过设备文件去理解设备收集到的数据(某些情况下,设备服务根据它提供的信息来与设备进行通信以及获取传感器的readings).

我们需要一个设备文件去描述从这个简单的随机数生成设备服务收集的那些数据。

1.查看src/c/examples/res 目录下的文件. 注意例子的设备文件YAML(TemplateProfile.yaml)已经存在了。你可以查看文件内容来看看设备怎样在YAML里表示的。特别注意,传感器的字段和属性是怎样被“deviceResources”表示的。发给设备的命令用“coreCommands”表示.

2.下载random-generator-device.yaml,放到./res文件夹.

你可以在文件编辑器里打开random-generator-device.yaml。在这个设备文件里, 你给EdgeX描述的设备有个单独或者(或者叫deviceResource)必须让EdgeX知道 - 在当前例子里,这个属性是“randomnumber”.

注意:deviceResource是类型化的

在真实的IoT场景中,deviceResource列表可以被扩展,并且可以被填写为各种不同的数据类型。

同时注意: 设备文件里描述的REST命令,可以被他人用来调用(或者GET),以此从设备服务中获取随机数。

7. 配置设备服务

现在,给你的新设备服务更新配置:修改它的运行端口(不能与其他服务冲突),修改从设备服务收集数据的调度时间(每10秒),设置设备启动时的生成的随机数初始值。

如果你是在Docker container里运行EdgeX,你需要告诉新的设备服务去监听Docker主机IP地址(172.17.0.1),而不是本地主机。 修改文件configuration.toml的顶端部分如下:

[Service]
Host = "172.17.0.1"
Port = 49992

8. 重新编译设备服务

现在,你有了新的设备服务,它会返回一个随机数,设备文件会告诉EdgeX如何去读取随机数,配置文件会让你的设备服务将它自己和设备文件注册到EdgeX,并开始每10秒读取一次。

重新编译设备服务,来包含新的修改:

gcc -I$CSDK_DIR/include -L$CSDK_DIR/lib -o device-example-c template.c -lcsdk

9. 运行设备服务

接下来运行设备服务,让这个通过C SDK实现的设备服务创建传感器模拟数据,并发送到EdgeX

按照手册Getting Started - Users 将所有的EdgeX服务在Docker里启动. 进入包含docker-compose文件的目录, 用下面命令启动EdgeX:

docker-compose up -d

回到你自定义的Device Service目录,告诉设备服务从哪儿取找到libcsdk.so:

export LD_LIBRARY_PATH=$CSDK_DIR/lib

运行设备服务:

./device-example-c

现在,你可以看到你的设备服务每10秒就调用一次/Random命令。你也可以查看edgex-core-data服务的log来验证它正在发送数据到EdgeX:

docker logs -f edgex-core-data

每当你的设备服务被调用时,它就会打印一次事件记录。

你也可以通过直接使用curl去query设备服务来手动生成一个事件

curl 0:49992/api/v1/device/name/RandNum-Device01/Random

注意: “randomnumber” reading的值是一个介于0到100之间的整数

{"device":"RandNum-Device01","origin":1559317102457,"readings":[{"name":"randomnumber","value":"63"}]}