前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >我是庖丁,<肢解IOT平台>之物模型

我是庖丁,<肢解IOT平台>之物模型

作者头像
sanshengshui
发布2019-06-26 14:50:01
1.5K0
发布2019-06-26 14:50:01
举报
文章被收录于专栏:穆书伟穆书伟

前言

物模型是对设备在云端的功能描述,包括设备的属性,数据,服务和事件。

物联网平台通过定义一种物的描述语言来描述物模型,称之为 TSL(即 Thing Specification Language),采用JSON格式,您可以根据TSL组装上报设备的数据。

最终能达到的效果:

  • 识别JSON中的键值内容,默认情况下,Key始终是一个字符串,而value可以是String,boolean,double或long。
  • 解析识别JSON字符串和JSON数组类型的字符串
  • 解析识别带有毫秒精度的unix时间戳的JSON字符串

效果如下:

引入依赖

使用序列化框架GSON对JSON格式的键值对进行识别解析,可以通过引入com.google.code.gson来配置关系。

代码语言:javascript
复制
 <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
 </dependency>

键值属性

KvEntry

KvEntry中提供了获取键值对属性的基本接口,例如获取字符属性的键,值和获取字符串,布尔型和数字类型的接口方法。BasicKvEntry定义了键只能为字符串类型,LongDataEntry,BooleanDataEntry,DoubleDataEntry和StringDataEntry分别定义了相应属性的值。

代码语言:javascript
复制
​
public interface KvEntry extends Serializable {
​
    String getKey();
​
    DataType getDataType();
​
    Optional<String> getStrValue();
​
    Optional<Long> getLongValue();
​
    Optional<Boolean> getBooleanValue();
​
    Optional<Double> getDoubleValue();
​
    String getValueAsString();
​
    Object getValue();
​
}
​

属性和上传数据

通过将来自设备的消息根据类型划分为设备属性(AttributesUpdateRequest)和设备上传数据(TelemetryUploadRequest),

其中TelemetryUploadRequest包含了Long型的unix时间戳。

Json识别解析

属性识别解析

属性识别解析如下,上传数据解析识别类似

UML 时序图如下:

代码语言:javascript
复制
public class JsonConverter {
​
    private static final Gson GSON = new Gson();
    public static final String CAN_T_PARSE_VALUE = "Can't parse value: ";
​
   //遍历键值属性,对相应键值进行处理
   public static List<KvEntry> parseValues(JsonObject valuesObject) {
        List<KvEntry> result = new ArrayList<>();
        for (Map.Entry<String, JsonElement> valueEntry : valuesObject.entrySet()) {
            JsonElement element = valueEntry.getValue();
            if (element.isJsonPrimitive()) {
                JsonPrimitive value = element.getAsJsonPrimitive();
                //如果值为字符串
                if (value.isString()) {
                    //新建StringDataEntry
                    result.add(new StringDataEntry(valueEntry.getKey(), value.getAsString()));
                //如果值为布尔型
                } else if (value.isBoolean()) {
                //新建BooleanDataEntry
                    result.add(new BooleanDataEntry(valueEntry.getKey(), value.getAsBoolean()));
                    //如果值为数值类型
                } else if (value.isNumber()) {
                    parseNumericValue(result, valueEntry, value);
                } else {
                    throw new JsonSyntaxException(CAN_T_PARSE_VALUE + value);
                }
            } else {
                throw new JsonSyntaxException(CAN_T_PARSE_VALUE + element);
            }
        }
        return result;
    }
    
    private static void parseNumericValue(List<KvEntry> result, Map.Entry<String, JsonElement> valueEntry, JsonPrimitive value) {
        //数值转化为字符串类型,并判断是不是包含".",来判断是Long,还是Double
        if (value.getAsString().contains(".")) {
            result.add(new DoubleDataEntry(valueEntry.getKey(), value.getAsDouble()));
        } else {
            try {
                long longValue = Long.parseLong(value.getAsString());
                result.add(new LongDataEntry(valueEntry.getKey(), longValue));
            } catch (NumberFormatException e) {
                throw new JsonSyntaxException("Big integer values are not supported!");
            }
        }
    }
​
    public static AttributesUpdateRequest convertToAttributes(JsonElement element) {
        return convertToAttributes(element, BasicRequest.DEFAULT_REQUEST_ID);
    }
​
    public static AttributesUpdateRequest convertToAttributes(JsonElement element, int requestId) {
        if (element.isJsonObject()) {
            BasicAttributesUpdateRequest request = new BasicAttributesUpdateRequest(requestId);
            long ts = System.currentTimeMillis();
            //将JSON字符串解析为键值属性的集合
            request.add(parseValues(element.getAsJsonObject()).stream().map(kv -> new BaseAttributeKvEntry(kv, ts)).collect(Collectors.toList()));
            return request;
        } else {
            throw new JsonSyntaxException(CAN_T_PARSE_VALUE + element);
        }
    }
}
​

运行

准备工作: 安装Docker 我已经将此工程制作成镜像,并上传到DockerHub上。

? ??

源代码地址IOT-Guide-TSL

  1. 从DockerHub下载sanshengshui/iot-guide-tsl镜像
代码语言:javascript
复制
 docker pull sanshengshui/iot-gui-tsl

2. 后台运行iot-guide-tsl,并将镜像端口80080映射到本机的8080

代码语言:javascript
复制
 docker run -d -p 8080:8080 sanshengshui/iot-guide-tsl
  1. 利用curl测试接口
代码语言:javascript
复制
curl -v -X POST -d '{"key1":"value1", "key2":true, "key3": 3.0, "key4": 4}' http://localhost:8080/api/v1/tsl --header "Content-Type:application/json"

版权声明: 作者:穆书伟

github出处:https://github.com/sanshengshui

个人博客出处:https://www.mushuwei.cn/

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-04-17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 引入依赖
  • 键值属性
    • KvEntry
      • 属性和上传数据
      • Json识别解析
        • 属性识别解析
        • 运行
        相关产品与服务
        容器镜像服务
        容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档