Java = 8(树莓派端)
Java >= 11(服务器端)
Granite Lite IoT XMPP Server
点击这里下载Granite Lite IoT XMPP Server
Raspberry Pi Zero W硬件板
LED模块
几颗杜邦线
下图是这个教程中使用到的硬件。

这篇教程,会涉及到IoT设备的硬件控制接口,以及IoT终端设备的分发部署。简单介绍相关概念如下。
- 检查设备的合法性
- 检查设备是否在此时被允许进入网络
- 登记设备相关信息到系统中
- 配置设备 - 例如对设备进行网络配置;发放安全token等。
在2 安装和配置Raspberry Pi步骤中,我们只是得到了一个初始化版本的RaspBerry Pi OS操作系统。要想在上面能运行Lithosphere IoT平台的终端程序,还得做以下的配置。
登录到树莓派硬件板。
注:
- 192.168.1.180是树莓派板的网络地址。请改为你配置树莓派板时,指定的静态IP地址。
- pi为树莓派用户。请改为你配置树莓派时,初始化创建的用户名。
注:
- 为何要安装OpenJDK 8版本?
Raspberry Pi OS默认自带的OpenJDK版本是OpenJDK 11。这意味着,如果你执行以下指令。系统会默认安装OpenJDK 11。
创建hello-actuator-protocol工程,pom.xml如下:
代码说明
- 指定parent为com.thefirstlineofcode.basalt:com.thefirstlineofcode.basalt,这样可以直接引用basalt parent pom的依赖管理配置。
- 因为要使用OXM(Object-XMPP Mapping),所以依赖basalt-oxm库。
- 目前,Lithosphere的开源库,仅被部署在TheFirstLineOfCode的私有的maven服务器上。为了构建时能够正确找到开源依赖库,需要配置com.thefirstlineofcode.releases的repository。
代码说明
- OXM框架会帮我们将Project Object转换成XMPP协议文档。当Flash对象的repeat属性值设置成5时,会生成下面的XMPP协议文档:
- 不需要担心"urn:leps:things:simple-light"字符串太长了,会带来传输效率的低下。在Lithosphere IoT平台下,如果使用BXMPP技术,ProtocolObject(namespace="urn:leps:things:simple-light", localName="flash")这段协议头信息,会被转化成3字节长度的二进制协议信息。
- TurnOn和TurnOff,表达一个不带任何参数的指令,所以它们被设计成不带任何实例属性的空对象。
代码说明
- 继承SimpleThingModelDescriptor,这个基类实现了IThingModelDescriptor接口,提供了一些复用代码,可以让我们编写Model Descriptor时更省事。
- IoT设备的型号名。在这里,我们把这个被遥控闪灯的IoT设备型号叫做HAT,Hello Actuator Thing的缩写。
- 这个IoT设备是一个Actuator(执行器)设备,它接受Action指令,然后执行指令对应的操作。它不是Sensor,不需要上报数据。它也不触发事件,不需要事件通知功能。所以构造器里的参数都是false,null。只有最后一个构造器参数,我们用createSupportedActions(),将这个Actuator设备支持的Action都登记到Model Descriptor中。当然,在这个例子里,IoT设备只支持3个指令,TurnOn,TurnOff,Flash。
因为需要在后续开发客户端和服务器端插件包时,引用协议包,所以我们在hello-actuator-protocol工程里,执行构建安装指令,把协议包安装到本地maven仓库。
创建hello-actuator-server目录,添加pom.xml文件。
代码说明
- parent设置为com.thefirstlineofcode.sand:sand-server,可引用parent POM里的以来配置管理。
- 依赖com.thefirstlineofcode.sand.server:sand-server-things库,因为我们要使用这个库里的接口IThingProvider和IThingRegistrationCustomizer来实现相关功能。
- 依赖hello-actuator-protocol协议包。
代码说明
- 实现IThingProvider接口,在接口方法里,我们将前面开发的HatModelDescripotor登记到服务器中。
- 请注意@Extension标注,它申明了这个类是PF4J的插件扩展。
代码说明
- 继承ThingRegistrationCustomizerAdapter,这个类提供了IThingRegistrationCustomizer接口的默认实现。
- 重载了isUnregisteredThing方法,这个方法检查IoT设备的 Thing ID和Registration Code的合法性。我们看到,实现检查一个硬编码写死的Registration Code。
- isAuthorizationRequired(),返回false。我们在这个例子中,只检查Thing ID和Registration Code的合法性。不做人工的设备注册授权。所以我们关掉Authorization功能。
- @Extension标注申明这个类是PF4J的插件扩展。
在src/main/resources目录下,创建plugin.properties。
代码说明
- plugin.dependencies,依赖sand-server-things插件。
- non-plugin.dependencies,依赖hello-actuator-protocol协议包(非插件格式jar)。
构建hello-actuator-server插件包
启动Granite Lite XMPP Server


创建hello-actuator-thing目录,添加pom.xml文件。
代码说明
- POM继承com.thefirstlineofcode.sand:sand-client,以便复用父POM里的依赖配置管理。
- hello-actuator-thing是一个独立运行的Java程序。我们使用maven-assembly-plugin和maven-jar-plugin来打包和配置可这个可运行程序。
- 依赖com.thefirstlineofcode.sand.client:sand-client-edge库,我们使用Edge库来帮助终端设备进行设备注册和连接服务器。
- 依赖pi4j-core库。我们用Pi4J库来访问控制硬件板的GPIO接口。
注:我们使用1.3版本Pi4J。因为Pi4J v1.4和Pi4J v2.x需要JDK 11。而我们在树莓派Zero W上,只安装了JDK 8。所以,我们使用Pi4J v1.3。
- 依赖hello-actautor-protocol协议包。
注:
这种控制硬件的接口,在概念里,我们把它叫做Thing Controller,智能物件控制器。
hello-actuator-thing的核心类HelloActuatorThing,我们让它实现ISimpleLight接口。
代码说明
- 在configureGpio()方法里,我们使用Pi4J库对GPIO进行配置。我们配置使用ledPin变量来对LED灯的IN接口进行控制。
- 在turnOn方法中,我们调用ledPin.high(),拉高GPIO引针电压,这会让LED灯亮灯。对应的,在turnOff方法中,我们调用ledPin.low()来让LED灯熄灯。
代码说明
- AbstractEdgeThing留下了一些抽象方法给子类来实现。这些抽象方法名字很直白,我们遵从方法名给出对应实现细节即可。
- registerIotPlugins()方法,在这里登记我们要使用的插件。因为这个IoT设备是一个可执行指令的Actuator。所以我们只需要注册ActuatorPlugin插件。
- startIotComponents()方法,Edge Thing连接到服务器后,会调用这个方法来启动设备。在这里,我们需要把Actuator组件启动起来,Actuator组件来自ActuatorPlugin。
我们在startActuator()方法里,创建IActuator实例,并注册Executors,最后调用Actuator的start()方法。
- 在registerExecutors()方法里,我们给TurnOn,TurnOff,Flash指令,注册它们对应的执行器。
有两种注册执行器的API。第一种API,我们直接将Action指令类,和Executor指令类,登记到Actuator。
注:
这里registerExecutor()方法的最后一个参数,是Thing Controller。
依据设计原则中的责任原则,Thing Controller负责直接控制IoT设备的硬件接口。在这里,Thing Controller是ISimpleLigh。
HelloActuatorThing实现了这个接口(ISimpleLight),提供控制硬件的turnOn(),TurnOff(),flash()方法。
我们把HelloActuatorThing当做第三个参数传给Actuator,Thing Controller会被注入给Executor使用。
- 第二种API,我们注册一个Executor Factory,由这个Factory来提供相关信息以及创建Executor,这样可以更灵活的处理Executor的创建。我们使用这种API来创建FlashExecutor。
- 我们来处理一下设备注册的对应逻辑。还记得吗,我们在服务器端的Registration Customizer里,在检查Registration Code合法性时,使用的是一个硬编码的Registration Code。
所以,在IoT设备端,我们需要使用这个硬编码的Registration Code去注册。
我们重载loadRegistrationCode()方法,用写死的"abcdefghijkl"作为Registration Code去进行注册。
我们编写一个主程序来启动hello-actuator-thing。
代码说明
- 很简单直白的代码,重要的是调用HelloActuatorThing的start()方法,将Edge Thing启动起来。
用maven构建hello-actuator-thing
注:
请将pi用户名,和树莓派网络ip 192.168.1.180,改为你自己环境的配置值。
登录到树莓派上
说明
- 启动thing程序之前,记得要先启动Granite XMPP Server。
- 第一次运行thing程序时,需要使用--host参数指定服务器地址。AbstractEdgeThing会记住程序启动参数,后续再启动thing程序,不需要再指定host。
- 程序启动后,会连接到服务器进行设备注册,注册成功后,登录到服务器
一切就绪后,可以看到Thing thing has started的提示。

可以使用exit命令来退出hello-actuator-thing程序。
代码说明
- 用chatClient创建IRemoting实例,然后调用IRemoting的execute()方法。方法3个参数,第一个参数是远程设备的地址;第二个参数是要执行的action对象(Protocol Object);第三个参数,是RemotingCallback,我们用这个回调接口来处理远程指令执行结果。
- 在RemotingCallback里,如果远程指令正常执行,会回调executed()方法;远程指令执行出错,会回调occurred()方法;远程指令执行超时(执行端未返回响应,不能确认指令是否执行成功),会调用timeout()方法。我们在这些回调方法里,做对应的处理。
通过这篇教程,我们可以了解到以下的内容:
- 我们可以通过IoT硬件板上的GPIO接口,来控制IoT设备的外接硬件模块。
- 开源的Pi4J库,可以帮助我们使用Java语言来访问树莓派上的GPIO接口。
- 在IoT的世界里,有不同的通讯协议可以选择。在互联网端,XMPP协议是一个很好的选择。
- 如果使用Lithosphere,基于OXM(Object/XMPP Mapping)技术,我们不需要去处理XML,也不需要了解XMPP协议的细节。我们简单的创建Protocol Object来表达通讯指令。
- Lithosphere基于插件架构,我们可以通过创建服务器端插件,将我们要管理的IoT设备注册到系统中。我们还可以定制设备注册过程,以应对真实项目的需求。
- 在IoT设备端,我们开发Thing程序。使用Sand的sand-client-edge库,可以简化设备注册,服务器连接过程。我们只要注册需要使用的插件,编写Thing端处理逻辑。
- 对于Actuator(执行器)类型的IoT设备,我们使用actuator插件来简化开发。我们登记设备可执行的指令,并且注册指令所对应的Executor(执行器)。
- 我们在手机App端,使用remoting插件来远程执行指令,遥控IoT设备。
- 这篇教程里的内容,全部基于Java平台,只有Java,不涉及其它编程语言。
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/h6javajc/8906.html