编写Mesh的Model需要先知道节点(node),元素(element),模型(model)的概念。
1. 节点(Node)
简单来讲,一个节点就是一个mesh芯片。要使一个节点成为Mesh网络里面的点,需要配网者(provisioner) 配网,配置客户端(configuration client) 配置后才能正常使用。
2. 元素(Element)
一个元素就是执行一组功能的单位实体,一个节点里面至少有一个元素,称做主元素(primary element),其余的是次要元素(secondary element)。
每个元素都会被配网者分配一个单播地址(unicast address)作为唯一标识。
3. 模型(Model)
一个模型定义了特定功能的实现及交互流程。模型一般是配套的,设计一组Model,既需要设计Client又需要设计Server。一端发送指定类型消息,对端响应另一指定消息,这些都属于模型的设计范畴。
3.1. Model ID
每个Model都有一个Model ID作为唯一的标识。
Model ID分为SIG Model和Vendor Model。
SIG Model ID是SIG规定的标准Model,长度共2字节。
其相关Model ID对应的Model如下表所示:
SIG Model ID | Description |
---|---|
0x0000 | Configuration Server |
0x0001 | Configuration Client |
0x0002 | Health Server |
0x0003 | Health Client |
0x1000 | Generic OnOff Server |
… | … |
0x1100 | Sensor Server |
… | … |
0x1200 | Time Server |
… | … |
0x1300 | Light Lightness Server |
… | … |
Vendor Model ID是厂商自定义的Model,共4字节。
field | Size(octs) | Notes |
---|---|---|
Vendor ID | 2 | 厂商ID,由SIG分配,Company Identifiers |
Model ID | 2 | 厂商自定义的Model ID,共256个 |
3.2. Opcode
代表该消息需要进行的操作。
Opcode Format | Notes |
---|---|
0x00-0x7E | 1-octet Opcodes,127个,由SIG使用 |
01111111 | RFU |
10xxxxxx xxxxxxxx | 2-octet Opcodes,16384个,由SIG使用 |
11xxxxxx zzzzzzzz | 3-octet Opcodes,‘zzzzzzzz’表示厂商ID,64个,由指定厂商使用 |
可以看出Opcode字段包含了操作码和Model ID这两个信息。
可以知道,厂商向SIG申请一个Vendor Company ID,可以自定义256个Model,每个Model可指定64个不同的操作码。
3.3. Payload
该消息进行操作附带的内容。
设计自定义Model需要分配一个指定的Model ID,以及该Model实现功能所需要的Opcode/Payload。
对于SIG的Model,其Model ID/Opcode/Payload都已经固定,了解其功能后就可以直接使用。
3.4. Model相关配置
每个Model都有属于自己的Public Address/Subscribe List表明消息发给谁,需要收到谁的消息,每个Model都绑定1个或多个AppKey/NetKey表明属于哪个网络,哪个App。
一个节点就是一个芯片,里面有多个元素。比如说我有一个mesh芯片,上面有三个灯,即是说这个芯片就是一个节点,三个灯就是三个元素。灯1和灯2里面有两个Model,分别是控制亮度的Model和控制开关的Model,灯3除此之外还有一个控制颜色的Model,于是三个元素,分别有2/2/3个Model。
4. 通过Model进行Mesh通信
Model需要绑定AppKey/NetKey,需要设置Pub/Sub地址。
AppKey在添加时就绑定在某一个NetKey上,因为光有AppKey是不能通信的,所有Model绑定了AppKey就相当与绑定了NetKey,不同的NetKey已经在子网的概念中讲过。那么不同的AppKey有什么用呢?在中继的时候提过,通过Appkey/NetKey可以有效的进行中继,避免中继进行多余的加解密浪费时间。Appkey还能保证该消息不能被其他model使用,只有绑定了相同的AppKey之间的Model才能进行通信。
下面来举例说明:
Q1:
假设所有设备都处在同一网络,遥控器1(node1)可以控制空调(node4),遥控器2(node2)可以控制电扇(node5),遥控器3(node3)既可以控制空调(node4),又可以控制电扇(node5)。
A:
遥控器1和空调都绑定AppKey1,遥控器2和电扇都绑定AppKey2,遥控器3绑定AppKey1和Appkey2。那么电扇收到遥控器1发送的消息时,发现没有绑定Appkey1的模型,就会把这条消息过滤掉。遥控器3发送空调的命令使用空调客户端模型,发送电扇的命令就使用电扇客户端模型,空调客户端模型绑定AppKey1,电扇客户端模型绑定AppKey2。
Q2:
假设所有设备都处在同一网络,遥控器1(node1)可以控制电扇1(node4),遥控器2(node2)可以控制电扇2(node5),遥控器3(node3)既可以控制电扇1(node4),又可以控制电扇2(node5)。
A:
其实和上面一样,电扇1和电扇2分配不同的AppKey就能做到区分。这里需要注意的一点是,Q1中的空调模型和电扇模型可以注册在同一个元素下面。而这里的两个电扇使用的同一个Model,因此具有相同的Model ID,不能放在同一元素下,会造成model无法区分,因此可以添加多个元素,比如元素1注册电扇1,元素2注册电扇2。.
Q3:
假设所有设备都处在同一网络,遥控器1(node1)可以控制灯1(node4),遥控器2(node2)可以控制灯2(node5)和灯3(node6),遥控器3(node3)可以控制灯1(node4),灯2(node5)和灯3(node6)。
A:
这里就可以使用pub/sub了,遥控器1将消息发送至group1,遥控器2将消息发送至group2,遥控器3将消息发送至group3,灯1订阅group1和group3,灯2订阅group2和group3,灯3订阅group2和group3。如果遥控器1想控制灯2,只需要将灯2的订阅表添加一个group1就行了,若遥控器2不控制灯3,只需要将灯3订阅表里面的group2删除就行了。
Q4:
如果空调遥控器和电扇绑定了相同的AppKey,他们之间能够通信吗?
A:
答案是肯定的,对于Model来说,它并不知道这是空调还是电扇。但是之前提到过Model收发的消息含有Opcode和Payload,只有通过了这两项的检查,消息才能被真正处理。